/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include "precompiled_stoc.hxx" #include "sal/config.h" #include #include #include #include #include "boost/noncopyable.hpp" #include "com/sun/star/container/NoSuchElementException.hpp" #include "com/sun/star/registry/InvalidRegistryException.hpp" #include "com/sun/star/registry/XRegistryKey.hpp" #include "com/sun/star/uno/Reference.hxx" #include "com/sun/star/uno/XInterface.hpp" #include "cppuhelper/implbase1.hxx" #include "osl/diagnose.h" #include "rtl/malformeduriexception.hxx" #include "rtl/ref.hxx" #include "rtl/string.h" #include "rtl/uri.hxx" #include "rtl/ustrbuf.hxx" #include "rtl/ustring.h" #include "rtl/ustring.hxx" #include "salhelper/simplereferenceobject.hxx" #include "xmlreader/span.hxx" #include "xmlreader/xmlreader.hxx" #include "textualservices.hxx" namespace stoc { namespace simpleregistry { namespace { namespace css = com::sun::star; struct Implementation { rtl::OUString uri; rtl::OUString loader; std::vector< rtl::OUString > services; std::vector< rtl::OUString > singletons; }; typedef std::map< rtl::OUString, Implementation > Implementations; typedef std::map< rtl::OUString, std::vector< rtl::OUString > > ImplementationMap; } class Data: public salhelper::SimpleReferenceObject, private boost::noncopyable { public: Implementations implementations; ImplementationMap services; ImplementationMap singletons; }; namespace { class Parser: private boost::noncopyable { public: Parser(rtl::OUString const & uri, rtl::Reference< Data > const & data); private: void handleComponent(); void handleImplementation(); void handleService(); void handleSingleton(); rtl::OUString getNameAttribute(); xmlreader::XmlReader reader_; rtl::Reference< Data > data_; rtl::OUString attrUri_; rtl::OUString attrLoader_; rtl::OUString attrImplementation_; }; Parser::Parser(rtl::OUString const & uri, rtl::Reference< Data > const & data): reader_(uri), data_(data) { OSL_ASSERT(data.is()); int ucNsId = reader_.registerNamespaceIri( xmlreader::Span( RTL_CONSTASCII_STRINGPARAM( "http://openoffice.org/2010/uno-components"))); enum State { STATE_BEGIN, STATE_END, STATE_COMPONENTS, STATE_COMPONENT_INITIAL, STATE_COMPONENT, STATE_IMPLEMENTATION, STATE_SERVICE, STATE_SINGLETON }; for (State state = STATE_BEGIN;;) { xmlreader::Span name; int nsId; xmlreader::XmlReader::Result res = reader_.nextItem( xmlreader::XmlReader::TEXT_NONE, &name, &nsId); switch (state) { case STATE_BEGIN: if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && name.equals(RTL_CONSTASCII_STRINGPARAM("components"))) { state = STATE_COMPONENTS; break; } throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": unexpected item in outer level"))), css::uno::Reference< css::uno::XInterface >()); case STATE_END: if (res == xmlreader::XmlReader::RESULT_DONE) { return; } throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": unexpected item in outer level"))), css::uno::Reference< css::uno::XInterface >()); case STATE_COMPONENTS: if (res == xmlreader::XmlReader::RESULT_END) { state = STATE_END; break; } if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && name.equals(RTL_CONSTASCII_STRINGPARAM("component"))) { handleComponent(); state = STATE_COMPONENT_INITIAL; break; } throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": unexpected item in "))), css::uno::Reference< css::uno::XInterface >()); case STATE_COMPONENT: if (res == xmlreader::XmlReader::RESULT_END) { state = STATE_COMPONENTS; break; } // fall through case STATE_COMPONENT_INITIAL: if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && name.equals(RTL_CONSTASCII_STRINGPARAM("implementation"))) { handleImplementation(); state = STATE_IMPLEMENTATION; break; } throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": unexpected item in "))), css::uno::Reference< css::uno::XInterface >()); case STATE_IMPLEMENTATION: if (res == xmlreader::XmlReader::RESULT_END) { state = STATE_COMPONENT; break; } if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && name.equals(RTL_CONSTASCII_STRINGPARAM("service"))) { handleService(); state = STATE_SERVICE; break; } if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && name.equals(RTL_CONSTASCII_STRINGPARAM("singleton"))) { handleSingleton(); state = STATE_SINGLETON; break; } throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": unexpected item in "))), css::uno::Reference< css::uno::XInterface >()); case STATE_SERVICE: if (res == xmlreader::XmlReader::RESULT_END) { state = STATE_IMPLEMENTATION; break; } throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": unexpected item in "))), css::uno::Reference< css::uno::XInterface >()); case STATE_SINGLETON: if (res == xmlreader::XmlReader::RESULT_END) { state = STATE_IMPLEMENTATION; break; } throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": unexpected item in "))), css::uno::Reference< css::uno::XInterface >()); } } } void Parser::handleComponent() { attrUri_ = rtl::OUString(); attrLoader_ = rtl::OUString(); xmlreader::Span name; int nsId; while (reader_.nextAttribute(&nsId, &name)) { if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && name.equals(RTL_CONSTASCII_STRINGPARAM("uri"))) { if (attrUri_.getLength() != 0) { throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": has multiple \"uri\" attributes"))), css::uno::Reference< css::uno::XInterface >()); } attrUri_ = reader_.getAttributeValue(false).convertFromUtf8(); if (attrUri_.getLength() == 0) { throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": has empty \"uri\" attribute"))), css::uno::Reference< css::uno::XInterface >()); } } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && name.equals(RTL_CONSTASCII_STRINGPARAM("loader"))) { if (attrLoader_.getLength() != 0) { throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": has multiple \"loader\"" " attributes"))), css::uno::Reference< css::uno::XInterface >()); } attrLoader_ = reader_.getAttributeValue(false).convertFromUtf8(); if (attrLoader_.getLength() == 0) { throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": has empty \"loader\" attribute"))), css::uno::Reference< css::uno::XInterface >()); } } else { throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": expected attribute \"uri\" or" " \"loader\""))), css::uno::Reference< css::uno::XInterface >()); } } if (attrUri_.getLength() == 0) { throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": is missing \"uri\" attribute"))), css::uno::Reference< css::uno::XInterface >()); } if (attrLoader_.getLength() == 0) { throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": is missing \"loader\" attribute"))), css::uno::Reference< css::uno::XInterface >()); } try { attrUri_ = rtl::Uri::convertRelToAbs(reader_.getUrl(), attrUri_); } catch (rtl::MalformedUriException & e) { throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(": bad \"uri\" attribute: ")) + e.getMessage()), css::uno::Reference< css::uno::XInterface >()); } } void Parser::handleImplementation() { attrImplementation_ = getNameAttribute(); if (data_->implementations.find(attrImplementation_) != data_->implementations.end()) { throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": duplicate "))), css::uno::Reference< css::uno::XInterface >()); } data_->implementations[attrImplementation_].uri = attrUri_; data_->implementations[attrImplementation_].loader = attrLoader_; } void Parser::handleService() { rtl::OUString name = getNameAttribute(); data_->implementations[attrImplementation_].services.push_back(name); data_->services[name].push_back(attrImplementation_); } void Parser::handleSingleton() { rtl::OUString name = getNameAttribute(); data_->implementations[attrImplementation_].singletons.push_back(name); data_->singletons[name].push_back(attrImplementation_); } rtl::OUString Parser::getNameAttribute() { rtl::OUString attrName; xmlreader::Span name; int nsId; while (reader_.nextAttribute(&nsId, &name)) { if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && name.equals(RTL_CONSTASCII_STRINGPARAM("name"))) { if (attrName.getLength() != 0) { throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": element has multiple \"name\" attributes"))), css::uno::Reference< css::uno::XInterface >()); } attrName = reader_.getAttributeValue(false).convertFromUtf8(); if (attrName.getLength() == 0) { throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": element has empty \"name\" attribute"))), css::uno::Reference< css::uno::XInterface >()); } } else { throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": expected element attribute \"name\""))), css::uno::Reference< css::uno::XInterface >()); } } if (attrName.getLength() == 0) { throw css::registry::InvalidRegistryException( (reader_.getUrl() + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": element is missing \"name\" attribute"))), css::uno::Reference< css::uno::XInterface >()); } return attrName; } rtl::OUString pathToString(std::vector< rtl::OUString > const & path) { rtl::OUStringBuffer buf; for (std::vector< rtl::OUString >::const_iterator i(path.begin()); i != path.end(); ++i) { buf.append(sal_Unicode('/')); buf.append(*i); } if (buf.getLength() == 0) { buf.append(sal_Unicode('/')); } return buf.makeStringAndClear(); } class Key: public cppu::WeakImplHelper1< css::registry::XRegistryKey > { public: Key( rtl::Reference< Data > const & data, std::vector< rtl::OUString > const & path): data_(data), path_(path) { OSL_ASSERT(data.is()); } private: /* / IMPLEMENTATIONS UNO LOCATION utf-8 ACTIVATOR utf-8 SERVICES ... SINGLETONS utf-16 ... ... SERVICES utf-8-list ... SINGLETONS utf-16 REGISTERED_BY utf-8-list ... */ enum State { STATE_ROOT, STATE_IMPLEMENTATIONS, STATE_IMPLEMENTATION, STATE_UNO, STATE_LOCATION, STATE_ACTIVATOR, STATE_IMPLEMENTATION_SERVICES, STATE_IMPLEMENTATION_SERVICE, STATE_IMPLEMENTATION_SINGLETONS, STATE_IMPLEMENTATION_SINGLETON, STATE_SERVICES, STATE_SERVICE, STATE_SINGLETONS, STATE_SINGLETON, STATE_REGISTEREDBY }; virtual rtl::OUString SAL_CALL getKeyName() throw (css::uno::RuntimeException); virtual sal_Bool SAL_CALL isReadOnly() throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual sal_Bool SAL_CALL isValid() throw(css::uno::RuntimeException); virtual css::registry::RegistryKeyType SAL_CALL getKeyType( rtl::OUString const & rKeyName) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual css::registry::RegistryValueType SAL_CALL getValueType() throw( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual sal_Int32 SAL_CALL getLongValue() throw ( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException); virtual void SAL_CALL setLongValue(sal_Int32 value) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual css::uno::Sequence< sal_Int32 > SAL_CALL getLongListValue() throw( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException); virtual void SAL_CALL setLongListValue( com::sun::star::uno::Sequence< sal_Int32 > const & seqValue) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual rtl::OUString SAL_CALL getAsciiValue() throw ( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException); virtual void SAL_CALL setAsciiValue(rtl::OUString const & value) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual css::uno::Sequence< rtl::OUString > SAL_CALL getAsciiListValue() throw ( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException); virtual void SAL_CALL setAsciiListValue( css::uno::Sequence< rtl::OUString > const & seqValue) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual rtl::OUString SAL_CALL getStringValue() throw( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException); virtual void SAL_CALL setStringValue(rtl::OUString const & value) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual css::uno::Sequence< rtl::OUString > SAL_CALL getStringListValue() throw ( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException); virtual void SAL_CALL setStringListValue( css::uno::Sequence< rtl::OUString > const & seqValue) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual css::uno::Sequence< sal_Int8 > SAL_CALL getBinaryValue() throw ( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException); virtual void SAL_CALL setBinaryValue( css::uno::Sequence< sal_Int8 > const & value) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL openKey( rtl::OUString const & aKeyName) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL createKey(rtl::OUString const & aKeyName) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual void SAL_CALL closeKey() throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual void SAL_CALL deleteKey(rtl::OUString const & rKeyName) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > SAL_CALL openKeys() throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual css::uno::Sequence< rtl::OUString > SAL_CALL getKeyNames() throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual sal_Bool SAL_CALL createLink( rtl::OUString const & aLinkName, rtl::OUString const & aLinkTarget) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual void SAL_CALL deleteLink(rtl::OUString const & rLinkName) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual rtl::OUString SAL_CALL getLinkTarget( rtl::OUString const & rLinkName) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); virtual rtl::OUString SAL_CALL getResolvedName( rtl::OUString const & aKeyName) throw ( css::registry::InvalidRegistryException, css::uno::RuntimeException); bool find( rtl::OUString const & relative, std::vector< rtl::OUString > * path, State * state, css::registry::RegistryValueType * type) const; css::uno::Sequence< rtl::OUString > getChildren(); rtl::Reference< Data > data_; std::vector< rtl::OUString > path_; }; rtl::OUString Key::getKeyName() throw (css::uno::RuntimeException) { return pathToString(path_); } sal_Bool Key::isReadOnly() throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { return true; } sal_Bool Key::isValid() throw(css::uno::RuntimeException) { return true; } css::registry::RegistryKeyType Key::getKeyType(rtl::OUString const & rKeyName) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { if (!find(rtl::OUString(), 0, 0, 0)) { throw css::registry::InvalidRegistryException( (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unknown key ")) + rKeyName), static_cast< cppu::OWeakObject * >(this)); } return css::registry::RegistryKeyType_KEY; } css::registry::RegistryValueType Key::getValueType() throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { css::registry::RegistryValueType type = css::registry::RegistryValueType_NOT_DEFINED; OSL_VERIFY(find(rtl::OUString(), 0, 0, &type)); return type; } sal_Int32 Key::getLongValue() throw ( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException) { throw css::registry::InvalidValueException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " getLongValue not supported")), static_cast< OWeakObject * >(this)); } void Key::setLongValue(sal_Int32) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { throw css::registry::InvalidRegistryException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " setLongValue not supported")), static_cast< OWeakObject * >(this)); } css::uno::Sequence< sal_Int32 > Key::getLongListValue() throw ( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException) { throw css::registry::InvalidValueException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " getLongListValue not supported")), static_cast< OWeakObject * >(this)); } void Key::setLongListValue(css::uno::Sequence< sal_Int32 > const &) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { throw css::registry::InvalidRegistryException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " setLongListValue not supported")), static_cast< OWeakObject * >(this)); } rtl::OUString Key::getAsciiValue() throw ( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException) { State state = STATE_ROOT; OSL_VERIFY(find(rtl::OUString(), 0, &state, 0)); switch (state) { case STATE_LOCATION: return data_->implementations[path_[1]].uri; case STATE_ACTIVATOR: return data_->implementations[path_[1]].loader; default: throw css::registry::InvalidValueException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " getAsciiValue: wrong type")), static_cast< OWeakObject * >(this)); } } void Key::setAsciiValue(rtl::OUString const &) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { throw css::registry::InvalidRegistryException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " setAsciiValue not supported")), static_cast< OWeakObject * >(this)); } css::uno::Sequence< rtl::OUString > Key::getAsciiListValue() throw ( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException) { State state = STATE_ROOT; OSL_VERIFY(find(rtl::OUString(), 0, &state, 0)); std::vector< rtl::OUString > const * list; switch (state) { case STATE_SERVICE: list = &data_->services[path_[1]]; break; case STATE_REGISTEREDBY: list = &data_->singletons[path_[1]]; break; default: throw css::registry::InvalidValueException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " getAsciiListValue: wrong type")), static_cast< OWeakObject * >(this)); } if (list->size() > SAL_MAX_INT32) { throw css::registry::InvalidValueException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " getAsciiListValue: too large")), static_cast< OWeakObject * >(this)); } css::uno::Sequence< rtl::OUString > seq( static_cast< sal_Int32 >(list->size())); sal_Int32 i = 0; for (std::vector< rtl::OUString >::const_iterator j(list->begin()); j != list->end(); ++j) { seq[i++] = *j; } return seq; } void Key::setAsciiListValue(css::uno::Sequence< rtl::OUString > const &) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { throw css::registry::InvalidRegistryException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " setAsciiListValue not supported")), static_cast< OWeakObject * >(this)); } rtl::OUString Key::getStringValue() throw ( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException) { State state = STATE_ROOT; OSL_VERIFY(find(rtl::OUString(), 0, &state, 0)); switch (state) { case STATE_IMPLEMENTATION_SINGLETON: case STATE_SINGLETON: throw css::registry::InvalidRegistryException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " getStringValue: does not associate singletons with" " services")), static_cast< OWeakObject * >(this)); default: break; } // default case extracted from switch to avoid erroneous compiler warnings // on Solaris: throw css::registry::InvalidValueException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " getStringValue: wrong type")), static_cast< OWeakObject * >(this)); } void Key::setStringValue(rtl::OUString const &) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { throw css::registry::InvalidRegistryException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " setStringValue not supported")), static_cast< OWeakObject * >(this)); } css::uno::Sequence< rtl::OUString > Key::getStringListValue() throw ( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException) { throw css::registry::InvalidValueException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " getStringListValue not supported")), static_cast< OWeakObject * >(this)); } void Key::setStringListValue(css::uno::Sequence< rtl::OUString > const &) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { throw css::registry::InvalidRegistryException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " setStringListValue not supported")), static_cast< OWeakObject * >(this)); } css::uno::Sequence< sal_Int8 > Key::getBinaryValue() throw ( css::registry::InvalidRegistryException, css::registry::InvalidValueException, css::uno::RuntimeException) { throw css::registry::InvalidValueException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " getBinarValue not supported")), static_cast< OWeakObject * >(this)); } void Key::setBinaryValue(css::uno::Sequence< sal_Int8 > const &) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { throw css::registry::InvalidRegistryException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " setBinaryValue not supported")), static_cast< OWeakObject * >(this)); } css::uno::Reference< css::registry::XRegistryKey > Key::openKey( rtl::OUString const & aKeyName) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { std::vector< rtl::OUString > path; if (!find(aKeyName, &path, 0, 0)) { return css::uno::Reference< css::registry::XRegistryKey >(); } return new Key(data_, path); } css::uno::Reference< css::registry::XRegistryKey > Key::createKey( rtl::OUString const &) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { throw css::registry::InvalidRegistryException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " createKey not supported")), static_cast< OWeakObject * >(this)); } void Key::closeKey() throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) {} void Key::deleteKey(rtl::OUString const &) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { throw css::registry::InvalidRegistryException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " deleteKey not supported")), static_cast< OWeakObject * >(this)); } css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > Key::openKeys() throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { css::uno::Sequence< rtl::OUString > names(getChildren()); css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > keys(names.getLength()); for (sal_Int32 i = 0; i < keys.getLength(); ++i) { keys[i] = openKey(names[i]); OSL_ASSERT(keys[i].is()); } return keys; } css::uno::Sequence< rtl::OUString > Key::getKeyNames() throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { css::uno::Sequence< rtl::OUString > names(getChildren()); rtl::OUString prefix(pathToString(path_)); prefix += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")); for (sal_Int32 i = 0; i < names.getLength(); ++i) { names[i] = prefix + names[i]; } return names; } sal_Bool Key::createLink(rtl::OUString const &, rtl::OUString const &) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { throw css::registry::InvalidRegistryException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " createLink not supported")), static_cast< OWeakObject * >(this)); } void Key::deleteLink(rtl::OUString const &) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { throw css::registry::InvalidRegistryException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " deleteLink not supported")), static_cast< OWeakObject * >(this)); } rtl::OUString Key::getLinkTarget(rtl::OUString const &) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { throw css::registry::InvalidRegistryException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual services key" " getLinkTarget not supported")), static_cast< OWeakObject * >(this)); } rtl::OUString Key::getResolvedName(rtl::OUString const & aKeyName) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { std::vector< rtl::OUString > path; find(aKeyName, &path, 0, 0); return pathToString(path); } bool Key::find( rtl::OUString const & relative, std::vector< rtl::OUString > * path, State * state, css::registry::RegistryValueType * type) const { std::vector< rtl::OUString > p(path_); sal_Int32 i = 0; do { rtl::OUString seg(relative.getToken(0, '/', i)); if (seg.getLength() != 0) { p.push_back(seg); } } while (i >= 0); if (path != 0) { *path = p; } std::size_t const MAX_TRANSITIONS = 4; struct StateInfo { css::registry::RegistryValueType type; std::size_t count; struct { char const * segment; State state; } transitions[MAX_TRANSITIONS]; }; static StateInfo const info[] = { // STATE_ROOT: { css::registry::RegistryValueType_NOT_DEFINED, 3, { { "IMPLEMENTATIONS", STATE_IMPLEMENTATIONS }, { "SERVICES", STATE_SERVICES }, { "SINGLETONS", STATE_SINGLETONS } } }, // STATE_IMPLEMENTATIONS: { css::registry::RegistryValueType_NOT_DEFINED, 1, { { 0, STATE_IMPLEMENTATION } } }, // STATE_IMPLEMENTATION: { css::registry::RegistryValueType_NOT_DEFINED, 1, { { "UNO", STATE_UNO } } }, // STATE_UNO: { css::registry::RegistryValueType_NOT_DEFINED, 4, { { "LOCATION", STATE_LOCATION }, { "ACTIVATOR", STATE_ACTIVATOR }, { "SERVICES", STATE_IMPLEMENTATION_SERVICES }, { "SINGLETONS", STATE_IMPLEMENTATION_SINGLETONS } } }, // STATE_LOCATION: { css::registry::RegistryValueType_ASCII, 0, {} }, // STATE_ACTIVATOR: { css::registry::RegistryValueType_ASCII, 0, {} }, // STATE_IMPLEMENTATION_SERVICES: { css::registry::RegistryValueType_NOT_DEFINED, 1, { { 0, STATE_IMPLEMENTATION_SERVICE } } }, // STATE_IMPLEMENTATION_SERVICE: { css::registry::RegistryValueType_NOT_DEFINED, 0, {} }, // STATE_IMPLEMENTATION_SINGLETONS: { css::registry::RegistryValueType_NOT_DEFINED, 1, { { 0, STATE_IMPLEMENTATION_SINGLETON } } }, // STATE_IMPLEMENTATION_SINGLETON: { css::registry::RegistryValueType_STRING, 0, {} }, // STATE_SERVICES: { css::registry::RegistryValueType_NOT_DEFINED, 1, { { 0, STATE_SERVICE } } }, // STATE_SERVICE: { css::registry::RegistryValueType_ASCIILIST, 0, {} }, // STATE_SINGLETONS: { css::registry::RegistryValueType_NOT_DEFINED, 1, { { 0, STATE_SINGLETON } } }, // STATE_SINGLETON: { css::registry::RegistryValueType_STRING, 1, { { "REGISTERED_BY", STATE_REGISTEREDBY } } }, // STATE_REGISTEREDBY: { css::registry::RegistryValueType_ASCIILIST, 0, {} } }; State s = STATE_ROOT; for (std::vector< rtl::OUString >::iterator j(p.begin()); j != p.end(); ++j) { bool found = false; for (std::size_t k = 0; k < info[s].count; ++k) { if (info[s].transitions[k].segment == 0) { switch (info[s].transitions[k].state) { case STATE_IMPLEMENTATION: found = data_->implementations.find(*j) != data_->implementations.end(); break; case STATE_IMPLEMENTATION_SERVICE: case STATE_IMPLEMENTATION_SINGLETON: found = true; //TODO break; case STATE_SERVICE: found = data_->services.find(*j) != data_->services.end(); break; case STATE_SINGLETON: found = data_->singletons.find(*j) != data_->singletons.end(); break; default: std::abort(); // this cannot happen } } else { found = j->equalsAscii(info[s].transitions[k].segment); } if (found) { s = info[s].transitions[k].state; break; } } if (!found) { return false; } } if (state != 0) { *state = s; } if (type != 0) { *type = info[s].type; } return true; } css::uno::Sequence< rtl::OUString > Key::getChildren() { State state = STATE_ROOT; OSL_VERIFY(find(rtl::OUString(), 0, &state, 0)); switch (state) { default: std::abort(); // this cannot happen // pseudo-fall-through to avoid warnings on MSC case STATE_ROOT: { css::uno::Sequence< rtl::OUString > seq(3); seq[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("IMPLEMENTATIONS")); seq[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SERVICES")); seq[2] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SINGLETONS")); return seq; } case STATE_IMPLEMENTATIONS: { if (data_->implementations.size() > SAL_MAX_INT32) { throw css::registry::InvalidValueException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual" " services key openKeys: too large")), static_cast< OWeakObject * >(this)); } css::uno::Sequence< rtl::OUString > seq( static_cast< sal_Int32 >(data_->implementations.size())); sal_Int32 i = 0; for (Implementations::iterator j(data_->implementations.begin()); j != data_->implementations.end(); ++j) { seq[i++] = j->first; } return seq; } case STATE_UNO: { css::uno::Sequence< rtl::OUString > seq(4); seq[0] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LOCATION")); seq[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ACTIVATOR")); seq[2] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SERVICES")); seq[3] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SINGLETONS")); return seq; } case STATE_LOCATION: case STATE_ACTIVATOR: case STATE_IMPLEMENTATION_SERVICE: case STATE_IMPLEMENTATION_SINGLETON: case STATE_SERVICE: case STATE_REGISTEREDBY: return css::uno::Sequence< rtl::OUString >(); case STATE_IMPLEMENTATION_SERVICES: { if (data_->implementations[path_[1]].services.size() > SAL_MAX_INT32) { throw css::registry::InvalidValueException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual" " services key openKeys: too large")), static_cast< OWeakObject * >(this)); } css::uno::Sequence< rtl::OUString > seq( static_cast< sal_Int32 >( data_->implementations[path_[1]].services.size())); sal_Int32 i = 0; for (std::vector< rtl::OUString >::iterator j( data_->implementations[path_[1]].services.begin()); j != data_->implementations[path_[1]].services.end(); ++j) { seq[i++] = *j; } return seq; } case STATE_IMPLEMENTATION_SINGLETONS: { if (data_->implementations[path_[1]].singletons.size() > SAL_MAX_INT32) { throw css::registry::InvalidValueException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual" " services key openKeys: too large")), static_cast< OWeakObject * >(this)); } css::uno::Sequence< rtl::OUString > seq( static_cast< sal_Int32 >( data_->implementations[path_[1]].singletons.size())); sal_Int32 i = 0; for (std::vector< rtl::OUString >::iterator j( data_->implementations[path_[1]].singletons.begin()); j != data_->implementations[path_[1]].singletons.end(); ++j) { seq[i++] = *j; } return seq; } case STATE_SERVICES: { if (data_->services.size() > SAL_MAX_INT32) { throw css::registry::InvalidValueException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual" " services key openKeys: too large")), static_cast< OWeakObject * >(this)); } css::uno::Sequence< rtl::OUString > seq( static_cast< sal_Int32 >(data_->services.size())); sal_Int32 i = 0; for (ImplementationMap::iterator j(data_->services.begin()); j != data_->services.end(); ++j) { seq[i++] = j->first; } return seq; } case STATE_SINGLETONS: { if (data_->singletons.size() > SAL_MAX_INT32) { throw css::registry::InvalidValueException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.registry.SimpleRegistry textual" " services key openKeys: too large")), static_cast< OWeakObject * >(this)); } css::uno::Sequence< rtl::OUString > seq( static_cast< sal_Int32 >(data_->singletons.size())); sal_Int32 i = 0; for (ImplementationMap::iterator j(data_->singletons.begin()); j != data_->singletons.end(); ++j) { seq[i++] = j->first; } return seq; } case STATE_SINGLETON: { css::uno::Sequence< rtl::OUString > seq(1); seq[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("REGISTERED_BY")); return seq; } } } } TextualServices::TextualServices(rtl::OUString const & uri): uri_(uri), data_(new Data) { try { Parser(uri, data_); } catch (css::container::NoSuchElementException &) { throw css::registry::InvalidRegistryException( (uri + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(": no such file"))), css::uno::Reference< css::uno::XInterface >()); } } TextualServices::~TextualServices() {} css::uno::Reference< css::registry::XRegistryKey > TextualServices::getRootKey() { return new Key(data_, std::vector< rtl::OUString >()); } } }