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::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() noexcept 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)
102 prefix_
= key_
.getName();
103 if (!prefix_
.endsWith("/")) {
106 RegError e
= key_
.getKeyNames("", names_
);
107 if (e
!= RegError::NO_ERROR
) {
108 throw FileFormatException(
109 key_
.getRegistryName(),
110 ("legacy format: cannot get sub-key names of " + key_
.getName()
111 + ": " + OUString::number(static_cast<int>(e
))));
115 rtl::Reference
< Entity
> Cursor::getNext(OUString
* name
) {
116 assert(name
!= nullptr);
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() noexcept override
{}
140 virtual std::vector
< OUString
> getMemberNames() const override
;
142 virtual rtl::Reference
< MapCursor
> createCursor() const 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
) {
167 assert(buffer
!= nullptr);
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
->data());
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
->data(), size
);
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
) {
237 mandBases
.emplace_back(
238 reader
.getSuperTypeName(j
).replace('/', '.'),
239 std::vector
< OUString
>());
241 std::vector
< AnnotatedReference
> optBases
;
242 n
= reader
.getReferenceCount();
243 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
244 optBases
.emplace_back(
245 reader
.getReferenceTypeName(j
).replace('/', '.'),
246 translateAnnotations(reader
.getReferenceDocumentation(j
)));
248 sal_uInt16 methodCount
= reader
.getMethodCount();
249 std::vector
< InterfaceTypeEntity::Attribute
> attrs
;
250 n
= reader
.getFieldCount(); // attributes
251 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
252 OUString
attrName(reader
.getFieldName(j
));
253 std::vector
< OUString
> getExcs
;
254 std::vector
< OUString
> setExcs
;
255 for (sal_uInt16 k
= 0; k
!= methodCount
; ++k
) {
256 if (reader
.getMethodName(k
) == attrName
) {
257 switch (reader
.getMethodFlags(k
)) {
258 case RTMethodMode::ATTRIBUTE_GET
:
261 = reader
.getMethodExceptionCount(k
);
262 // cid#1213376 unhelpfully warns about an
263 // untrusted loop bound here:
264 // coverity[tainted_data] - trusted data source
265 for (sal_uInt16 l
= 0; l
!= m
; ++l
) {
267 reader
.getMethodExceptionTypeName(k
, l
).
272 case RTMethodMode::ATTRIBUTE_SET
:
275 = reader
.getMethodExceptionCount(k
);
276 // cid#1213376 unhelpfully warns about an
277 // untrusted loop bound here:
278 // coverity[tainted_data] - trusted data source
279 for (sal_uInt16 l
= 0; l
!= m
; ++l
) {
281 reader
.getMethodExceptionTypeName(k
, l
).
287 throw FileFormatException(
288 key
.getRegistryName(),
289 ("legacy format: method and attribute with same"
291 + " in interface type with key "
296 RTFieldAccess flags
= reader
.getFieldFlags(j
);
298 attrName
, reader
.getFieldTypeName(j
).replace('/', '.'),
299 bool(flags
& RTFieldAccess::BOUND
),
300 bool(flags
& RTFieldAccess::READONLY
), std::move(getExcs
), std::move(setExcs
),
301 translateAnnotations(reader
.getFieldDocumentation(j
)));
303 std::vector
< InterfaceTypeEntity::Method
> meths
;
304 meths
.reserve(methodCount
);
305 for (sal_uInt16 j
= 0; j
!= methodCount
; ++j
) {
306 RTMethodMode flags
= reader
.getMethodFlags(j
);
307 if (flags
!= RTMethodMode::ATTRIBUTE_GET
308 && flags
!= RTMethodMode::ATTRIBUTE_SET
)
310 std::vector
< InterfaceTypeEntity::Method::Parameter
>
312 sal_uInt16 m
= reader
.getMethodParameterCount(j
);
313 // cid#1213376 unhelpfully warns about an untrusted loop
315 // coverity[tainted_data] - trusted data source
316 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
317 RTParamMode mode
= reader
.getMethodParameterFlags(j
, k
);
318 InterfaceTypeEntity::Method::Parameter::Direction dir
;
321 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
;
324 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT
;
327 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT
;
330 throw FileFormatException(
331 key
.getRegistryName(),
332 ("legacy format: unexpected mode "
333 + OUString::number(mode
) + " of parameter "
334 + reader
.getMethodParameterName(j
, k
)
335 + " of method " + reader
.getMethodName(j
)
336 + " in interface type with key "
340 reader
.getMethodParameterName(j
, k
),
341 (reader
.getMethodParameterTypeName(j
, k
).
345 std::vector
< OUString
> excs
;
346 m
= reader
.getMethodExceptionCount(j
);
347 // cid#1213376 unhelpfully warns about an untrusted loop
349 // coverity[tainted_data] - trusted data source
350 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
352 reader
.getMethodExceptionTypeName(j
, k
).replace(
356 reader
.getMethodName(j
),
357 reader
.getMethodReturnTypeName(j
).replace('/', '.'),
358 std::move(params
), std::move(excs
),
359 translateAnnotations(
360 reader
.getMethodDocumentation(j
)));
363 return new InterfaceTypeEntity(
364 reader
.isPublished(), std::move(mandBases
), std::move(optBases
), std::move(attrs
), std::move(meths
),
365 translateAnnotations(reader
.getDocumentation()));
368 return new Module(manager
, ucr
, sub
);
371 sal_uInt16 n
= reader
.getReferenceCount();
374 switch (reader
.getSuperTypeCount()) {
378 base
= reader
.getSuperTypeName(0).replace('/', '.');
381 throw FileFormatException(
382 key
.getRegistryName(),
383 ("legacy format: unexpected number "
384 + OUString::number(reader
.getSuperTypeCount())
385 + " of super-types of plain struct type with key "
388 std::vector
< PlainStructTypeEntity::Member
> mems
;
389 n
= reader
.getFieldCount();
390 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
392 reader
.getFieldName(j
),
393 reader
.getFieldTypeName(j
).replace('/', '.'),
394 translateAnnotations(reader
.getFieldDocumentation(j
)));
396 return new PlainStructTypeEntity(
397 reader
.isPublished(), base
, std::move(mems
),
398 translateAnnotations(reader
.getDocumentation()));
400 if (reader
.getSuperTypeCount() != 0) {
401 throw FileFormatException(
402 key
.getRegistryName(),
403 ("legacy format: unexpected number "
404 + OUString::number(reader
.getSuperTypeCount())
405 + " of super-types of polymorphic struct type template"
406 " with key " + sub
.getName()));
408 std::vector
< OUString
> params
;
409 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
411 reader
.getReferenceTypeName(j
).replace('/', '.'));
413 std::vector
< PolymorphicStructTypeTemplateEntity::Member
> mems
;
414 n
= reader
.getFieldCount();
415 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
417 reader
.getFieldName(j
),
418 reader
.getFieldTypeName(j
).replace('/', '.'),
420 reader
.getFieldFlags(j
)
421 & RTFieldAccess::PARAMETERIZED_TYPE
),
422 translateAnnotations(reader
.getFieldDocumentation(j
)));
424 return new PolymorphicStructTypeTemplateEntity(
425 reader
.isPublished(), std::move(params
), std::move(mems
),
426 translateAnnotations(reader
.getDocumentation()));
431 std::vector
< EnumTypeEntity::Member
> mems
;
432 sal_uInt16 n
= reader
.getFieldCount();
433 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
434 RTConstValue
v(reader
.getFieldValue(j
));
435 if (v
.m_type
!= RT_TYPE_INT32
) {
436 throw FileFormatException(
437 key
.getRegistryName(),
438 ("legacy format: unexpected type "
439 + OUString::number(v
.m_type
) + " of value of field "
440 + reader
.getFieldName(j
) + " of enum type with key "
444 reader
.getFieldName(j
), v
.m_value
.aLong
,
445 translateAnnotations(reader
.getFieldDocumentation(j
)));
448 return new EnumTypeEntity(
449 reader
.isPublished(), std::move(mems
),
450 translateAnnotations(reader
.getDocumentation()));
452 case RT_TYPE_EXCEPTION
:
455 switch (reader
.getSuperTypeCount()) {
459 base
= reader
.getSuperTypeName(0).replace('/', '.');
462 throw FileFormatException(
463 key
.getRegistryName(),
464 ("legacy format: unexpected number "
465 + OUString::number(reader
.getSuperTypeCount())
466 + " of super-types of exception type with key "
469 std::vector
< ExceptionTypeEntity::Member
> mems
;
470 sal_uInt16 n
= reader
.getFieldCount();
471 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
473 reader
.getFieldName(j
),
474 reader
.getFieldTypeName(j
).replace('/', '.'),
475 translateAnnotations(reader
.getFieldDocumentation(j
)));
477 return new ExceptionTypeEntity(
478 reader
.isPublished(), base
, std::move(mems
),
479 translateAnnotations(reader
.getDocumentation()));
481 case RT_TYPE_TYPEDEF
:
482 if (reader
.getSuperTypeCount() != 1) {
483 throw FileFormatException(
484 key
.getRegistryName(),
485 ("legacy format: unexpected number "
486 + OUString::number(reader
.getSuperTypeCount())
487 + " of super-types of typedef with key " + sub
.getName()));
489 return new TypedefEntity(
490 reader
.isPublished(), reader
.getSuperTypeName(0).replace('/', '.'),
491 translateAnnotations(reader
.getDocumentation()));
492 case RT_TYPE_SERVICE
:
493 switch (reader
.getSuperTypeCount()) {
496 std::vector
< AnnotatedReference
> mandServs
;
497 std::vector
< AnnotatedReference
> optServs
;
498 std::vector
< AnnotatedReference
> mandIfcs
;
499 std::vector
< AnnotatedReference
> optIfcs
;
500 sal_uInt16 n
= reader
.getReferenceCount();
501 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
502 AnnotatedReference base
{
503 reader
.getReferenceTypeName(j
).replace('/', '.'),
504 translateAnnotations(
505 reader
.getReferenceDocumentation(j
))};
506 switch (reader
.getReferenceSort(j
)) {
507 case RTReferenceType::EXPORTS
:
508 if (!(reader
.getReferenceFlags(j
) & RTFieldAccess::OPTIONAL
))
510 mandServs
.push_back(base
);
512 optServs
.push_back(base
);
515 case RTReferenceType::SUPPORTS
:
516 if (!(reader
.getReferenceFlags(j
) & RTFieldAccess::OPTIONAL
))
518 mandIfcs
.push_back(base
);
520 optIfcs
.push_back(base
);
524 throw FileFormatException(
525 key
.getRegistryName(),
526 ("legacy format: unexpected mode "
527 + OUString::number(static_cast<int>(reader
.getReferenceSort(j
)))
528 + " of reference " + reader
.getReferenceTypeName(j
)
529 + " in service with key " + sub
.getName()));
532 std::vector
< AccumulationBasedServiceEntity::Property
> props
;
533 n
= reader
.getFieldCount();
534 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
535 RTFieldAccess acc
= reader
.getFieldFlags(j
);
537 if (acc
& RTFieldAccess::READONLY
) {
538 attrs
|= AccumulationBasedServiceEntity::Property::
541 if (acc
& RTFieldAccess::OPTIONAL
) {
542 attrs
|= AccumulationBasedServiceEntity::Property::
545 if (acc
& RTFieldAccess::MAYBEVOID
) {
546 attrs
|= AccumulationBasedServiceEntity::Property::
547 ATTRIBUTE_MAYBE_VOID
;
549 if (acc
& RTFieldAccess::BOUND
) {
550 attrs
|= AccumulationBasedServiceEntity::Property::
553 if (acc
& RTFieldAccess::CONSTRAINED
) {
554 attrs
|= AccumulationBasedServiceEntity::Property::
555 ATTRIBUTE_CONSTRAINED
;
557 if (acc
& RTFieldAccess::TRANSIENT
) {
558 attrs
|= AccumulationBasedServiceEntity::Property::
561 if (acc
& RTFieldAccess::MAYBEAMBIGUOUS
) {
562 attrs
|= AccumulationBasedServiceEntity::Property::
563 ATTRIBUTE_MAYBE_AMBIGUOUS
;
565 if (acc
& RTFieldAccess::MAYBEDEFAULT
) {
566 attrs
|= AccumulationBasedServiceEntity::Property::
567 ATTRIBUTE_MAYBE_DEFAULT
;
569 if (acc
& RTFieldAccess::REMOVABLE
) {
570 attrs
|= AccumulationBasedServiceEntity::Property::
574 reader
.getFieldName(j
),
575 reader
.getFieldTypeName(j
).replace('/', '.'),
577 AccumulationBasedServiceEntity::Property::
579 translateAnnotations(reader
.getFieldDocumentation(j
)));
581 return new AccumulationBasedServiceEntity(
582 reader
.isPublished(), std::move(mandServs
), std::move(optServs
), std::move(mandIfcs
),
583 std::move(optIfcs
), std::move(props
),
584 translateAnnotations(reader
.getDocumentation()));
588 std::vector
< SingleInterfaceBasedServiceEntity::Constructor
>
590 sal_uInt16 n
= reader
.getMethodCount();
591 if (n
== 1 && reader
.getMethodFlags(0) == RTMethodMode::TWOWAY
592 && reader
.getMethodName(0).isEmpty()
593 && reader
.getMethodReturnTypeName(0) == "void"
594 && reader
.getMethodParameterCount(0) == 0
595 && reader
.getMethodExceptionCount(0) == 0)
598 SingleInterfaceBasedServiceEntity::Constructor());
600 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
601 if (reader
.getMethodFlags(j
) != RTMethodMode::TWOWAY
) {
602 throw FileFormatException(
603 key
.getRegistryName(),
604 ("legacy format: unexpected mode "
605 + OUString::number(static_cast<int>(reader
.getMethodFlags(j
)))
606 + " of constructor " + reader
.getMethodName(j
)
607 + " in service with key " + sub
.getName()));
610 SingleInterfaceBasedServiceEntity::Constructor::
612 sal_uInt16 m
= reader
.getMethodParameterCount(j
);
613 // cid#1213376 unhelpfully warns about an untrusted
615 // coverity[tainted_data] - trusted data source
616 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
618 = reader
.getMethodParameterFlags(j
, k
);
619 if ((mode
& ~RT_PARAM_REST
) != RT_PARAM_IN
) {
620 throw FileFormatException(
621 key
.getRegistryName(),
622 ("legacy format: unexpected mode "
623 + OUString::number(mode
)
625 + reader
.getMethodParameterName(j
, k
)
627 + reader
.getMethodName(j
)
628 + " in service with key "
631 if ((mode
& RT_PARAM_REST
) != 0
633 || ((reader
.getMethodParameterTypeName(
637 throw FileFormatException(
638 key
.getRegistryName(),
639 ("legacy format: bad rest parameter "
640 + reader
.getMethodParameterName(j
, k
)
642 + reader
.getMethodName(j
)
643 + " in service with key "
647 reader
.getMethodParameterName(j
, k
),
648 (reader
.getMethodParameterTypeName(j
, k
).
650 (mode
& RT_PARAM_REST
) != 0);
652 std::vector
< OUString
> excs
;
653 m
= reader
.getMethodExceptionCount(j
);
654 // cid#1213376 unhelpfully warns about an untrusted
656 // coverity[tainted_data] - trusted data source
657 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
659 reader
.getMethodExceptionTypeName(j
, k
).replace(
663 SingleInterfaceBasedServiceEntity::Constructor(
664 reader
.getMethodName(j
), std::move(params
), std::move(excs
),
665 translateAnnotations(
666 reader
.getMethodDocumentation(j
))));
669 return new SingleInterfaceBasedServiceEntity(
670 reader
.isPublished(),
671 reader
.getSuperTypeName(0).replace('/', '.'), std::move(ctors
),
672 translateAnnotations(reader
.getDocumentation()));
675 throw FileFormatException(
676 key
.getRegistryName(),
677 ("legacy format: unexpected number "
678 + OUString::number(reader
.getSuperTypeCount())
679 + " of super-types of service with key " + sub
.getName()));
681 case RT_TYPE_SINGLETON
:
683 if (reader
.getSuperTypeCount() != 1) {
684 throw FileFormatException(
685 key
.getRegistryName(),
686 ("legacy format: unexpected number "
687 + OUString::number(reader
.getSuperTypeCount())
688 + " of super-types of singleton with key "
691 OUString
basePath(reader
.getSuperTypeName(0));
692 OUString
baseName(basePath
.replace('/', '.'));
694 rtl::Reference
< Entity
> base(manager
->findEntity(baseName
));
696 switch (base
->getSort()) {
697 case Entity::SORT_INTERFACE_TYPE
:
700 case Entity::SORT_ACCUMULATION_BASED_SERVICE
:
704 throw FileFormatException(
705 key
.getRegistryName(),
706 ("legacy format: unexpected sort "
707 + OUString::number(base
->getSort()) + " of base "
708 + baseName
+ " of singleton with key "
713 e
= ucr
.openKey(basePath
, key2
);
715 case RegError::NO_ERROR
:
717 case RegError::KEY_NOT_EXISTS
:
718 throw FileFormatException(
719 key
.getRegistryName(),
720 ("legacy format: unknown super-type " + basePath
721 + " of super-type with key " + sub
.getName()));
723 throw FileFormatException(
724 key
.getRegistryName(),
725 ("legacy format: cannot open ucr sub-key " + basePath
726 + ": " + OUString::number(static_cast<int>(e
))));
728 std::vector
< char > buf2
;
729 typereg::Reader
reader2(getReader(key2
, &buf2
));
730 switch (reader2
.getTypeClass()) {
731 case RT_TYPE_INTERFACE
:
734 case RT_TYPE_SERVICE
:
738 throw FileFormatException(
739 key
.getRegistryName(),
740 ("legacy format: unexpected type class "
741 + OUString::number(reader2
.getTypeClass())
742 + " of super-type with key " + key2
.getName()
743 + " of singleton with key " + sub
.getName()));
747 ? rtl::Reference
< Entity
>(
748 new InterfaceBasedSingletonEntity(
749 reader
.isPublished(), baseName
,
750 translateAnnotations(reader
.getDocumentation())))
751 : rtl::Reference
< Entity
>(
752 new ServiceBasedSingletonEntity(
753 reader
.isPublished(), baseName
,
754 translateAnnotations(reader
.getDocumentation())));
756 case RT_TYPE_CONSTANTS
:
758 std::vector
< ConstantGroupEntity::Member
> mems
;
759 sal_uInt16 n
= reader
.getFieldCount();
760 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
762 reader
.getFieldName(j
),
763 translateConstantValue(sub
, reader
.getFieldValue(j
)),
764 translateAnnotations(reader
.getFieldDocumentation(j
)));
766 return new ConstantGroupEntity(
767 reader
.isPublished(), std::move(mems
),
768 translateAnnotations(reader
.getDocumentation()));
771 throw FileFormatException(
772 key
.getRegistryName(),
773 ("legacy format: unexpected type class "
774 + OUString::number(reader
.getTypeClass()) + " of key "
781 LegacyProvider::LegacyProvider(Manager
& manager
, OUString
const & uri
):
785 RegError e
= reg
.open(uri
, RegAccessMode::READONLY
);
787 case RegError::NO_ERROR
:
789 case RegError::REGISTRY_NOT_EXISTS
:
790 throw NoSuchFileException(uri
);
792 throw FileFormatException(
793 uri
, "cannot open legacy file: " + OUString::number(static_cast<int>(e
)));
796 e
= reg
.openRootKey(root
);
797 if (e
!= RegError::NO_ERROR
) {
798 throw FileFormatException(
799 uri
, "legacy format: cannot open root key: " + OUString::number(static_cast<int>(e
)));
801 e
= root
.openKey("UCR", ucr_
);
803 case RegError::NO_ERROR
:
804 case RegError::KEY_NOT_EXISTS
: // such effectively empty files exist in the wild
807 throw FileFormatException(
808 uri
, "legacy format: cannot open UCR key: " + OUString::number(static_cast<int>(e
)));
812 rtl::Reference
< MapCursor
> LegacyProvider::createRootCursor() const {
813 return new Cursor(&manager_
, ucr_
, ucr_
);
816 rtl::Reference
< Entity
> LegacyProvider::findEntity(OUString
const & name
)
819 return ucr_
.isValid()
820 ? readEntity(&manager_
, ucr_
, ucr_
, name
.replace('.', '/'), true)
821 : rtl::Reference
< Entity
>();
824 LegacyProvider::~LegacyProvider() noexcept
{}
828 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */