xref: /AOO41X/main/desktop/source/deployment/dp_persmap.cxx (revision 2722ceddc26af33ca9ed6a22fc3c4dfb805171c3)
1*2722ceddSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*2722ceddSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*2722ceddSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*2722ceddSAndrew Rist  * distributed with this work for additional information
6*2722ceddSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*2722ceddSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*2722ceddSAndrew Rist  * "License"); you may not use this file except in compliance
9*2722ceddSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*2722ceddSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*2722ceddSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*2722ceddSAndrew Rist  * software distributed under the License is distributed on an
15*2722ceddSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2722ceddSAndrew Rist  * KIND, either express or implied.  See the License for the
17*2722ceddSAndrew Rist  * specific language governing permissions and limitations
18*2722ceddSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*2722ceddSAndrew Rist  *************************************************************/
21*2722ceddSAndrew Rist 
22*2722ceddSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_desktop.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "dp_misc.h"
28cdf0e10cSrcweir #include "dp_ucb.h"
29cdf0e10cSrcweir #include "dp_persmap.h"
30cdf0e10cSrcweir #include "rtl/strbuf.hxx"
31cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
32cdf0e10cSrcweir #include "osl/file.hxx"
33cdf0e10cSrcweir #include "osl/thread.h"
34cdf0e10cSrcweir 
35cdf0e10cSrcweir 
36cdf0e10cSrcweir using namespace ::com::sun::star;
37cdf0e10cSrcweir using namespace ::com::sun::star::uno;
38cdf0e10cSrcweir using namespace ::rtl;
39cdf0e10cSrcweir using ::osl::File;
40cdf0e10cSrcweir 
41cdf0e10cSrcweir namespace dp_misc
42cdf0e10cSrcweir {
43cdf0e10cSrcweir 
44cdf0e10cSrcweir //______________________________________________________________________________
45cdf0e10cSrcweir void PersistentMap::throw_rtexc( int err, char const * pmsg ) const
46cdf0e10cSrcweir {
47cdf0e10cSrcweir     OUStringBuffer buf;
48cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[") );
49cdf0e10cSrcweir     buf.append( m_sysPath );
50cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] Berkeley Db error (") );
51cdf0e10cSrcweir     buf.append( static_cast<sal_Int32>(err) );
52cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("): ") );
53cdf0e10cSrcweir     if (pmsg == 0)
54cdf0e10cSrcweir         pmsg = DbEnv::strerror(err);
55cdf0e10cSrcweir     const OString msg(pmsg);
56cdf0e10cSrcweir     buf.append( OUString( msg.getStr(), msg.getLength(),
57cdf0e10cSrcweir                           osl_getThreadTextEncoding() ) );
58cdf0e10cSrcweir     const OUString msg_(buf.makeStringAndClear());
59cdf0e10cSrcweir     OSL_ENSURE( 0, rtl::OUStringToOString(
60cdf0e10cSrcweir                     msg_, RTL_TEXTENCODING_UTF8 ).getStr() );
61cdf0e10cSrcweir     throw RuntimeException( msg_, Reference<XInterface>() );
62cdf0e10cSrcweir }
63cdf0e10cSrcweir 
64cdf0e10cSrcweir //______________________________________________________________________________
65cdf0e10cSrcweir PersistentMap::~PersistentMap()
66cdf0e10cSrcweir {
67cdf0e10cSrcweir     try {
68cdf0e10cSrcweir         m_db.close(0);
69cdf0e10cSrcweir     }
70cdf0e10cSrcweir     catch (DbException & exc) {
71cdf0e10cSrcweir         (void) exc; // avoid warnings
72cdf0e10cSrcweir         OSL_ENSURE( 0, DbEnv::strerror( exc.get_errno() ) );
73cdf0e10cSrcweir     }
74cdf0e10cSrcweir }
75cdf0e10cSrcweir 
76cdf0e10cSrcweir //______________________________________________________________________________
77cdf0e10cSrcweir PersistentMap::PersistentMap( OUString const & url_, bool readOnly )
78cdf0e10cSrcweir     : m_db( 0, 0 )
79cdf0e10cSrcweir {
80cdf0e10cSrcweir     try {
81cdf0e10cSrcweir         OUString url( expandUnoRcUrl(url_) );
82cdf0e10cSrcweir         if ( File::getSystemPathFromFileURL( url, m_sysPath ) != File::E_None )
83cdf0e10cSrcweir         {
84cdf0e10cSrcweir             OSL_ASSERT( false );
85cdf0e10cSrcweir         }
86cdf0e10cSrcweir         OString cstr_sysPath(
87cdf0e10cSrcweir             OUStringToOString( m_sysPath, RTL_TEXTENCODING_UTF8 ) );
88cdf0e10cSrcweir         char const * pcstr_sysPath = cstr_sysPath.getStr();
89cdf0e10cSrcweir 
90cdf0e10cSrcweir         u_int32_t flags = DB_CREATE;
91cdf0e10cSrcweir         if (readOnly) {
92cdf0e10cSrcweir             flags = DB_RDONLY;
93cdf0e10cSrcweir             if (! create_ucb_content(
94cdf0e10cSrcweir                     0, url,
95cdf0e10cSrcweir                     Reference<com::sun::star::ucb::XCommandEnvironment>(),
96cdf0e10cSrcweir                     false /* no throw */ )) {
97cdf0e10cSrcweir                 // ignore non-existent file in read-only mode: simulate empty db
98cdf0e10cSrcweir                 pcstr_sysPath = 0;
99cdf0e10cSrcweir                 flags = DB_CREATE;
100cdf0e10cSrcweir             }
101cdf0e10cSrcweir         }
102cdf0e10cSrcweir 
103cdf0e10cSrcweir         int err = m_db.open(
104cdf0e10cSrcweir             // xxx todo: DB_THREAD, DB_DBT_MALLOC currently not used
105cdf0e10cSrcweir             0, pcstr_sysPath, 0, DB_HASH, flags/* | DB_THREAD*/, 0664 /* fs mode */ );
106cdf0e10cSrcweir         if (err != 0)
107cdf0e10cSrcweir             throw_rtexc(err);
108cdf0e10cSrcweir     }
109cdf0e10cSrcweir     catch (DbException & exc) {
110cdf0e10cSrcweir         throw_rtexc( exc.get_errno(), exc.what() );
111cdf0e10cSrcweir     }
112cdf0e10cSrcweir }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir //______________________________________________________________________________
115cdf0e10cSrcweir PersistentMap::PersistentMap()
116cdf0e10cSrcweir     : m_db( 0, 0 )
117cdf0e10cSrcweir {
118cdf0e10cSrcweir     try {
119cdf0e10cSrcweir         // xxx todo: DB_THREAD, DB_DBT_MALLOC currently not used
120cdf0e10cSrcweir         int err = m_db.open( 0, 0, 0, DB_HASH, DB_CREATE/* | DB_THREAD*/, 0 );
121cdf0e10cSrcweir         if (err != 0)
122cdf0e10cSrcweir             throw_rtexc(err);
123cdf0e10cSrcweir     }
124cdf0e10cSrcweir     catch (DbException & exc) {
125cdf0e10cSrcweir         throw_rtexc( exc.get_errno(), exc.what() );
126cdf0e10cSrcweir     }
127cdf0e10cSrcweir }
128cdf0e10cSrcweir 
129cdf0e10cSrcweir //______________________________________________________________________________
130cdf0e10cSrcweir bool PersistentMap::has( OString const & key ) const
131cdf0e10cSrcweir {
132cdf0e10cSrcweir     return get( 0, key );
133cdf0e10cSrcweir }
134cdf0e10cSrcweir 
135cdf0e10cSrcweir //______________________________________________________________________________
136cdf0e10cSrcweir bool PersistentMap::get( OString * value, OString const & key ) const
137cdf0e10cSrcweir {
138cdf0e10cSrcweir     try {
139cdf0e10cSrcweir         Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
140cdf0e10cSrcweir         Dbt dbData;
141cdf0e10cSrcweir         int err = m_db.get( 0, &dbKey, &dbData, 0 );
142cdf0e10cSrcweir         if (err == DB_NOTFOUND)
143cdf0e10cSrcweir             return false;
144cdf0e10cSrcweir         if (err == 0) {
145cdf0e10cSrcweir             if (value != 0) {
146cdf0e10cSrcweir                 *value = OString(
147cdf0e10cSrcweir                     static_cast< sal_Char const * >(dbData.get_data()),
148cdf0e10cSrcweir                     dbData.get_size() );
149cdf0e10cSrcweir             }
150cdf0e10cSrcweir             return true;
151cdf0e10cSrcweir         }
152cdf0e10cSrcweir         throw_rtexc(err);
153cdf0e10cSrcweir     }
154cdf0e10cSrcweir     catch (DbException & exc) {
155cdf0e10cSrcweir         throw_rtexc( exc.get_errno(), exc.what() );
156cdf0e10cSrcweir     }
157cdf0e10cSrcweir     return false; // avoiding warning
158cdf0e10cSrcweir }
159cdf0e10cSrcweir 
160cdf0e10cSrcweir //______________________________________________________________________________
161cdf0e10cSrcweir void PersistentMap::put( OString const & key, OString const & value )
162cdf0e10cSrcweir {
163cdf0e10cSrcweir     try {
164cdf0e10cSrcweir         Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
165cdf0e10cSrcweir         Dbt dbData( const_cast< sal_Char * >(
166cdf0e10cSrcweir                         value.getStr()), value.getLength() );
167cdf0e10cSrcweir         int err = m_db.put( 0, &dbKey, &dbData, 0 );
168cdf0e10cSrcweir         if (err == 0) {
169cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
170cdf0e10cSrcweir             OString v;
171cdf0e10cSrcweir             OSL_ASSERT( get( &v, key ) );
172cdf0e10cSrcweir             OSL_ASSERT( v.equals( value ) );
173cdf0e10cSrcweir #endif
174cdf0e10cSrcweir             err = m_db.sync(0);
175cdf0e10cSrcweir         }
176cdf0e10cSrcweir         if (err != 0)
177cdf0e10cSrcweir             throw_rtexc(err);
178cdf0e10cSrcweir     }
179cdf0e10cSrcweir     catch (DbException & exc) {
180cdf0e10cSrcweir         throw_rtexc( exc.get_errno(), exc.what() );
181cdf0e10cSrcweir     }
182cdf0e10cSrcweir }
183cdf0e10cSrcweir 
184cdf0e10cSrcweir //______________________________________________________________________________
185cdf0e10cSrcweir bool PersistentMap::erase( OString const & key, bool flush_immediately )
186cdf0e10cSrcweir {
187cdf0e10cSrcweir     try {
188cdf0e10cSrcweir         Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
189cdf0e10cSrcweir         int err = m_db.del( &dbKey, 0 );
190cdf0e10cSrcweir         if (err == 0) {
191cdf0e10cSrcweir             if (flush_immediately) {
192cdf0e10cSrcweir                 err = m_db.sync(0);
193cdf0e10cSrcweir                 if (err != 0)
194cdf0e10cSrcweir                     throw_rtexc(err);
195cdf0e10cSrcweir             }
196cdf0e10cSrcweir             return true;
197cdf0e10cSrcweir         }
198cdf0e10cSrcweir         if (err == DB_NOTFOUND)
199cdf0e10cSrcweir             return false;
200cdf0e10cSrcweir         throw_rtexc(err);
201cdf0e10cSrcweir     }
202cdf0e10cSrcweir     catch (DbException & exc) {
203cdf0e10cSrcweir         throw_rtexc( exc.get_errno(), exc.what() );
204cdf0e10cSrcweir     }
205cdf0e10cSrcweir     return false; // avoiding warning
206cdf0e10cSrcweir }
207cdf0e10cSrcweir 
208cdf0e10cSrcweir //______________________________________________________________________________
209cdf0e10cSrcweir t_string2string_map PersistentMap::getEntries() const
210cdf0e10cSrcweir {
211cdf0e10cSrcweir     try {
212cdf0e10cSrcweir         Dbc * pcurs = 0;
213cdf0e10cSrcweir         int err = m_db.cursor( 0, &pcurs, 0 );
214cdf0e10cSrcweir         if (err != 0)
215cdf0e10cSrcweir             throw_rtexc(err);
216cdf0e10cSrcweir 
217cdf0e10cSrcweir         t_string2string_map ret;
218cdf0e10cSrcweir         for (;;) {
219cdf0e10cSrcweir             Dbt dbKey, dbData;
220cdf0e10cSrcweir             err = pcurs->get( &dbKey, &dbData, DB_NEXT );
221cdf0e10cSrcweir             if (err == DB_NOTFOUND)
222cdf0e10cSrcweir                 break;
223cdf0e10cSrcweir             if (err != 0)
224cdf0e10cSrcweir                 throw_rtexc(err);
225cdf0e10cSrcweir 
226cdf0e10cSrcweir             ::std::pair<t_string2string_map::iterator, bool > insertion(
227cdf0e10cSrcweir                 ret.insert( t_string2string_map::value_type(
228cdf0e10cSrcweir                                 t_string2string_map::value_type(
229cdf0e10cSrcweir                                     OString( static_cast< sal_Char const * >(
230cdf0e10cSrcweir                                                  dbKey.get_data()),
231cdf0e10cSrcweir                                              dbKey.get_size() ),
232cdf0e10cSrcweir                                     OString( static_cast< sal_Char const * >(
233cdf0e10cSrcweir                                                  dbData.get_data()),
234cdf0e10cSrcweir                                              dbData.get_size() ) ) ) ) );
235cdf0e10cSrcweir             OSL_ASSERT( insertion.second );
236cdf0e10cSrcweir         }
237cdf0e10cSrcweir         err = pcurs->close();
238cdf0e10cSrcweir         if (err != 0)
239cdf0e10cSrcweir             throw_rtexc(err);
240cdf0e10cSrcweir         return ret;
241cdf0e10cSrcweir     }
242cdf0e10cSrcweir     catch (DbException & exc) {
243cdf0e10cSrcweir         throw_rtexc( exc.get_errno(), exc.what() );
244cdf0e10cSrcweir     }
245cdf0e10cSrcweir     return t_string2string_map(); // avoiding warning
246cdf0e10cSrcweir }
247cdf0e10cSrcweir 
248cdf0e10cSrcweir }
249cdf0e10cSrcweir 
250