defer finding dialog parent until we need it
[LibreOffice.git] / xmlhelp / source / cxxhelp / provider / db.cxx
blobe0c099c94410f2e252d6e92457cb28399320d73c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "db.hxx"
23 #include <algorithm>
24 #include <charconv>
25 #include <cstring>
26 #include <system_error>
27 #include <utility>
29 #include <com/sun/star/io/XSeekable.hpp>
31 using namespace com::sun::star::uno;
32 using namespace com::sun::star::io;
34 namespace {
36 std::pair<sal_Int32, char const *> readInt32(char const * begin, char const * end) {
37 sal_Int32 n = 0;
38 auto const [ptr, ec] = std::from_chars(begin, end, n, 16);
39 return {std::max(n, sal_Int32(0)), ec == std::errc{} && n >= 0 ? ptr : begin};
44 namespace helpdatafileproxy {
46 void HDFData::copyToBuffer( const char* pSrcData, int nSize )
48 m_nSize = nSize;
49 m_pBuffer.reset( new char[m_nSize+1] );
50 memcpy( m_pBuffer.get(), pSrcData, m_nSize );
51 m_pBuffer[m_nSize] = 0;
55 // Hdf
57 bool Hdf::implReadLenAndData( const char* pData, char const * end, int& riPos, HDFData& rValue )
59 bool bSuccess = false;
61 // Read key len
62 const char* pStartPtr = pData + riPos;
63 auto [nKeyLen, pEndPtr] = readInt32(pStartPtr, end);
64 if( pEndPtr == pStartPtr )
65 return bSuccess;
66 riPos += (pEndPtr - pStartPtr) + 1;
68 const char* pKeySrc = pData + riPos;
69 rValue.copyToBuffer( pKeySrc, nKeyLen );
70 riPos += nKeyLen + 1;
72 bSuccess = true;
73 return bSuccess;
76 void Hdf::createHashMap( bool bOptimizeForPerformance )
78 releaseHashMap();
79 if( bOptimizeForPerformance )
81 if( m_pStringToDataMap != nullptr )
82 return;
83 m_pStringToDataMap.reset(new StringToDataMap);
85 else
87 if( m_pStringToValPosMap != nullptr )
88 return;
89 m_pStringToValPosMap.reset(new StringToValPosMap);
92 Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL );
93 if( !xIn.is() )
94 return;
96 Sequence< sal_Int8 > aData;
97 sal_Int32 nSize = m_xSFA->getSize( m_aFileURL );
98 sal_Int32 nRead = xIn->readBytes( aData, nSize );
100 const char* pData = reinterpret_cast<const char*>(aData.getConstArray());
101 auto const end = pData + nRead;
102 int iPos = 0;
103 while( iPos < nRead )
105 HDFData aDBKey;
106 if( !implReadLenAndData( pData, end, iPos, aDBKey ) )
107 break;
109 OString aOKeyStr = aDBKey.getData();
111 // Read val len
112 const char* pStartPtr = pData + iPos;
113 auto [nValLen, pEndPtr] = readInt32(pStartPtr, end);
114 if( pEndPtr == pStartPtr )
115 break;
117 iPos += (pEndPtr - pStartPtr) + 1;
119 if( bOptimizeForPerformance )
121 const char* pValSrc = pData + iPos;
122 (*m_pStringToDataMap)[aOKeyStr] = OString(pValSrc, nValLen);
124 else
126 // store value start position
127 (*m_pStringToValPosMap)[aOKeyStr] = std::pair<int,int>( iPos, nValLen );
129 iPos += nValLen + 1;
132 xIn->closeInput();
135 void Hdf::releaseHashMap()
137 m_pStringToDataMap.reset();
138 m_pStringToValPosMap.reset();
142 Hdf::~Hdf()
146 bool Hdf::getValueForKey( const OString& rKey, HDFData& rValue )
148 bool bSuccess = false;
149 if( !m_xSFA.is() )
150 return bSuccess;
155 if( m_pStringToDataMap == nullptr && m_pStringToValPosMap == nullptr )
157 createHashMap( false/*bOptimizeForPerformance*/ );
160 if( m_pStringToValPosMap != nullptr )
162 StringToValPosMap::const_iterator it = m_pStringToValPosMap->find( rKey );
163 if( it != m_pStringToValPosMap->end() )
165 const std::pair<int,int>& rValPair = it->second;
166 int iValuePos = rValPair.first;
167 int nValueLen = rValPair.second;
169 Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL );
170 if( xIn.is() )
172 Reference< XSeekable > xXSeekable( xIn, UNO_QUERY );
173 if( xXSeekable.is() )
175 xXSeekable->seek( iValuePos );
177 Sequence< sal_Int8 > aData;
178 sal_Int32 nRead = xIn->readBytes( aData, nValueLen );
179 if( nRead == nValueLen )
181 const char* pData = reinterpret_cast<const char*>(aData.getConstArray());
182 rValue.copyToBuffer( pData, nValueLen );
183 bSuccess = true;
186 xIn->closeInput();
191 else if( m_pStringToDataMap != nullptr )
193 StringToDataMap::const_iterator it = m_pStringToDataMap->find( rKey );
194 if( it != m_pStringToDataMap->end() )
196 const OString& rValueStr = it->second;
197 int nValueLen = rValueStr.getLength();
198 const char* pData = rValueStr.getStr();
199 rValue.copyToBuffer( pData, nValueLen );
200 bSuccess = true;
205 catch( Exception & )
207 bSuccess = false;
210 return bSuccess;
213 bool Hdf::startIteration()
215 bool bSuccess = false;
217 sal_Int32 nSize = m_xSFA->getSize( m_aFileURL );
219 Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL );
220 if( xIn.is() )
222 m_nItRead = xIn->readBytes( m_aItData, nSize );
223 if( m_nItRead == nSize )
225 bSuccess = true;
226 m_iItPos = 0;
228 else
230 stopIteration();
234 return bSuccess;
237 bool Hdf::getNextKeyAndValue( HDFData& rKey, HDFData& rValue )
239 bool bSuccess = false;
241 if( m_iItPos < m_nItRead )
243 auto const p = reinterpret_cast<const char*>(m_aItData.getConstArray());
244 if( implReadLenAndData( p, p + m_aItData.size(), m_iItPos, rKey ) )
246 if( implReadLenAndData( p, p + m_aItData.size(), m_iItPos, rValue ) )
247 bSuccess = true;
251 return bSuccess;
254 void Hdf::stopIteration()
256 m_aItData = Sequence<sal_Int8>();
257 m_nItRead = -1;
258 m_iItPos = -1;
261 } // end of namespace helpdatafileproxy
263 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */