/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace com::sun::star::uno { class XComponentContext; } namespace { class SimpleRegistry: public cppu::WeakImplHelper< css::registry::XSimpleRegistry, css::lang::XServiceInfo > { public: SimpleRegistry(): registry_(Registry()) {} ~SimpleRegistry() { std::scoped_lock guard(mutex_); registry_.reset(); } std::mutex mutex_; private: virtual OUString SAL_CALL getURL() override; virtual void SAL_CALL open( OUString const & rURL, sal_Bool bReadOnly, sal_Bool bCreate) override; virtual sal_Bool SAL_CALL isValid() override; virtual void SAL_CALL close() override; virtual void SAL_CALL destroy() override; virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL getRootKey() override; virtual sal_Bool SAL_CALL isReadOnly() override; virtual void SAL_CALL mergeKey( OUString const & aKeyName, OUString const & aUrl) override; virtual OUString SAL_CALL getImplementationName() override { return u"com.sun.star.comp.stoc.SimpleRegistry"_ustr; } virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override { return cppu::supportsService(this, ServiceName); } virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override { css::uno::Sequence< OUString > names { u"com.sun.star.registry.SimpleRegistry"_ustr }; return names; } std::optional registry_; }; class Key: public cppu::WeakImplHelper< css::registry::XRegistryKey > { public: Key( rtl::Reference< SimpleRegistry > registry, RegistryKey const & key): registry_(std::move(registry)), key_(key) {} ~Key() { std::scoped_lock guard(registry_->mutex_); key_.reset(); } private: virtual OUString SAL_CALL getKeyName() override; virtual sal_Bool SAL_CALL isReadOnly() override; virtual sal_Bool SAL_CALL isValid() override; virtual css::registry::RegistryKeyType SAL_CALL getKeyType( OUString const & rKeyName) override; virtual css::registry::RegistryValueType SAL_CALL getValueType() override; virtual sal_Int32 SAL_CALL getLongValue() override; virtual void SAL_CALL setLongValue(sal_Int32 value) override; virtual css::uno::Sequence< sal_Int32 > SAL_CALL getLongListValue() override; virtual void SAL_CALL setLongListValue( css::uno::Sequence< sal_Int32 > const & seqValue) override; virtual OUString SAL_CALL getAsciiValue() override; virtual void SAL_CALL setAsciiValue(OUString const & value) override; virtual css::uno::Sequence< OUString > SAL_CALL getAsciiListValue() override; virtual void SAL_CALL setAsciiListValue( css::uno::Sequence< OUString > const & seqValue) override; virtual OUString SAL_CALL getStringValue() override; virtual void SAL_CALL setStringValue(OUString const & value) override; virtual css::uno::Sequence< OUString > SAL_CALL getStringListValue() override; virtual void SAL_CALL setStringListValue( css::uno::Sequence< OUString > const & seqValue) override; virtual css::uno::Sequence< sal_Int8 > SAL_CALL getBinaryValue() override; virtual void SAL_CALL setBinaryValue( css::uno::Sequence< sal_Int8 > const & value) override; virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL openKey( OUString const & aKeyName) override; virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL createKey(OUString const & aKeyName) override; virtual void SAL_CALL closeKey() override; virtual void SAL_CALL deleteKey(OUString const & rKeyName) override; virtual css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > SAL_CALL openKeys() override; virtual css::uno::Sequence< OUString > SAL_CALL getKeyNames() override; virtual sal_Bool SAL_CALL createLink( OUString const & aLinkName, OUString const & aLinkTarget) override; virtual void SAL_CALL deleteLink(OUString const & rLinkName) override; virtual OUString SAL_CALL getLinkTarget(OUString const & rLinkName) override; virtual OUString SAL_CALL getResolvedName(OUString const & aKeyName) override; rtl::Reference< SimpleRegistry > registry_; std::optional key_; }; OUString Key::getKeyName() { std::scoped_lock guard(registry_->mutex_); return key_->getName(); } sal_Bool Key::isReadOnly() { std::scoped_lock guard(registry_->mutex_); return key_->isReadOnly(); } sal_Bool Key::isValid() { std::scoped_lock guard(registry_->mutex_); return key_->isValid(); } css::registry::RegistryKeyType Key::getKeyType(OUString const & ) { return css::registry::RegistryKeyType_KEY; } css::registry::RegistryValueType Key::getValueType() { std::scoped_lock guard(registry_->mutex_); RegValueType type; sal_uInt32 size; RegError err = key_->getValueInfo(OUString(), &type, &size); switch (err) { case RegError::NO_ERROR: break; case RegError::INVALID_VALUE: type = RegValueType::NOT_DEFINED; break; default: throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key getValueType:" " underlying RegistryKey::getValueInfo() = " + OUString::number(static_cast(err)), getXWeak()); } switch (type) { default: std::abort(); // this cannot happen // pseudo-fall-through to avoid warnings on MSC case RegValueType::NOT_DEFINED: return css::registry::RegistryValueType_NOT_DEFINED; case RegValueType::LONG: return css::registry::RegistryValueType_LONG; case RegValueType::STRING: return css::registry::RegistryValueType_ASCII; case RegValueType::UNICODE: return css::registry::RegistryValueType_STRING; case RegValueType::BINARY: return css::registry::RegistryValueType_BINARY; case RegValueType::LONGLIST: return css::registry::RegistryValueType_LONGLIST; case RegValueType::STRINGLIST: return css::registry::RegistryValueType_ASCIILIST; case RegValueType::UNICODELIST: return css::registry::RegistryValueType_STRINGLIST; } } sal_Int32 Key::getLongValue() { std::scoped_lock guard(registry_->mutex_); sal_Int32 value; RegError err = key_->getValue(OUString(), &value); switch (err) { case RegError::NO_ERROR: break; case RegError::INVALID_VALUE: throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key getLongValue:" " underlying RegistryKey::getValue() = RegError::INVALID_VALUE"_ustr, getXWeak()); default: throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key getLongValue:" " underlying RegistryKey::getValue() = " + OUString::number(static_cast(err)), getXWeak()); } return value; } void Key::setLongValue(sal_Int32 value) { std::scoped_lock guard(registry_->mutex_); RegError err = key_->setValue( OUString(), RegValueType::LONG, &value, sizeof (sal_Int32)); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key setLongValue:" " underlying RegistryKey::setValue() = " + OUString::number(static_cast(err)), getXWeak()); } } css::uno::Sequence< sal_Int32 > Key::getLongListValue() { std::scoped_lock guard(registry_->mutex_); RegistryValueList< sal_Int32 > list; RegError err = key_->getLongListValue(OUString(), list); switch (err) { case RegError::NO_ERROR: break; case RegError::VALUE_NOT_EXISTS: return css::uno::Sequence< sal_Int32 >(); case RegError::INVALID_VALUE: throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key getLongListValue:" " underlying RegistryKey::getLongListValue() =" " RegError::INVALID_VALUE"_ustr, getXWeak()); default: throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key getLongListValue:" " underlying RegistryKey::getLongListValue() = " + OUString::number(static_cast(err)), getXWeak()); } sal_uInt32 n = list.getLength(); if (n > SAL_MAX_INT32) { throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key getLongListValue:" " underlying RegistryKey::getLongListValue() too large"_ustr, getXWeak()); } css::uno::Sequence< sal_Int32 > value(static_cast< sal_Int32 >(n)); auto aValueRange = asNonConstRange(value); for (sal_uInt32 i = 0; i < n; ++i) { aValueRange[static_cast< sal_Int32 >(i)] = list.getElement(i); } return value; } void Key::setLongListValue(css::uno::Sequence< sal_Int32 > const & seqValue) { std::scoped_lock guard(registry_->mutex_); RegError err = key_->setLongListValue( OUString(), seqValue.getConstArray(), static_cast< sal_uInt32 >(seqValue.getLength())); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key setLongListValue:" " underlying RegistryKey::setLongListValue() = " + OUString::number(static_cast(err)), getXWeak()); } } OUString Key::getAsciiValue() { std::scoped_lock guard(registry_->mutex_); RegValueType type; sal_uInt32 size; RegError err = key_->getValueInfo(OUString(), &type, &size); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key getAsciiValue:" " underlying RegistryKey::getValueInfo() = " + OUString::number(static_cast(err)), getXWeak()); } if (type != RegValueType::STRING) { throw css::registry::InvalidValueException( "com.sun.star.registry.SimpleRegistry key getAsciiValue:" " underlying RegistryKey type = " + OUString::number(static_cast(type)), getXWeak()); } // size contains terminating null (error in underlying registry.cxx): if (size == 0) { throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key getAsciiValue:" " underlying RegistryKey size 0 cannot happen due to" " design error"_ustr, getXWeak()); } if (size > SAL_MAX_INT32) { throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key getAsciiValue:" " underlying RegistryKey size too large"_ustr, getXWeak()); } std::vector< char > list(size); err = key_->getValue(OUString(), list.data()); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key getAsciiValue:" " underlying RegistryKey::getValue() = " + OUString::number(static_cast(err)), getXWeak()); } if (list[size - 1] != '\0') { throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key getAsciiValue:" " underlying RegistryKey value must be null-terminated due" " to design error"_ustr, getXWeak()); } OUString value; if (!rtl_convertStringToUString( &value.pData, list.data(), static_cast< sal_Int32 >(size - 1), RTL_TEXTENCODING_UTF8, (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))) { throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key getAsciiValue:" " underlying RegistryKey not UTF-8"_ustr, getXWeak()); } return value; } void Key::setAsciiValue(OUString const & value) { std::scoped_lock guard(registry_->mutex_); OString utf8; if (!value.convertToString( &utf8, RTL_TEXTENCODING_UTF8, (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))) { throw css::uno::RuntimeException( u"com.sun.star.registry.SimpleRegistry key setAsciiValue:" " value not UTF-16"_ustr, getXWeak()); } RegError err = key_->setValue( OUString(), RegValueType::STRING, const_cast< char * >(utf8.getStr()), utf8.getLength() + 1); // +1 for terminating null (error in underlying registry.cxx) if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key setAsciiValue:" " underlying RegistryKey::setValue() = " + OUString::number(static_cast(err)), getXWeak()); } } css::uno::Sequence< OUString > Key::getAsciiListValue() { std::scoped_lock guard(registry_->mutex_); RegistryValueList< char * > list; RegError err = key_->getStringListValue(OUString(), list); switch (err) { case RegError::NO_ERROR: break; case RegError::VALUE_NOT_EXISTS: return css::uno::Sequence< OUString >(); case RegError::INVALID_VALUE: throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key" " getAsciiListValue: underlying" " RegistryKey::getStringListValue() = RegError::INVALID_VALUE"_ustr, getXWeak()); default: throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key" " getAsciiListValue: underlying" " RegistryKey::getStringListValue() = " + OUString::number(static_cast(err)), getXWeak()); } sal_uInt32 n = list.getLength(); if (n > SAL_MAX_INT32) { throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key" " getAsciiListValue: underlying" " RegistryKey::getStringListValue() too large"_ustr, getXWeak()); } css::uno::Sequence< OUString > value(static_cast< sal_Int32 >(n)); auto aValueRange = asNonConstRange(value); for (sal_uInt32 i = 0; i < n; ++i) { char * el = list.getElement(i); sal_Int32 size = rtl_str_getLength(el); if (!rtl_convertStringToUString( &aValueRange[static_cast< sal_Int32 >(i)].pData, el, size, RTL_TEXTENCODING_UTF8, (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))) { throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key" " getAsciiListValue: underlying RegistryKey not" " UTF-8"_ustr, getXWeak()); } } return value; } void Key::setAsciiListValue( css::uno::Sequence< OUString > const & seqValue) { std::scoped_lock guard(registry_->mutex_); std::vector< OString > list; for (const auto& rValue : seqValue) { OString utf8; if (!rValue.convertToString( &utf8, RTL_TEXTENCODING_UTF8, (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))) { throw css::uno::RuntimeException( u"com.sun.star.registry.SimpleRegistry key" " setAsciiListValue: value not UTF-16"_ustr, getXWeak()); } list.push_back(utf8); } std::vector< char * > list2; for (const auto& rItem : list) { list2.push_back(const_cast< char * >(rItem.getStr())); } RegError err = key_->setStringListValue( OUString(), list2.data(), static_cast< sal_uInt32 >(list2.size())); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key" " setAsciiListValue: underlying" " RegistryKey::setStringListValue() = " + OUString::number(static_cast(err)), getXWeak()); } } OUString Key::getStringValue() { std::scoped_lock guard(registry_->mutex_); RegValueType type; sal_uInt32 size; RegError err = key_->getValueInfo(OUString(), &type, &size); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key getStringValue:" " underlying RegistryKey::getValueInfo() = " + OUString::number(static_cast(err)), getXWeak()); } if (type != RegValueType::UNICODE) { throw css::registry::InvalidValueException( "com.sun.star.registry.SimpleRegistry key getStringValue:" " underlying RegistryKey type = " + OUString::number(static_cast(type)), getXWeak()); } // size contains terminating null and is *2 (error in underlying // registry.cxx): if (size == 0 || (size & 1) == 1) { throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key getStringValue:" " underlying RegistryKey size 0 or odd cannot happen due to" " design error"_ustr, getXWeak()); } if (size > SAL_MAX_INT32) { throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key getStringValue:" " underlying RegistryKey size too large"_ustr, getXWeak()); } std::vector< sal_Unicode > list(size); err = key_->getValue(OUString(), list.data()); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key getStringValue:" " underlying RegistryKey::getValue() = " + OUString::number(static_cast(err)), getXWeak()); } if (list[size/2 - 1] != 0) { throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key getStringValue:" " underlying RegistryKey value must be null-terminated due" " to design error"_ustr, getXWeak()); } return OUString(list.data(), static_cast< sal_Int32 >(size/2 - 1)); } void Key::setStringValue(OUString const & value) { std::scoped_lock guard(registry_->mutex_); RegError err = key_->setValue( OUString(), RegValueType::UNICODE, const_cast< sal_Unicode * >(value.getStr()), (value.getLength() + 1) * sizeof (sal_Unicode)); // +1 for terminating null (error in underlying registry.cxx) if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key setStringValue:" " underlying RegistryKey::setValue() = " + OUString::number(static_cast(err)), getXWeak()); } } css::uno::Sequence< OUString > Key::getStringListValue() { std::scoped_lock guard(registry_->mutex_); RegistryValueList< sal_Unicode * > list; RegError err = key_->getUnicodeListValue(OUString(), list); switch (err) { case RegError::NO_ERROR: break; case RegError::VALUE_NOT_EXISTS: return css::uno::Sequence< OUString >(); case RegError::INVALID_VALUE: throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key" " getStringListValue: underlying" " RegistryKey::getUnicodeListValue() = RegError::INVALID_VALUE"_ustr, getXWeak()); default: throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key" " getStringListValue: underlying" " RegistryKey::getUnicodeListValue() = " + OUString::number(static_cast(err)), getXWeak()); } sal_uInt32 n = list.getLength(); if (n > SAL_MAX_INT32) { throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key" " getStringListValue: underlying" " RegistryKey::getUnicodeListValue() too large"_ustr, getXWeak()); } css::uno::Sequence< OUString > value(static_cast< sal_Int32 >(n)); auto aValueRange = asNonConstRange(value); for (sal_uInt32 i = 0; i < n; ++i) { aValueRange[static_cast< sal_Int32 >(i)] = list.getElement(i); } return value; } void Key::setStringListValue( css::uno::Sequence< OUString > const & seqValue) { std::scoped_lock guard(registry_->mutex_); std::vector< sal_Unicode * > list; list.reserve(seqValue.getLength()); std::transform(seqValue.begin(), seqValue.end(), std::back_inserter(list), [](const OUString& rValue) -> sal_Unicode* { return const_cast(rValue.getStr()); }); RegError err = key_->setUnicodeListValue( OUString(), list.data(), static_cast< sal_uInt32 >(list.size())); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key" " setStringListValue: underlying" " RegistryKey::setUnicodeListValue() = " + OUString::number(static_cast(err)), getXWeak()); } } css::uno::Sequence< sal_Int8 > Key::getBinaryValue() { std::scoped_lock guard(registry_->mutex_); RegValueType type; sal_uInt32 size; RegError err = key_->getValueInfo(OUString(), &type, &size); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key getBinaryValue:" " underlying RegistryKey::getValueInfo() = " + OUString::number(static_cast(err)), getXWeak()); } if (type != RegValueType::BINARY) { throw css::registry::InvalidValueException( "com.sun.star.registry.SimpleRegistry key getBinaryValue:" " underlying RegistryKey type = " + OUString::number(static_cast(type)), getXWeak()); } if (size > SAL_MAX_INT32) { throw css::registry::InvalidValueException( u"com.sun.star.registry.SimpleRegistry key getBinaryValue:" " underlying RegistryKey size too large"_ustr, getXWeak()); } css::uno::Sequence< sal_Int8 > value(static_cast< sal_Int32 >(size)); err = key_->getValue(OUString(), value.getArray()); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key getBinaryValue:" " underlying RegistryKey::getValue() = " + OUString::number(static_cast(err)), getXWeak()); } return value; } void Key::setBinaryValue(css::uno::Sequence< sal_Int8 > const & value) { std::scoped_lock guard(registry_->mutex_); RegError err = key_->setValue( OUString(), RegValueType::BINARY, const_cast< sal_Int8 * >(value.getConstArray()), static_cast< sal_uInt32 >(value.getLength())); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key setBinaryValue:" " underlying RegistryKey::setValue() = " + OUString::number(static_cast(err)), getXWeak()); } } css::uno::Reference< css::registry::XRegistryKey > Key::openKey( OUString const & aKeyName) { std::scoped_lock guard(registry_->mutex_); RegistryKey key; RegError err = key_->openKey(aKeyName, key); switch (err) { case RegError::NO_ERROR: return new Key(registry_, key); case RegError::KEY_NOT_EXISTS: return css::uno::Reference< css::registry::XRegistryKey >(); default: throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key openKey:" " underlying RegistryKey::openKey() = " + OUString::number(static_cast(err)), getXWeak()); } } css::uno::Reference< css::registry::XRegistryKey > Key::createKey( OUString const & aKeyName) { std::scoped_lock guard(registry_->mutex_); RegistryKey key; RegError err = key_->createKey(aKeyName, key); switch (err) { case RegError::NO_ERROR: return new Key(registry_, key); case RegError::INVALID_KEYNAME: return css::uno::Reference< css::registry::XRegistryKey >(); default: throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key createKey:" " underlying RegistryKey::createKey() = " + OUString::number(static_cast(err)), getXWeak()); } } void Key::closeKey() { std::scoped_lock guard(registry_->mutex_); RegError err = key_->closeKey(); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key closeKey:" " underlying RegistryKey::closeKey() = " + OUString::number(static_cast(err)), getXWeak()); } } void Key::deleteKey(OUString const & rKeyName) { std::scoped_lock guard(registry_->mutex_); RegError err = key_->deleteKey(rKeyName); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key deleteKey:" " underlying RegistryKey::deleteKey() = " + OUString::number(static_cast(err)), getXWeak()); } } css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > Key::openKeys() { std::scoped_lock guard(registry_->mutex_); RegistryKeyArray list; RegError err = key_->openSubKeys(OUString(), list); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key openKeys:" " underlying RegistryKey::openSubKeys() = " + OUString::number(static_cast(err)), getXWeak()); } sal_uInt32 n = list.getLength(); if (n > SAL_MAX_INT32) { throw css::registry::InvalidRegistryException( u"com.sun.star.registry.SimpleRegistry key getKeyNames:" " underlying RegistryKey::getKeyNames() too large"_ustr, getXWeak()); } css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > keys(static_cast< sal_Int32 >(n)); auto aKeysRange = asNonConstRange(keys); for (sal_uInt32 i = 0; i < n; ++i) { aKeysRange[static_cast< sal_Int32 >(i)] = new Key( registry_, list.getElement(i)); } return keys; } css::uno::Sequence< OUString > Key::getKeyNames() { std::scoped_lock guard(registry_->mutex_); RegistryKeyNames list; RegError err = key_->getKeyNames(OUString(), list); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key getKeyNames:" " underlying RegistryKey::getKeyNames() = " + OUString::number(static_cast(err)), getXWeak()); } sal_uInt32 n = list.getLength(); if (n > SAL_MAX_INT32) { throw css::registry::InvalidRegistryException( u"com.sun.star.registry.SimpleRegistry key getKeyNames:" " underlying RegistryKey::getKeyNames() too large"_ustr, getXWeak()); } css::uno::Sequence< OUString > names(static_cast< sal_Int32 >(n)); auto aNamesRange = asNonConstRange(names); for (sal_uInt32 i = 0; i < n; ++i) { aNamesRange[static_cast< sal_Int32 >(i)] = list.getElement(i); } return names; } sal_Bool Key::createLink( OUString const & /*aLinkName*/, OUString const & /*aLinkTarget*/) { throw css::registry::InvalidRegistryException( u"com.sun.star.registry.SimpleRegistry key createLink: links are no longer supported"_ustr, getXWeak()); } void Key::deleteLink(OUString const & /*rLinkName*/) { throw css::registry::InvalidRegistryException( u"com.sun.star.registry.SimpleRegistry key deleteLink: links are no longer supported"_ustr, getXWeak()); } OUString Key::getLinkTarget(OUString const & /*rLinkName*/) { throw css::registry::InvalidRegistryException( u"com.sun.star.registry.SimpleRegistry key getLinkTarget: links are no longer supported"_ustr, getXWeak()); } OUString Key::getResolvedName(OUString const & aKeyName) { std::scoped_lock guard(registry_->mutex_); OUString resolved; RegError err = key_->getResolvedKeyName(aKeyName, resolved); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry key getResolvedName:" " underlying RegistryKey::getResolvedName() = " + OUString::number(static_cast(err)), getXWeak()); } return resolved; } OUString SimpleRegistry::getURL() { std::scoped_lock guard(mutex_); return registry_->getName(); } void SimpleRegistry::open( OUString const & rURL, sal_Bool bReadOnly, sal_Bool bCreate) { std::scoped_lock guard(mutex_); RegError err = (rURL.isEmpty() && bCreate) ? RegError::REGISTRY_NOT_EXISTS : registry_->open(rURL, bReadOnly ? RegAccessMode::READONLY : RegAccessMode::READWRITE); if (err == RegError::REGISTRY_NOT_EXISTS && bCreate) { err = registry_->create(rURL); } if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry.open(" + rURL + "): underlying Registry::open/create() = " + OUString::number(static_cast(err)), getXWeak()); } } sal_Bool SimpleRegistry::isValid() { std::scoped_lock guard(mutex_); return registry_->isValid(); } void SimpleRegistry::close() { std::scoped_lock guard(mutex_); RegError err = registry_->close(); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry.close:" " underlying Registry::close() = " + OUString::number(static_cast(err)), getXWeak()); } } void SimpleRegistry::destroy() { std::scoped_lock guard(mutex_); RegError err = registry_->destroy(OUString()); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry.destroy:" " underlying Registry::destroy() = " + OUString::number(static_cast(err)), getXWeak()); } } css::uno::Reference< css::registry::XRegistryKey > SimpleRegistry::getRootKey() { std::scoped_lock guard(mutex_); RegistryKey root; RegError err = registry_->openRootKey(root); if (err != RegError::NO_ERROR) { throw css::registry::InvalidRegistryException( "com.sun.star.registry.SimpleRegistry.getRootKey:" " underlying Registry::getRootKey() = " + OUString::number(static_cast(err)), getXWeak()); } return new Key(this, root); } sal_Bool SimpleRegistry::isReadOnly() { std::scoped_lock guard(mutex_); return registry_->isReadOnly(); } void SimpleRegistry::mergeKey( OUString const &, OUString const &) { throw css::uno::RuntimeException(u"css.registry.SimpleRegistry::mergeKey: not implemented"_ustr); } } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_stoc_SimpleRegistry_get_implementation( SAL_UNUSED_PARAMETER css::uno::XComponentContext *, css::uno::Sequence const &) { return cppu::acquire(new SimpleRegistry); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */