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