Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "db.hxx"
31 : :
32 : : #include <rtl/alloc.h>
33 : : #include <cstring>
34 : :
35 : : #include "com/sun/star/io/XSeekable.hpp"
36 : :
37 : : #include "osl/file.hxx"
38 : : #include "osl/thread.hxx"
39 : : using namespace com::sun::star;
40 : : using namespace com::sun::star::uno;
41 : : using namespace com::sun::star::io;
42 : :
43 : : namespace berkeleydbproxy {
44 : :
45 : : //----------------------------------------------------------------------------
46 : : namespace db_internal
47 : : {
48 : 24 : static inline int check_error(int dberr, const char * where)
49 : : {
50 : : (void)where;
51 : 24 : return dberr;
52 : : }
53 : : }
54 : :
55 : 54096 : void DBData::copyToBuffer( const char* pSrcData, int nSize )
56 : : {
57 : 54096 : m_nSize = nSize;
58 [ - + ]: 54096 : delete [] m_pBuffer;
59 : 54096 : m_pBuffer = new char[m_nSize+1];
60 : 54096 : memcpy( m_pBuffer, pSrcData, m_nSize );
61 : 54096 : m_pBuffer[m_nSize] = 0;
62 : 54096 : }
63 : :
64 : :
65 : : // DBHelp
66 : :
67 : 53908 : bool DBHelp::implReadLenAndData( const char* pData, int& riPos, DBData& rValue )
68 : : {
69 : 53908 : bool bSuccess = false;
70 : :
71 : : // Read key len
72 : 53908 : const char* pStartPtr = pData + riPos;
73 : : char* pEndPtr;
74 : 53908 : sal_Int32 nKeyLen = strtol( pStartPtr, &pEndPtr, 16 );
75 [ - + ]: 53908 : if( pEndPtr == pStartPtr )
76 : 0 : return bSuccess;
77 : 53908 : riPos += (pEndPtr - pStartPtr) + 1;
78 : :
79 : 53908 : const char* pKeySrc = pData + riPos;
80 [ + - ]: 53908 : rValue.copyToBuffer( pKeySrc, nKeyLen );
81 : 53908 : riPos += nKeyLen + 1;
82 : :
83 : 53908 : bSuccess = true;
84 : 53908 : return bSuccess;
85 : : }
86 : :
87 : 12 : void DBHelp::createHashMap( bool bOptimizeForPerformance )
88 : : {
89 [ + - ]: 12 : releaseHashMap();
90 [ - + ]: 12 : if( bOptimizeForPerformance )
91 : : {
92 [ # # ]: 0 : if( m_pStringToDataMap != NULL )
93 : : return;
94 [ # # ][ # # ]: 0 : m_pStringToDataMap = new StringToDataMap();
95 : : }
96 : : else
97 : : {
98 [ + - ]: 12 : if( m_pStringToValPosMap != NULL )
99 : : return;
100 [ + - ][ + - ]: 12 : m_pStringToValPosMap = new StringToValPosMap();
101 : : }
102 : :
103 [ + - ][ + - ]: 12 : Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL );
104 [ + - ]: 12 : if( xIn.is() )
105 : : {
106 [ + - ]: 12 : Sequence< sal_Int8 > aData;
107 [ + - ][ + - ]: 12 : sal_Int32 nSize = m_xSFA->getSize( m_aFileURL );
108 [ + - ][ + - ]: 12 : sal_Int32 nRead = xIn->readBytes( aData, nSize );
109 : :
110 : 12 : const char* pData = (const char*)aData.getConstArray();
111 : 12 : int iPos = 0;
112 [ + + ]: 53920 : while( iPos < nRead )
113 : : {
114 : 53908 : DBData aDBKey;
115 [ - + ][ + - ]: 53908 : if( !implReadLenAndData( pData, iPos, aDBKey ) )
116 : : break;
117 : :
118 : 53908 : rtl::OString aOKeyStr = aDBKey.getData();
119 : :
120 : : // Read val len
121 : 53908 : const char* pStartPtr = pData + iPos;
122 : : char* pEndPtr;
123 : 53908 : sal_Int32 nValLen = strtol( pStartPtr, &pEndPtr, 16 );
124 [ - + ]: 53908 : if( pEndPtr == pStartPtr )
125 : : break;
126 : :
127 : 53908 : iPos += (pEndPtr - pStartPtr) + 1;
128 : :
129 [ - + ]: 53908 : if( bOptimizeForPerformance )
130 : : {
131 : 0 : const char* pValSrc = pData + iPos;
132 : 0 : rtl::OString aValStr( pValSrc, nValLen );
133 [ # # ]: 0 : (*m_pStringToDataMap)[aOKeyStr] = aValStr;
134 : : }
135 : : else
136 : : {
137 : : // store value start position
138 [ + - ][ + - ]: 53908 : (*m_pStringToValPosMap)[aOKeyStr] = std::pair<int,int>( iPos, nValLen );
139 : : }
140 [ - + ]: 107816 : iPos += nValLen + 1;
141 [ + - ]: 107816 : }
142 : :
143 [ + - ][ + - ]: 12 : xIn->closeInput();
[ + - ]
144 : 12 : }
145 : : }
146 : :
147 : 24 : void DBHelp::releaseHashMap( void )
148 : : {
149 [ - + ]: 24 : if( m_pStringToDataMap != NULL )
150 : : {
151 [ # # ]: 0 : delete m_pStringToDataMap;
152 : 0 : m_pStringToDataMap = NULL;
153 : : }
154 [ + + ]: 24 : if( m_pStringToValPosMap != NULL )
155 : : {
156 [ + - ]: 12 : delete m_pStringToValPosMap;
157 : 12 : m_pStringToValPosMap = NULL;
158 : : }
159 : 24 : }
160 : :
161 : :
162 : 404 : bool DBHelp::getValueForKey( const rtl::OString& rKey, DBData& rValue )
163 : : {
164 : 404 : bool bSuccess = false;
165 [ - + ]: 404 : if( !m_xSFA.is() )
166 : 0 : return bSuccess;
167 : :
168 : : try
169 : : {
170 : :
171 [ + - ][ + + ]: 404 : if( m_pStringToDataMap == NULL && m_pStringToValPosMap == NULL )
172 : : {
173 : 12 : bool bOptimizeForPerformance = false;
174 [ + - ]: 12 : createHashMap( bOptimizeForPerformance );
175 : : }
176 : :
177 [ + - ]: 404 : if( m_pStringToValPosMap != NULL )
178 : : {
179 [ + - ]: 404 : StringToValPosMap::const_iterator it = m_pStringToValPosMap->find( rKey );
180 [ + + ][ + - ]: 404 : if( it != m_pStringToValPosMap->end() )
181 : : {
182 [ + - ]: 188 : const std::pair<int,int>& rValPair = it->second;
183 : 188 : int iValuePos = rValPair.first;
184 : 188 : int nValueLen = rValPair.second;
185 : :
186 [ + - ][ + - ]: 188 : Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL );
187 [ + - ]: 188 : if( xIn.is() )
188 : : {
189 [ + - ]: 188 : Reference< XSeekable > xXSeekable( xIn, UNO_QUERY );
190 [ + - ]: 188 : if( xXSeekable.is() )
191 : : {
192 [ + - ][ + - ]: 188 : xXSeekable->seek( iValuePos );
193 : :
194 [ + - ]: 188 : Sequence< sal_Int8 > aData;
195 [ + - ][ + - ]: 188 : sal_Int32 nRead = xIn->readBytes( aData, nValueLen );
196 [ + - ]: 188 : if( nRead == nValueLen )
197 : : {
198 : 188 : const char* pData = (const sal_Char*)aData.getConstArray();
199 [ + - ]: 188 : rValue.copyToBuffer( pData, nValueLen );
200 : 188 : bSuccess = true;
201 [ + - ]: 188 : }
202 : : }
203 [ + - ][ + - ]: 188 : xIn->closeInput();
204 [ # # ]: 404 : }
205 : : }
206 : : }
207 : :
208 [ # # ]: 0 : else if( m_pStringToDataMap != NULL )
209 : : {
210 [ # # ]: 0 : StringToDataMap::const_iterator it = m_pStringToDataMap->find( rKey );
211 [ # # ][ # # ]: 0 : if( it != m_pStringToDataMap->end() )
212 : : {
213 [ # # ]: 0 : const rtl::OString& rValueStr = it->second;
214 : 0 : int nValueLen = rValueStr.getLength();
215 : 0 : const char* pData = rValueStr.getStr();
216 [ # # ]: 0 : rValue.copyToBuffer( pData, nValueLen );
217 : 0 : bSuccess = true;
218 : : }
219 : : }
220 : :
221 : : }
222 : 0 : catch( Exception & )
223 : : {
224 : 0 : bSuccess = false;
225 : : }
226 : :
227 : 404 : return bSuccess;
228 : : }
229 : :
230 : 0 : bool DBHelp::startIteration( void )
231 : : {
232 : 0 : bool bSuccess = false;
233 : :
234 [ # # ][ # # ]: 0 : sal_Int32 nSize = m_xSFA->getSize( m_aFileURL );
235 : :
236 [ # # ][ # # ]: 0 : Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileURL );
237 [ # # ]: 0 : if( xIn.is() )
238 : : {
239 [ # # ][ # # ]: 0 : m_nItRead = xIn->readBytes( m_aItData, nSize );
240 [ # # ]: 0 : if( m_nItRead == nSize )
241 : : {
242 : 0 : bSuccess = true;
243 : 0 : m_pItData = (const char*)m_aItData.getConstArray();
244 : 0 : m_iItPos = 0;
245 : : }
246 : : else
247 : : {
248 [ # # ]: 0 : stopIteration();
249 : : }
250 : : }
251 : :
252 : 0 : return bSuccess;
253 : : }
254 : :
255 : 0 : bool DBHelp::getNextKeyAndValue( DBData& rKey, DBData& rValue )
256 : : {
257 : 0 : bool bSuccess = false;
258 : :
259 [ # # ]: 0 : if( m_iItPos < m_nItRead )
260 : : {
261 [ # # ]: 0 : if( implReadLenAndData( m_pItData, m_iItPos, rKey ) )
262 : : {
263 [ # # ]: 0 : if( implReadLenAndData( m_pItData, m_iItPos, rValue ) )
264 : 0 : bSuccess = true;
265 : : }
266 : : }
267 : :
268 : 0 : return bSuccess;
269 : : }
270 : :
271 : 0 : void DBHelp::stopIteration( void )
272 : : {
273 [ # # ]: 0 : m_aItData = Sequence<sal_Int8>();
274 : 0 : m_pItData = NULL;
275 : 0 : m_nItRead = -1;
276 : 0 : m_iItPos = -1;
277 : 0 : }
278 : :
279 : :
280 : 12 : Db::Db()
281 : : {
282 [ + - ]: 12 : db_internal::check_error( db_create(&m_pDBP,0,0),"Db::Db" );
283 : 12 : m_pDBHelp = NULL;
284 : 12 : }
285 : :
286 : :
287 : 12 : Db::~Db()
288 : : {
289 : 12 : if (m_pDBP)
290 : : {
291 : : // should not happen
292 : : // TODO: add assert
293 : : }
294 : :
295 [ + - ][ + - ]: 12 : delete m_pDBHelp;
296 : 12 : }
297 : :
298 : :
299 : 12 : int Db::close(u_int32_t flags)
300 : : {
301 : 12 : int error = m_pDBP->close(m_pDBP,flags);
302 : 12 : m_pDBP = 0;
303 : 12 : return db_internal::check_error(error,"Db::close");
304 : : }
305 : :
306 : 0 : int Db::open(DB_TXN *txnid,
307 : : const char *file,
308 : : const char *database,
309 : : DBTYPE type,
310 : : u_int32_t flags,
311 : : int mode)
312 : : {
313 : 0 : int err = m_pDBP->open(m_pDBP,txnid,file,database,type,flags,mode);
314 : 0 : return db_internal::check_error( err,"Db::open" );
315 : : }
316 : :
317 : 0 : int Db::open(DB_TXN *txnid,
318 : : ::rtl::OUString const & fileURL,
319 : : DBTYPE type,
320 : : u_int32_t flags,
321 : : int mode)
322 : : {
323 : 0 : ::rtl::OUString ouPath;
324 [ # # ]: 0 : ::osl::FileBase::getSystemPathFromFileURL(fileURL, ouPath);
325 [ # # ][ # # ]: 0 : const ::rtl::OString sPath = ::rtl::OUStringToOString(ouPath, osl_getThreadTextEncoding());
326 [ # # ]: 0 : return open(txnid, sPath.getStr(), 0, type, flags, mode);
327 : : }
328 : :
329 : :
330 : :
331 : 0 : int Db::get(DB_TXN *txnid, Dbt *key, Dbt *data, u_int32_t flags)
332 : : {
333 : 0 : int err = m_pDBP->get(m_pDBP,txnid,key,data,flags);
334 : :
335 : : // these are non-exceptional outcomes
336 [ # # ][ # # ]: 0 : if (err != DB_NOTFOUND && err != DB_KEYEMPTY)
337 : 0 : db_internal::check_error( err,"Db::get" );
338 : :
339 : 0 : return err;
340 : : }
341 : :
342 : 0 : int Db::cursor(DB_TXN *txnid, Dbc **cursorp, u_int32_t flags)
343 : : {
344 : 0 : DBC * dbc = 0;
345 [ # # ]: 0 : int error = m_pDBP->cursor(m_pDBP,txnid,&dbc,flags);
346 : :
347 [ # # ]: 0 : if (!db_internal::check_error(error,"Db::cursor"))
348 [ # # ]: 0 : *cursorp = new Dbc(dbc);
349 : :
350 : 0 : return error;
351 : : }
352 : :
353 : : //----------------------------------------------------------------------------
354 : :
355 : 0 : Dbc::Dbc(DBC * dbc)
356 : 0 : : m_pDBC(dbc)
357 : : {
358 : 0 : }
359 : :
360 : 0 : Dbc::~Dbc()
361 : : {
362 : 0 : }
363 : :
364 : 0 : int Dbc::close()
365 : : {
366 : 0 : int err = m_pDBC->c_close(m_pDBC);
367 [ # # ]: 0 : delete this;
368 : 0 : return db_internal::check_error( err,"Dbcursor::close" );
369 : : }
370 : :
371 : 0 : int Dbc::get(Dbt *key, Dbt *data, u_int32_t flags)
372 : : {
373 : 0 : int err = m_pDBC->c_get(m_pDBC,key,data,flags);
374 : :
375 : : // these are non-exceptional outcomes
376 [ # # ][ # # ]: 0 : if (err != DB_NOTFOUND && err != DB_KEYEMPTY)
377 : 0 : db_internal::check_error( err, "Dbcursor::get" );
378 : :
379 : 0 : return err;
380 : : }
381 : :
382 : : //----------------------------------------------------------------------------
383 : :
384 : :
385 : 576 : Dbt::Dbt()
386 : : {
387 : : using namespace std;
388 : 576 : DBT * thispod = this;
389 : 576 : memset(thispod, 0, sizeof *thispod);
390 : 576 : }
391 : :
392 : :
393 : 106 : Dbt::Dbt(void *data_arg, u_int32_t size_arg)
394 : : {
395 : : using namespace std;
396 : 106 : DBT * thispod = this;
397 : 106 : memset(thispod, 0, sizeof *thispod);
398 : 106 : this->set_data(data_arg);
399 : 106 : this->set_size(size_arg);
400 : 106 : }
401 : :
402 : 682 : Dbt::~Dbt()
403 : : {
404 : 682 : }
405 : :
406 : 0 : void * Dbt::get_data() const
407 : : {
408 : 0 : return this->data;
409 : : }
410 : :
411 : 106 : void Dbt::set_data(void *value)
412 : : {
413 : 106 : this->data = value;
414 : 106 : }
415 : :
416 : 0 : u_int32_t Dbt::get_size() const
417 : : {
418 : 0 : return this->size;
419 : : }
420 : :
421 : 106 : void Dbt::set_size(u_int32_t value)
422 : : {
423 : 106 : this->size = value;
424 : 106 : }
425 : :
426 : 0 : void Dbt::set_flags(u_int32_t value)
427 : : {
428 : 0 : this->flags = value;
429 : 0 : }
430 : :
431 : : } // namespace ecomp
432 : :
433 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|