/* -*- 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 "additions.hxx" #include "data.hxx" #include "groupnode.hxx" #include "node.hxx" #include "nodemap.hxx" #include "rootnode.hxx" #include "setnode.hxx" namespace configmgr { namespace { bool decode( OUString const & encoded, sal_Int32 begin, sal_Int32 end, OUString * decoded) { assert( begin >= 0 && begin <= end && end <= encoded.getLength() && decoded != nullptr); OUStringBuffer buf; while (begin != end) { sal_Unicode c = encoded[begin++]; if (c == '&') { if (encoded.match("amp;", begin)) { buf.append('&'); begin += RTL_CONSTASCII_LENGTH("amp;"); } else if (encoded.match("quot;", begin)) { buf.append('"'); begin += RTL_CONSTASCII_LENGTH("quot;"); } else if (encoded.match("apos;", begin)) { buf.append('\''); begin += RTL_CONSTASCII_LENGTH("apos;"); } else { return false; } assert(begin <= end); } else { buf.append(c); } } *decoded = buf.makeStringAndClear(); return true; } } OUString Data::createSegment( OUString const & templateName, OUString const & name) { if (templateName.isEmpty()) { return name; } OUStringBuffer buf(templateName); //TODO: verify template name contains no bad chars? buf.append("['"); for (sal_Int32 i = 0; i < name.getLength(); ++i) { sal_Unicode c = name[i]; switch (c) { case '&': buf.append("&"); break; case '"': buf.append("""); break; case '\'': buf.append("'"); break; default: buf.append(c); break; } } buf.append("']"); return buf.makeStringAndClear(); } sal_Int32 Data::parseSegment( OUString const & path, sal_Int32 index, OUString * name, bool * setElement, OUString * templateName) { assert( index >= 0 && index <= path.getLength() && name != nullptr && setElement != nullptr); sal_Int32 i = index; while (i < path.getLength() && path[i] != '/' && path[i] != '[') { ++i; } if (i == path.getLength() || path[i] == '/') { *name = path.copy(index, i - index); *setElement = false; return i; } if (templateName != nullptr) { if (i - index == 1 && path[index] == '*') { templateName->clear(); } else { *templateName = path.copy(index, i - index); } } if (++i == path.getLength()) { return -1; } sal_Unicode del = path[i++]; if (del != '\'' && del != '"') { return -1; } sal_Int32 j = path.indexOf(del, i); if (j == -1 || j + 1 == path.getLength() || path[j + 1] != ']' || !decode(path, i, j, name)) { return -1; } *setElement = true; return j + 2; } OUString Data::fullTemplateName( OUString const & component, OUString const & name) { if (component.indexOf(':') != -1 || name.indexOf(':') != -1) { throw css::uno::RuntimeException( "bad component/name pair containing colon " + component + "/" + name); } OUStringBuffer buf(component); buf.append(':'); buf.append(name); return buf.makeStringAndClear(); } bool Data::equalTemplateNames( OUString const & shortName, OUString const & longName) { if (shortName.indexOf(':') == -1) { sal_Int32 i = longName.indexOf(':') + 1; assert(i > 0); return rtl_ustr_compare_WithLength( shortName.getStr(), shortName.getLength(), longName.getStr() + i, longName.getLength() - i) == 0; } else { return shortName == longName; } } Data::Data(): root_(new RootNode) {} rtl::Reference< Node > Data::resolvePathRepresentation( OUString const & pathRepresentation, OUString * canonicRepresentation, std::vector * path, int * finalizedLayer) const { if (pathRepresentation.isEmpty() || pathRepresentation[0] != '/') { throw css::uno::RuntimeException( "bad path " + pathRepresentation); } if (path != nullptr) { path->clear(); } if (pathRepresentation == "/") { if (canonicRepresentation != nullptr) { *canonicRepresentation = pathRepresentation; } if (finalizedLayer != nullptr) { *finalizedLayer = NO_LAYER; } return root_; } OUString seg; bool setElement; OUString templateName; sal_Int32 n = parseSegment(pathRepresentation, 1, &seg, &setElement, nullptr); if (n == -1 || setElement) { throw css::uno::RuntimeException( "bad path " + pathRepresentation); } NodeMap const & components = getComponents(); NodeMap::const_iterator i(components.find(seg)); OUStringBuffer canonic; rtl::Reference< Node > parent; int finalized = NO_LAYER; for (rtl::Reference< Node > p(i == components.end() ? nullptr : i->second);;) { if (!p.is()) { return p; } if (canonicRepresentation != nullptr) { canonic.append('/'); canonic.append(createSegment(templateName, seg)); } if (path != nullptr) { path->push_back(seg); } finalized = std::min(finalized, p->getFinalized()); if (n != pathRepresentation.getLength() && pathRepresentation[n++] != '/') { throw css::uno::RuntimeException( "bad path " + pathRepresentation); } // for backwards compatibility, ignore a final slash if (n == pathRepresentation.getLength()) { if (canonicRepresentation != nullptr) { *canonicRepresentation = canonic.makeStringAndClear(); } if (finalizedLayer != nullptr) { *finalizedLayer = finalized; } return p; } parent = p; templateName.clear(); n = parseSegment( pathRepresentation, n, &seg, &setElement, &templateName); if (n == -1) { throw css::uno::RuntimeException( "bad path " + pathRepresentation); } // For backwards compatibility, allow set members to be accessed with // simple path segments, like group members: p = p->getMember(seg); if (setElement) { switch (parent->kind()) { case Node::KIND_LOCALIZED_PROPERTY: if (!templateName.isEmpty()) { throw css::uno::RuntimeException( "bad path " + pathRepresentation); } break; case Node::KIND_SET: if (!templateName.isEmpty() && !static_cast< SetNode * >(parent.get())->isValidTemplate( templateName)) { throw css::uno::RuntimeException( "bad path " + pathRepresentation); } break; default: throw css::uno::RuntimeException( "bad path " + pathRepresentation); } if (!templateName.isEmpty() && p != nullptr) { assert(!p->getTemplateName().isEmpty()); if (!equalTemplateNames(templateName, p->getTemplateName())) { throw css::uno::RuntimeException( "bad path " + pathRepresentation); } } } } } rtl::Reference< Node > Data::getTemplate( int layer, OUString const & fullName) const { return templates.findNode(layer, fullName); } NodeMap & Data::getComponents() const { return root_->getMembers(); } Additions * Data::addExtensionXcuAdditions( OUString const & url, int layer) { rtl::Reference< ExtensionXcu > item(new ExtensionXcu); ExtensionXcuAdditions::iterator i( extensionXcuAdditions_.emplace( url, rtl::Reference< ExtensionXcu >()).first); if (i->second.is()) { throw css::uno::RuntimeException( "already added extension xcu " + url); } i->second = item; item->layer = layer; return &item->additions; } rtl::Reference< Data::ExtensionXcu > Data::removeExtensionXcuAdditions( OUString const & url) { ExtensionXcuAdditions::iterator i(extensionXcuAdditions_.find(url)); if (i == extensionXcuAdditions_.end()) { // This can happen, as migration of pre OOo 3.3 UserInstallation // extensions in dp_registry::backend::configuration::BackendImpl:: // PackageImpl::processPackage_ can cause just-in-time creation of // extension xcu files that are never added via addExtensionXcuAdditions // (also, there might be url spelling differences between calls to // addExtensionXcuAdditions and removeExtensionXcuAdditions?): SAL_INFO( "configmgr", "unknown Data::removeExtensionXcuAdditions(" << url << ")"); return rtl::Reference< ExtensionXcu >(); } rtl::Reference< ExtensionXcu > item(i->second); extensionXcuAdditions_.erase(i); return item; } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ tion> LibreOffice 核心代码仓库文档基金会
summaryrefslogtreecommitdiff
AgeCommit message (Expand)Author
2018-07-26i18nlangtag: avoid -Werror=deprecated-copy (GCC trunk towards GCC 9)Stephan Bergmann
2018-05-25no need declare these tag structs separatelyNoel Grandin
2018-05-15Resolves: tdf#117617 Add Iloko [ilo-PH] to language listEike Rathke
2018-05-08Add Ju|’hoansi [ktz-NA] and Naro [nhr-BW] to language listEike Rathke
2018-05-04Add Malay Arabic [ms-Arab-MY] and [ms-Arab-BN] to language list, both CTLEike Rathke
2018-03-01Resolves: tdf#116058 add Armenian [hy-IR] [hy-RU] [hyw-AM] [xcl-AM]Eike Rathke
2018-01-29Fix typosAndrea Gelmini
2018-01-05ofz#4952 avoid liblangtag config when fuzzing enabledCaolán McNamara
2017-12-04Add Plautdietsch [pdt-CA] to language listboxEike Rathke
2017-11-14Resolves: tdf#113835 add Fon [fon-BJ] to language listEike Rathke
2017-11-10clang-tidy modernize-use-equals-default LanguageTagJochen Nitschke
2017-10-31loplugin:constantparam in i18nlangtagNoel Grandin
2017-10-25loplugin:constmethod in comphelper,ucbhelperNoel Grandin
2017-10-04Add 0xF400 and 0xF800 constants for number format code modifiers, tdf#102075Eike Rathke
2017-10-02Remove now moot comment about comments and .src file inclusionEike Rathke
2017-09-05Introduce LanguageTag::getBcp47MS() for writing MS malformed tags, tdf#83190Eike Rathke
2017-07-21de-hrc various thingsCaolán McNamara
2017-06-26Fix typosAndrea Gelmini
2017-06-19Add Kituba (Democratic Republic of the Congo) [ktu-CD] to language listEike Rathke
2017-06-07tdf#108349: fix LanguageType conversions from UNO "short"Michael Stahl
2017-05-30drop LANGUAGE_USER_MALAGASY_PLATEAU defineNoel Grandin
2017-05-30teach redundantcast plugin about functional castsNoel Grandin
2017-04-26use strong_int for LanguageTypeNoel Grandin
2017-04-25make __RSC a builtin define for the RSC compilerNoel Grandin
2017-04-24loplugin:checkunusedparams in i18nlangtag and l10ntoolsNoel Grandin
2017-03-21Just include rtl/locale.hStephan Bergmann
2017-03-15tdf#105448 add Xibe [sjo-CN] to language list (and remove Sibe [nco-PG])Eike Rathke
2017-03-14tdf#100462 prefer en-GB-oxendict over en-GB-oedEike Rathke
2017-03-03Remove redundant 'inline' keywordStephan Bergmann
2017-01-31a whole bunch of SAL_WARN_UNUSEDNoel Grandin
2017-01-30tdf#105448 add Sibe [nco-PG] to language listEike Rathke
2017-01-30tdf#105448 add Manchu [mnc-CN] to language list (CTL)Eike Rathke
2016-12-05loplugin:countusersofdefaultparams in include/drawinglayer..i18nlangtagNoel Grandin
2016-11-17Fix tdf#103855 add language codes and names to language lists from extensionsMartin Hosken
2016-08-29name it Hungarian Rovas, tdf#97406 follow-upEike Rathke
2016-08-26add Old Hungarian (Hungarian Rovas) [hu-Hung-HU] to language list, tdf#97406Eike Rathke
2016-08-16Resolves: tdf#101540 add Silesian [szl-PL] to language listEike Rathke