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