merged tag ooo/DEV300_m102
[LibreOffice.git] / desktop / source / deployment / dp_persmap.cxx
blobd93c5a52c782ec608bc1ea7e72a480029cde02f6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_desktop.hxx"
31 #include "dp_misc.h"
32 #include "dp_ucb.h"
33 #include "dp_persmap.h"
34 #include "rtl/strbuf.hxx"
35 #include "rtl/ustrbuf.hxx"
36 #include "osl/file.hxx"
37 #include "osl/thread.h"
40 using namespace ::com::sun::star;
41 using namespace ::com::sun::star::uno;
42 using namespace ::rtl;
43 using ::osl::File;
45 namespace dp_misc
48 //______________________________________________________________________________
49 void PersistentMap::throw_rtexc( int err, char const * pmsg ) const
51 OUStringBuffer buf;
52 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[") );
53 buf.append( m_sysPath );
54 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] Berkeley Db error (") );
55 buf.append( static_cast<sal_Int32>(err) );
56 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("): ") );
57 if (pmsg == 0)
58 pmsg = DbEnv::strerror(err);
59 const OString msg(pmsg);
60 buf.append( OUString( msg.getStr(), msg.getLength(),
61 osl_getThreadTextEncoding() ) );
62 const OUString msg_(buf.makeStringAndClear());
63 OSL_ENSURE( 0, rtl::OUStringToOString(
64 msg_, RTL_TEXTENCODING_UTF8 ).getStr() );
65 throw RuntimeException( msg_, Reference<XInterface>() );
68 //______________________________________________________________________________
69 PersistentMap::~PersistentMap()
71 try {
72 m_db.close(0);
74 catch (DbException & exc) {
75 (void) exc; // avoid warnings
76 OSL_ENSURE( 0, DbEnv::strerror( exc.get_errno() ) );
80 //______________________________________________________________________________
81 PersistentMap::PersistentMap( OUString const & url_, bool readOnly )
82 : m_db( 0, 0 )
84 try {
85 OUString url( expandUnoRcUrl(url_) );
86 if ( File::getSystemPathFromFileURL( url, m_sysPath ) != File::E_None )
88 OSL_ASSERT( false );
90 OString cstr_sysPath(
91 OUStringToOString( m_sysPath, RTL_TEXTENCODING_UTF8 ) );
92 char const * pcstr_sysPath = cstr_sysPath.getStr();
94 u_int32_t flags = DB_CREATE;
95 if (readOnly) {
96 flags = DB_RDONLY;
97 if (! create_ucb_content(
98 0, url,
99 Reference<com::sun::star::ucb::XCommandEnvironment>(),
100 false /* no throw */ )) {
101 // ignore non-existent file in read-only mode: simulate empty db
102 pcstr_sysPath = 0;
103 flags = DB_CREATE;
107 int err = m_db.open(
108 // xxx todo: DB_THREAD, DB_DBT_MALLOC currently not used
109 0, pcstr_sysPath, 0, DB_HASH, flags/* | DB_THREAD*/, 0664 /* fs mode */ );
110 if (err != 0)
111 throw_rtexc(err);
113 catch (DbException & exc) {
114 throw_rtexc( exc.get_errno(), exc.what() );
118 //______________________________________________________________________________
119 PersistentMap::PersistentMap()
120 : m_db( 0, 0 )
122 try {
123 // xxx todo: DB_THREAD, DB_DBT_MALLOC currently not used
124 int err = m_db.open( 0, 0, 0, DB_HASH, DB_CREATE/* | DB_THREAD*/, 0 );
125 if (err != 0)
126 throw_rtexc(err);
128 catch (DbException & exc) {
129 throw_rtexc( exc.get_errno(), exc.what() );
133 //______________________________________________________________________________
134 bool PersistentMap::has( OString const & key ) const
136 return get( 0, key );
139 //______________________________________________________________________________
140 bool PersistentMap::get( OString * value, OString const & key ) const
142 try {
143 Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
144 Dbt dbData;
145 int err = m_db.get( 0, &dbKey, &dbData, 0 );
146 if (err == DB_NOTFOUND)
147 return false;
148 if (err == 0) {
149 if (value != 0) {
150 *value = OString(
151 static_cast< sal_Char const * >(dbData.get_data()),
152 dbData.get_size() );
154 return true;
156 throw_rtexc(err);
158 catch (DbException & exc) {
159 throw_rtexc( exc.get_errno(), exc.what() );
161 return false; // avoiding warning
164 //______________________________________________________________________________
165 void PersistentMap::put( OString const & key, OString const & value )
167 try {
168 Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
169 Dbt dbData( const_cast< sal_Char * >(
170 value.getStr()), value.getLength() );
171 int err = m_db.put( 0, &dbKey, &dbData, 0 );
172 if (err == 0) {
173 #if OSL_DEBUG_LEVEL > 0
174 OString v;
175 OSL_ASSERT( get( &v, key ) );
176 OSL_ASSERT( v.equals( value ) );
177 #endif
178 err = m_db.sync(0);
180 if (err != 0)
181 throw_rtexc(err);
183 catch (DbException & exc) {
184 throw_rtexc( exc.get_errno(), exc.what() );
188 //______________________________________________________________________________
189 bool PersistentMap::erase( OString const & key, bool flush_immediately )
191 try {
192 Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
193 int err = m_db.del( &dbKey, 0 );
194 if (err == 0) {
195 if (flush_immediately) {
196 err = m_db.sync(0);
197 if (err != 0)
198 throw_rtexc(err);
200 return true;
202 if (err == DB_NOTFOUND)
203 return false;
204 throw_rtexc(err);
206 catch (DbException & exc) {
207 throw_rtexc( exc.get_errno(), exc.what() );
209 return false; // avoiding warning
212 //______________________________________________________________________________
213 t_string2string_map PersistentMap::getEntries() const
215 try {
216 Dbc * pcurs = 0;
217 int err = m_db.cursor( 0, &pcurs, 0 );
218 if (err != 0)
219 throw_rtexc(err);
221 t_string2string_map ret;
222 for (;;) {
223 Dbt dbKey, dbData;
224 err = pcurs->get( &dbKey, &dbData, DB_NEXT );
225 if (err == DB_NOTFOUND)
226 break;
227 if (err != 0)
228 throw_rtexc(err);
230 ::std::pair<t_string2string_map::iterator, bool > insertion(
231 ret.insert( t_string2string_map::value_type(
232 t_string2string_map::value_type(
233 OString( static_cast< sal_Char const * >(
234 dbKey.get_data()),
235 dbKey.get_size() ),
236 OString( static_cast< sal_Char const * >(
237 dbData.get_data()),
238 dbData.get_size() ) ) ) ) );
239 OSL_ASSERT( insertion.second );
241 err = pcurs->close();
242 if (err != 0)
243 throw_rtexc(err);
244 return ret;
246 catch (DbException & exc) {
247 throw_rtexc( exc.get_errno(), exc.what() );
249 return t_string2string_map(); // avoiding warning