LCOV - code coverage report
Current view: top level - configmgr/source - xcsparser.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 236 316 74.7 %
Date: 2012-08-25 Functions: 13 15 86.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 290 709 40.9 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : #include "sal/config.h"
      21                 :            : 
      22                 :            : #include <cassert>
      23                 :            : #include <cstddef>
      24                 :            : 
      25                 :            : #include "com/sun/star/uno/Any.hxx"
      26                 :            : #include "com/sun/star/uno/Reference.hxx"
      27                 :            : #include "com/sun/star/uno/RuntimeException.hpp"
      28                 :            : #include "com/sun/star/uno/XInterface.hpp"
      29                 :            : #include "rtl/ref.hxx"
      30                 :            : #include "rtl/strbuf.hxx"
      31                 :            : #include "rtl/string.h"
      32                 :            : #include "rtl/string.hxx"
      33                 :            : #include "rtl/ustring.h"
      34                 :            : #include "rtl/ustring.hxx"
      35                 :            : #include "xmlreader/span.hxx"
      36                 :            : #include "xmlreader/xmlreader.hxx"
      37                 :            : 
      38                 :            : #include "data.hxx"
      39                 :            : #include "localizedpropertynode.hxx"
      40                 :            : #include "groupnode.hxx"
      41                 :            : #include "node.hxx"
      42                 :            : #include "nodemap.hxx"
      43                 :            : #include "parsemanager.hxx"
      44                 :            : #include "propertynode.hxx"
      45                 :            : #include "setnode.hxx"
      46                 :            : #include "xcsparser.hxx"
      47                 :            : #include "xmldata.hxx"
      48                 :            : 
      49                 :            : namespace configmgr {
      50                 :            : 
      51                 :            : namespace {
      52                 :            : 
      53                 :            : namespace css = com::sun::star;
      54                 :            : 
      55                 :            : // Conservatively merge a template or component (and its recursive parts) into
      56                 :            : // an existing instance:
      57                 :          0 : void merge(
      58                 :            :     rtl::Reference< Node > const & original,
      59                 :            :     rtl::Reference< Node > const & update)
      60                 :            : {
      61                 :            :     assert(
      62                 :            :         original.is() && update.is() && original->kind() == update->kind() &&
      63                 :            :         update->getFinalized() == Data::NO_LAYER);
      64   [ #  #  #  # ]:          0 :     if (update->getLayer() >= original->getLayer() &&
                 [ #  # ]
      65                 :          0 :         update->getLayer() <= original->getFinalized())
      66                 :            :     {
      67   [ #  #  #  #  :          0 :         switch (original->kind()) {
                      # ]
      68                 :            :         case Node::KIND_PROPERTY:
      69                 :            :         case Node::KIND_LOCALIZED_PROPERTY:
      70                 :            :         case Node::KIND_LOCALIZED_VALUE:
      71                 :          0 :             break; //TODO: merge certain parts?
      72                 :            :         case Node::KIND_GROUP:
      73 [ #  # ][ #  # ]:          0 :             for (NodeMap::const_iterator i2(update->getMembers().begin());
      74         [ #  # ]:          0 :                  i2 != update->getMembers().end(); ++i2)
      75                 :            :             {
      76         [ #  # ]:          0 :                 NodeMap & members = original->getMembers();
      77         [ #  # ]:          0 :                 NodeMap::iterator i1(members.find(i2->first));
      78         [ #  # ]:          0 :                 if (i1 == members.end()) {
      79 [ #  # ][ #  # ]:          0 :                     if (i2->second->kind() == Node::KIND_PROPERTY &&
         [ #  # ][ #  # ]
      80                 :            :                         dynamic_cast< GroupNode * >(
      81 [ #  # ][ #  # ]:          0 :                             original.get())->isExtensible())
      82                 :            :                     {
      83         [ #  # ]:          0 :                         members.insert(*i2);
      84                 :            :                     }
      85 [ #  # ][ #  # ]:          0 :                 } else if (i2->second->kind() == i1->second->kind()) {
                 [ #  # ]
      86         [ #  # ]:          0 :                     merge(i1->second, i2->second);
      87                 :            :                 }
      88                 :            :             }
      89                 :          0 :             break;
      90                 :            :         case Node::KIND_SET:
      91 [ #  # ][ #  # ]:          0 :             for (NodeMap::const_iterator i2(update->getMembers().begin());
      92         [ #  # ]:          0 :                  i2 != update->getMembers().end(); ++i2)
      93                 :            :             {
      94         [ #  # ]:          0 :                 NodeMap & members = original->getMembers();
      95         [ #  # ]:          0 :                 NodeMap::iterator i1(members.find(i2->first));
      96         [ #  # ]:          0 :                 if (i1 == members.end()) {
      97   [ #  #  #  # ]:          0 :                     if (dynamic_cast< SetNode * >(original.get())->
      98   [ #  #  #  # ]:          0 :                         isValidTemplate(i2->second->getTemplateName()))
      99                 :            :                     {
     100         [ #  # ]:          0 :                         members.insert(*i2);
     101                 :            :                     }
     102 [ #  # ][ #  # ]:          0 :                 } else if (i2->second->kind() == i1->second->kind() &&
           [ #  #  #  # ]
                 [ #  # ]
     103                 :          0 :                            (i2->second->getTemplateName() ==
     104   [ #  #  #  # ]:          0 :                             i1->second->getTemplateName()))
         [ #  # ][ #  # ]
           [ #  #  #  # ]
     105                 :            :                 {
     106         [ #  # ]:          0 :                     merge(i1->second, i2->second);
     107                 :            :                 }
     108                 :            :             }
     109                 :          0 :             break;
     110                 :            :         case Node::KIND_ROOT:
     111                 :            :             assert(false); // this cannot happen
     112                 :          0 :             break;
     113                 :            :         }
     114                 :            :     }
     115                 :          0 : }
     116                 :            : 
     117                 :            : }
     118                 :            : 
     119                 :      33652 : XcsParser::XcsParser(int layer, Data & data):
     120 [ +  - ][ +  - ]:      33652 :     valueParser_(layer), data_(data), state_(STATE_START)
                 [ +  - ]
     121                 :      33652 : {}
     122                 :            : 
     123 [ +  - ][ -  + ]:      67304 : XcsParser::~XcsParser() {}
     124                 :            : 
     125                 :    7540612 : xmlreader::XmlReader::Text XcsParser::getTextMode() {
     126                 :    7540612 :     return valueParser_.getTextMode();
     127                 :            : }
     128                 :            : 
     129                 :    3554322 : bool XcsParser::startElement(
     130                 :            :     xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name)
     131                 :            : {
     132         [ +  + ]:    3554322 :     if (valueParser_.startElement(reader, nsId, name)) {
     133                 :       8100 :         return true;
     134                 :            :     }
     135         [ +  + ]:    3546222 :     if (state_ == STATE_START) {
     136   [ +  -  +  - ]:      67304 :         if (nsId == ParseManager::NAMESPACE_OOR &&
                 [ +  - ]
     137                 :      33652 :             name.equals(RTL_CONSTASCII_STRINGPARAM("component-schema"))) {
     138                 :      33652 :             handleComponentSchema(reader);
     139                 :      33652 :             state_ = STATE_COMPONENT_SCHEMA;
     140                 :      33652 :             ignoring_ = 0;
     141                 :      33652 :             return true;
     142                 :            :         }
     143                 :            :     } else {
     144                 :            :         //TODO: ignoring component-schema import, component-schema uses, and
     145                 :            :         // prop constraints; accepting all four at illegal places (and with
     146                 :            :         // illegal content):
     147 [ +  + ][ +  -  :   10928232 :         if (ignoring_ > 0 ||
          +  +  +  +  +  
                +  +  + ]
                 [ +  + ]
     148                 :            :             (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
     149                 :    2319186 :              (name.equals(RTL_CONSTASCII_STRINGPARAM("info")) ||
     150                 :    1705428 :               name.equals(RTL_CONSTASCII_STRINGPARAM("import")) ||
     151                 :    1698410 :               name.equals(RTL_CONSTASCII_STRINGPARAM("uses")) ||
     152                 :    1692638 :               name.equals(RTL_CONSTASCII_STRINGPARAM("constraints")))))
     153                 :            :         {
     154                 :            :             assert(ignoring_ < LONG_MAX);
     155                 :    1856666 :             ++ignoring_;
     156                 :    1856666 :             return true;
     157                 :            :         }
     158   [ +  +  +  +  :    1655904 :         switch (state_) {
                   -  - ]
     159                 :            :         case STATE_COMPONENT_SCHEMA:
     160   [ +  -  +  + ]:      67304 :             if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  + ]
     161                 :      33652 :                 name.equals(RTL_CONSTASCII_STRINGPARAM("templates")))
     162                 :            :             {
     163                 :      30798 :                 state_ = STATE_TEMPLATES;
     164                 :      30798 :                 return true;
     165                 :            :             }
     166                 :            :             // fall through
     167                 :            :         case STATE_TEMPLATES_DONE:
     168   [ +  -  +  - ]:      67304 :             if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  - ]
     169                 :      33652 :                 name.equals(RTL_CONSTASCII_STRINGPARAM("component")))
     170                 :            :             {
     171                 :      33652 :                 state_ = STATE_COMPONENT;
     172                 :            :                 assert(elements_.empty());
     173                 :            :                 elements_.push(
     174                 :            :                     Element(
     175                 :            :                         new GroupNode(
     176         [ +  - ]:      33652 :                             valueParser_.getLayer(), false, rtl::OUString()),
     177 [ +  - ][ +  - ]:      67304 :                         componentName_));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     178                 :      33652 :                 return true;
     179                 :            :             }
     180                 :          0 :             break;
     181                 :            :         case STATE_TEMPLATES:
     182         [ +  + ]:     378362 :             if (elements_.empty()) {
     183   [ +  -  +  + ]:     120896 :                 if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  + ]
     184                 :      60448 :                     name.equals(RTL_CONSTASCII_STRINGPARAM("group")))
     185                 :            :                 {
     186                 :      57856 :                     handleGroup(reader, true);
     187                 :      57856 :                     return true;
     188                 :            :                 }
     189   [ +  -  +  - ]:       5184 :                 if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  - ]
     190                 :       2592 :                     name.equals(RTL_CONSTASCII_STRINGPARAM("set")))
     191                 :            :                 {
     192                 :       2592 :                     handleSet(reader, true);
     193                 :       2592 :                     return true;
     194                 :            :                 }
     195                 :          0 :                 break;
     196                 :            :             }
     197                 :            :             // fall through
     198                 :            :         case STATE_COMPONENT:
     199                 :            :             assert(!elements_.empty());
     200   [ +  +  -  - ]:    1531006 :             switch (elements_.top().node->kind()) {
     201                 :            :             case Node::KIND_PROPERTY:
     202                 :            :             case Node::KIND_LOCALIZED_PROPERTY:
     203   [ +  -  +  - ]:     961388 :                 if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  - ]
     204                 :     480694 :                     name.equals(RTL_CONSTASCII_STRINGPARAM("value")))
     205                 :            :                 {
     206                 :     480694 :                     handlePropValue(reader, elements_.top().node);
     207                 :     480694 :                     return true;
     208                 :            :                 }
     209                 :          0 :                 break;
     210                 :            :             case Node::KIND_GROUP:
     211   [ +  -  +  + ]:    2100624 :                 if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  + ]
     212                 :    1050312 :                     name.equals(RTL_CONSTASCII_STRINGPARAM("prop")))
     213                 :            :                 {
     214                 :     779748 :                     handleProp(reader);
     215                 :     779748 :                     return true;
     216                 :            :                 }
     217   [ +  -  +  + ]:     541128 :                 if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  + ]
     218                 :     270564 :                     name.equals(RTL_CONSTASCII_STRINGPARAM("node-ref")))
     219                 :            :                 {
     220                 :      12558 :                     handleNodeRef(reader);
     221                 :      12558 :                     return true;
     222                 :            :                 }
     223   [ +  -  +  + ]:     516012 :                 if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  + ]
     224                 :     258006 :                     name.equals(RTL_CONSTASCII_STRINGPARAM("group")))
     225                 :            :                 {
     226                 :     185174 :                     handleGroup(reader, false);
     227                 :     185174 :                     return true;
     228                 :            :                 }
     229   [ +  -  +  - ]:     145664 :                 if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  - ]
     230                 :      72832 :                     name.equals(RTL_CONSTASCII_STRINGPARAM("set")))
     231                 :            :                 {
     232                 :      72832 :                     handleSet(reader, false);
     233                 :      72832 :                     return true;
     234                 :            :                 }
     235                 :          0 :                 break;
     236                 :            :             case Node::KIND_SET:
     237   [ #  #  #  # ]:          0 :                 if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ #  # ]
     238                 :          0 :                     name.equals(RTL_CONSTASCII_STRINGPARAM("item")))
     239                 :            :                 {
     240                 :            :                     handleSetItem(
     241                 :            :                         reader,
     242         [ #  # ]:          0 :                         dynamic_cast< SetNode * >(elements_.top().node.get()));
     243                 :          0 :                     return true;
     244                 :            :                 }
     245                 :          0 :                 break;
     246                 :            :             default: // Node::KIND_LOCALIZED_VALUE
     247                 :            :                 assert(false); // this cannot happen
     248                 :          0 :                 break;
     249                 :            :             }
     250                 :          0 :             break;
     251                 :            :         case STATE_COMPONENT_DONE:
     252                 :          0 :             break;
     253                 :            :         default: // STATE_START
     254                 :            :             assert(false); // this cannot happen
     255                 :          0 :             break;
     256                 :            :         }
     257                 :            :     }
     258                 :            :     throw css::uno::RuntimeException(
     259                 :            :         (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad member <")) +
     260                 :            :          name.convertFromUtf8() +
     261                 :            :          rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) + reader.getUrl()),
     262 [ #  # ][ #  # ]:    3554322 :         css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
                 [ #  # ]
     263                 :            : }
     264                 :            : 
     265                 :    3554322 : void XcsParser::endElement(xmlreader::XmlReader const & reader) {
     266         [ +  + ]:    3554322 :     if (valueParser_.endElement()) {
     267                 :    3554322 :         return;
     268                 :            :     }
     269         [ +  + ]:    3065528 :     if (ignoring_ > 0) {
     270                 :    1856666 :         --ignoring_;
     271         [ +  + ]:    1208862 :     } else if (!elements_.empty()) {
     272 [ +  - ][ +  - ]:    1144412 :         Element top(elements_.top());
     273         [ +  - ]:    1144412 :         elements_.pop();
     274         [ +  - ]:    1144412 :         if (top.node.is()) {
     275         [ +  + ]:    1144412 :             if (elements_.empty()) {
     276      [ +  +  - ]:      94100 :                 switch (state_) {
     277                 :            :                 case STATE_TEMPLATES:
     278                 :            :                     {
     279         [ +  - ]:      60448 :                         NodeMap::iterator i(data_.templates.find(top.name));
     280         [ +  - ]:      60448 :                         if (i == data_.templates.end()) {
     281                 :            :                             data_.templates.insert(
     282 [ +  - ][ +  - ]:      60448 :                                 NodeMap::value_type(top.name, top.node));
                 [ +  - ]
     283                 :            :                         } else {
     284         [ #  # ]:          0 :                             merge(i->second, top.node);
     285                 :            :                         }
     286                 :            :                     }
     287                 :      60448 :                     break;
     288                 :            :                 case STATE_COMPONENT:
     289                 :            :                     {
     290         [ +  - ]:      33652 :                         NodeMap & components = data_.getComponents();
     291         [ +  - ]:      33652 :                         NodeMap::iterator i(components.find(top.name));
     292         [ +  - ]:      33652 :                         if (i == components.end()) {
     293                 :            :                             components.insert(
     294 [ +  - ][ +  - ]:      33652 :                                 NodeMap::value_type(top.name, top.node));
                 [ +  - ]
     295                 :            :                         } else {
     296         [ #  # ]:          0 :                             merge(i->second, top.node);
     297                 :            :                         }
     298                 :      33652 :                         state_ = STATE_COMPONENT_DONE;
     299                 :            :                     }
     300                 :      33652 :                     break;
     301                 :            :                 default:
     302                 :            :                     assert(false);
     303                 :            :                     throw css::uno::RuntimeException(
     304                 :            :                         rtl::OUString(
     305                 :            :                             RTL_CONSTASCII_USTRINGPARAM("this cannot happen")),
     306 [ #  # ][ #  # ]:      94100 :                         css::uno::Reference< css::uno::XInterface >());
     307                 :            :                 }
     308                 :            :             } else {
     309 [ +  - ][ +  - ]:    2100624 :                 if (!elements_.top().node->getMembers().insert(
                 [ -  + ]
     310 [ +  - ][ +  - ]:    2100624 :                         NodeMap::value_type(top.name, top.node)).second)
                 [ +  - ]
     311                 :            :                 {
     312                 :            :                     throw css::uno::RuntimeException(
     313                 :            :                         (rtl::OUString(
     314                 :            :                             RTL_CONSTASCII_USTRINGPARAM("duplicate ")) +
     315                 :            :                          top.name +
     316                 :            :                          rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
     317                 :            :                          reader.getUrl()),
     318 [ #  # ][ #  # ]:          0 :                         css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
     319                 :            :                 }
     320                 :            :             }
     321         [ +  - ]:    1144412 :         }
     322                 :            :     } else {
     323   [ -  +  -  +  :      64450 :         switch (state_) {
                      - ]
     324                 :            :         case STATE_COMPONENT_SCHEMA:
     325                 :            :             // To support old, broken extensions with .xcs files that contain
     326                 :            :             // empty <component-schema> elements:
     327                 :          0 :             state_ = STATE_COMPONENT_DONE;
     328                 :          0 :             break;
     329                 :            :         case STATE_TEMPLATES:
     330                 :      30798 :             state_ = STATE_TEMPLATES_DONE;
     331                 :      30798 :             break;
     332                 :            :         case STATE_TEMPLATES_DONE:
     333                 :            :             throw css::uno::RuntimeException(
     334                 :            :                 (rtl::OUString(
     335                 :            :                     RTL_CONSTASCII_USTRINGPARAM("no component element in ")) +
     336                 :            :                  reader.getUrl()),
     337 [ #  # ][ #  # ]:          0 :                 css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     338                 :            :         case STATE_COMPONENT_DONE:
     339                 :      33652 :             break;
     340                 :            :         default:
     341                 :            :             assert(false); // this cannot happen
     342                 :            :         }
     343                 :            :     }
     344                 :            : }
     345                 :            : 
     346                 :     429676 : void XcsParser::characters(xmlreader::Span const & text) {
     347                 :     429676 :     valueParser_.characters(text);
     348                 :     429676 : }
     349                 :            : 
     350                 :      33652 : void XcsParser::handleComponentSchema(xmlreader::XmlReader & reader) {
     351                 :            :     //TODO: oor:version, xml:lang attributes
     352                 :      33652 :     rtl::OStringBuffer buf;
     353         [ +  - ]:      33652 :     buf.append('.');
     354                 :      33652 :     bool hasPackage = false;
     355                 :      33652 :     bool hasName = false;
     356                 :     100956 :     for (;;) {
     357                 :            :         int attrNsId;
     358                 :     134608 :         xmlreader::Span attrLn;
     359 [ +  + ][ +  - ]:     134608 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     360                 :            :             break;
     361                 :            :         }
     362   [ +  +  +  + ]:     168260 :         if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     363                 :      67304 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("package")))
     364                 :            :         {
     365         [ -  + ]:      33652 :             if (hasPackage) {
     366                 :            :                 throw css::uno::RuntimeException(
     367                 :            :                     (rtl::OUString(
     368                 :            :                         RTL_CONSTASCII_USTRINGPARAM(
     369                 :            :                             "multiple component-schema package attributes"
     370                 :            :                             " in ")) +
     371                 :            :                      reader.getUrl()),
     372 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     373                 :            :             }
     374                 :      33652 :             hasPackage = true;
     375         [ +  - ]:      33652 :             xmlreader::Span s(reader.getAttributeValue(false));
     376         [ +  - ]:      33652 :             buf.insert(0, s.begin, s.length);
     377   [ +  +  +  - ]:     100956 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     378                 :      33652 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
     379                 :            :         {
     380         [ -  + ]:      33652 :             if (hasName) {
     381                 :            :                 throw css::uno::RuntimeException(
     382                 :            :                     (rtl::OUString(
     383                 :            :                         RTL_CONSTASCII_USTRINGPARAM(
     384                 :            :                             "multiple component-schema name attributes in ")) +
     385                 :            :                      reader.getUrl()),
     386 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     387                 :            :             }
     388                 :      33652 :             hasName = true;
     389         [ +  - ]:      33652 :             xmlreader::Span s(reader.getAttributeValue(false));
     390         [ +  - ]:      33652 :             buf.append(s.begin, s.length);
     391                 :            :         }
     392                 :            :     }
     393         [ -  + ]:      33652 :     if (!hasPackage) {
     394                 :            :         throw css::uno::RuntimeException(
     395                 :            :             (rtl::OUString(
     396                 :            :                 RTL_CONSTASCII_USTRINGPARAM(
     397                 :            :                     "no component-schema package attribute in ")) +
     398                 :            :              reader.getUrl()),
     399 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     400                 :            :     }
     401         [ -  + ]:      33652 :     if (!hasName) {
     402                 :            :         throw css::uno::RuntimeException(
     403                 :            :             (rtl::OUString(
     404                 :            :                 RTL_CONSTASCII_USTRINGPARAM(
     405                 :            :                     "no component-schema name attribute in ")) +
     406                 :            :              reader.getUrl()),
     407 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     408                 :            :     }
     409                 :            :     componentName_ = xmlreader::Span(buf.getStr(), buf.getLength()).
     410         [ +  - ]:      33652 :         convertFromUtf8();
     411                 :      33652 : }
     412                 :            : 
     413                 :      12558 : void XcsParser::handleNodeRef(xmlreader::XmlReader & reader) {
     414                 :      12558 :     bool hasName = false;
     415                 :      12558 :     rtl::OUString name;
     416                 :      12558 :     rtl::OUString component(componentName_);
     417                 :      12558 :     bool hasNodeType = false;
     418                 :      12558 :     rtl::OUString nodeType;
     419                 :      25116 :     for (;;) {
     420                 :            :         int attrNsId;
     421                 :      37674 :         xmlreader::Span attrLn;
     422 [ +  + ][ +  - ]:      37674 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     423                 :            :             break;
     424                 :            :         }
     425   [ +  -  +  + ]:      50232 :         if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     426                 :      25116 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
     427                 :            :         {
     428                 :      12558 :             hasName = true;
     429 [ +  - ][ +  - ]:      12558 :             name = reader.getAttributeValue(false).convertFromUtf8();
     430   [ +  -  -  + ]:      25116 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ -  + ]
     431                 :      12558 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("component")))
     432                 :            :         {
     433 [ #  # ][ #  # ]:          0 :             component = reader.getAttributeValue(false).convertFromUtf8();
     434   [ +  -  +  - ]:      25116 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  - ]
     435                 :      12558 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("node-type")))
     436                 :            :         {
     437                 :      12558 :             hasNodeType = true;
     438 [ +  - ][ +  - ]:      12558 :             nodeType = reader.getAttributeValue(false).convertFromUtf8();
     439                 :            :         }
     440                 :            :     }
     441         [ -  + ]:      12558 :     if (!hasName) {
     442                 :            :         throw css::uno::RuntimeException(
     443                 :            :             (rtl::OUString(
     444                 :            :                 RTL_CONSTASCII_USTRINGPARAM("no node-ref name attribute in ")) +
     445                 :            :              reader.getUrl()),
     446 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     447                 :            :     }
     448                 :            :     rtl::Reference< Node > tmpl(
     449                 :            :         data_.getTemplate(
     450                 :            :             valueParser_.getLayer(),
     451                 :            :             xmldata::parseTemplateReference(
     452 [ +  - ][ +  - ]:      12558 :                 component, hasNodeType, nodeType, 0)));
                 [ +  - ]
     453         [ -  + ]:      12558 :     if (!tmpl.is()) {
     454                 :            :         //TODO: this can erroneously happen as long as import/uses attributes
     455                 :            :         // are not correctly processed
     456                 :            :         throw css::uno::RuntimeException(
     457                 :            :             (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unknown node-ref ")) +
     458                 :            :              name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
     459                 :            :              reader.getUrl()),
     460 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
     461                 :            :     }
     462         [ +  - ]:      12558 :     rtl::Reference< Node > node(tmpl->clone(false));
     463 [ +  - ][ +  - ]:      12558 :     node->setLayer(valueParser_.getLayer());
     464 [ +  - ][ +  - ]:      12558 :     elements_.push(Element(node, name));
         [ +  - ][ +  - ]
                 [ +  - ]
     465                 :      12558 : }
     466                 :            : 
     467                 :     779748 : void XcsParser::handleProp(xmlreader::XmlReader & reader) {
     468                 :     779748 :     bool hasName = false;
     469                 :     779748 :     rtl::OUString name;
     470                 :     779748 :     valueParser_.type_ = TYPE_ERROR;
     471                 :     779748 :     bool localized = false;
     472                 :     779748 :     bool nillable = true;
     473                 :    2064946 :     for (;;) {
     474                 :            :         int attrNsId;
     475                 :    2844694 :         xmlreader::Span attrLn;
     476 [ +  + ][ +  - ]:    2844694 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     477                 :            :             break;
     478                 :            :         }
     479   [ +  -  +  + ]:    4129892 :         if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     480                 :    2064946 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
     481                 :            :         {
     482                 :     779748 :             hasName = true;
     483 [ +  - ][ +  - ]:     779748 :             name = reader.getAttributeValue(false).convertFromUtf8();
     484   [ +  -  +  + ]:    2570396 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     485                 :    1285198 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type")))
     486                 :            :         {
     487                 :            :             valueParser_.type_ = xmldata::parseType(
     488 [ +  - ][ +  - ]:     779748 :                 reader, reader.getAttributeValue(true));
     489   [ +  -  +  + ]:    1010900 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     490                 :     505450 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("localized")))
     491                 :            :         {
     492 [ +  - ][ +  - ]:      60274 :             localized = xmldata::parseBoolean(reader.getAttributeValue(true));
     493   [ +  -  +  - ]:     890352 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  - ]
     494                 :     445176 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("nillable")))
     495                 :            :         {
     496 [ +  - ][ +  - ]:     445176 :             nillable = xmldata::parseBoolean(reader.getAttributeValue(true));
     497                 :            :         }
     498                 :            :     }
     499         [ -  + ]:     779748 :     if (!hasName) {
     500                 :            :         throw css::uno::RuntimeException(
     501                 :            :             (rtl::OUString(
     502                 :            :                 RTL_CONSTASCII_USTRINGPARAM("no prop name attribute in ")) +
     503                 :            :              reader.getUrl()),
     504 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     505                 :            :     }
     506         [ -  + ]:     779748 :     if (valueParser_.type_ == TYPE_ERROR) {
     507                 :            :         throw css::uno::RuntimeException(
     508                 :            :             (rtl::OUString(
     509                 :            :                 RTL_CONSTASCII_USTRINGPARAM("no prop type attribute in ")) +
     510                 :            :              reader.getUrl()),
     511 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     512                 :            :     }
     513                 :            :     elements_.push(
     514                 :            :         Element(
     515                 :            :             (localized
     516                 :            :              ? rtl::Reference< Node >(
     517                 :            :                  new LocalizedPropertyNode(
     518         [ +  - ]:      59302 :                      valueParser_.getLayer(), valueParser_.type_, nillable))
     519                 :            :              : rtl::Reference< Node >(
     520                 :            :                  new PropertyNode(
     521                 :     720446 :                      valueParser_.getLayer(), valueParser_.type_, nillable,
     522         [ +  - ]:     720446 :                      css::uno::Any(), false))),
     523 [ +  + ][ +  - ]:    1559496 :             name));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
                 [ #  # ]
     524                 :     779748 : }
     525                 :            : 
     526                 :     480694 : void XcsParser::handlePropValue(
     527                 :            :     xmlreader::XmlReader & reader, rtl::Reference< Node > const & property)
     528                 :            : {
     529                 :     480694 :     xmlreader::Span attrSeparator;
     530                 :       2268 :     for (;;) {
     531                 :            :         int attrNsId;
     532                 :     482962 :         xmlreader::Span attrLn;
     533 [ +  + ][ +  - ]:     482962 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     534                 :            :             break;
     535                 :            :         }
     536   [ +  -  +  - ]:       4536 :         if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  - ]
     537                 :       2268 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("separator")))
     538                 :            :         {
     539         [ +  - ]:       2268 :             attrSeparator = reader.getAttributeValue(false);
     540         [ -  + ]:       2268 :             if (attrSeparator.length == 0) {
     541                 :            :                 throw css::uno::RuntimeException(
     542                 :            :                     (rtl::OUString(
     543                 :            :                         RTL_CONSTASCII_USTRINGPARAM(
     544                 :            :                             "bad oor:separator attribute in ")) +
     545                 :            :                      reader.getUrl()),
     546 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     547                 :            :             }
     548                 :            :         }
     549                 :            :     }
     550                 :            :     valueParser_.separator_ = rtl::OString(
     551                 :     480694 :         attrSeparator.begin, attrSeparator.length);
     552         [ +  - ]:     480694 :     valueParser_.start(property);
     553                 :     480694 : }
     554                 :            : 
     555                 :     243030 : void XcsParser::handleGroup(xmlreader::XmlReader & reader, bool isTemplate) {
     556                 :     243030 :     bool hasName = false;
     557                 :     243030 :     rtl::OUString name;
     558                 :     243030 :     bool extensible = false;
     559                 :     250744 :     for (;;) {
     560                 :            :         int attrNsId;
     561                 :     493774 :         xmlreader::Span attrLn;
     562 [ +  + ][ +  - ]:     493774 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     563                 :            :             break;
     564                 :            :         }
     565   [ +  -  +  + ]:     501488 :         if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     566                 :     250744 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
     567                 :            :         {
     568                 :     243030 :             hasName = true;
     569 [ +  - ][ +  - ]:     243030 :             name = reader.getAttributeValue(false).convertFromUtf8();
     570   [ +  -  +  + ]:      15428 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     571                 :       7714 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("extensible")))
     572                 :            :         {
     573 [ +  - ][ +  - ]:       7390 :             extensible = xmldata::parseBoolean(reader.getAttributeValue(true));
     574                 :            :         }
     575                 :            :     }
     576         [ -  + ]:     243030 :     if (!hasName) {
     577                 :            :         throw css::uno::RuntimeException(
     578                 :            :             (rtl::OUString(
     579                 :            :                 RTL_CONSTASCII_USTRINGPARAM("no group name attribute in ")) +
     580                 :            :              reader.getUrl()),
     581 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     582                 :            :     }
     583         [ +  + ]:     243030 :     if (isTemplate) {
     584         [ +  - ]:      57856 :         name = Data::fullTemplateName(componentName_, name);
     585                 :            :     }
     586                 :            :     elements_.push(
     587                 :            :         Element(
     588                 :            :             new GroupNode(
     589                 :     243030 :                 valueParser_.getLayer(), extensible,
     590         [ +  - ]:     243030 :                 isTemplate ? name : rtl::OUString()),
     591 [ +  - ][ +  + ]:     486060 :             name));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     592                 :     243030 : }
     593                 :            : 
     594                 :      75424 : void XcsParser::handleSet(xmlreader::XmlReader & reader, bool isTemplate) {
     595                 :      75424 :     bool hasName = false;
     596                 :      75424 :     rtl::OUString name;
     597                 :      75424 :     rtl::OUString component(componentName_);
     598                 :      75424 :     bool hasNodeType = false;
     599                 :      75424 :     rtl::OUString nodeType;
     600                 :     164918 :     for (;;) {
     601                 :            :         int attrNsId;
     602                 :     240342 :         xmlreader::Span attrLn;
     603 [ +  + ][ +  - ]:     240342 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     604                 :            :             break;
     605                 :            :         }
     606   [ +  -  +  + ]:     329836 :         if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     607                 :     164918 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
     608                 :            :         {
     609                 :      75424 :             hasName = true;
     610 [ +  - ][ +  - ]:      75424 :             name = reader.getAttributeValue(false).convertFromUtf8();
     611   [ +  -  +  + ]:     178988 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     612                 :      89494 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("component")))
     613                 :            :         {
     614 [ +  - ][ +  - ]:      14070 :             component = reader.getAttributeValue(false).convertFromUtf8();
     615   [ +  -  +  - ]:     150848 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  - ]
     616                 :      75424 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("node-type")))
     617                 :            :         {
     618                 :      75424 :             hasNodeType = true;
     619 [ +  - ][ +  - ]:      75424 :             nodeType = reader.getAttributeValue(false).convertFromUtf8();
     620                 :            :         }
     621                 :            :     }
     622         [ -  + ]:      75424 :     if (!hasName) {
     623                 :            :         throw css::uno::RuntimeException(
     624                 :            :             (rtl::OUString(
     625                 :            :                 RTL_CONSTASCII_USTRINGPARAM("no set name attribute in ")) +
     626                 :            :              reader.getUrl()),
     627 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     628                 :            :     }
     629         [ +  + ]:      75424 :     if (isTemplate) {
     630         [ +  - ]:       2592 :         name = Data::fullTemplateName(componentName_, name);
     631                 :            :     }
     632                 :            :     elements_.push(
     633                 :            :         Element(
     634                 :            :             new SetNode(
     635                 :      75424 :                 valueParser_.getLayer(),
     636                 :            :                 xmldata::parseTemplateReference(
     637                 :            :                     component, hasNodeType, nodeType, 0),
     638         [ +  - ]:      75424 :                 isTemplate ? name : rtl::OUString()),
     639 [ +  - ][ +  - ]:     150848 :             name));
         [ +  + ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     640                 :      75424 : }
     641                 :            : 
     642                 :          0 : void XcsParser::handleSetItem(xmlreader::XmlReader & reader, SetNode * set) {
     643                 :          0 :     rtl::OUString component(componentName_);
     644                 :          0 :     bool hasNodeType = false;
     645                 :          0 :     rtl::OUString nodeType;
     646                 :          0 :     for (;;) {
     647                 :            :         int attrNsId;
     648                 :          0 :         xmlreader::Span attrLn;
     649 [ #  # ][ #  # ]:          0 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     650                 :            :             break;
     651                 :            :         }
     652   [ #  #  #  # ]:          0 :         if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ #  # ]
     653                 :          0 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("component")))
     654                 :            :         {
     655 [ #  # ][ #  # ]:          0 :             component = reader.getAttributeValue(false).convertFromUtf8();
     656   [ #  #  #  # ]:          0 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ #  # ]
     657                 :          0 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("node-type")))
     658                 :            :         {
     659                 :          0 :             hasNodeType = true;
     660 [ #  # ][ #  # ]:          0 :             nodeType = reader.getAttributeValue(false).convertFromUtf8();
     661                 :            :         }
     662                 :            :     }
     663         [ #  # ]:          0 :     set->getAdditionalTemplateNames().push_back(
     664 [ #  # ][ #  # ]:          0 :         xmldata::parseTemplateReference(component, hasNodeType, nodeType, 0));
     665 [ #  # ][ #  # ]:          0 :     elements_.push(Element(rtl::Reference< Node >(), rtl::OUString()));
         [ #  # ][ #  # ]
     666                 :          0 : }
     667                 :            : 
     668                 :            : }
     669                 :            : 
     670                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10