LibreOffice Module stoc (master) 1
simpleregistry.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#include <cstdlib>
23#include <mutex>
24#include <optional>
25#include <utility>
26#include <vector>
27
28#include <com/sun/star/lang/XServiceInfo.hpp>
29#include <com/sun/star/registry/InvalidRegistryException.hpp>
30#include <com/sun/star/registry/InvalidValueException.hpp>
31#include <com/sun/star/registry/RegistryKeyType.hpp>
32#include <com/sun/star/registry/XRegistryKey.hpp>
33#include <com/sun/star/registry/XSimpleRegistry.hpp>
34#include <com/sun/star/uno/Reference.hxx>
35#include <com/sun/star/uno/RuntimeException.hpp>
36#include <com/sun/star/uno/XInterface.hpp>
37#include <com/sun/star/uno/Sequence.hxx>
41#include <cppuhelper/weak.hxx>
42#include <registry/registry.hxx>
43#include <registry/regtype.h>
44#include <rtl/ref.hxx>
45#include <rtl/string.h>
46#include <rtl/string.hxx>
47#include <rtl/textcvt.h>
48#include <rtl/textenc.h>
49#include <rtl/ustring.h>
50#include <rtl/ustring.hxx>
51#include <sal/types.h>
52
53namespace com::sun::star::uno { class XComponentContext; }
54
55namespace {
56
57class SimpleRegistry:
58 public cppu::WeakImplHelper<
59 css::registry::XSimpleRegistry, css::lang::XServiceInfo >
60{
61public:
62 SimpleRegistry(): registry_(Registry()) {}
63
64 ~SimpleRegistry() {
65 std::scoped_lock guard(mutex_);
66 registry_.reset();
67 }
68
69 std::mutex mutex_;
70
71private:
72 virtual OUString SAL_CALL getURL() override;
73
74 virtual void SAL_CALL open(
75 OUString const & rURL, sal_Bool bReadOnly, sal_Bool bCreate) override;
76
77 virtual sal_Bool SAL_CALL isValid() override;
78
79 virtual void SAL_CALL close() override;
80
81 virtual void SAL_CALL destroy() override;
82
83 virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL
84 getRootKey() override;
85
86 virtual sal_Bool SAL_CALL isReadOnly() override;
87
88 virtual void SAL_CALL mergeKey(
89 OUString const & aKeyName, OUString const & aUrl) override;
90
91 virtual OUString SAL_CALL getImplementationName() override
92 { return "com.sun.star.comp.stoc.SimpleRegistry"; }
93
94 virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
95 { return cppu::supportsService(this, ServiceName); }
96
97 virtual css::uno::Sequence< OUString > SAL_CALL
99 {
100 css::uno::Sequence< OUString > names { "com.sun.star.registry.SimpleRegistry" };
101 return names;
102 }
103
104 std::optional<Registry> registry_;
105};
106
107class Key: public cppu::WeakImplHelper< css::registry::XRegistryKey > {
108public:
109 Key(
111 RegistryKey const & key):
112 registry_(std::move(registry)), key_(key) {}
113
114 ~Key() {
115 std::scoped_lock guard(registry_->mutex_);
116 key_.reset();
117 }
118
119private:
120 virtual OUString SAL_CALL getKeyName() override;
121
122 virtual sal_Bool SAL_CALL isReadOnly() override;
123
124 virtual sal_Bool SAL_CALL isValid() override;
125
126 virtual css::registry::RegistryKeyType SAL_CALL getKeyType(
127 OUString const & rKeyName) override;
128
129 virtual css::registry::RegistryValueType SAL_CALL getValueType() override;
130
131 virtual sal_Int32 SAL_CALL getLongValue() override;
132
133 virtual void SAL_CALL setLongValue(sal_Int32 value) override;
134
135 virtual css::uno::Sequence< sal_Int32 > SAL_CALL getLongListValue() override;
136
137 virtual void SAL_CALL setLongListValue(
138 css::uno::Sequence< sal_Int32 > const & seqValue) override;
139
140 virtual OUString SAL_CALL getAsciiValue() override;
141
142 virtual void SAL_CALL setAsciiValue(OUString const & value) override;
143
144 virtual css::uno::Sequence< OUString > SAL_CALL getAsciiListValue() override;
145
146 virtual void SAL_CALL setAsciiListValue(
147 css::uno::Sequence< OUString > const & seqValue) override;
148
149 virtual OUString SAL_CALL getStringValue() override;
150
151 virtual void SAL_CALL setStringValue(OUString const & value) override;
152
153 virtual css::uno::Sequence< OUString > SAL_CALL getStringListValue() override;
154
155 virtual void SAL_CALL setStringListValue(
156 css::uno::Sequence< OUString > const & seqValue) override;
157
158 virtual css::uno::Sequence< sal_Int8 > SAL_CALL getBinaryValue() override;
159
160 virtual void SAL_CALL setBinaryValue(
161 css::uno::Sequence< sal_Int8 > const & value) override;
162
163 virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL openKey(
164 OUString const & aKeyName) override;
165
166 virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL
167 createKey(OUString const & aKeyName) override;
168
169 virtual void SAL_CALL closeKey() override;
170
171 virtual void SAL_CALL deleteKey(OUString const & rKeyName) override;
172
173 virtual
174 css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
175 SAL_CALL openKeys() override;
176
177 virtual css::uno::Sequence< OUString > SAL_CALL getKeyNames() override;
178
179 virtual sal_Bool SAL_CALL createLink(
180 OUString const & aLinkName, OUString const & aLinkTarget) override;
181
182 virtual void SAL_CALL deleteLink(OUString const & rLinkName) override;
183
184 virtual OUString SAL_CALL getLinkTarget(OUString const & rLinkName) override;
185
186 virtual OUString SAL_CALL getResolvedName(OUString const & aKeyName) override;
187
189 std::optional<RegistryKey> key_;
190};
191
192OUString Key::getKeyName() {
193 std::scoped_lock guard(registry_->mutex_);
194 return key_->getName();
195}
196
197sal_Bool Key::isReadOnly()
198{
199 std::scoped_lock guard(registry_->mutex_);
200 return key_->isReadOnly();
201}
202
203sal_Bool Key::isValid() {
204 std::scoped_lock guard(registry_->mutex_);
205 return key_->isValid();
206}
207
208css::registry::RegistryKeyType Key::getKeyType(OUString const & )
209{
210 return css::registry::RegistryKeyType_KEY;
211}
212
213css::registry::RegistryValueType Key::getValueType()
214{
215 std::scoped_lock guard(registry_->mutex_);
217 sal_uInt32 size;
218 RegError err = key_->getValueInfo(OUString(), &type, &size);
219 switch (err) {
220 case RegError::NO_ERROR:
221 break;
222 case RegError::INVALID_VALUE:
223 type = RegValueType::NOT_DEFINED;
224 break;
225 default:
226 throw css::registry::InvalidRegistryException(
227 "com.sun.star.registry.SimpleRegistry key getValueType:"
228 " underlying RegistryKey::getValueInfo() = " + OUString::number(static_cast<int>(err)),
229 getXWeak());
230 }
231 switch (type) {
232 default:
233 std::abort(); // this cannot happen
234 // pseudo-fall-through to avoid warnings on MSC
235 case RegValueType::NOT_DEFINED:
236 return css::registry::RegistryValueType_NOT_DEFINED;
237 case RegValueType::LONG:
238 return css::registry::RegistryValueType_LONG;
239 case RegValueType::STRING:
240 return css::registry::RegistryValueType_ASCII;
241 case RegValueType::UNICODE:
242 return css::registry::RegistryValueType_STRING;
243 case RegValueType::BINARY:
244 return css::registry::RegistryValueType_BINARY;
245 case RegValueType::LONGLIST:
246 return css::registry::RegistryValueType_LONGLIST;
247 case RegValueType::STRINGLIST:
248 return css::registry::RegistryValueType_ASCIILIST;
249 case RegValueType::UNICODELIST:
250 return css::registry::RegistryValueType_STRINGLIST;
251 }
252}
253
254sal_Int32 Key::getLongValue()
255{
256 std::scoped_lock guard(registry_->mutex_);
257 sal_Int32 value;
258 RegError err = key_->getValue(OUString(), &value);
259 switch (err) {
260 case RegError::NO_ERROR:
261 break;
262 case RegError::INVALID_VALUE:
263 throw css::registry::InvalidValueException(
264 "com.sun.star.registry.SimpleRegistry key getLongValue:"
265 " underlying RegistryKey::getValue() = RegError::INVALID_VALUE",
266 getXWeak());
267 default:
268 throw css::registry::InvalidRegistryException(
269 "com.sun.star.registry.SimpleRegistry key getLongValue:"
270 " underlying RegistryKey::getValue() = " + OUString::number(static_cast<int>(err)),
271 getXWeak());
272 }
273 return value;
274}
275
276void Key::setLongValue(sal_Int32 value)
277{
278 std::scoped_lock guard(registry_->mutex_);
280 OUString(), RegValueType::LONG, &value, sizeof (sal_Int32));
281 if (err != RegError::NO_ERROR) {
282 throw css::registry::InvalidRegistryException(
283 "com.sun.star.registry.SimpleRegistry key setLongValue:"
284 " underlying RegistryKey::setValue() = " + OUString::number(static_cast<int>(err)),
285 getXWeak());
286 }
287}
288
289css::uno::Sequence< sal_Int32 > Key::getLongListValue()
290{
291 std::scoped_lock guard(registry_->mutex_);
293 RegError err = key_->getLongListValue(OUString(), list);
294 switch (err) {
295 case RegError::NO_ERROR:
296 break;
297 case RegError::VALUE_NOT_EXISTS:
298 return css::uno::Sequence< sal_Int32 >();
299 case RegError::INVALID_VALUE:
300 throw css::registry::InvalidValueException(
301 "com.sun.star.registry.SimpleRegistry key getLongListValue:"
302 " underlying RegistryKey::getLongListValue() ="
303 " RegError::INVALID_VALUE",
304 getXWeak());
305 default:
306 throw css::registry::InvalidRegistryException(
307 "com.sun.star.registry.SimpleRegistry key getLongListValue:"
308 " underlying RegistryKey::getLongListValue() = " + OUString::number(static_cast<int>(err)),
309 getXWeak());
310 }
311 sal_uInt32 n = list.getLength();
312 if (n > SAL_MAX_INT32) {
313 throw css::registry::InvalidValueException(
314 "com.sun.star.registry.SimpleRegistry key getLongListValue:"
315 " underlying RegistryKey::getLongListValue() too large",
316 getXWeak());
317 }
318 css::uno::Sequence< sal_Int32 > value(static_cast< sal_Int32 >(n));
319 auto aValueRange = asNonConstRange(value);
320 for (sal_uInt32 i = 0; i < n; ++i) {
321 aValueRange[static_cast< sal_Int32 >(i)] = list.getElement(i);
322 }
323 return value;
324}
325
326void Key::setLongListValue(css::uno::Sequence< sal_Int32 > const & seqValue)
327{
328 std::scoped_lock guard(registry_->mutex_);
330 OUString(), seqValue.getConstArray(), static_cast< sal_uInt32 >(seqValue.getLength()));
331 if (err != RegError::NO_ERROR) {
332 throw css::registry::InvalidRegistryException(
333 "com.sun.star.registry.SimpleRegistry key setLongListValue:"
334 " underlying RegistryKey::setLongListValue() = " + OUString::number(static_cast<int>(err)),
335 getXWeak());
336 }
337}
338
339OUString Key::getAsciiValue()
340{
341 std::scoped_lock guard(registry_->mutex_);
343 sal_uInt32 size;
344 RegError err = key_->getValueInfo(OUString(), &type, &size);
345 if (err != RegError::NO_ERROR) {
346 throw css::registry::InvalidRegistryException(
347 "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
348 " underlying RegistryKey::getValueInfo() = " + OUString::number(static_cast<int>(err)),
349 getXWeak());
350 }
351 if (type != RegValueType::STRING) {
352 throw css::registry::InvalidValueException(
353 "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
354 " underlying RegistryKey type = " + OUString::number(static_cast<int>(type)),
355 getXWeak());
356 }
357 // size contains terminating null (error in underlying registry.cxx):
358 if (size == 0) {
359 throw css::registry::InvalidValueException(
360 "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
361 " underlying RegistryKey size 0 cannot happen due to"
362 " design error",
363 getXWeak());
364 }
365 if (size > SAL_MAX_INT32) {
366 throw css::registry::InvalidValueException(
367 "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
368 " underlying RegistryKey size too large",
369 getXWeak());
370 }
371 std::vector< char > list(size);
372 err = key_->getValue(OUString(), list.data());
373 if (err != RegError::NO_ERROR) {
374 throw css::registry::InvalidRegistryException(
375 "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
376 " underlying RegistryKey::getValue() = " + OUString::number(static_cast<int>(err)),
377 getXWeak());
378 }
379 if (list[size - 1] != '\0') {
380 throw css::registry::InvalidValueException(
381 "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
382 " underlying RegistryKey value must be null-terminated due"
383 " to design error",
384 getXWeak());
385 }
386 OUString value;
387 if (!rtl_convertStringToUString(
388 &value.pData, list.data(),
389 static_cast< sal_Int32 >(size - 1), RTL_TEXTENCODING_UTF8,
390 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
391 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
392 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
393 {
394 throw css::registry::InvalidValueException(
395 "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
396 " underlying RegistryKey not UTF-8",
397 getXWeak());
398 }
399 return value;
400}
401
402void Key::setAsciiValue(OUString const & value)
403{
404 std::scoped_lock guard(registry_->mutex_);
405 OString utf8;
406 if (!value.convertToString(
407 &utf8, RTL_TEXTENCODING_UTF8,
408 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
409 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
410 {
411 throw css::uno::RuntimeException(
412 "com.sun.star.registry.SimpleRegistry key setAsciiValue:"
413 " value not UTF-16",
414 getXWeak());
415 }
417 OUString(), RegValueType::STRING,
418 const_cast< char * >(utf8.getStr()), utf8.getLength() + 1);
419 // +1 for terminating null (error in underlying registry.cxx)
420 if (err != RegError::NO_ERROR) {
421 throw css::registry::InvalidRegistryException(
422 "com.sun.star.registry.SimpleRegistry key setAsciiValue:"
423 " underlying RegistryKey::setValue() = " + OUString::number(static_cast<int>(err)),
424 getXWeak());
425 }
426}
427
428css::uno::Sequence< OUString > Key::getAsciiListValue()
429{
430 std::scoped_lock guard(registry_->mutex_);
432 RegError err = key_->getStringListValue(OUString(), list);
433 switch (err) {
434 case RegError::NO_ERROR:
435 break;
436 case RegError::VALUE_NOT_EXISTS:
437 return css::uno::Sequence< OUString >();
438 case RegError::INVALID_VALUE:
439 throw css::registry::InvalidValueException(
440 "com.sun.star.registry.SimpleRegistry key"
441 " getAsciiListValue: underlying"
442 " RegistryKey::getStringListValue() = RegError::INVALID_VALUE",
443 getXWeak());
444 default:
445 throw css::registry::InvalidRegistryException(
446 "com.sun.star.registry.SimpleRegistry key"
447 " getAsciiListValue: underlying"
448 " RegistryKey::getStringListValue() = " + OUString::number(static_cast<int>(err)),
449 getXWeak());
450 }
451 sal_uInt32 n = list.getLength();
452 if (n > SAL_MAX_INT32) {
453 throw css::registry::InvalidValueException(
454 "com.sun.star.registry.SimpleRegistry key"
455 " getAsciiListValue: underlying"
456 " RegistryKey::getStringListValue() too large",
457 getXWeak());
458 }
459 css::uno::Sequence< OUString > value(static_cast< sal_Int32 >(n));
460 auto aValueRange = asNonConstRange(value);
461 for (sal_uInt32 i = 0; i < n; ++i) {
462 char * el = list.getElement(i);
463 sal_Int32 size = rtl_str_getLength(el);
464 if (!rtl_convertStringToUString(
465 &aValueRange[static_cast< sal_Int32 >(i)].pData, el, size,
466 RTL_TEXTENCODING_UTF8,
467 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
468 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
469 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
470 {
471 throw css::registry::InvalidValueException(
472 "com.sun.star.registry.SimpleRegistry key"
473 " getAsciiListValue: underlying RegistryKey not"
474 " UTF-8",
475 getXWeak());
476 }
477 }
478 return value;
479}
480
481void Key::setAsciiListValue(
482 css::uno::Sequence< OUString > const & seqValue)
483{
484 std::scoped_lock guard(registry_->mutex_);
485 std::vector< OString > list;
486 for (const auto& rValue : seqValue) {
487 OString utf8;
488 if (!rValue.convertToString(
489 &utf8, RTL_TEXTENCODING_UTF8,
490 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
491 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
492 {
493 throw css::uno::RuntimeException(
494 "com.sun.star.registry.SimpleRegistry key"
495 " setAsciiListValue: value not UTF-16",
496 getXWeak());
497 }
498 list.push_back(utf8);
499 }
500 std::vector< char * > list2;
501 for (const auto& rItem : list)
502 {
503 list2.push_back(const_cast< char * >(rItem.getStr()));
504 }
506 OUString(), list2.data(), static_cast< sal_uInt32 >(list2.size()));
507 if (err != RegError::NO_ERROR) {
508 throw css::registry::InvalidRegistryException(
509 "com.sun.star.registry.SimpleRegistry key"
510 " setAsciiListValue: underlying"
511 " RegistryKey::setStringListValue() = " + OUString::number(static_cast<int>(err)),
512 getXWeak());
513 }
514}
515
516OUString Key::getStringValue()
517{
518 std::scoped_lock guard(registry_->mutex_);
520 sal_uInt32 size;
521 RegError err = key_->getValueInfo(OUString(), &type, &size);
522 if (err != RegError::NO_ERROR) {
523 throw css::registry::InvalidRegistryException(
524 "com.sun.star.registry.SimpleRegistry key getStringValue:"
525 " underlying RegistryKey::getValueInfo() = " + OUString::number(static_cast<int>(err)),
526 getXWeak());
527 }
528 if (type != RegValueType::UNICODE) {
529 throw css::registry::InvalidValueException(
530 "com.sun.star.registry.SimpleRegistry key getStringValue:"
531 " underlying RegistryKey type = " + OUString::number(static_cast<int>(type)),
532 getXWeak());
533 }
534 // size contains terminating null and is *2 (error in underlying
535 // registry.cxx):
536 if (size == 0 || (size & 1) == 1) {
537 throw css::registry::InvalidValueException(
538 "com.sun.star.registry.SimpleRegistry key getStringValue:"
539 " underlying RegistryKey size 0 or odd cannot happen due to"
540 " design error",
541 getXWeak());
542 }
543 if (size > SAL_MAX_INT32) {
544 throw css::registry::InvalidValueException(
545 "com.sun.star.registry.SimpleRegistry key getStringValue:"
546 " underlying RegistryKey size too large",
547 getXWeak());
548 }
549 std::vector< sal_Unicode > list(size);
550 err = key_->getValue(OUString(), list.data());
551 if (err != RegError::NO_ERROR) {
552 throw css::registry::InvalidRegistryException(
553 "com.sun.star.registry.SimpleRegistry key getStringValue:"
554 " underlying RegistryKey::getValue() = " + OUString::number(static_cast<int>(err)),
555 getXWeak());
556 }
557 if (list[size/2 - 1] != 0) {
558 throw css::registry::InvalidValueException(
559 "com.sun.star.registry.SimpleRegistry key getStringValue:"
560 " underlying RegistryKey value must be null-terminated due"
561 " to design error",
562 getXWeak());
563 }
564 return OUString(list.data(), static_cast< sal_Int32 >(size/2 - 1));
565}
566
567void Key::setStringValue(OUString const & value)
568{
569 std::scoped_lock guard(registry_->mutex_);
571 OUString(), RegValueType::UNICODE,
572 const_cast< sal_Unicode * >(value.getStr()),
573 (value.getLength() + 1) * sizeof (sal_Unicode));
574 // +1 for terminating null (error in underlying registry.cxx)
575 if (err != RegError::NO_ERROR) {
576 throw css::registry::InvalidRegistryException(
577 "com.sun.star.registry.SimpleRegistry key setStringValue:"
578 " underlying RegistryKey::setValue() = " + OUString::number(static_cast<int>(err)),
579 getXWeak());
580 }
581}
582
583css::uno::Sequence< OUString > Key::getStringListValue()
584{
585 std::scoped_lock guard(registry_->mutex_);
587 RegError err = key_->getUnicodeListValue(OUString(), list);
588 switch (err) {
589 case RegError::NO_ERROR:
590 break;
591 case RegError::VALUE_NOT_EXISTS:
592 return css::uno::Sequence< OUString >();
593 case RegError::INVALID_VALUE:
594 throw css::registry::InvalidValueException(
595 "com.sun.star.registry.SimpleRegistry key"
596 " getStringListValue: underlying"
597 " RegistryKey::getUnicodeListValue() = RegError::INVALID_VALUE",
598 getXWeak());
599 default:
600 throw css::registry::InvalidRegistryException(
601 "com.sun.star.registry.SimpleRegistry key"
602 " getStringListValue: underlying"
603 " RegistryKey::getUnicodeListValue() = " + OUString::number(static_cast<int>(err)),
604 getXWeak());
605 }
606 sal_uInt32 n = list.getLength();
607 if (n > SAL_MAX_INT32) {
608 throw css::registry::InvalidValueException(
609 "com.sun.star.registry.SimpleRegistry key"
610 " getStringListValue: underlying"
611 " RegistryKey::getUnicodeListValue() too large",
612 getXWeak());
613 }
614 css::uno::Sequence< OUString > value(static_cast< sal_Int32 >(n));
615 auto aValueRange = asNonConstRange(value);
616 for (sal_uInt32 i = 0; i < n; ++i) {
617 aValueRange[static_cast< sal_Int32 >(i)] = list.getElement(i);
618 }
619 return value;
620}
621
622void Key::setStringListValue(
623 css::uno::Sequence< OUString > const & seqValue)
624{
625 std::scoped_lock guard(registry_->mutex_);
626 std::vector< sal_Unicode * > list;
627 list.reserve(seqValue.getLength());
628 std::transform(seqValue.begin(), seqValue.end(), std::back_inserter(list),
629 [](const OUString& rValue) -> sal_Unicode* { return const_cast<sal_Unicode*>(rValue.getStr()); });
631 OUString(), list.data(), static_cast< sal_uInt32 >(list.size()));
632 if (err != RegError::NO_ERROR) {
633 throw css::registry::InvalidRegistryException(
634 "com.sun.star.registry.SimpleRegistry key"
635 " setStringListValue: underlying"
636 " RegistryKey::setUnicodeListValue() = " + OUString::number(static_cast<int>(err)),
637 getXWeak());
638 }
639}
640
641css::uno::Sequence< sal_Int8 > Key::getBinaryValue()
642{
643 std::scoped_lock guard(registry_->mutex_);
645 sal_uInt32 size;
646 RegError err = key_->getValueInfo(OUString(), &type, &size);
647 if (err != RegError::NO_ERROR) {
648 throw css::registry::InvalidRegistryException(
649 "com.sun.star.registry.SimpleRegistry key getBinaryValue:"
650 " underlying RegistryKey::getValueInfo() = " + OUString::number(static_cast<int>(err)),
651 getXWeak());
652 }
653 if (type != RegValueType::BINARY) {
654 throw css::registry::InvalidValueException(
655 "com.sun.star.registry.SimpleRegistry key getBinaryValue:"
656 " underlying RegistryKey type = " + OUString::number(static_cast<int>(type)),
657 getXWeak());
658 }
659 if (size > SAL_MAX_INT32) {
660 throw css::registry::InvalidValueException(
661 "com.sun.star.registry.SimpleRegistry key getBinaryValue:"
662 " underlying RegistryKey size too large",
663 getXWeak());
664 }
665 css::uno::Sequence< sal_Int8 > value(static_cast< sal_Int32 >(size));
666 err = key_->getValue(OUString(), value.getArray());
667 if (err != RegError::NO_ERROR) {
668 throw css::registry::InvalidRegistryException(
669 "com.sun.star.registry.SimpleRegistry key getBinaryValue:"
670 " underlying RegistryKey::getValue() = " + OUString::number(static_cast<int>(err)),
671 getXWeak());
672 }
673 return value;
674}
675
676void Key::setBinaryValue(css::uno::Sequence< sal_Int8 > const & value)
677{
678 std::scoped_lock guard(registry_->mutex_);
680 OUString(), RegValueType::BINARY,
681 const_cast< sal_Int8 * >(value.getConstArray()),
682 static_cast< sal_uInt32 >(value.getLength()));
683 if (err != RegError::NO_ERROR) {
684 throw css::registry::InvalidRegistryException(
685 "com.sun.star.registry.SimpleRegistry key setBinaryValue:"
686 " underlying RegistryKey::setValue() = " + OUString::number(static_cast<int>(err)),
687 getXWeak());
688 }
689}
690
691css::uno::Reference< css::registry::XRegistryKey > Key::openKey(
692 OUString const & aKeyName)
693{
694 std::scoped_lock guard(registry_->mutex_);
695 RegistryKey key;
696 RegError err = key_->openKey(aKeyName, key);
697 switch (err) {
698 case RegError::NO_ERROR:
699 return new Key(registry_, key);
700 case RegError::KEY_NOT_EXISTS:
701 return css::uno::Reference< css::registry::XRegistryKey >();
702 default:
703 throw css::registry::InvalidRegistryException(
704 "com.sun.star.registry.SimpleRegistry key openKey:"
705 " underlying RegistryKey::openKey() = " + OUString::number(static_cast<int>(err)),
706 getXWeak());
707 }
708}
709
710css::uno::Reference< css::registry::XRegistryKey > Key::createKey(
711 OUString const & aKeyName)
712{
713 std::scoped_lock guard(registry_->mutex_);
714 RegistryKey key;
715 RegError err = key_->createKey(aKeyName, key);
716 switch (err) {
717 case RegError::NO_ERROR:
718 return new Key(registry_, key);
719 case RegError::INVALID_KEYNAME:
720 return css::uno::Reference< css::registry::XRegistryKey >();
721 default:
722 throw css::registry::InvalidRegistryException(
723 "com.sun.star.registry.SimpleRegistry key createKey:"
724 " underlying RegistryKey::createKey() = " + OUString::number(static_cast<int>(err)),
725 getXWeak());
726 }
727}
728
729void Key::closeKey()
730{
731 std::scoped_lock guard(registry_->mutex_);
733 if (err != RegError::NO_ERROR) {
734 throw css::registry::InvalidRegistryException(
735 "com.sun.star.registry.SimpleRegistry key closeKey:"
736 " underlying RegistryKey::closeKey() = " + OUString::number(static_cast<int>(err)),
737 getXWeak());
738 }
739}
740
741void Key::deleteKey(OUString const & rKeyName)
742{
743 std::scoped_lock guard(registry_->mutex_);
744 RegError err = key_->deleteKey(rKeyName);
745 if (err != RegError::NO_ERROR) {
746 throw css::registry::InvalidRegistryException(
747 "com.sun.star.registry.SimpleRegistry key deleteKey:"
748 " underlying RegistryKey::deleteKey() = " + OUString::number(static_cast<int>(err)),
749 getXWeak());
750 }
751}
752
753css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
754Key::openKeys()
755{
756 std::scoped_lock guard(registry_->mutex_);
757 RegistryKeyArray list;
758 RegError err = key_->openSubKeys(OUString(), list);
759 if (err != RegError::NO_ERROR) {
760 throw css::registry::InvalidRegistryException(
761 "com.sun.star.registry.SimpleRegistry key openKeys:"
762 " underlying RegistryKey::openSubKeys() = " + OUString::number(static_cast<int>(err)),
763 getXWeak());
764 }
765 sal_uInt32 n = list.getLength();
766 if (n > SAL_MAX_INT32) {
767 throw css::registry::InvalidRegistryException(
768 "com.sun.star.registry.SimpleRegistry key getKeyNames:"
769 " underlying RegistryKey::getKeyNames() too large",
770 getXWeak());
771 }
772 css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
773 keys(static_cast< sal_Int32 >(n));
774 auto aKeysRange = asNonConstRange(keys);
775 for (sal_uInt32 i = 0; i < n; ++i) {
776 aKeysRange[static_cast< sal_Int32 >(i)] = new Key(
777 registry_, list.getElement(i));
778 }
779 return keys;
780}
781
782css::uno::Sequence< OUString > Key::getKeyNames()
783{
784 std::scoped_lock guard(registry_->mutex_);
785 RegistryKeyNames list;
786 RegError err = key_->getKeyNames(OUString(), list);
787 if (err != RegError::NO_ERROR) {
788 throw css::registry::InvalidRegistryException(
789 "com.sun.star.registry.SimpleRegistry key getKeyNames:"
790 " underlying RegistryKey::getKeyNames() = " + OUString::number(static_cast<int>(err)),
791 getXWeak());
792 }
793 sal_uInt32 n = list.getLength();
794 if (n > SAL_MAX_INT32) {
795 throw css::registry::InvalidRegistryException(
796 "com.sun.star.registry.SimpleRegistry key getKeyNames:"
797 " underlying RegistryKey::getKeyNames() too large",
798 getXWeak());
799 }
800 css::uno::Sequence< OUString > names(static_cast< sal_Int32 >(n));
801 auto aNamesRange = asNonConstRange(names);
802 for (sal_uInt32 i = 0; i < n; ++i) {
803 aNamesRange[static_cast< sal_Int32 >(i)] = list.getElement(i);
804 }
805 return names;
806}
807
808sal_Bool Key::createLink(
809 OUString const & /*aLinkName*/, OUString const & /*aLinkTarget*/)
810{
811 throw css::registry::InvalidRegistryException(
812 "com.sun.star.registry.SimpleRegistry key createLink: links are no longer supported",
813 getXWeak());
814}
815
816void Key::deleteLink(OUString const & /*rLinkName*/)
817{
818 throw css::registry::InvalidRegistryException(
819 "com.sun.star.registry.SimpleRegistry key deleteLink: links are no longer supported",
820 getXWeak());
821}
822
823OUString Key::getLinkTarget(OUString const & /*rLinkName*/)
824{
825 throw css::registry::InvalidRegistryException(
826 "com.sun.star.registry.SimpleRegistry key getLinkTarget: links are no longer supported",
827 getXWeak());
828}
829
830OUString Key::getResolvedName(OUString const & aKeyName)
831{
832 std::scoped_lock guard(registry_->mutex_);
833 OUString resolved;
834 RegError err = key_->getResolvedKeyName(aKeyName, resolved);
835 if (err != RegError::NO_ERROR) {
836 throw css::registry::InvalidRegistryException(
837 "com.sun.star.registry.SimpleRegistry key getResolvedName:"
838 " underlying RegistryKey::getResolvedName() = " + OUString::number(static_cast<int>(err)),
839 getXWeak());
840 }
841 return resolved;
842}
843
844OUString SimpleRegistry::getURL() {
845 std::scoped_lock guard(mutex_);
846 return registry_->getName();
847}
848
849void SimpleRegistry::open(
850 OUString const & rURL, sal_Bool bReadOnly, sal_Bool bCreate)
851{
852 std::scoped_lock guard(mutex_);
853 RegError err = (rURL.isEmpty() && bCreate)
854 ? RegError::REGISTRY_NOT_EXISTS
855 : registry_->open(rURL, bReadOnly ? RegAccessMode::READONLY : RegAccessMode::READWRITE);
856 if (err == RegError::REGISTRY_NOT_EXISTS && bCreate) {
857 err = registry_->create(rURL);
858 }
859 if (err != RegError::NO_ERROR) {
860 throw css::registry::InvalidRegistryException(
861 "com.sun.star.registry.SimpleRegistry.open(" + rURL +
862 "): underlying Registry::open/create() = " + OUString::number(static_cast<int>(err)),
863 getXWeak());
864 }
865}
866
867sal_Bool SimpleRegistry::isValid() {
868 std::scoped_lock guard(mutex_);
869 return registry_->isValid();
870}
871
872void SimpleRegistry::close()
873{
874 std::scoped_lock guard(mutex_);
875 RegError err = registry_->close();
876 if (err != RegError::NO_ERROR) {
877 throw css::registry::InvalidRegistryException(
878 "com.sun.star.registry.SimpleRegistry.close:"
879 " underlying Registry::close() = " + OUString::number(static_cast<int>(err)),
880 getXWeak());
881 }
882}
883
884void SimpleRegistry::destroy()
885{
886 std::scoped_lock guard(mutex_);
887 RegError err = registry_->destroy(OUString());
888 if (err != RegError::NO_ERROR) {
889 throw css::registry::InvalidRegistryException(
890 "com.sun.star.registry.SimpleRegistry.destroy:"
891 " underlying Registry::destroy() = " + OUString::number(static_cast<int>(err)),
892 getXWeak());
893 }
894}
895
896css::uno::Reference< css::registry::XRegistryKey > SimpleRegistry::getRootKey()
897{
898 std::scoped_lock guard(mutex_);
899 RegistryKey root;
900 RegError err = registry_->openRootKey(root);
901 if (err != RegError::NO_ERROR) {
902 throw css::registry::InvalidRegistryException(
903 "com.sun.star.registry.SimpleRegistry.getRootKey:"
904 " underlying Registry::getRootKey() = " + OUString::number(static_cast<int>(err)),
905 getXWeak());
906 }
907 return new Key(this, root);
908}
909
910sal_Bool SimpleRegistry::isReadOnly()
911{
912 std::scoped_lock guard(mutex_);
913 return registry_->isReadOnly();
914}
915
916void SimpleRegistry::mergeKey(
917 OUString const &, OUString const &)
918{
919 throw css::uno::RuntimeException("css.registry.SimpleRegistry::mergeKey: not implemented");
920}
921
922}
923
924extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
926 SAL_UNUSED_PARAMETER css::uno::XComponentContext *,
927 css::uno::Sequence<css::uno::Any> const &)
928{
929 return cppu::acquire(new SimpleRegistry);
930}
931
932/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
struct _ADOKey Key
sal_uInt32 getLength() const
RegistryKey getElement(sal_uInt32 index)
OUString getElement(sal_uInt32 index)
sal_uInt32 getLength() const
RegError getKeyNames(const OUString &keyName, RegistryKeyNames &rSubKeyNames)
RegError openKey(const OUString &keyName, RegistryKey &rOpenKey)
RegError deleteKey(const OUString &keyName)
RegError getResolvedKeyName(const OUString &keyName, OUString &rResolvedName) const
RegError closeKey()
RegError getLongListValue(const OUString &keyName, RegistryValueList< sal_Int32 > &rValueList)
OUString getName()
RegError getValueInfo(const OUString &keyName, RegValueType *pValueType, sal_uInt32 *pValueSize)
bool isValid() const
RegError getUnicodeListValue(const OUString &keyName, RegistryValueList< sal_Unicode * > &rValueList)
RegError setValue(const OUString &keyName, RegValueType valueType, RegValue pValue, sal_uInt32 valueSize)
RegError setStringListValue(const OUString &keyName, char **pValueList, sal_uInt32 len)
RegError getValue(const OUString &keyName, RegValue pValue)
bool isReadOnly() const
RegError openSubKeys(const OUString &keyName, RegistryKeyArray &rSubKeys)
RegError setLongListValue(const OUString &keyName, sal_Int32 const *pValueList, sal_uInt32 len)
RegError setUnicodeListValue(const OUString &keyName, sal_Unicode **pValueList, sal_uInt32 len)
RegError createKey(const OUString &keyName, RegistryKey &rNewKey)
RegError getStringListValue(const OUString &keyName, RegistryValueList< char * > &rValueList)
ValueType getElement(sal_uInt32 index)
sal_uInt32 getLength()
Any value
std::mutex mutex_
bool close
sal_Int64 n
RegistryKey key_
err
size
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
RegError REGISTRY_CALLTYPE setLongListValue(RegKeyHandle hKey, rtl_uString *keyName, sal_Int32 const *pValueList, sal_uInt32 len)
RegError REGISTRY_CALLTYPE createKey(RegKeyHandle hKey, rtl_uString *keyName, RegKeyHandle *phNewKey)
RegError REGISTRY_CALLTYPE setStringListValue(RegKeyHandle hKey, rtl_uString *keyName, char **pValueList, sal_uInt32 len)
RegError REGISTRY_CALLTYPE getStringListValue(RegKeyHandle hKey, rtl_uString *keyName, char ***pValueList, sal_uInt32 *pLen)
RegError REGISTRY_CALLTYPE getKeyNames(RegKeyHandle hKey, rtl_uString *keyName, rtl_uString ***pSubKeyNames, sal_uInt32 *pnSubKeys)
RegError REGISTRY_CALLTYPE getLongListValue(RegKeyHandle hKey, rtl_uString *keyName, sal_Int32 **pValueList, sal_uInt32 *pLen)
RegError REGISTRY_CALLTYPE getKeyName(RegKeyHandle hKey, rtl_uString **pKeyName)
RegError REGISTRY_CALLTYPE deleteKey(RegKeyHandle hKey, rtl_uString *keyName)
RegError REGISTRY_CALLTYPE openKey(RegKeyHandle hKey, rtl_uString *keyName, RegKeyHandle *phOpenKey)
RegError REGISTRY_CALLTYPE closeKey(RegKeyHandle hKey)
enum SAL_DLLPUBLIC_RTTI RegValueType
enum SAL_DLLPUBLIC_RTTI RegError
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_stoc_SimpleRegistry_get_implementation(SAL_UNUSED_PARAMETER css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
unsigned char sal_Bool
sal_uInt16 sal_Unicode
signed char sal_Int8
ResultType type