1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmlhelp.hxx"
26
27 #include "db.hxx"
28
29 #include <rtl/alloc.h>
30 #include <cstring>
31
32 #include "com/sun/star/io/XSeekable.hpp"
33
34 using namespace com::sun::star::uno;
35 using namespace com::sun::star::io;
36
37 namespace helpdatafileproxy {
38
39 //----------------------------------------------------------------------------
copyToBuffer(const char * pSrcData,int nSize)40 void HDFData::copyToBuffer( const char* pSrcData, int nSize )
41 {
42 m_nSize = nSize;
43 delete [] m_pBuffer;
44 m_pBuffer = new char[m_nSize+1];
45 memcpy( m_pBuffer, pSrcData, m_nSize );
46 m_pBuffer[m_nSize] = 0;
47 }
48
49
50 // Hdf
51
implReadLenAndData(const char * pData,int & riPos,HDFData & rValue)52 bool Hdf::implReadLenAndData( const char* pData, int& riPos, HDFData& rValue )
53 {
54 bool bSuccess = false;
55
56 // Read key len
57 const char* pStartPtr = pData + riPos;
58 char* pEndPtr;
59 sal_Int32 nKeyLen = strtol( pStartPtr, &pEndPtr, 16 );
60 if( pEndPtr == pStartPtr )
61 return bSuccess;
62 riPos += (pEndPtr - pStartPtr) + 1;
63
64 const char* pKeySrc = pData + riPos;
65 rValue.copyToBuffer( pKeySrc, nKeyLen );
66 riPos += nKeyLen + 1;
67
68 bSuccess = true;
69 return bSuccess;
70 }
71
createHashMap(bool bOptimizeForPerformance)72 void Hdf::createHashMap( bool bOptimizeForPerformance )
73 {
74 releaseHashMap();
75 if( bOptimizeForPerformance )
76 {
77 if( m_pStringToDataMap != NULL )
78 return;
79 m_pStringToDataMap = new StringToDataMap();
80 }
81 else
82 {
83 if( m_pStringToValPosMap != NULL )
84 return;
85 m_pStringToValPosMap = new StringToValPosMap();
86 }
87
88 Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL );
89 if( xIn.is() )
90 {
91 Sequence< sal_Int8 > aData;
92 sal_Int32 nSize = m_xSFA->getSize( m_aFileURL );
93 sal_Int32 nRead = xIn->readBytes( aData, nSize );
94
95 const char* pData = (const char*)aData.getConstArray();
96 int iPos = 0;
97 while( iPos < nRead )
98 {
99 HDFData aDBKey;
100 if( !implReadLenAndData( pData, iPos, aDBKey ) )
101 break;
102
103 rtl::OString aOKeyStr = aDBKey.getData();
104
105 // Read val len
106 const char* pStartPtr = pData + iPos;
107 char* pEndPtr;
108 sal_Int32 nValLen = strtol( pStartPtr, &pEndPtr, 16 );
109 if( pEndPtr == pStartPtr )
110 break;
111
112 iPos += (pEndPtr - pStartPtr) + 1;
113
114 if( bOptimizeForPerformance )
115 {
116 const char* pValSrc = pData + iPos;
117 rtl::OString aValStr( pValSrc, nValLen );
118 (*m_pStringToDataMap)[aOKeyStr] = aValStr;
119 }
120 else
121 {
122 // store value start position
123 (*m_pStringToValPosMap)[aOKeyStr] = std::pair<int,int>( iPos, nValLen );
124 }
125 iPos += nValLen + 1;
126 }
127
128 xIn->closeInput();
129 }
130 }
131
releaseHashMap(void)132 void Hdf::releaseHashMap( void )
133 {
134 if( m_pStringToDataMap != NULL )
135 {
136 delete m_pStringToDataMap;
137 m_pStringToDataMap = NULL;
138 }
139 if( m_pStringToValPosMap != NULL )
140 {
141 delete m_pStringToValPosMap;
142 m_pStringToValPosMap = NULL;
143 }
144 }
145
146
getValueForKey(const rtl::OString & rKey,HDFData & rValue)147 bool Hdf::getValueForKey( const rtl::OString& rKey, HDFData& rValue )
148 {
149 bool bSuccess = false;
150 if( !m_xSFA.is() )
151 return bSuccess;
152
153 try
154 {
155
156 if( m_pStringToDataMap == NULL && m_pStringToValPosMap == NULL )
157 {
158 bool bOptimizeForPerformance = false;
159 createHashMap( bOptimizeForPerformance );
160 }
161
162 if( m_pStringToValPosMap != NULL )
163 {
164 StringToValPosMap::const_iterator it = m_pStringToValPosMap->find( rKey );
165 if( it != m_pStringToValPosMap->end() )
166 {
167 const std::pair<int,int>& rValPair = it->second;
168 int iValuePos = rValPair.first;
169 int nValueLen = rValPair.second;
170
171 Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL );
172 if( xIn.is() )
173 {
174 Reference< XSeekable > xXSeekable( xIn, UNO_QUERY );
175 if( xXSeekable.is() )
176 {
177 xXSeekable->seek( iValuePos );
178
179 Sequence< sal_Int8 > aData;
180 sal_Int32 nRead = xIn->readBytes( aData, nValueLen );
181 if( nRead == nValueLen )
182 {
183 const char* pData = (const sal_Char*)aData.getConstArray();
184 rValue.copyToBuffer( pData, nValueLen );
185 bSuccess = true;
186 }
187 }
188 xIn->closeInput();
189 }
190 }
191 }
192
193 else if( m_pStringToDataMap != NULL )
194 {
195 StringToDataMap::const_iterator it = m_pStringToDataMap->find( rKey );
196 if( it != m_pStringToDataMap->end() )
197 {
198 const rtl::OString& rValueStr = it->second;
199 int nValueLen = rValueStr.getLength();
200 const char* pData = rValueStr.getStr();
201 rValue.copyToBuffer( pData, nValueLen );
202 bSuccess = true;
203 }
204 }
205
206 }
207 catch( Exception & )
208 {
209 bSuccess = false;
210 }
211
212 return bSuccess;
213 }
214
startIteration(void)215 bool Hdf::startIteration( void )
216 {
217 bool bSuccess = false;
218
219 sal_Int32 nSize = m_xSFA->getSize( m_aFileURL );
220
221 Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL );
222 if( xIn.is() )
223 {
224 m_nItRead = xIn->readBytes( m_aItData, nSize );
225 if( m_nItRead == nSize )
226 {
227 bSuccess = true;
228 m_pItData = (const char*)m_aItData.getConstArray();
229 m_iItPos = 0;
230 }
231 else
232 {
233 stopIteration();
234 }
235 }
236
237 return bSuccess;
238 }
239
getNextKeyAndValue(HDFData & rKey,HDFData & rValue)240 bool Hdf::getNextKeyAndValue( HDFData& rKey, HDFData& rValue )
241 {
242 bool bSuccess = false;
243
244 if( m_iItPos < m_nItRead )
245 {
246 if( implReadLenAndData( m_pItData, m_iItPos, rKey ) )
247 {
248 if( implReadLenAndData( m_pItData, m_iItPos, rValue ) )
249 bSuccess = true;
250 }
251 }
252
253 return bSuccess;
254 }
255
stopIteration(void)256 void Hdf::stopIteration( void )
257 {
258 m_aItData = Sequence<sal_Int8>();
259 m_pItData = NULL;
260 m_nItRead = -1;
261 m_iItPos = -1;
262 }
263 } // end of namespace helpdatafileproxy
264