LCOV - code coverage report
Current view: top level - unoidl/source - legacyprovider.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 377 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          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             : 
      10             : #include "sal/config.h"
      11             : 
      12             : #include <cassert>
      13             : #include <cstring>
      14             : #include <vector>
      15             : 
      16             : #include "registry/reader.hxx"
      17             : #include "registry/registry.hxx"
      18             : #include "registry/regtype.h"
      19             : #include "rtl/ref.hxx"
      20             : #include "rtl/ustring.hxx"
      21             : #include "sal/types.h"
      22             : #include "unoidl/unoidl.hxx"
      23             : 
      24             : #include "legacyprovider.hxx"
      25             : 
      26             : namespace unoidl { namespace detail {
      27             : 
      28             : namespace {
      29             : 
      30           0 : std::vector< OUString > translateAnnotations(OUString const & documentation) {
      31           0 :     std::vector< OUString > ans;
      32           0 :     if (documentation.indexOf("@deprecated") != -1) {
      33             :         //TODO: this check is somewhat crude
      34           0 :         ans.push_back("deprecated");
      35             :     }
      36           0 :     return ans;
      37             : }
      38             : 
      39           0 : ConstantValue translateConstantValue(
      40             :     RegistryKey & key, RTConstValue const & value)
      41             : {
      42           0 :     switch (value.m_type) {
      43             :     case RT_TYPE_BOOL:
      44           0 :         return ConstantValue(static_cast< bool >(value.m_value.aBool));
      45             :     case RT_TYPE_BYTE:
      46           0 :         return ConstantValue(value.m_value.aByte);
      47             :     case RT_TYPE_INT16:
      48           0 :         return ConstantValue(value.m_value.aShort);
      49             :     case RT_TYPE_UINT16:
      50           0 :         return ConstantValue(value.m_value.aUShort);
      51             :     case RT_TYPE_INT32:
      52           0 :         return ConstantValue(value.m_value.aLong);
      53             :     case RT_TYPE_UINT32:
      54           0 :         return ConstantValue(value.m_value.aULong);
      55             :     case RT_TYPE_INT64:
      56           0 :         return ConstantValue(value.m_value.aHyper);
      57             :     case RT_TYPE_UINT64:
      58           0 :         return ConstantValue(value.m_value.aUHyper);
      59             :     case RT_TYPE_FLOAT:
      60           0 :         return ConstantValue(value.m_value.aFloat);
      61             :     case RT_TYPE_DOUBLE:
      62           0 :         return ConstantValue(value.m_value.aDouble);
      63             :     default:
      64             :         throw FileFormatException(
      65             :             key.getRegistryName(),
      66           0 :             ("legacy format: unexpected type " + OUString::number(value.m_type)
      67           0 :              + " of value of a field  of constant group with key "
      68           0 :              + key.getName()));
      69             :     }
      70             : }
      71             : 
      72             : rtl::Reference< Entity > readEntity(
      73             :     rtl::Reference< Manager > const & manager, RegistryKey & ucr,
      74             :     RegistryKey & key, OUString const & path, bool probe);
      75             : 
      76             : class Cursor: public MapCursor {
      77             : public:
      78             :     Cursor(
      79             :         rtl::Reference< Manager > const & manager, RegistryKey const & ucr,
      80             :         RegistryKey const & key);
      81             : 
      82             : private:
      83           0 :     virtual ~Cursor() throw () {}
      84             : 
      85             :     virtual rtl::Reference< Entity > getNext(OUString * name) SAL_OVERRIDE;
      86             : 
      87             :     rtl::Reference< Manager > manager_;
      88             :     RegistryKey ucr_;
      89             :     RegistryKey key_;
      90             :     OUString prefix_;
      91             :     RegistryKeyNames names_;
      92             :     sal_uInt32 index_;
      93             : };
      94             : 
      95           0 : Cursor::Cursor(
      96             :     rtl::Reference< Manager > const & manager, RegistryKey const & ucr,
      97             :     RegistryKey const & key):
      98           0 :     manager_(manager), ucr_(ucr), key_(key), index_(0)
      99             : {
     100           0 :     if (ucr_.isValid()) {
     101           0 :         prefix_ = key_.getName();
     102           0 :         if (!prefix_.endsWith("/")) {
     103           0 :             prefix_ += "/";
     104             :         }
     105           0 :         RegError e = key_.getKeyNames("", names_);
     106           0 :         if (e != RegError::NO_ERROR) {
     107             :             throw FileFormatException(
     108             :                 key_.getRegistryName(),
     109           0 :                 ("legacy format: cannot get sub-key names of " + key_.getName()
     110           0 :                  + ": " + OUString::number(static_cast<int>(e))));
     111             :         }
     112             :     }
     113           0 : }
     114             : 
     115           0 : rtl::Reference< Entity > Cursor::getNext(OUString * name) {
     116             :     assert(name != 0);
     117           0 :     rtl::Reference< Entity > ent;
     118           0 :     if (index_ != names_.getLength()) {
     119           0 :         OUString path(names_.getElement(index_));
     120             :         assert(path.match(prefix_));
     121           0 :         *name = path.copy(prefix_.getLength());
     122           0 :         ent = readEntity(manager_, ucr_, key_, *name, false);
     123             :         assert(ent.is());
     124           0 :         ++index_;
     125             :     }
     126           0 :     return ent;
     127             : }
     128             : 
     129             : class Module: public ModuleEntity {
     130             : public:
     131           0 :     Module(
     132             :         rtl::Reference< Manager > const & manager, RegistryKey const & ucr,
     133             :         RegistryKey const & key):
     134           0 :         manager_(manager), ucr_(ucr), key_(key)
     135           0 :     {}
     136             : 
     137             : private:
     138           0 :     virtual ~Module() throw () {}
     139             : 
     140             :     virtual std::vector< OUString > getMemberNames() const SAL_OVERRIDE;
     141             : 
     142           0 :     virtual rtl::Reference< MapCursor > createCursor() const SAL_OVERRIDE
     143           0 :     { return new Cursor(manager_, ucr_, key_); }
     144             : 
     145             :     rtl::Reference< Manager > manager_;
     146             :     RegistryKey ucr_;
     147             :     mutable RegistryKey key_;
     148             : };
     149             : 
     150           0 : std::vector< OUString > Module::getMemberNames() const {
     151           0 :     RegistryKeyNames names;
     152           0 :     RegError e = key_.getKeyNames("", names);
     153           0 :     if (e != RegError::NO_ERROR) {
     154             :         throw FileFormatException(
     155             :             key_.getRegistryName(),
     156           0 :             ("legacy format: cannot get sub-key names of " + key_.getName()
     157           0 :              + ": " + OUString::number(static_cast<int>(e))));
     158             :     }
     159           0 :     std::vector< OUString > ns;
     160           0 :     for (sal_uInt32 i = 0; i != names.getLength(); ++i) {
     161           0 :         ns.push_back(names.getElement(i));
     162             :     }
     163           0 :     return ns;
     164             : }
     165             : 
     166           0 : typereg::Reader getReader(RegistryKey & key, std::vector< char > * buffer) {
     167             :     assert(buffer != 0);
     168             :     RegValueType type;
     169             :     sal_uInt32 size;
     170           0 :     RegError e = key.getValueInfo("", &type, &size);
     171           0 :     if (e != RegError::NO_ERROR) {
     172             :         throw FileFormatException(
     173             :             key.getRegistryName(),
     174           0 :             ("legacy format: cannot get value info about key " + key.getName()
     175           0 :              + ": " + OUString::number(static_cast<int>(e))));
     176             :     }
     177           0 :     if (type != RegValueType::BINARY) {
     178             :         throw FileFormatException(
     179             :             key.getRegistryName(),
     180           0 :             ("legacy format: unexpected value type " + OUString::number(static_cast<int>(type))
     181           0 :              + " of key " + key.getName()));
     182             :     }
     183           0 :     if (size == 0
     184             :         /*TODO: || size > std::numeric_limits< std::vector< char >::size_type >::max() */)
     185             :     {
     186             :         throw FileFormatException(
     187             :             key.getRegistryName(),
     188           0 :             ("legacy format: bad binary value size " + OUString::number(size)
     189           0 :              + " of key " + key.getName()));
     190             :     }
     191           0 :     buffer->resize(static_cast< std::vector< char >::size_type >(size));
     192           0 :     e = key.getValue("", &(*buffer)[0]);
     193           0 :     if (e != RegError::NO_ERROR) {
     194             :         throw FileFormatException(
     195             :             key.getRegistryName(),
     196           0 :             ("legacy format: cannot get binary value of key " + key.getName()
     197           0 :              + ": " + OUString::number(static_cast<int>(e))));
     198             :     }
     199           0 :     typereg::Reader reader(&(*buffer)[0], size, false, TYPEREG_VERSION_1);
     200           0 :     if (!reader.isValid()) {
     201             :         throw FileFormatException(
     202             :             key.getRegistryName(),
     203           0 :             "legacy format: malformed binary value of key " + key.getName());
     204             :     }
     205           0 :     return reader;
     206             : }
     207             : 
     208           0 : rtl::Reference< Entity > readEntity(
     209             :     rtl::Reference< Manager > const & manager, RegistryKey & ucr,
     210             :     RegistryKey & key, OUString const & path, bool probe)
     211             : {
     212             :     assert(manager.is());
     213           0 :     RegistryKey sub;
     214           0 :     RegError e = key.openKey(path, sub);
     215           0 :     switch (e) {
     216             :     case RegError::NO_ERROR:
     217           0 :         break;
     218             :     case RegError::KEY_NOT_EXISTS:
     219           0 :         if (probe) {
     220           0 :             return rtl::Reference< Entity >();
     221             :         }
     222             :         // fall through
     223             :     default:
     224             :         throw FileFormatException(
     225             :             key.getRegistryName(),
     226           0 :             ("legacy format: cannot open sub-key " + path + " of "
     227           0 :              + key.getName() + ": " + OUString::number(static_cast<int>(e))));
     228             :     }
     229           0 :     std::vector< char > buf;
     230           0 :     typereg::Reader reader(getReader(sub, &buf));
     231           0 :     switch (reader.getTypeClass()) {
     232             :     case RT_TYPE_INTERFACE:
     233             :         {
     234           0 :             std::vector< AnnotatedReference > mandBases;
     235           0 :             sal_uInt16 n = reader.getSuperTypeCount();
     236           0 :             for (sal_uInt16 j = 0; j != n; ++j) {
     237             :                 mandBases.push_back(
     238             :                     AnnotatedReference(
     239             :                         reader.getSuperTypeName(j).replace('/', '.'),
     240           0 :                         std::vector< OUString >()));
     241             :             }
     242           0 :             std::vector< AnnotatedReference > optBases;
     243           0 :             n = reader.getReferenceCount();
     244           0 :             for (sal_uInt16 j = 0; j != n; ++j) {
     245             :                 optBases.push_back(
     246             :                     AnnotatedReference(
     247             :                         reader.getReferenceTypeName(j).replace('/', '.'),
     248             :                         translateAnnotations(
     249           0 :                             reader.getReferenceDocumentation(j))));
     250             :             }
     251           0 :             sal_uInt16 methodCount = reader.getMethodCount();
     252           0 :             std::vector< InterfaceTypeEntity::Attribute > attrs;
     253           0 :             n = reader.getFieldCount(); // attributes
     254           0 :             for (sal_uInt16 j = 0; j != n; ++j) {
     255           0 :                 OUString attrName(reader.getFieldName(j));
     256           0 :                 std::vector< OUString > getExcs;
     257           0 :                 std::vector< OUString > setExcs;
     258           0 :                 for (sal_uInt16 k = 0; k != methodCount; ++k) {
     259           0 :                     if (reader.getMethodName(k) == attrName) {
     260           0 :                         switch (reader.getMethodFlags(k)) {
     261             :                         case RTMethodMode::ATTRIBUTE_GET:
     262             :                             {
     263             :                                 sal_uInt16 m
     264           0 :                                     = reader.getMethodExceptionCount(k);
     265             :                                 // coverity[tainted_data] cid#1213376
     266             :                                 // unhelpfully warns about an untrusted loop
     267             :                                 // bound here:
     268           0 :                                 for (sal_uInt16 l = 0; l != m; ++l) {
     269             :                                     getExcs.push_back(
     270             :                                         reader.getMethodExceptionTypeName(k, l).
     271           0 :                                         replace('/', '.'));
     272             :                                 }
     273           0 :                                 break;
     274             :                             }
     275             :                         case RTMethodMode::ATTRIBUTE_SET:
     276             :                             {
     277             :                                 sal_uInt16 m
     278           0 :                                     = reader.getMethodExceptionCount(k);
     279             :                                 // coverity[tainted_data] cid#1213376
     280             :                                 // unhelpfully warns about an untrusted loop
     281             :                                 // bound here:
     282           0 :                                 for (sal_uInt16 l = 0; l != m; ++l) {
     283             :                                     setExcs.push_back(
     284             :                                         reader.getMethodExceptionTypeName(k, l).
     285           0 :                                         replace('/', '.'));
     286             :                                 }
     287           0 :                                 break;
     288             :                             }
     289             :                         default:
     290             :                             throw FileFormatException(
     291             :                                 key.getRegistryName(),
     292             :                                 ("legacy format: method and attribute with same"
     293           0 :                                  " name " + attrName
     294           0 :                                  + " in interface type with key "
     295           0 :                                  + sub.getName()));
     296             :                         }
     297             :                     }
     298             :                 }
     299           0 :                 RTFieldAccess flags = reader.getFieldFlags(j);
     300             :                 attrs.push_back(
     301             :                     InterfaceTypeEntity::Attribute(
     302             :                         attrName, reader.getFieldTypeName(j).replace('/', '.'),
     303           0 :                         bool(flags & RTFieldAccess::BOUND),
     304           0 :                         bool(flags & RTFieldAccess::READONLY), getExcs, setExcs,
     305           0 :                         translateAnnotations(reader.getFieldDocumentation(j))));
     306           0 :             }
     307           0 :             std::vector< InterfaceTypeEntity::Method > meths;
     308           0 :             for (sal_uInt16 j = 0; j != methodCount; ++j) {
     309           0 :                 RTMethodMode flags = reader.getMethodFlags(j);
     310           0 :                 if (flags != RTMethodMode::ATTRIBUTE_GET
     311           0 :                     && flags != RTMethodMode::ATTRIBUTE_SET)
     312             :                 {
     313             :                     std::vector< InterfaceTypeEntity::Method::Parameter >
     314           0 :                         params;
     315           0 :                     sal_uInt16 m = reader.getMethodParameterCount(j);
     316             :                     // coverity[tainted_data] cid#1213376 unhelpfully warns
     317             :                     // about an untrusted loop bound here:
     318           0 :                     for (sal_uInt16 k = 0; k != m; ++k) {
     319           0 :                         RTParamMode mode = reader.getMethodParameterFlags(j, k);
     320             :                         InterfaceTypeEntity::Method::Parameter::Direction dir;
     321           0 :                         switch (mode) {
     322             :                         case RT_PARAM_IN:
     323           0 :                             dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN;
     324           0 :                             break;
     325             :                         case RT_PARAM_OUT:
     326           0 :                             dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT;
     327           0 :                             break;
     328             :                         case RT_PARAM_INOUT:
     329           0 :                             dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT;
     330           0 :                             break;
     331             :                         default:
     332             :                             throw FileFormatException(
     333             :                                 key.getRegistryName(),
     334             :                                 ("legacy format: unexpected mode "
     335           0 :                                  + OUString::number(mode) + " of parameter "
     336           0 :                                  + reader.getMethodParameterName(j, k)
     337           0 :                                  + " of method " + reader.getMethodName(j)
     338           0 :                                  + " in interface type with key "
     339           0 :                                  + sub.getName()));
     340             :                         }
     341             :                         params.push_back(
     342             :                             InterfaceTypeEntity::Method::Parameter(
     343             :                                 reader.getMethodParameterName(j, k),
     344             :                                 (reader.getMethodParameterTypeName(j, k).
     345             :                                  replace('/', '.')),
     346           0 :                                 dir));
     347             :                     }
     348           0 :                     std::vector< OUString > excs;
     349           0 :                     m = reader.getMethodExceptionCount(j);
     350             :                     // coverity[tainted_data] cid#1213376 unhelpfully warns
     351             :                     // about an untrusted loop bound here:
     352           0 :                     for (sal_uInt16 k = 0; k != m; ++k) {
     353             :                         excs.push_back(
     354             :                             reader.getMethodExceptionTypeName(j, k).replace(
     355           0 :                                 '/', '.'));
     356             :                     }
     357             :                     meths.push_back(
     358             :                         InterfaceTypeEntity::Method(
     359             :                             reader.getMethodName(j),
     360             :                             reader.getMethodReturnTypeName(j).replace('/', '.'),
     361             :                             params, excs,
     362             :                             translateAnnotations(
     363           0 :                                 reader.getMethodDocumentation(j))));
     364             :                 }
     365             :             }
     366             :             return new InterfaceTypeEntity(
     367           0 :                 reader.isPublished(), mandBases, optBases, attrs, meths,
     368           0 :                 translateAnnotations(reader.getDocumentation()));
     369             :         }
     370             :     case RT_TYPE_MODULE:
     371           0 :         return new Module(manager, ucr, sub);
     372             :     case RT_TYPE_STRUCT:
     373             :         {
     374           0 :             sal_uInt32 n = reader.getReferenceCount();
     375           0 :             if (n == 0) {
     376           0 :                 OUString base;
     377           0 :                 switch (reader.getSuperTypeCount()) {
     378             :                 case 0:
     379           0 :                     break;
     380             :                 case 1:
     381           0 :                     base = reader.getSuperTypeName(0).replace('/', '.');
     382           0 :                     break;
     383             :                 default:
     384             :                     FileFormatException(
     385             :                         key.getRegistryName(),
     386             :                         ("legacy format: unexpected number "
     387           0 :                          + OUString::number(reader.getSuperTypeCount())
     388           0 :                          + " of super-types of plain struct type with key "
     389           0 :                          + sub.getName()));
     390             :                 }
     391           0 :                 std::vector< PlainStructTypeEntity::Member > mems;
     392           0 :                 n = reader.getFieldCount();
     393           0 :                 for (sal_uInt32 j = 0; j != n; ++j) {
     394             :                     mems.push_back(
     395             :                         PlainStructTypeEntity::Member(
     396             :                             reader.getFieldName(j),
     397             :                             reader.getFieldTypeName(j).replace('/', '.'),
     398             :                             translateAnnotations(
     399           0 :                                 reader.getFieldDocumentation(j))));
     400             :                 }
     401             :                 return new PlainStructTypeEntity(
     402           0 :                     reader.isPublished(), base, mems,
     403           0 :                     translateAnnotations(reader.getDocumentation()));
     404             :             } else {
     405           0 :                 if (reader.getSuperTypeCount() != 0) {
     406             :                     FileFormatException(
     407             :                         key.getRegistryName(),
     408             :                         ("legacy format: unexpected number "
     409           0 :                          + OUString::number(reader.getSuperTypeCount())
     410           0 :                          + " of super-types of polymorphic struct type template"
     411           0 :                          " with key " + sub.getName()));
     412             :                 }
     413           0 :                 std::vector< OUString > params;
     414           0 :                 for (sal_uInt32 j = 0; j != n; ++j) {
     415             :                     params.push_back(
     416           0 :                         reader.getReferenceTypeName(j).replace('/', '.'));
     417             :                 }
     418           0 :                 std::vector< PolymorphicStructTypeTemplateEntity::Member > mems;
     419           0 :                 n = reader.getFieldCount();
     420           0 :                 for (sal_uInt32 j = 0; j != n; ++j) {
     421             :                     mems.push_back(
     422             :                         PolymorphicStructTypeTemplateEntity::Member(
     423             :                             reader.getFieldName(j),
     424             :                             reader.getFieldTypeName(j).replace('/', '.'),
     425             :                             bool(reader.getFieldFlags(j)
     426           0 :                                  & RTFieldAccess::PARAMETERIZED_TYPE),
     427             :                             translateAnnotations(
     428           0 :                                 reader.getFieldDocumentation(j))));
     429             :                 }
     430             :                 return new PolymorphicStructTypeTemplateEntity(
     431           0 :                     reader.isPublished(), params, mems,
     432           0 :                     translateAnnotations(reader.getDocumentation()));
     433             :             }
     434             :         }
     435             :     case RT_TYPE_ENUM:
     436             :         {
     437           0 :             std::vector< EnumTypeEntity::Member > mems;
     438           0 :             sal_uInt16 n = reader.getFieldCount();
     439           0 :             for (sal_uInt16 j = 0; j != n; ++j) {
     440           0 :                 RTConstValue v(reader.getFieldValue(j));
     441           0 :                 if (v.m_type != RT_TYPE_INT32) {
     442             :                     FileFormatException(
     443             :                         key.getRegistryName(),
     444             :                         ("legacy format: unexpected type "
     445           0 :                          + OUString::number(v.m_type) + " of value of field "
     446           0 :                          + reader.getFieldName(j) + " of enum type with key "
     447           0 :                          + sub.getName()));
     448             :                 }
     449             :                 mems.push_back(
     450             :                     EnumTypeEntity::Member(
     451             :                         reader.getFieldName(j), v.m_value.aLong,
     452           0 :                         translateAnnotations(reader.getFieldDocumentation(j))));
     453             : 
     454           0 :             }
     455             :             return new EnumTypeEntity(
     456           0 :                 reader.isPublished(), mems,
     457           0 :                 translateAnnotations(reader.getDocumentation()));
     458             :         }
     459             :     case RT_TYPE_EXCEPTION:
     460             :         {
     461           0 :             OUString base;
     462           0 :             switch (reader.getSuperTypeCount()) {
     463             :             case 0:
     464           0 :                 break;
     465             :             case 1:
     466           0 :                 base = reader.getSuperTypeName(0).replace('/', '.');
     467           0 :                 break;
     468             :             default:
     469             :                 throw FileFormatException(
     470             :                     key.getRegistryName(),
     471             :                     ("legacy format: unexpected number "
     472           0 :                      + OUString::number(reader.getSuperTypeCount())
     473           0 :                      + " of super-types of exception type with key "
     474           0 :                      + sub.getName()));
     475             :             }
     476           0 :             std::vector< ExceptionTypeEntity::Member > mems;
     477           0 :             sal_uInt16 n = reader.getFieldCount();
     478           0 :             for (sal_uInt16 j = 0; j != n; ++j) {
     479             :                 mems.push_back(
     480             :                     ExceptionTypeEntity::Member(
     481             :                         reader.getFieldName(j),
     482             :                         reader.getFieldTypeName(j).replace('/', '.'),
     483           0 :                         translateAnnotations(reader.getFieldDocumentation(j))));
     484             :             }
     485             :             return new ExceptionTypeEntity(
     486           0 :                 reader.isPublished(), base, mems,
     487           0 :                 translateAnnotations(reader.getDocumentation()));
     488             :         }
     489             :     case RT_TYPE_TYPEDEF:
     490           0 :         if (reader.getSuperTypeCount() != 1) {
     491             :             throw FileFormatException(
     492             :                 key.getRegistryName(),
     493             :                 ("legacy format: unexpected number "
     494           0 :                  + OUString::number(reader.getSuperTypeCount())
     495           0 :                  + " of super-types of typedef with key " + sub.getName()));
     496             :         }
     497             :         return new TypedefEntity(
     498           0 :             reader.isPublished(), reader.getSuperTypeName(0).replace('/', '.'),
     499           0 :             translateAnnotations(reader.getDocumentation()));
     500             :     case RT_TYPE_SERVICE:
     501           0 :         switch (reader.getSuperTypeCount()) {
     502             :         case 0:
     503             :             {
     504           0 :                 std::vector< AnnotatedReference > mandServs;
     505           0 :                 std::vector< AnnotatedReference > optServs;
     506           0 :                 std::vector< AnnotatedReference > mandIfcs;
     507           0 :                 std::vector< AnnotatedReference > optIfcs;
     508           0 :                 sal_uInt16 n = reader.getReferenceCount();
     509           0 :                 for (sal_uInt16 j = 0; j != n; ++j) {
     510             :                     AnnotatedReference base(
     511             :                         reader.getReferenceTypeName(j).replace('/', '.'),
     512             :                         translateAnnotations(
     513           0 :                             reader.getReferenceDocumentation(j)));
     514           0 :                     switch (reader.getReferenceSort(j)) {
     515             :                     case RTReferenceType::EXPORTS:
     516           0 :                         if (!(reader.getReferenceFlags(j) & RTFieldAccess::OPTIONAL))
     517             :                         {
     518           0 :                             mandServs.push_back(base);
     519             :                         } else {
     520           0 :                             optServs.push_back(base);
     521             :                         }
     522           0 :                         break;
     523             :                     case RTReferenceType::SUPPORTS:
     524           0 :                         if (!(reader.getReferenceFlags(j) & RTFieldAccess::OPTIONAL))
     525             :                         {
     526           0 :                             mandIfcs.push_back(base);
     527             :                         } else {
     528           0 :                             optIfcs.push_back(base);
     529             :                         }
     530           0 :                         break;
     531             :                     default:
     532             :                         throw FileFormatException(
     533             :                             key.getRegistryName(),
     534             :                             ("legacy format: unexpected mode "
     535           0 :                              + OUString::number(static_cast<int>(reader.getReferenceSort(j)))
     536           0 :                              + " of reference " + reader.getReferenceTypeName(j)
     537           0 :                              + " in service with key " + sub.getName()));
     538             :                     }
     539           0 :                 }
     540           0 :                 std::vector< AccumulationBasedServiceEntity::Property > props;
     541           0 :                 n = reader.getFieldCount();
     542           0 :                 for (sal_uInt16 j = 0; j != n; ++j) {
     543           0 :                     RTFieldAccess acc = reader.getFieldFlags(j);
     544           0 :                     int attrs = 0;
     545           0 :                     if (acc & RTFieldAccess::READONLY) {
     546             :                         attrs |= AccumulationBasedServiceEntity::Property::
     547           0 :                             ATTRIBUTE_READ_ONLY;
     548             :                     }
     549           0 :                     if (acc & RTFieldAccess::OPTIONAL) {
     550             :                         attrs |= AccumulationBasedServiceEntity::Property::
     551           0 :                             ATTRIBUTE_OPTIONAL;
     552             :                     }
     553           0 :                     if (acc & RTFieldAccess::MAYBEVOID) {
     554             :                         attrs |= AccumulationBasedServiceEntity::Property::
     555           0 :                             ATTRIBUTE_MAYBE_VOID;
     556             :                     }
     557           0 :                     if (acc & RTFieldAccess::BOUND) {
     558             :                         attrs |= AccumulationBasedServiceEntity::Property::
     559           0 :                             ATTRIBUTE_BOUND;
     560             :                     }
     561           0 :                     if (acc & RTFieldAccess::CONSTRAINED) {
     562             :                         attrs |= AccumulationBasedServiceEntity::Property::
     563           0 :                             ATTRIBUTE_CONSTRAINED;
     564             :                     }
     565           0 :                     if (acc & RTFieldAccess::TRANSIENT) {
     566             :                         attrs |= AccumulationBasedServiceEntity::Property::
     567           0 :                             ATTRIBUTE_TRANSIENT;
     568             :                     }
     569           0 :                     if (acc & RTFieldAccess::MAYBEAMBIGUOUS) {
     570             :                         attrs |= AccumulationBasedServiceEntity::Property::
     571           0 :                             ATTRIBUTE_MAYBE_AMBIGUOUS;
     572             :                     }
     573           0 :                     if (acc & RTFieldAccess::MAYBEDEFAULT) {
     574             :                         attrs |= AccumulationBasedServiceEntity::Property::
     575           0 :                             ATTRIBUTE_MAYBE_DEFAULT;
     576             :                     }
     577           0 :                     if (acc & RTFieldAccess::REMOVABLE) {
     578             :                         attrs |= AccumulationBasedServiceEntity::Property::
     579           0 :                             ATTRIBUTE_REMOVABLE;
     580             :                     }
     581             :                     props.push_back(
     582             :                         AccumulationBasedServiceEntity::Property(
     583             :                             reader.getFieldName(j),
     584             :                             reader.getFieldTypeName(j).replace('/', '.'),
     585             :                             static_cast<
     586             :                                 AccumulationBasedServiceEntity::Property::
     587             :                                 Attributes >(attrs),
     588             :                             translateAnnotations(
     589           0 :                                 reader.getFieldDocumentation(j))));
     590             :                 }
     591             :                 return new AccumulationBasedServiceEntity(
     592           0 :                     reader.isPublished(), mandServs, optServs, mandIfcs,
     593             :                     optIfcs, props,
     594           0 :                     translateAnnotations(reader.getDocumentation()));
     595             :             }
     596             :         case 1:
     597             :             {
     598             :                 std::vector< SingleInterfaceBasedServiceEntity::Constructor >
     599           0 :                     ctors;
     600           0 :                 sal_uInt16 n = reader.getMethodCount();
     601           0 :                 if (n == 1 && reader.getMethodFlags(0) == RTMethodMode::TWOWAY
     602           0 :                     && reader.getMethodName(0).isEmpty()
     603           0 :                     && reader.getMethodReturnTypeName(0) == "void"
     604           0 :                     && reader.getMethodParameterCount(0) == 0
     605           0 :                     && reader.getMethodExceptionCount(0) == 0)
     606             :                 {
     607             :                     ctors.push_back(
     608           0 :                         SingleInterfaceBasedServiceEntity::Constructor());
     609             :                 } else {
     610           0 :                     for (sal_uInt16 j = 0; j != n; ++j) {
     611           0 :                         if (reader.getMethodFlags(j) != RTMethodMode::TWOWAY) {
     612             :                             throw FileFormatException(
     613             :                                 key.getRegistryName(),
     614             :                                 ("legacy format: unexpected mode "
     615           0 :                                  + OUString::number(static_cast<int>(reader.getMethodFlags(j)))
     616           0 :                                  + " of constructor " + reader.getMethodName(j)
     617           0 :                                  + " in service with key " + sub.getName()));
     618             :                         }
     619             :                         std::vector<
     620             :                             SingleInterfaceBasedServiceEntity::Constructor::
     621           0 :                             Parameter > params;
     622           0 :                         sal_uInt16 m = reader.getMethodParameterCount(j);
     623             :                         // coverity[tainted_data] cid#1213376 unhelpfully warns
     624             :                         // about an untrusted loop bound here:
     625           0 :                         for (sal_uInt16 k = 0; k != m; ++k) {
     626             :                             RTParamMode mode
     627           0 :                                 = reader.getMethodParameterFlags(j, k);
     628           0 :                             if ((mode & ~RT_PARAM_REST) != RT_PARAM_IN) {
     629             :                                 throw FileFormatException(
     630             :                                     key.getRegistryName(),
     631             :                                     ("legacy format: unexpected mode "
     632           0 :                                      + OUString::number(mode)
     633           0 :                                      + " of parameter "
     634           0 :                                      + reader.getMethodParameterName(j, k)
     635           0 :                                      + " of constructor "
     636           0 :                                      + reader.getMethodName(j)
     637           0 :                                      + " in service with key "
     638           0 :                                      + sub.getName()));
     639             :                             }
     640           0 :                             if ((mode & RT_PARAM_REST) != 0
     641           0 :                                 && !(m == 1
     642             :                                      && ((reader.getMethodParameterTypeName(
     643             :                                               j, 0))
     644           0 :                                          == "any")))
     645             :                             {
     646             :                                 throw FileFormatException(
     647             :                                     key.getRegistryName(),
     648             :                                     ("legacy format: bad rest parameter "
     649           0 :                                      + reader.getMethodParameterName(j, k)
     650           0 :                                      + " of constructor "
     651           0 :                                      + reader.getMethodName(j)
     652           0 :                                      + " in service with key "
     653           0 :                                      + sub.getName()));
     654             :                             }
     655             :                             params.push_back(
     656             :                                 SingleInterfaceBasedServiceEntity::Constructor::
     657             :                                 Parameter(
     658             :                                     reader.getMethodParameterName(j, k),
     659             :                                     (reader.getMethodParameterTypeName(j, k).
     660             :                                      replace('/', '.')),
     661           0 :                                     (mode & RT_PARAM_REST) != 0));
     662             :                         }
     663           0 :                         std::vector< OUString > excs;
     664           0 :                         m = reader.getMethodExceptionCount(j);
     665             :                         // coverity[tainted_data] cid#1213376 unhelpfully warns
     666             :                         // about an untrusted loop bound here:
     667           0 :                         for (sal_uInt16 k = 0; k != m; ++k) {
     668             :                             excs.push_back(
     669             :                                 reader.getMethodExceptionTypeName(j, k).replace(
     670           0 :                                     '/', '.'));
     671             :                         }
     672             :                         ctors.push_back(
     673             :                             SingleInterfaceBasedServiceEntity::Constructor(
     674             :                                 reader.getMethodName(j), params, excs,
     675             :                                 translateAnnotations(
     676           0 :                                     reader.getMethodDocumentation(j))));
     677           0 :                     }
     678             :                 }
     679             :                 return new SingleInterfaceBasedServiceEntity(
     680           0 :                     reader.isPublished(),
     681             :                     reader.getSuperTypeName(0).replace('/', '.'), ctors,
     682           0 :                     translateAnnotations(reader.getDocumentation()));
     683             :             }
     684             :         default:
     685             :             throw FileFormatException(
     686             :                 key.getRegistryName(),
     687             :                 ("legacy format: unexpected number "
     688           0 :                  + OUString::number(reader.getSuperTypeCount())
     689           0 :                  + " of super-types of service with key " + sub.getName()));
     690             :         }
     691             :     case RT_TYPE_SINGLETON:
     692             :         {
     693           0 :             if (reader.getSuperTypeCount() != 1) {
     694             :                 throw FileFormatException(
     695             :                     key.getRegistryName(),
     696             :                     ("legacy format: unexpected number "
     697           0 :                      + OUString::number(reader.getSuperTypeCount())
     698           0 :                      + " of super-types of singleton with key "
     699           0 :                      + sub.getName()));
     700             :             }
     701           0 :             OUString basePath(reader.getSuperTypeName(0));
     702           0 :             OUString baseName(basePath.replace('/', '.'));
     703             :             bool newStyle;
     704           0 :             rtl::Reference< Entity > base(manager->findEntity(baseName));
     705           0 :             if (base.is()) {
     706           0 :                 switch (base->getSort()) {
     707             :                 case Entity::SORT_INTERFACE_TYPE:
     708           0 :                     newStyle = true;
     709           0 :                     break;
     710             :                 case Entity::SORT_ACCUMULATION_BASED_SERVICE:
     711           0 :                     newStyle = false;
     712           0 :                     break;
     713             :                 default:
     714             :                     throw FileFormatException(
     715             :                         key.getRegistryName(),
     716             :                         ("legacy format: unexpected sort "
     717           0 :                          + OUString::number(base->getSort()) + " of base "
     718           0 :                          + baseName + " of singleton with key "
     719           0 :                          + sub.getName()));
     720             :                 }
     721             :             } else {
     722           0 :                 RegistryKey key2;
     723           0 :                 e = ucr.openKey(basePath, key2);
     724           0 :                 switch (e) {
     725             :                 case RegError::NO_ERROR:
     726           0 :                     break;
     727             :                 case RegError::KEY_NOT_EXISTS:
     728             :                     throw FileFormatException(
     729             :                         key.getRegistryName(),
     730           0 :                         ("legacy format: unknown super-type " + basePath
     731           0 :                          + " of super-type with key " + sub.getName()));
     732             :                 default:
     733             :                     throw FileFormatException(
     734             :                         key.getRegistryName(),
     735           0 :                         ("legacy format: cannot open ucr sub-key " + basePath
     736           0 :                          + ": " + OUString::number(static_cast<int>(e))));
     737             :                 }
     738           0 :                 std::vector< char > buf2;
     739           0 :                 typereg::Reader reader2(getReader(key2, &buf2));
     740           0 :                 switch (reader2.getTypeClass()) {
     741             :                 case RT_TYPE_INTERFACE:
     742           0 :                     newStyle = true;
     743           0 :                     break;
     744             :                 case RT_TYPE_SERVICE:
     745           0 :                     newStyle = false;
     746           0 :                     break;
     747             :                 default:
     748             :                     throw FileFormatException(
     749             :                         key.getRegistryName(),
     750             :                         ("legacy format: unexpected type class "
     751           0 :                          + OUString::number(reader2.getTypeClass())
     752           0 :                          + " of super-type with key " + key2.getName()
     753           0 :                          + " of singleton with key " + sub.getName()));
     754           0 :                 }
     755             :             }
     756             :             return newStyle
     757             :                 ? rtl::Reference< Entity >(
     758             :                     new InterfaceBasedSingletonEntity(
     759           0 :                         reader.isPublished(), baseName,
     760           0 :                         translateAnnotations(reader.getDocumentation())))
     761             :                 : rtl::Reference< Entity >(
     762             :                     new ServiceBasedSingletonEntity(
     763           0 :                         reader.isPublished(), baseName,
     764           0 :                         translateAnnotations(reader.getDocumentation())));
     765             :         }
     766             :     case RT_TYPE_CONSTANTS:
     767             :         {
     768           0 :             std::vector< ConstantGroupEntity::Member > mems;
     769           0 :             sal_uInt16 n = reader.getFieldCount();
     770           0 :             for (sal_uInt16 j = 0; j != n; ++j) {
     771             :                 mems.push_back(
     772             :                     ConstantGroupEntity::Member(
     773             :                         reader.getFieldName(j),
     774           0 :                         translateConstantValue(sub, reader.getFieldValue(j)),
     775           0 :                         translateAnnotations(reader.getFieldDocumentation(j))));
     776             :             }
     777             :             return new ConstantGroupEntity(
     778           0 :                 reader.isPublished(), mems,
     779           0 :                 translateAnnotations(reader.getDocumentation()));
     780             :         }
     781             :     default:
     782             :         throw FileFormatException(
     783             :             key.getRegistryName(),
     784             :             ("legacy format: unexpected type class "
     785           0 :              + OUString::number(reader.getTypeClass()) + " of key "
     786           0 :              + sub.getName()));
     787           0 :     }
     788             : }
     789             : 
     790             : }
     791             : 
     792           0 : LegacyProvider::LegacyProvider(Manager & manager, OUString const & uri):
     793           0 :     manager_(manager)
     794             : {
     795           0 :     Registry reg;
     796           0 :     RegError e = reg.open(uri, RegAccessMode::READONLY);
     797           0 :     switch (e) {
     798             :     case RegError::NO_ERROR:
     799           0 :         break;
     800             :     case RegError::REGISTRY_NOT_EXISTS:
     801           0 :         throw NoSuchFileException(uri);
     802             :     default:
     803             :         throw FileFormatException(
     804           0 :             uri, "cannot open legacy file: " + OUString::number(static_cast<int>(e)));
     805             :     }
     806           0 :     RegistryKey root;
     807           0 :     e = reg.openRootKey(root);
     808           0 :     if (e != RegError::NO_ERROR) {
     809             :         throw FileFormatException(
     810           0 :             uri, "legacy format: cannot open root key: " + OUString::number(static_cast<int>(e)));
     811             :     }
     812           0 :     e = root.openKey("UCR", ucr_);
     813           0 :     switch (e) {
     814             :     case RegError::NO_ERROR:
     815             :     case RegError::KEY_NOT_EXISTS: // such effectively empty files exist in the wild
     816           0 :         break;
     817             :     default:
     818             :         throw FileFormatException(
     819           0 :             uri, "legacy format: cannot open UCR key: " + OUString::number(static_cast<int>(e)));
     820           0 :     }
     821           0 : }
     822             : 
     823           0 : rtl::Reference< MapCursor > LegacyProvider::createRootCursor() const {
     824           0 :     return new Cursor(&manager_, ucr_, ucr_);
     825             : }
     826             : 
     827           0 : rtl::Reference< Entity > LegacyProvider::findEntity(OUString const & name)
     828             :     const
     829             : {
     830           0 :     return ucr_.isValid()
     831             :         ? readEntity(&manager_, ucr_, ucr_, name.replace('.', '/'), true)
     832           0 :         : rtl::Reference< Entity >();
     833             : }
     834             : 
     835           0 : LegacyProvider::~LegacyProvider() throw () {}
     836             : 
     837             : } }
     838             : 
     839             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11