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 != REG_NO_ERROR) {
107 : throw FileFormatException(
108 : key_.getRegistryName(),
109 0 : ("legacy format: cannot get sub-key names of " + key_.getName()
110 0 : + ": " + OUString::number(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 != REG_NO_ERROR) {
154 : throw FileFormatException(
155 : key_.getRegistryName(),
156 0 : ("legacy format: cannot get sub-key names of " + key_.getName()
157 0 : + ": " + OUString::number(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 != REG_NO_ERROR) {
172 : throw FileFormatException(
173 : key.getRegistryName(),
174 0 : ("legacy format: cannot get value info about key " + key.getName()
175 0 : + ": " + OUString::number(e)));
176 : }
177 0 : if (type != RG_VALUETYPE_BINARY) {
178 : throw FileFormatException(
179 : key.getRegistryName(),
180 0 : ("legacy format: unexpected value type " + OUString::number(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 != REG_NO_ERROR) {
194 : throw FileFormatException(
195 : key.getRegistryName(),
196 0 : ("legacy format: cannot get binary value of key " + key.getName()
197 0 : + ": " + OUString::number(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 REG_NO_ERROR:
217 0 : break;
218 : case REG_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(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 RT_MODE_ATTRIBUTE_GET:
262 : {
263 : sal_uInt16 m
264 0 : = reader.getMethodExceptionCount(k);
265 0 : for (sal_uInt16 l = 0; l != m; ++l) {
266 : getExcs.push_back(
267 : reader.getMethodExceptionTypeName(k, l).
268 0 : replace('/', '.'));
269 : }
270 0 : break;
271 : }
272 : case RT_MODE_ATTRIBUTE_SET:
273 : {
274 : sal_uInt16 m
275 0 : = reader.getMethodExceptionCount(k);
276 0 : for (sal_uInt16 l = 0; l != m; ++l) {
277 : setExcs.push_back(
278 : reader.getMethodExceptionTypeName(k, l).
279 0 : replace('/', '.'));
280 : }
281 0 : break;
282 : }
283 : default:
284 : throw FileFormatException(
285 : key.getRegistryName(),
286 : ("legacy format: method and attribute with same"
287 0 : " name " + attrName
288 0 : + " in interface type with key "
289 0 : + sub.getName()));
290 : }
291 : }
292 : }
293 0 : RTFieldAccess flags = reader.getFieldFlags(j);
294 : attrs.push_back(
295 : InterfaceTypeEntity::Attribute(
296 : attrName, reader.getFieldTypeName(j).replace('/', '.'),
297 0 : (flags & RT_ACCESS_BOUND) != 0,
298 0 : (flags & RT_ACCESS_READONLY) != 0, getExcs, setExcs,
299 0 : translateAnnotations(reader.getFieldDocumentation(j))));
300 0 : }
301 0 : std::vector< InterfaceTypeEntity::Method > meths;
302 0 : for (sal_uInt16 j = 0; j != methodCount; ++j) {
303 0 : RTMethodMode flags = reader.getMethodFlags(j);
304 0 : if (flags != RT_MODE_ATTRIBUTE_GET
305 0 : && flags != RT_MODE_ATTRIBUTE_SET)
306 : {
307 : std::vector< InterfaceTypeEntity::Method::Parameter >
308 0 : params;
309 0 : sal_uInt16 m = reader.getMethodParameterCount(j);
310 0 : for (sal_uInt16 k = 0; k != m; ++k) {
311 0 : RTParamMode mode = reader.getMethodParameterFlags(j, k);
312 : InterfaceTypeEntity::Method::Parameter::Direction dir;
313 0 : switch (mode) {
314 : case RT_PARAM_IN:
315 0 : dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN;
316 0 : break;
317 : case RT_PARAM_OUT:
318 0 : dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT;
319 0 : break;
320 : case RT_PARAM_INOUT:
321 0 : dir = InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT;
322 0 : break;
323 : default:
324 : throw FileFormatException(
325 : key.getRegistryName(),
326 : ("legacy format: unexpected mode "
327 0 : + OUString::number(mode) + " of parameter "
328 0 : + reader.getMethodParameterName(j, k)
329 0 : + " of method " + reader.getMethodName(j)
330 0 : + " in interface type with key "
331 0 : + sub.getName()));
332 : }
333 : params.push_back(
334 : InterfaceTypeEntity::Method::Parameter(
335 : reader.getMethodParameterName(j, k),
336 : (reader.getMethodParameterTypeName(j, k).
337 : replace('/', '.')),
338 0 : dir));
339 : }
340 0 : std::vector< OUString > excs;
341 0 : m = reader.getMethodExceptionCount(j);
342 0 : for (sal_uInt16 k = 0; k != m; ++k) {
343 : excs.push_back(
344 : reader.getMethodExceptionTypeName(j, k).replace(
345 0 : '/', '.'));
346 : }
347 : meths.push_back(
348 : InterfaceTypeEntity::Method(
349 : reader.getMethodName(j),
350 : reader.getMethodReturnTypeName(j).replace('/', '.'),
351 : params, excs,
352 : translateAnnotations(
353 0 : reader.getMethodDocumentation(j))));
354 : }
355 : }
356 : return new InterfaceTypeEntity(
357 0 : reader.isPublished(), mandBases, optBases, attrs, meths,
358 0 : translateAnnotations(reader.getDocumentation()));
359 : }
360 : case RT_TYPE_MODULE:
361 0 : return new Module(manager, ucr, sub);
362 : case RT_TYPE_STRUCT:
363 : {
364 0 : sal_uInt32 n = reader.getReferenceCount();
365 0 : if (n == 0) {
366 0 : OUString base;
367 0 : switch (reader.getSuperTypeCount()) {
368 : case 0:
369 0 : break;
370 : case 1:
371 0 : base = reader.getSuperTypeName(0).replace('/', '.');
372 0 : break;
373 : default:
374 : FileFormatException(
375 : key.getRegistryName(),
376 : ("legacy format: unexpected number "
377 0 : + OUString::number(reader.getSuperTypeCount())
378 0 : + " of super-types of plain struct type with key "
379 0 : + sub.getName()));
380 : }
381 0 : std::vector< PlainStructTypeEntity::Member > mems;
382 0 : n = reader.getFieldCount();
383 0 : for (sal_uInt16 j = 0; j != n; ++j) {
384 : mems.push_back(
385 : PlainStructTypeEntity::Member(
386 : reader.getFieldName(j),
387 : reader.getFieldTypeName(j).replace('/', '.'),
388 : translateAnnotations(
389 0 : reader.getFieldDocumentation(j))));
390 : }
391 : return new PlainStructTypeEntity(
392 0 : reader.isPublished(), base, mems,
393 0 : translateAnnotations(reader.getDocumentation()));
394 : } else {
395 0 : if (reader.getSuperTypeCount() != 0) {
396 : FileFormatException(
397 : key.getRegistryName(),
398 : ("legacy format: unexpected number "
399 0 : + OUString::number(reader.getSuperTypeCount())
400 0 : + " of super-types of polymorphic struct type template"
401 0 : " with key " + sub.getName()));
402 : }
403 0 : std::vector< OUString > params;
404 0 : for (sal_uInt16 j = 0; j != n; ++j) {
405 : params.push_back(
406 0 : reader.getReferenceTypeName(j).replace('/', '.'));
407 : }
408 0 : std::vector< PolymorphicStructTypeTemplateEntity::Member > mems;
409 0 : n = reader.getFieldCount();
410 0 : for (sal_uInt16 j = 0; j != n; ++j) {
411 : mems.push_back(
412 : PolymorphicStructTypeTemplateEntity::Member(
413 : reader.getFieldName(j),
414 : reader.getFieldTypeName(j).replace('/', '.'),
415 0 : ((reader.getFieldFlags(j)
416 0 : & RT_ACCESS_PARAMETERIZED_TYPE)
417 : != 0),
418 : translateAnnotations(
419 0 : reader.getFieldDocumentation(j))));
420 : }
421 : return new PolymorphicStructTypeTemplateEntity(
422 0 : reader.isPublished(), params, mems,
423 0 : translateAnnotations(reader.getDocumentation()));
424 : }
425 : }
426 : case RT_TYPE_ENUM:
427 : {
428 0 : std::vector< EnumTypeEntity::Member > mems;
429 0 : sal_uInt16 n = reader.getFieldCount();
430 0 : for (sal_uInt16 j = 0; j != n; ++j) {
431 0 : RTConstValue v(reader.getFieldValue(j));
432 0 : if (v.m_type != RT_TYPE_INT32) {
433 : FileFormatException(
434 : key.getRegistryName(),
435 : ("legacy format: unexpected type "
436 0 : + OUString::number(v.m_type) + " of value of field "
437 0 : + reader.getFieldName(j) + " of enum type with key "
438 0 : + sub.getName()));
439 : }
440 : mems.push_back(
441 : EnumTypeEntity::Member(
442 : reader.getFieldName(j), v.m_value.aLong,
443 0 : translateAnnotations(reader.getFieldDocumentation(j))));
444 :
445 0 : }
446 : return new EnumTypeEntity(
447 0 : reader.isPublished(), mems,
448 0 : translateAnnotations(reader.getDocumentation()));
449 : }
450 : case RT_TYPE_EXCEPTION:
451 : {
452 0 : OUString base;
453 0 : switch (reader.getSuperTypeCount()) {
454 : case 0:
455 0 : break;
456 : case 1:
457 0 : base = reader.getSuperTypeName(0).replace('/', '.');
458 0 : break;
459 : default:
460 : throw FileFormatException(
461 : key.getRegistryName(),
462 : ("legacy format: unexpected number "
463 0 : + OUString::number(reader.getSuperTypeCount())
464 0 : + " of super-types of exception type with key "
465 0 : + sub.getName()));
466 : }
467 0 : std::vector< ExceptionTypeEntity::Member > mems;
468 0 : sal_uInt16 n = reader.getFieldCount();
469 0 : for (sal_uInt16 j = 0; j != n; ++j) {
470 : mems.push_back(
471 : ExceptionTypeEntity::Member(
472 : reader.getFieldName(j),
473 : reader.getFieldTypeName(j).replace('/', '.'),
474 0 : translateAnnotations(reader.getFieldDocumentation(j))));
475 : }
476 : return new ExceptionTypeEntity(
477 0 : reader.isPublished(), base, mems,
478 0 : translateAnnotations(reader.getDocumentation()));
479 : }
480 : case RT_TYPE_TYPEDEF:
481 0 : if (reader.getSuperTypeCount() != 1) {
482 : throw FileFormatException(
483 : key.getRegistryName(),
484 : ("legacy format: unexpected number "
485 0 : + OUString::number(reader.getSuperTypeCount())
486 0 : + " of super-types of typedef with key " + sub.getName()));
487 : }
488 : return new TypedefEntity(
489 0 : reader.isPublished(), reader.getSuperTypeName(0).replace('/', '.'),
490 0 : translateAnnotations(reader.getDocumentation()));
491 : case RT_TYPE_SERVICE:
492 0 : switch (reader.getSuperTypeCount()) {
493 : case 0:
494 : {
495 0 : std::vector< AnnotatedReference > mandServs;
496 0 : std::vector< AnnotatedReference > optServs;
497 0 : std::vector< AnnotatedReference > mandIfcs;
498 0 : std::vector< AnnotatedReference > optIfcs;
499 0 : sal_uInt16 n = reader.getReferenceCount();
500 0 : for (sal_uInt16 j = 0; j != n; ++j) {
501 : AnnotatedReference base(
502 : reader.getReferenceTypeName(j).replace('/', '.'),
503 : translateAnnotations(
504 0 : reader.getReferenceDocumentation(j)));
505 0 : switch (reader.getReferenceSort(j)) {
506 : case RT_REF_EXPORTS:
507 0 : if ((reader.getReferenceFlags(j) & RT_ACCESS_OPTIONAL)
508 : == 0)
509 : {
510 0 : mandServs.push_back(base);
511 : } else {
512 0 : optServs.push_back(base);
513 : }
514 0 : break;
515 : case RT_REF_SUPPORTS:
516 0 : if ((reader.getReferenceFlags(j) & RT_ACCESS_OPTIONAL)
517 : == 0)
518 : {
519 0 : mandIfcs.push_back(base);
520 : } else {
521 0 : optIfcs.push_back(base);
522 : }
523 0 : break;
524 : default:
525 : throw FileFormatException(
526 : key.getRegistryName(),
527 : ("legacy format: unexpected mode "
528 0 : + OUString::number(reader.getReferenceSort(j))
529 0 : + " of reference " + reader.getReferenceTypeName(j)
530 0 : + " in service with key " + sub.getName()));
531 : }
532 0 : }
533 0 : std::vector< AccumulationBasedServiceEntity::Property > props;
534 0 : n = reader.getFieldCount();
535 0 : for (sal_uInt16 j = 0; j != n; ++j) {
536 0 : RTFieldAccess acc = reader.getFieldFlags(j);
537 0 : int attrs = 0;
538 0 : if ((acc & RT_ACCESS_READONLY) != 0) {
539 : attrs |= AccumulationBasedServiceEntity::Property::
540 0 : ATTRIBUTE_READ_ONLY;
541 : }
542 0 : if ((acc & RT_ACCESS_OPTIONAL) != 0) {
543 : attrs |= AccumulationBasedServiceEntity::Property::
544 0 : ATTRIBUTE_OPTIONAL;
545 : }
546 0 : if ((acc & RT_ACCESS_MAYBEVOID) != 0) {
547 : attrs |= AccumulationBasedServiceEntity::Property::
548 0 : ATTRIBUTE_MAYBE_VOID;
549 : }
550 0 : if ((acc & RT_ACCESS_BOUND) != 0) {
551 : attrs |= AccumulationBasedServiceEntity::Property::
552 0 : ATTRIBUTE_BOUND;
553 : }
554 0 : if ((acc & RT_ACCESS_CONSTRAINED) != 0) {
555 : attrs |= AccumulationBasedServiceEntity::Property::
556 0 : ATTRIBUTE_CONSTRAINED;
557 : }
558 0 : if ((acc & RT_ACCESS_TRANSIENT) != 0) {
559 : attrs |= AccumulationBasedServiceEntity::Property::
560 0 : ATTRIBUTE_TRANSIENT;
561 : }
562 0 : if ((acc & RT_ACCESS_MAYBEAMBIGUOUS) != 0) {
563 : attrs |= AccumulationBasedServiceEntity::Property::
564 0 : ATTRIBUTE_MAYBE_AMBIGUOUS;
565 : }
566 0 : if ((acc & RT_ACCESS_MAYBEDEFAULT) != 0) {
567 : attrs |= AccumulationBasedServiceEntity::Property::
568 0 : ATTRIBUTE_MAYBE_DEFAULT;
569 : }
570 0 : if ((acc & RT_ACCESS_REMOVABLE) != 0) {
571 : attrs |= AccumulationBasedServiceEntity::Property::
572 0 : ATTRIBUTE_REMOVABLE;
573 : }
574 : props.push_back(
575 : AccumulationBasedServiceEntity::Property(
576 : reader.getFieldName(j),
577 : reader.getFieldTypeName(j).replace('/', '.'),
578 : static_cast<
579 : AccumulationBasedServiceEntity::Property::
580 : Attributes >(attrs),
581 : translateAnnotations(
582 0 : reader.getFieldDocumentation(j))));
583 : }
584 : return new AccumulationBasedServiceEntity(
585 0 : reader.isPublished(), mandServs, optServs, mandIfcs,
586 : optIfcs, props,
587 0 : translateAnnotations(reader.getDocumentation()));
588 : }
589 : case 1:
590 : {
591 : std::vector< SingleInterfaceBasedServiceEntity::Constructor >
592 0 : ctors;
593 0 : sal_uInt16 n = reader.getMethodCount();
594 0 : if (n == 1 && reader.getMethodFlags(0) == RT_MODE_TWOWAY
595 0 : && reader.getMethodName(0).isEmpty()
596 0 : && reader.getMethodReturnTypeName(0) == "void"
597 0 : && reader.getMethodParameterCount(0) == 0
598 0 : && reader.getMethodExceptionCount(0) == 0)
599 : {
600 : ctors.push_back(
601 0 : SingleInterfaceBasedServiceEntity::Constructor());
602 : } else {
603 0 : for (sal_uInt16 j = 0; j != n; ++j) {
604 0 : if (reader.getMethodFlags(j) != RT_MODE_TWOWAY) {
605 : throw FileFormatException(
606 : key.getRegistryName(),
607 : ("legacy format: unexpected mode "
608 0 : + OUString::number(reader.getMethodFlags(j))
609 0 : + " of constructor " + reader.getMethodName(j)
610 0 : + " in service with key " + sub.getName()));
611 : }
612 : std::vector<
613 : SingleInterfaceBasedServiceEntity::Constructor::
614 0 : Parameter > params;
615 0 : sal_uInt16 m = reader.getMethodParameterCount(j);
616 0 : for (sal_uInt16 k = 0; k != m; ++k) {
617 : RTParamMode mode
618 0 : = reader.getMethodParameterFlags(j, k);
619 0 : if ((mode & ~RT_PARAM_REST) != RT_PARAM_IN) {
620 : throw FileFormatException(
621 : key.getRegistryName(),
622 : ("legacy format: unexpected mode "
623 0 : + OUString::number(mode)
624 0 : + " of parameter "
625 0 : + reader.getMethodParameterName(j, k)
626 0 : + " of constructor "
627 0 : + reader.getMethodName(j)
628 0 : + " in service with key "
629 0 : + sub.getName()));
630 : }
631 0 : if ((mode & RT_PARAM_REST) != 0
632 0 : && !(m == 1
633 : && ((reader.getMethodParameterTypeName(
634 : j, 0))
635 0 : == "any")))
636 : {
637 : throw FileFormatException(
638 : key.getRegistryName(),
639 : ("legacy format: bad rest parameter "
640 0 : + reader.getMethodParameterName(j, k)
641 0 : + " of constructor "
642 0 : + reader.getMethodName(j)
643 0 : + " in service with key "
644 0 : + sub.getName()));
645 : }
646 : params.push_back(
647 : SingleInterfaceBasedServiceEntity::Constructor::
648 : Parameter(
649 : reader.getMethodParameterName(j, k),
650 : (reader.getMethodParameterTypeName(j, k).
651 : replace('/', '.')),
652 0 : (mode & RT_PARAM_REST) != 0));
653 : }
654 0 : std::vector< OUString > excs;
655 0 : m = reader.getMethodExceptionCount(j);
656 0 : for (sal_uInt16 k = 0; k != m; ++k) {
657 : excs.push_back(
658 : reader.getMethodExceptionTypeName(j, k).replace(
659 0 : '/', '.'));
660 : }
661 : ctors.push_back(
662 : SingleInterfaceBasedServiceEntity::Constructor(
663 : reader.getMethodName(j), params, excs,
664 : translateAnnotations(
665 0 : reader.getMethodDocumentation(j))));
666 0 : }
667 : }
668 : return new SingleInterfaceBasedServiceEntity(
669 0 : reader.isPublished(),
670 : reader.getSuperTypeName(0).replace('/', '.'), ctors,
671 0 : translateAnnotations(reader.getDocumentation()));
672 : }
673 : default:
674 : throw FileFormatException(
675 : key.getRegistryName(),
676 : ("legacy format: unexpected number "
677 0 : + OUString::number(reader.getSuperTypeCount())
678 0 : + " of super-types of service with key " + sub.getName()));
679 : }
680 : case RT_TYPE_SINGLETON:
681 : {
682 0 : if (reader.getSuperTypeCount() != 1) {
683 : throw FileFormatException(
684 : key.getRegistryName(),
685 : ("legacy format: unexpected number "
686 0 : + OUString::number(reader.getSuperTypeCount())
687 0 : + " of super-types of singleton with key "
688 0 : + sub.getName()));
689 : }
690 0 : OUString basePath(reader.getSuperTypeName(0));
691 0 : OUString baseName(basePath.replace('/', '.'));
692 : bool newStyle;
693 0 : rtl::Reference< Entity > base(manager->findEntity(baseName));
694 0 : if (base.is()) {
695 0 : switch (base->getSort()) {
696 : case Entity::SORT_INTERFACE_TYPE:
697 0 : newStyle = true;
698 0 : break;
699 : case Entity::SORT_ACCUMULATION_BASED_SERVICE:
700 0 : newStyle = false;
701 0 : break;
702 : default:
703 : throw FileFormatException(
704 : key.getRegistryName(),
705 : ("legacy format: unexpected sort "
706 0 : + OUString::number(base->getSort()) + " of base "
707 0 : + baseName + " of singleton with key "
708 0 : + sub.getName()));
709 : }
710 : } else {
711 0 : RegistryKey key2;
712 0 : e = ucr.openKey(basePath, key2);
713 0 : switch (e) {
714 : case REG_NO_ERROR:
715 0 : break;
716 : case REG_KEY_NOT_EXISTS:
717 : throw FileFormatException(
718 : key.getRegistryName(),
719 0 : ("legacy format: unknown super-type " + basePath
720 0 : + " of super-type with key " + sub.getName()));
721 : default:
722 : throw FileFormatException(
723 : key.getRegistryName(),
724 0 : ("legacy format: cannot open ucr sub-key " + basePath
725 0 : + ": " + OUString::number(e)));
726 : }
727 0 : std::vector< char > buf2;
728 0 : typereg::Reader reader2(getReader(key2, &buf2));
729 0 : switch (reader2.getTypeClass()) {
730 : case RT_TYPE_INTERFACE:
731 0 : newStyle = true;
732 0 : break;
733 : case RT_TYPE_SERVICE:
734 0 : newStyle = false;
735 0 : break;
736 : default:
737 : throw FileFormatException(
738 : key.getRegistryName(),
739 : ("legacy format: unexpected type class "
740 0 : + OUString::number(reader2.getTypeClass())
741 0 : + " of super-type with key " + key2.getName()
742 0 : + " of singleton with key " + sub.getName()));
743 0 : }
744 : }
745 : return newStyle
746 : ? rtl::Reference< Entity >(
747 : new InterfaceBasedSingletonEntity(
748 0 : reader.isPublished(), baseName,
749 0 : translateAnnotations(reader.getDocumentation())))
750 : : rtl::Reference< Entity >(
751 : new ServiceBasedSingletonEntity(
752 0 : reader.isPublished(), baseName,
753 0 : translateAnnotations(reader.getDocumentation())));
754 : }
755 : case RT_TYPE_CONSTANTS:
756 : {
757 0 : std::vector< ConstantGroupEntity::Member > mems;
758 0 : sal_uInt16 n = reader.getFieldCount();
759 0 : for (sal_uInt16 j = 0; j != n; ++j) {
760 : mems.push_back(
761 : ConstantGroupEntity::Member(
762 : reader.getFieldName(j),
763 0 : translateConstantValue(sub, reader.getFieldValue(j)),
764 0 : translateAnnotations(reader.getFieldDocumentation(j))));
765 : }
766 : return new ConstantGroupEntity(
767 0 : reader.isPublished(), mems,
768 0 : translateAnnotations(reader.getDocumentation()));
769 : }
770 : default:
771 : throw FileFormatException(
772 : key.getRegistryName(),
773 : ("legacy format: unexpected type class "
774 0 : + OUString::number(reader.getTypeClass()) + " of key "
775 0 : + sub.getName()));
776 0 : }
777 : }
778 :
779 : }
780 :
781 0 : LegacyProvider::LegacyProvider(
782 : rtl::Reference< Manager > const & manager, OUString const & uri):
783 0 : manager_(manager)
784 : {
785 0 : Registry reg;
786 0 : RegError e = reg.open(uri, REG_READONLY);
787 0 : switch (e) {
788 : case REG_NO_ERROR:
789 0 : break;
790 : case REG_REGISTRY_NOT_EXISTS:
791 0 : throw NoSuchFileException(uri);
792 : default:
793 : throw FileFormatException(
794 0 : uri, "cannot open legacy file: " + OUString::number(e));
795 : }
796 0 : RegistryKey root;
797 0 : e = reg.openRootKey(root);
798 0 : if (e != REG_NO_ERROR) {
799 : throw FileFormatException(
800 0 : uri, "legacy format: cannot open root key: " + OUString::number(e));
801 : }
802 0 : e = root.openKey("UCR", ucr_);
803 0 : switch (e) {
804 : case REG_NO_ERROR:
805 : case REG_KEY_NOT_EXISTS: // such effectively empty files exist in the wild
806 0 : break;
807 : default:
808 : throw FileFormatException(
809 0 : uri, "legacy format: cannot open UCR key: " + OUString::number(e));
810 0 : }
811 0 : }
812 :
813 0 : rtl::Reference< MapCursor > LegacyProvider::createRootCursor() const {
814 0 : return new Cursor(manager_, ucr_, ucr_);
815 : }
816 :
817 0 : rtl::Reference< Entity > LegacyProvider::findEntity(OUString const & name)
818 : const
819 : {
820 0 : return ucr_.isValid()
821 : ? readEntity(manager_, ucr_, ucr_, name.replace('.', '/'), true)
822 0 : : rtl::Reference< Entity >();
823 : }
824 :
825 0 : LegacyProvider::~LegacyProvider() throw () {}
826 :
827 : } }
828 :
829 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|