LibreOffice Module unoidl (master) 1
legacyprovider.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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 */
9
10#include <sal/config.h>
11
12#include <cassert>
13#include <utility>
14#include <vector>
15
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>
23
24#include "legacyprovider.hxx"
25
26namespace unoidl::detail {
27
28namespace {
29
30std::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");
35 }
36 return ans;
37}
38
39ConstantValue translateConstantValue(
40 RegistryKey & key, RTConstValue const & value)
41{
42 switch (value.m_type) {
43 case RT_TYPE_BOOL:
44 return ConstantValue(value.m_value.aBool);
45 case RT_TYPE_BYTE:
46 return ConstantValue(value.m_value.aByte);
47 case RT_TYPE_INT16:
48 return ConstantValue(value.m_value.aShort);
49 case RT_TYPE_UINT16:
50 return ConstantValue(value.m_value.aUShort);
51 case RT_TYPE_INT32:
52 return ConstantValue(value.m_value.aLong);
53 case RT_TYPE_UINT32:
54 return ConstantValue(value.m_value.aULong);
55 case RT_TYPE_INT64:
56 return ConstantValue(value.m_value.aHyper);
57 case RT_TYPE_UINT64:
58 return ConstantValue(value.m_value.aUHyper);
59 case RT_TYPE_FLOAT:
60 return ConstantValue(value.m_value.aFloat);
61 case RT_TYPE_DOUBLE:
62 return ConstantValue(value.m_value.aDouble);
63 default:
65 key.getRegistryName(),
66 ("legacy format: unexpected type " + OUString::number(value.m_type)
67 + " of value of a field of constant group with key "
68 + key.getName()));
69 }
70}
71
74 RegistryKey & key, OUString const & path, bool probe);
75
76class Cursor: public MapCursor {
77public:
78 Cursor(
80 RegistryKey const & key);
81
82private:
83 virtual ~Cursor() noexcept override {}
84
85 virtual rtl::Reference< Entity > getNext(OUString * name) override;
86
90 OUString prefix_;
92 sal_uInt32 index_;
93};
94
95Cursor::Cursor(
96 rtl::Reference< Manager > manager, RegistryKey const & ucr,
97 RegistryKey const & key):
98 manager_(std::move(manager)), ucr_(ucr), key_(key), index_(0)
99{
100 if (!ucr_.isValid())
101 return;
102
103 prefix_ = key_.getName();
104 if (!prefix_.endsWith("/")) {
105 prefix_ += "/";
106 }
108 if (e != RegError::NO_ERROR) {
109 throw FileFormatException(
111 ("legacy format: cannot get sub-key names of " + key_.getName()
112 + ": " + OUString::number(static_cast<int>(e))));
113 }
114}
115
116rtl::Reference< Entity > Cursor::getNext(OUString * name) {
117 assert(name != nullptr);
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);
124 assert(ent.is());
125 ++index_;
126 }
127 return ent;
128}
129
130class Module: public ModuleEntity {
131public:
132 Module(
133 rtl::Reference< Manager > manager, RegistryKey const & ucr,
134 RegistryKey const & key):
135 manager_(std::move(manager)), ucr_(ucr), key_(key)
136 {}
137
138private:
139 virtual ~Module() noexcept override {}
140
141 virtual std::vector< OUString > getMemberNames() const override;
142
143 virtual rtl::Reference< MapCursor > createCursor() const override
144 { return new Cursor(manager_, ucr_, key_); }
145
148 mutable RegistryKey key_;
149};
150
151std::vector< OUString > Module::getMemberNames() const {
152 RegistryKeyNames names;
153 RegError e = key_.getKeyNames("", names);
154 if (e != RegError::NO_ERROR) {
155 throw FileFormatException(
157 ("legacy format: cannot get sub-key names of " + key_.getName()
158 + ": " + OUString::number(static_cast<int>(e))));
159 }
160 std::vector< OUString > ns;
161 for (sal_uInt32 i = 0; i != names.getLength(); ++i) {
162 ns.push_back(names.getElement(i));
163 }
164 return ns;
165}
166
167typereg::Reader getReader(RegistryKey & key, std::vector< char > * buffer) {
168 assert(buffer != nullptr);
170 sal_uInt32 size;
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))));
177 }
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()));
183 }
184 if (size == 0
185 /*TODO: || size > std::numeric_limits< std::vector< char >::size_type >::max() */)
186 {
187 throw FileFormatException(
188 key.getRegistryName(),
189 ("legacy format: bad binary value size " + OUString::number(size)
190 + " of key " + key.getName()));
191 }
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))));
199 }
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());
205 }
206 return reader;
207}
208
209rtl::Reference< Entity > readEntity(
210 rtl::Reference< Manager > const & manager, RegistryKey & ucr,
211 RegistryKey & key, OUString const & path, bool probe)
212{
213 assert(manager.is());
214 RegistryKey sub;
215 RegError e = key.openKey(path, sub);
216 switch (e) {
217 case RegError::NO_ERROR:
218 break;
219 case RegError::KEY_NOT_EXISTS:
220 if (probe) {
222 }
223 [[fallthrough]];
224 default:
225 throw FileFormatException(
226 key.getRegistryName(),
227 ("legacy format: cannot open sub-key " + path + " of "
228 + key.getName() + ": " + OUString::number(static_cast<int>(e))));
229 }
230 std::vector< char > buf;
231 typereg::Reader reader(getReader(sub, &buf));
232 switch (reader.getTypeClass()) {
234 {
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 >());
241 }
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)));
248 }
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:
260 {
261 sal_uInt16 m
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) {
267 getExcs.push_back(
268 reader.getMethodExceptionTypeName(k, l).
269 replace('/', '.'));
270 }
271 break;
272 }
273 case RTMethodMode::ATTRIBUTE_SET:
274 {
275 sal_uInt16 m
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) {
281 setExcs.push_back(
282 reader.getMethodExceptionTypeName(k, l).
283 replace('/', '.'));
284 }
285 break;
286 }
287 default:
288 throw FileFormatException(
289 key.getRegistryName(),
290 ("legacy format: method and attribute with same"
291 " name " + attrName
292 + " in interface type with key "
293 + sub.getName()));
294 }
295 }
296 }
297 RTFieldAccess flags = reader.getFieldFlags(j);
298 attrs.emplace_back(
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)));
303 }
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)
310 {
311 std::vector< InterfaceTypeEntity::Method::Parameter >
312 params;
313 sal_uInt16 m = reader.getMethodParameterCount(j);
314 // cid#1213376 unhelpfully warns about an untrusted loop
315 // bound here:
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;
320 switch (mode) {
321 case RT_PARAM_IN:
322 dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN;
323 break;
324 case RT_PARAM_OUT:
325 dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT;
326 break;
327 case RT_PARAM_INOUT:
328 dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT;
329 break;
330 default:
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 "
338 + sub.getName()));
339 }
340 params.emplace_back(
341 reader.getMethodParameterName(j, k),
342 (reader.getMethodParameterTypeName(j, k).
343 replace('/', '.')),
344 dir);
345 }
346 std::vector< OUString > excs;
347 m = reader.getMethodExceptionCount(j);
348 // cid#1213376 unhelpfully warns about an untrusted loop
349 // bound here:
350 // coverity[tainted_data] - trusted data source
351 for (sal_uInt16 k = 0; k != m; ++k) {
352 excs.push_back(
353 reader.getMethodExceptionTypeName(j, k).replace(
354 '/', '.'));
355 }
356 meths.emplace_back(
357 reader.getMethodName(j),
358 reader.getMethodReturnTypeName(j).replace('/', '.'),
359 std::move(params), std::move(excs),
360 translateAnnotations(
361 reader.getMethodDocumentation(j)));
362 }
363 }
364 return new InterfaceTypeEntity(
365 reader.isPublished(), std::move(mandBases), std::move(optBases), std::move(attrs), std::move(meths),
366 translateAnnotations(reader.getDocumentation()));
367 }
368 case RT_TYPE_MODULE:
369 return new Module(manager, ucr, sub);
370 case RT_TYPE_STRUCT:
371 {
372 sal_uInt16 n = reader.getReferenceCount();
373 if (n == 0) {
374 OUString base;
375 switch (reader.getSuperTypeCount()) {
376 case 0:
377 break;
378 case 1:
379 base = reader.getSuperTypeName(0).replace('/', '.');
380 break;
381 default:
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 "
387 + sub.getName()));
388 }
389 std::vector< PlainStructTypeEntity::Member > mems;
390 n = reader.getFieldCount();
391 for (sal_uInt16 j = 0; j != n; ++j) {
392 mems.emplace_back(
393 reader.getFieldName(j),
394 reader.getFieldTypeName(j).replace('/', '.'),
395 translateAnnotations(reader.getFieldDocumentation(j)));
396 }
397 return new PlainStructTypeEntity(
398 reader.isPublished(), base, std::move(mems),
399 translateAnnotations(reader.getDocumentation()));
400 } else {
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()));
408 }
409 std::vector< OUString > params;
410 for (sal_uInt16 j = 0; j != n; ++j) {
411 params.push_back(
412 reader.getReferenceTypeName(j).replace('/', '.'));
413 }
414 std::vector< PolymorphicStructTypeTemplateEntity::Member > mems;
415 n = reader.getFieldCount();
416 for (sal_uInt16 j = 0; j != n; ++j) {
417 mems.emplace_back(
418 reader.getFieldName(j),
419 reader.getFieldTypeName(j).replace('/', '.'),
420 bool(
421 reader.getFieldFlags(j)
422 & RTFieldAccess::PARAMETERIZED_TYPE),
423 translateAnnotations(reader.getFieldDocumentation(j)));
424 }
425 return new PolymorphicStructTypeTemplateEntity(
426 reader.isPublished(), std::move(params), std::move(mems),
427 translateAnnotations(reader.getDocumentation()));
428 }
429 }
430 case RT_TYPE_ENUM:
431 {
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 "
442 + sub.getName()));
443 }
444 mems.emplace_back(
445 reader.getFieldName(j), v.m_value.aLong,
446 translateAnnotations(reader.getFieldDocumentation(j)));
447
448 }
449 return new EnumTypeEntity(
450 reader.isPublished(), std::move(mems),
451 translateAnnotations(reader.getDocumentation()));
452 }
454 {
455 OUString base;
456 switch (reader.getSuperTypeCount()) {
457 case 0:
458 break;
459 case 1:
460 base = reader.getSuperTypeName(0).replace('/', '.');
461 break;
462 default:
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 "
468 + sub.getName()));
469 }
470 std::vector< ExceptionTypeEntity::Member > mems;
471 sal_uInt16 n = reader.getFieldCount();
472 for (sal_uInt16 j = 0; j != n; ++j) {
473 mems.emplace_back(
474 reader.getFieldName(j),
475 reader.getFieldTypeName(j).replace('/', '.'),
476 translateAnnotations(reader.getFieldDocumentation(j)));
477 }
478 return new ExceptionTypeEntity(
479 reader.isPublished(), base, std::move(mems),
480 translateAnnotations(reader.getDocumentation()));
481 }
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()));
489 }
490 return new TypedefEntity(
491 reader.isPublished(), reader.getSuperTypeName(0).replace('/', '.'),
492 translateAnnotations(reader.getDocumentation()));
493 case RT_TYPE_SERVICE:
494 switch (reader.getSuperTypeCount()) {
495 case 0:
496 {
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))
510 {
511 mandServs.push_back(base);
512 } else {
513 optServs.push_back(base);
514 }
515 break;
516 case RTReferenceType::SUPPORTS:
517 if (!(reader.getReferenceFlags(j) & RTFieldAccess::OPTIONAL))
518 {
519 mandIfcs.push_back(base);
520 } else {
521 optIfcs.push_back(base);
522 }
523 break;
524 default:
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()));
531 }
532 }
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);
537 int attrs = 0;
538 if (acc & RTFieldAccess::READONLY) {
539 attrs |= AccumulationBasedServiceEntity::Property::
540 ATTRIBUTE_READ_ONLY;
541 }
542 if (acc & RTFieldAccess::OPTIONAL) {
543 attrs |= AccumulationBasedServiceEntity::Property::
544 ATTRIBUTE_OPTIONAL;
545 }
546 if (acc & RTFieldAccess::MAYBEVOID) {
547 attrs |= AccumulationBasedServiceEntity::Property::
548 ATTRIBUTE_MAYBE_VOID;
549 }
550 if (acc & RTFieldAccess::BOUND) {
551 attrs |= AccumulationBasedServiceEntity::Property::
552 ATTRIBUTE_BOUND;
553 }
554 if (acc & RTFieldAccess::CONSTRAINED) {
555 attrs |= AccumulationBasedServiceEntity::Property::
556 ATTRIBUTE_CONSTRAINED;
557 }
558 if (acc & RTFieldAccess::TRANSIENT) {
559 attrs |= AccumulationBasedServiceEntity::Property::
560 ATTRIBUTE_TRANSIENT;
561 }
562 if (acc & RTFieldAccess::MAYBEAMBIGUOUS) {
563 attrs |= AccumulationBasedServiceEntity::Property::
564 ATTRIBUTE_MAYBE_AMBIGUOUS;
565 }
566 if (acc & RTFieldAccess::MAYBEDEFAULT) {
567 attrs |= AccumulationBasedServiceEntity::Property::
568 ATTRIBUTE_MAYBE_DEFAULT;
569 }
570 if (acc & RTFieldAccess::REMOVABLE) {
571 attrs |= AccumulationBasedServiceEntity::Property::
572 ATTRIBUTE_REMOVABLE;
573 }
574 props.emplace_back(
575 reader.getFieldName(j),
576 reader.getFieldTypeName(j).replace('/', '.'),
577 static_cast<
578 AccumulationBasedServiceEntity::Property::
579 Attributes >(attrs),
580 translateAnnotations(reader.getFieldDocumentation(j)));
581 }
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()));
586 }
587 case 1:
588 {
589 std::vector< SingleInterfaceBasedServiceEntity::Constructor >
590 ctors;
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)
597 {
598 ctors.push_back(
599 SingleInterfaceBasedServiceEntity::Constructor());
600 } else {
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()));
609 }
610 std::vector<
611 SingleInterfaceBasedServiceEntity::Constructor::
612 Parameter > params;
613 sal_uInt16 m = reader.getMethodParameterCount(j);
614 // cid#1213376 unhelpfully warns about an untrusted
615 // loop bound here:
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)
625 + " of parameter "
626 + reader.getMethodParameterName(j, k)
627 + " of constructor "
628 + reader.getMethodName(j)
629 + " in service with key "
630 + sub.getName()));
631 }
632 if ((mode & RT_PARAM_REST) != 0
633 && (m != 1
634 || ((reader.getMethodParameterTypeName(
635 j, 0))
636 != "any")))
637 {
638 throw FileFormatException(
639 key.getRegistryName(),
640 ("legacy format: bad rest parameter "
641 + reader.getMethodParameterName(j, k)
642 + " of constructor "
643 + reader.getMethodName(j)
644 + " in service with key "
645 + sub.getName()));
646 }
647 params.emplace_back(
648 reader.getMethodParameterName(j, k),
649 (reader.getMethodParameterTypeName(j, k).
650 replace('/', '.')),
651 (mode & RT_PARAM_REST) != 0);
652 }
653 std::vector< OUString > excs;
654 m = reader.getMethodExceptionCount(j);
655 // cid#1213376 unhelpfully warns about an untrusted
656 // loop bound here:
657 // coverity[tainted_data] - trusted data source
658 for (sal_uInt16 k = 0; k != m; ++k) {
659 excs.push_back(
660 reader.getMethodExceptionTypeName(j, k).replace(
661 '/', '.'));
662 }
663 ctors.push_back(
664 SingleInterfaceBasedServiceEntity::Constructor(
665 reader.getMethodName(j), std::move(params), std::move(excs),
666 translateAnnotations(
667 reader.getMethodDocumentation(j))));
668 }
669 }
670 return new SingleInterfaceBasedServiceEntity(
671 reader.isPublished(),
672 reader.getSuperTypeName(0).replace('/', '.'), std::move(ctors),
673 translateAnnotations(reader.getDocumentation()));
674 }
675 default:
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()));
681 }
683 {
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 "
690 + sub.getName()));
691 }
692 OUString basePath(reader.getSuperTypeName(0));
693 OUString baseName(basePath.replace('/', '.'));
694 bool newStyle;
695 rtl::Reference< Entity > base(manager->findEntity(baseName));
696 if (base.is()) {
697 switch (base->getSort()) {
698 case Entity::SORT_INTERFACE_TYPE:
699 newStyle = true;
700 break;
701 case Entity::SORT_ACCUMULATION_BASED_SERVICE:
702 newStyle = false;
703 break;
704 default:
705 throw FileFormatException(
706 key.getRegistryName(),
707 ("legacy format: unexpected sort "
708 + OUString::number(base->getSort()) + " of base "
709 + baseName + " of singleton with key "
710 + sub.getName()));
711 }
712 } else {
713 RegistryKey key2;
714 e = ucr.openKey(basePath, key2);
715 switch (e) {
716 case RegError::NO_ERROR:
717 break;
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()));
723 default:
724 throw FileFormatException(
725 key.getRegistryName(),
726 ("legacy format: cannot open ucr sub-key " + basePath
727 + ": " + OUString::number(static_cast<int>(e))));
728 }
729 std::vector< char > buf2;
730 typereg::Reader reader2(getReader(key2, &buf2));
731 switch (reader2.getTypeClass()) {
733 newStyle = true;
734 break;
735 case RT_TYPE_SERVICE:
736 newStyle = false;
737 break;
738 default:
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()));
745 }
746 }
747 return newStyle
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())));
756 }
758 {
759 std::vector< ConstantGroupEntity::Member > mems;
760 sal_uInt16 n = reader.getFieldCount();
761 for (sal_uInt16 j = 0; j != n; ++j) {
762 mems.emplace_back(
763 reader.getFieldName(j),
764 translateConstantValue(sub, reader.getFieldValue(j)),
765 translateAnnotations(reader.getFieldDocumentation(j)));
766 }
767 return new ConstantGroupEntity(
768 reader.isPublished(), std::move(mems),
769 translateAnnotations(reader.getDocumentation()));
770 }
771 default:
772 throw FileFormatException(
773 key.getRegistryName(),
774 ("legacy format: unexpected type class "
775 + OUString::number(reader.getTypeClass()) + " of key "
776 + sub.getName()));
777 }
778}
779
780}
781
782LegacyProvider::LegacyProvider(Manager & manager, OUString const & uri):
784{
785 Registry reg;
786 RegError e = reg.open(uri, RegAccessMode::READONLY);
787 switch (e) {
788 case RegError::NO_ERROR:
789 break;
790 case RegError::REGISTRY_NOT_EXISTS:
791 throw NoSuchFileException(uri);
792 default:
794 uri, "cannot open legacy file: " + OUString::number(static_cast<int>(e)));
795 }
796 RegistryKey root;
797 e = reg.openRootKey(root);
798 if (e != RegError::NO_ERROR) {
800 uri, "legacy format: cannot open root key: " + OUString::number(static_cast<int>(e)));
801 }
802 e = root.openKey("UCR", ucr_);
803 switch (e) {
804 case RegError::NO_ERROR:
805 case RegError::KEY_NOT_EXISTS: // such effectively empty files exist in the wild
806 break;
807 default:
809 uri, "legacy format: cannot open UCR key: " + OUString::number(static_cast<int>(e)));
810 }
811}
812
814 return new Cursor(&manager_, ucr_, ucr_);
815}
816
818 const
819{
820 return ucr_.isValid()
821 ? readEntity(&manager_, ucr_, ucr_, name.replace('.', '/'), true)
823}
824
826
827}
828
829/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString getElement(sal_uInt32 index)
sal_uInt32 getLength() const
OUString getRegistryName()
RegError getKeyNames(const OUString &keyName, RegistryKeyNames &rSubKeyNames)
RegError openKey(const OUString &keyName, RegistryKey &rOpenKey)
OUString getName()
RegError getValueInfo(const OUString &keyName, RegValueType *pValueType, sal_uInt32 *pValueSize)
bool isValid() const
RegError getValue(const OUString &keyName, RegValue pValue)
RegError openRootKey(RegistryKey &rRootKey)
RegError open(const OUString &registryName, RegAccessMode accessMode)
virtual rtl::Reference< MapCursor > createRootCursor() const override
virtual rtl::Reference< Entity > findEntity(OUString const &name) const override
virtual ~LegacyProvider() noexcept override
Any value
rtl::Reference< ParseManager > manager
float v
float u
void const * base
const char * name
sal_Int64 n
RegistryKeyNames names_
RegistryKey ucr_
sal_uInt32 index_
OUString prefix_
RegistryKey key_
rtl::Reference< Manager > manager_
const char * attrName
size
ns
Reference
int i
m
dictionary props
ConversionMode mode
enum SAL_DLLPUBLIC_RTTI RegValueType
enum SAL_DLLPUBLIC_RTTI RegError
RTParamMode
RT_PARAM_INOUT
RT_PARAM_IN
RT_PARAM_OUT
RT_TYPE_BYTE
RT_TYPE_FLOAT
RT_TYPE_INT64
RT_TYPE_INT32
RT_TYPE_DOUBLE
RT_TYPE_UINT16
RT_TYPE_BOOL
RT_TYPE_UINT64
RT_TYPE_UINT32
RT_TYPE_INT16
RTFieldAccess
RTMethodMode
RT_TYPE_INTERFACE
RT_TYPE_MODULE
RT_TYPE_CONSTANTS
RT_TYPE_STRUCT
RT_TYPE_SINGLETON
RT_TYPE_SERVICE
RT_TYPE_EXCEPTION
RT_TYPE_ENUM
RT_TYPE_TYPEDEF
ResultType type