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 meths
.reserve(methodCount
);
304 for (sal_uInt16 j
= 0; j
!= methodCount
; ++j
) {
305 RTMethodMode flags
= reader
.getMethodFlags(j
);
306 if (flags
!= RTMethodMode::ATTRIBUTE_GET
307 && flags
!= RTMethodMode::ATTRIBUTE_SET
)
309 std::vector
< InterfaceTypeEntity::Method::Parameter
>
311 sal_uInt16 m
= reader
.getMethodParameterCount(j
);
312 // cid#1213376 unhelpfully warns about an untrusted loop
314 // coverity[tainted_data] - trusted data source
315 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
316 RTParamMode mode
= reader
.getMethodParameterFlags(j
, k
);
317 InterfaceTypeEntity::Method::Parameter::Direction dir
;
320 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
;
323 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT
;
326 dir
= InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT
;
329 throw FileFormatException(
330 key
.getRegistryName(),
331 ("legacy format: unexpected mode "
332 + OUString::number(mode
) + " of parameter "
333 + reader
.getMethodParameterName(j
, k
)
334 + " of method " + reader
.getMethodName(j
)
335 + " in interface type with key "
339 reader
.getMethodParameterName(j
, k
),
340 (reader
.getMethodParameterTypeName(j
, k
).
344 std::vector
< OUString
> excs
;
345 m
= reader
.getMethodExceptionCount(j
);
346 // cid#1213376 unhelpfully warns about an untrusted loop
348 // coverity[tainted_data] - trusted data source
349 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
351 reader
.getMethodExceptionTypeName(j
, k
).replace(
355 reader
.getMethodName(j
),
356 reader
.getMethodReturnTypeName(j
).replace('/', '.'),
358 translateAnnotations(
359 reader
.getMethodDocumentation(j
)));
362 return new InterfaceTypeEntity(
363 reader
.isPublished(), mandBases
, optBases
, attrs
, meths
,
364 translateAnnotations(reader
.getDocumentation()));
367 return new Module(manager
, ucr
, sub
);
370 sal_uInt16 n
= reader
.getReferenceCount();
373 switch (reader
.getSuperTypeCount()) {
377 base
= reader
.getSuperTypeName(0).replace('/', '.');
380 throw FileFormatException(
381 key
.getRegistryName(),
382 ("legacy format: unexpected number "
383 + OUString::number(reader
.getSuperTypeCount())
384 + " of super-types of plain struct type with key "
387 std::vector
< PlainStructTypeEntity::Member
> mems
;
388 n
= reader
.getFieldCount();
389 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
391 reader
.getFieldName(j
),
392 reader
.getFieldTypeName(j
).replace('/', '.'),
393 translateAnnotations(reader
.getFieldDocumentation(j
)));
395 return new PlainStructTypeEntity(
396 reader
.isPublished(), base
, mems
,
397 translateAnnotations(reader
.getDocumentation()));
399 if (reader
.getSuperTypeCount() != 0) {
400 throw FileFormatException(
401 key
.getRegistryName(),
402 ("legacy format: unexpected number "
403 + OUString::number(reader
.getSuperTypeCount())
404 + " of super-types of polymorphic struct type template"
405 " with key " + sub
.getName()));
407 std::vector
< OUString
> params
;
408 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
410 reader
.getReferenceTypeName(j
).replace('/', '.'));
412 std::vector
< PolymorphicStructTypeTemplateEntity::Member
> mems
;
413 n
= reader
.getFieldCount();
414 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
416 reader
.getFieldName(j
),
417 reader
.getFieldTypeName(j
).replace('/', '.'),
419 reader
.getFieldFlags(j
)
420 & RTFieldAccess::PARAMETERIZED_TYPE
),
421 translateAnnotations(reader
.getFieldDocumentation(j
)));
423 return new PolymorphicStructTypeTemplateEntity(
424 reader
.isPublished(), params
, mems
,
425 translateAnnotations(reader
.getDocumentation()));
430 std::vector
< EnumTypeEntity::Member
> mems
;
431 sal_uInt16 n
= reader
.getFieldCount();
432 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
433 RTConstValue
v(reader
.getFieldValue(j
));
434 if (v
.m_type
!= RT_TYPE_INT32
) {
435 throw FileFormatException(
436 key
.getRegistryName(),
437 ("legacy format: unexpected type "
438 + OUString::number(v
.m_type
) + " of value of field "
439 + reader
.getFieldName(j
) + " of enum type with key "
443 reader
.getFieldName(j
), v
.m_value
.aLong
,
444 translateAnnotations(reader
.getFieldDocumentation(j
)));
447 return new EnumTypeEntity(
448 reader
.isPublished(), mems
,
449 translateAnnotations(reader
.getDocumentation()));
451 case RT_TYPE_EXCEPTION
:
454 switch (reader
.getSuperTypeCount()) {
458 base
= reader
.getSuperTypeName(0).replace('/', '.');
461 throw FileFormatException(
462 key
.getRegistryName(),
463 ("legacy format: unexpected number "
464 + OUString::number(reader
.getSuperTypeCount())
465 + " of super-types of exception type with key "
468 std::vector
< ExceptionTypeEntity::Member
> mems
;
469 sal_uInt16 n
= reader
.getFieldCount();
470 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
472 reader
.getFieldName(j
),
473 reader
.getFieldTypeName(j
).replace('/', '.'),
474 translateAnnotations(reader
.getFieldDocumentation(j
)));
476 return new ExceptionTypeEntity(
477 reader
.isPublished(), base
, mems
,
478 translateAnnotations(reader
.getDocumentation()));
480 case RT_TYPE_TYPEDEF
:
481 if (reader
.getSuperTypeCount() != 1) {
482 throw FileFormatException(
483 key
.getRegistryName(),
484 ("legacy format: unexpected number "
485 + OUString::number(reader
.getSuperTypeCount())
486 + " of super-types of typedef with key " + sub
.getName()));
488 return new TypedefEntity(
489 reader
.isPublished(), reader
.getSuperTypeName(0).replace('/', '.'),
490 translateAnnotations(reader
.getDocumentation()));
491 case RT_TYPE_SERVICE
:
492 switch (reader
.getSuperTypeCount()) {
495 std::vector
< AnnotatedReference
> mandServs
;
496 std::vector
< AnnotatedReference
> optServs
;
497 std::vector
< AnnotatedReference
> mandIfcs
;
498 std::vector
< AnnotatedReference
> optIfcs
;
499 sal_uInt16 n
= reader
.getReferenceCount();
500 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
501 AnnotatedReference base
{
502 reader
.getReferenceTypeName(j
).replace('/', '.'),
503 translateAnnotations(
504 reader
.getReferenceDocumentation(j
))};
505 switch (reader
.getReferenceSort(j
)) {
506 case RTReferenceType::EXPORTS
:
507 if (!(reader
.getReferenceFlags(j
) & RTFieldAccess::OPTIONAL
))
509 mandServs
.push_back(base
);
511 optServs
.push_back(base
);
514 case RTReferenceType::SUPPORTS
:
515 if (!(reader
.getReferenceFlags(j
) & RTFieldAccess::OPTIONAL
))
517 mandIfcs
.push_back(base
);
519 optIfcs
.push_back(base
);
523 throw FileFormatException(
524 key
.getRegistryName(),
525 ("legacy format: unexpected mode "
526 + OUString::number(static_cast<int>(reader
.getReferenceSort(j
)))
527 + " of reference " + reader
.getReferenceTypeName(j
)
528 + " in service with key " + sub
.getName()));
531 std::vector
< AccumulationBasedServiceEntity::Property
> props
;
532 n
= reader
.getFieldCount();
533 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
534 RTFieldAccess acc
= reader
.getFieldFlags(j
);
536 if (acc
& RTFieldAccess::READONLY
) {
537 attrs
|= AccumulationBasedServiceEntity::Property::
540 if (acc
& RTFieldAccess::OPTIONAL
) {
541 attrs
|= AccumulationBasedServiceEntity::Property::
544 if (acc
& RTFieldAccess::MAYBEVOID
) {
545 attrs
|= AccumulationBasedServiceEntity::Property::
546 ATTRIBUTE_MAYBE_VOID
;
548 if (acc
& RTFieldAccess::BOUND
) {
549 attrs
|= AccumulationBasedServiceEntity::Property::
552 if (acc
& RTFieldAccess::CONSTRAINED
) {
553 attrs
|= AccumulationBasedServiceEntity::Property::
554 ATTRIBUTE_CONSTRAINED
;
556 if (acc
& RTFieldAccess::TRANSIENT
) {
557 attrs
|= AccumulationBasedServiceEntity::Property::
560 if (acc
& RTFieldAccess::MAYBEAMBIGUOUS
) {
561 attrs
|= AccumulationBasedServiceEntity::Property::
562 ATTRIBUTE_MAYBE_AMBIGUOUS
;
564 if (acc
& RTFieldAccess::MAYBEDEFAULT
) {
565 attrs
|= AccumulationBasedServiceEntity::Property::
566 ATTRIBUTE_MAYBE_DEFAULT
;
568 if (acc
& RTFieldAccess::REMOVABLE
) {
569 attrs
|= AccumulationBasedServiceEntity::Property::
573 reader
.getFieldName(j
),
574 reader
.getFieldTypeName(j
).replace('/', '.'),
576 AccumulationBasedServiceEntity::Property::
578 translateAnnotations(reader
.getFieldDocumentation(j
)));
580 return new AccumulationBasedServiceEntity(
581 reader
.isPublished(), mandServs
, optServs
, mandIfcs
,
583 translateAnnotations(reader
.getDocumentation()));
587 std::vector
< SingleInterfaceBasedServiceEntity::Constructor
>
589 sal_uInt16 n
= reader
.getMethodCount();
590 if (n
== 1 && reader
.getMethodFlags(0) == RTMethodMode::TWOWAY
591 && reader
.getMethodName(0).isEmpty()
592 && reader
.getMethodReturnTypeName(0) == "void"
593 && reader
.getMethodParameterCount(0) == 0
594 && reader
.getMethodExceptionCount(0) == 0)
597 SingleInterfaceBasedServiceEntity::Constructor());
599 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
600 if (reader
.getMethodFlags(j
) != RTMethodMode::TWOWAY
) {
601 throw FileFormatException(
602 key
.getRegistryName(),
603 ("legacy format: unexpected mode "
604 + OUString::number(static_cast<int>(reader
.getMethodFlags(j
)))
605 + " of constructor " + reader
.getMethodName(j
)
606 + " in service with key " + sub
.getName()));
609 SingleInterfaceBasedServiceEntity::Constructor::
611 sal_uInt16 m
= reader
.getMethodParameterCount(j
);
612 // cid#1213376 unhelpfully warns about an untrusted
614 // coverity[tainted_data] - trusted data source
615 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
617 = reader
.getMethodParameterFlags(j
, k
);
618 if ((mode
& ~RT_PARAM_REST
) != RT_PARAM_IN
) {
619 throw FileFormatException(
620 key
.getRegistryName(),
621 ("legacy format: unexpected mode "
622 + OUString::number(mode
)
624 + reader
.getMethodParameterName(j
, k
)
626 + reader
.getMethodName(j
)
627 + " in service with key "
630 if ((mode
& RT_PARAM_REST
) != 0
632 && ((reader
.getMethodParameterTypeName(
636 throw FileFormatException(
637 key
.getRegistryName(),
638 ("legacy format: bad rest parameter "
639 + reader
.getMethodParameterName(j
, k
)
641 + reader
.getMethodName(j
)
642 + " in service with key "
646 reader
.getMethodParameterName(j
, k
),
647 (reader
.getMethodParameterTypeName(j
, k
).
649 (mode
& RT_PARAM_REST
) != 0);
651 std::vector
< OUString
> excs
;
652 m
= reader
.getMethodExceptionCount(j
);
653 // cid#1213376 unhelpfully warns about an untrusted
655 // coverity[tainted_data] - trusted data source
656 for (sal_uInt16 k
= 0; k
!= m
; ++k
) {
658 reader
.getMethodExceptionTypeName(j
, k
).replace(
662 SingleInterfaceBasedServiceEntity::Constructor(
663 reader
.getMethodName(j
), params
, excs
,
664 translateAnnotations(
665 reader
.getMethodDocumentation(j
))));
668 return new SingleInterfaceBasedServiceEntity(
669 reader
.isPublished(),
670 reader
.getSuperTypeName(0).replace('/', '.'), ctors
,
671 translateAnnotations(reader
.getDocumentation()));
674 throw FileFormatException(
675 key
.getRegistryName(),
676 ("legacy format: unexpected number "
677 + OUString::number(reader
.getSuperTypeCount())
678 + " of super-types of service with key " + sub
.getName()));
680 case RT_TYPE_SINGLETON
:
682 if (reader
.getSuperTypeCount() != 1) {
683 throw FileFormatException(
684 key
.getRegistryName(),
685 ("legacy format: unexpected number "
686 + OUString::number(reader
.getSuperTypeCount())
687 + " of super-types of singleton with key "
690 OUString
basePath(reader
.getSuperTypeName(0));
691 OUString
baseName(basePath
.replace('/', '.'));
693 rtl::Reference
< Entity
> base(manager
->findEntity(baseName
));
695 switch (base
->getSort()) {
696 case Entity::SORT_INTERFACE_TYPE
:
699 case Entity::SORT_ACCUMULATION_BASED_SERVICE
:
703 throw FileFormatException(
704 key
.getRegistryName(),
705 ("legacy format: unexpected sort "
706 + OUString::number(base
->getSort()) + " of base "
707 + baseName
+ " of singleton with key "
712 e
= ucr
.openKey(basePath
, key2
);
714 case RegError::NO_ERROR
:
716 case RegError::KEY_NOT_EXISTS
:
717 throw FileFormatException(
718 key
.getRegistryName(),
719 ("legacy format: unknown super-type " + basePath
720 + " of super-type with key " + sub
.getName()));
722 throw FileFormatException(
723 key
.getRegistryName(),
724 ("legacy format: cannot open ucr sub-key " + basePath
725 + ": " + OUString::number(static_cast<int>(e
))));
727 std::vector
< char > buf2
;
728 typereg::Reader
reader2(getReader(key2
, &buf2
));
729 switch (reader2
.getTypeClass()) {
730 case RT_TYPE_INTERFACE
:
733 case RT_TYPE_SERVICE
:
737 throw FileFormatException(
738 key
.getRegistryName(),
739 ("legacy format: unexpected type class "
740 + OUString::number(reader2
.getTypeClass())
741 + " of super-type with key " + key2
.getName()
742 + " of singleton with key " + sub
.getName()));
746 ? rtl::Reference
< Entity
>(
747 new InterfaceBasedSingletonEntity(
748 reader
.isPublished(), baseName
,
749 translateAnnotations(reader
.getDocumentation())))
750 : rtl::Reference
< Entity
>(
751 new ServiceBasedSingletonEntity(
752 reader
.isPublished(), baseName
,
753 translateAnnotations(reader
.getDocumentation())));
755 case RT_TYPE_CONSTANTS
:
757 std::vector
< ConstantGroupEntity::Member
> mems
;
758 sal_uInt16 n
= reader
.getFieldCount();
759 for (sal_uInt16 j
= 0; j
!= n
; ++j
) {
761 reader
.getFieldName(j
),
762 translateConstantValue(sub
, reader
.getFieldValue(j
)),
763 translateAnnotations(reader
.getFieldDocumentation(j
)));
765 return new ConstantGroupEntity(
766 reader
.isPublished(), mems
,
767 translateAnnotations(reader
.getDocumentation()));
770 throw FileFormatException(
771 key
.getRegistryName(),
772 ("legacy format: unexpected type class "
773 + OUString::number(reader
.getTypeClass()) + " of key "
780 LegacyProvider::LegacyProvider(Manager
& manager
, OUString
const & uri
):
784 RegError e
= reg
.open(uri
, RegAccessMode::READONLY
);
786 case RegError::NO_ERROR
:
788 case RegError::REGISTRY_NOT_EXISTS
:
789 throw NoSuchFileException(uri
);
791 throw FileFormatException(
792 uri
, "cannot open legacy file: " + OUString::number(static_cast<int>(e
)));
795 e
= reg
.openRootKey(root
);
796 if (e
!= RegError::NO_ERROR
) {
797 throw FileFormatException(
798 uri
, "legacy format: cannot open root key: " + OUString::number(static_cast<int>(e
)));
800 e
= root
.openKey("UCR", ucr_
);
802 case RegError::NO_ERROR
:
803 case RegError::KEY_NOT_EXISTS
: // such effectively empty files exist in the wild
806 throw FileFormatException(
807 uri
, "legacy format: cannot open UCR key: " + OUString::number(static_cast<int>(e
)));
811 rtl::Reference
< MapCursor
> LegacyProvider::createRootCursor() const {
812 return new Cursor(&manager_
, ucr_
, ucr_
);
815 rtl::Reference
< Entity
> LegacyProvider::findEntity(OUString
const & name
)
818 return ucr_
.isValid()
819 ? readEntity(&manager_
, ucr_
, ucr_
, name
.replace('.', '/'), true)
820 : rtl::Reference
< Entity
>();
823 LegacyProvider::~LegacyProvider() throw () {}
827 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */