xref: /trunk/main/stoc/source/simpleregistry/simpleregistry.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "precompiled_stoc.hxx"
25 #include "sal/config.h"
26 
27 #include <cstdlib>
28 #include <memory>
29 #include <vector>
30 
31 #include "com/sun/star/lang/XServiceInfo.hpp"
32 #include "com/sun/star/registry/InvalidRegistryException.hpp"
33 #include "com/sun/star/registry/InvalidValueException.hpp"
34 #include "com/sun/star/registry/MergeConflictException.hpp"
35 #include "com/sun/star/registry/RegistryKeyType.hpp"
36 #include "com/sun/star/registry/XRegistryKey.hpp"
37 #include "com/sun/star/registry/XSimpleRegistry.hpp"
38 #include "com/sun/star/uno/Reference.hxx"
39 #include "com/sun/star/uno/RuntimeException.hpp"
40 #include "com/sun/star/uno/XComponentContext.hpp"
41 #include "com/sun/star/uno/XInterface.hpp"
42 #include "com/sun/star/uno/Sequence.hxx"
43 #include "cppuhelper/implbase1.hxx"
44 #include "cppuhelper/implbase2.hxx"
45 #include "cppuhelper/weak.hxx"
46 #include "osl/mutex.hxx"
47 #include "registry/registry.hxx"
48 #include "registry/regtype.h"
49 #include "rtl/ref.hxx"
50 #include "rtl/string.h"
51 #include "rtl/string.hxx"
52 #include "rtl/textcvt.h"
53 #include "rtl/textenc.h"
54 #include "rtl/unload.h"
55 #include "rtl/ustring.h"
56 #include "rtl/ustring.hxx"
57 #include "sal/types.h"
58 
59 #include "bootstrapservices.hxx"
60 
61 #include "textualservices.hxx"
62 
63 extern rtl_StandardModuleCount g_moduleCount;
64 
65 namespace {
66 
67 namespace css = com::sun::star;
68 
69 class SimpleRegistry:
70     public cppu::WeakImplHelper2<
71         css::registry::XSimpleRegistry, css::lang::XServiceInfo >
72 {
73 public:
SimpleRegistry()74     SimpleRegistry() { g_moduleCount.modCnt.acquire(&g_moduleCount.modCnt); }
75 
~SimpleRegistry()76     ~SimpleRegistry() { g_moduleCount.modCnt.release(&g_moduleCount.modCnt); }
77 
78     osl::Mutex mutex_;
79 
80 private:
81     virtual rtl::OUString SAL_CALL getURL();
82 
83     virtual void SAL_CALL open(
84         rtl::OUString const & rURL, sal_Bool bReadOnly, sal_Bool bCreate);
85 
86     virtual sal_Bool SAL_CALL isValid();
87 
88     virtual void SAL_CALL close();
89 
90     virtual void SAL_CALL destroy();
91 
92     virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL
93     getRootKey();
94 
95     virtual sal_Bool SAL_CALL isReadOnly();
96 
97     virtual void SAL_CALL mergeKey(
98         rtl::OUString const & aKeyName, rtl::OUString const & aUrl);
99 
getImplementationName()100     virtual rtl::OUString SAL_CALL getImplementationName()
101     { return stoc_bootstrap::simreg_getImplementationName(); }
102 
supportsService(rtl::OUString const & ServiceName)103     virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
104     { return ServiceName == getSupportedServiceNames()[0]; }
105 
106     virtual css::uno::Sequence< rtl::OUString > SAL_CALL
getSupportedServiceNames()107     getSupportedServiceNames()
108     { return stoc_bootstrap::simreg_getSupportedServiceNames(); }
109 
110     Registry registry_;
111     std::auto_ptr< stoc::simpleregistry::TextualServices > textual_;
112 };
113 
114 class Key: public cppu::WeakImplHelper1< css::registry::XRegistryKey > {
115 public:
Key(rtl::Reference<SimpleRegistry> const & registry,RegistryKey const & key)116     Key(
117         rtl::Reference< SimpleRegistry > const & registry,
118         RegistryKey const & key):
119         registry_(registry), key_(key) {}
120 
121 private:
122     virtual rtl::OUString SAL_CALL getKeyName();
123 
124     virtual sal_Bool SAL_CALL isReadOnly();
125 
126     virtual sal_Bool SAL_CALL isValid();
127 
128     virtual css::registry::RegistryKeyType SAL_CALL getKeyType(
129         rtl::OUString const & rKeyName);
130 
131     virtual css::registry::RegistryValueType SAL_CALL getValueType();
132 
133     virtual sal_Int32 SAL_CALL getLongValue();
134 
135     virtual void SAL_CALL setLongValue(sal_Int32 value);
136 
137     virtual css::uno::Sequence< sal_Int32 > SAL_CALL getLongListValue();
138 
139     virtual void SAL_CALL setLongListValue(
140         com::sun::star::uno::Sequence< sal_Int32 > const & seqValue);
141 
142     virtual rtl::OUString SAL_CALL getAsciiValue();
143 
144     virtual void SAL_CALL setAsciiValue(rtl::OUString const & value);
145 
146     virtual css::uno::Sequence< rtl::OUString > SAL_CALL getAsciiListValue();
147 
148     virtual void SAL_CALL setAsciiListValue(
149         css::uno::Sequence< rtl::OUString > const & seqValue);
150 
151     virtual rtl::OUString SAL_CALL getStringValue();
152 
153     virtual void SAL_CALL setStringValue(rtl::OUString const & value);
154 
155     virtual css::uno::Sequence< rtl::OUString > SAL_CALL getStringListValue();
156 
157     virtual void SAL_CALL setStringListValue(
158         css::uno::Sequence< rtl::OUString > const & seqValue);
159 
160     virtual css::uno::Sequence< sal_Int8 > SAL_CALL getBinaryValue();
161 
162     virtual void SAL_CALL setBinaryValue(
163         css::uno::Sequence< sal_Int8 > const & value);
164 
165     virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL openKey(
166         rtl::OUString const & aKeyName);
167 
168     virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL
169     createKey(rtl::OUString const & aKeyName);
170 
171     virtual void SAL_CALL closeKey();
172 
173     virtual void SAL_CALL deleteKey(rtl::OUString const & rKeyName);
174 
175     virtual
176     css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
177     SAL_CALL openKeys();
178 
179     virtual css::uno::Sequence< rtl::OUString > SAL_CALL getKeyNames();
180 
181     virtual sal_Bool SAL_CALL createLink(
182         rtl::OUString const & aLinkName, rtl::OUString const & aLinkTarget);
183 
184     virtual void SAL_CALL deleteLink(rtl::OUString const & rLinkName);
185 
186     virtual rtl::OUString SAL_CALL getLinkTarget(
187         rtl::OUString const & rLinkName);
188 
189     virtual rtl::OUString SAL_CALL getResolvedName(
190         rtl::OUString const & aKeyName);
191 
192     rtl::Reference< SimpleRegistry > registry_;
193     RegistryKey key_;
194 };
195 
getKeyName()196 rtl::OUString Key::getKeyName() {
197     osl::MutexGuard guard(registry_->mutex_);
198     return key_.getName();
199 }
200 
isReadOnly()201 sal_Bool Key::isReadOnly()
202 {
203     osl::MutexGuard guard(registry_->mutex_);
204     return key_.isReadOnly();
205 }
206 
isValid()207 sal_Bool Key::isValid() {
208     osl::MutexGuard guard(registry_->mutex_);
209     return key_.isValid();
210 }
211 
getKeyType(rtl::OUString const & rKeyName)212 css::registry::RegistryKeyType Key::getKeyType(rtl::OUString const & rKeyName)
213 {
214     osl::MutexGuard guard(registry_->mutex_);
215     RegKeyType type;
216     RegError err = key_.getKeyType(rKeyName, &type);
217     if (err != REG_NO_ERROR) {
218         throw css::registry::InvalidRegistryException(
219             (rtl::OUString(
220                 RTL_CONSTASCII_USTRINGPARAM(
221                     "com.sun.star.registry.SimpleRegistry key getKeyType:"
222                     " underlying RegistryKey::getKeyType() = ")) +
223              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
224             static_cast< OWeakObject * >(this));
225     }
226     switch (type) {
227     default:
228         std::abort(); // this cannot happen
229         // pseudo-fall-through to avoid warnings on MSC
230     case RG_KEYTYPE:
231         return css::registry::RegistryKeyType_KEY;
232     case RG_LINKTYPE:
233         return css::registry::RegistryKeyType_LINK;
234     }
235 }
236 
getValueType()237 css::registry::RegistryValueType Key::getValueType()
238 {
239     osl::MutexGuard guard(registry_->mutex_);
240     RegValueType type;
241     sal_uInt32 size;
242     RegError err = key_.getValueInfo(rtl::OUString(), &type, &size);
243     switch (err) {
244     case REG_NO_ERROR:
245         break;
246     case REG_INVALID_VALUE:
247         type = RG_VALUETYPE_NOT_DEFINED;
248         break;
249     default:
250         throw css::registry::InvalidRegistryException(
251             (rtl::OUString(
252                 RTL_CONSTASCII_USTRINGPARAM(
253                     "com.sun.star.registry.SimpleRegistry key getValueType:"
254                     " underlying RegistryKey::getValueInfo() = ")) +
255              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
256             static_cast< OWeakObject * >(this));
257     }
258     switch (type) {
259     default:
260         std::abort(); // this cannot happen
261         // pseudo-fall-through to avoid warnings on MSC
262     case RG_VALUETYPE_NOT_DEFINED:
263         return css::registry::RegistryValueType_NOT_DEFINED;
264     case RG_VALUETYPE_LONG:
265         return css::registry::RegistryValueType_LONG;
266     case RG_VALUETYPE_STRING:
267         return css::registry::RegistryValueType_ASCII;
268     case RG_VALUETYPE_UNICODE:
269         return css::registry::RegistryValueType_STRING;
270     case RG_VALUETYPE_BINARY:
271         return css::registry::RegistryValueType_BINARY;
272     case RG_VALUETYPE_LONGLIST:
273         return css::registry::RegistryValueType_LONGLIST;
274     case RG_VALUETYPE_STRINGLIST:
275         return css::registry::RegistryValueType_ASCIILIST;
276     case RG_VALUETYPE_UNICODELIST:
277         return css::registry::RegistryValueType_STRINGLIST;
278     }
279 }
280 
getLongValue()281 sal_Int32 Key::getLongValue()
282 {
283     osl::MutexGuard guard(registry_->mutex_);
284     sal_Int32 value;
285     RegError err = key_.getValue(rtl::OUString(), &value);
286     switch (err) {
287     case REG_NO_ERROR:
288         break;
289     case REG_INVALID_VALUE:
290         throw css::registry::InvalidValueException(
291             rtl::OUString(
292                 RTL_CONSTASCII_USTRINGPARAM(
293                     "com.sun.star.registry.SimpleRegistry key getLongValue:"
294                     " underlying RegistryKey::getValue() = REG_INVALID_VALUE")),
295             static_cast< OWeakObject * >(this));
296     default:
297         throw css::registry::InvalidRegistryException(
298             (rtl::OUString(
299                 RTL_CONSTASCII_USTRINGPARAM(
300                     "com.sun.star.registry.SimpleRegistry key getLongValue:"
301                     " underlying RegistryKey::getValue() = ")) +
302              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
303             static_cast< OWeakObject * >(this));
304     }
305     return value;
306 }
307 
setLongValue(sal_Int32 value)308 void Key::setLongValue(sal_Int32 value)
309 {
310     osl::MutexGuard guard(registry_->mutex_);
311     RegError err = key_.setValue(
312         rtl::OUString(), RG_VALUETYPE_LONG, &value, sizeof (sal_Int32));
313     if (err != REG_NO_ERROR) {
314         throw css::registry::InvalidRegistryException(
315             (rtl::OUString(
316                 RTL_CONSTASCII_USTRINGPARAM(
317                     "com.sun.star.registry.SimpleRegistry key setLongValue:"
318                     " underlying RegistryKey::setValue() = ")) +
319              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
320             static_cast< OWeakObject * >(this));
321     }
322 }
323 
getLongListValue()324 css::uno::Sequence< sal_Int32 > Key::getLongListValue()
325 {
326     osl::MutexGuard guard(registry_->mutex_);
327     RegistryValueList< sal_Int32 > list;
328     RegError err = key_.getLongListValue(rtl::OUString(), list);
329     switch (err) {
330     case REG_NO_ERROR:
331         break;
332     case REG_VALUE_NOT_EXISTS:
333         return css::uno::Sequence< sal_Int32 >();
334     case REG_INVALID_VALUE:
335         throw css::registry::InvalidValueException(
336             rtl::OUString(
337                 RTL_CONSTASCII_USTRINGPARAM(
338                     "com.sun.star.registry.SimpleRegistry key getLongListValue:"
339                     " underlying RegistryKey::getLongListValue() ="
340                     " REG_INVALID_VALUE")),
341             static_cast< OWeakObject * >(this));
342     default:
343         throw css::registry::InvalidRegistryException(
344             (rtl::OUString(
345                 RTL_CONSTASCII_USTRINGPARAM(
346                     "com.sun.star.registry.SimpleRegistry key getLongListValue:"
347                     " underlying RegistryKey::getLongListValue() = ")) +
348              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
349             static_cast< OWeakObject * >(this));
350     }
351     sal_uInt32 n = list.getLength();
352     if (n > SAL_MAX_INT32) {
353         throw css::registry::InvalidValueException(
354             rtl::OUString(
355                 RTL_CONSTASCII_USTRINGPARAM(
356                     "com.sun.star.registry.SimpleRegistry key getLongListValue:"
357                     " underlying RegistryKey::getLongListValue() too large")),
358             static_cast< OWeakObject * >(this));
359     }
360     css::uno::Sequence< sal_Int32 > value(static_cast< sal_Int32 >(n));
361     for (sal_uInt32 i = 0; i < n; ++i) {
362         value[static_cast< sal_Int32 >(i)] = list.getElement(i);
363     }
364     return value;
365 }
366 
setLongListValue(css::uno::Sequence<sal_Int32> const & seqValue)367 void Key::setLongListValue(css::uno::Sequence< sal_Int32 > const & seqValue)
368 {
369     osl::MutexGuard guard(registry_->mutex_);
370     std::vector< sal_Int32 > list;
371     for (sal_Int32 i = 0; i < seqValue.getLength(); ++i) {
372         list.push_back(seqValue[i]);
373     }
374     RegError err = key_.setLongListValue(
375         rtl::OUString(), list.empty() ? 0 : &list[0],
376         static_cast< sal_uInt32 >(list.size()));
377     if (err != REG_NO_ERROR) {
378         throw css::registry::InvalidRegistryException(
379             (rtl::OUString(
380                 RTL_CONSTASCII_USTRINGPARAM(
381                     "com.sun.star.registry.SimpleRegistry key setLongListValue:"
382                     " underlying RegistryKey::setLongListValue() = ")) +
383              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
384             static_cast< OWeakObject * >(this));
385     }
386 }
387 
getAsciiValue()388 rtl::OUString Key::getAsciiValue()
389 {
390     osl::MutexGuard guard(registry_->mutex_);
391     RegValueType type;
392     sal_uInt32 size;
393     RegError err = key_.getValueInfo(rtl::OUString(), &type, &size);
394     if (err != REG_NO_ERROR) {
395         throw css::registry::InvalidRegistryException(
396             (rtl::OUString(
397                 RTL_CONSTASCII_USTRINGPARAM(
398                     "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
399                     " underlying RegistryKey::getValueInfo() = ")) +
400              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
401             static_cast< OWeakObject * >(this));
402     }
403     if (type != RG_VALUETYPE_STRING) {
404         throw css::registry::InvalidValueException(
405             (rtl::OUString(
406                 RTL_CONSTASCII_USTRINGPARAM(
407                     "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
408                     " underlying RegistryKey type = ")) +
409              rtl::OUString::valueOf(static_cast< sal_Int32 >(type))),
410             static_cast< OWeakObject * >(this));
411     }
412     // size contains terminating null (error in underlying registry.cxx):
413     if (size == 0) {
414         throw css::registry::InvalidValueException(
415             rtl::OUString(
416                 RTL_CONSTASCII_USTRINGPARAM(
417                     "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
418                     " underlying RegistryKey size 0 cannot happen due to"
419                     " design error")),
420             static_cast< OWeakObject * >(this));
421     }
422     if (size > SAL_MAX_INT32) {
423         throw css::registry::InvalidValueException(
424             rtl::OUString(
425                 RTL_CONSTASCII_USTRINGPARAM(
426                     "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
427                     " underlying RegistryKey size too large")),
428             static_cast< OWeakObject * >(this));
429     }
430     std::vector< char > list(size);
431     err = key_.getValue(rtl::OUString(), &list[0]);
432     if (err != REG_NO_ERROR) {
433         throw css::registry::InvalidRegistryException(
434             (rtl::OUString(
435                 RTL_CONSTASCII_USTRINGPARAM(
436                     "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
437                     " underlying RegistryKey::getValue() = ")) +
438              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
439             static_cast< OWeakObject * >(this));
440     }
441     if (list[size - 1] != '\0') {
442         throw css::registry::InvalidValueException(
443             rtl::OUString(
444                 RTL_CONSTASCII_USTRINGPARAM(
445                     "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
446                     " underlying RegistryKey value must be null-terminated due"
447                     " to design error")),
448             static_cast< OWeakObject * >(this));
449     }
450     rtl::OUString value;
451     if (!rtl_convertStringToUString(
452             &value.pData, &list[0],
453             static_cast< sal_Int32 >(size - 1), RTL_TEXTENCODING_UTF8,
454             (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
455              RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
456              RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
457     {
458         throw css::registry::InvalidValueException(
459             rtl::OUString(
460                 RTL_CONSTASCII_USTRINGPARAM(
461                     "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
462                     " underlying RegistryKey not UTF-8")),
463             static_cast< OWeakObject * >(this));
464     }
465     return value;
466 }
467 
setAsciiValue(rtl::OUString const & value)468 void Key::setAsciiValue(rtl::OUString const & value)
469 {
470     osl::MutexGuard guard(registry_->mutex_);
471     rtl::OString utf8;
472     if (!value.convertToString(
473             &utf8, RTL_TEXTENCODING_UTF8,
474             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
475              RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
476     {
477         throw css::uno::RuntimeException(
478             rtl::OUString(
479                 RTL_CONSTASCII_USTRINGPARAM(
480                     "com.sun.star.registry.SimpleRegistry key setAsciiValue:"
481                     " value not UTF-16")),
482             static_cast< OWeakObject * >(this));
483     }
484     RegError err = key_.setValue(
485         rtl::OUString(), RG_VALUETYPE_STRING,
486         const_cast< char * >(utf8.getStr()), utf8.getLength() + 1);
487         // +1 for terminating null (error in underlying registry.cxx)
488     if (err != REG_NO_ERROR) {
489         throw css::registry::InvalidRegistryException(
490             (rtl::OUString(
491                 RTL_CONSTASCII_USTRINGPARAM(
492                     "com.sun.star.registry.SimpleRegistry key setAsciiValue:"
493                     " underlying RegistryKey::setValue() = ")) +
494              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
495             static_cast< OWeakObject * >(this));
496     }
497 }
498 
getAsciiListValue()499 css::uno::Sequence< rtl::OUString > Key::getAsciiListValue()
500 {
501     osl::MutexGuard guard(registry_->mutex_);
502     RegistryValueList< char * > list;
503     RegError err = key_.getStringListValue(rtl::OUString(), list);
504     switch (err) {
505     case REG_NO_ERROR:
506         break;
507     case REG_VALUE_NOT_EXISTS:
508         return css::uno::Sequence< rtl::OUString >();
509     case REG_INVALID_VALUE:
510         throw css::registry::InvalidValueException(
511             rtl::OUString(
512                 RTL_CONSTASCII_USTRINGPARAM(
513                     "com.sun.star.registry.SimpleRegistry key"
514                     " getAsciiListValue: underlying"
515                     " RegistryKey::getStringListValue() = REG_INVALID_VALUE")),
516             static_cast< OWeakObject * >(this));
517     default:
518         throw css::registry::InvalidRegistryException(
519             (rtl::OUString(
520                 RTL_CONSTASCII_USTRINGPARAM(
521                     "com.sun.star.registry.SimpleRegistry key"
522                     " getAsciiListValue: underlying"
523                     " RegistryKey::getStringListValue() = ")) +
524              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
525             static_cast< OWeakObject * >(this));
526     }
527     sal_uInt32 n = list.getLength();
528     if (n > SAL_MAX_INT32) {
529         throw css::registry::InvalidValueException(
530             rtl::OUString(
531                 RTL_CONSTASCII_USTRINGPARAM(
532                     "com.sun.star.registry.SimpleRegistry key"
533                     " getAsciiListValue: underlying"
534                     " RegistryKey::getStringListValue() too large")),
535             static_cast< OWeakObject * >(this));
536     }
537     css::uno::Sequence< rtl::OUString > value(static_cast< sal_Int32 >(n));
538     for (sal_uInt32 i = 0; i < n; ++i) {
539         char * el = list.getElement(i);
540         sal_Int32 size = rtl_str_getLength(el);
541         if (!rtl_convertStringToUString(
542                 &value[static_cast< sal_Int32 >(i)].pData, el, size,
543                 RTL_TEXTENCODING_UTF8,
544                 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
545                  RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
546                  RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
547         {
548             throw css::registry::InvalidValueException(
549                 rtl::OUString(
550                     RTL_CONSTASCII_USTRINGPARAM(
551                         "com.sun.star.registry.SimpleRegistry key"
552                         " getAsciiListValue: underlying RegistryKey not"
553                         " UTF-8")),
554                 static_cast< OWeakObject * >(this));
555         }
556     }
557     return value;
558 }
559 
setAsciiListValue(css::uno::Sequence<rtl::OUString> const & seqValue)560 void Key::setAsciiListValue(
561     css::uno::Sequence< rtl::OUString > const & seqValue)
562 {
563     osl::MutexGuard guard(registry_->mutex_);
564     std::vector< rtl::OString > list;
565     for (sal_Int32 i = 0; i < seqValue.getLength(); ++i) {
566         rtl::OString utf8;
567         if (!seqValue[i].convertToString(
568                 &utf8, RTL_TEXTENCODING_UTF8,
569                 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
570                  RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
571         {
572             throw css::uno::RuntimeException(
573                 rtl::OUString(
574                     RTL_CONSTASCII_USTRINGPARAM(
575                         "com.sun.star.registry.SimpleRegistry key"
576                         " setAsciiListValue: value not UTF-16")),
577                 static_cast< OWeakObject * >(this));
578         }
579         list.push_back(utf8);
580     }
581     std::vector< char * > list2;
582     for (std::vector< rtl::OString >::iterator i(list.begin()); i != list.end();
583          ++i)
584     {
585         list2.push_back(const_cast< char * >(i->getStr()));
586     }
587     RegError err = key_.setStringListValue(
588         rtl::OUString(), list2.empty() ? 0 : &list2[0],
589         static_cast< sal_uInt32 >(list2.size()));
590     if (err != REG_NO_ERROR) {
591         throw css::registry::InvalidRegistryException(
592             (rtl::OUString(
593                 RTL_CONSTASCII_USTRINGPARAM(
594                     "com.sun.star.registry.SimpleRegistry key"
595                     " setAsciiListValue: underlying"
596                     " RegistryKey::setStringListValue() = ")) +
597              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
598             static_cast< OWeakObject * >(this));
599     }
600 }
601 
getStringValue()602 rtl::OUString Key::getStringValue()
603 {
604     osl::MutexGuard guard(registry_->mutex_);
605     RegValueType type;
606     sal_uInt32 size;
607     RegError err = key_.getValueInfo(rtl::OUString(), &type, &size);
608     if (err != REG_NO_ERROR) {
609         throw css::registry::InvalidRegistryException(
610             (rtl::OUString(
611                 RTL_CONSTASCII_USTRINGPARAM(
612                     "com.sun.star.registry.SimpleRegistry key getStringValue:"
613                     " underlying RegistryKey::getValueInfo() = ")) +
614              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
615             static_cast< OWeakObject * >(this));
616     }
617     if (type != RG_VALUETYPE_UNICODE) {
618         throw css::registry::InvalidValueException(
619             (rtl::OUString(
620                 RTL_CONSTASCII_USTRINGPARAM(
621                     "com.sun.star.registry.SimpleRegistry key getStringValue:"
622                     " underlying RegistryKey type = ")) +
623              rtl::OUString::valueOf(static_cast< sal_Int32 >(type))),
624             static_cast< OWeakObject * >(this));
625     }
626     // size contains terminating null and is *2 (error in underlying
627     // registry.cxx):
628     if (size == 0 || (size & 1) == 1) {
629         throw css::registry::InvalidValueException(
630             rtl::OUString(
631                 RTL_CONSTASCII_USTRINGPARAM(
632                     "com.sun.star.registry.SimpleRegistry key getStringValue:"
633                     " underlying RegistryKey size 0 or odd cannot happen due to"
634                     " design error")),
635             static_cast< OWeakObject * >(this));
636     }
637     if (size > SAL_MAX_INT32) {
638         throw css::registry::InvalidValueException(
639             rtl::OUString(
640                 RTL_CONSTASCII_USTRINGPARAM(
641                     "com.sun.star.registry.SimpleRegistry key getStringValue:"
642                     " underlying RegistryKey size too large")),
643             static_cast< OWeakObject * >(this));
644     }
645     std::vector< sal_Unicode > list(size);
646     err = key_.getValue(rtl::OUString(), &list[0]);
647     if (err != REG_NO_ERROR) {
648         throw css::registry::InvalidRegistryException(
649             (rtl::OUString(
650                 RTL_CONSTASCII_USTRINGPARAM(
651                     "com.sun.star.registry.SimpleRegistry key getStringValue:"
652                     " underlying RegistryKey::getValue() = ")) +
653              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
654             static_cast< OWeakObject * >(this));
655     }
656     if (list[size/2 - 1] != 0) {
657         throw css::registry::InvalidValueException(
658             rtl::OUString(
659                 RTL_CONSTASCII_USTRINGPARAM(
660                     "com.sun.star.registry.SimpleRegistry key getStringValue:"
661                     " underlying RegistryKey value must be null-terminated due"
662                     " to design error")),
663             static_cast< OWeakObject * >(this));
664     }
665     return rtl::OUString(&list[0], static_cast< sal_Int32 >(size/2 - 1));
666 }
667 
setStringValue(rtl::OUString const & value)668 void Key::setStringValue(rtl::OUString const & value)
669 {
670     osl::MutexGuard guard(registry_->mutex_);
671     RegError err = key_.setValue(
672         rtl::OUString(), RG_VALUETYPE_UNICODE,
673         const_cast< sal_Unicode * >(value.getStr()),
674         (value.getLength() + 1) * sizeof (sal_Unicode));
675         // +1 for terminating null (error in underlying registry.cxx)
676     if (err != REG_NO_ERROR) {
677         throw css::registry::InvalidRegistryException(
678             (rtl::OUString(
679                 RTL_CONSTASCII_USTRINGPARAM(
680                     "com.sun.star.registry.SimpleRegistry key setStringValue:"
681                     " underlying RegistryKey::setValue() = ")) +
682              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
683             static_cast< OWeakObject * >(this));
684     }
685 }
686 
getStringListValue()687 css::uno::Sequence< rtl::OUString > Key::getStringListValue()
688 {
689     osl::MutexGuard guard(registry_->mutex_);
690     RegistryValueList< sal_Unicode * > list;
691     RegError err = key_.getUnicodeListValue(rtl::OUString(), list);
692     switch (err) {
693     case REG_NO_ERROR:
694         break;
695     case REG_VALUE_NOT_EXISTS:
696         return css::uno::Sequence< rtl::OUString >();
697     case REG_INVALID_VALUE:
698         throw css::registry::InvalidValueException(
699             rtl::OUString(
700                 RTL_CONSTASCII_USTRINGPARAM(
701                     "com.sun.star.registry.SimpleRegistry key"
702                     " getStringListValue: underlying"
703                     " RegistryKey::getUnicodeListValue() = REG_INVALID_VALUE")),
704             static_cast< OWeakObject * >(this));
705     default:
706         throw css::registry::InvalidRegistryException(
707             (rtl::OUString(
708                 RTL_CONSTASCII_USTRINGPARAM(
709                     "com.sun.star.registry.SimpleRegistry key"
710                     " getStringListValue: underlying"
711                     " RegistryKey::getUnicodeListValue() = ")) +
712              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
713             static_cast< OWeakObject * >(this));
714     }
715     sal_uInt32 n = list.getLength();
716     if (n > SAL_MAX_INT32) {
717         throw css::registry::InvalidValueException(
718             rtl::OUString(
719                 RTL_CONSTASCII_USTRINGPARAM(
720                     "com.sun.star.registry.SimpleRegistry key"
721                     " getStringListValue: underlying"
722                     " RegistryKey::getUnicodeListValue() too large")),
723             static_cast< OWeakObject * >(this));
724     }
725     css::uno::Sequence< rtl::OUString > value(static_cast< sal_Int32 >(n));
726     for (sal_uInt32 i = 0; i < n; ++i) {
727         value[static_cast< sal_Int32 >(i)] = list.getElement(i);
728     }
729     return value;
730 }
731 
setStringListValue(css::uno::Sequence<rtl::OUString> const & seqValue)732 void Key::setStringListValue(
733     css::uno::Sequence< rtl::OUString > const & seqValue)
734 {
735     osl::MutexGuard guard(registry_->mutex_);
736     std::vector< sal_Unicode * > list;
737     for (sal_Int32 i = 0; i < seqValue.getLength(); ++i) {
738         list.push_back(const_cast< sal_Unicode * >(seqValue[i].getStr()));
739     }
740     RegError err = key_.setUnicodeListValue(
741         rtl::OUString(), list.empty() ? 0 : &list[0],
742         static_cast< sal_uInt32 >(list.size()));
743     if (err != REG_NO_ERROR) {
744         throw css::registry::InvalidRegistryException(
745             (rtl::OUString(
746                 RTL_CONSTASCII_USTRINGPARAM(
747                     "com.sun.star.registry.SimpleRegistry key"
748                     " setStringListValue: underlying"
749                     " RegistryKey::setUnicodeListValue() = ")) +
750              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
751             static_cast< OWeakObject * >(this));
752     }
753 }
754 
getBinaryValue()755 css::uno::Sequence< sal_Int8 > Key::getBinaryValue()
756 {
757     osl::MutexGuard guard(registry_->mutex_);
758     RegValueType type;
759     sal_uInt32 size;
760     RegError err = key_.getValueInfo(rtl::OUString(), &type, &size);
761     if (err != REG_NO_ERROR) {
762         throw css::registry::InvalidRegistryException(
763             (rtl::OUString(
764                 RTL_CONSTASCII_USTRINGPARAM(
765                     "com.sun.star.registry.SimpleRegistry key getBinaryValue:"
766                     " underlying RegistryKey::getValueInfo() = ")) +
767              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
768             static_cast< OWeakObject * >(this));
769     }
770     if (type != RG_VALUETYPE_BINARY) {
771         throw css::registry::InvalidValueException(
772             (rtl::OUString(
773                 RTL_CONSTASCII_USTRINGPARAM(
774                     "com.sun.star.registry.SimpleRegistry key getBinaryValue:"
775                     " underlying RegistryKey type = ")) +
776              rtl::OUString::valueOf(static_cast< sal_Int32 >(type))),
777             static_cast< OWeakObject * >(this));
778     }
779     if (size > SAL_MAX_INT32) {
780         throw css::registry::InvalidValueException(
781             rtl::OUString(
782                 RTL_CONSTASCII_USTRINGPARAM(
783                     "com.sun.star.registry.SimpleRegistry key getBinaryValue:"
784                     " underlying RegistryKey size too large")),
785             static_cast< OWeakObject * >(this));
786     }
787     css::uno::Sequence< sal_Int8 > value(static_cast< sal_Int32 >(size));
788     err = key_.getValue(rtl::OUString(), value.getArray());
789     if (err != REG_NO_ERROR) {
790         throw css::registry::InvalidRegistryException(
791             (rtl::OUString(
792                 RTL_CONSTASCII_USTRINGPARAM(
793                     "com.sun.star.registry.SimpleRegistry key getBinaryValue:"
794                     " underlying RegistryKey::getValue() = ")) +
795              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
796             static_cast< OWeakObject * >(this));
797     }
798     return value;
799 }
800 
setBinaryValue(css::uno::Sequence<sal_Int8> const & value)801 void Key::setBinaryValue(css::uno::Sequence< sal_Int8 > const & value)
802 {
803     osl::MutexGuard guard(registry_->mutex_);
804     RegError err = key_.setValue(
805         rtl::OUString(), RG_VALUETYPE_BINARY,
806         const_cast< sal_Int8 * >(value.getConstArray()),
807         static_cast< sal_uInt32 >(value.getLength()));
808     if (err != REG_NO_ERROR) {
809         throw css::registry::InvalidRegistryException(
810             (rtl::OUString(
811                 RTL_CONSTASCII_USTRINGPARAM(
812                     "com.sun.star.registry.SimpleRegistry key setBinaryValue:"
813                     " underlying RegistryKey::setValue() = ")) +
814              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
815             static_cast< OWeakObject * >(this));
816     }
817 }
818 
openKey(rtl::OUString const & aKeyName)819 css::uno::Reference< css::registry::XRegistryKey > Key::openKey(
820     rtl::OUString const & aKeyName)
821 {
822     osl::MutexGuard guard(registry_->mutex_);
823     RegistryKey key;
824     RegError err = key_.openKey(aKeyName, key);
825     switch (err) {
826     case REG_NO_ERROR:
827         return new Key(registry_, key);
828     case REG_KEY_NOT_EXISTS:
829         return css::uno::Reference< css::registry::XRegistryKey >();
830     default:
831         throw css::registry::InvalidRegistryException(
832             (rtl::OUString(
833                 RTL_CONSTASCII_USTRINGPARAM(
834                     "com.sun.star.registry.SimpleRegistry key openKey:"
835                     " underlying RegistryKey::openKey() = ")) +
836              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
837             static_cast< OWeakObject * >(this));
838     }
839 }
840 
createKey(rtl::OUString const & aKeyName)841 css::uno::Reference< css::registry::XRegistryKey > Key::createKey(
842     rtl::OUString const & aKeyName)
843 {
844     osl::MutexGuard guard(registry_->mutex_);
845     RegistryKey key;
846     RegError err = key_.createKey(aKeyName, key);
847     switch (err) {
848     case REG_NO_ERROR:
849         return new Key(registry_, key);
850     case REG_INVALID_KEYNAME:
851         return css::uno::Reference< css::registry::XRegistryKey >();
852     default:
853         throw css::registry::InvalidRegistryException(
854             (rtl::OUString(
855                 RTL_CONSTASCII_USTRINGPARAM(
856                     "com.sun.star.registry.SimpleRegistry key createKey:"
857                     " underlying RegistryKey::createKey() = ")) +
858              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
859             static_cast< OWeakObject * >(this));
860     }
861 }
862 
closeKey()863 void Key::closeKey()
864 {
865     osl::MutexGuard guard(registry_->mutex_);
866     RegError err = key_.closeKey();
867     if (err != REG_NO_ERROR) {
868         throw css::registry::InvalidRegistryException(
869             (rtl::OUString(
870                 RTL_CONSTASCII_USTRINGPARAM(
871                     "com.sun.star.registry.SimpleRegistry key closeKey:"
872                     " underlying RegistryKey::closeKey() = ")) +
873              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
874             static_cast< OWeakObject * >(this));
875     }
876 }
877 
deleteKey(rtl::OUString const & rKeyName)878 void Key::deleteKey(rtl::OUString const & rKeyName)
879 {
880     osl::MutexGuard guard(registry_->mutex_);
881     RegError err = key_.deleteKey(rKeyName);
882     if (err != REG_NO_ERROR) {
883         throw css::registry::InvalidRegistryException(
884             (rtl::OUString(
885                 RTL_CONSTASCII_USTRINGPARAM(
886                     "com.sun.star.registry.SimpleRegistry key deleteKey:"
887                     " underlying RegistryKey::deleteKey() = ")) +
888              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
889             static_cast< OWeakObject * >(this));
890     }
891 }
892 
893 css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
openKeys()894 Key::openKeys()
895 {
896     osl::MutexGuard guard(registry_->mutex_);
897     RegistryKeyArray list;
898     RegError err = key_.openSubKeys(rtl::OUString(), list);
899     if (err != REG_NO_ERROR) {
900         throw css::registry::InvalidRegistryException(
901             (rtl::OUString(
902                 RTL_CONSTASCII_USTRINGPARAM(
903                     "com.sun.star.registry.SimpleRegistry key openKeys:"
904                     " underlying RegistryKey::openSubKeys() = ")) +
905              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
906             static_cast< OWeakObject * >(this));
907     }
908     sal_uInt32 n = list.getLength();
909     if (n > SAL_MAX_INT32) {
910         throw css::registry::InvalidRegistryException(
911             rtl::OUString(
912                 RTL_CONSTASCII_USTRINGPARAM(
913                     "com.sun.star.registry.SimpleRegistry key getKeyNames:"
914                     " underlying RegistryKey::getKeyNames() too large")),
915             static_cast< OWeakObject * >(this));
916     }
917     css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
918         keys(static_cast< sal_Int32 >(n));
919     for (sal_uInt32 i = 0; i < n; ++i) {
920         keys[static_cast< sal_Int32 >(i)] = new Key(
921             registry_, list.getElement(i));
922     }
923     return keys;
924 }
925 
getKeyNames()926 css::uno::Sequence< rtl::OUString > Key::getKeyNames()
927 {
928     osl::MutexGuard guard(registry_->mutex_);
929     RegistryKeyNames list;
930     RegError err = key_.getKeyNames(rtl::OUString(), list);
931     if (err != REG_NO_ERROR) {
932         throw css::registry::InvalidRegistryException(
933             (rtl::OUString(
934                 RTL_CONSTASCII_USTRINGPARAM(
935                     "com.sun.star.registry.SimpleRegistry key getKeyNames:"
936                     " underlying RegistryKey::getKeyNames() = ")) +
937              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
938             static_cast< OWeakObject * >(this));
939     }
940     sal_uInt32 n = list.getLength();
941     if (n > SAL_MAX_INT32) {
942         throw css::registry::InvalidRegistryException(
943             rtl::OUString(
944                 RTL_CONSTASCII_USTRINGPARAM(
945                     "com.sun.star.registry.SimpleRegistry key getKeyNames:"
946                     " underlying RegistryKey::getKeyNames() too large")),
947             static_cast< OWeakObject * >(this));
948     }
949     css::uno::Sequence< rtl::OUString > names(static_cast< sal_Int32 >(n));
950     for (sal_uInt32 i = 0; i < n; ++i) {
951         names[static_cast< sal_Int32 >(i)] = list.getElement(i);
952     }
953     return names;
954 }
955 
createLink(rtl::OUString const & aLinkName,rtl::OUString const & aLinkTarget)956 sal_Bool Key::createLink(
957     rtl::OUString const & aLinkName, rtl::OUString const & aLinkTarget)
958 {
959     osl::MutexGuard guard(registry_->mutex_);
960     RegError err = key_.createLink(aLinkName, aLinkTarget);
961     switch (err) {
962     case REG_NO_ERROR:
963         return true;
964     case REG_INVALID_KEY:
965     case REG_DETECT_RECURSION:
966         throw css::registry::InvalidRegistryException(
967             (rtl::OUString(
968                 RTL_CONSTASCII_USTRINGPARAM(
969                     "com.sun.star.registry.SimpleRegistry key createLink:"
970                     " underlying RegistryKey::createLink() = ")) +
971              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
972             static_cast< OWeakObject * >(this));
973     default:
974         return false;
975     }
976 }
977 
deleteLink(rtl::OUString const & rLinkName)978 void Key::deleteLink(rtl::OUString const & rLinkName)
979 {
980     osl::MutexGuard guard(registry_->mutex_);
981     RegError err = key_.deleteLink(rLinkName);
982     if (err != REG_NO_ERROR) {
983         throw css::registry::InvalidRegistryException(
984             (rtl::OUString(
985                 RTL_CONSTASCII_USTRINGPARAM(
986                     "com.sun.star.registry.SimpleRegistry key deleteLink:"
987                     " underlying RegistryKey::deleteLink() = ")) +
988              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
989             static_cast< OWeakObject * >(this));
990     }
991 }
992 
getLinkTarget(rtl::OUString const & rLinkName)993 rtl::OUString Key::getLinkTarget(rtl::OUString const & rLinkName)
994 {
995     osl::MutexGuard guard(registry_->mutex_);
996     rtl::OUString target;
997     RegError err = key_.getLinkTarget(rLinkName, target);
998     if (err != REG_NO_ERROR) {
999         throw css::registry::InvalidRegistryException(
1000             (rtl::OUString(
1001                 RTL_CONSTASCII_USTRINGPARAM(
1002                     "com.sun.star.registry.SimpleRegistry key getLinkTarget:"
1003                     " underlying RegistryKey::getLinkTarget() = ")) +
1004              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
1005             static_cast< OWeakObject * >(this));
1006     }
1007     return target;
1008 }
1009 
getResolvedName(rtl::OUString const & aKeyName)1010 rtl::OUString Key::getResolvedName(rtl::OUString const & aKeyName)
1011 {
1012     osl::MutexGuard guard(registry_->mutex_);
1013     rtl::OUString resolved;
1014     RegError err = key_.getResolvedKeyName(aKeyName, true, resolved);
1015     if (err != REG_NO_ERROR) {
1016         throw css::registry::InvalidRegistryException(
1017             (rtl::OUString(
1018                 RTL_CONSTASCII_USTRINGPARAM(
1019                     "com.sun.star.registry.SimpleRegistry key getResolvedName:"
1020                     " underlying RegistryKey::getResolvedName() = ")) +
1021              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
1022             static_cast< OWeakObject * >(this));
1023     }
1024     return resolved;
1025 }
1026 
getURL()1027 rtl::OUString SimpleRegistry::getURL() {
1028     osl::MutexGuard guard(mutex_);
1029     return textual_.get() == 0 ? registry_.getName() : textual_->getUri();
1030 }
1031 
open(rtl::OUString const & rURL,sal_Bool bReadOnly,sal_Bool bCreate)1032 void SimpleRegistry::open(
1033     rtl::OUString const & rURL, sal_Bool bReadOnly, sal_Bool bCreate)
1034 {
1035     osl::MutexGuard guard(mutex_);
1036     if (textual_.get() != 0) {
1037         throw css::registry::InvalidRegistryException(
1038             (rtl::OUString(
1039                 RTL_CONSTASCII_USTRINGPARAM(
1040                     "com.sun.star.registry.SimpleRegistry.open(")) +
1041              rURL +
1042              rtl::OUString(
1043                 RTL_CONSTASCII_USTRINGPARAM(
1044                     "): instance already open"))),
1045             static_cast< OWeakObject * >(this));
1046     }
1047     RegError err = (rURL.getLength() == 0 && bCreate)
1048         ? REG_REGISTRY_NOT_EXISTS
1049         : registry_.open(rURL, bReadOnly ? REG_READONLY : REG_READWRITE);
1050     if (err == REG_REGISTRY_NOT_EXISTS && bCreate) {
1051         err = registry_.create(rURL);
1052     }
1053     switch (err) {
1054     case REG_NO_ERROR:
1055         break;
1056     case REG_INVALID_REGISTRY:
1057         if (bReadOnly && !bCreate) {
1058             textual_.reset(new stoc::simpleregistry::TextualServices(rURL));
1059             break;
1060         }
1061         // fall through
1062     default:
1063         throw css::registry::InvalidRegistryException(
1064             (rtl::OUString(
1065                 RTL_CONSTASCII_USTRINGPARAM(
1066                     "com.sun.star.registry.SimpleRegistry.open(")) +
1067              rURL +
1068              rtl::OUString(
1069                 RTL_CONSTASCII_USTRINGPARAM(
1070                     "): underlying Registry::open/create() = ")) +
1071              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
1072             static_cast< OWeakObject * >(this));
1073     }
1074 }
1075 
isValid()1076 sal_Bool SimpleRegistry::isValid() {
1077     osl::MutexGuard guard(mutex_);
1078     return textual_.get() != 0 || registry_.isValid();
1079 }
1080 
close()1081 void SimpleRegistry::close()
1082 {
1083     osl::MutexGuard guard(mutex_);
1084     if (textual_.get() != 0) {
1085         textual_.reset();
1086         return;
1087     }
1088     RegError err = registry_.close();
1089     if (err != REG_NO_ERROR) {
1090         throw css::registry::InvalidRegistryException(
1091             (rtl::OUString(
1092                 RTL_CONSTASCII_USTRINGPARAM(
1093                     "com.sun.star.registry.SimpleRegistry.close:"
1094                     " underlying Registry::close() = ")) +
1095              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
1096             static_cast< OWeakObject * >(this));
1097     }
1098 }
1099 
destroy()1100 void SimpleRegistry::destroy()
1101 {
1102     osl::MutexGuard guard(mutex_);
1103     if (textual_.get() != 0) {
1104         textual_.reset();
1105         return;
1106     }
1107     RegError err = registry_.destroy(rtl::OUString());
1108     if (err != REG_NO_ERROR) {
1109         throw css::registry::InvalidRegistryException(
1110             (rtl::OUString(
1111                 RTL_CONSTASCII_USTRINGPARAM(
1112                     "com.sun.star.registry.SimpleRegistry.destroy:"
1113                     " underlying Registry::destroy() = ")) +
1114              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
1115             static_cast< OWeakObject * >(this));
1116     }
1117 }
1118 
getRootKey()1119 css::uno::Reference< css::registry::XRegistryKey > SimpleRegistry::getRootKey()
1120 {
1121     osl::MutexGuard guard(mutex_);
1122     if (textual_.get() != 0) {
1123         return textual_->getRootKey();
1124     }
1125     RegistryKey root;
1126     RegError err = registry_.openRootKey(root);
1127     if (err != REG_NO_ERROR) {
1128         throw css::registry::InvalidRegistryException(
1129             (rtl::OUString(
1130                 RTL_CONSTASCII_USTRINGPARAM(
1131                     "com.sun.star.registry.SimpleRegistry.getRootKey:"
1132                     " underlying Registry::getRootKey() = ")) +
1133              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
1134             static_cast< OWeakObject * >(this));
1135     }
1136     return new Key(this, root);
1137 }
1138 
isReadOnly()1139 sal_Bool SimpleRegistry::isReadOnly()
1140 {
1141     osl::MutexGuard guard(mutex_);
1142     return textual_.get() != 0 || registry_.isReadOnly();
1143 }
1144 
mergeKey(rtl::OUString const & aKeyName,rtl::OUString const & aUrl)1145 void SimpleRegistry::mergeKey(
1146     rtl::OUString const & aKeyName, rtl::OUString const & aUrl)
1147 {
1148     osl::MutexGuard guard(mutex_);
1149     if (textual_.get() != 0) {
1150         throw css::uno::RuntimeException(
1151             rtl::OUString(
1152                 RTL_CONSTASCII_USTRINGPARAM(
1153                     "com.sun.star.registry.SimpleRegistry.mergeKey: not"
1154                     " supported for textual representation")),
1155             static_cast< cppu::OWeakObject * >(this));
1156     }
1157     RegistryKey root;
1158     RegError err = registry_.openRootKey(root);
1159     if (err == REG_NO_ERROR) {
1160         err = registry_.mergeKey(root, aKeyName, aUrl, false, false);
1161     }
1162     switch (err) {
1163     case REG_NO_ERROR:
1164     case REG_MERGE_CONFLICT:
1165         break;
1166     case REG_MERGE_ERROR:
1167         throw css::registry::MergeConflictException(
1168             rtl::OUString(
1169                 RTL_CONSTASCII_USTRINGPARAM(
1170                     "com.sun.star.registry.SimpleRegistry.mergeKey:"
1171                     " underlying Registry::mergeKey() = REG_MERGE_ERROR")),
1172             static_cast< cppu::OWeakObject * >(this));
1173     default:
1174         throw css::registry::InvalidRegistryException(
1175             (rtl::OUString(
1176                 RTL_CONSTASCII_USTRINGPARAM(
1177                     "com.sun.star.registry.SimpleRegistry.mergeKey:"
1178                     " underlying Registry::getRootKey/mergeKey() = ")) +
1179              rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
1180             static_cast< OWeakObject * >(this));
1181     }
1182 }
1183 
1184 }
1185 
1186 namespace stoc_bootstrap {
1187 
SimpleRegistry_CreateInstance(css::uno::Reference<css::uno::XComponentContext> const &)1188 css::uno::Reference< css::uno::XInterface > SimpleRegistry_CreateInstance(
1189     css::uno::Reference< css::uno::XComponentContext > const &)
1190 {
1191     return static_cast< cppu::OWeakObject * >(new SimpleRegistry);
1192 }
1193 
simreg_getSupportedServiceNames()1194 css::uno::Sequence< rtl::OUString > simreg_getSupportedServiceNames() {
1195     css::uno::Sequence< rtl::OUString > names(1);
1196     names[0] = rtl::OUString(
1197         RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry"));
1198     return names;
1199 }
1200 
simreg_getImplementationName()1201 rtl::OUString simreg_getImplementationName() {
1202     return rtl::OUString(
1203         RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.SimpleRegistry"));
1204 }
1205 
1206 }
1207