fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / unoidl / source / legacyprovider.cxx
blobd3f34bb0918eb97061c7b701d73a101acdacdf6a
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 <cstring>
14 #include <vector>
16 #include "registry/reader.hxx"
17 #include "registry/registry.hxx"
18 #include "registry/regtype.h"
19 #include "rtl/ref.hxx"
20 #include "rtl/ustring.hxx"
21 #include "sal/types.h"
22 #include "unoidl/unoidl.hxx"
24 #include "legacyprovider.hxx"
26 namespace unoidl { namespace detail {
28 namespace {
30 std::vector< OUString > translateAnnotations(OUString const & documentation) {
31 std::vector< OUString > ans;
32 if (documentation.indexOf("@deprecated") != -1) {
33 //TODO: this check is somewhat crude
34 ans.push_back("deprecated");
36 return ans;
39 ConstantValue translateConstantValue(
40 RegistryKey & key, RTConstValue const & value)
42 switch (value.m_type) {
43 case RT_TYPE_BOOL:
44 return ConstantValue(static_cast< bool >(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:
64 throw FileFormatException(
65 key.getRegistryName(),
66 ("legacy format: unexpected type " + OUString::number(value.m_type)
67 + " of value of a field of constant group with key "
68 + key.getName()));
72 rtl::Reference< Entity > readEntity(
73 rtl::Reference< Manager > const & manager, RegistryKey & ucr,
74 RegistryKey & key, OUString const & path, bool probe);
76 class Cursor: public MapCursor {
77 public:
78 Cursor(
79 rtl::Reference< Manager > const & manager, RegistryKey const & ucr,
80 RegistryKey const & key);
82 private:
83 virtual ~Cursor() throw () {}
85 virtual rtl::Reference< Entity > getNext(OUString * name) SAL_OVERRIDE;
87 rtl::Reference< Manager > manager_;
88 RegistryKey ucr_;
89 RegistryKey key_;
90 OUString prefix_;
91 RegistryKeyNames names_;
92 sal_uInt32 index_;
95 Cursor::Cursor(
96 rtl::Reference< Manager > const & manager, RegistryKey const & ucr,
97 RegistryKey const & key):
98 manager_(manager), ucr_(ucr), key_(key), index_(0)
100 if (ucr_.isValid()) {
101 prefix_ = key_.getName();
102 if (!prefix_.endsWith("/")) {
103 prefix_ += "/";
105 RegError e = key_.getKeyNames("", names_);
106 if (e != RegError::NO_ERROR) {
107 throw FileFormatException(
108 key_.getRegistryName(),
109 ("legacy format: cannot get sub-key names of " + key_.getName()
110 + ": " + OUString::number(static_cast<int>(e))));
115 rtl::Reference< Entity > Cursor::getNext(OUString * name) {
116 assert(name != 0);
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() throw () {}
140 virtual std::vector< OUString > getMemberNames() const SAL_OVERRIDE;
142 virtual rtl::Reference< MapCursor > createCursor() const SAL_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 != 0);
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)[0]);
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)[0], size, false, TYPEREG_VERSION_1);
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 // fall through
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.push_back(
238 AnnotatedReference(
239 reader.getSuperTypeName(j).replace('/', '.'),
240 std::vector< OUString >()));
242 std::vector< AnnotatedReference > optBases;
243 n = reader.getReferenceCount();
244 for (sal_uInt16 j = 0; j != n; ++j) {
245 optBases.push_back(
246 AnnotatedReference(
247 reader.getReferenceTypeName(j).replace('/', '.'),
248 translateAnnotations(
249 reader.getReferenceDocumentation(j))));
251 sal_uInt16 methodCount = reader.getMethodCount();
252 std::vector< InterfaceTypeEntity::Attribute > attrs;
253 n = reader.getFieldCount(); // attributes
254 for (sal_uInt16 j = 0; j != n; ++j) {
255 OUString attrName(reader.getFieldName(j));
256 std::vector< OUString > getExcs;
257 std::vector< OUString > setExcs;
258 for (sal_uInt16 k = 0; k != methodCount; ++k) {
259 if (reader.getMethodName(k) == attrName) {
260 switch (reader.getMethodFlags(k)) {
261 case RTMethodMode::ATTRIBUTE_GET:
263 sal_uInt16 m
264 = reader.getMethodExceptionCount(k);
265 // coverity[tainted_data] cid#1213376
266 // unhelpfully warns about an untrusted loop
267 // bound here:
268 for (sal_uInt16 l = 0; l != m; ++l) {
269 getExcs.push_back(
270 reader.getMethodExceptionTypeName(k, l).
271 replace('/', '.'));
273 break;
275 case RTMethodMode::ATTRIBUTE_SET:
277 sal_uInt16 m
278 = reader.getMethodExceptionCount(k);
279 // coverity[tainted_data] cid#1213376
280 // unhelpfully warns about an untrusted loop
281 // bound here:
282 for (sal_uInt16 l = 0; l != m; ++l) {
283 setExcs.push_back(
284 reader.getMethodExceptionTypeName(k, l).
285 replace('/', '.'));
287 break;
289 default:
290 throw FileFormatException(
291 key.getRegistryName(),
292 ("legacy format: method and attribute with same"
293 " name " + attrName
294 + " in interface type with key "
295 + sub.getName()));
299 RTFieldAccess flags = reader.getFieldFlags(j);
300 attrs.push_back(
301 InterfaceTypeEntity::Attribute(
302 attrName, reader.getFieldTypeName(j).replace('/', '.'),
303 bool(flags & RTFieldAccess::BOUND),
304 bool(flags & RTFieldAccess::READONLY), getExcs, setExcs,
305 translateAnnotations(reader.getFieldDocumentation(j))));
307 std::vector< InterfaceTypeEntity::Method > meths;
308 for (sal_uInt16 j = 0; j != methodCount; ++j) {
309 RTMethodMode flags = reader.getMethodFlags(j);
310 if (flags != RTMethodMode::ATTRIBUTE_GET
311 && flags != RTMethodMode::ATTRIBUTE_SET)
313 std::vector< InterfaceTypeEntity::Method::Parameter >
314 params;
315 sal_uInt16 m = reader.getMethodParameterCount(j);
316 // coverity[tainted_data] cid#1213376 unhelpfully warns
317 // about an untrusted loop bound here:
318 for (sal_uInt16 k = 0; k != m; ++k) {
319 RTParamMode mode = reader.getMethodParameterFlags(j, k);
320 InterfaceTypeEntity::Method::Parameter::Direction dir;
321 switch (mode) {
322 case RT_PARAM_IN:
323 dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN;
324 break;
325 case RT_PARAM_OUT:
326 dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT;
327 break;
328 case RT_PARAM_INOUT:
329 dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT;
330 break;
331 default:
332 throw FileFormatException(
333 key.getRegistryName(),
334 ("legacy format: unexpected mode "
335 + OUString::number(mode) + " of parameter "
336 + reader.getMethodParameterName(j, k)
337 + " of method " + reader.getMethodName(j)
338 + " in interface type with key "
339 + sub.getName()));
341 params.push_back(
342 InterfaceTypeEntity::Method::Parameter(
343 reader.getMethodParameterName(j, k),
344 (reader.getMethodParameterTypeName(j, k).
345 replace('/', '.')),
346 dir));
348 std::vector< OUString > excs;
349 m = reader.getMethodExceptionCount(j);
350 // coverity[tainted_data] cid#1213376 unhelpfully warns
351 // about an untrusted loop bound here:
352 for (sal_uInt16 k = 0; k != m; ++k) {
353 excs.push_back(
354 reader.getMethodExceptionTypeName(j, k).replace(
355 '/', '.'));
357 meths.push_back(
358 InterfaceTypeEntity::Method(
359 reader.getMethodName(j),
360 reader.getMethodReturnTypeName(j).replace('/', '.'),
361 params, excs,
362 translateAnnotations(
363 reader.getMethodDocumentation(j))));
366 return new InterfaceTypeEntity(
367 reader.isPublished(), mandBases, optBases, attrs, meths,
368 translateAnnotations(reader.getDocumentation()));
370 case RT_TYPE_MODULE:
371 return new Module(manager, ucr, sub);
372 case RT_TYPE_STRUCT:
374 sal_uInt32 n = reader.getReferenceCount();
375 if (n == 0) {
376 OUString base;
377 switch (reader.getSuperTypeCount()) {
378 case 0:
379 break;
380 case 1:
381 base = reader.getSuperTypeName(0).replace('/', '.');
382 break;
383 default:
384 FileFormatException(
385 key.getRegistryName(),
386 ("legacy format: unexpected number "
387 + OUString::number(reader.getSuperTypeCount())
388 + " of super-types of plain struct type with key "
389 + sub.getName()));
391 std::vector< PlainStructTypeEntity::Member > mems;
392 n = reader.getFieldCount();
393 for (sal_uInt16 j = 0; j != n; ++j) {
394 mems.push_back(
395 PlainStructTypeEntity::Member(
396 reader.getFieldName(j),
397 reader.getFieldTypeName(j).replace('/', '.'),
398 translateAnnotations(
399 reader.getFieldDocumentation(j))));
401 return new PlainStructTypeEntity(
402 reader.isPublished(), base, mems,
403 translateAnnotations(reader.getDocumentation()));
404 } else {
405 if (reader.getSuperTypeCount() != 0) {
406 FileFormatException(
407 key.getRegistryName(),
408 ("legacy format: unexpected number "
409 + OUString::number(reader.getSuperTypeCount())
410 + " of super-types of polymorphic struct type template"
411 " with key " + sub.getName()));
413 std::vector< OUString > params;
414 for (sal_uInt16 j = 0; j != n; ++j) {
415 params.push_back(
416 reader.getReferenceTypeName(j).replace('/', '.'));
418 std::vector< PolymorphicStructTypeTemplateEntity::Member > mems;
419 n = reader.getFieldCount();
420 for (sal_uInt16 j = 0; j != n; ++j) {
421 mems.push_back(
422 PolymorphicStructTypeTemplateEntity::Member(
423 reader.getFieldName(j),
424 reader.getFieldTypeName(j).replace('/', '.'),
425 bool(reader.getFieldFlags(j)
426 & RTFieldAccess::PARAMETERIZED_TYPE),
427 translateAnnotations(
428 reader.getFieldDocumentation(j))));
430 return new PolymorphicStructTypeTemplateEntity(
431 reader.isPublished(), params, mems,
432 translateAnnotations(reader.getDocumentation()));
435 case RT_TYPE_ENUM:
437 std::vector< EnumTypeEntity::Member > mems;
438 sal_uInt16 n = reader.getFieldCount();
439 for (sal_uInt16 j = 0; j != n; ++j) {
440 RTConstValue v(reader.getFieldValue(j));
441 if (v.m_type != RT_TYPE_INT32) {
442 FileFormatException(
443 key.getRegistryName(),
444 ("legacy format: unexpected type "
445 + OUString::number(v.m_type) + " of value of field "
446 + reader.getFieldName(j) + " of enum type with key "
447 + sub.getName()));
449 mems.push_back(
450 EnumTypeEntity::Member(
451 reader.getFieldName(j), v.m_value.aLong,
452 translateAnnotations(reader.getFieldDocumentation(j))));
455 return new EnumTypeEntity(
456 reader.isPublished(), mems,
457 translateAnnotations(reader.getDocumentation()));
459 case RT_TYPE_EXCEPTION:
461 OUString base;
462 switch (reader.getSuperTypeCount()) {
463 case 0:
464 break;
465 case 1:
466 base = reader.getSuperTypeName(0).replace('/', '.');
467 break;
468 default:
469 throw FileFormatException(
470 key.getRegistryName(),
471 ("legacy format: unexpected number "
472 + OUString::number(reader.getSuperTypeCount())
473 + " of super-types of exception type with key "
474 + sub.getName()));
476 std::vector< ExceptionTypeEntity::Member > mems;
477 sal_uInt16 n = reader.getFieldCount();
478 for (sal_uInt16 j = 0; j != n; ++j) {
479 mems.push_back(
480 ExceptionTypeEntity::Member(
481 reader.getFieldName(j),
482 reader.getFieldTypeName(j).replace('/', '.'),
483 translateAnnotations(reader.getFieldDocumentation(j))));
485 return new ExceptionTypeEntity(
486 reader.isPublished(), base, mems,
487 translateAnnotations(reader.getDocumentation()));
489 case RT_TYPE_TYPEDEF:
490 if (reader.getSuperTypeCount() != 1) {
491 throw FileFormatException(
492 key.getRegistryName(),
493 ("legacy format: unexpected number "
494 + OUString::number(reader.getSuperTypeCount())
495 + " of super-types of typedef with key " + sub.getName()));
497 return new TypedefEntity(
498 reader.isPublished(), reader.getSuperTypeName(0).replace('/', '.'),
499 translateAnnotations(reader.getDocumentation()));
500 case RT_TYPE_SERVICE:
501 switch (reader.getSuperTypeCount()) {
502 case 0:
504 std::vector< AnnotatedReference > mandServs;
505 std::vector< AnnotatedReference > optServs;
506 std::vector< AnnotatedReference > mandIfcs;
507 std::vector< AnnotatedReference > optIfcs;
508 sal_uInt16 n = reader.getReferenceCount();
509 for (sal_uInt16 j = 0; j != n; ++j) {
510 AnnotatedReference base(
511 reader.getReferenceTypeName(j).replace('/', '.'),
512 translateAnnotations(
513 reader.getReferenceDocumentation(j)));
514 switch (reader.getReferenceSort(j)) {
515 case RTReferenceType::EXPORTS:
516 if (!(reader.getReferenceFlags(j) & RTFieldAccess::OPTIONAL))
518 mandServs.push_back(base);
519 } else {
520 optServs.push_back(base);
522 break;
523 case RTReferenceType::SUPPORTS:
524 if (!(reader.getReferenceFlags(j) & RTFieldAccess::OPTIONAL))
526 mandIfcs.push_back(base);
527 } else {
528 optIfcs.push_back(base);
530 break;
531 default:
532 throw FileFormatException(
533 key.getRegistryName(),
534 ("legacy format: unexpected mode "
535 + OUString::number(static_cast<int>(reader.getReferenceSort(j)))
536 + " of reference " + reader.getReferenceTypeName(j)
537 + " in service with key " + sub.getName()));
540 std::vector< AccumulationBasedServiceEntity::Property > props;
541 n = reader.getFieldCount();
542 for (sal_uInt16 j = 0; j != n; ++j) {
543 RTFieldAccess acc = reader.getFieldFlags(j);
544 int attrs = 0;
545 if (acc & RTFieldAccess::READONLY) {
546 attrs |= AccumulationBasedServiceEntity::Property::
547 ATTRIBUTE_READ_ONLY;
549 if (acc & RTFieldAccess::OPTIONAL) {
550 attrs |= AccumulationBasedServiceEntity::Property::
551 ATTRIBUTE_OPTIONAL;
553 if (acc & RTFieldAccess::MAYBEVOID) {
554 attrs |= AccumulationBasedServiceEntity::Property::
555 ATTRIBUTE_MAYBE_VOID;
557 if (acc & RTFieldAccess::BOUND) {
558 attrs |= AccumulationBasedServiceEntity::Property::
559 ATTRIBUTE_BOUND;
561 if (acc & RTFieldAccess::CONSTRAINED) {
562 attrs |= AccumulationBasedServiceEntity::Property::
563 ATTRIBUTE_CONSTRAINED;
565 if (acc & RTFieldAccess::TRANSIENT) {
566 attrs |= AccumulationBasedServiceEntity::Property::
567 ATTRIBUTE_TRANSIENT;
569 if (acc & RTFieldAccess::MAYBEAMBIGUOUS) {
570 attrs |= AccumulationBasedServiceEntity::Property::
571 ATTRIBUTE_MAYBE_AMBIGUOUS;
573 if (acc & RTFieldAccess::MAYBEDEFAULT) {
574 attrs |= AccumulationBasedServiceEntity::Property::
575 ATTRIBUTE_MAYBE_DEFAULT;
577 if (acc & RTFieldAccess::REMOVABLE) {
578 attrs |= AccumulationBasedServiceEntity::Property::
579 ATTRIBUTE_REMOVABLE;
581 props.push_back(
582 AccumulationBasedServiceEntity::Property(
583 reader.getFieldName(j),
584 reader.getFieldTypeName(j).replace('/', '.'),
585 static_cast<
586 AccumulationBasedServiceEntity::Property::
587 Attributes >(attrs),
588 translateAnnotations(
589 reader.getFieldDocumentation(j))));
591 return new AccumulationBasedServiceEntity(
592 reader.isPublished(), mandServs, optServs, mandIfcs,
593 optIfcs, props,
594 translateAnnotations(reader.getDocumentation()));
596 case 1:
598 std::vector< SingleInterfaceBasedServiceEntity::Constructor >
599 ctors;
600 sal_uInt16 n = reader.getMethodCount();
601 if (n == 1 && reader.getMethodFlags(0) == RTMethodMode::TWOWAY
602 && reader.getMethodName(0).isEmpty()
603 && reader.getMethodReturnTypeName(0) == "void"
604 && reader.getMethodParameterCount(0) == 0
605 && reader.getMethodExceptionCount(0) == 0)
607 ctors.push_back(
608 SingleInterfaceBasedServiceEntity::Constructor());
609 } else {
610 for (sal_uInt16 j = 0; j != n; ++j) {
611 if (reader.getMethodFlags(j) != RTMethodMode::TWOWAY) {
612 throw FileFormatException(
613 key.getRegistryName(),
614 ("legacy format: unexpected mode "
615 + OUString::number(static_cast<int>(reader.getMethodFlags(j)))
616 + " of constructor " + reader.getMethodName(j)
617 + " in service with key " + sub.getName()));
619 std::vector<
620 SingleInterfaceBasedServiceEntity::Constructor::
621 Parameter > params;
622 sal_uInt16 m = reader.getMethodParameterCount(j);
623 // coverity[tainted_data] cid#1213376 unhelpfully warns
624 // about an untrusted loop bound here:
625 for (sal_uInt16 k = 0; k != m; ++k) {
626 RTParamMode mode
627 = reader.getMethodParameterFlags(j, k);
628 if ((mode & ~RT_PARAM_REST) != RT_PARAM_IN) {
629 throw FileFormatException(
630 key.getRegistryName(),
631 ("legacy format: unexpected mode "
632 + OUString::number(mode)
633 + " of parameter "
634 + reader.getMethodParameterName(j, k)
635 + " of constructor "
636 + reader.getMethodName(j)
637 + " in service with key "
638 + sub.getName()));
640 if ((mode & RT_PARAM_REST) != 0
641 && !(m == 1
642 && ((reader.getMethodParameterTypeName(
643 j, 0))
644 == "any")))
646 throw FileFormatException(
647 key.getRegistryName(),
648 ("legacy format: bad rest parameter "
649 + reader.getMethodParameterName(j, k)
650 + " of constructor "
651 + reader.getMethodName(j)
652 + " in service with key "
653 + sub.getName()));
655 params.push_back(
656 SingleInterfaceBasedServiceEntity::Constructor::
657 Parameter(
658 reader.getMethodParameterName(j, k),
659 (reader.getMethodParameterTypeName(j, k).
660 replace('/', '.')),
661 (mode & RT_PARAM_REST) != 0));
663 std::vector< OUString > excs;
664 m = reader.getMethodExceptionCount(j);
665 // coverity[tainted_data] cid#1213376 unhelpfully warns
666 // about an untrusted loop bound here:
667 for (sal_uInt16 k = 0; k != m; ++k) {
668 excs.push_back(
669 reader.getMethodExceptionTypeName(j, k).replace(
670 '/', '.'));
672 ctors.push_back(
673 SingleInterfaceBasedServiceEntity::Constructor(
674 reader.getMethodName(j), params, excs,
675 translateAnnotations(
676 reader.getMethodDocumentation(j))));
679 return new SingleInterfaceBasedServiceEntity(
680 reader.isPublished(),
681 reader.getSuperTypeName(0).replace('/', '.'), ctors,
682 translateAnnotations(reader.getDocumentation()));
684 default:
685 throw FileFormatException(
686 key.getRegistryName(),
687 ("legacy format: unexpected number "
688 + OUString::number(reader.getSuperTypeCount())
689 + " of super-types of service with key " + sub.getName()));
691 case RT_TYPE_SINGLETON:
693 if (reader.getSuperTypeCount() != 1) {
694 throw FileFormatException(
695 key.getRegistryName(),
696 ("legacy format: unexpected number "
697 + OUString::number(reader.getSuperTypeCount())
698 + " of super-types of singleton with key "
699 + sub.getName()));
701 OUString basePath(reader.getSuperTypeName(0));
702 OUString baseName(basePath.replace('/', '.'));
703 bool newStyle;
704 rtl::Reference< Entity > base(manager->findEntity(baseName));
705 if (base.is()) {
706 switch (base->getSort()) {
707 case Entity::SORT_INTERFACE_TYPE:
708 newStyle = true;
709 break;
710 case Entity::SORT_ACCUMULATION_BASED_SERVICE:
711 newStyle = false;
712 break;
713 default:
714 throw FileFormatException(
715 key.getRegistryName(),
716 ("legacy format: unexpected sort "
717 + OUString::number(base->getSort()) + " of base "
718 + baseName + " of singleton with key "
719 + sub.getName()));
721 } else {
722 RegistryKey key2;
723 e = ucr.openKey(basePath, key2);
724 switch (e) {
725 case RegError::NO_ERROR:
726 break;
727 case RegError::KEY_NOT_EXISTS:
728 throw FileFormatException(
729 key.getRegistryName(),
730 ("legacy format: unknown super-type " + basePath
731 + " of super-type with key " + sub.getName()));
732 default:
733 throw FileFormatException(
734 key.getRegistryName(),
735 ("legacy format: cannot open ucr sub-key " + basePath
736 + ": " + OUString::number(static_cast<int>(e))));
738 std::vector< char > buf2;
739 typereg::Reader reader2(getReader(key2, &buf2));
740 switch (reader2.getTypeClass()) {
741 case RT_TYPE_INTERFACE:
742 newStyle = true;
743 break;
744 case RT_TYPE_SERVICE:
745 newStyle = false;
746 break;
747 default:
748 throw FileFormatException(
749 key.getRegistryName(),
750 ("legacy format: unexpected type class "
751 + OUString::number(reader2.getTypeClass())
752 + " of super-type with key " + key2.getName()
753 + " of singleton with key " + sub.getName()));
756 return newStyle
757 ? rtl::Reference< Entity >(
758 new InterfaceBasedSingletonEntity(
759 reader.isPublished(), baseName,
760 translateAnnotations(reader.getDocumentation())))
761 : rtl::Reference< Entity >(
762 new ServiceBasedSingletonEntity(
763 reader.isPublished(), baseName,
764 translateAnnotations(reader.getDocumentation())));
766 case RT_TYPE_CONSTANTS:
768 std::vector< ConstantGroupEntity::Member > mems;
769 sal_uInt16 n = reader.getFieldCount();
770 for (sal_uInt16 j = 0; j != n; ++j) {
771 mems.push_back(
772 ConstantGroupEntity::Member(
773 reader.getFieldName(j),
774 translateConstantValue(sub, reader.getFieldValue(j)),
775 translateAnnotations(reader.getFieldDocumentation(j))));
777 return new ConstantGroupEntity(
778 reader.isPublished(), mems,
779 translateAnnotations(reader.getDocumentation()));
781 default:
782 throw FileFormatException(
783 key.getRegistryName(),
784 ("legacy format: unexpected type class "
785 + OUString::number(reader.getTypeClass()) + " of key "
786 + sub.getName()));
792 LegacyProvider::LegacyProvider(Manager & manager, OUString const & uri):
793 manager_(manager)
795 Registry reg;
796 RegError e = reg.open(uri, RegAccessMode::READONLY);
797 switch (e) {
798 case RegError::NO_ERROR:
799 break;
800 case RegError::REGISTRY_NOT_EXISTS:
801 throw NoSuchFileException(uri);
802 default:
803 throw FileFormatException(
804 uri, "cannot open legacy file: " + OUString::number(static_cast<int>(e)));
806 RegistryKey root;
807 e = reg.openRootKey(root);
808 if (e != RegError::NO_ERROR) {
809 throw FileFormatException(
810 uri, "legacy format: cannot open root key: " + OUString::number(static_cast<int>(e)));
812 e = root.openKey("UCR", ucr_);
813 switch (e) {
814 case RegError::NO_ERROR:
815 case RegError::KEY_NOT_EXISTS: // such effectively empty files exist in the wild
816 break;
817 default:
818 throw FileFormatException(
819 uri, "legacy format: cannot open UCR key: " + OUString::number(static_cast<int>(e)));
823 rtl::Reference< MapCursor > LegacyProvider::createRootCursor() const {
824 return new Cursor(&manager_, ucr_, ucr_);
827 rtl::Reference< Entity > LegacyProvider::findEntity(OUString const & name)
828 const
830 return ucr_.isValid()
831 ? readEntity(&manager_, ucr_, ucr_, name.replace('.', '/'), true)
832 : rtl::Reference< Entity >();
835 LegacyProvider::~LegacyProvider() throw () {}
839 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */