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::detail
{
30 std::vector
< OUString
> translateAnnotations(std::u16string_view documentation
) {
31 std::vector
< OUString
> ans
;
32 if (documentation
.find(u
"@deprecated") != std::u16string_view::npos
) {
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(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
> manager
, RegistryKey
const & ucr
,
80 RegistryKey
const & key
);
83 virtual ~Cursor() noexcept override
{}
85 virtual rtl::Reference
< Entity
> getNext(OUString
* name
) override
;
87 rtl::Reference
< Manager
> manager_
;
91 RegistryKeyNames names_
;
96 rtl::Reference
< Manager
> manager
, RegistryKey
const & ucr
,
97 RegistryKey
const & key
):
98 manager_(std::move(manager
)), ucr_(ucr
), key_(key
), index_(0)
103 prefix_
= key_
.getName();
104 if (!prefix_
.endsWith("/")) {
107 RegError e
= key_
.getKeyNames("", names_
);
108 if (e
!= RegError::NO_ERROR
) {
109 throw FileFormatException(
110 key_
.getRegistryName(),
111 ("legacy format: cannot get sub-key names of " + key_
.getName()
112 + ": " + OUString::number(static_cast<int>(e
))));
116 rtl::Reference
< Entity
> Cursor::getNext(OUString
* name
) {
117 assert(name
!= nullptr);
118 rtl::Reference
< Entity
> ent
;
119 if (index_
!= names_
.getLength()) {
120 OUString
path(names_
.getElement(index_
));
121 assert(path
.match(prefix_
));
122 *name
= path
.copy(prefix_
.getLength());
123 ent
= readEntity(manager_
, ucr_
, key_
, *name
, false);
130 class Module
: public ModuleEntity
{
133 rtl::Reference
< Manager
> manager
, RegistryKey
const & ucr
,
134 RegistryKey
const & key
):
135 manager_(std::move(manager
)), ucr_(ucr
), key_(key
)
139 virtual ~Module() noexcept override
{}
141 virtual std::vector
< OUString
> getMemberNames() const override
;
143 virtual rtl::Reference
< MapCursor
> createCursor() const override
144 { return new Cursor(manager_
, ucr_
, key_
); }
146 rtl::Reference
< Manager
> manager_
;
148 mutable RegistryKey key_
;
151 std::vector
< OUString
> Module::getMemberNames() const {
152 RegistryKeyNames names
;
153 RegError e
= key_
.getKeyNames("", names
);
154 if (e
!= RegError::NO_ERROR
) {
155 throw FileFormatException(
156 key_
.getRegistryName(),
157 ("legacy format: cannot get sub-key names of " + key_
.getName()
158 + ": " + OUString::number(static_cast<int>(e
))));
160 std::vector
< OUString
> ns
;
161 for (sal_uInt32 i
= 0; i
!= names
.getLength(); ++i
) {
162 ns
.push_back(names
.getElement(i
));
167 typereg::Reader
getReader(RegistryKey
& key
, std::vector
< char > * buffer
) {
168 assert(buffer
!= nullptr);
171 RegError e
= key
.getValueInfo("", &type
, &size
);
172 if (e
!= RegError::NO_ERROR
) {
173 throw FileFormatException(
174 key
.getRegistryName(),
175 ("legacy format: cannot get value info about key " + key
.getName()
176 + ": " + OUString::number(static_cast<int>(e
))));
178 if (type
!= RegValueType::BINARY
) {
179 throw FileFormatException(
180 key
.getRegistryName(),
181 ("legacy format: unexpected value type " + OUString::number(static_cast<int>(type
))
182 + " of key " + key
.getName()));
185 /*TODO: || size > std::numeric_limits< std::vector< char >::size_type >::max() */)
187 throw FileFormatException(
188 key
.getRegistryName(),
189 ("legacy format: bad binary value size " + OUString::number(size
)
190 + " of key " + key
.getName()));
192 buffer
->resize(static_cast< std::vector
< char >::size_type
>(size
));
193 e
= key
.getValue("", buffer
->data());
194 if (e
!= RegError::NO_ERROR
) {
195 throw FileFormatException(
196 key
.getRegistryName(),
197 ("legacy format: cannot get binary value of key " + key
.getName()
198 + ": " + OUString::number(static_cast<int>(e
))));
200 typereg::Reader
reader(buffer
->data(), size
);
201 if (!reader
.isValid()) {
202 throw FileFormatException(
203 key
.getRegistryName(),
204 "legacy format: malformed binary value of key " + key
.getName());
209 rtl::Reference
< Entity
> readEntity(
210 rtl::Reference
< Manager
> const & manager
, RegistryKey
& ucr
,
211 RegistryKey
& key
, OUString
const & path
, bool probe
)
213 assert(manager
.is());
215 RegError e
= key
.openKey(path
, sub
);
217 case RegError::NO_ERROR
:
219 case RegError::KEY_NOT_EXISTS
:
221 return rtl::Reference
< Entity
>();
225 throw FileFormatException(
226 key
.getRegistryName(),
227 ("legacy format: cannot open sub-key " + path
+ " of "
228 + key
.getName() + ": " + OUString::number(static_cast<int>(e
))));
230 std::vector
< char > buf
;
231 typereg::Reader
reader(getReader(sub
, &buf
));
232 switch (reader
.getTypeClass()) {
233 case RT_TYPE_INTERFACE
:
235 std::vector
< AnnotatedReference
> mandBases
;
236 sal_uInt16 n
= reader
.getSuperTypeCount();
237 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
238 mandBases
.emplace_back(
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
) {
245 optBases
.emplace_back(
246 reader
.getReferenceTypeName(j
).replace('/', '.'),
247 translateAnnotations(reader
.getReferenceDocumentation(j
)));
249 sal_uInt16 methodCount
= reader
.getMethodCount();
250 std::vector
< InterfaceTypeEntity::Attribute
> attrs
;
251 n
= reader
.getFieldCount(); // attributes
252 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
253 OUString
attrName(reader
.getFieldName(j
));
254 std::vector
< OUString
> getExcs
;
255 std::vector
< OUString
> setExcs
;
256 for (sal_uInt16 k
= 0; k
!= methodCount
; ++k
) {
257 if (reader
.getMethodName(k
) == attrName
) {
258 switch (reader
.getMethodFlags(k
)) {
259 case RTMethodMode::ATTRIBUTE_GET
:
262 = reader
.getMethodExceptionCount(k
);
263 // cid#1213376 unhelpfully warns about an
264 // untrusted loop bound here:
265 // coverity[tainted_data] - trusted data source
266 for (sal_uInt16 l
= 0; l
!= m
; ++l
) {
268 reader
.getMethodExceptionTypeName(k
, l
).
273 case RTMethodMode::ATTRIBUTE_SET
:
276 = reader
.getMethodExceptionCount(k
);
277 // cid#1213376 unhelpfully warns about an
278 // untrusted loop bound here:
279 // coverity[tainted_data] - trusted data source
280 for (sal_uInt16 l
= 0; l
!= m
; ++l
) {
282 reader
.getMethodExceptionTypeName(k
, l
).
288 throw FileFormatException(
289 key
.getRegistryName(),
290 ("legacy format: method and attribute with same"
292 + " in interface type with key "
297 RTFieldAccess flags
= reader
.getFieldFlags(j
);
299 attrName
, reader
.getFieldTypeName(j
).replace('/', '.'),
300 bool(flags
& RTFieldAccess::BOUND
),
301 bool(flags
& RTFieldAccess::READONLY
), std::move(getExcs
), std::move(setExcs
),
302 translateAnnotations(reader
.getFieldDocumentation(j
)));
304 std::vector
< InterfaceTypeEntity::Method
> meths
;
305 meths
.reserve(methodCount
);
306 for (sal_uInt16 j
= 0; j
!= methodCount
; ++j
) {
307 RTMethodMode flags
= reader
.getMethodFlags(j
);
308 if (flags
!= RTMethodMode::ATTRIBUTE_GET
309 && flags
!= RTMethodMode::ATTRIBUTE_SET
)
311 std::vector
< InterfaceTypeEntity::Method::Parameter
>
313 sal_uInt16 m
= reader
.getMethodParameterCount(j
);
314 // cid#1213376 unhelpfully warns about an untrusted loop
316 // coverity[tainted_data] - trusted data source
317 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
318 RTParamMode mode
= reader
.getMethodParameterFlags(j
, k
);
319 InterfaceTypeEntity::Method::Parameter::Direction dir
;
322 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
;
325 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT
;
328 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT
;
331 throw FileFormatException(
332 key
.getRegistryName(),
333 ("legacy format: unexpected mode "
334 + OUString::number(mode
) + " of parameter "
335 + reader
.getMethodParameterName(j
, k
)
336 + " of method " + reader
.getMethodName(j
)
337 + " in interface type with key "
341 reader
.getMethodParameterName(j
, k
),
342 (reader
.getMethodParameterTypeName(j
, k
).
346 std::vector
< OUString
> excs
;
347 m
= reader
.getMethodExceptionCount(j
);
348 // cid#1213376 unhelpfully warns about an untrusted loop
350 // coverity[tainted_data] - trusted data source
351 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
353 reader
.getMethodExceptionTypeName(j
, k
).replace(
357 reader
.getMethodName(j
),
358 reader
.getMethodReturnTypeName(j
).replace('/', '.'),
359 std::move(params
), std::move(excs
),
360 translateAnnotations(
361 reader
.getMethodDocumentation(j
)));
364 return new InterfaceTypeEntity(
365 reader
.isPublished(), std::move(mandBases
), std::move(optBases
), std::move(attrs
), std::move(meths
),
366 translateAnnotations(reader
.getDocumentation()));
369 return new Module(manager
, ucr
, sub
);
372 sal_uInt16 n
= reader
.getReferenceCount();
375 switch (reader
.getSuperTypeCount()) {
379 base
= reader
.getSuperTypeName(0).replace('/', '.');
382 throw FileFormatException(
383 key
.getRegistryName(),
384 ("legacy format: unexpected number "
385 + OUString::number(reader
.getSuperTypeCount())
386 + " of super-types of plain struct type with key "
389 std::vector
< PlainStructTypeEntity::Member
> mems
;
390 n
= reader
.getFieldCount();
391 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
393 reader
.getFieldName(j
),
394 reader
.getFieldTypeName(j
).replace('/', '.'),
395 translateAnnotations(reader
.getFieldDocumentation(j
)));
397 return new PlainStructTypeEntity(
398 reader
.isPublished(), base
, std::move(mems
),
399 translateAnnotations(reader
.getDocumentation()));
401 if (reader
.getSuperTypeCount() != 0) {
402 throw FileFormatException(
403 key
.getRegistryName(),
404 ("legacy format: unexpected number "
405 + OUString::number(reader
.getSuperTypeCount())
406 + " of super-types of polymorphic struct type template"
407 " with key " + sub
.getName()));
409 std::vector
< OUString
> params
;
410 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
412 reader
.getReferenceTypeName(j
).replace('/', '.'));
414 std::vector
< PolymorphicStructTypeTemplateEntity::Member
> mems
;
415 n
= reader
.getFieldCount();
416 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
418 reader
.getFieldName(j
),
419 reader
.getFieldTypeName(j
).replace('/', '.'),
421 reader
.getFieldFlags(j
)
422 & RTFieldAccess::PARAMETERIZED_TYPE
),
423 translateAnnotations(reader
.getFieldDocumentation(j
)));
425 return new PolymorphicStructTypeTemplateEntity(
426 reader
.isPublished(), std::move(params
), std::move(mems
),
427 translateAnnotations(reader
.getDocumentation()));
432 std::vector
< EnumTypeEntity::Member
> mems
;
433 sal_uInt16 n
= reader
.getFieldCount();
434 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
435 RTConstValue
v(reader
.getFieldValue(j
));
436 if (v
.m_type
!= RT_TYPE_INT32
) {
437 throw FileFormatException(
438 key
.getRegistryName(),
439 ("legacy format: unexpected type "
440 + OUString::number(v
.m_type
) + " of value of field "
441 + reader
.getFieldName(j
) + " of enum type with key "
445 reader
.getFieldName(j
), v
.m_value
.aLong
,
446 translateAnnotations(reader
.getFieldDocumentation(j
)));
449 return new EnumTypeEntity(
450 reader
.isPublished(), std::move(mems
),
451 translateAnnotations(reader
.getDocumentation()));
453 case RT_TYPE_EXCEPTION
:
456 switch (reader
.getSuperTypeCount()) {
460 base
= reader
.getSuperTypeName(0).replace('/', '.');
463 throw FileFormatException(
464 key
.getRegistryName(),
465 ("legacy format: unexpected number "
466 + OUString::number(reader
.getSuperTypeCount())
467 + " of super-types of exception type with key "
470 std::vector
< ExceptionTypeEntity::Member
> mems
;
471 sal_uInt16 n
= reader
.getFieldCount();
472 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
474 reader
.getFieldName(j
),
475 reader
.getFieldTypeName(j
).replace('/', '.'),
476 translateAnnotations(reader
.getFieldDocumentation(j
)));
478 return new ExceptionTypeEntity(
479 reader
.isPublished(), base
, std::move(mems
),
480 translateAnnotations(reader
.getDocumentation()));
482 case RT_TYPE_TYPEDEF
:
483 if (reader
.getSuperTypeCount() != 1) {
484 throw FileFormatException(
485 key
.getRegistryName(),
486 ("legacy format: unexpected number "
487 + OUString::number(reader
.getSuperTypeCount())
488 + " of super-types of typedef with key " + sub
.getName()));
490 return new TypedefEntity(
491 reader
.isPublished(), reader
.getSuperTypeName(0).replace('/', '.'),
492 translateAnnotations(reader
.getDocumentation()));
493 case RT_TYPE_SERVICE
:
494 switch (reader
.getSuperTypeCount()) {
497 std::vector
< AnnotatedReference
> mandServs
;
498 std::vector
< AnnotatedReference
> optServs
;
499 std::vector
< AnnotatedReference
> mandIfcs
;
500 std::vector
< AnnotatedReference
> optIfcs
;
501 sal_uInt16 n
= reader
.getReferenceCount();
502 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
503 AnnotatedReference base
{
504 reader
.getReferenceTypeName(j
).replace('/', '.'),
505 translateAnnotations(
506 reader
.getReferenceDocumentation(j
))};
507 switch (reader
.getReferenceSort(j
)) {
508 case RTReferenceType::EXPORTS
:
509 if (!(reader
.getReferenceFlags(j
) & RTFieldAccess::OPTIONAL
))
511 mandServs
.push_back(base
);
513 optServs
.push_back(base
);
516 case RTReferenceType::SUPPORTS
:
517 if (!(reader
.getReferenceFlags(j
) & RTFieldAccess::OPTIONAL
))
519 mandIfcs
.push_back(base
);
521 optIfcs
.push_back(base
);
525 throw FileFormatException(
526 key
.getRegistryName(),
527 ("legacy format: unexpected mode "
528 + OUString::number(static_cast<int>(reader
.getReferenceSort(j
)))
529 + " of reference " + reader
.getReferenceTypeName(j
)
530 + " in service with key " + sub
.getName()));
533 std::vector
< AccumulationBasedServiceEntity::Property
> props
;
534 n
= reader
.getFieldCount();
535 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
536 RTFieldAccess acc
= reader
.getFieldFlags(j
);
538 if (acc
& RTFieldAccess::READONLY
) {
539 attrs
|= AccumulationBasedServiceEntity::Property::
542 if (acc
& RTFieldAccess::OPTIONAL
) {
543 attrs
|= AccumulationBasedServiceEntity::Property::
546 if (acc
& RTFieldAccess::MAYBEVOID
) {
547 attrs
|= AccumulationBasedServiceEntity::Property::
548 ATTRIBUTE_MAYBE_VOID
;
550 if (acc
& RTFieldAccess::BOUND
) {
551 attrs
|= AccumulationBasedServiceEntity::Property::
554 if (acc
& RTFieldAccess::CONSTRAINED
) {
555 attrs
|= AccumulationBasedServiceEntity::Property::
556 ATTRIBUTE_CONSTRAINED
;
558 if (acc
& RTFieldAccess::TRANSIENT
) {
559 attrs
|= AccumulationBasedServiceEntity::Property::
562 if (acc
& RTFieldAccess::MAYBEAMBIGUOUS
) {
563 attrs
|= AccumulationBasedServiceEntity::Property::
564 ATTRIBUTE_MAYBE_AMBIGUOUS
;
566 if (acc
& RTFieldAccess::MAYBEDEFAULT
) {
567 attrs
|= AccumulationBasedServiceEntity::Property::
568 ATTRIBUTE_MAYBE_DEFAULT
;
570 if (acc
& RTFieldAccess::REMOVABLE
) {
571 attrs
|= AccumulationBasedServiceEntity::Property::
575 reader
.getFieldName(j
),
576 reader
.getFieldTypeName(j
).replace('/', '.'),
578 AccumulationBasedServiceEntity::Property::
580 translateAnnotations(reader
.getFieldDocumentation(j
)));
582 return new AccumulationBasedServiceEntity(
583 reader
.isPublished(), std::move(mandServs
), std::move(optServs
), std::move(mandIfcs
),
584 std::move(optIfcs
), std::move(props
),
585 translateAnnotations(reader
.getDocumentation()));
589 std::vector
< SingleInterfaceBasedServiceEntity::Constructor
>
591 sal_uInt16 n
= reader
.getMethodCount();
592 if (n
== 1 && reader
.getMethodFlags(0) == RTMethodMode::TWOWAY
593 && reader
.getMethodName(0).isEmpty()
594 && reader
.getMethodReturnTypeName(0) == "void"
595 && reader
.getMethodParameterCount(0) == 0
596 && reader
.getMethodExceptionCount(0) == 0)
599 SingleInterfaceBasedServiceEntity::Constructor());
601 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
602 if (reader
.getMethodFlags(j
) != RTMethodMode::TWOWAY
) {
603 throw FileFormatException(
604 key
.getRegistryName(),
605 ("legacy format: unexpected mode "
606 + OUString::number(static_cast<int>(reader
.getMethodFlags(j
)))
607 + " of constructor " + reader
.getMethodName(j
)
608 + " in service with key " + sub
.getName()));
611 SingleInterfaceBasedServiceEntity::Constructor::
613 sal_uInt16 m
= reader
.getMethodParameterCount(j
);
614 // cid#1213376 unhelpfully warns about an untrusted
616 // coverity[tainted_data] - trusted data source
617 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
619 = reader
.getMethodParameterFlags(j
, k
);
620 if ((mode
& ~RT_PARAM_REST
) != RT_PARAM_IN
) {
621 throw FileFormatException(
622 key
.getRegistryName(),
623 ("legacy format: unexpected mode "
624 + OUString::number(mode
)
626 + reader
.getMethodParameterName(j
, k
)
628 + reader
.getMethodName(j
)
629 + " in service with key "
632 if ((mode
& RT_PARAM_REST
) != 0
634 || ((reader
.getMethodParameterTypeName(
638 throw FileFormatException(
639 key
.getRegistryName(),
640 ("legacy format: bad rest parameter "
641 + reader
.getMethodParameterName(j
, k
)
643 + reader
.getMethodName(j
)
644 + " in service with key "
648 reader
.getMethodParameterName(j
, k
),
649 (reader
.getMethodParameterTypeName(j
, k
).
651 (mode
& RT_PARAM_REST
) != 0);
653 std::vector
< OUString
> excs
;
654 m
= reader
.getMethodExceptionCount(j
);
655 // cid#1213376 unhelpfully warns about an untrusted
657 // coverity[tainted_data] - trusted data source
658 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
660 reader
.getMethodExceptionTypeName(j
, k
).replace(
664 SingleInterfaceBasedServiceEntity::Constructor(
665 reader
.getMethodName(j
), std::move(params
), std::move(excs
),
666 translateAnnotations(
667 reader
.getMethodDocumentation(j
))));
670 return new SingleInterfaceBasedServiceEntity(
671 reader
.isPublished(),
672 reader
.getSuperTypeName(0).replace('/', '.'), std::move(ctors
),
673 translateAnnotations(reader
.getDocumentation()));
676 throw FileFormatException(
677 key
.getRegistryName(),
678 ("legacy format: unexpected number "
679 + OUString::number(reader
.getSuperTypeCount())
680 + " of super-types of service with key " + sub
.getName()));
682 case RT_TYPE_SINGLETON
:
684 if (reader
.getSuperTypeCount() != 1) {
685 throw FileFormatException(
686 key
.getRegistryName(),
687 ("legacy format: unexpected number "
688 + OUString::number(reader
.getSuperTypeCount())
689 + " of super-types of singleton with key "
692 OUString
basePath(reader
.getSuperTypeName(0));
693 OUString
baseName(basePath
.replace('/', '.'));
695 rtl::Reference
< Entity
> base(manager
->findEntity(baseName
));
697 switch (base
->getSort()) {
698 case Entity::SORT_INTERFACE_TYPE
:
701 case Entity::SORT_ACCUMULATION_BASED_SERVICE
:
705 throw FileFormatException(
706 key
.getRegistryName(),
707 ("legacy format: unexpected sort "
708 + OUString::number(base
->getSort()) + " of base "
709 + baseName
+ " of singleton with key "
714 e
= ucr
.openKey(basePath
, key2
);
716 case RegError::NO_ERROR
:
718 case RegError::KEY_NOT_EXISTS
:
719 throw FileFormatException(
720 key
.getRegistryName(),
721 ("legacy format: unknown super-type " + basePath
722 + " of super-type with key " + sub
.getName()));
724 throw FileFormatException(
725 key
.getRegistryName(),
726 ("legacy format: cannot open ucr sub-key " + basePath
727 + ": " + OUString::number(static_cast<int>(e
))));
729 std::vector
< char > buf2
;
730 typereg::Reader
reader2(getReader(key2
, &buf2
));
731 switch (reader2
.getTypeClass()) {
732 case RT_TYPE_INTERFACE
:
735 case RT_TYPE_SERVICE
:
739 throw FileFormatException(
740 key
.getRegistryName(),
741 ("legacy format: unexpected type class "
742 + OUString::number(reader2
.getTypeClass())
743 + " of super-type with key " + key2
.getName()
744 + " of singleton with key " + sub
.getName()));
748 ? rtl::Reference
< Entity
>(
749 new InterfaceBasedSingletonEntity(
750 reader
.isPublished(), baseName
,
751 translateAnnotations(reader
.getDocumentation())))
752 : rtl::Reference
< Entity
>(
753 new ServiceBasedSingletonEntity(
754 reader
.isPublished(), baseName
,
755 translateAnnotations(reader
.getDocumentation())));
757 case RT_TYPE_CONSTANTS
:
759 std::vector
< ConstantGroupEntity::Member
> mems
;
760 sal_uInt16 n
= reader
.getFieldCount();
761 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
763 reader
.getFieldName(j
),
764 translateConstantValue(sub
, reader
.getFieldValue(j
)),
765 translateAnnotations(reader
.getFieldDocumentation(j
)));
767 return new ConstantGroupEntity(
768 reader
.isPublished(), std::move(mems
),
769 translateAnnotations(reader
.getDocumentation()));
772 throw FileFormatException(
773 key
.getRegistryName(),
774 ("legacy format: unexpected type class "
775 + OUString::number(reader
.getTypeClass()) + " of key "
782 LegacyProvider::LegacyProvider(Manager
& manager
, OUString
const & uri
):
786 RegError e
= reg
.open(uri
, RegAccessMode::READONLY
);
788 case RegError::NO_ERROR
:
790 case RegError::REGISTRY_NOT_EXISTS
:
791 throw NoSuchFileException(uri
);
793 throw FileFormatException(
794 uri
, "cannot open legacy file: " + OUString::number(static_cast<int>(e
)));
797 e
= reg
.openRootKey(root
);
798 if (e
!= RegError::NO_ERROR
) {
799 throw FileFormatException(
800 uri
, "legacy format: cannot open root key: " + OUString::number(static_cast<int>(e
)));
802 e
= root
.openKey("UCR", ucr_
);
804 case RegError::NO_ERROR
:
805 case RegError::KEY_NOT_EXISTS
: // such effectively empty files exist in the wild
808 throw FileFormatException(
809 uri
, "legacy format: cannot open UCR key: " + OUString::number(static_cast<int>(e
)));
813 rtl::Reference
< MapCursor
> LegacyProvider::createRootCursor() const {
814 return new Cursor(&manager_
, ucr_
, ucr_
);
817 rtl::Reference
< Entity
> LegacyProvider::findEntity(OUString
const & name
)
820 return ucr_
.isValid()
821 ? readEntity(&manager_
, ucr_
, ucr_
, name
.replace('.', '/'), true)
822 : rtl::Reference
< Entity
>();
825 LegacyProvider::~LegacyProvider() noexcept
{}
829 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */