xref: /trunk/main/xmlhelp/source/cxxhelp/provider/db.cxx (revision 89dcb3da00a29b2b7b028d5bd430e2099844a09e)
1*89dcb3daSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*89dcb3daSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*89dcb3daSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*89dcb3daSAndrew Rist  * distributed with this work for additional information
6*89dcb3daSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*89dcb3daSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*89dcb3daSAndrew Rist  * "License"); you may not use this file except in compliance
9*89dcb3daSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*89dcb3daSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*89dcb3daSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*89dcb3daSAndrew Rist  * software distributed under the License is distributed on an
15*89dcb3daSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*89dcb3daSAndrew Rist  * KIND, either express or implied.  See the License for the
17*89dcb3daSAndrew Rist  * specific language governing permissions and limitations
18*89dcb3daSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*89dcb3daSAndrew Rist  *************************************************************/
21*89dcb3daSAndrew Rist 
22*89dcb3daSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_xmlhelp.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "db.hxx"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <rtl/alloc.h>
30cdf0e10cSrcweir #include <cstring>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "com/sun/star/io/XSeekable.hpp"
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include "osl/file.hxx"
35cdf0e10cSrcweir #include "osl/thread.hxx"
36cdf0e10cSrcweir #ifdef TEST_DBHELP
37cdf0e10cSrcweir #include <osl/time.h>
38cdf0e10cSrcweir #endif
39cdf0e10cSrcweir 
40cdf0e10cSrcweir using namespace com::sun::star;
41cdf0e10cSrcweir using namespace com::sun::star::uno;
42cdf0e10cSrcweir using namespace com::sun::star::io;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir namespace berkeleydbproxy {
45cdf0e10cSrcweir 
46cdf0e10cSrcweir //----------------------------------------------------------------------------
47cdf0e10cSrcweir namespace db_internal
48cdf0e10cSrcweir {
49cdf0e10cSrcweir     // static void raise_error(int dberr, const char * where);
50cdf0e10cSrcweir 
51cdf0e10cSrcweir     static inline int check_error(int dberr, const char * where)
52cdf0e10cSrcweir     {
53cdf0e10cSrcweir         (void)where;
54cdf0e10cSrcweir 
55cdf0e10cSrcweir         // if (dberr) raise_error(dberr,where);
56cdf0e10cSrcweir         return dberr;
57cdf0e10cSrcweir     }
58cdf0e10cSrcweir }
59cdf0e10cSrcweir 
60cdf0e10cSrcweir void DBData::copyToBuffer( const char* pSrcData, int nSize )
61cdf0e10cSrcweir {
62cdf0e10cSrcweir     m_nSize = nSize;
63cdf0e10cSrcweir     delete [] m_pBuffer;
64cdf0e10cSrcweir     m_pBuffer = new char[m_nSize+1];
65cdf0e10cSrcweir     memcpy( m_pBuffer, pSrcData, m_nSize );
66cdf0e10cSrcweir     m_pBuffer[m_nSize] = 0;
67cdf0e10cSrcweir }
68cdf0e10cSrcweir 
69cdf0e10cSrcweir 
70cdf0e10cSrcweir // DBHelp
71cdf0e10cSrcweir 
72cdf0e10cSrcweir bool DBHelp::implReadLenAndData( const char* pData, int& riPos, DBData& rValue )
73cdf0e10cSrcweir {
74cdf0e10cSrcweir     bool bSuccess = false;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir     // Read key len
77cdf0e10cSrcweir     const char* pStartPtr = pData + riPos;
78cdf0e10cSrcweir     char* pEndPtr;
79cdf0e10cSrcweir     sal_Int32 nKeyLen = strtol( pStartPtr, &pEndPtr, 16 );
80cdf0e10cSrcweir     if( pEndPtr == pStartPtr )
81cdf0e10cSrcweir         return bSuccess;
82cdf0e10cSrcweir     riPos += (pEndPtr - pStartPtr) + 1;
83cdf0e10cSrcweir 
84cdf0e10cSrcweir     const char* pKeySrc = pData + riPos;
85cdf0e10cSrcweir     rValue.copyToBuffer( pKeySrc, nKeyLen );
86cdf0e10cSrcweir     riPos += nKeyLen + 1;
87cdf0e10cSrcweir 
88cdf0e10cSrcweir     bSuccess = true;
89cdf0e10cSrcweir     return bSuccess;
90cdf0e10cSrcweir }
91cdf0e10cSrcweir 
92cdf0e10cSrcweir #ifdef TEST_DBHELP
93cdf0e10cSrcweir 
94cdf0e10cSrcweir typedef std::pair< rtl::OString, rtl::OString >     KeyValPair;
95cdf0e10cSrcweir typedef std::vector< KeyValPair >                   KeyValPairVector;
96cdf0e10cSrcweir 
97cdf0e10cSrcweir void testWriteKeyValue( FILE* pFile, const KeyValPair& rKeyValPair )
98cdf0e10cSrcweir {
99cdf0e10cSrcweir     if( pFile == NULL )
100cdf0e10cSrcweir         return;
101cdf0e10cSrcweir     char cLF = 10;
102cdf0e10cSrcweir 
103cdf0e10cSrcweir     const rtl::OString& aKeyStr = rKeyValPair.first;
104cdf0e10cSrcweir     const rtl::OString& aValueStr = rKeyValPair.second;
105cdf0e10cSrcweir     int nKeyLen = aKeyStr.getLength();
106cdf0e10cSrcweir     int nValueLen = aValueStr.getLength();
107cdf0e10cSrcweir     fprintf( pFile, "%x ", nKeyLen );
108cdf0e10cSrcweir     if( nKeyLen > 0 )
109cdf0e10cSrcweir         fwrite( aKeyStr.getStr(), 1, nKeyLen, pFile );
110cdf0e10cSrcweir     fprintf( pFile, " %x ", nValueLen );
111cdf0e10cSrcweir     if( nValueLen > 0 )
112cdf0e10cSrcweir         fwrite( aValueStr.getStr(), 1, nValueLen, pFile );
113cdf0e10cSrcweir     fprintf( pFile, "%c", cLF );
114cdf0e10cSrcweir }
115cdf0e10cSrcweir 
116cdf0e10cSrcweir bool DBHelp::testAgainstDb( const rtl::OUString& fileURL, bool bOldDbAccess )
117cdf0e10cSrcweir {
118cdf0e10cSrcweir     bool bSuccess = true;
119cdf0e10cSrcweir 
120cdf0e10cSrcweir     KeyValPairVector avKeyValPair;
121cdf0e10cSrcweir 
122cdf0e10cSrcweir     rtl::OUString aOutFileName = fileURL;
123cdf0e10cSrcweir     aOutFileName += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_TestOut"));
124cdf0e10cSrcweir     if( bOldDbAccess )
125cdf0e10cSrcweir         aOutFileName += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_Old"));
126cdf0e10cSrcweir #ifdef WNT
127cdf0e10cSrcweir     FILE* pFile = _wfopen( aOutFileName.getStr(), L"wb" );
128cdf0e10cSrcweir #else
129cdf0e10cSrcweir     rtl::OString sFile = rtl::OUStringToOString(aOutFileName, osl_getThreadTextEncoding());
130cdf0e10cSrcweir     FILE* pFile = fopen( sFile.getStr(), "wb" );
131cdf0e10cSrcweir #endif
132cdf0e10cSrcweir     // Get all values
133cdf0e10cSrcweir     Db table;
134cdf0e10cSrcweir     if( 0 == table.open( 0,fileURL,DB_BTREE,DB_RDONLY,0644 ) )
135cdf0e10cSrcweir     {
136cdf0e10cSrcweir         bool first = true;
137cdf0e10cSrcweir 
138cdf0e10cSrcweir         Dbc* cursor = 0;
139cdf0e10cSrcweir         table.cursor( 0,&cursor,0 );
140cdf0e10cSrcweir         Dbt key_,data;
141cdf0e10cSrcweir         key_.set_flags( DB_DBT_MALLOC ); // Initially the cursor must allocate the necessary memory
142cdf0e10cSrcweir         data.set_flags( DB_DBT_MALLOC );
143cdf0e10cSrcweir 
144cdf0e10cSrcweir         while( cursor && DB_NOTFOUND != cursor->get( &key_,&data,DB_NEXT ) )
145cdf0e10cSrcweir         {
146cdf0e10cSrcweir             rtl::OString keyword( static_cast<sal_Char*>(key_.get_data()),
147cdf0e10cSrcweir                                   key_.get_size() );
148cdf0e10cSrcweir             rtl::OString value( static_cast<sal_Char*>(data.get_data()),
149cdf0e10cSrcweir                                 data.get_size() );
150cdf0e10cSrcweir 
151cdf0e10cSrcweir             KeyValPair aPair( keyword, value );
152cdf0e10cSrcweir             avKeyValPair.push_back( aPair );
153cdf0e10cSrcweir             if( pFile != NULL )
154cdf0e10cSrcweir                 testWriteKeyValue( pFile, aPair );
155cdf0e10cSrcweir 
156cdf0e10cSrcweir             if( first )
157cdf0e10cSrcweir             {
158cdf0e10cSrcweir                 key_.set_flags( DB_DBT_REALLOC );
159cdf0e10cSrcweir                 data.set_flags( DB_DBT_REALLOC );
160cdf0e10cSrcweir                 first = false;
161cdf0e10cSrcweir             }
162cdf0e10cSrcweir         }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir         if( cursor ) cursor->close();
165cdf0e10cSrcweir     }
166cdf0e10cSrcweir     table.close( 0 );
167cdf0e10cSrcweir 
168cdf0e10cSrcweir     // TEST
169cdf0e10cSrcweir     DBData aDBData;
170cdf0e10cSrcweir     Db tableTest;
171cdf0e10cSrcweir     Dbt data;
172cdf0e10cSrcweir 
173cdf0e10cSrcweir     int nOkCount = 0;
174cdf0e10cSrcweir     int nErrCount = 0;
175cdf0e10cSrcweir 
176cdf0e10cSrcweir     bool bTestSuccess;
177cdf0e10cSrcweir     const char* pTestReadData = NULL;
178cdf0e10cSrcweir     int nTestReadDataSize = 0;
179cdf0e10cSrcweir 
180cdf0e10cSrcweir     sal_uInt32 starttime = osl_getGlobalTimer();
181cdf0e10cSrcweir     sal_uInt32 afterfirsttime = starttime;
182cdf0e10cSrcweir 
183cdf0e10cSrcweir     if( pFile != NULL )
184cdf0e10cSrcweir     {
185cdf0e10cSrcweir         if( bOldDbAccess )
186cdf0e10cSrcweir             fprintf( pFile, "\nTesting old access:\n" );
187cdf0e10cSrcweir         else
188cdf0e10cSrcweir             fprintf( pFile, "\nTesting new access:\n" );
189cdf0e10cSrcweir     }
190cdf0e10cSrcweir 
191cdf0e10cSrcweir     KeyValPairVector::const_iterator it;
192cdf0e10cSrcweir     bool bFirst = true;
193cdf0e10cSrcweir     for( it = avKeyValPair.begin() ; it != avKeyValPair.end() ; ++it )
194cdf0e10cSrcweir     {
195cdf0e10cSrcweir         const KeyValPair& rKeyValPair = *it;
196cdf0e10cSrcweir 
197cdf0e10cSrcweir         const rtl::OString& aKeyStr = rKeyValPair.first;
198cdf0e10cSrcweir         const rtl::OString& aValueStr = rKeyValPair.second;
199cdf0e10cSrcweir         int nKeyLen = aKeyStr.getLength();
200cdf0e10cSrcweir         int nValueLen = aValueStr.getLength();
201cdf0e10cSrcweir 
202cdf0e10cSrcweir         const sal_Char* ptr = aValueStr.getStr();
203cdf0e10cSrcweir 
204cdf0e10cSrcweir         bTestSuccess = false;
205cdf0e10cSrcweir         pTestReadData = NULL;
206cdf0e10cSrcweir         nTestReadDataSize = 0;
207cdf0e10cSrcweir         if( bOldDbAccess )
208cdf0e10cSrcweir         {
209cdf0e10cSrcweir             if( bFirst )
210cdf0e10cSrcweir             {
211cdf0e10cSrcweir                 if( tableTest.open( 0,fileURL, DB_BTREE,DB_RDONLY,0644 ) )
212cdf0e10cSrcweir                 {
213cdf0e10cSrcweir                     if( pFile != NULL )
214cdf0e10cSrcweir                         fprintf( pFile, "Cannot open database\n" );
215cdf0e10cSrcweir 
216cdf0e10cSrcweir                     break;
217cdf0e10cSrcweir                 }
218cdf0e10cSrcweir             }
219cdf0e10cSrcweir 
220cdf0e10cSrcweir             Dbt key( static_cast< void* >( const_cast< sal_Char* >( aKeyStr.getStr() ) ), aKeyStr.getLength() );
221cdf0e10cSrcweir             int err = tableTest.get( 0, &key, &data, 0 );
222cdf0e10cSrcweir             if( err == 0 )
223cdf0e10cSrcweir             {
224cdf0e10cSrcweir                 bTestSuccess = true;
225cdf0e10cSrcweir                 pTestReadData = static_cast< sal_Char* >( data.get_data() );
226cdf0e10cSrcweir                 nTestReadDataSize = data.get_size();
227cdf0e10cSrcweir             }
228cdf0e10cSrcweir         }
229cdf0e10cSrcweir         else
230cdf0e10cSrcweir         {
231cdf0e10cSrcweir             bTestSuccess = getValueForKey( aKeyStr, aDBData );
232cdf0e10cSrcweir             if( bTestSuccess )
233cdf0e10cSrcweir             {
234cdf0e10cSrcweir                 pTestReadData = aDBData.getData();
235cdf0e10cSrcweir                 nTestReadDataSize = aDBData.getSize();
236cdf0e10cSrcweir             }
237cdf0e10cSrcweir         }
238cdf0e10cSrcweir         if( bFirst )
239cdf0e10cSrcweir         {
240cdf0e10cSrcweir             afterfirsttime = osl_getGlobalTimer();
241cdf0e10cSrcweir             bFirst = false;
242cdf0e10cSrcweir         }
243cdf0e10cSrcweir         int nError = 0;
244cdf0e10cSrcweir         if( bTestSuccess && pTestReadData != NULL )
245cdf0e10cSrcweir         {
246cdf0e10cSrcweir             int nCmp = memcmp( ptr, pTestReadData, nValueLen );
247cdf0e10cSrcweir             if( nCmp == 0 )
248cdf0e10cSrcweir                 ++nOkCount;
249cdf0e10cSrcweir             else
250cdf0e10cSrcweir                 nError = 1;
251cdf0e10cSrcweir 
252cdf0e10cSrcweir             if( nValueLen != nTestReadDataSize )
253cdf0e10cSrcweir                 nError = 2;
254cdf0e10cSrcweir         }
255cdf0e10cSrcweir         else
256cdf0e10cSrcweir             nError = 3;
257cdf0e10cSrcweir 
258cdf0e10cSrcweir         if( nError != 0 )
259cdf0e10cSrcweir         {
260cdf0e10cSrcweir             bSuccess = false;
261cdf0e10cSrcweir             ++nErrCount;
262cdf0e10cSrcweir 
263cdf0e10cSrcweir             if( pFile != NULL )
264cdf0e10cSrcweir             {
265cdf0e10cSrcweir                 fprintf( pFile, "ERROR, not found:\n" );
266cdf0e10cSrcweir                 testWriteKeyValue( pFile, rKeyValPair );
267cdf0e10cSrcweir                 fprintf( pFile, "\nError Code: %d\n", nError );
268cdf0e10cSrcweir             }
269cdf0e10cSrcweir         }
270cdf0e10cSrcweir     }
271cdf0e10cSrcweir     tableTest.close( 0 );
272cdf0e10cSrcweir 
273cdf0e10cSrcweir     sal_uInt32 endtime = osl_getGlobalTimer();
274cdf0e10cSrcweir     double dDiffTime = (endtime-starttime) / 1000.0;
275cdf0e10cSrcweir     double dDiffFirstTime = (afterfirsttime-starttime) / 1000.0;
276cdf0e10cSrcweir     if( pFile != NULL )
277cdf0e10cSrcweir     {
278cdf0e10cSrcweir         int nCount = avKeyValPair.size();
279cdf0e10cSrcweir         fprintf( pFile, "%d key/values in total, read %d correctly, %d errors\n",
280cdf0e10cSrcweir             nCount, nOkCount, nErrCount );
281cdf0e10cSrcweir         fprintf( pFile, "Time taken: %g s (First access %g s)\n", dDiffTime, dDiffFirstTime );
282cdf0e10cSrcweir         fprintf( pFile, "Average time per access: %g s\n", dDiffTime / nCount );
283cdf0e10cSrcweir     }
284cdf0e10cSrcweir 
285cdf0e10cSrcweir     if( pFile != NULL )
286cdf0e10cSrcweir         fclose( pFile );
287cdf0e10cSrcweir 
288cdf0e10cSrcweir     return bSuccess;
289cdf0e10cSrcweir }
290cdf0e10cSrcweir 
291cdf0e10cSrcweir #endif
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 
294cdf0e10cSrcweir void DBHelp::createHashMap( bool bOptimizeForPerformance )
295cdf0e10cSrcweir {
296cdf0e10cSrcweir     releaseHashMap();
297cdf0e10cSrcweir     if( bOptimizeForPerformance )
298cdf0e10cSrcweir     {
299cdf0e10cSrcweir         if( m_pStringToDataMap != NULL )
300cdf0e10cSrcweir             return;
301cdf0e10cSrcweir         m_pStringToDataMap = new StringToDataMap();
302cdf0e10cSrcweir     }
303cdf0e10cSrcweir     else
304cdf0e10cSrcweir     {
305cdf0e10cSrcweir         if( m_pStringToValPosMap != NULL )
306cdf0e10cSrcweir             return;
307cdf0e10cSrcweir         m_pStringToValPosMap = new StringToValPosMap();
308cdf0e10cSrcweir     }
309cdf0e10cSrcweir 
310cdf0e10cSrcweir     Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL );
311cdf0e10cSrcweir     if( xIn.is() )
312cdf0e10cSrcweir     {
313cdf0e10cSrcweir         Sequence< sal_Int8 > aData;
314cdf0e10cSrcweir         sal_Int32 nSize = m_xSFA->getSize( m_aFileURL );
315cdf0e10cSrcweir         sal_Int32 nRead = xIn->readBytes( aData, nSize );
316cdf0e10cSrcweir 
317cdf0e10cSrcweir         const char* pData = (const char*)aData.getConstArray();
318cdf0e10cSrcweir         int iPos = 0;
319cdf0e10cSrcweir         while( iPos < nRead )
320cdf0e10cSrcweir         {
321cdf0e10cSrcweir             DBData aDBKey;
322cdf0e10cSrcweir             if( !implReadLenAndData( pData, iPos, aDBKey ) )
323cdf0e10cSrcweir                 break;
324cdf0e10cSrcweir 
325cdf0e10cSrcweir             rtl::OString aOKeyStr = aDBKey.getData();
326cdf0e10cSrcweir 
327cdf0e10cSrcweir             // Read val len
328cdf0e10cSrcweir             const char* pStartPtr = pData + iPos;
329cdf0e10cSrcweir             char* pEndPtr;
330cdf0e10cSrcweir             sal_Int32 nValLen = strtol( pStartPtr, &pEndPtr, 16 );
331cdf0e10cSrcweir             if( pEndPtr == pStartPtr )
332cdf0e10cSrcweir                 break;
333cdf0e10cSrcweir 
334cdf0e10cSrcweir             iPos += (pEndPtr - pStartPtr) + 1;
335cdf0e10cSrcweir 
336cdf0e10cSrcweir             if( bOptimizeForPerformance )
337cdf0e10cSrcweir             {
338cdf0e10cSrcweir                 const char* pValSrc = pData + iPos;
339cdf0e10cSrcweir                 rtl::OString aValStr( pValSrc, nValLen );
340cdf0e10cSrcweir                 (*m_pStringToDataMap)[aOKeyStr] = aValStr;
341cdf0e10cSrcweir             }
342cdf0e10cSrcweir             else
343cdf0e10cSrcweir             {
344cdf0e10cSrcweir                 // store value start position
345cdf0e10cSrcweir                 (*m_pStringToValPosMap)[aOKeyStr] = std::pair<int,int>( iPos, nValLen );
346cdf0e10cSrcweir             }
347cdf0e10cSrcweir             iPos += nValLen + 1;
348cdf0e10cSrcweir         }
349cdf0e10cSrcweir 
350cdf0e10cSrcweir         xIn->closeInput();
351cdf0e10cSrcweir     }
352cdf0e10cSrcweir }
353cdf0e10cSrcweir 
354cdf0e10cSrcweir void DBHelp::releaseHashMap( void )
355cdf0e10cSrcweir {
356cdf0e10cSrcweir     if( m_pStringToDataMap != NULL )
357cdf0e10cSrcweir     {
358cdf0e10cSrcweir         delete m_pStringToDataMap;
359cdf0e10cSrcweir         m_pStringToDataMap = NULL;
360cdf0e10cSrcweir     }
361cdf0e10cSrcweir     if( m_pStringToValPosMap != NULL )
362cdf0e10cSrcweir     {
363cdf0e10cSrcweir         delete m_pStringToValPosMap;
364cdf0e10cSrcweir         m_pStringToValPosMap = NULL;
365cdf0e10cSrcweir     }
366cdf0e10cSrcweir }
367cdf0e10cSrcweir 
368cdf0e10cSrcweir 
369cdf0e10cSrcweir bool DBHelp::getValueForKey( const rtl::OString& rKey, DBData& rValue )
370cdf0e10cSrcweir {
371cdf0e10cSrcweir     bool bSuccess = false;
372cdf0e10cSrcweir     if( !m_xSFA.is() )
373cdf0e10cSrcweir         return bSuccess;
374cdf0e10cSrcweir 
375cdf0e10cSrcweir     try
376cdf0e10cSrcweir     {
377cdf0e10cSrcweir 
378cdf0e10cSrcweir     if( m_pStringToDataMap == NULL && m_pStringToValPosMap == NULL )
379cdf0e10cSrcweir     {
380cdf0e10cSrcweir         bool bOptimizeForPerformance = false;
381cdf0e10cSrcweir         createHashMap( bOptimizeForPerformance );
382cdf0e10cSrcweir     }
383cdf0e10cSrcweir 
384cdf0e10cSrcweir     if( m_pStringToValPosMap != NULL )
385cdf0e10cSrcweir     {
386cdf0e10cSrcweir         StringToValPosMap::const_iterator it = m_pStringToValPosMap->find( rKey );
387cdf0e10cSrcweir         if( it != m_pStringToValPosMap->end() )
388cdf0e10cSrcweir         {
389cdf0e10cSrcweir             const std::pair<int,int>& rValPair = it->second;
390cdf0e10cSrcweir             int iValuePos = rValPair.first;
391cdf0e10cSrcweir             int nValueLen = rValPair.second;
392cdf0e10cSrcweir 
393cdf0e10cSrcweir             Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL );
394cdf0e10cSrcweir             if( xIn.is() )
395cdf0e10cSrcweir             {
396cdf0e10cSrcweir                 Reference< XSeekable > xXSeekable( xIn, UNO_QUERY );
397cdf0e10cSrcweir                 if( xXSeekable.is() )
398cdf0e10cSrcweir                 {
399cdf0e10cSrcweir                     xXSeekable->seek( iValuePos );
400cdf0e10cSrcweir 
401cdf0e10cSrcweir                     Sequence< sal_Int8 > aData;
402cdf0e10cSrcweir                     sal_Int32 nRead = xIn->readBytes( aData, nValueLen );
403cdf0e10cSrcweir                     if( nRead == nValueLen )
404cdf0e10cSrcweir                     {
405cdf0e10cSrcweir                         const char* pData = (const sal_Char*)aData.getConstArray();
406cdf0e10cSrcweir                         rValue.copyToBuffer( pData, nValueLen );
407cdf0e10cSrcweir                         bSuccess = true;
408cdf0e10cSrcweir                     }
409cdf0e10cSrcweir                 }
410cdf0e10cSrcweir                 xIn->closeInput();
411cdf0e10cSrcweir             }
412cdf0e10cSrcweir         }
413cdf0e10cSrcweir     }
414cdf0e10cSrcweir 
415cdf0e10cSrcweir     else if( m_pStringToDataMap != NULL )
416cdf0e10cSrcweir     {
417cdf0e10cSrcweir         StringToDataMap::const_iterator it = m_pStringToDataMap->find( rKey );
418cdf0e10cSrcweir         if( it != m_pStringToDataMap->end() )
419cdf0e10cSrcweir         {
420cdf0e10cSrcweir             const rtl::OString& rValueStr = it->second;
421cdf0e10cSrcweir             int nValueLen = rValueStr.getLength();
422cdf0e10cSrcweir             const char* pData = rValueStr.getStr();
423cdf0e10cSrcweir             rValue.copyToBuffer( pData, nValueLen );
424cdf0e10cSrcweir             bSuccess = true;
425cdf0e10cSrcweir         }
426cdf0e10cSrcweir     }
427cdf0e10cSrcweir 
428cdf0e10cSrcweir     }
429cdf0e10cSrcweir     catch( Exception & )
430cdf0e10cSrcweir     {
431cdf0e10cSrcweir         bSuccess = false;
432cdf0e10cSrcweir     }
433cdf0e10cSrcweir 
434cdf0e10cSrcweir     return bSuccess;
435cdf0e10cSrcweir }
436cdf0e10cSrcweir 
437cdf0e10cSrcweir bool DBHelp::startIteration( void )
438cdf0e10cSrcweir {
439cdf0e10cSrcweir     bool bSuccess = false;
440cdf0e10cSrcweir 
441cdf0e10cSrcweir     sal_Int32 nSize = m_xSFA->getSize( m_aFileURL );
442cdf0e10cSrcweir 
443cdf0e10cSrcweir     Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL );
444cdf0e10cSrcweir     if( xIn.is() )
445cdf0e10cSrcweir     {
446cdf0e10cSrcweir         m_nItRead = xIn->readBytes( m_aItData, nSize );
447cdf0e10cSrcweir         if( m_nItRead == nSize )
448cdf0e10cSrcweir         {
449cdf0e10cSrcweir             bSuccess = true;
450cdf0e10cSrcweir             m_pItData = (const char*)m_aItData.getConstArray();
451cdf0e10cSrcweir             m_iItPos = 0;
452cdf0e10cSrcweir         }
453cdf0e10cSrcweir         else
454cdf0e10cSrcweir         {
455cdf0e10cSrcweir             stopIteration();
456cdf0e10cSrcweir         }
457cdf0e10cSrcweir     }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir     return bSuccess;
460cdf0e10cSrcweir }
461cdf0e10cSrcweir 
462cdf0e10cSrcweir bool DBHelp::getNextKeyAndValue( DBData& rKey, DBData& rValue )
463cdf0e10cSrcweir {
464cdf0e10cSrcweir     bool bSuccess = false;
465cdf0e10cSrcweir 
466cdf0e10cSrcweir     if( m_iItPos < m_nItRead )
467cdf0e10cSrcweir     {
468cdf0e10cSrcweir         if( implReadLenAndData( m_pItData, m_iItPos, rKey ) )
469cdf0e10cSrcweir         {
470cdf0e10cSrcweir             if( implReadLenAndData( m_pItData, m_iItPos, rValue ) )
471cdf0e10cSrcweir                 bSuccess = true;
472cdf0e10cSrcweir         }
473cdf0e10cSrcweir     }
474cdf0e10cSrcweir 
475cdf0e10cSrcweir     return bSuccess;
476cdf0e10cSrcweir }
477cdf0e10cSrcweir 
478cdf0e10cSrcweir void DBHelp::stopIteration( void )
479cdf0e10cSrcweir {
480cdf0e10cSrcweir     m_aItData = Sequence<sal_Int8>();
481cdf0e10cSrcweir     m_pItData = NULL;
482cdf0e10cSrcweir     m_nItRead = -1;
483cdf0e10cSrcweir     m_iItPos = -1;
484cdf0e10cSrcweir }
485cdf0e10cSrcweir 
486cdf0e10cSrcweir 
487cdf0e10cSrcweir Db::Db()
488cdf0e10cSrcweir {
489cdf0e10cSrcweir     db_internal::check_error( db_create(&m_pDBP,0,0),"Db::Db" );
490cdf0e10cSrcweir     m_pDBHelp = NULL;
491cdf0e10cSrcweir }
492cdf0e10cSrcweir 
493cdf0e10cSrcweir 
494cdf0e10cSrcweir Db::~Db()
495cdf0e10cSrcweir {
496cdf0e10cSrcweir     if (m_pDBP)
497cdf0e10cSrcweir     {
498cdf0e10cSrcweir         // should not happen
499cdf0e10cSrcweir         // TODO: add assert
500cdf0e10cSrcweir     }
501cdf0e10cSrcweir 
502cdf0e10cSrcweir     delete m_pDBHelp;
503cdf0e10cSrcweir }
504cdf0e10cSrcweir 
505cdf0e10cSrcweir 
506cdf0e10cSrcweir int Db::close(u_int32_t flags)
507cdf0e10cSrcweir {
508cdf0e10cSrcweir     int error = m_pDBP->close(m_pDBP,flags);
509cdf0e10cSrcweir     m_pDBP = 0;
510cdf0e10cSrcweir     return db_internal::check_error(error,"Db::close");
511cdf0e10cSrcweir }
512cdf0e10cSrcweir 
513cdf0e10cSrcweir int Db::open(DB_TXN *txnid,
514cdf0e10cSrcweir              const char *file,
515cdf0e10cSrcweir              const char *database,
516cdf0e10cSrcweir              DBTYPE type,
517cdf0e10cSrcweir              u_int32_t flags,
518cdf0e10cSrcweir              int mode)
519cdf0e10cSrcweir {
520cdf0e10cSrcweir     int err = m_pDBP->open(m_pDBP,txnid,file,database,type,flags,mode);
521cdf0e10cSrcweir     return db_internal::check_error( err,"Db::open" );
522cdf0e10cSrcweir }
523cdf0e10cSrcweir 
524cdf0e10cSrcweir int Db::open(DB_TXN *txnid,
525cdf0e10cSrcweir              ::rtl::OUString const & fileURL,
526cdf0e10cSrcweir              DBTYPE type,
527cdf0e10cSrcweir              u_int32_t flags,
528cdf0e10cSrcweir              int mode)
529cdf0e10cSrcweir {
530cdf0e10cSrcweir     ::rtl::OUString ouPath;
531cdf0e10cSrcweir     ::osl::FileBase::getSystemPathFromFileURL(fileURL, ouPath);
532cdf0e10cSrcweir     const ::rtl::OString sPath = ::rtl::OUStringToOString(ouPath, osl_getThreadTextEncoding());
533cdf0e10cSrcweir     return open(txnid, sPath.getStr(), 0, type, flags, mode);
534cdf0e10cSrcweir }
535cdf0e10cSrcweir 
536cdf0e10cSrcweir 
537cdf0e10cSrcweir 
538cdf0e10cSrcweir int Db::get(DB_TXN *txnid, Dbt *key, Dbt *data, u_int32_t flags)
539cdf0e10cSrcweir {
540cdf0e10cSrcweir     int err = m_pDBP->get(m_pDBP,txnid,key,data,flags);
541cdf0e10cSrcweir 
542cdf0e10cSrcweir     // these are non-exceptional outcomes
543cdf0e10cSrcweir     if (err != DB_NOTFOUND && err != DB_KEYEMPTY)
544cdf0e10cSrcweir         db_internal::check_error( err,"Db::get" );
545cdf0e10cSrcweir 
546cdf0e10cSrcweir     return err;
547cdf0e10cSrcweir }
548cdf0e10cSrcweir 
549cdf0e10cSrcweir int Db::cursor(DB_TXN *txnid, Dbc **cursorp, u_int32_t flags)
550cdf0e10cSrcweir {
551cdf0e10cSrcweir     DBC * dbc = 0;
552cdf0e10cSrcweir     int error = m_pDBP->cursor(m_pDBP,txnid,&dbc,flags);
553cdf0e10cSrcweir 
554cdf0e10cSrcweir     if (!db_internal::check_error(error,"Db::cursor"))
555cdf0e10cSrcweir         *cursorp = new Dbc(dbc);
556cdf0e10cSrcweir 
557cdf0e10cSrcweir     return error;
558cdf0e10cSrcweir }
559cdf0e10cSrcweir 
560cdf0e10cSrcweir //----------------------------------------------------------------------------
561cdf0e10cSrcweir 
562cdf0e10cSrcweir Dbc::Dbc(DBC * dbc)
563cdf0e10cSrcweir : m_pDBC(dbc)
564cdf0e10cSrcweir {
565cdf0e10cSrcweir }
566cdf0e10cSrcweir 
567cdf0e10cSrcweir Dbc::~Dbc()
568cdf0e10cSrcweir {
569cdf0e10cSrcweir }
570cdf0e10cSrcweir 
571cdf0e10cSrcweir int Dbc::close()
572cdf0e10cSrcweir {
573cdf0e10cSrcweir     int err = m_pDBC->c_close(m_pDBC);
574cdf0e10cSrcweir     delete this;
575cdf0e10cSrcweir     return db_internal::check_error( err,"Dbcursor::close" );
576cdf0e10cSrcweir }
577cdf0e10cSrcweir 
578cdf0e10cSrcweir int Dbc::get(Dbt *key, Dbt *data, u_int32_t flags)
579cdf0e10cSrcweir {
580cdf0e10cSrcweir     int err = m_pDBC->c_get(m_pDBC,key,data,flags);
581cdf0e10cSrcweir 
582cdf0e10cSrcweir     // these are non-exceptional outcomes
583cdf0e10cSrcweir     if (err != DB_NOTFOUND && err != DB_KEYEMPTY)
584cdf0e10cSrcweir         db_internal::check_error( err, "Dbcursor::get" );
585cdf0e10cSrcweir 
586cdf0e10cSrcweir     return err;
587cdf0e10cSrcweir }
588cdf0e10cSrcweir 
589cdf0e10cSrcweir //----------------------------------------------------------------------------
590cdf0e10cSrcweir 
591cdf0e10cSrcweir 
592cdf0e10cSrcweir Dbt::Dbt()
593cdf0e10cSrcweir {
594cdf0e10cSrcweir     using namespace std;
595cdf0e10cSrcweir     DBT * thispod = this;
596cdf0e10cSrcweir     memset(thispod, 0, sizeof *thispod);
597cdf0e10cSrcweir }
598cdf0e10cSrcweir 
599cdf0e10cSrcweir 
600cdf0e10cSrcweir Dbt::Dbt(void *data_arg, u_int32_t size_arg)
601cdf0e10cSrcweir {
602cdf0e10cSrcweir     using namespace std;
603cdf0e10cSrcweir     DBT * thispod = this;
604cdf0e10cSrcweir     memset(thispod, 0, sizeof *thispod);
605cdf0e10cSrcweir     this->set_data(data_arg);
606cdf0e10cSrcweir     this->set_size(size_arg);
607cdf0e10cSrcweir }
608cdf0e10cSrcweir 
609cdf0e10cSrcweir /*
610cdf0e10cSrcweir Dbt::Dbt(const Dbt & other)
611cdf0e10cSrcweir {
612cdf0e10cSrcweir     using namespace std;
613cdf0e10cSrcweir     const DBT *otherpod = &other;
614cdf0e10cSrcweir     DBT *thispod = this;
615cdf0e10cSrcweir     memcpy(thispod, otherpod, sizeof *thispod);
616cdf0e10cSrcweir }
617cdf0e10cSrcweir 
618cdf0e10cSrcweir Dbt& Dbt::operator = (const Dbt & other)
619cdf0e10cSrcweir {
620cdf0e10cSrcweir     if (this != &other)
621cdf0e10cSrcweir     {
622cdf0e10cSrcweir         using namespace std;
623cdf0e10cSrcweir         const DBT *otherpod = &other;
624cdf0e10cSrcweir         DBT *thispod = this;
625cdf0e10cSrcweir         memcpy(thispod, otherpod, sizeof *thispod);
626cdf0e10cSrcweir     }
627cdf0e10cSrcweir     return *this;
628cdf0e10cSrcweir }
629cdf0e10cSrcweir */
630cdf0e10cSrcweir 
631cdf0e10cSrcweir Dbt::~Dbt()
632cdf0e10cSrcweir {
633cdf0e10cSrcweir }
634cdf0e10cSrcweir 
635cdf0e10cSrcweir void * Dbt::get_data() const
636cdf0e10cSrcweir {
637cdf0e10cSrcweir     return this->data;
638cdf0e10cSrcweir }
639cdf0e10cSrcweir 
640cdf0e10cSrcweir void Dbt::set_data(void *value)
641cdf0e10cSrcweir {
642cdf0e10cSrcweir     this->data = value;
643cdf0e10cSrcweir }
644cdf0e10cSrcweir 
645cdf0e10cSrcweir u_int32_t Dbt::get_size() const
646cdf0e10cSrcweir {
647cdf0e10cSrcweir     return this->size;
648cdf0e10cSrcweir }
649cdf0e10cSrcweir 
650cdf0e10cSrcweir void Dbt::set_size(u_int32_t value)
651cdf0e10cSrcweir {
652cdf0e10cSrcweir     this->size = value;
653cdf0e10cSrcweir }
654cdf0e10cSrcweir 
655cdf0e10cSrcweir void Dbt::set_flags(u_int32_t value)
656cdf0e10cSrcweir {
657cdf0e10cSrcweir     this->flags = value;
658cdf0e10cSrcweir }
659cdf0e10cSrcweir 
660cdf0e10cSrcweir //----------------------------------------------------------------------------
661cdf0e10cSrcweir /*
662cdf0e10cSrcweir void db_internal::raise_error(int dberr, const char * where)
663cdf0e10cSrcweir {
664cdf0e10cSrcweir     if (!where) where = "<unknown>";
665cdf0e10cSrcweir 
666cdf0e10cSrcweir     const char * dberrmsg = db_strerror(dberr);
667cdf0e10cSrcweir     if (!dberrmsg || !*dberrmsg) dberrmsg = "<unknown DB error>";
668cdf0e10cSrcweir 
669cdf0e10cSrcweir     rtl::OString msg = where;
670cdf0e10cSrcweir     msg += ": ";
671cdf0e10cSrcweir     msg += dberrmsg;
672cdf0e10cSrcweir 
673cdf0e10cSrcweir     throw DbException(msg);
674cdf0e10cSrcweir }
675cdf0e10cSrcweir */
676cdf0e10cSrcweir 
677cdf0e10cSrcweir //----------------------------------------------------------------------------
678cdf0e10cSrcweir } // namespace ecomp
679cdf0e10cSrcweir 
680