Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  legacyprovider.cxx   Sprache: C

 
/* -*- 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/.
 */


#include <sal/config.h>

#include <cassert>
#include <utility>
#include <vector>

#include <registry/reader.hxx>
#include <registry/registry.hxx>
#include <registry/regtype.h>
#include <rtl/ref.hxx>
#include <rtl/ustring.hxx>
#include <sal/types.h>
#include <unoidl/unoidl.hxx>

#include "legacyprovider.hxx"

namespace unoidl::detail {

namespace {

std::vector< OUString > translateAnnotations(std::u16string_view documentation) {
    std::vector< OUString > ans;
    if (documentation.find(u"@deprecated") != std::u16string_view::npos) {
        //TODO: this check is somewhat crude
        ans.push_back(u"deprecated"_ustr);
    }
    return ans;
}

ConstantValue translateConstantValue(
    RegistryKey & key, RTConstValue const & value)
{
    switch (value.m_type) {
    case RT_TYPE_BOOL:
        return ConstantValue(value.m_value.aBool);
    case RT_TYPE_BYTE:
        return ConstantValue(value.m_value.aByte);
    case RT_TYPE_INT16:
        return ConstantValue(value.m_value.aShort);
    case RT_TYPE_UINT16:
        return ConstantValue(value.m_value.aUShort);
    case RT_TYPE_INT32:
        return ConstantValue(value.m_value.aLong);
    case RT_TYPE_UINT32:
        return ConstantValue(value.m_value.aULong);
    case RT_TYPE_INT64:
        return ConstantValue(value.m_value.aHyper);
    case RT_TYPE_UINT64:
        return ConstantValue(value.m_value.aUHyper);
    case RT_TYPE_FLOAT:
        return ConstantValue(value.m_value.aFloat);
    case RT_TYPE_DOUBLE:
        return ConstantValue(value.m_value.aDouble);
    default:
        throw FileFormatException(
            key.getRegistryName(),
            ("legacy format: unexpected type " + OUString::number(value.m_type)
             + " of value of a field of constant group with key "
             + key.getName()));
    }
}

rtl::Reference< Entity > readEntity(
    rtl::Reference< Manager > const & manager, RegistryKey & ucr,
    RegistryKey & key, OUString const & path, bool probe);

class Cursor: public MapCursor {
public:
    Cursor(
        rtl::Reference< Manager > manager, RegistryKey const & ucr,
        RegistryKey const & key);

private:
    virtual ~Cursor() noexcept override {}

    virtual rtl::Reference< Entity > getNext(OUString * name) override;

    rtl::Reference< Manager > manager_;
    RegistryKey ucr_;
    RegistryKey key_;
    OUString prefix_;
    RegistryKeyNames names_;
    sal_uInt32 index_;
};

Cursor::Cursor(
    rtl::Reference< Manager > manager, RegistryKey const & ucr,
    RegistryKey const & key):
    manager_(std::move(manager)), ucr_(ucr), key_(key), index_(0)
{
    if (!ucr_.isValid())
        return;

    prefix_ = key_.getName();
    if (!prefix_.endsWith("/")) {
        prefix_ += "/";
    }
    RegError e = key_.getKeyNames(u""_ustr, names_);
    if (e != RegError::NO_ERROR) {
        throw FileFormatException(
            key_.getRegistryName(),
            ("legacy format: cannot get sub-key names of " + key_.getName()
             + ": " + OUString::number(static_cast<int>(e))));
    }
}

rtl::Reference< Entity > Cursor::getNext(OUString * name) {
    assert(name != nullptr);
    rtl::Reference< Entity > ent;
    if (index_ != names_.getLength()) {
        OUString path(names_.getElement(index_));
        assert(path.match(prefix_));
        *name = path.copy(prefix_.getLength());
        ent = readEntity(manager_, ucr_, key_, *name, false);
        assert(ent.is());
        ++index_;
    }
    return ent;
}

class Module: public ModuleEntity {
public:
    Module(
        rtl::Reference< Manager > manager, RegistryKey const & ucr,
        RegistryKey const & key):
        manager_(std::move(manager)), ucr_(ucr), key_(key)
    {}

private:
    virtual ~Module() noexcept override {}

    virtual std::vector< OUString > getMemberNames() const override;

    virtual rtl::Reference< MapCursor > createCursor() const override
    { return new Cursor(manager_, ucr_, key_); }

    rtl::Reference< Manager > manager_;
    RegistryKey ucr_;
    mutable RegistryKey key_;
};

std::vector< OUString > Module::getMemberNames() const {
    RegistryKeyNames names;
    RegError e = key_.getKeyNames(u""_ustr, names);
    if (e != RegError::NO_ERROR) {
        throw FileFormatException(
            key_.getRegistryName(),
            ("legacy format: cannot get sub-key names of " + key_.getName()
             + ": " + OUString::number(static_cast<int>(e))));
    }
    std::vector< OUString > ns;
    for (sal_uInt32 i = 0; i != names.getLength(); ++i) {
        ns.push_back(names.getElement(i));
    }
    return ns;
}

typereg::Reader getReader(RegistryKey & key, std::vector< char > * buffer) {
    assert(buffer != nullptr);
    RegValueType type;
    sal_uInt32 size;
    RegError e = key.getValueInfo(u""_ustr, &type, &size);
    if (e != RegError::NO_ERROR) {
        throw FileFormatException(
            key.getRegistryName(),
            ("legacy format: cannot get value info about key " + key.getName()
             + ": " + OUString::number(static_cast<int>(e))));
    }
    if (type != RegValueType::BINARY) {
        throw FileFormatException(
            key.getRegistryName(),
            ("legacy format: unexpected value type " + OUString::number(static_cast<int>(type))
             + " of key " + key.getName()));
    }
    if (size == 0
        /*TODO: || size > std::numeric_limits< std::vector< char >::size_type >::max() */)
    {
        throw FileFormatException(
            key.getRegistryName(),
            ("legacy format: bad binary value size " + OUString::number(size)
             + " of key " + key.getName()));
    }
    buffer->resize(static_cast< std::vector< char >::size_type >(size));
    e = key.getValue(u""_ustr, buffer->data());
    if (e != RegError::NO_ERROR) {
        throw FileFormatException(
            key.getRegistryName(),
            ("legacy format: cannot get binary value of key " + key.getName()
             + ": " + OUString::number(static_cast<int>(e))));
    }
    typereg::Reader reader(buffer->data(), size);
    if (!reader.isValid()) {
        throw FileFormatException(
            key.getRegistryName(),
            "legacy format: malformed binary value of key " + key.getName());
    }
    return reader;
}

rtl::Reference< Entity > readEntity(
    rtl::Reference< Manager > const & manager, RegistryKey & ucr,
    RegistryKey & key, OUString const & path, bool probe)
{
    assert(manager.is());
    RegistryKey sub;
    RegError e = key.openKey(path, sub);
    switch (e) {
    case RegError::NO_ERROR:
        break;
    case RegError::KEY_NOT_EXISTS:
        if (probe) {
            return rtl::Reference< Entity >();
        }
        [[fallthrough]];
    default:
        throw FileFormatException(
            key.getRegistryName(),
            ("legacy format: cannot open sub-key " + path + " of "
             + key.getName() + ": " + OUString::number(static_cast<int>(e))));
    }
    std::vector< char > buf;
    typereg::Reader reader(getReader(sub, &buf));
    switch (reader.getTypeClass()) {
    case RT_TYPE_INTERFACE:
        {
            std::vector< AnnotatedReference > mandBases;
            sal_uInt16 n = reader.getSuperTypeCount();
            for (sal_uInt16 j = 0; j != n; ++j) {
                mandBases.emplace_back(
                    reader.getSuperTypeName(j).replace('/''.'),
                    std::vector< OUString >());
            }
            std::vector< AnnotatedReference > optBases;
            n = reader.getReferenceCount();
            for (sal_uInt16 j = 0; j != n; ++j) {
                optBases.emplace_back(
                    reader.getReferenceTypeName(j).replace('/''.'),
                    translateAnnotations(reader.getReferenceDocumentation(j)));
            }
            sal_uInt16 methodCount = reader.getMethodCount();
            std::vector< InterfaceTypeEntity::Attribute > attrs;
            n = reader.getFieldCount(); // attributes
            for (sal_uInt16 j = 0; j != n; ++j) {
                OUString attrName(reader.getFieldName(j));
                std::vector< OUString > getExcs;
                std::vector< OUString > setExcs;
                for (sal_uInt16 k = 0; k != methodCount; ++k) {
                    if (reader.getMethodName(k) == attrName) {
                        switch (reader.getMethodFlags(k)) {
                        case RTMethodMode::ATTRIBUTE_GET:
                            {
                                sal_uInt16 m
                                    = reader.getMethodExceptionCount(k);
                                // cid#1213376 unhelpfully warns about an
                                // untrusted loop bound here:
                                // coverity[tainted_data] - trusted data source
                                for (sal_uInt16 l = 0; l != m; ++l) {
                                    getExcs.push_back(
                                        reader.getMethodExceptionTypeName(k, l).
                                        replace('/''.'));
                                }
                                break;
                            }
                        case RTMethodMode::ATTRIBUTE_SET:
                            {
                                sal_uInt16 m
                                    = reader.getMethodExceptionCount(k);
                                // cid#1213376 unhelpfully warns about an
                                // untrusted loop bound here:
                                // coverity[tainted_data] - trusted data source
                                for (sal_uInt16 l = 0; l != m; ++l) {
                                    setExcs.push_back(
                                        reader.getMethodExceptionTypeName(k, l).
                                        replace('/''.'));
                                }
                                break;
                            }
                        default:
                            throw FileFormatException(
                                key.getRegistryName(),
                                ("legacy format: method and attribute with same"
                                 " name " + attrName
                                 + " in interface type with key "
                                 + sub.getName()));
                        }
                    }
                }
                RTFieldAccess flags = reader.getFieldFlags(j);
                attrs.emplace_back(
                    attrName, reader.getFieldTypeName(j).replace('/''.'),
                    bool(flags & RTFieldAccess::BOUND),
                    bool(flags & RTFieldAccess::READONLY), std::move(getExcs), std::move(setExcs),
                    translateAnnotations(reader.getFieldDocumentation(j)));
            }
            std::vector< InterfaceTypeEntity::Method > meths;
            meths.reserve(methodCount);
            for (sal_uInt16 j = 0; j != methodCount; ++j) {
                RTMethodMode flags = reader.getMethodFlags(j);
                if (flags != RTMethodMode::ATTRIBUTE_GET
                    && flags != RTMethodMode::ATTRIBUTE_SET)
                {
                    std::vector< InterfaceTypeEntity::Method::Parameter >
                        params;
                    sal_uInt16 m = reader.getMethodParameterCount(j);
                    // cid#1213376 unhelpfully warns about an untrusted loop
                    // bound here:
                    // coverity[tainted_data] - trusted data source
                    for (sal_uInt16 k = 0; k != m; ++k) {
                        RTParamMode mode = reader.getMethodParameterFlags(j, k);
                        InterfaceTypeEntity::Method::Parameter::Direction dir;
                        switch (mode) {
                        case RT_PARAM_IN:
                            dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN;
                            break;
                        case RT_PARAM_OUT:
                            dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT;
                            break;
                        case RT_PARAM_INOUT:
                            dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT;
                            break;
                        default:
                            throw FileFormatException(
                                key.getRegistryName(),
                                ("legacy format: unexpected mode "
                                 + OUString::number(mode) + " of parameter "
                                 + reader.getMethodParameterName(j, k)
                                 + " of method " + reader.getMethodName(j)
                                 + " in interface type with key "
                                 + sub.getName()));
                        }
                        params.emplace_back(
                            reader.getMethodParameterName(j, k),
                            (reader.getMethodParameterTypeName(j, k).
                             replace('/''.')),
                            dir);
                    }
                    std::vector< OUString > excs;
                    m = reader.getMethodExceptionCount(j);
                    // cid#1213376 unhelpfully warns about an untrusted loop
                    // bound here:
                    // coverity[tainted_data] - trusted data source
                    for (sal_uInt16 k = 0; k != m; ++k) {
                        excs.push_back(
                            reader.getMethodExceptionTypeName(j, k).replace(
                                '/''.'));
                    }
                    meths.emplace_back(
                        reader.getMethodName(j),
                        reader.getMethodReturnTypeName(j).replace('/''.'),
                        std::move(params), std::move(excs),
                        translateAnnotations(
                            reader.getMethodDocumentation(j)));
                }
            }
            return new InterfaceTypeEntity(
                reader.isPublished(), std::move(mandBases), std::move(optBases), std::move(attrs), std::move(meths),
                translateAnnotations(reader.getDocumentation()));
        }
    case RT_TYPE_MODULE:
        return new Module(manager, ucr, sub);
    case RT_TYPE_STRUCT:
        {
            sal_uInt16 n = reader.getReferenceCount();
            if (n == 0) {
                OUString base;
                switch (reader.getSuperTypeCount()) {
                case 0:
                    break;
                case 1:
                    base = reader.getSuperTypeName(0).replace('/''.');
                    break;
                default:
                    throw FileFormatException(
                        key.getRegistryName(),
                        ("legacy format: unexpected number "
                         + OUString::number(reader.getSuperTypeCount())
                         + " of super-types of plain struct type with key "
                         + sub.getName()));
                }
                std::vector< PlainStructTypeEntity::Member > mems;
                n = reader.getFieldCount();
                for (sal_uInt16 j = 0; j != n; ++j) {
                    mems.emplace_back(
                        reader.getFieldName(j),
                        reader.getFieldTypeName(j).replace('/''.'),
                        translateAnnotations(reader.getFieldDocumentation(j)));
                }
                return new PlainStructTypeEntity(
                    reader.isPublished(), base, std::move(mems),
                    translateAnnotations(reader.getDocumentation()));
            } else {
                if (reader.getSuperTypeCount() != 0) {
                    throw FileFormatException(
                        key.getRegistryName(),
                        ("legacy format: unexpected number "
                         + OUString::number(reader.getSuperTypeCount())
                         + " of super-types of polymorphic struct type template"
                         " with key " + sub.getName()));
                }
                std::vector< OUString > params;
                for (sal_uInt16 j = 0; j != n; ++j) {
                    params.push_back(
                        reader.getReferenceTypeName(j).replace('/''.'));
                }
                std::vector< PolymorphicStructTypeTemplateEntity::Member > mems;
                n = reader.getFieldCount();
                for (sal_uInt16 j = 0; j != n; ++j) {
                    mems.emplace_back(
                        reader.getFieldName(j),
                        reader.getFieldTypeName(j).replace('/''.'),
                        bool(
                            reader.getFieldFlags(j)
                            & RTFieldAccess::PARAMETERIZED_TYPE),
                        translateAnnotations(reader.getFieldDocumentation(j)));
                }
                return new PolymorphicStructTypeTemplateEntity(
                    reader.isPublished(), std::move(params), std::move(mems),
                    translateAnnotations(reader.getDocumentation()));
            }
        }
    case RT_TYPE_ENUM:
        {
            std::vector< EnumTypeEntity::Member > mems;
            sal_uInt16 n = reader.getFieldCount();
            for (sal_uInt16 j = 0; j != n; ++j) {
                RTConstValue v(reader.getFieldValue(j));
                if (v.m_type != RT_TYPE_INT32) {
                    throw FileFormatException(
                        key.getRegistryName(),
                        ("legacy format: unexpected type "
                         + OUString::number(v.m_type) + " of value of field "
                         + reader.getFieldName(j) + " of enum type with key "
                         + sub.getName()));
                }
                mems.emplace_back(
                    reader.getFieldName(j), v.m_value.aLong,
                    translateAnnotations(reader.getFieldDocumentation(j)));

            }
            return new EnumTypeEntity(
                reader.isPublished(), std::move(mems),
                translateAnnotations(reader.getDocumentation()));
        }
    case RT_TYPE_EXCEPTION:
        {
            OUString base;
            switch (reader.getSuperTypeCount()) {
            case 0:
                break;
            case 1:
                base = reader.getSuperTypeName(0).replace('/''.');
                break;
            default:
                throw FileFormatException(
                    key.getRegistryName(),
                    ("legacy format: unexpected number "
                     + OUString::number(reader.getSuperTypeCount())
                     + " of super-types of exception type with key "
                     + sub.getName()));
            }
            std::vector< ExceptionTypeEntity::Member > mems;
            sal_uInt16 n = reader.getFieldCount();
            for (sal_uInt16 j = 0; j != n; ++j) {
                mems.emplace_back(
                    reader.getFieldName(j),
                    reader.getFieldTypeName(j).replace('/''.'),
                    translateAnnotations(reader.getFieldDocumentation(j)));
            }
            return new ExceptionTypeEntity(
                reader.isPublished(), base, std::move(mems),
                translateAnnotations(reader.getDocumentation()));
        }
    case RT_TYPE_TYPEDEF:
        if (reader.getSuperTypeCount() != 1) {
            throw FileFormatException(
                key.getRegistryName(),
                ("legacy format: unexpected number "
                 + OUString::number(reader.getSuperTypeCount())
                 + " of super-types of typedef with key " + sub.getName()));
        }
        return new TypedefEntity(
            reader.isPublished(), reader.getSuperTypeName(0).replace('/''.'),
            translateAnnotations(reader.getDocumentation()));
    case RT_TYPE_SERVICE:
        switch (reader.getSuperTypeCount()) {
        case 0:
            {
                std::vector< AnnotatedReference > mandServs;
                std::vector< AnnotatedReference > optServs;
                std::vector< AnnotatedReference > mandIfcs;
                std::vector< AnnotatedReference > optIfcs;
                sal_uInt16 n = reader.getReferenceCount();
                for (sal_uInt16 j = 0; j != n; ++j) {
                    AnnotatedReference base{
                        reader.getReferenceTypeName(j).replace('/''.'),
                        translateAnnotations(
                            reader.getReferenceDocumentation(j))};
                    switch (reader.getReferenceSort(j)) {
                    case RTReferenceType::EXPORTS:
                        if (!(reader.getReferenceFlags(j) & RTFieldAccess::OPTIONAL))
                        {
                            mandServs.push_back(base);
                        } else {
                            optServs.push_back(base);
                        }
                        break;
                    case RTReferenceType::SUPPORTS:
                        if (!(reader.getReferenceFlags(j) & RTFieldAccess::OPTIONAL))
                        {
                            mandIfcs.push_back(base);
                        } else {
                            optIfcs.push_back(base);
                        }
                        break;
                    default:
                        throw FileFormatException(
                            key.getRegistryName(),
                            ("legacy format: unexpected mode "
                             + OUString::number(static_cast<int>(reader.getReferenceSort(j)))
                             + " of reference " + reader.getReferenceTypeName(j)
                             + " in service with key " + sub.getName()));
                    }
                }
                std::vector< AccumulationBasedServiceEntity::Property > props;
                n = reader.getFieldCount();
                for (sal_uInt16 j = 0; j != n; ++j) {
                    RTFieldAccess acc = reader.getFieldFlags(j);
                    int attrs = 0;
                    if (acc & RTFieldAccess::READONLY) {
                        attrs |= AccumulationBasedServiceEntity::Property::
                            ATTRIBUTE_READ_ONLY;
                    }
                    if (acc & RTFieldAccess::OPTIONAL) {
                        attrs |= AccumulationBasedServiceEntity::Property::
                            ATTRIBUTE_OPTIONAL;
                    }
                    if (acc & RTFieldAccess::MAYBEVOID) {
                        attrs |= AccumulationBasedServiceEntity::Property::
                            ATTRIBUTE_MAYBE_VOID;
                    }
                    if (acc & RTFieldAccess::BOUND) {
                        attrs |= AccumulationBasedServiceEntity::Property::
                            ATTRIBUTE_BOUND;
                    }
                    if (acc & RTFieldAccess::CONSTRAINED) {
                        attrs |= AccumulationBasedServiceEntity::Property::
                            ATTRIBUTE_CONSTRAINED;
                    }
                    if (acc & RTFieldAccess::TRANSIENT) {
                        attrs |= AccumulationBasedServiceEntity::Property::
                            ATTRIBUTE_TRANSIENT;
                    }
                    if (acc & RTFieldAccess::MAYBEAMBIGUOUS) {
                        attrs |= AccumulationBasedServiceEntity::Property::
                            ATTRIBUTE_MAYBE_AMBIGUOUS;
                    }
                    if (acc & RTFieldAccess::MAYBEDEFAULT) {
                        attrs |= AccumulationBasedServiceEntity::Property::
                            ATTRIBUTE_MAYBE_DEFAULT;
                    }
                    if (acc & RTFieldAccess::REMOVABLE) {
                        attrs |= AccumulationBasedServiceEntity::Property::
                            ATTRIBUTE_REMOVABLE;
                    }
                    props.emplace_back(
                        reader.getFieldName(j),
                        reader.getFieldTypeName(j).replace('/''.'),
                        static_cast<
                            AccumulationBasedServiceEntity::Property::
                                Attributes >(attrs),
                        translateAnnotations(reader.getFieldDocumentation(j)));
                }
                return new AccumulationBasedServiceEntity(
                    reader.isPublished(), std::move(mandServs), std::move(optServs), std::move(mandIfcs),
                    std::move(optIfcs), std::move(props),
                    translateAnnotations(reader.getDocumentation()));
            }
        case 1:
            {
                std::vector< SingleInterfaceBasedServiceEntity::Constructor >
                    ctors;
                sal_uInt16 n = reader.getMethodCount();
                if (n == 1 && reader.getMethodFlags(0) == RTMethodMode::TWOWAY
                    && reader.getMethodName(0).isEmpty()
                    && reader.getMethodReturnTypeName(0) == "void"
                    && reader.getMethodParameterCount(0) == 0
                    && reader.getMethodExceptionCount(0) == 0)
                {
                    ctors.push_back(
                        SingleInterfaceBasedServiceEntity::Constructor());
                } else {
                    for (sal_uInt16 j = 0; j != n; ++j) {
                        if (reader.getMethodFlags(j) != RTMethodMode::TWOWAY) {
                            throw FileFormatException(
                                key.getRegistryName(),
                                ("legacy format: unexpected mode "
                                 + OUString::number(static_cast<int>(reader.getMethodFlags(j)))
                                 + " of constructor " + reader.getMethodName(j)
                                 + " in service with key " + sub.getName()));
                        }
                        std::vector<
                            SingleInterfaceBasedServiceEntity::Constructor::
                            Parameter > params;
                        sal_uInt16 m = reader.getMethodParameterCount(j);
                        // cid#1213376 unhelpfully warns about an untrusted
                        // loop bound here:
                        // coverity[tainted_data] - trusted data source
                        for (sal_uInt16 k = 0; k != m; ++k) {
                            RTParamMode mode
                                = reader.getMethodParameterFlags(j, k);
                            if ((mode & ~RT_PARAM_REST) != RT_PARAM_IN) {
                                throw FileFormatException(
                                    key.getRegistryName(),
                                    ("legacy format: unexpected mode "
                                     + OUString::number(mode)
                                     + " of parameter "
                                     + reader.getMethodParameterName(j, k)
                                     + " of constructor "
                                     + reader.getMethodName(j)
                                     + " in service with key "
                                     + sub.getName()));
                            }
                            if ((mode & RT_PARAM_REST) != 0
                                && (m != 1
                                     || ((reader.getMethodParameterTypeName(
                                              j, 0))
                                         != "any")))
                            {
                                throw FileFormatException(
                                    key.getRegistryName(),
                                    ("legacy format: bad rest parameter "
                                     + reader.getMethodParameterName(j, k)
                                     + " of constructor "
                                     + reader.getMethodName(j)
                                     + " in service with key "
                                     + sub.getName()));
                            }
                            params.emplace_back(
                                reader.getMethodParameterName(j, k),
                                (reader.getMethodParameterTypeName(j, k).
                                 replace('/''.')),
                                (mode & RT_PARAM_REST) != 0);
                        }
                        std::vector< OUString > excs;
                        m = reader.getMethodExceptionCount(j);
                        // cid#1213376 unhelpfully warns about an untrusted
                        // loop bound here:
                        // coverity[tainted_data] - trusted data source
                        for (sal_uInt16 k = 0; k != m; ++k) {
                            excs.push_back(
                                reader.getMethodExceptionTypeName(j, k).replace(
                                    '/''.'));
                        }
                        ctors.push_back(
                            SingleInterfaceBasedServiceEntity::Constructor(
                                reader.getMethodName(j), std::move(params), std::move(excs),
                                translateAnnotations(
                                    reader.getMethodDocumentation(j))));
                    }
                }
                return new SingleInterfaceBasedServiceEntity(
                    reader.isPublished(),
                    reader.getSuperTypeName(0).replace('/''.'), std::move(ctors),
                    translateAnnotations(reader.getDocumentation()));
            }
        default:
            throw FileFormatException(
                key.getRegistryName(),
                ("legacy format: unexpected number "
                 + OUString::number(reader.getSuperTypeCount())
                 + " of super-types of service with key " + sub.getName()));
        }
    case RT_TYPE_SINGLETON:
        {
            if (reader.getSuperTypeCount() != 1) {
                throw FileFormatException(
                    key.getRegistryName(),
                    ("legacy format: unexpected number "
                     + OUString::number(reader.getSuperTypeCount())
                     + " of super-types of singleton with key "
                     + sub.getName()));
            }
            OUString basePath(reader.getSuperTypeName(0));
            OUString baseName(basePath.replace('/''.'));
            bool newStyle;
            rtl::Reference< Entity > base(manager->findEntity(baseName));
            if (base.is()) {
                switch (base->getSort()) {
                case Entity::SORT_INTERFACE_TYPE:
                    newStyle = true;
                    break;
                case Entity::SORT_ACCUMULATION_BASED_SERVICE:
                    newStyle = false;
                    break;
                default:
                    throw FileFormatException(
                        key.getRegistryName(),
                        ("legacy format: unexpected sort "
                         + OUString::number(base->getSort()) + " of base "
                         + baseName + " of singleton with key "
                         + sub.getName()));
                }
            } else {
                RegistryKey key2;
                e = ucr.openKey(basePath, key2);
                switch (e) {
                case RegError::NO_ERROR:
                    break;
                case RegError::KEY_NOT_EXISTS:
                    throw FileFormatException(
                        key.getRegistryName(),
                        ("legacy format: unknown super-type " + basePath
                         + " of super-type with key " + sub.getName()));
                default:
                    throw FileFormatException(
                        key.getRegistryName(),
                        ("legacy format: cannot open ucr sub-key " + basePath
                         + ": " + OUString::number(static_cast<int>(e))));
                }
                std::vector< char > buf2;
                typereg::Reader reader2(getReader(key2, &buf2));
                switch (reader2.getTypeClass()) {
                case RT_TYPE_INTERFACE:
                    newStyle = true;
                    break;
                case RT_TYPE_SERVICE:
                    newStyle = false;
                    break;
                default:
                    throw FileFormatException(
                        key.getRegistryName(),
                        ("legacy format: unexpected type class "
                         + OUString::number(reader2.getTypeClass())
                         + " of super-type with key " + key2.getName()
                         + " of singleton with key " + sub.getName()));
                }
            }
            return newStyle
                ? rtl::Reference< Entity >(
                    new InterfaceBasedSingletonEntity(
                        reader.isPublished(), baseName,
                        translateAnnotations(reader.getDocumentation())))
                : rtl::Reference< Entity >(
                    new ServiceBasedSingletonEntity(
                        reader.isPublished(), baseName,
                        translateAnnotations(reader.getDocumentation())));
        }
    case RT_TYPE_CONSTANTS:
        {
            std::vector< ConstantGroupEntity::Member > mems;
            sal_uInt16 n = reader.getFieldCount();
            for (sal_uInt16 j = 0; j != n; ++j) {
                mems.emplace_back(
                    reader.getFieldName(j),
                    translateConstantValue(sub, reader.getFieldValue(j)),
                    translateAnnotations(reader.getFieldDocumentation(j)));
            }
            return new ConstantGroupEntity(
                reader.isPublished(), std::move(mems),
                translateAnnotations(reader.getDocumentation()));
        }
    default:
        throw FileFormatException(
            key.getRegistryName(),
            ("legacy format: unexpected type class "
             + OUString::number(reader.getTypeClass()) + " of key "
             + sub.getName()));
    }
}

}

LegacyProvider::LegacyProvider(Manager & manager, OUString const & uri):
    manager_(manager)
{
    Registry reg;
    RegError e = reg.open(uri, RegAccessMode::READONLY);
    switch (e) {
    case RegError::NO_ERROR:
        break;
    case RegError::REGISTRY_NOT_EXISTS:
        throw NoSuchFileException(uri);
    default:
        throw FileFormatException(
            uri, "cannot open legacy file: " + OUString::number(static_cast<int>(e)));
    }
    RegistryKey root;
    e = reg.openRootKey(root);
    if (e != RegError::NO_ERROR) {
        throw FileFormatException(
            uri, "legacy format: cannot open root key: " + OUString::number(static_cast<int>(e)));
    }
    e = root.openKey(u"UCR"_ustr, ucr_);
    switch (e) {
    case RegError::NO_ERROR:
    case RegError::KEY_NOT_EXISTS: // such effectively empty files exist in the wild
        break;
    default:
        throw FileFormatException(
            uri, "legacy format: cannot open UCR key: " + OUString::number(static_cast<int>(e)));
    }
}

rtl::Reference< MapCursor > LegacyProvider::createRootCursor() const {
    return new Cursor(&manager_, ucr_, ucr_);
}

rtl::Reference< Entity > LegacyProvider::findEntity(OUString const & name)
    const
{
    return ucr_.isValid()
        ? readEntity(&manager_, ucr_, ucr_, name.replace('.''/'), true)
        : rtl::Reference< Entity >();
}

LegacyProvider::~LegacyProvider() noexcept {}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=91 H=95 G=92

¤ Dauer der Verarbeitung: 0.3 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge