1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #include <sal/config.h>
15 #include <registry/reader.hxx>
16 #include <registry/registry.hxx>
17 #include <registry/regtype.h>
18 #include <rtl/ref.hxx>
19 #include <rtl/ustring.hxx>
20 #include <sal/types.h>
21 #include <unoidl/unoidl.hxx>
23 #include "legacyprovider.hxx"
25 namespace unoidl
{ namespace detail
{
29 std::vector
< OUString
> translateAnnotations(OUString
const & documentation
) {
30 std::vector
< OUString
> ans
;
31 if (documentation
.indexOf("@deprecated") != -1) {
32 //TODO: this check is somewhat crude
33 ans
.push_back("deprecated");
38 ConstantValue
translateConstantValue(
39 RegistryKey
& key
, RTConstValue
const & value
)
41 switch (value
.m_type
) {
43 return ConstantValue(value
.m_value
.aBool
);
45 return ConstantValue(value
.m_value
.aByte
);
47 return ConstantValue(value
.m_value
.aShort
);
49 return ConstantValue(value
.m_value
.aUShort
);
51 return ConstantValue(value
.m_value
.aLong
);
53 return ConstantValue(value
.m_value
.aULong
);
55 return ConstantValue(value
.m_value
.aHyper
);
57 return ConstantValue(value
.m_value
.aUHyper
);
59 return ConstantValue(value
.m_value
.aFloat
);
61 return ConstantValue(value
.m_value
.aDouble
);
63 throw FileFormatException(
64 key
.getRegistryName(),
65 ("legacy format: unexpected type " + OUString::number(value
.m_type
)
66 + " of value of a field of constant group with key "
71 rtl::Reference
< Entity
> readEntity(
72 rtl::Reference
< Manager
> const & manager
, RegistryKey
& ucr
,
73 RegistryKey
& key
, OUString
const & path
, bool probe
);
75 class Cursor
: public MapCursor
{
78 rtl::Reference
< Manager
> const & manager
, RegistryKey
const & ucr
,
79 RegistryKey
const & key
);
82 virtual ~Cursor() throw () override
{}
84 virtual rtl::Reference
< Entity
> getNext(OUString
* name
) override
;
86 rtl::Reference
< Manager
> manager_
;
90 RegistryKeyNames names_
;
95 rtl::Reference
< Manager
> const & manager
, RegistryKey
const & ucr
,
96 RegistryKey
const & key
):
97 manager_(manager
), ucr_(ucr
), key_(key
), index_(0)
100 prefix_
= key_
.getName();
101 if (!prefix_
.endsWith("/")) {
104 RegError e
= key_
.getKeyNames("", names_
);
105 if (e
!= RegError::NO_ERROR
) {
106 throw FileFormatException(
107 key_
.getRegistryName(),
108 ("legacy format: cannot get sub-key names of " + key_
.getName()
109 + ": " + OUString::number(static_cast<int>(e
))));
114 rtl::Reference
< Entity
> Cursor::getNext(OUString
* name
) {
115 assert(name
!= nullptr);
116 rtl::Reference
< Entity
> ent
;
117 if (index_
!= names_
.getLength()) {
118 OUString
path(names_
.getElement(index_
));
119 assert(path
.match(prefix_
));
120 *name
= path
.copy(prefix_
.getLength());
121 ent
= readEntity(manager_
, ucr_
, key_
, *name
, false);
128 class Module
: public ModuleEntity
{
131 rtl::Reference
< Manager
> const & manager
, RegistryKey
const & ucr
,
132 RegistryKey
const & key
):
133 manager_(manager
), ucr_(ucr
), key_(key
)
137 virtual ~Module() throw () override
{}
139 virtual std::vector
< OUString
> getMemberNames() const override
;
141 virtual rtl::Reference
< MapCursor
> createCursor() const override
142 { return new Cursor(manager_
, ucr_
, key_
); }
144 rtl::Reference
< Manager
> manager_
;
145 RegistryKey
const ucr_
;
146 mutable RegistryKey key_
;
149 std::vector
< OUString
> Module::getMemberNames() const {
150 RegistryKeyNames names
;
151 RegError e
= key_
.getKeyNames("", names
);
152 if (e
!= RegError::NO_ERROR
) {
153 throw FileFormatException(
154 key_
.getRegistryName(),
155 ("legacy format: cannot get sub-key names of " + key_
.getName()
156 + ": " + OUString::number(static_cast<int>(e
))));
158 std::vector
< OUString
> ns
;
159 for (sal_uInt32 i
= 0; i
!= names
.getLength(); ++i
) {
160 ns
.push_back(names
.getElement(i
));
165 typereg::Reader
getReader(RegistryKey
& key
, std::vector
< char > * buffer
) {
166 assert(buffer
!= nullptr);
169 RegError e
= key
.getValueInfo("", &type
, &size
);
170 if (e
!= RegError::NO_ERROR
) {
171 throw FileFormatException(
172 key
.getRegistryName(),
173 ("legacy format: cannot get value info about key " + key
.getName()
174 + ": " + OUString::number(static_cast<int>(e
))));
176 if (type
!= RegValueType::BINARY
) {
177 throw FileFormatException(
178 key
.getRegistryName(),
179 ("legacy format: unexpected value type " + OUString::number(static_cast<int>(type
))
180 + " of key " + key
.getName()));
183 /*TODO: || size > std::numeric_limits< std::vector< char >::size_type >::max() */)
185 throw FileFormatException(
186 key
.getRegistryName(),
187 ("legacy format: bad binary value size " + OUString::number(size
)
188 + " of key " + key
.getName()));
190 buffer
->resize(static_cast< std::vector
< char >::size_type
>(size
));
191 e
= key
.getValue("", buffer
->data());
192 if (e
!= RegError::NO_ERROR
) {
193 throw FileFormatException(
194 key
.getRegistryName(),
195 ("legacy format: cannot get binary value of key " + key
.getName()
196 + ": " + OUString::number(static_cast<int>(e
))));
198 typereg::Reader
reader(buffer
->data(), size
);
199 if (!reader
.isValid()) {
200 throw FileFormatException(
201 key
.getRegistryName(),
202 "legacy format: malformed binary value of key " + key
.getName());
207 rtl::Reference
< Entity
> readEntity(
208 rtl::Reference
< Manager
> const & manager
, RegistryKey
& ucr
,
209 RegistryKey
& key
, OUString
const & path
, bool probe
)
211 assert(manager
.is());
213 RegError e
= key
.openKey(path
, sub
);
215 case RegError::NO_ERROR
:
217 case RegError::KEY_NOT_EXISTS
:
219 return rtl::Reference
< Entity
>();
223 throw FileFormatException(
224 key
.getRegistryName(),
225 ("legacy format: cannot open sub-key " + path
+ " of "
226 + key
.getName() + ": " + OUString::number(static_cast<int>(e
))));
228 std::vector
< char > buf
;
229 typereg::Reader
reader(getReader(sub
, &buf
));
230 switch (reader
.getTypeClass()) {
231 case RT_TYPE_INTERFACE
:
233 std::vector
< AnnotatedReference
> mandBases
;
234 sal_uInt16 n
= reader
.getSuperTypeCount();
235 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
236 mandBases
.emplace_back(
237 reader
.getSuperTypeName(j
).replace('/', '.'),
238 std::vector
< OUString
>());
240 std::vector
< AnnotatedReference
> optBases
;
241 n
= reader
.getReferenceCount();
242 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
243 optBases
.emplace_back(
244 reader
.getReferenceTypeName(j
).replace('/', '.'),
245 translateAnnotations(reader
.getReferenceDocumentation(j
)));
247 sal_uInt16 methodCount
= reader
.getMethodCount();
248 std::vector
< InterfaceTypeEntity::Attribute
> attrs
;
249 n
= reader
.getFieldCount(); // attributes
250 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
251 OUString
attrName(reader
.getFieldName(j
));
252 std::vector
< OUString
> getExcs
;
253 std::vector
< OUString
> setExcs
;
254 for (sal_uInt16 k
= 0; k
!= methodCount
; ++k
) {
255 if (reader
.getMethodName(k
) == attrName
) {
256 switch (reader
.getMethodFlags(k
)) {
257 case RTMethodMode::ATTRIBUTE_GET
:
260 = reader
.getMethodExceptionCount(k
);
261 // cid#1213376 unhelpfully warns about an
262 // untrusted loop bound here:
263 // coverity[tainted_data] - trusted data source
264 for (sal_uInt16 l
= 0; l
!= m
; ++l
) {
266 reader
.getMethodExceptionTypeName(k
, l
).
271 case RTMethodMode::ATTRIBUTE_SET
:
274 = reader
.getMethodExceptionCount(k
);
275 // cid#1213376 unhelpfully warns about an
276 // untrusted loop bound here:
277 // coverity[tainted_data] - trusted data source
278 for (sal_uInt16 l
= 0; l
!= m
; ++l
) {
280 reader
.getMethodExceptionTypeName(k
, l
).
286 throw FileFormatException(
287 key
.getRegistryName(),
288 ("legacy format: method and attribute with same"
290 + " in interface type with key "
295 RTFieldAccess flags
= reader
.getFieldFlags(j
);
297 attrName
, reader
.getFieldTypeName(j
).replace('/', '.'),
298 bool(flags
& RTFieldAccess::BOUND
),
299 bool(flags
& RTFieldAccess::READONLY
), getExcs
, setExcs
,
300 translateAnnotations(reader
.getFieldDocumentation(j
)));
302 std::vector
< InterfaceTypeEntity::Method
> meths
;
303 for (sal_uInt16 j
= 0; j
!= methodCount
; ++j
) {
304 RTMethodMode flags
= reader
.getMethodFlags(j
);
305 if (flags
!= RTMethodMode::ATTRIBUTE_GET
306 && flags
!= RTMethodMode::ATTRIBUTE_SET
)
308 std::vector
< InterfaceTypeEntity::Method::Parameter
>
310 sal_uInt16 m
= reader
.getMethodParameterCount(j
);
311 // cid#1213376 unhelpfully warns about an untrusted loop
313 // coverity[tainted_data] - trusted data source
314 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
315 RTParamMode mode
= reader
.getMethodParameterFlags(j
, k
);
316 InterfaceTypeEntity::Method::Parameter::Direction dir
;
319 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
;
322 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT
;
325 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT
;
328 throw FileFormatException(
329 key
.getRegistryName(),
330 ("legacy format: unexpected mode "
331 + OUString::number(mode
) + " of parameter "
332 + reader
.getMethodParameterName(j
, k
)
333 + " of method " + reader
.getMethodName(j
)
334 + " in interface type with key "
338 reader
.getMethodParameterName(j
, k
),
339 (reader
.getMethodParameterTypeName(j
, k
).
343 std::vector
< OUString
> excs
;
344 m
= reader
.getMethodExceptionCount(j
);
345 // cid#1213376 unhelpfully warns about an untrusted loop
347 // coverity[tainted_data] - trusted data source
348 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
350 reader
.getMethodExceptionTypeName(j
, k
).replace(
354 reader
.getMethodName(j
),
355 reader
.getMethodReturnTypeName(j
).replace('/', '.'),
357 translateAnnotations(
358 reader
.getMethodDocumentation(j
)));
361 return new InterfaceTypeEntity(
362 reader
.isPublished(), mandBases
, optBases
, attrs
, meths
,
363 translateAnnotations(reader
.getDocumentation()));
366 return new Module(manager
, ucr
, sub
);
369 sal_uInt16 n
= reader
.getReferenceCount();
372 switch (reader
.getSuperTypeCount()) {
376 base
= reader
.getSuperTypeName(0).replace('/', '.');
379 throw FileFormatException(
380 key
.getRegistryName(),
381 ("legacy format: unexpected number "
382 + OUString::number(reader
.getSuperTypeCount())
383 + " of super-types of plain struct type with key "
386 std::vector
< PlainStructTypeEntity::Member
> mems
;
387 n
= reader
.getFieldCount();
388 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
390 reader
.getFieldName(j
),
391 reader
.getFieldTypeName(j
).replace('/', '.'),
392 translateAnnotations(reader
.getFieldDocumentation(j
)));
394 return new PlainStructTypeEntity(
395 reader
.isPublished(), base
, mems
,
396 translateAnnotations(reader
.getDocumentation()));
398 if (reader
.getSuperTypeCount() != 0) {
399 throw FileFormatException(
400 key
.getRegistryName(),
401 ("legacy format: unexpected number "
402 + OUString::number(reader
.getSuperTypeCount())
403 + " of super-types of polymorphic struct type template"
404 " with key " + sub
.getName()));
406 std::vector
< OUString
> params
;
407 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
409 reader
.getReferenceTypeName(j
).replace('/', '.'));
411 std::vector
< PolymorphicStructTypeTemplateEntity::Member
> mems
;
412 n
= reader
.getFieldCount();
413 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
415 reader
.getFieldName(j
),
416 reader
.getFieldTypeName(j
).replace('/', '.'),
418 reader
.getFieldFlags(j
)
419 & RTFieldAccess::PARAMETERIZED_TYPE
),
420 translateAnnotations(reader
.getFieldDocumentation(j
)));
422 return new PolymorphicStructTypeTemplateEntity(
423 reader
.isPublished(), params
, mems
,
424 translateAnnotations(reader
.getDocumentation()));
429 std::vector
< EnumTypeEntity::Member
> mems
;
430 sal_uInt16 n
= reader
.getFieldCount();
431 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
432 RTConstValue
v(reader
.getFieldValue(j
));
433 if (v
.m_type
!= RT_TYPE_INT32
) {
434 throw FileFormatException(
435 key
.getRegistryName(),
436 ("legacy format: unexpected type "
437 + OUString::number(v
.m_type
) + " of value of field "
438 + reader
.getFieldName(j
) + " of enum type with key "
442 reader
.getFieldName(j
), v
.m_value
.aLong
,
443 translateAnnotations(reader
.getFieldDocumentation(j
)));
446 return new EnumTypeEntity(
447 reader
.isPublished(), mems
,
448 translateAnnotations(reader
.getDocumentation()));
450 case RT_TYPE_EXCEPTION
:
453 switch (reader
.getSuperTypeCount()) {
457 base
= reader
.getSuperTypeName(0).replace('/', '.');
460 throw FileFormatException(
461 key
.getRegistryName(),
462 ("legacy format: unexpected number "
463 + OUString::number(reader
.getSuperTypeCount())
464 + " of super-types of exception type with key "
467 std::vector
< ExceptionTypeEntity::Member
> mems
;
468 sal_uInt16 n
= reader
.getFieldCount();
469 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
471 reader
.getFieldName(j
),
472 reader
.getFieldTypeName(j
).replace('/', '.'),
473 translateAnnotations(reader
.getFieldDocumentation(j
)));
475 return new ExceptionTypeEntity(
476 reader
.isPublished(), base
, mems
,
477 translateAnnotations(reader
.getDocumentation()));
479 case RT_TYPE_TYPEDEF
:
480 if (reader
.getSuperTypeCount() != 1) {
481 throw FileFormatException(
482 key
.getRegistryName(),
483 ("legacy format: unexpected number "
484 + OUString::number(reader
.getSuperTypeCount())
485 + " of super-types of typedef with key " + sub
.getName()));
487 return new TypedefEntity(
488 reader
.isPublished(), reader
.getSuperTypeName(0).replace('/', '.'),
489 translateAnnotations(reader
.getDocumentation()));
490 case RT_TYPE_SERVICE
:
491 switch (reader
.getSuperTypeCount()) {
494 std::vector
< AnnotatedReference
> mandServs
;
495 std::vector
< AnnotatedReference
> optServs
;
496 std::vector
< AnnotatedReference
> mandIfcs
;
497 std::vector
< AnnotatedReference
> optIfcs
;
498 sal_uInt16 n
= reader
.getReferenceCount();
499 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
500 AnnotatedReference base
{
501 reader
.getReferenceTypeName(j
).replace('/', '.'),
502 translateAnnotations(
503 reader
.getReferenceDocumentation(j
))};
504 switch (reader
.getReferenceSort(j
)) {
505 case RTReferenceType::EXPORTS
:
506 if (!(reader
.getReferenceFlags(j
) & RTFieldAccess::OPTIONAL
))
508 mandServs
.push_back(base
);
510 optServs
.push_back(base
);
513 case RTReferenceType::SUPPORTS
:
514 if (!(reader
.getReferenceFlags(j
) & RTFieldAccess::OPTIONAL
))
516 mandIfcs
.push_back(base
);
518 optIfcs
.push_back(base
);
522 throw FileFormatException(
523 key
.getRegistryName(),
524 ("legacy format: unexpected mode "
525 + OUString::number(static_cast<int>(reader
.getReferenceSort(j
)))
526 + " of reference " + reader
.getReferenceTypeName(j
)
527 + " in service with key " + sub
.getName()));
530 std::vector
< AccumulationBasedServiceEntity::Property
> props
;
531 n
= reader
.getFieldCount();
532 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
533 RTFieldAccess acc
= reader
.getFieldFlags(j
);
535 if (acc
& RTFieldAccess::READONLY
) {
536 attrs
|= AccumulationBasedServiceEntity::Property::
539 if (acc
& RTFieldAccess::OPTIONAL
) {
540 attrs
|= AccumulationBasedServiceEntity::Property::
543 if (acc
& RTFieldAccess::MAYBEVOID
) {
544 attrs
|= AccumulationBasedServiceEntity::Property::
545 ATTRIBUTE_MAYBE_VOID
;
547 if (acc
& RTFieldAccess::BOUND
) {
548 attrs
|= AccumulationBasedServiceEntity::Property::
551 if (acc
& RTFieldAccess::CONSTRAINED
) {
552 attrs
|= AccumulationBasedServiceEntity::Property::
553 ATTRIBUTE_CONSTRAINED
;
555 if (acc
& RTFieldAccess::TRANSIENT
) {
556 attrs
|= AccumulationBasedServiceEntity::Property::
559 if (acc
& RTFieldAccess::MAYBEAMBIGUOUS
) {
560 attrs
|= AccumulationBasedServiceEntity::Property::
561 ATTRIBUTE_MAYBE_AMBIGUOUS
;
563 if (acc
& RTFieldAccess::MAYBEDEFAULT
) {
564 attrs
|= AccumulationBasedServiceEntity::Property::
565 ATTRIBUTE_MAYBE_DEFAULT
;
567 if (acc
& RTFieldAccess::REMOVABLE
) {
568 attrs
|= AccumulationBasedServiceEntity::Property::
572 reader
.getFieldName(j
),
573 reader
.getFieldTypeName(j
).replace('/', '.'),
575 AccumulationBasedServiceEntity::Property::
577 translateAnnotations(reader
.getFieldDocumentation(j
)));
579 return new AccumulationBasedServiceEntity(
580 reader
.isPublished(), mandServs
, optServs
, mandIfcs
,
582 translateAnnotations(reader
.getDocumentation()));
586 std::vector
< SingleInterfaceBasedServiceEntity::Constructor
>
588 sal_uInt16 n
= reader
.getMethodCount();
589 if (n
== 1 && reader
.getMethodFlags(0) == RTMethodMode::TWOWAY
590 && reader
.getMethodName(0).isEmpty()
591 && reader
.getMethodReturnTypeName(0) == "void"
592 && reader
.getMethodParameterCount(0) == 0
593 && reader
.getMethodExceptionCount(0) == 0)
596 SingleInterfaceBasedServiceEntity::Constructor());
598 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
599 if (reader
.getMethodFlags(j
) != RTMethodMode::TWOWAY
) {
600 throw FileFormatException(
601 key
.getRegistryName(),
602 ("legacy format: unexpected mode "
603 + OUString::number(static_cast<int>(reader
.getMethodFlags(j
)))
604 + " of constructor " + reader
.getMethodName(j
)
605 + " in service with key " + sub
.getName()));
608 SingleInterfaceBasedServiceEntity::Constructor::
610 sal_uInt16 m
= reader
.getMethodParameterCount(j
);
611 // cid#1213376 unhelpfully warns about an untrusted
613 // coverity[tainted_data] - trusted data source
614 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
616 = reader
.getMethodParameterFlags(j
, k
);
617 if ((mode
& ~RT_PARAM_REST
) != RT_PARAM_IN
) {
618 throw FileFormatException(
619 key
.getRegistryName(),
620 ("legacy format: unexpected mode "
621 + OUString::number(mode
)
623 + reader
.getMethodParameterName(j
, k
)
625 + reader
.getMethodName(j
)
626 + " in service with key "
629 if ((mode
& RT_PARAM_REST
) != 0
631 && ((reader
.getMethodParameterTypeName(
635 throw FileFormatException(
636 key
.getRegistryName(),
637 ("legacy format: bad rest parameter "
638 + reader
.getMethodParameterName(j
, k
)
640 + reader
.getMethodName(j
)
641 + " in service with key "
645 reader
.getMethodParameterName(j
, k
),
646 (reader
.getMethodParameterTypeName(j
, k
).
648 (mode
& RT_PARAM_REST
) != 0);
650 std::vector
< OUString
> excs
;
651 m
= reader
.getMethodExceptionCount(j
);
652 // cid#1213376 unhelpfully warns about an untrusted
654 // coverity[tainted_data] - trusted data source
655 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
657 reader
.getMethodExceptionTypeName(j
, k
).replace(
661 SingleInterfaceBasedServiceEntity::Constructor(
662 reader
.getMethodName(j
), params
, excs
,
663 translateAnnotations(
664 reader
.getMethodDocumentation(j
))));
667 return new SingleInterfaceBasedServiceEntity(
668 reader
.isPublished(),
669 reader
.getSuperTypeName(0).replace('/', '.'), ctors
,
670 translateAnnotations(reader
.getDocumentation()));
673 throw FileFormatException(
674 key
.getRegistryName(),
675 ("legacy format: unexpected number "
676 + OUString::number(reader
.getSuperTypeCount())
677 + " of super-types of service with key " + sub
.getName()));
679 case RT_TYPE_SINGLETON
:
681 if (reader
.getSuperTypeCount() != 1) {
682 throw FileFormatException(
683 key
.getRegistryName(),
684 ("legacy format: unexpected number "
685 + OUString::number(reader
.getSuperTypeCount())
686 + " of super-types of singleton with key "
689 OUString
basePath(reader
.getSuperTypeName(0));
690 OUString
baseName(basePath
.replace('/', '.'));
692 rtl::Reference
< Entity
> base(manager
->findEntity(baseName
));
694 switch (base
->getSort()) {
695 case Entity::SORT_INTERFACE_TYPE
:
698 case Entity::SORT_ACCUMULATION_BASED_SERVICE
:
702 throw FileFormatException(
703 key
.getRegistryName(),
704 ("legacy format: unexpected sort "
705 + OUString::number(base
->getSort()) + " of base "
706 + baseName
+ " of singleton with key "
711 e
= ucr
.openKey(basePath
, key2
);
713 case RegError::NO_ERROR
:
715 case RegError::KEY_NOT_EXISTS
:
716 throw FileFormatException(
717 key
.getRegistryName(),
718 ("legacy format: unknown super-type " + basePath
719 + " of super-type with key " + sub
.getName()));
721 throw FileFormatException(
722 key
.getRegistryName(),
723 ("legacy format: cannot open ucr sub-key " + basePath
724 + ": " + OUString::number(static_cast<int>(e
))));
726 std::vector
< char > buf2
;
727 typereg::Reader
reader2(getReader(key2
, &buf2
));
728 switch (reader2
.getTypeClass()) {
729 case RT_TYPE_INTERFACE
:
732 case RT_TYPE_SERVICE
:
736 throw FileFormatException(
737 key
.getRegistryName(),
738 ("legacy format: unexpected type class "
739 + OUString::number(reader2
.getTypeClass())
740 + " of super-type with key " + key2
.getName()
741 + " of singleton with key " + sub
.getName()));
745 ? rtl::Reference
< Entity
>(
746 new InterfaceBasedSingletonEntity(
747 reader
.isPublished(), baseName
,
748 translateAnnotations(reader
.getDocumentation())))
749 : rtl::Reference
< Entity
>(
750 new ServiceBasedSingletonEntity(
751 reader
.isPublished(), baseName
,
752 translateAnnotations(reader
.getDocumentation())));
754 case RT_TYPE_CONSTANTS
:
756 std::vector
< ConstantGroupEntity::Member
> mems
;
757 sal_uInt16 n
= reader
.getFieldCount();
758 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
760 reader
.getFieldName(j
),
761 translateConstantValue(sub
, reader
.getFieldValue(j
)),
762 translateAnnotations(reader
.getFieldDocumentation(j
)));
764 return new ConstantGroupEntity(
765 reader
.isPublished(), mems
,
766 translateAnnotations(reader
.getDocumentation()));
769 throw FileFormatException(
770 key
.getRegistryName(),
771 ("legacy format: unexpected type class "
772 + OUString::number(reader
.getTypeClass()) + " of key "
779 LegacyProvider::LegacyProvider(Manager
& manager
, OUString
const & uri
):
783 RegError e
= reg
.open(uri
, RegAccessMode::READONLY
);
785 case RegError::NO_ERROR
:
787 case RegError::REGISTRY_NOT_EXISTS
:
788 throw NoSuchFileException(uri
);
790 throw FileFormatException(
791 uri
, "cannot open legacy file: " + OUString::number(static_cast<int>(e
)));
794 e
= reg
.openRootKey(root
);
795 if (e
!= RegError::NO_ERROR
) {
796 throw FileFormatException(
797 uri
, "legacy format: cannot open root key: " + OUString::number(static_cast<int>(e
)));
799 e
= root
.openKey("UCR", ucr_
);
801 case RegError::NO_ERROR
:
802 case RegError::KEY_NOT_EXISTS
: // such effectively empty files exist in the wild
805 throw FileFormatException(
806 uri
, "legacy format: cannot open UCR key: " + OUString::number(static_cast<int>(e
)));
810 rtl::Reference
< MapCursor
> LegacyProvider::createRootCursor() const {
811 return new Cursor(&manager_
, ucr_
, ucr_
);
814 rtl::Reference
< Entity
> LegacyProvider::findEntity(OUString
const & name
)
817 return ucr_
.isValid()
818 ? readEntity(&manager_
, ucr_
, ucr_
, name
.replace('.', '/'), true)
819 : rtl::Reference
< Entity
>();
822 LegacyProvider::~LegacyProvider() throw () {}
826 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */