xref: /AOO41X/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