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"
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"
24 #include "legacyprovider.hxx"
26 namespace unoidl
{ namespace detail
{
30 std::vector
< OUString
> translateAnnotations(OUString
const & documentation
) {
31 std::vector
< OUString
> ans
;
32 if (documentation
.indexOf("@deprecated") != -1) {
33 //TODO: this check is somewhat crude
34 ans
.push_back("deprecated");
39 ConstantValue
translateConstantValue(
40 RegistryKey
& key
, RTConstValue
const & value
)
42 switch (value
.m_type
) {
44 return ConstantValue(static_cast< bool >(value
.m_value
.aBool
));
46 return ConstantValue(value
.m_value
.aByte
);
48 return ConstantValue(value
.m_value
.aShort
);
50 return ConstantValue(value
.m_value
.aUShort
);
52 return ConstantValue(value
.m_value
.aLong
);
54 return ConstantValue(value
.m_value
.aULong
);
56 return ConstantValue(value
.m_value
.aHyper
);
58 return ConstantValue(value
.m_value
.aUHyper
);
60 return ConstantValue(value
.m_value
.aFloat
);
62 return ConstantValue(value
.m_value
.aDouble
);
64 throw FileFormatException(
65 key
.getRegistryName(),
66 ("legacy format: unexpected type " + OUString::number(value
.m_type
)
67 + " of value of a field of constant group with key "
72 rtl::Reference
< Entity
> readEntity(
73 rtl::Reference
< Manager
> const & manager
, RegistryKey
& ucr
,
74 RegistryKey
& key
, OUString
const & path
, bool probe
);
76 class Cursor
: public MapCursor
{
79 rtl::Reference
< Manager
> const & manager
, RegistryKey
const & ucr
,
80 RegistryKey
const & key
);
83 virtual ~Cursor() throw () {}
85 virtual rtl::Reference
< Entity
> getNext(OUString
* name
) SAL_OVERRIDE
;
87 rtl::Reference
< Manager
> manager_
;
91 RegistryKeyNames names_
;
96 rtl::Reference
< Manager
> const & manager
, RegistryKey
const & ucr
,
97 RegistryKey
const & key
):
98 manager_(manager
), ucr_(ucr
), key_(key
), index_(0)
100 if (ucr_
.isValid()) {
101 prefix_
= key_
.getName();
102 if (!prefix_
.endsWith("/")) {
105 RegError e
= key_
.getKeyNames("", names_
);
106 if (e
!= RegError::NO_ERROR
) {
107 throw FileFormatException(
108 key_
.getRegistryName(),
109 ("legacy format: cannot get sub-key names of " + key_
.getName()
110 + ": " + OUString::number(static_cast<int>(e
))));
115 rtl::Reference
< Entity
> Cursor::getNext(OUString
* name
) {
117 rtl::Reference
< Entity
> ent
;
118 if (index_
!= names_
.getLength()) {
119 OUString
path(names_
.getElement(index_
));
120 assert(path
.match(prefix_
));
121 *name
= path
.copy(prefix_
.getLength());
122 ent
= readEntity(manager_
, ucr_
, key_
, *name
, false);
129 class Module
: public ModuleEntity
{
132 rtl::Reference
< Manager
> const & manager
, RegistryKey
const & ucr
,
133 RegistryKey
const & key
):
134 manager_(manager
), ucr_(ucr
), key_(key
)
138 virtual ~Module() throw () {}
140 virtual std::vector
< OUString
> getMemberNames() const SAL_OVERRIDE
;
142 virtual rtl::Reference
< MapCursor
> createCursor() const SAL_OVERRIDE
143 { return new Cursor(manager_
, ucr_
, key_
); }
145 rtl::Reference
< Manager
> manager_
;
147 mutable RegistryKey key_
;
150 std::vector
< OUString
> Module::getMemberNames() const {
151 RegistryKeyNames names
;
152 RegError e
= key_
.getKeyNames("", names
);
153 if (e
!= RegError::NO_ERROR
) {
154 throw FileFormatException(
155 key_
.getRegistryName(),
156 ("legacy format: cannot get sub-key names of " + key_
.getName()
157 + ": " + OUString::number(static_cast<int>(e
))));
159 std::vector
< OUString
> ns
;
160 for (sal_uInt32 i
= 0; i
!= names
.getLength(); ++i
) {
161 ns
.push_back(names
.getElement(i
));
166 typereg::Reader
getReader(RegistryKey
& key
, std::vector
< char > * buffer
) {
170 RegError e
= key
.getValueInfo("", &type
, &size
);
171 if (e
!= RegError::NO_ERROR
) {
172 throw FileFormatException(
173 key
.getRegistryName(),
174 ("legacy format: cannot get value info about key " + key
.getName()
175 + ": " + OUString::number(static_cast<int>(e
))));
177 if (type
!= RegValueType::BINARY
) {
178 throw FileFormatException(
179 key
.getRegistryName(),
180 ("legacy format: unexpected value type " + OUString::number(static_cast<int>(type
))
181 + " of key " + key
.getName()));
184 /*TODO: || size > std::numeric_limits< std::vector< char >::size_type >::max() */)
186 throw FileFormatException(
187 key
.getRegistryName(),
188 ("legacy format: bad binary value size " + OUString::number(size
)
189 + " of key " + key
.getName()));
191 buffer
->resize(static_cast< std::vector
< char >::size_type
>(size
));
192 e
= key
.getValue("", &(*buffer
)[0]);
193 if (e
!= RegError::NO_ERROR
) {
194 throw FileFormatException(
195 key
.getRegistryName(),
196 ("legacy format: cannot get binary value of key " + key
.getName()
197 + ": " + OUString::number(static_cast<int>(e
))));
199 typereg::Reader
reader(&(*buffer
)[0], size
, false, TYPEREG_VERSION_1
);
200 if (!reader
.isValid()) {
201 throw FileFormatException(
202 key
.getRegistryName(),
203 "legacy format: malformed binary value of key " + key
.getName());
208 rtl::Reference
< Entity
> readEntity(
209 rtl::Reference
< Manager
> const & manager
, RegistryKey
& ucr
,
210 RegistryKey
& key
, OUString
const & path
, bool probe
)
212 assert(manager
.is());
214 RegError e
= key
.openKey(path
, sub
);
216 case RegError::NO_ERROR
:
218 case RegError::KEY_NOT_EXISTS
:
220 return rtl::Reference
< Entity
>();
224 throw FileFormatException(
225 key
.getRegistryName(),
226 ("legacy format: cannot open sub-key " + path
+ " of "
227 + key
.getName() + ": " + OUString::number(static_cast<int>(e
))));
229 std::vector
< char > buf
;
230 typereg::Reader
reader(getReader(sub
, &buf
));
231 switch (reader
.getTypeClass()) {
232 case RT_TYPE_INTERFACE
:
234 std::vector
< AnnotatedReference
> mandBases
;
235 sal_uInt16 n
= reader
.getSuperTypeCount();
236 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
239 reader
.getSuperTypeName(j
).replace('/', '.'),
240 std::vector
< OUString
>()));
242 std::vector
< AnnotatedReference
> optBases
;
243 n
= reader
.getReferenceCount();
244 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
247 reader
.getReferenceTypeName(j
).replace('/', '.'),
248 translateAnnotations(
249 reader
.getReferenceDocumentation(j
))));
251 sal_uInt16 methodCount
= reader
.getMethodCount();
252 std::vector
< InterfaceTypeEntity::Attribute
> attrs
;
253 n
= reader
.getFieldCount(); // attributes
254 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
255 OUString
attrName(reader
.getFieldName(j
));
256 std::vector
< OUString
> getExcs
;
257 std::vector
< OUString
> setExcs
;
258 for (sal_uInt16 k
= 0; k
!= methodCount
; ++k
) {
259 if (reader
.getMethodName(k
) == attrName
) {
260 switch (reader
.getMethodFlags(k
)) {
261 case RTMethodMode::ATTRIBUTE_GET
:
264 = reader
.getMethodExceptionCount(k
);
265 // coverity[tainted_data] cid#1213376
266 // unhelpfully warns about an untrusted loop
268 for (sal_uInt16 l
= 0; l
!= m
; ++l
) {
270 reader
.getMethodExceptionTypeName(k
, l
).
275 case RTMethodMode::ATTRIBUTE_SET
:
278 = reader
.getMethodExceptionCount(k
);
279 // coverity[tainted_data] cid#1213376
280 // unhelpfully warns about an untrusted loop
282 for (sal_uInt16 l
= 0; l
!= m
; ++l
) {
284 reader
.getMethodExceptionTypeName(k
, l
).
290 throw FileFormatException(
291 key
.getRegistryName(),
292 ("legacy format: method and attribute with same"
294 + " in interface type with key "
299 RTFieldAccess flags
= reader
.getFieldFlags(j
);
301 InterfaceTypeEntity::Attribute(
302 attrName
, reader
.getFieldTypeName(j
).replace('/', '.'),
303 bool(flags
& RTFieldAccess::BOUND
),
304 bool(flags
& RTFieldAccess::READONLY
), getExcs
, setExcs
,
305 translateAnnotations(reader
.getFieldDocumentation(j
))));
307 std::vector
< InterfaceTypeEntity::Method
> meths
;
308 for (sal_uInt16 j
= 0; j
!= methodCount
; ++j
) {
309 RTMethodMode flags
= reader
.getMethodFlags(j
);
310 if (flags
!= RTMethodMode::ATTRIBUTE_GET
311 && flags
!= RTMethodMode::ATTRIBUTE_SET
)
313 std::vector
< InterfaceTypeEntity::Method::Parameter
>
315 sal_uInt16 m
= reader
.getMethodParameterCount(j
);
316 // coverity[tainted_data] cid#1213376 unhelpfully warns
317 // about an untrusted loop bound here:
318 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
319 RTParamMode mode
= reader
.getMethodParameterFlags(j
, k
);
320 InterfaceTypeEntity::Method::Parameter::Direction dir
;
323 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
;
326 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT
;
329 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT
;
332 throw FileFormatException(
333 key
.getRegistryName(),
334 ("legacy format: unexpected mode "
335 + OUString::number(mode
) + " of parameter "
336 + reader
.getMethodParameterName(j
, k
)
337 + " of method " + reader
.getMethodName(j
)
338 + " in interface type with key "
342 InterfaceTypeEntity::Method::Parameter(
343 reader
.getMethodParameterName(j
, k
),
344 (reader
.getMethodParameterTypeName(j
, k
).
348 std::vector
< OUString
> excs
;
349 m
= reader
.getMethodExceptionCount(j
);
350 // coverity[tainted_data] cid#1213376 unhelpfully warns
351 // about an untrusted loop bound here:
352 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
354 reader
.getMethodExceptionTypeName(j
, k
).replace(
358 InterfaceTypeEntity::Method(
359 reader
.getMethodName(j
),
360 reader
.getMethodReturnTypeName(j
).replace('/', '.'),
362 translateAnnotations(
363 reader
.getMethodDocumentation(j
))));
366 return new InterfaceTypeEntity(
367 reader
.isPublished(), mandBases
, optBases
, attrs
, meths
,
368 translateAnnotations(reader
.getDocumentation()));
371 return new Module(manager
, ucr
, sub
);
374 sal_uInt32 n
= reader
.getReferenceCount();
377 switch (reader
.getSuperTypeCount()) {
381 base
= reader
.getSuperTypeName(0).replace('/', '.');
385 key
.getRegistryName(),
386 ("legacy format: unexpected number "
387 + OUString::number(reader
.getSuperTypeCount())
388 + " of super-types of plain struct type with key "
391 std::vector
< PlainStructTypeEntity::Member
> mems
;
392 n
= reader
.getFieldCount();
393 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
395 PlainStructTypeEntity::Member(
396 reader
.getFieldName(j
),
397 reader
.getFieldTypeName(j
).replace('/', '.'),
398 translateAnnotations(
399 reader
.getFieldDocumentation(j
))));
401 return new PlainStructTypeEntity(
402 reader
.isPublished(), base
, mems
,
403 translateAnnotations(reader
.getDocumentation()));
405 if (reader
.getSuperTypeCount() != 0) {
407 key
.getRegistryName(),
408 ("legacy format: unexpected number "
409 + OUString::number(reader
.getSuperTypeCount())
410 + " of super-types of polymorphic struct type template"
411 " with key " + sub
.getName()));
413 std::vector
< OUString
> params
;
414 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
416 reader
.getReferenceTypeName(j
).replace('/', '.'));
418 std::vector
< PolymorphicStructTypeTemplateEntity::Member
> mems
;
419 n
= reader
.getFieldCount();
420 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
422 PolymorphicStructTypeTemplateEntity::Member(
423 reader
.getFieldName(j
),
424 reader
.getFieldTypeName(j
).replace('/', '.'),
425 bool(reader
.getFieldFlags(j
)
426 & RTFieldAccess::PARAMETERIZED_TYPE
),
427 translateAnnotations(
428 reader
.getFieldDocumentation(j
))));
430 return new PolymorphicStructTypeTemplateEntity(
431 reader
.isPublished(), params
, mems
,
432 translateAnnotations(reader
.getDocumentation()));
437 std::vector
< EnumTypeEntity::Member
> mems
;
438 sal_uInt16 n
= reader
.getFieldCount();
439 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
440 RTConstValue
v(reader
.getFieldValue(j
));
441 if (v
.m_type
!= RT_TYPE_INT32
) {
443 key
.getRegistryName(),
444 ("legacy format: unexpected type "
445 + OUString::number(v
.m_type
) + " of value of field "
446 + reader
.getFieldName(j
) + " of enum type with key "
450 EnumTypeEntity::Member(
451 reader
.getFieldName(j
), v
.m_value
.aLong
,
452 translateAnnotations(reader
.getFieldDocumentation(j
))));
455 return new EnumTypeEntity(
456 reader
.isPublished(), mems
,
457 translateAnnotations(reader
.getDocumentation()));
459 case RT_TYPE_EXCEPTION
:
462 switch (reader
.getSuperTypeCount()) {
466 base
= reader
.getSuperTypeName(0).replace('/', '.');
469 throw FileFormatException(
470 key
.getRegistryName(),
471 ("legacy format: unexpected number "
472 + OUString::number(reader
.getSuperTypeCount())
473 + " of super-types of exception type with key "
476 std::vector
< ExceptionTypeEntity::Member
> mems
;
477 sal_uInt16 n
= reader
.getFieldCount();
478 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
480 ExceptionTypeEntity::Member(
481 reader
.getFieldName(j
),
482 reader
.getFieldTypeName(j
).replace('/', '.'),
483 translateAnnotations(reader
.getFieldDocumentation(j
))));
485 return new ExceptionTypeEntity(
486 reader
.isPublished(), base
, mems
,
487 translateAnnotations(reader
.getDocumentation()));
489 case RT_TYPE_TYPEDEF
:
490 if (reader
.getSuperTypeCount() != 1) {
491 throw FileFormatException(
492 key
.getRegistryName(),
493 ("legacy format: unexpected number "
494 + OUString::number(reader
.getSuperTypeCount())
495 + " of super-types of typedef with key " + sub
.getName()));
497 return new TypedefEntity(
498 reader
.isPublished(), reader
.getSuperTypeName(0).replace('/', '.'),
499 translateAnnotations(reader
.getDocumentation()));
500 case RT_TYPE_SERVICE
:
501 switch (reader
.getSuperTypeCount()) {
504 std::vector
< AnnotatedReference
> mandServs
;
505 std::vector
< AnnotatedReference
> optServs
;
506 std::vector
< AnnotatedReference
> mandIfcs
;
507 std::vector
< AnnotatedReference
> optIfcs
;
508 sal_uInt16 n
= reader
.getReferenceCount();
509 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
510 AnnotatedReference
base(
511 reader
.getReferenceTypeName(j
).replace('/', '.'),
512 translateAnnotations(
513 reader
.getReferenceDocumentation(j
)));
514 switch (reader
.getReferenceSort(j
)) {
515 case RTReferenceType::EXPORTS
:
516 if (!(reader
.getReferenceFlags(j
) & RTFieldAccess::OPTIONAL
))
518 mandServs
.push_back(base
);
520 optServs
.push_back(base
);
523 case RTReferenceType::SUPPORTS
:
524 if (!(reader
.getReferenceFlags(j
) & RTFieldAccess::OPTIONAL
))
526 mandIfcs
.push_back(base
);
528 optIfcs
.push_back(base
);
532 throw FileFormatException(
533 key
.getRegistryName(),
534 ("legacy format: unexpected mode "
535 + OUString::number(static_cast<int>(reader
.getReferenceSort(j
)))
536 + " of reference " + reader
.getReferenceTypeName(j
)
537 + " in service with key " + sub
.getName()));
540 std::vector
< AccumulationBasedServiceEntity::Property
> props
;
541 n
= reader
.getFieldCount();
542 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
543 RTFieldAccess acc
= reader
.getFieldFlags(j
);
545 if (acc
& RTFieldAccess::READONLY
) {
546 attrs
|= AccumulationBasedServiceEntity::Property::
549 if (acc
& RTFieldAccess::OPTIONAL
) {
550 attrs
|= AccumulationBasedServiceEntity::Property::
553 if (acc
& RTFieldAccess::MAYBEVOID
) {
554 attrs
|= AccumulationBasedServiceEntity::Property::
555 ATTRIBUTE_MAYBE_VOID
;
557 if (acc
& RTFieldAccess::BOUND
) {
558 attrs
|= AccumulationBasedServiceEntity::Property::
561 if (acc
& RTFieldAccess::CONSTRAINED
) {
562 attrs
|= AccumulationBasedServiceEntity::Property::
563 ATTRIBUTE_CONSTRAINED
;
565 if (acc
& RTFieldAccess::TRANSIENT
) {
566 attrs
|= AccumulationBasedServiceEntity::Property::
569 if (acc
& RTFieldAccess::MAYBEAMBIGUOUS
) {
570 attrs
|= AccumulationBasedServiceEntity::Property::
571 ATTRIBUTE_MAYBE_AMBIGUOUS
;
573 if (acc
& RTFieldAccess::MAYBEDEFAULT
) {
574 attrs
|= AccumulationBasedServiceEntity::Property::
575 ATTRIBUTE_MAYBE_DEFAULT
;
577 if (acc
& RTFieldAccess::REMOVABLE
) {
578 attrs
|= AccumulationBasedServiceEntity::Property::
582 AccumulationBasedServiceEntity::Property(
583 reader
.getFieldName(j
),
584 reader
.getFieldTypeName(j
).replace('/', '.'),
586 AccumulationBasedServiceEntity::Property::
588 translateAnnotations(
589 reader
.getFieldDocumentation(j
))));
591 return new AccumulationBasedServiceEntity(
592 reader
.isPublished(), mandServs
, optServs
, mandIfcs
,
594 translateAnnotations(reader
.getDocumentation()));
598 std::vector
< SingleInterfaceBasedServiceEntity::Constructor
>
600 sal_uInt16 n
= reader
.getMethodCount();
601 if (n
== 1 && reader
.getMethodFlags(0) == RTMethodMode::TWOWAY
602 && reader
.getMethodName(0).isEmpty()
603 && reader
.getMethodReturnTypeName(0) == "void"
604 && reader
.getMethodParameterCount(0) == 0
605 && reader
.getMethodExceptionCount(0) == 0)
608 SingleInterfaceBasedServiceEntity::Constructor());
610 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
611 if (reader
.getMethodFlags(j
) != RTMethodMode::TWOWAY
) {
612 throw FileFormatException(
613 key
.getRegistryName(),
614 ("legacy format: unexpected mode "
615 + OUString::number(static_cast<int>(reader
.getMethodFlags(j
)))
616 + " of constructor " + reader
.getMethodName(j
)
617 + " in service with key " + sub
.getName()));
620 SingleInterfaceBasedServiceEntity::Constructor::
622 sal_uInt16 m
= reader
.getMethodParameterCount(j
);
623 // coverity[tainted_data] cid#1213376 unhelpfully warns
624 // about an untrusted loop bound here:
625 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
627 = reader
.getMethodParameterFlags(j
, k
);
628 if ((mode
& ~RT_PARAM_REST
) != RT_PARAM_IN
) {
629 throw FileFormatException(
630 key
.getRegistryName(),
631 ("legacy format: unexpected mode "
632 + OUString::number(mode
)
634 + reader
.getMethodParameterName(j
, k
)
636 + reader
.getMethodName(j
)
637 + " in service with key "
640 if ((mode
& RT_PARAM_REST
) != 0
642 && ((reader
.getMethodParameterTypeName(
646 throw FileFormatException(
647 key
.getRegistryName(),
648 ("legacy format: bad rest parameter "
649 + reader
.getMethodParameterName(j
, k
)
651 + reader
.getMethodName(j
)
652 + " in service with key "
656 SingleInterfaceBasedServiceEntity::Constructor::
658 reader
.getMethodParameterName(j
, k
),
659 (reader
.getMethodParameterTypeName(j
, k
).
661 (mode
& RT_PARAM_REST
) != 0));
663 std::vector
< OUString
> excs
;
664 m
= reader
.getMethodExceptionCount(j
);
665 // coverity[tainted_data] cid#1213376 unhelpfully warns
666 // about an untrusted loop bound here:
667 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
669 reader
.getMethodExceptionTypeName(j
, k
).replace(
673 SingleInterfaceBasedServiceEntity::Constructor(
674 reader
.getMethodName(j
), params
, excs
,
675 translateAnnotations(
676 reader
.getMethodDocumentation(j
))));
679 return new SingleInterfaceBasedServiceEntity(
680 reader
.isPublished(),
681 reader
.getSuperTypeName(0).replace('/', '.'), ctors
,
682 translateAnnotations(reader
.getDocumentation()));
685 throw FileFormatException(
686 key
.getRegistryName(),
687 ("legacy format: unexpected number "
688 + OUString::number(reader
.getSuperTypeCount())
689 + " of super-types of service with key " + sub
.getName()));
691 case RT_TYPE_SINGLETON
:
693 if (reader
.getSuperTypeCount() != 1) {
694 throw FileFormatException(
695 key
.getRegistryName(),
696 ("legacy format: unexpected number "
697 + OUString::number(reader
.getSuperTypeCount())
698 + " of super-types of singleton with key "
701 OUString
basePath(reader
.getSuperTypeName(0));
702 OUString
baseName(basePath
.replace('/', '.'));
704 rtl::Reference
< Entity
> base(manager
->findEntity(baseName
));
706 switch (base
->getSort()) {
707 case Entity::SORT_INTERFACE_TYPE
:
710 case Entity::SORT_ACCUMULATION_BASED_SERVICE
:
714 throw FileFormatException(
715 key
.getRegistryName(),
716 ("legacy format: unexpected sort "
717 + OUString::number(base
->getSort()) + " of base "
718 + baseName
+ " of singleton with key "
723 e
= ucr
.openKey(basePath
, key2
);
725 case RegError::NO_ERROR
:
727 case RegError::KEY_NOT_EXISTS
:
728 throw FileFormatException(
729 key
.getRegistryName(),
730 ("legacy format: unknown super-type " + basePath
731 + " of super-type with key " + sub
.getName()));
733 throw FileFormatException(
734 key
.getRegistryName(),
735 ("legacy format: cannot open ucr sub-key " + basePath
736 + ": " + OUString::number(static_cast<int>(e
))));
738 std::vector
< char > buf2
;
739 typereg::Reader
reader2(getReader(key2
, &buf2
));
740 switch (reader2
.getTypeClass()) {
741 case RT_TYPE_INTERFACE
:
744 case RT_TYPE_SERVICE
:
748 throw FileFormatException(
749 key
.getRegistryName(),
750 ("legacy format: unexpected type class "
751 + OUString::number(reader2
.getTypeClass())
752 + " of super-type with key " + key2
.getName()
753 + " of singleton with key " + sub
.getName()));
757 ? rtl::Reference
< Entity
>(
758 new InterfaceBasedSingletonEntity(
759 reader
.isPublished(), baseName
,
760 translateAnnotations(reader
.getDocumentation())))
761 : rtl::Reference
< Entity
>(
762 new ServiceBasedSingletonEntity(
763 reader
.isPublished(), baseName
,
764 translateAnnotations(reader
.getDocumentation())));
766 case RT_TYPE_CONSTANTS
:
768 std::vector
< ConstantGroupEntity::Member
> mems
;
769 sal_uInt16 n
= reader
.getFieldCount();
770 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
772 ConstantGroupEntity::Member(
773 reader
.getFieldName(j
),
774 translateConstantValue(sub
, reader
.getFieldValue(j
)),
775 translateAnnotations(reader
.getFieldDocumentation(j
))));
777 return new ConstantGroupEntity(
778 reader
.isPublished(), mems
,
779 translateAnnotations(reader
.getDocumentation()));
782 throw FileFormatException(
783 key
.getRegistryName(),
784 ("legacy format: unexpected type class "
785 + OUString::number(reader
.getTypeClass()) + " of key "
792 LegacyProvider::LegacyProvider(Manager
& manager
, OUString
const & uri
):
796 RegError e
= reg
.open(uri
, RegAccessMode::READONLY
);
798 case RegError::NO_ERROR
:
800 case RegError::REGISTRY_NOT_EXISTS
:
801 throw NoSuchFileException(uri
);
803 throw FileFormatException(
804 uri
, "cannot open legacy file: " + OUString::number(static_cast<int>(e
)));
807 e
= reg
.openRootKey(root
);
808 if (e
!= RegError::NO_ERROR
) {
809 throw FileFormatException(
810 uri
, "legacy format: cannot open root key: " + OUString::number(static_cast<int>(e
)));
812 e
= root
.openKey("UCR", ucr_
);
814 case RegError::NO_ERROR
:
815 case RegError::KEY_NOT_EXISTS
: // such effectively empty files exist in the wild
818 throw FileFormatException(
819 uri
, "legacy format: cannot open UCR key: " + OUString::number(static_cast<int>(e
)));
823 rtl::Reference
< MapCursor
> LegacyProvider::createRootCursor() const {
824 return new Cursor(&manager_
, ucr_
, ucr_
);
827 rtl::Reference
< Entity
> LegacyProvider::findEntity(OUString
const & name
)
830 return ucr_
.isValid()
831 ? readEntity(&manager_
, ucr_
, ucr_
, name
.replace('.', '/'), true)
832 : rtl::Reference
< Entity
>();
835 LegacyProvider::~LegacyProvider() throw () {}
839 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */