Update ooo320-m1
[ooovba.git] / desktop / source / deployment / dp_persmap.cxx
blob43fe8b87f39f02eb815c222b737579d9d45411e7
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dp_persmap.cxx,v $
10 * $Revision: 1.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_desktop.hxx"
34 #include "dp_misc.h"
35 #include "dp_ucb.h"
36 #include "dp_persmap.h"
37 #include "rtl/strbuf.hxx"
38 #include "rtl/ustrbuf.hxx"
39 #include "osl/file.hxx"
40 #include "osl/thread.h"
43 using namespace ::com::sun::star;
44 using namespace ::com::sun::star::uno;
45 using namespace ::rtl;
46 using ::osl::File;
48 namespace dp_misc
51 //______________________________________________________________________________
52 void PersistentMap::throw_rtexc( int err, char const * pmsg ) const
54 OUStringBuffer buf;
55 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[") );
56 buf.append( m_sysPath );
57 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] Berkeley Db error (") );
58 buf.append( static_cast<sal_Int32>(err) );
59 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("): ") );
60 if (pmsg == 0)
61 pmsg = DbEnv::strerror(err);
62 const OString msg(pmsg);
63 buf.append( OUString( msg.getStr(), msg.getLength(),
64 osl_getThreadTextEncoding() ) );
65 const OUString msg_(buf.makeStringAndClear());
66 OSL_ENSURE( 0, rtl::OUStringToOString(
67 msg_, RTL_TEXTENCODING_UTF8 ).getStr() );
68 throw RuntimeException( msg_, Reference<XInterface>() );
71 //______________________________________________________________________________
72 PersistentMap::~PersistentMap()
74 try {
75 m_db.close(0);
77 catch (DbException & exc) {
78 (void) exc; // avoid warnings
79 OSL_ENSURE( 0, DbEnv::strerror( exc.get_errno() ) );
83 //______________________________________________________________________________
84 void PersistentMap::flush() const
86 try {
87 int err = m_db.sync(0);
88 if (err != 0)
89 throw_rtexc(err);
91 catch (DbException & exc) {
92 throw_rtexc( exc.get_errno(), exc.what() );
96 //______________________________________________________________________________
97 PersistentMap::PersistentMap( OUString const & url_, bool readOnly )
98 : m_db( 0, 0 )
100 try {
101 OUString url( expandUnoRcUrl(url_) );
102 if ( File::getSystemPathFromFileURL( url, m_sysPath ) != File::E_None )
104 OSL_ASSERT( false );
106 OString cstr_sysPath(
107 OUStringToOString( m_sysPath, osl_getThreadTextEncoding() ) );
108 char const * pcstr_sysPath = cstr_sysPath.getStr();
110 u_int32_t flags = DB_CREATE;
111 if (readOnly) {
112 flags = DB_RDONLY;
113 if (! create_ucb_content(
114 0, url,
115 Reference<com::sun::star::ucb::XCommandEnvironment>(),
116 false /* no throw */ )) {
117 // ignore non-existent file in read-only mode: simulate empty db
118 pcstr_sysPath = 0;
119 flags = DB_CREATE;
123 int err = m_db.open(
124 // xxx todo: DB_THREAD, DB_DBT_MALLOC currently not used
125 0, pcstr_sysPath, 0, DB_HASH, flags/* | DB_THREAD*/, 0664 /* fs mode */ );
126 if (err != 0)
127 throw_rtexc(err);
129 catch (DbException & exc) {
130 throw_rtexc( exc.get_errno(), exc.what() );
134 //______________________________________________________________________________
135 PersistentMap::PersistentMap()
136 : m_db( 0, 0 )
138 try {
139 // xxx todo: DB_THREAD, DB_DBT_MALLOC currently not used
140 int err = m_db.open( 0, 0, 0, DB_HASH, DB_CREATE/* | DB_THREAD*/, 0 );
141 if (err != 0)
142 throw_rtexc(err);
144 catch (DbException & exc) {
145 throw_rtexc( exc.get_errno(), exc.what() );
149 //______________________________________________________________________________
150 bool PersistentMap::has( OString const & key ) const
152 return get( 0, key );
155 //______________________________________________________________________________
156 bool PersistentMap::get( OString * value, OString const & key ) const
158 try {
159 Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
160 Dbt dbData;
161 int err = m_db.get( 0, &dbKey, &dbData, 0 );
162 if (err == DB_NOTFOUND)
163 return false;
164 if (err == 0) {
165 if (value != 0) {
166 *value = OString(
167 static_cast< sal_Char const * >(dbData.get_data()),
168 dbData.get_size() );
170 return true;
172 throw_rtexc(err);
174 catch (DbException & exc) {
175 throw_rtexc( exc.get_errno(), exc.what() );
177 return false; // avoiding warning
180 //______________________________________________________________________________
181 void PersistentMap::put( OString const & key, OString const & value )
183 try {
184 Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
185 Dbt dbData( const_cast< sal_Char * >(
186 value.getStr()), value.getLength() );
187 int err = m_db.put( 0, &dbKey, &dbData, 0 );
188 if (err == 0) {
189 #if OSL_DEBUG_LEVEL > 0
190 OString v;
191 OSL_ASSERT( get( &v, key ) );
192 OSL_ASSERT( v.equals( value ) );
193 #endif
194 err = m_db.sync(0);
196 if (err != 0)
197 throw_rtexc(err);
199 catch (DbException & exc) {
200 throw_rtexc( exc.get_errno(), exc.what() );
204 //______________________________________________________________________________
205 bool PersistentMap::erase( OString const & key, bool flush_immediately )
207 try {
208 Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
209 int err = m_db.del( &dbKey, 0 );
210 if (err == 0) {
211 if (flush_immediately) {
212 err = m_db.sync(0);
213 if (err != 0)
214 throw_rtexc(err);
216 return true;
218 if (err == DB_NOTFOUND)
219 return false;
220 throw_rtexc(err);
222 catch (DbException & exc) {
223 throw_rtexc( exc.get_errno(), exc.what() );
225 return false; // avoiding warning
228 //______________________________________________________________________________
229 t_string2string_map PersistentMap::getEntries() const
231 try {
232 Dbc * pcurs = 0;
233 int err = m_db.cursor( 0, &pcurs, 0 );
234 if (err != 0)
235 throw_rtexc(err);
237 t_string2string_map ret;
238 for (;;) {
239 Dbt dbKey, dbData;
240 err = pcurs->get( &dbKey, &dbData, DB_NEXT );
241 if (err == DB_NOTFOUND)
242 break;
243 if (err != 0)
244 throw_rtexc(err);
246 ::std::pair<t_string2string_map::iterator, bool > insertion(
247 ret.insert( t_string2string_map::value_type(
248 t_string2string_map::value_type(
249 OString( static_cast< sal_Char const * >(
250 dbKey.get_data()),
251 dbKey.get_size() ),
252 OString( static_cast< sal_Char const * >(
253 dbData.get_data()),
254 dbData.get_size() ) ) ) ) );
255 OSL_ASSERT( insertion.second );
257 err = pcurs->close();
258 if (err != 0)
259 throw_rtexc(err);
260 return ret;
262 catch (DbException & exc) {
263 throw_rtexc( exc.get_errno(), exc.what() );
265 return t_string2string_map(); // avoiding warning