LCOV - code coverage report
Current view: top level - unoidl/source - legacyprovider.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 0 378 0.0 %
Date: 2014-11-03 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 != REG_NO_ERROR) {
     107             :             throw FileFormatException(
     108             :                 key_.getRegistryName(),
     109           0 :                 ("legacy format: cannot get sub-key names of " + key_.getName()
     110           0 :                  + ": " + OUString::number(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 != REG_NO_ERROR) {
     154             :         throw FileFormatException(
     155             :             key_.getRegistryName(),
     156           0 :             ("legacy format: cannot get sub-key names of " + key_.getName()
     157           0 :              + ": " + OUString::number(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 != REG_NO_ERROR) {
     172             :         throw FileFormatException(
     173             :             key.getRegistryName(),
     174           0 :             ("legacy format: cannot get value info about key " + key.getName()
     175           0 :              + ": " + OUString::number(e)));
     176             :     }
     177           0 :     if (type != RG_VALUETYPE_BINARY) {
     178             :         throw FileFormatException(
     179             :             key.getRegistryName(),
     180           0 :             ("legacy format: unexpected value type " + OUString::number(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 != REG_NO_ERROR) {
     194             :         throw FileFormatException(
     195             :             key.getRegistryName(),
     196           0 :             ("legacy format: cannot get binary value of key " + key.getName()
     197           0 :              + ": " + OUString::number(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 REG_NO_ERROR:
     217           0 :         break;
     218             :     case REG_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(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 RT_MODE_ATTRIBUTE_GET:
     262             :                             {
     263             :                                 sal_uInt16 m
     264           0 :                                     = reader.getMethodExceptionCount(k);
     265           0 :                                 for (sal_uInt16 l = 0; l != m; ++l) {
     266             :                                     getExcs.push_back(
     267             :                                         reader.getMethodExceptionTypeName(k, l).
     268           0 :                                         replace('/', '.'));
     269             :                                 }
     270           0 :                                 break;
     271             :                             }
     272             :                         case RT_MODE_ATTRIBUTE_SET:
     273             :                             {
     274             :                                 sal_uInt16 m
     275           0 :                                     = reader.getMethodExceptionCount(k);
     276           0 :                                 for (sal_uInt16 l = 0; l != m; ++l) {
     277             :                                     setExcs.push_back(
     278             :                                         reader.getMethodExceptionTypeName(k, l).
     279           0 :                                         replace('/', '.'));
     280             :                                 }
     281           0 :                                 break;
     282             :                             }
     283             :                         default:
     284             :                             throw FileFormatException(
     285             :                                 key.getRegistryName(),
     286             :                                 ("legacy format: method and attribute with same"
     287           0 :                                  " name " + attrName
     288           0 :                                  + " in interface type with key "
     289           0 :                                  + sub.getName()));
     290             :                         }
     291             :                     }
     292             :                 }
     293           0 :                 RTFieldAccess flags = reader.getFieldFlags(j);
     294             :                 attrs.push_back(
     295             :                     InterfaceTypeEntity::Attribute(
     296             :                         attrName, reader.getFieldTypeName(j).replace('/', '.'),
     297           0 :                         (flags & RT_ACCESS_BOUND) != 0,
     298           0 :                         (flags & RT_ACCESS_READONLY) != 0, getExcs, setExcs,
     299           0 :                         translateAnnotations(reader.getFieldDocumentation(j))));
     300           0 :             }
     301           0 :             std::vector< InterfaceTypeEntity::Method > meths;
     302           0 :             for (sal_uInt16 j = 0; j != methodCount; ++j) {
     303           0 :                 RTMethodMode flags = reader.getMethodFlags(j);
     304           0 :                 if (flags != RT_MODE_ATTRIBUTE_GET
     305           0 :                     && flags != RT_MODE_ATTRIBUTE_SET)
     306             :                 {
     307             :                     std::vector< InterfaceTypeEntity::Method::Parameter >
     308           0 :                         params;
     309           0 :                     sal_uInt16 m = reader.getMethodParameterCount(j);
     310           0 :                     for (sal_uInt16 k = 0; k != m; ++k) {
     311           0 :                         RTParamMode mode = reader.getMethodParameterFlags(j, k);
     312             :                         InterfaceTypeEntity::Method::Parameter::Direction dir;
     313           0 :                         switch (mode) {
     314             :                         case RT_PARAM_IN:
     315           0 :                             dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN;
     316           0 :                             break;
     317             :                         case RT_PARAM_OUT:
     318           0 :                             dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT;
     319           0 :                             break;
     320             :                         case RT_PARAM_INOUT:
     321           0 :                             dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT;
     322           0 :                             break;
     323             :                         default:
     324             :                             throw FileFormatException(
     325             :                                 key.getRegistryName(),
     326             :                                 ("legacy format: unexpected mode "
     327           0 :                                  + OUString::number(mode) + " of parameter "
     328           0 :                                  + reader.getMethodParameterName(j, k)
     329           0 :                                  + " of method " + reader.getMethodName(j)
     330           0 :                                  + " in interface type with key "
     331           0 :                                  + sub.getName()));
     332             :                         }
     333             :                         params.push_back(
     334             :                             InterfaceTypeEntity::Method::Parameter(
     335             :                                 reader.getMethodParameterName(j, k),
     336             :                                 (reader.getMethodParameterTypeName(j, k).
     337             :                                  replace('/', '.')),
     338           0 :                                 dir));
     339             :                     }
     340           0 :                     std::vector< OUString > excs;
     341           0 :                     m = reader.getMethodExceptionCount(j);
     342           0 :                     for (sal_uInt16 k = 0; k != m; ++k) {
     343             :                         excs.push_back(
     344             :                             reader.getMethodExceptionTypeName(j, k).replace(
     345           0 :                                 '/', '.'));
     346             :                     }
     347             :                     meths.push_back(
     348             :                         InterfaceTypeEntity::Method(
     349             :                             reader.getMethodName(j),
     350             :                             reader.getMethodReturnTypeName(j).replace('/', '.'),
     351             :                             params, excs,
     352             :                             translateAnnotations(
     353           0 :                                 reader.getMethodDocumentation(j))));
     354             :                 }
     355             :             }
     356             :             return new InterfaceTypeEntity(
     357           0 :                 reader.isPublished(), mandBases, optBases, attrs, meths,
     358           0 :                 translateAnnotations(reader.getDocumentation()));
     359             :         }
     360             :     case RT_TYPE_MODULE:
     361           0 :         return new Module(manager, ucr, sub);
     362             :     case RT_TYPE_STRUCT:
     363             :         {
     364           0 :             sal_uInt32 n = reader.getReferenceCount();
     365           0 :             if (n == 0) {
     366           0 :                 OUString base;
     367           0 :                 switch (reader.getSuperTypeCount()) {
     368             :                 case 0:
     369           0 :                     break;
     370             :                 case 1:
     371           0 :                     base = reader.getSuperTypeName(0).replace('/', '.');
     372           0 :                     break;
     373             :                 default:
     374             :                     FileFormatException(
     375             :                         key.getRegistryName(),
     376             :                         ("legacy format: unexpected number "
     377           0 :                          + OUString::number(reader.getSuperTypeCount())
     378           0 :                          + " of super-types of plain struct type with key "
     379           0 :                          + sub.getName()));
     380             :                 }
     381           0 :                 std::vector< PlainStructTypeEntity::Member > mems;
     382           0 :                 n = reader.getFieldCount();
     383           0 :                 for (sal_uInt16 j = 0; j != n; ++j) {
     384             :                     mems.push_back(
     385             :                         PlainStructTypeEntity::Member(
     386             :                             reader.getFieldName(j),
     387             :                             reader.getFieldTypeName(j).replace('/', '.'),
     388             :                             translateAnnotations(
     389           0 :                                 reader.getFieldDocumentation(j))));
     390             :                 }
     391             :                 return new PlainStructTypeEntity(
     392           0 :                     reader.isPublished(), base, mems,
     393           0 :                     translateAnnotations(reader.getDocumentation()));
     394             :             } else {
     395           0 :                 if (reader.getSuperTypeCount() != 0) {
     396             :                     FileFormatException(
     397             :                         key.getRegistryName(),
     398             :                         ("legacy format: unexpected number "
     399           0 :                          + OUString::number(reader.getSuperTypeCount())
     400           0 :                          + " of super-types of polymorphic struct type template"
     401           0 :                          " with key " + sub.getName()));
     402             :                 }
     403           0 :                 std::vector< OUString > params;
     404           0 :                 for (sal_uInt16 j = 0; j != n; ++j) {
     405             :                     params.push_back(
     406           0 :                         reader.getReferenceTypeName(j).replace('/', '.'));
     407             :                 }
     408           0 :                 std::vector< PolymorphicStructTypeTemplateEntity::Member > mems;
     409           0 :                 n = reader.getFieldCount();
     410           0 :                 for (sal_uInt16 j = 0; j != n; ++j) {
     411             :                     mems.push_back(
     412             :                         PolymorphicStructTypeTemplateEntity::Member(
     413             :                             reader.getFieldName(j),
     414             :                             reader.getFieldTypeName(j).replace('/', '.'),
     415           0 :                             ((reader.getFieldFlags(j)
     416           0 :                               & RT_ACCESS_PARAMETERIZED_TYPE)
     417             :                              != 0),
     418             :                             translateAnnotations(
     419           0 :                                 reader.getFieldDocumentation(j))));
     420             :                 }
     421             :                 return new PolymorphicStructTypeTemplateEntity(
     422           0 :                     reader.isPublished(), params, mems,
     423           0 :                     translateAnnotations(reader.getDocumentation()));
     424             :             }
     425             :         }
     426             :     case RT_TYPE_ENUM:
     427             :         {
     428           0 :             std::vector< EnumTypeEntity::Member > mems;
     429           0 :             sal_uInt16 n = reader.getFieldCount();
     430           0 :             for (sal_uInt16 j = 0; j != n; ++j) {
     431           0 :                 RTConstValue v(reader.getFieldValue(j));
     432           0 :                 if (v.m_type != RT_TYPE_INT32) {
     433             :                     FileFormatException(
     434             :                         key.getRegistryName(),
     435             :                         ("legacy format: unexpected type "
     436           0 :                          + OUString::number(v.m_type) + " of value of field "
     437           0 :                          + reader.getFieldName(j) + " of enum type with key "
     438           0 :                          + sub.getName()));
     439             :                 }
     440             :                 mems.push_back(
     441             :                     EnumTypeEntity::Member(
     442             :                         reader.getFieldName(j), v.m_value.aLong,
     443           0 :                         translateAnnotations(reader.getFieldDocumentation(j))));
     444             : 
     445           0 :             }
     446             :             return new EnumTypeEntity(
     447           0 :                 reader.isPublished(), mems,
     448           0 :                 translateAnnotations(reader.getDocumentation()));
     449             :         }
     450             :     case RT_TYPE_EXCEPTION:
     451             :         {
     452           0 :             OUString base;
     453           0 :             switch (reader.getSuperTypeCount()) {
     454             :             case 0:
     455           0 :                 break;
     456             :             case 1:
     457           0 :                 base = reader.getSuperTypeName(0).replace('/', '.');
     458           0 :                 break;
     459             :             default:
     460             :                 throw FileFormatException(
     461             :                     key.getRegistryName(),
     462             :                     ("legacy format: unexpected number "
     463           0 :                      + OUString::number(reader.getSuperTypeCount())
     464           0 :                      + " of super-types of exception type with key "
     465           0 :                      + sub.getName()));
     466             :             }
     467           0 :             std::vector< ExceptionTypeEntity::Member > mems;
     468           0 :             sal_uInt16 n = reader.getFieldCount();
     469           0 :             for (sal_uInt16 j = 0; j != n; ++j) {
     470             :                 mems.push_back(
     471             :                     ExceptionTypeEntity::Member(
     472             :                         reader.getFieldName(j),
     473             :                         reader.getFieldTypeName(j).replace('/', '.'),
     474           0 :                         translateAnnotations(reader.getFieldDocumentation(j))));
     475             :             }
     476             :             return new ExceptionTypeEntity(
     477           0 :                 reader.isPublished(), base, mems,
     478           0 :                 translateAnnotations(reader.getDocumentation()));
     479             :         }
     480             :     case RT_TYPE_TYPEDEF:
     481           0 :         if (reader.getSuperTypeCount() != 1) {
     482             :             throw FileFormatException(
     483             :                 key.getRegistryName(),
     484             :                 ("legacy format: unexpected number "
     485           0 :                  + OUString::number(reader.getSuperTypeCount())
     486           0 :                  + " of super-types of typedef with key " + sub.getName()));
     487             :         }
     488             :         return new TypedefEntity(
     489           0 :             reader.isPublished(), reader.getSuperTypeName(0).replace('/', '.'),
     490           0 :             translateAnnotations(reader.getDocumentation()));
     491             :     case RT_TYPE_SERVICE:
     492           0 :         switch (reader.getSuperTypeCount()) {
     493             :         case 0:
     494             :             {
     495           0 :                 std::vector< AnnotatedReference > mandServs;
     496           0 :                 std::vector< AnnotatedReference > optServs;
     497           0 :                 std::vector< AnnotatedReference > mandIfcs;
     498           0 :                 std::vector< AnnotatedReference > optIfcs;
     499           0 :                 sal_uInt16 n = reader.getReferenceCount();
     500           0 :                 for (sal_uInt16 j = 0; j != n; ++j) {
     501             :                     AnnotatedReference base(
     502             :                         reader.getReferenceTypeName(j).replace('/', '.'),
     503             :                         translateAnnotations(
     504           0 :                             reader.getReferenceDocumentation(j)));
     505           0 :                     switch (reader.getReferenceSort(j)) {
     506             :                     case RT_REF_EXPORTS:
     507           0 :                         if ((reader.getReferenceFlags(j) & RT_ACCESS_OPTIONAL)
     508             :                             == 0)
     509             :                         {
     510           0 :                             mandServs.push_back(base);
     511             :                         } else {
     512           0 :                             optServs.push_back(base);
     513             :                         }
     514           0 :                         break;
     515             :                     case RT_REF_SUPPORTS:
     516           0 :                         if ((reader.getReferenceFlags(j) & RT_ACCESS_OPTIONAL)
     517             :                             == 0)
     518             :                         {
     519           0 :                             mandIfcs.push_back(base);
     520             :                         } else {
     521           0 :                             optIfcs.push_back(base);
     522             :                         }
     523           0 :                         break;
     524             :                     default:
     525             :                         throw FileFormatException(
     526             :                             key.getRegistryName(),
     527             :                             ("legacy format: unexpected mode "
     528           0 :                              + OUString::number(reader.getReferenceSort(j))
     529           0 :                              + " of reference " + reader.getReferenceTypeName(j)
     530           0 :                              + " in service with key " + sub.getName()));
     531             :                     }
     532           0 :                 }
     533           0 :                 std::vector< AccumulationBasedServiceEntity::Property > props;
     534           0 :                 n = reader.getFieldCount();
     535           0 :                 for (sal_uInt16 j = 0; j != n; ++j) {
     536           0 :                     RTFieldAccess acc = reader.getFieldFlags(j);
     537           0 :                     int attrs = 0;
     538           0 :                     if ((acc & RT_ACCESS_READONLY) != 0) {
     539             :                         attrs |= AccumulationBasedServiceEntity::Property::
     540           0 :                             ATTRIBUTE_READ_ONLY;
     541             :                     }
     542           0 :                     if ((acc & RT_ACCESS_OPTIONAL) != 0) {
     543             :                         attrs |= AccumulationBasedServiceEntity::Property::
     544           0 :                             ATTRIBUTE_OPTIONAL;
     545             :                     }
     546           0 :                     if ((acc & RT_ACCESS_MAYBEVOID) != 0) {
     547             :                         attrs |= AccumulationBasedServiceEntity::Property::
     548           0 :                             ATTRIBUTE_MAYBE_VOID;
     549             :                     }
     550           0 :                     if ((acc & RT_ACCESS_BOUND) != 0) {
     551             :                         attrs |= AccumulationBasedServiceEntity::Property::
     552           0 :                             ATTRIBUTE_BOUND;
     553             :                     }
     554           0 :                     if ((acc & RT_ACCESS_CONSTRAINED) != 0) {
     555             :                         attrs |= AccumulationBasedServiceEntity::Property::
     556           0 :                             ATTRIBUTE_CONSTRAINED;
     557             :                     }
     558           0 :                     if ((acc & RT_ACCESS_TRANSIENT) != 0) {
     559             :                         attrs |= AccumulationBasedServiceEntity::Property::
     560           0 :                             ATTRIBUTE_TRANSIENT;
     561             :                     }
     562           0 :                     if ((acc & RT_ACCESS_MAYBEAMBIGUOUS) != 0) {
     563             :                         attrs |= AccumulationBasedServiceEntity::Property::
     564           0 :                             ATTRIBUTE_MAYBE_AMBIGUOUS;
     565             :                     }
     566           0 :                     if ((acc & RT_ACCESS_MAYBEDEFAULT) != 0) {
     567             :                         attrs |= AccumulationBasedServiceEntity::Property::
     568           0 :                             ATTRIBUTE_MAYBE_DEFAULT;
     569             :                     }
     570           0 :                     if ((acc & RT_ACCESS_REMOVABLE) != 0) {
     571             :                         attrs |= AccumulationBasedServiceEntity::Property::
     572           0 :                             ATTRIBUTE_REMOVABLE;
     573             :                     }
     574             :                     props.push_back(
     575             :                         AccumulationBasedServiceEntity::Property(
     576             :                             reader.getFieldName(j),
     577             :                             reader.getFieldTypeName(j).replace('/', '.'),
     578             :                             static_cast<
     579             :                                 AccumulationBasedServiceEntity::Property::
     580             :                                 Attributes >(attrs),
     581             :                             translateAnnotations(
     582           0 :                                 reader.getFieldDocumentation(j))));
     583             :                 }
     584             :                 return new AccumulationBasedServiceEntity(
     585           0 :                     reader.isPublished(), mandServs, optServs, mandIfcs,
     586             :                     optIfcs, props,
     587           0 :                     translateAnnotations(reader.getDocumentation()));
     588             :             }
     589             :         case 1:
     590             :             {
     591             :                 std::vector< SingleInterfaceBasedServiceEntity::Constructor >
     592           0 :                     ctors;
     593           0 :                 sal_uInt16 n = reader.getMethodCount();
     594           0 :                 if (n == 1 && reader.getMethodFlags(0) == RT_MODE_TWOWAY
     595           0 :                     && reader.getMethodName(0).isEmpty()
     596           0 :                     && reader.getMethodReturnTypeName(0) == "void"
     597           0 :                     && reader.getMethodParameterCount(0) == 0
     598           0 :                     && reader.getMethodExceptionCount(0) == 0)
     599             :                 {
     600             :                     ctors.push_back(
     601           0 :                         SingleInterfaceBasedServiceEntity::Constructor());
     602             :                 } else {
     603           0 :                     for (sal_uInt16 j = 0; j != n; ++j) {
     604           0 :                         if (reader.getMethodFlags(j) != RT_MODE_TWOWAY) {
     605             :                             throw FileFormatException(
     606             :                                 key.getRegistryName(),
     607             :                                 ("legacy format: unexpected mode "
     608           0 :                                  + OUString::number(reader.getMethodFlags(j))
     609           0 :                                  + " of constructor " + reader.getMethodName(j)
     610           0 :                                  + " in service with key " + sub.getName()));
     611             :                         }
     612             :                         std::vector<
     613             :                             SingleInterfaceBasedServiceEntity::Constructor::
     614           0 :                             Parameter > params;
     615           0 :                         sal_uInt16 m = reader.getMethodParameterCount(j);
     616           0 :                         for (sal_uInt16 k = 0; k != m; ++k) {
     617             :                             RTParamMode mode
     618           0 :                                 = reader.getMethodParameterFlags(j, k);
     619           0 :                             if ((mode & ~RT_PARAM_REST) != RT_PARAM_IN) {
     620             :                                 throw FileFormatException(
     621             :                                     key.getRegistryName(),
     622             :                                     ("legacy format: unexpected mode "
     623           0 :                                      + OUString::number(mode)
     624           0 :                                      + " of parameter "
     625           0 :                                      + reader.getMethodParameterName(j, k)
     626           0 :                                      + " of constructor "
     627           0 :                                      + reader.getMethodName(j)
     628           0 :                                      + " in service with key "
     629           0 :                                      + sub.getName()));
     630             :                             }
     631           0 :                             if ((mode & RT_PARAM_REST) != 0
     632           0 :                                 && !(m == 1
     633             :                                      && ((reader.getMethodParameterTypeName(
     634             :                                               j, 0))
     635           0 :                                          == "any")))
     636             :                             {
     637             :                                 throw FileFormatException(
     638             :                                     key.getRegistryName(),
     639             :                                     ("legacy format: bad rest parameter "
     640           0 :                                      + reader.getMethodParameterName(j, k)
     641           0 :                                      + " of constructor "
     642           0 :                                      + reader.getMethodName(j)
     643           0 :                                      + " in service with key "
     644           0 :                                      + sub.getName()));
     645             :                             }
     646             :                             params.push_back(
     647             :                                 SingleInterfaceBasedServiceEntity::Constructor::
     648             :                                 Parameter(
     649             :                                     reader.getMethodParameterName(j, k),
     650             :                                     (reader.getMethodParameterTypeName(j, k).
     651             :                                      replace('/', '.')),
     652           0 :                                     (mode & RT_PARAM_REST) != 0));
     653             :                         }
     654           0 :                         std::vector< OUString > excs;
     655           0 :                         m = reader.getMethodExceptionCount(j);
     656           0 :                         for (sal_uInt16 k = 0; k != m; ++k) {
     657             :                             excs.push_back(
     658             :                                 reader.getMethodExceptionTypeName(j, k).replace(
     659           0 :                                     '/', '.'));
     660             :                         }
     661             :                         ctors.push_back(
     662             :                             SingleInterfaceBasedServiceEntity::Constructor(
     663             :                                 reader.getMethodName(j), params, excs,
     664             :                                 translateAnnotations(
     665           0 :                                     reader.getMethodDocumentation(j))));
     666           0 :                     }
     667             :                 }
     668             :                 return new SingleInterfaceBasedServiceEntity(
     669           0 :                     reader.isPublished(),
     670             :                     reader.getSuperTypeName(0).replace('/', '.'), ctors,
     671           0 :                     translateAnnotations(reader.getDocumentation()));
     672             :             }
     673             :         default:
     674             :             throw FileFormatException(
     675             :                 key.getRegistryName(),
     676             :                 ("legacy format: unexpected number "
     677           0 :                  + OUString::number(reader.getSuperTypeCount())
     678           0 :                  + " of super-types of service with key " + sub.getName()));
     679             :         }
     680             :     case RT_TYPE_SINGLETON:
     681             :         {
     682           0 :             if (reader.getSuperTypeCount() != 1) {
     683             :                 throw FileFormatException(
     684             :                     key.getRegistryName(),
     685             :                     ("legacy format: unexpected number "
     686           0 :                      + OUString::number(reader.getSuperTypeCount())
     687           0 :                      + " of super-types of singleton with key "
     688           0 :                      + sub.getName()));
     689             :             }
     690           0 :             OUString basePath(reader.getSuperTypeName(0));
     691           0 :             OUString baseName(basePath.replace('/', '.'));
     692             :             bool newStyle;
     693           0 :             rtl::Reference< Entity > base(manager->findEntity(baseName));
     694           0 :             if (base.is()) {
     695           0 :                 switch (base->getSort()) {
     696             :                 case Entity::SORT_INTERFACE_TYPE:
     697           0 :                     newStyle = true;
     698           0 :                     break;
     699             :                 case Entity::SORT_ACCUMULATION_BASED_SERVICE:
     700           0 :                     newStyle = false;
     701           0 :                     break;
     702             :                 default:
     703             :                     throw FileFormatException(
     704             :                         key.getRegistryName(),
     705             :                         ("legacy format: unexpected sort "
     706           0 :                          + OUString::number(base->getSort()) + " of base "
     707           0 :                          + baseName + " of singleton with key "
     708           0 :                          + sub.getName()));
     709             :                 }
     710             :             } else {
     711           0 :                 RegistryKey key2;
     712           0 :                 e = ucr.openKey(basePath, key2);
     713           0 :                 switch (e) {
     714             :                 case REG_NO_ERROR:
     715           0 :                     break;
     716             :                 case REG_KEY_NOT_EXISTS:
     717             :                     throw FileFormatException(
     718             :                         key.getRegistryName(),
     719           0 :                         ("legacy format: unknown super-type " + basePath
     720           0 :                          + " of super-type with key " + sub.getName()));
     721             :                 default:
     722             :                     throw FileFormatException(
     723             :                         key.getRegistryName(),
     724           0 :                         ("legacy format: cannot open ucr sub-key " + basePath
     725           0 :                          + ": " + OUString::number(e)));
     726             :                 }
     727           0 :                 std::vector< char > buf2;
     728           0 :                 typereg::Reader reader2(getReader(key2, &buf2));
     729           0 :                 switch (reader2.getTypeClass()) {
     730             :                 case RT_TYPE_INTERFACE:
     731           0 :                     newStyle = true;
     732           0 :                     break;
     733             :                 case RT_TYPE_SERVICE:
     734           0 :                     newStyle = false;
     735           0 :                     break;
     736             :                 default:
     737             :                     throw FileFormatException(
     738             :                         key.getRegistryName(),
     739             :                         ("legacy format: unexpected type class "
     740           0 :                          + OUString::number(reader2.getTypeClass())
     741           0 :                          + " of super-type with key " + key2.getName()
     742           0 :                          + " of singleton with key " + sub.getName()));
     743           0 :                 }
     744             :             }
     745             :             return newStyle
     746             :                 ? rtl::Reference< Entity >(
     747             :                     new InterfaceBasedSingletonEntity(
     748           0 :                         reader.isPublished(), baseName,
     749           0 :                         translateAnnotations(reader.getDocumentation())))
     750             :                 : rtl::Reference< Entity >(
     751             :                     new ServiceBasedSingletonEntity(
     752           0 :                         reader.isPublished(), baseName,
     753           0 :                         translateAnnotations(reader.getDocumentation())));
     754             :         }
     755             :     case RT_TYPE_CONSTANTS:
     756             :         {
     757           0 :             std::vector< ConstantGroupEntity::Member > mems;
     758           0 :             sal_uInt16 n = reader.getFieldCount();
     759           0 :             for (sal_uInt16 j = 0; j != n; ++j) {
     760             :                 mems.push_back(
     761             :                     ConstantGroupEntity::Member(
     762             :                         reader.getFieldName(j),
     763           0 :                         translateConstantValue(sub, reader.getFieldValue(j)),
     764           0 :                         translateAnnotations(reader.getFieldDocumentation(j))));
     765             :             }
     766             :             return new ConstantGroupEntity(
     767           0 :                 reader.isPublished(), mems,
     768           0 :                 translateAnnotations(reader.getDocumentation()));
     769             :         }
     770             :     default:
     771             :         throw FileFormatException(
     772             :             key.getRegistryName(),
     773             :             ("legacy format: unexpected type class "
     774           0 :              + OUString::number(reader.getTypeClass()) + " of key "
     775           0 :              + sub.getName()));
     776           0 :     }
     777             : }
     778             : 
     779             : }
     780             : 
     781           0 : LegacyProvider::LegacyProvider(Manager & manager, OUString const & uri):
     782           0 :     manager_(manager)
     783             : {
     784           0 :     Registry reg;
     785           0 :     RegError e = reg.open(uri, REG_READONLY);
     786           0 :     switch (e) {
     787             :     case REG_NO_ERROR:
     788           0 :         break;
     789             :     case REG_REGISTRY_NOT_EXISTS:
     790           0 :         throw NoSuchFileException(uri);
     791             :     default:
     792             :         throw FileFormatException(
     793           0 :             uri, "cannot open legacy file: " + OUString::number(e));
     794             :     }
     795           0 :     RegistryKey root;
     796           0 :     e = reg.openRootKey(root);
     797           0 :     if (e != REG_NO_ERROR) {
     798             :         throw FileFormatException(
     799           0 :             uri, "legacy format: cannot open root key: " + OUString::number(e));
     800             :     }
     801           0 :     e = root.openKey("UCR", ucr_);
     802           0 :     switch (e) {
     803             :     case REG_NO_ERROR:
     804             :     case REG_KEY_NOT_EXISTS: // such effectively empty files exist in the wild
     805           0 :         break;
     806             :     default:
     807             :         throw FileFormatException(
     808           0 :             uri, "legacy format: cannot open UCR key: " + OUString::number(e));
     809           0 :     }
     810           0 : }
     811             : 
     812           0 : rtl::Reference< MapCursor > LegacyProvider::createRootCursor() const {
     813           0 :     return new Cursor(&manager_, ucr_, ucr_);
     814             : }
     815             : 
     816           0 : rtl::Reference< Entity > LegacyProvider::findEntity(OUString const & name)
     817             :     const
     818             : {
     819           0 :     return ucr_.isValid()
     820             :         ? readEntity(&manager_, ucr_, ucr_, name.replace('.', '/'), true)
     821           0 :         : rtl::Reference< Entity >();
     822             : }
     823             : 
     824           0 : LegacyProvider::~LegacyProvider() throw () {}
     825             : 
     826             : } }
     827             : 
     828             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10