Use o3tl::convert in Math
[LibreOffice.git] / unoidl / source / legacyprovider.cxx
blob1d147a97558295bc9e0094edce436c40b24953a6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <sal/config.h>
12 #include <cassert>
13 #include <vector>
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 {
27 namespace {
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");
35 return ans;
38 ConstantValue translateConstantValue(
39 RegistryKey & key, RTConstValue const & value)
41 switch (value.m_type) {
42 case RT_TYPE_BOOL:
43 return ConstantValue(value.m_value.aBool);
44 case RT_TYPE_BYTE:
45 return ConstantValue(value.m_value.aByte);
46 case RT_TYPE_INT16:
47 return ConstantValue(value.m_value.aShort);
48 case RT_TYPE_UINT16:
49 return ConstantValue(value.m_value.aUShort);
50 case RT_TYPE_INT32:
51 return ConstantValue(value.m_value.aLong);
52 case RT_TYPE_UINT32:
53 return ConstantValue(value.m_value.aULong);
54 case RT_TYPE_INT64:
55 return ConstantValue(value.m_value.aHyper);
56 case RT_TYPE_UINT64:
57 return ConstantValue(value.m_value.aUHyper);
58 case RT_TYPE_FLOAT:
59 return ConstantValue(value.m_value.aFloat);
60 case RT_TYPE_DOUBLE:
61 return ConstantValue(value.m_value.aDouble);
62 default:
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 "
67 + key.getName()));
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 {
76 public:
77 Cursor(
78 rtl::Reference< Manager > const & manager, RegistryKey const & ucr,
79 RegistryKey const & key);
81 private:
82 virtual ~Cursor() noexcept override {}
84 virtual rtl::Reference< Entity > getNext(OUString * name) override;
86 rtl::Reference< Manager > manager_;
87 RegistryKey ucr_;
88 RegistryKey key_;
89 OUString prefix_;
90 RegistryKeyNames names_;
91 sal_uInt32 index_;
94 Cursor::Cursor(
95 rtl::Reference< Manager > const & manager, RegistryKey const & ucr,
96 RegistryKey const & key):
97 manager_(manager), ucr_(ucr), key_(key), index_(0)
99 if (!ucr_.isValid())
100 return;
102 prefix_ = key_.getName();
103 if (!prefix_.endsWith("/")) {
104 prefix_ += "/";
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);
123 assert(ent.is());
124 ++index_;
126 return ent;
129 class Module: public ModuleEntity {
130 public:
131 Module(
132 rtl::Reference< Manager > const & manager, RegistryKey const & ucr,
133 RegistryKey const & key):
134 manager_(manager), ucr_(ucr), key_(key)
137 private:
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_;
146 RegistryKey ucr_;
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));
163 return ns;
166 typereg::Reader getReader(RegistryKey & key, std::vector< char > * buffer) {
167 assert(buffer != nullptr);
168 RegValueType type;
169 sal_uInt32 size;
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()));
183 if (size == 0
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());
205 return reader;
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());
213 RegistryKey sub;
214 RegError e = key.openKey(path, sub);
215 switch (e) {
216 case RegError::NO_ERROR:
217 break;
218 case RegError::KEY_NOT_EXISTS:
219 if (probe) {
220 return rtl::Reference< Entity >();
222 [[fallthrough]];
223 default:
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:
260 sal_uInt16 m
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) {
266 getExcs.push_back(
267 reader.getMethodExceptionTypeName(k, l).
268 replace('/', '.'));
270 break;
272 case RTMethodMode::ATTRIBUTE_SET:
274 sal_uInt16 m
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) {
280 setExcs.push_back(
281 reader.getMethodExceptionTypeName(k, l).
282 replace('/', '.'));
284 break;
286 default:
287 throw FileFormatException(
288 key.getRegistryName(),
289 ("legacy format: method and attribute with same"
290 " name " + attrName
291 + " in interface type with key "
292 + sub.getName()));
296 RTFieldAccess flags = reader.getFieldFlags(j);
297 attrs.emplace_back(
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 >
311 params;
312 sal_uInt16 m = reader.getMethodParameterCount(j);
313 // cid#1213376 unhelpfully warns about an untrusted loop
314 // bound here:
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;
319 switch (mode) {
320 case RT_PARAM_IN:
321 dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN;
322 break;
323 case RT_PARAM_OUT:
324 dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT;
325 break;
326 case RT_PARAM_INOUT:
327 dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT;
328 break;
329 default:
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 "
337 + sub.getName()));
339 params.emplace_back(
340 reader.getMethodParameterName(j, k),
341 (reader.getMethodParameterTypeName(j, k).
342 replace('/', '.')),
343 dir);
345 std::vector< OUString > excs;
346 m = reader.getMethodExceptionCount(j);
347 // cid#1213376 unhelpfully warns about an untrusted loop
348 // bound here:
349 // coverity[tainted_data] - trusted data source
350 for (sal_uInt16 k = 0; k != m; ++k) {
351 excs.push_back(
352 reader.getMethodExceptionTypeName(j, k).replace(
353 '/', '.'));
355 meths.emplace_back(
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()));
367 case RT_TYPE_MODULE:
368 return new Module(manager, ucr, sub);
369 case RT_TYPE_STRUCT:
371 sal_uInt16 n = reader.getReferenceCount();
372 if (n == 0) {
373 OUString base;
374 switch (reader.getSuperTypeCount()) {
375 case 0:
376 break;
377 case 1:
378 base = reader.getSuperTypeName(0).replace('/', '.');
379 break;
380 default:
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 "
386 + sub.getName()));
388 std::vector< PlainStructTypeEntity::Member > mems;
389 n = reader.getFieldCount();
390 for (sal_uInt16 j = 0; j != n; ++j) {
391 mems.emplace_back(
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()));
399 } else {
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) {
410 params.push_back(
411 reader.getReferenceTypeName(j).replace('/', '.'));
413 std::vector< PolymorphicStructTypeTemplateEntity::Member > mems;
414 n = reader.getFieldCount();
415 for (sal_uInt16 j = 0; j != n; ++j) {
416 mems.emplace_back(
417 reader.getFieldName(j),
418 reader.getFieldTypeName(j).replace('/', '.'),
419 bool(
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()));
429 case RT_TYPE_ENUM:
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 "
441 + sub.getName()));
443 mems.emplace_back(
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:
454 OUString base;
455 switch (reader.getSuperTypeCount()) {
456 case 0:
457 break;
458 case 1:
459 base = reader.getSuperTypeName(0).replace('/', '.');
460 break;
461 default:
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 "
467 + sub.getName()));
469 std::vector< ExceptionTypeEntity::Member > mems;
470 sal_uInt16 n = reader.getFieldCount();
471 for (sal_uInt16 j = 0; j != n; ++j) {
472 mems.emplace_back(
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()) {
494 case 0:
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);
511 } else {
512 optServs.push_back(base);
514 break;
515 case RTReferenceType::SUPPORTS:
516 if (!(reader.getReferenceFlags(j) & RTFieldAccess::OPTIONAL))
518 mandIfcs.push_back(base);
519 } else {
520 optIfcs.push_back(base);
522 break;
523 default:
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);
536 int attrs = 0;
537 if (acc & RTFieldAccess::READONLY) {
538 attrs |= AccumulationBasedServiceEntity::Property::
539 ATTRIBUTE_READ_ONLY;
541 if (acc & RTFieldAccess::OPTIONAL) {
542 attrs |= AccumulationBasedServiceEntity::Property::
543 ATTRIBUTE_OPTIONAL;
545 if (acc & RTFieldAccess::MAYBEVOID) {
546 attrs |= AccumulationBasedServiceEntity::Property::
547 ATTRIBUTE_MAYBE_VOID;
549 if (acc & RTFieldAccess::BOUND) {
550 attrs |= AccumulationBasedServiceEntity::Property::
551 ATTRIBUTE_BOUND;
553 if (acc & RTFieldAccess::CONSTRAINED) {
554 attrs |= AccumulationBasedServiceEntity::Property::
555 ATTRIBUTE_CONSTRAINED;
557 if (acc & RTFieldAccess::TRANSIENT) {
558 attrs |= AccumulationBasedServiceEntity::Property::
559 ATTRIBUTE_TRANSIENT;
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::
571 ATTRIBUTE_REMOVABLE;
573 props.emplace_back(
574 reader.getFieldName(j),
575 reader.getFieldTypeName(j).replace('/', '.'),
576 static_cast<
577 AccumulationBasedServiceEntity::Property::
578 Attributes >(attrs),
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()));
586 case 1:
588 std::vector< SingleInterfaceBasedServiceEntity::Constructor >
589 ctors;
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)
597 ctors.push_back(
598 SingleInterfaceBasedServiceEntity::Constructor());
599 } else {
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()));
609 std::vector<
610 SingleInterfaceBasedServiceEntity::Constructor::
611 Parameter > params;
612 sal_uInt16 m = reader.getMethodParameterCount(j);
613 // cid#1213376 unhelpfully warns about an untrusted
614 // loop bound here:
615 // coverity[tainted_data] - trusted data source
616 for (sal_uInt16 k = 0; k != m; ++k) {
617 RTParamMode mode
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)
624 + " of parameter "
625 + reader.getMethodParameterName(j, k)
626 + " of constructor "
627 + reader.getMethodName(j)
628 + " in service with key "
629 + sub.getName()));
631 if ((mode & RT_PARAM_REST) != 0
632 && (m != 1
633 || ((reader.getMethodParameterTypeName(
634 j, 0))
635 != "any")))
637 throw FileFormatException(
638 key.getRegistryName(),
639 ("legacy format: bad rest parameter "
640 + reader.getMethodParameterName(j, k)
641 + " of constructor "
642 + reader.getMethodName(j)
643 + " in service with key "
644 + sub.getName()));
646 params.emplace_back(
647 reader.getMethodParameterName(j, k),
648 (reader.getMethodParameterTypeName(j, k).
649 replace('/', '.')),
650 (mode & RT_PARAM_REST) != 0);
652 std::vector< OUString > excs;
653 m = reader.getMethodExceptionCount(j);
654 // cid#1213376 unhelpfully warns about an untrusted
655 // loop bound here:
656 // coverity[tainted_data] - trusted data source
657 for (sal_uInt16 k = 0; k != m; ++k) {
658 excs.push_back(
659 reader.getMethodExceptionTypeName(j, k).replace(
660 '/', '.'));
662 ctors.push_back(
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()));
674 default:
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 "
689 + sub.getName()));
691 OUString basePath(reader.getSuperTypeName(0));
692 OUString baseName(basePath.replace('/', '.'));
693 bool newStyle;
694 rtl::Reference< Entity > base(manager->findEntity(baseName));
695 if (base.is()) {
696 switch (base->getSort()) {
697 case Entity::SORT_INTERFACE_TYPE:
698 newStyle = true;
699 break;
700 case Entity::SORT_ACCUMULATION_BASED_SERVICE:
701 newStyle = false;
702 break;
703 default:
704 throw FileFormatException(
705 key.getRegistryName(),
706 ("legacy format: unexpected sort "
707 + OUString::number(base->getSort()) + " of base "
708 + baseName + " of singleton with key "
709 + sub.getName()));
711 } else {
712 RegistryKey key2;
713 e = ucr.openKey(basePath, key2);
714 switch (e) {
715 case RegError::NO_ERROR:
716 break;
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()));
722 default:
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:
732 newStyle = true;
733 break;
734 case RT_TYPE_SERVICE:
735 newStyle = false;
736 break;
737 default:
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()));
746 return newStyle
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) {
761 mems.emplace_back(
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()));
770 default:
771 throw FileFormatException(
772 key.getRegistryName(),
773 ("legacy format: unexpected type class "
774 + OUString::number(reader.getTypeClass()) + " of key "
775 + sub.getName()));
781 LegacyProvider::LegacyProvider(Manager & manager, OUString const & uri):
782 manager_(manager)
784 Registry reg;
785 RegError e = reg.open(uri, RegAccessMode::READONLY);
786 switch (e) {
787 case RegError::NO_ERROR:
788 break;
789 case RegError::REGISTRY_NOT_EXISTS:
790 throw NoSuchFileException(uri);
791 default:
792 throw FileFormatException(
793 uri, "cannot open legacy file: " + OUString::number(static_cast<int>(e)));
795 RegistryKey root;
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_);
802 switch (e) {
803 case RegError::NO_ERROR:
804 case RegError::KEY_NOT_EXISTS: // such effectively empty files exist in the wild
805 break;
806 default:
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)
817 const
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: */