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

Generated by: LCOV version 1.10