Line data Source code
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 <cstring>
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 :
26 : namespace unoidl { namespace detail {
27 :
28 : namespace {
29 :
30 0 : std::vector< OUString > translateAnnotations(OUString const & documentation) {
31 0 : std::vector< OUString > ans;
32 0 : if (documentation.indexOf("@deprecated") != -1) {
33 : //TODO: this check is somewhat crude
34 0 : ans.push_back("deprecated");
35 : }
36 0 : return ans;
37 : }
38 :
39 0 : ConstantValue translateConstantValue(
40 : RegistryKey & key, RTConstValue const & value)
41 : {
42 0 : switch (value.m_type) {
43 : case RT_TYPE_BOOL:
44 0 : return ConstantValue(static_cast< bool >(value.m_value.aBool));
45 : case RT_TYPE_BYTE:
46 0 : return ConstantValue(value.m_value.aByte);
47 : case RT_TYPE_INT16:
48 0 : return ConstantValue(value.m_value.aShort);
49 : case RT_TYPE_UINT16:
50 0 : return ConstantValue(value.m_value.aUShort);
51 : case RT_TYPE_INT32:
52 0 : return ConstantValue(value.m_value.aLong);
53 : case RT_TYPE_UINT32:
54 0 : return ConstantValue(value.m_value.aULong);
55 : case RT_TYPE_INT64:
56 0 : return ConstantValue(value.m_value.aHyper);
57 : case RT_TYPE_UINT64:
58 0 : return ConstantValue(value.m_value.aUHyper);
59 : case RT_TYPE_FLOAT:
60 0 : return ConstantValue(value.m_value.aFloat);
61 : case RT_TYPE_DOUBLE:
62 0 : return ConstantValue(value.m_value.aDouble);
63 : default:
64 : throw FileFormatException(
65 : key.getRegistryName(),
66 0 : ("legacy format: unexpected type " + OUString::number(value.m_type)
67 0 : + " of value of a field of constant group with key "
68 0 : + key.getName()));
69 : }
70 : }
71 :
72 : rtl::Reference< Entity > readEntity(
73 : rtl::Reference< Manager > const & manager, RegistryKey & ucr,
74 : RegistryKey & key, OUString const & path, bool probe);
75 :
76 : class Cursor: public MapCursor {
77 : public:
78 : Cursor(
79 : rtl::Reference< Manager > const & manager, RegistryKey const & ucr,
80 : RegistryKey const & key);
81 :
82 : private:
83 0 : virtual ~Cursor() throw () {}
84 :
85 : virtual rtl::Reference< Entity > getNext(OUString * name) SAL_OVERRIDE;
86 :
87 : rtl::Reference< Manager > manager_;
88 : RegistryKey ucr_;
89 : RegistryKey key_;
90 : OUString prefix_;
91 : RegistryKeyNames names_;
92 : sal_uInt32 index_;
93 : };
94 :
95 0 : Cursor::Cursor(
96 : rtl::Reference< Manager > const & manager, RegistryKey const & ucr,
97 : RegistryKey const & key):
98 0 : manager_(manager), ucr_(ucr), key_(key), index_(0)
99 : {
100 0 : if (ucr_.isValid()) {
101 0 : prefix_ = key_.getName();
102 0 : if (!prefix_.endsWith("/")) {
103 0 : prefix_ += "/";
104 : }
105 0 : RegError e = key_.getKeyNames("", names_);
106 0 : if (e != RegError::NO_ERROR) {
107 : throw FileFormatException(
108 : key_.getRegistryName(),
109 0 : ("legacy format: cannot get sub-key names of " + key_.getName()
110 0 : + ": " + OUString::number(static_cast<int>(e))));
111 : }
112 : }
113 0 : }
114 :
115 0 : rtl::Reference< Entity > Cursor::getNext(OUString * name) {
116 : assert(name != 0);
117 0 : rtl::Reference< Entity > ent;
118 0 : if (index_ != names_.getLength()) {
119 0 : OUString path(names_.getElement(index_));
120 : assert(path.match(prefix_));
121 0 : *name = path.copy(prefix_.getLength());
122 0 : ent = readEntity(manager_, ucr_, key_, *name, false);
123 : assert(ent.is());
124 0 : ++index_;
125 : }
126 0 : return ent;
127 : }
128 :
129 : class Module: public ModuleEntity {
130 : public:
131 0 : Module(
132 : rtl::Reference< Manager > const & manager, RegistryKey const & ucr,
133 : RegistryKey const & key):
134 0 : manager_(manager), ucr_(ucr), key_(key)
135 0 : {}
136 :
137 : private:
138 0 : virtual ~Module() throw () {}
139 :
140 : virtual std::vector< OUString > getMemberNames() const SAL_OVERRIDE;
141 :
142 0 : virtual rtl::Reference< MapCursor > createCursor() const SAL_OVERRIDE
143 0 : { return new Cursor(manager_, ucr_, key_); }
144 :
145 : rtl::Reference< Manager > manager_;
146 : RegistryKey ucr_;
147 : mutable RegistryKey key_;
148 : };
149 :
150 0 : std::vector< OUString > Module::getMemberNames() const {
151 0 : RegistryKeyNames names;
152 0 : RegError e = key_.getKeyNames("", names);
153 0 : if (e != RegError::NO_ERROR) {
154 : throw FileFormatException(
155 : key_.getRegistryName(),
156 0 : ("legacy format: cannot get sub-key names of " + key_.getName()
157 0 : + ": " + OUString::number(static_cast<int>(e))));
158 : }
159 0 : std::vector< OUString > ns;
160 0 : for (sal_uInt32 i = 0; i != names.getLength(); ++i) {
161 0 : ns.push_back(names.getElement(i));
162 : }
163 0 : return ns;
164 : }
165 :
166 0 : typereg::Reader getReader(RegistryKey & key, std::vector< char > * buffer) {
167 : assert(buffer != 0);
168 : RegValueType type;
169 : sal_uInt32 size;
170 0 : RegError e = key.getValueInfo("", &type, &size);
171 0 : if (e != RegError::NO_ERROR) {
172 : throw FileFormatException(
173 : key.getRegistryName(),
174 0 : ("legacy format: cannot get value info about key " + key.getName()
175 0 : + ": " + OUString::number(static_cast<int>(e))));
176 : }
177 0 : if (type != RegValueType::BINARY) {
178 : throw FileFormatException(
179 : key.getRegistryName(),
180 0 : ("legacy format: unexpected value type " + OUString::number(static_cast<int>(type))
181 0 : + " of key " + key.getName()));
182 : }
183 0 : if (size == 0
184 : /*TODO: || size > std::numeric_limits< std::vector< char >::size_type >::max() */)
185 : {
186 : throw FileFormatException(
187 : key.getRegistryName(),
188 0 : ("legacy format: bad binary value size " + OUString::number(size)
189 0 : + " of key " + key.getName()));
190 : }
191 0 : buffer->resize(static_cast< std::vector< char >::size_type >(size));
192 0 : e = key.getValue("", &(*buffer)[0]);
193 0 : if (e != RegError::NO_ERROR) {
194 : throw FileFormatException(
195 : key.getRegistryName(),
196 0 : ("legacy format: cannot get binary value of key " + key.getName()
197 0 : + ": " + OUString::number(static_cast<int>(e))));
198 : }
199 0 : typereg::Reader reader(&(*buffer)[0], size, false, TYPEREG_VERSION_1);
200 0 : if (!reader.isValid()) {
201 : throw FileFormatException(
202 : key.getRegistryName(),
203 0 : "legacy format: malformed binary value of key " + key.getName());
204 : }
205 0 : return reader;
206 : }
207 :
208 0 : rtl::Reference< Entity > readEntity(
209 : rtl::Reference< Manager > const & manager, RegistryKey & ucr,
210 : RegistryKey & key, OUString const & path, bool probe)
211 : {
212 : assert(manager.is());
213 0 : RegistryKey sub;
214 0 : RegError e = key.openKey(path, sub);
215 0 : switch (e) {
216 : case RegError::NO_ERROR:
217 0 : break;
218 : case RegError::KEY_NOT_EXISTS:
219 0 : if (probe) {
220 0 : return rtl::Reference< Entity >();
221 : }
222 : // fall through
223 : default:
224 : throw FileFormatException(
225 : key.getRegistryName(),
226 0 : ("legacy format: cannot open sub-key " + path + " of "
227 0 : + key.getName() + ": " + OUString::number(static_cast<int>(e))));
228 : }
229 0 : std::vector< char > buf;
230 0 : typereg::Reader reader(getReader(sub, &buf));
231 0 : switch (reader.getTypeClass()) {
232 : case RT_TYPE_INTERFACE:
233 : {
234 0 : std::vector< AnnotatedReference > mandBases;
235 0 : sal_uInt16 n = reader.getSuperTypeCount();
236 0 : for (sal_uInt16 j = 0; j != n; ++j) {
237 : mandBases.push_back(
238 : AnnotatedReference(
239 : reader.getSuperTypeName(j).replace('/', '.'),
240 0 : std::vector< OUString >()));
241 : }
242 0 : std::vector< AnnotatedReference > optBases;
243 0 : n = reader.getReferenceCount();
244 0 : for (sal_uInt16 j = 0; j != n; ++j) {
245 : optBases.push_back(
246 : AnnotatedReference(
247 : reader.getReferenceTypeName(j).replace('/', '.'),
248 : translateAnnotations(
249 0 : reader.getReferenceDocumentation(j))));
250 : }
251 0 : sal_uInt16 methodCount = reader.getMethodCount();
252 0 : std::vector< InterfaceTypeEntity::Attribute > attrs;
253 0 : n = reader.getFieldCount(); // attributes
254 0 : for (sal_uInt16 j = 0; j != n; ++j) {
255 0 : OUString attrName(reader.getFieldName(j));
256 0 : std::vector< OUString > getExcs;
257 0 : std::vector< OUString > setExcs;
258 0 : for (sal_uInt16 k = 0; k != methodCount; ++k) {
259 0 : if (reader.getMethodName(k) == attrName) {
260 0 : switch (reader.getMethodFlags(k)) {
261 : case RTMethodMode::ATTRIBUTE_GET:
262 : {
263 : sal_uInt16 m
264 0 : = reader.getMethodExceptionCount(k);
265 : // coverity[tainted_data] cid#1213376
266 : // unhelpfully warns about an untrusted loop
267 : // bound here:
268 0 : for (sal_uInt16 l = 0; l != m; ++l) {
269 : getExcs.push_back(
270 : reader.getMethodExceptionTypeName(k, l).
271 0 : replace('/', '.'));
272 : }
273 0 : break;
274 : }
275 : case RTMethodMode::ATTRIBUTE_SET:
276 : {
277 : sal_uInt16 m
278 0 : = reader.getMethodExceptionCount(k);
279 : // coverity[tainted_data] cid#1213376
280 : // unhelpfully warns about an untrusted loop
281 : // bound here:
282 0 : for (sal_uInt16 l = 0; l != m; ++l) {
283 : setExcs.push_back(
284 : reader.getMethodExceptionTypeName(k, l).
285 0 : replace('/', '.'));
286 : }
287 0 : break;
288 : }
289 : default:
290 : throw FileFormatException(
291 : key.getRegistryName(),
292 : ("legacy format: method and attribute with same"
293 0 : " name " + attrName
294 0 : + " in interface type with key "
295 0 : + sub.getName()));
296 : }
297 : }
298 : }
299 0 : RTFieldAccess flags = reader.getFieldFlags(j);
300 : attrs.push_back(
301 : InterfaceTypeEntity::Attribute(
302 : attrName, reader.getFieldTypeName(j).replace('/', '.'),
303 0 : bool(flags & RTFieldAccess::BOUND),
304 0 : bool(flags & RTFieldAccess::READONLY), getExcs, setExcs,
305 0 : translateAnnotations(reader.getFieldDocumentation(j))));
306 0 : }
307 0 : std::vector< InterfaceTypeEntity::Method > meths;
308 0 : for (sal_uInt16 j = 0; j != methodCount; ++j) {
309 0 : RTMethodMode flags = reader.getMethodFlags(j);
310 0 : if (flags != RTMethodMode::ATTRIBUTE_GET
311 0 : && flags != RTMethodMode::ATTRIBUTE_SET)
312 : {
313 : std::vector< InterfaceTypeEntity::Method::Parameter >
314 0 : params;
315 0 : sal_uInt16 m = reader.getMethodParameterCount(j);
316 : // coverity[tainted_data] cid#1213376 unhelpfully warns
317 : // about an untrusted loop bound here:
318 0 : for (sal_uInt16 k = 0; k != m; ++k) {
319 0 : RTParamMode mode = reader.getMethodParameterFlags(j, k);
320 : InterfaceTypeEntity::Method::Parameter::Direction dir;
321 0 : switch (mode) {
322 : case RT_PARAM_IN:
323 0 : dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN;
324 0 : break;
325 : case RT_PARAM_OUT:
326 0 : dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT;
327 0 : break;
328 : case RT_PARAM_INOUT:
329 0 : dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT;
330 0 : break;
331 : default:
332 : throw FileFormatException(
333 : key.getRegistryName(),
334 : ("legacy format: unexpected mode "
335 0 : + OUString::number(mode) + " of parameter "
336 0 : + reader.getMethodParameterName(j, k)
337 0 : + " of method " + reader.getMethodName(j)
338 0 : + " in interface type with key "
339 0 : + sub.getName()));
340 : }
341 : params.push_back(
342 : InterfaceTypeEntity::Method::Parameter(
343 : reader.getMethodParameterName(j, k),
344 : (reader.getMethodParameterTypeName(j, k).
345 : replace('/', '.')),
346 0 : dir));
347 : }
348 0 : std::vector< OUString > excs;
349 0 : m = reader.getMethodExceptionCount(j);
350 : // coverity[tainted_data] cid#1213376 unhelpfully warns
351 : // about an untrusted loop bound here:
352 0 : for (sal_uInt16 k = 0; k != m; ++k) {
353 : excs.push_back(
354 : reader.getMethodExceptionTypeName(j, k).replace(
355 0 : '/', '.'));
356 : }
357 : meths.push_back(
358 : InterfaceTypeEntity::Method(
359 : reader.getMethodName(j),
360 : reader.getMethodReturnTypeName(j).replace('/', '.'),
361 : params, excs,
362 : translateAnnotations(
363 0 : reader.getMethodDocumentation(j))));
364 : }
365 : }
366 : return new InterfaceTypeEntity(
367 0 : reader.isPublished(), mandBases, optBases, attrs, meths,
368 0 : translateAnnotations(reader.getDocumentation()));
369 : }
370 : case RT_TYPE_MODULE:
371 0 : return new Module(manager, ucr, sub);
372 : case RT_TYPE_STRUCT:
373 : {
374 0 : sal_uInt32 n = reader.getReferenceCount();
375 0 : if (n == 0) {
376 0 : OUString base;
377 0 : switch (reader.getSuperTypeCount()) {
378 : case 0:
379 0 : break;
380 : case 1:
381 0 : base = reader.getSuperTypeName(0).replace('/', '.');
382 0 : break;
383 : default:
384 : FileFormatException(
385 : key.getRegistryName(),
386 : ("legacy format: unexpected number "
387 0 : + OUString::number(reader.getSuperTypeCount())
388 0 : + " of super-types of plain struct type with key "
389 0 : + sub.getName()));
390 : }
391 0 : std::vector< PlainStructTypeEntity::Member > mems;
392 0 : n = reader.getFieldCount();
393 0 : for (sal_uInt32 j = 0; j != n; ++j) {
394 : mems.push_back(
395 : PlainStructTypeEntity::Member(
396 : reader.getFieldName(j),
397 : reader.getFieldTypeName(j).replace('/', '.'),
398 : translateAnnotations(
399 0 : reader.getFieldDocumentation(j))));
400 : }
401 : return new PlainStructTypeEntity(
402 0 : reader.isPublished(), base, mems,
403 0 : translateAnnotations(reader.getDocumentation()));
404 : } else {
405 0 : if (reader.getSuperTypeCount() != 0) {
406 : FileFormatException(
407 : key.getRegistryName(),
408 : ("legacy format: unexpected number "
409 0 : + OUString::number(reader.getSuperTypeCount())
410 0 : + " of super-types of polymorphic struct type template"
411 0 : " with key " + sub.getName()));
412 : }
413 0 : std::vector< OUString > params;
414 0 : for (sal_uInt32 j = 0; j != n; ++j) {
415 : params.push_back(
416 0 : reader.getReferenceTypeName(j).replace('/', '.'));
417 : }
418 0 : std::vector< PolymorphicStructTypeTemplateEntity::Member > mems;
419 0 : n = reader.getFieldCount();
420 0 : for (sal_uInt32 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 0 : & RTFieldAccess::PARAMETERIZED_TYPE),
427 : translateAnnotations(
428 0 : reader.getFieldDocumentation(j))));
429 : }
430 : return new PolymorphicStructTypeTemplateEntity(
431 0 : reader.isPublished(), params, mems,
432 0 : translateAnnotations(reader.getDocumentation()));
433 : }
434 : }
435 : case RT_TYPE_ENUM:
436 : {
437 0 : std::vector< EnumTypeEntity::Member > mems;
438 0 : sal_uInt16 n = reader.getFieldCount();
439 0 : for (sal_uInt16 j = 0; j != n; ++j) {
440 0 : RTConstValue v(reader.getFieldValue(j));
441 0 : if (v.m_type != RT_TYPE_INT32) {
442 : FileFormatException(
443 : key.getRegistryName(),
444 : ("legacy format: unexpected type "
445 0 : + OUString::number(v.m_type) + " of value of field "
446 0 : + reader.getFieldName(j) + " of enum type with key "
447 0 : + sub.getName()));
448 : }
449 : mems.push_back(
450 : EnumTypeEntity::Member(
451 : reader.getFieldName(j), v.m_value.aLong,
452 0 : translateAnnotations(reader.getFieldDocumentation(j))));
453 :
454 0 : }
455 : return new EnumTypeEntity(
456 0 : reader.isPublished(), mems,
457 0 : translateAnnotations(reader.getDocumentation()));
458 : }
459 : case RT_TYPE_EXCEPTION:
460 : {
461 0 : OUString base;
462 0 : switch (reader.getSuperTypeCount()) {
463 : case 0:
464 0 : break;
465 : case 1:
466 0 : base = reader.getSuperTypeName(0).replace('/', '.');
467 0 : break;
468 : default:
469 : throw FileFormatException(
470 : key.getRegistryName(),
471 : ("legacy format: unexpected number "
472 0 : + OUString::number(reader.getSuperTypeCount())
473 0 : + " of super-types of exception type with key "
474 0 : + sub.getName()));
475 : }
476 0 : std::vector< ExceptionTypeEntity::Member > mems;
477 0 : sal_uInt16 n = reader.getFieldCount();
478 0 : 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 0 : translateAnnotations(reader.getFieldDocumentation(j))));
484 : }
485 : return new ExceptionTypeEntity(
486 0 : reader.isPublished(), base, mems,
487 0 : translateAnnotations(reader.getDocumentation()));
488 : }
489 : case RT_TYPE_TYPEDEF:
490 0 : if (reader.getSuperTypeCount() != 1) {
491 : throw FileFormatException(
492 : key.getRegistryName(),
493 : ("legacy format: unexpected number "
494 0 : + OUString::number(reader.getSuperTypeCount())
495 0 : + " of super-types of typedef with key " + sub.getName()));
496 : }
497 : return new TypedefEntity(
498 0 : reader.isPublished(), reader.getSuperTypeName(0).replace('/', '.'),
499 0 : translateAnnotations(reader.getDocumentation()));
500 : case RT_TYPE_SERVICE:
501 0 : switch (reader.getSuperTypeCount()) {
502 : case 0:
503 : {
504 0 : std::vector< AnnotatedReference > mandServs;
505 0 : std::vector< AnnotatedReference > optServs;
506 0 : std::vector< AnnotatedReference > mandIfcs;
507 0 : std::vector< AnnotatedReference > optIfcs;
508 0 : sal_uInt16 n = reader.getReferenceCount();
509 0 : for (sal_uInt16 j = 0; j != n; ++j) {
510 : AnnotatedReference base(
511 : reader.getReferenceTypeName(j).replace('/', '.'),
512 : translateAnnotations(
513 0 : reader.getReferenceDocumentation(j)));
514 0 : switch (reader.getReferenceSort(j)) {
515 : case RTReferenceType::EXPORTS:
516 0 : if (!(reader.getReferenceFlags(j) & RTFieldAccess::OPTIONAL))
517 : {
518 0 : mandServs.push_back(base);
519 : } else {
520 0 : optServs.push_back(base);
521 : }
522 0 : break;
523 : case RTReferenceType::SUPPORTS:
524 0 : if (!(reader.getReferenceFlags(j) & RTFieldAccess::OPTIONAL))
525 : {
526 0 : mandIfcs.push_back(base);
527 : } else {
528 0 : optIfcs.push_back(base);
529 : }
530 0 : break;
531 : default:
532 : throw FileFormatException(
533 : key.getRegistryName(),
534 : ("legacy format: unexpected mode "
535 0 : + OUString::number(static_cast<int>(reader.getReferenceSort(j)))
536 0 : + " of reference " + reader.getReferenceTypeName(j)
537 0 : + " in service with key " + sub.getName()));
538 : }
539 0 : }
540 0 : std::vector< AccumulationBasedServiceEntity::Property > props;
541 0 : n = reader.getFieldCount();
542 0 : for (sal_uInt16 j = 0; j != n; ++j) {
543 0 : RTFieldAccess acc = reader.getFieldFlags(j);
544 0 : int attrs = 0;
545 0 : if (acc & RTFieldAccess::READONLY) {
546 : attrs |= AccumulationBasedServiceEntity::Property::
547 0 : ATTRIBUTE_READ_ONLY;
548 : }
549 0 : if (acc & RTFieldAccess::OPTIONAL) {
550 : attrs |= AccumulationBasedServiceEntity::Property::
551 0 : ATTRIBUTE_OPTIONAL;
552 : }
553 0 : if (acc & RTFieldAccess::MAYBEVOID) {
554 : attrs |= AccumulationBasedServiceEntity::Property::
555 0 : ATTRIBUTE_MAYBE_VOID;
556 : }
557 0 : if (acc & RTFieldAccess::BOUND) {
558 : attrs |= AccumulationBasedServiceEntity::Property::
559 0 : ATTRIBUTE_BOUND;
560 : }
561 0 : if (acc & RTFieldAccess::CONSTRAINED) {
562 : attrs |= AccumulationBasedServiceEntity::Property::
563 0 : ATTRIBUTE_CONSTRAINED;
564 : }
565 0 : if (acc & RTFieldAccess::TRANSIENT) {
566 : attrs |= AccumulationBasedServiceEntity::Property::
567 0 : ATTRIBUTE_TRANSIENT;
568 : }
569 0 : if (acc & RTFieldAccess::MAYBEAMBIGUOUS) {
570 : attrs |= AccumulationBasedServiceEntity::Property::
571 0 : ATTRIBUTE_MAYBE_AMBIGUOUS;
572 : }
573 0 : if (acc & RTFieldAccess::MAYBEDEFAULT) {
574 : attrs |= AccumulationBasedServiceEntity::Property::
575 0 : ATTRIBUTE_MAYBE_DEFAULT;
576 : }
577 0 : if (acc & RTFieldAccess::REMOVABLE) {
578 : attrs |= AccumulationBasedServiceEntity::Property::
579 0 : ATTRIBUTE_REMOVABLE;
580 : }
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 0 : reader.getFieldDocumentation(j))));
590 : }
591 : return new AccumulationBasedServiceEntity(
592 0 : reader.isPublished(), mandServs, optServs, mandIfcs,
593 : optIfcs, props,
594 0 : translateAnnotations(reader.getDocumentation()));
595 : }
596 : case 1:
597 : {
598 : std::vector< SingleInterfaceBasedServiceEntity::Constructor >
599 0 : ctors;
600 0 : sal_uInt16 n = reader.getMethodCount();
601 0 : if (n == 1 && reader.getMethodFlags(0) == RTMethodMode::TWOWAY
602 0 : && reader.getMethodName(0).isEmpty()
603 0 : && reader.getMethodReturnTypeName(0) == "void"
604 0 : && reader.getMethodParameterCount(0) == 0
605 0 : && reader.getMethodExceptionCount(0) == 0)
606 : {
607 : ctors.push_back(
608 0 : SingleInterfaceBasedServiceEntity::Constructor());
609 : } else {
610 0 : for (sal_uInt16 j = 0; j != n; ++j) {
611 0 : if (reader.getMethodFlags(j) != RTMethodMode::TWOWAY) {
612 : throw FileFormatException(
613 : key.getRegistryName(),
614 : ("legacy format: unexpected mode "
615 0 : + OUString::number(static_cast<int>(reader.getMethodFlags(j)))
616 0 : + " of constructor " + reader.getMethodName(j)
617 0 : + " in service with key " + sub.getName()));
618 : }
619 : std::vector<
620 : SingleInterfaceBasedServiceEntity::Constructor::
621 0 : Parameter > params;
622 0 : sal_uInt16 m = reader.getMethodParameterCount(j);
623 : // coverity[tainted_data] cid#1213376 unhelpfully warns
624 : // about an untrusted loop bound here:
625 0 : for (sal_uInt16 k = 0; k != m; ++k) {
626 : RTParamMode mode
627 0 : = reader.getMethodParameterFlags(j, k);
628 0 : if ((mode & ~RT_PARAM_REST) != RT_PARAM_IN) {
629 : throw FileFormatException(
630 : key.getRegistryName(),
631 : ("legacy format: unexpected mode "
632 0 : + OUString::number(mode)
633 0 : + " of parameter "
634 0 : + reader.getMethodParameterName(j, k)
635 0 : + " of constructor "
636 0 : + reader.getMethodName(j)
637 0 : + " in service with key "
638 0 : + sub.getName()));
639 : }
640 0 : if ((mode & RT_PARAM_REST) != 0
641 0 : && !(m == 1
642 : && ((reader.getMethodParameterTypeName(
643 : j, 0))
644 0 : == "any")))
645 : {
646 : throw FileFormatException(
647 : key.getRegistryName(),
648 : ("legacy format: bad rest parameter "
649 0 : + reader.getMethodParameterName(j, k)
650 0 : + " of constructor "
651 0 : + reader.getMethodName(j)
652 0 : + " in service with key "
653 0 : + sub.getName()));
654 : }
655 : params.push_back(
656 : SingleInterfaceBasedServiceEntity::Constructor::
657 : Parameter(
658 : reader.getMethodParameterName(j, k),
659 : (reader.getMethodParameterTypeName(j, k).
660 : replace('/', '.')),
661 0 : (mode & RT_PARAM_REST) != 0));
662 : }
663 0 : std::vector< OUString > excs;
664 0 : m = reader.getMethodExceptionCount(j);
665 : // coverity[tainted_data] cid#1213376 unhelpfully warns
666 : // about an untrusted loop bound here:
667 0 : for (sal_uInt16 k = 0; k != m; ++k) {
668 : excs.push_back(
669 : reader.getMethodExceptionTypeName(j, k).replace(
670 0 : '/', '.'));
671 : }
672 : ctors.push_back(
673 : SingleInterfaceBasedServiceEntity::Constructor(
674 : reader.getMethodName(j), params, excs,
675 : translateAnnotations(
676 0 : reader.getMethodDocumentation(j))));
677 0 : }
678 : }
679 : return new SingleInterfaceBasedServiceEntity(
680 0 : reader.isPublished(),
681 : reader.getSuperTypeName(0).replace('/', '.'), ctors,
682 0 : translateAnnotations(reader.getDocumentation()));
683 : }
684 : default:
685 : throw FileFormatException(
686 : key.getRegistryName(),
687 : ("legacy format: unexpected number "
688 0 : + OUString::number(reader.getSuperTypeCount())
689 0 : + " of super-types of service with key " + sub.getName()));
690 : }
691 : case RT_TYPE_SINGLETON:
692 : {
693 0 : if (reader.getSuperTypeCount() != 1) {
694 : throw FileFormatException(
695 : key.getRegistryName(),
696 : ("legacy format: unexpected number "
697 0 : + OUString::number(reader.getSuperTypeCount())
698 0 : + " of super-types of singleton with key "
699 0 : + sub.getName()));
700 : }
701 0 : OUString basePath(reader.getSuperTypeName(0));
702 0 : OUString baseName(basePath.replace('/', '.'));
703 : bool newStyle;
704 0 : rtl::Reference< Entity > base(manager->findEntity(baseName));
705 0 : if (base.is()) {
706 0 : switch (base->getSort()) {
707 : case Entity::SORT_INTERFACE_TYPE:
708 0 : newStyle = true;
709 0 : break;
710 : case Entity::SORT_ACCUMULATION_BASED_SERVICE:
711 0 : newStyle = false;
712 0 : break;
713 : default:
714 : throw FileFormatException(
715 : key.getRegistryName(),
716 : ("legacy format: unexpected sort "
717 0 : + OUString::number(base->getSort()) + " of base "
718 0 : + baseName + " of singleton with key "
719 0 : + sub.getName()));
720 : }
721 : } else {
722 0 : RegistryKey key2;
723 0 : e = ucr.openKey(basePath, key2);
724 0 : switch (e) {
725 : case RegError::NO_ERROR:
726 0 : break;
727 : case RegError::KEY_NOT_EXISTS:
728 : throw FileFormatException(
729 : key.getRegistryName(),
730 0 : ("legacy format: unknown super-type " + basePath
731 0 : + " of super-type with key " + sub.getName()));
732 : default:
733 : throw FileFormatException(
734 : key.getRegistryName(),
735 0 : ("legacy format: cannot open ucr sub-key " + basePath
736 0 : + ": " + OUString::number(static_cast<int>(e))));
737 : }
738 0 : std::vector< char > buf2;
739 0 : typereg::Reader reader2(getReader(key2, &buf2));
740 0 : switch (reader2.getTypeClass()) {
741 : case RT_TYPE_INTERFACE:
742 0 : newStyle = true;
743 0 : break;
744 : case RT_TYPE_SERVICE:
745 0 : newStyle = false;
746 0 : break;
747 : default:
748 : throw FileFormatException(
749 : key.getRegistryName(),
750 : ("legacy format: unexpected type class "
751 0 : + OUString::number(reader2.getTypeClass())
752 0 : + " of super-type with key " + key2.getName()
753 0 : + " of singleton with key " + sub.getName()));
754 0 : }
755 : }
756 : return newStyle
757 : ? rtl::Reference< Entity >(
758 : new InterfaceBasedSingletonEntity(
759 0 : reader.isPublished(), baseName,
760 0 : translateAnnotations(reader.getDocumentation())))
761 : : rtl::Reference< Entity >(
762 : new ServiceBasedSingletonEntity(
763 0 : reader.isPublished(), baseName,
764 0 : translateAnnotations(reader.getDocumentation())));
765 : }
766 : case RT_TYPE_CONSTANTS:
767 : {
768 0 : std::vector< ConstantGroupEntity::Member > mems;
769 0 : sal_uInt16 n = reader.getFieldCount();
770 0 : for (sal_uInt16 j = 0; j != n; ++j) {
771 : mems.push_back(
772 : ConstantGroupEntity::Member(
773 : reader.getFieldName(j),
774 0 : translateConstantValue(sub, reader.getFieldValue(j)),
775 0 : translateAnnotations(reader.getFieldDocumentation(j))));
776 : }
777 : return new ConstantGroupEntity(
778 0 : reader.isPublished(), mems,
779 0 : translateAnnotations(reader.getDocumentation()));
780 : }
781 : default:
782 : throw FileFormatException(
783 : key.getRegistryName(),
784 : ("legacy format: unexpected type class "
785 0 : + OUString::number(reader.getTypeClass()) + " of key "
786 0 : + sub.getName()));
787 0 : }
788 : }
789 :
790 : }
791 :
792 0 : LegacyProvider::LegacyProvider(Manager & manager, OUString const & uri):
793 0 : manager_(manager)
794 : {
795 0 : Registry reg;
796 0 : RegError e = reg.open(uri, RegAccessMode::READONLY);
797 0 : switch (e) {
798 : case RegError::NO_ERROR:
799 0 : break;
800 : case RegError::REGISTRY_NOT_EXISTS:
801 0 : throw NoSuchFileException(uri);
802 : default:
803 : throw FileFormatException(
804 0 : uri, "cannot open legacy file: " + OUString::number(static_cast<int>(e)));
805 : }
806 0 : RegistryKey root;
807 0 : e = reg.openRootKey(root);
808 0 : if (e != RegError::NO_ERROR) {
809 : throw FileFormatException(
810 0 : uri, "legacy format: cannot open root key: " + OUString::number(static_cast<int>(e)));
811 : }
812 0 : e = root.openKey("UCR", ucr_);
813 0 : switch (e) {
814 : case RegError::NO_ERROR:
815 : case RegError::KEY_NOT_EXISTS: // such effectively empty files exist in the wild
816 0 : break;
817 : default:
818 : throw FileFormatException(
819 0 : uri, "legacy format: cannot open UCR key: " + OUString::number(static_cast<int>(e)));
820 0 : }
821 0 : }
822 :
823 0 : rtl::Reference< MapCursor > LegacyProvider::createRootCursor() const {
824 0 : return new Cursor(&manager_, ucr_, ucr_);
825 : }
826 :
827 0 : rtl::Reference< Entity > LegacyProvider::findEntity(OUString const & name)
828 : const
829 : {
830 0 : return ucr_.isValid()
831 : ? readEntity(&manager_, ucr_, ucr_, name.replace('.', '/'), true)
832 0 : : rtl::Reference< Entity >();
833 : }
834 :
835 0 : LegacyProvider::~LegacyProvider() throw () {}
836 :
837 : } }
838 :
839 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|