1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "rtl/alloc.h"
25 #include "registry/writer.hxx"
26
27 #include "com/sun/star/beans/PropertyAttribute.hpp"
28 #include "com/sun/star/container/XHierarchicalNameAccess.hpp"
29 #include "com/sun/star/reflection/XPublished.hpp"
30 #include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp"
31 #include "com/sun/star/reflection/XSingletonTypeDescription2.hpp"
32 #include "com/sun/star/reflection/XServiceTypeDescription2.hpp"
33 #include "com/sun/star/reflection/XStructTypeDescription.hpp"
34 #include "com/sun/star/reflection/XConstantsTypeDescription.hpp"
35 #include "com/sun/star/reflection/XConstantTypeDescription.hpp"
36 #include "com/sun/star/reflection/XModuleTypeDescription.hpp"
37 #include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp"
38 #include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp"
39 #include "com/sun/star/reflection/XMethodParameter.hpp"
40 #include "com/sun/star/reflection/XCompoundTypeDescription.hpp"
41 #include "com/sun/star/reflection/XIndirectTypeDescription.hpp"
42 #include "com/sun/star/reflection/XEnumTypeDescription.hpp"
43
44 #include "codemaker/generatedtypeset.hxx"
45
46 using namespace com::sun::star::uno;
47 using namespace com::sun::star::beans;
48 using namespace com::sun::star::container;
49 using namespace com::sun::star::reflection;
50 using namespace rtl;
51 using namespace codemaker;
52
53 namespace unodevtools {
54
writeConstantData(typereg::Writer & rWriter,sal_uInt16 fieldIndex,const Reference<XConstantTypeDescription> & xConstant)55 void writeConstantData(typereg::Writer& rWriter, sal_uInt16 fieldIndex,
56 const Reference< XConstantTypeDescription >& xConstant)
57
58 {
59 RTConstValue constValue;
60 OUString uConstTypeName;
61 OUString uConstName = xConstant->getName();
62 Any aConstantAny = xConstant->getConstantValue();
63
64 switch ( aConstantAny.getValueTypeClass() )
65 {
66 case TypeClass_BOOLEAN:
67 {
68 uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("boolean"));
69 constValue.m_type = RT_TYPE_BOOL;
70 aConstantAny >>= constValue.m_value.aBool;
71 }
72 break;
73 case TypeClass_BYTE:
74 {
75 uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("byte"));
76 constValue.m_type = RT_TYPE_BYTE;
77 aConstantAny >>= constValue.m_value.aByte;
78 }
79 break;
80 case TypeClass_SHORT:
81 {
82 uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("short"));
83 constValue.m_type = RT_TYPE_INT16;
84 aConstantAny >>= constValue.m_value.aShort;
85 }
86 break;
87 case TypeClass_UNSIGNED_SHORT:
88 {
89 uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("unsigned short"));
90 constValue.m_type = RT_TYPE_UINT16;
91 aConstantAny >>= constValue.m_value.aUShort;
92 }
93 break;
94 case TypeClass_LONG:
95 {
96 uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("long"));
97 constValue.m_type = RT_TYPE_INT32;
98 aConstantAny >>= constValue.m_value.aLong;
99 }
100 break;
101 case TypeClass_UNSIGNED_LONG:
102 {
103 uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("unsigned long"));
104 constValue.m_type = RT_TYPE_UINT32;
105 aConstantAny >>= constValue.m_value.aULong;
106 }
107 break;
108 case TypeClass_FLOAT:
109 {
110 uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("float"));
111 constValue.m_type = RT_TYPE_FLOAT;
112 aConstantAny >>= constValue.m_value.aFloat;
113 }
114 break;
115 case TypeClass_DOUBLE:
116 {
117 uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("double"));
118 constValue.m_type = RT_TYPE_DOUBLE;
119 aConstantAny >>= constValue.m_value.aDouble;
120 }
121 break;
122 case TypeClass_STRING:
123 {
124 uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("string"));
125 constValue.m_type = RT_TYPE_STRING;
126 constValue.m_value.aString = ((OUString*)aConstantAny.getValue())->getStr();
127 }
128 break;
129 default:
130 OSL_ENSURE( 0, "unsupported constant type" );
131 break;
132 }
133
134 rWriter.setFieldData(fieldIndex, OUString(), OUString(), RT_ACCESS_CONST,
135 uConstName, uConstTypeName, constValue);
136 }
137
getInheritedMemberCount(GeneratedTypeSet & checkedTypes,Sequence<Reference<XTypeDescription>> & superTypes)138 sal_uInt32 getInheritedMemberCount(
139 GeneratedTypeSet& checkedTypes,
140 Sequence< Reference< XTypeDescription > >& superTypes)
141 {
142 sal_uInt32 memberCount = 0;
143
144 sal_uInt16 count = (sal_uInt16)superTypes.getLength();
145 OString name;
146 for (sal_uInt16 i=0; i < count; i++) {
147 name = OString(OUStringToOString(superTypes[i]->getName(),
148 RTL_TEXTENCODING_UTF8));
149 if (!checkedTypes.contains(name)) {
150 checkedTypes.add(name);
151
152 Reference< XInterfaceTypeDescription2 > xIFace(
153 superTypes[i], UNO_QUERY);
154
155 Sequence< Reference< XTypeDescription> > baseTypes =
156 xIFace->getBaseTypes();
157 if ( baseTypes.getLength() > 0)
158 memberCount += getInheritedMemberCount(checkedTypes, baseTypes);
159
160 memberCount += xIFace->getMembers().getLength();
161 }
162 }
163
164 return memberCount;
165 }
166
writeMethodData(typereg::Writer & rWriter,sal_uInt32 calculatedMemberOffset,const Reference<XInterfaceMethodTypeDescription> & xMethod)167 void writeMethodData( typereg::Writer& rWriter, sal_uInt32 calculatedMemberOffset,
168 const Reference< XInterfaceMethodTypeDescription >& xMethod )
169 {
170 RTMethodMode methodMode = RT_MODE_TWOWAY;
171 if ( xMethod->isOneway() )
172 methodMode = RT_MODE_ONEWAY;
173
174 Sequence< Reference< XMethodParameter > > parameters(xMethod->getParameters());
175 Sequence< Reference< XTypeDescription > > exceptions(xMethod->getExceptions());
176
177 OUString name(xMethod->getMemberName());
178 sal_uInt16 methodIndex = (sal_uInt16)(xMethod->getPosition()
179 - calculatedMemberOffset);
180 sal_uInt16 paramCount = (sal_uInt16)parameters.getLength();
181 sal_uInt16 exceptionCount = (sal_uInt16)exceptions.getLength();
182
183 rWriter.setMethodData(methodIndex, OUString(), methodMode,
184 xMethod->getMemberName(),
185 xMethod->getReturnType()->getName().replace('.', '/'),
186 paramCount, exceptionCount);
187
188 RTParamMode paramMode = RT_PARAM_IN;
189 sal_uInt16 i;
190
191 for ( i=0; i < paramCount; i++) {
192 Reference< XMethodParameter > xParam = parameters[i];
193 if ( xParam->isIn() && xParam->isOut())
194 paramMode = RT_PARAM_INOUT;
195 else if ( xParam->isIn() )
196 paramMode = RT_PARAM_IN;
197 else if ( xParam->isOut() )
198 paramMode = RT_PARAM_OUT;
199
200 rWriter.setMethodParameterData(methodIndex,
201 (sal_uInt16)xParam->getPosition(),
202 paramMode, xParam->getName(),
203 xParam->getType()->
204 getName().replace('.', '/'));
205 }
206
207 for (i=0; i < exceptionCount; i++) {
208 rWriter.setMethodExceptionTypeName(
209 methodIndex, i, exceptions[i]->getName().replace('.', '/'));
210 }
211 }
212
writeAttributeMethodData(typereg::Writer & rWriter,sal_uInt16 & methodindex,RTMethodMode methodmode,const Reference<XInterfaceAttributeTypeDescription2> & xAttr)213 void writeAttributeMethodData(
214 typereg::Writer& rWriter, sal_uInt16& methodindex, RTMethodMode methodmode,
215 const Reference<XInterfaceAttributeTypeDescription2>& xAttr)
216 {
217 Sequence<Reference<XCompoundTypeDescription> > seqExcp;
218 if (methodmode == RT_MODE_ATTRIBUTE_GET)
219 seqExcp = xAttr->getGetExceptions();
220 else
221 seqExcp = xAttr->getSetExceptions();
222
223 if (seqExcp.getLength() > 0) {
224 rWriter.setMethodData(methodindex, OUString(), methodmode,
225 xAttr->getMemberName(),
226 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")),
227 0, (sal_uInt16)seqExcp.getLength());
228
229 for (sal_Int32 i=0; i < seqExcp.getLength(); i++) {
230 rWriter.setMethodExceptionTypeName(
231 methodindex, (sal_uInt16)i,
232 seqExcp[i]->getName().replace('.', '/'));
233 }
234 ++methodindex;
235 }
236 }
237
checkParameterizedTypeFlag(const Sequence<OUString> & typeParams,const OUString & memberType)238 RTFieldAccess checkParameterizedTypeFlag(const Sequence< OUString >& typeParams,
239 const OUString & memberType)
240 {
241 for (sal_uInt16 i=0; i < typeParams.getLength(); i++) {
242 if (typeParams[i].equals(memberType))
243 return RT_ACCESS_PARAMETERIZED_TYPE;
244 }
245
246 return RT_ACCESS_READWRITE;
247 }
248
checkPropertyFlags(short flags)249 RTFieldAccess checkPropertyFlags(short flags) {
250 RTFieldAccess propertyFlags=RT_ACCESS_INVALID;
251 switch(flags) {
252 case PropertyAttribute::MAYBEVOID:
253 propertyFlags |= RT_ACCESS_MAYBEVOID;
254 case PropertyAttribute::BOUND:
255 propertyFlags |= RT_ACCESS_BOUND;
256 case PropertyAttribute::CONSTRAINED:
257 propertyFlags |= RT_ACCESS_CONSTRAINED;
258 case PropertyAttribute::TRANSIENT:
259 propertyFlags |= RT_ACCESS_TRANSIENT;
260 case PropertyAttribute::READONLY :
261 propertyFlags |= RT_ACCESS_READONLY;
262 case PropertyAttribute::MAYBEAMBIGUOUS:
263 propertyFlags |= RT_ACCESS_MAYBEAMBIGUOUS;
264 case PropertyAttribute::MAYBEDEFAULT:
265 propertyFlags |= RT_ACCESS_MAYBEDEFAULT;
266 case PropertyAttribute::REMOVEABLE:
267 propertyFlags |= RT_ACCESS_REMOVEABLE;
268 case PropertyAttribute::OPTIONAL:
269 propertyFlags |= RT_ACCESS_OPTIONAL;
270 }
271 return propertyFlags;
272 }
273
getTypeBlob(Reference<XHierarchicalNameAccess> xTDmgr,const OString & typeName,sal_uInt32 * blobsize)274 void* getTypeBlob(Reference< XHierarchicalNameAccess > xTDmgr,
275 const OString& typeName, sal_uInt32* blobsize)
276 {
277 if ( typeName.getLength() == 0 )
278 return NULL;
279
280 OUString uTypeName(OStringToOUString(typeName, RTL_TEXTENCODING_UTF8)
281 .replace('/', '.'));
282
283 Any aTypeAny( xTDmgr->getByHierarchicalName( uTypeName ) );
284
285 if ( !aTypeAny.hasValue() )
286 return NULL;
287
288 Reference< XTypeDescription > xType;
289 aTypeAny >>= xType;
290
291 if ( !xType.is() )
292 return NULL;
293
294 Reference< XPublished > xPublished(xType, UNO_QUERY);
295 void* pBlob = NULL;
296 switch (xType->getTypeClass())
297 {
298 case TypeClass_CONSTANTS:
299 {
300 Reference< XConstantsTypeDescription > xCFace(xType, UNO_QUERY);
301
302 if ( !xCFace.is() )
303 return NULL;
304
305 Sequence< Reference< XConstantTypeDescription > > constTypes(
306 xCFace->getConstants());
307 sal_uInt16 constCount = (sal_uInt16)constTypes.getLength();
308
309 typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(),
310 RT_TYPE_CONSTANTS, xPublished->isPublished(),
311 uTypeName.replace('.', '/'),
312 0, constCount, 0, 0);
313
314 for (sal_uInt16 i=0; i < constCount; i++)
315 writeConstantData(writer, i, constTypes[i]);
316
317 const void* p = writer.getBlob(blobsize);
318 pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize);
319 rtl_copyMemory(pBlob, p, *blobsize);
320 }
321 break;
322 case TypeClass_MODULE:
323 {
324 Reference< XModuleTypeDescription > xMFace(xType, UNO_QUERY);
325
326 if ( !xMFace.is() )
327 return NULL;
328
329 Sequence< Reference< XTypeDescription > > memberTypes(
330 xMFace->getMembers());
331
332 sal_uInt16 memberCount = (sal_uInt16)memberTypes.getLength();
333 sal_uInt16 constCount = 0;
334 sal_Int16 i;
335
336 for ( i=0; i < memberCount; i++) {
337 if ( TypeClass_CONSTANT == memberTypes[i]->getTypeClass() )
338 constCount++;
339 }
340
341 typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(),
342 RT_TYPE_MODULE, xPublished->isPublished(),
343 uTypeName.replace('.', '/'),
344 0, constCount, 0, 0);
345
346 if ( 0 < constCount ) {
347 Reference< XConstantTypeDescription > xConst;
348 sal_uInt16 fieldIndex = 0;
349 for (i=0; i < memberCount; i++) {
350 if ( TypeClass_CONSTANT == memberTypes[i]->getTypeClass() ) {
351 xConst = Reference< XConstantTypeDescription >(
352 memberTypes[i], UNO_QUERY);
353
354 writeConstantData(writer, ++fieldIndex, xConst);
355 }
356 }
357 }
358
359 const void* p = writer.getBlob(blobsize);
360 pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize);
361 rtl_copyMemory(pBlob, p, *blobsize);
362 }
363 break;
364 case TypeClass_INTERFACE:
365 {
366 Reference< XInterfaceTypeDescription2 > xIFace(xType, UNO_QUERY);
367
368 if ( !xIFace.is() )
369 return NULL;
370
371 Reference< XInterfaceAttributeTypeDescription2 > xAttr;
372 Reference< XInterfaceMethodTypeDescription > xMethod;
373 Sequence< Reference< XInterfaceMemberTypeDescription > > memberTypes(
374 xIFace->getMembers());
375 Sequence< Reference< XTypeDescription > > baseTypes =
376 xIFace->getBaseTypes();
377 Sequence< Reference< XTypeDescription > > optBaseTypes =
378 xIFace->getOptionalBaseTypes();
379
380 sal_uInt16 baseCount = (sal_uInt16)baseTypes.getLength();
381 sal_uInt16 optBaseCount = (sal_uInt16)optBaseTypes.getLength();
382 sal_uInt16 memberCount = (sal_uInt16)memberTypes.getLength();
383 sal_uInt16 attrCount = 0, attrmethods = 0;
384 sal_uInt16 inheritedMemberCount = 0;
385 sal_uInt16 i;
386
387 for (i=0; i < memberCount; i++) {
388 xAttr = Reference< XInterfaceAttributeTypeDescription2 >(
389 memberTypes[i], UNO_QUERY);
390 if ( xAttr.is() ) {
391 attrCount++;
392
393 if (xAttr->getGetExceptions().getLength() > 0)
394 attrmethods++;
395
396 if (xAttr->getSetExceptions().getLength() > 0)
397 attrmethods++;
398 }
399 }
400
401 // check inherited members count
402 if (baseCount > 0) {
403 GeneratedTypeSet checkedTypes;
404 inheritedMemberCount = (sal_uInt16)getInheritedMemberCount(
405 checkedTypes, baseTypes );
406 }
407
408 typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(),
409 RT_TYPE_INTERFACE, xPublished->isPublished(),
410 uTypeName.replace('.', '/'),
411 baseCount, attrCount, memberCount-attrCount+attrmethods,
412 (sal_uInt16)optBaseTypes.getLength());
413
414 // set super types
415 for (i=0; i < baseCount; i++) {
416 writer.setSuperTypeName(i, baseTypes[i]->
417 getName().replace('.', '/'));
418 }
419
420 // set optional super types
421 RTReferenceType referenceType = RT_REF_SUPPORTS;
422 RTFieldAccess fieldAccess = RT_ACCESS_OPTIONAL;
423 for (i=0; i < optBaseCount; i++) {
424 writer.setReferenceData(i, OUString(), referenceType,
425 fieldAccess, optBaseTypes[i]->
426 getName().replace('.', '/'));
427 }
428
429 fieldAccess = RT_ACCESS_READWRITE;
430 // reset attrCount, used for method index calculation
431 attrCount = 0;
432 attrmethods = 0;
433 for (i=0; i < memberCount; i++) {
434 xAttr = Reference< XInterfaceAttributeTypeDescription2 >(
435 memberTypes[i], UNO_QUERY);
436 if ( xAttr.is() ) {
437 ++attrCount;
438 if (xAttr->isReadOnly())
439 fieldAccess = RT_ACCESS_READONLY;
440 else
441 fieldAccess = RT_ACCESS_READWRITE;
442
443 if (xAttr->isBound())
444 fieldAccess |= RT_ACCESS_BOUND;
445
446 writer.setFieldData((sal_uInt16)memberTypes[i]->getPosition()
447 - inheritedMemberCount,
448 OUString(), OUString(), fieldAccess,
449 memberTypes[i]->getMemberName(),
450 xAttr->getType()->getName().replace('.','/'),
451 RTConstValue());
452
453 writeAttributeMethodData(writer, attrmethods,
454 RT_MODE_ATTRIBUTE_GET, xAttr);
455 if (!xAttr->isReadOnly()) {
456 writeAttributeMethodData(writer, attrmethods,
457 RT_MODE_ATTRIBUTE_SET, xAttr);
458 }
459
460 continue;
461 }
462
463 xMethod = Reference< XInterfaceMethodTypeDescription >(
464 memberTypes[i], UNO_QUERY);
465 if ( xMethod.is() ) {
466 writeMethodData(writer, attrCount+inheritedMemberCount-attrmethods,
467 xMethod);
468 }
469 }
470
471 const void* p = writer.getBlob(blobsize);
472 pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize);
473 rtl_copyMemory(pBlob, p, *blobsize);
474 }
475 break;
476 case TypeClass_STRUCT:
477 {
478 Reference< XStructTypeDescription > xStruct(xType, UNO_QUERY);
479
480 if ( !xStruct.is() )
481 return NULL;
482
483 if ( xStruct->getTypeArguments().getLength() > 0)
484 return NULL;
485
486
487 Sequence< OUString > typeParams( xStruct->getTypeParameters());
488 Sequence< OUString > memberNames( xStruct->getMemberNames());
489 Sequence< Reference< XTypeDescription > > memberTypes(
490 xStruct->getMemberTypes());
491 sal_uInt16 memberCount = (sal_uInt16)memberNames.getLength();
492
493 OUString uSuperType;
494 sal_uInt16 superCount=0;
495 if ( typeParams.getLength() == 0) {
496 Reference< XTypeDescription > xSuperType = xStruct->getBaseType();
497 if ( xSuperType.is() ) {
498 ++superCount;
499 uSuperType = xSuperType->getName().replace('.','/');
500 }
501 }
502 typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(),
503 RT_TYPE_STRUCT, xPublished->isPublished(),
504 uTypeName.replace('.', '/'),
505 superCount, memberCount, 0,
506 (sal_uInt16)typeParams.getLength());
507
508 // set super type
509 if (superCount > 0) {
510 writer.setSuperTypeName(0, uSuperType);
511 }
512
513 sal_uInt16 i=0;
514 for (i=0; i < memberCount; i++) {
515 RTFieldAccess fieldAccess = RT_ACCESS_READWRITE;
516 if (typeParams.getLength() > 0)
517 fieldAccess |= checkParameterizedTypeFlag(
518 typeParams, memberTypes[i]->getName());
519
520 writer.setFieldData(i, OUString(), OUString(), fieldAccess,
521 memberNames[i],
522 memberTypes[i]->getName().replace('.', '/'),
523 RTConstValue());
524 }
525
526 for (i=0; i < typeParams.getLength(); i++) {
527 writer.setReferenceData(i, OUString(), RT_REF_TYPE_PARAMETER,
528 RT_ACCESS_INVALID, typeParams[i]);
529 }
530
531 const void* p = writer.getBlob(blobsize);
532 pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize);
533 rtl_copyMemory(pBlob, p, *blobsize);
534 }
535 break;
536 case TypeClass_EXCEPTION:
537 {
538 Reference< XCompoundTypeDescription > xComp(xType, UNO_QUERY);
539
540 if ( !xComp.is() )
541 return NULL;
542
543 Sequence< OUString > memberNames( xComp->getMemberNames());
544 Sequence< Reference< XTypeDescription > > memberTypes(
545 xComp->getMemberTypes());
546 sal_uInt16 memberCount = (sal_uInt16)memberNames.getLength();
547
548 OUString uSuperType;
549 sal_uInt16 superCount=0;
550 Reference< XTypeDescription > xSuperType = xComp->getBaseType();
551 if ( xSuperType.is() ) {
552 ++superCount;
553 uSuperType = xSuperType->getName().replace('.','/');
554 }
555
556 typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(),
557 RT_TYPE_EXCEPTION, xPublished->isPublished(),
558 uTypeName.replace('.', '/'),
559 superCount, memberCount, 0, 0);
560
561 // set super type
562 if (superCount > 0) {
563 writer.setSuperTypeName(0, uSuperType);
564 }
565
566 for (sal_Int16 i=0; i < memberCount; i++) {
567 writer.setFieldData(i, OUString(), OUString(), RT_ACCESS_READWRITE,
568 memberNames[i],
569 memberTypes[i]->getName().replace('.', '/'),
570 RTConstValue());
571 }
572
573 const void* p = writer.getBlob(blobsize);
574 pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize);
575 rtl_copyMemory(pBlob, p, *blobsize);
576 }
577 break;
578 case TypeClass_ENUM:
579 {
580 Reference< XEnumTypeDescription > xEnum(xType, UNO_QUERY);
581
582 if ( !xEnum.is() )
583 return NULL;
584
585 Sequence< OUString > enumNames( xEnum->getEnumNames());
586 Sequence< sal_Int32 > enumValues( xEnum->getEnumValues());
587 sal_uInt16 enumCount = (sal_uInt16)enumNames.getLength();
588
589 typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(),
590 RT_TYPE_ENUM, xPublished->isPublished(),
591 uTypeName.replace('.', '/'),
592 0, enumCount, 0, 0);
593
594 RTConstValue constValue;
595 for (sal_Int16 i=0; i < enumCount; i++) {
596 constValue.m_type = RT_TYPE_INT32;
597 constValue.m_value.aLong = enumValues[i];
598
599 writer.setFieldData(i, OUString(), OUString(),
600 RT_ACCESS_CONST, enumNames[i],
601 OUString(), constValue);
602 }
603
604 const void* p = writer.getBlob(blobsize);
605 pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize);
606 rtl_copyMemory(pBlob, p, *blobsize);
607 }
608 break;
609 case TypeClass_TYPEDEF:
610 {
611 Reference< XIndirectTypeDescription > xTD(xType, UNO_QUERY);
612
613 if ( !xTD.is() )
614 return NULL;
615
616 typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(),
617 RT_TYPE_TYPEDEF, xPublished->isPublished(),
618 uTypeName.replace('.', '/'),
619 1, 0, 0, 0);
620
621 writer.setSuperTypeName(0, xTD->getReferencedType()
622 ->getName().replace('.','/'));
623
624 const void* p = writer.getBlob(blobsize);
625 pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize);
626 rtl_copyMemory(pBlob, p, *blobsize);
627 }
628 break;
629 case TypeClass_SERVICE:
630 {
631 Reference< XServiceTypeDescription2 > xService(xType, UNO_QUERY);
632
633 if ( !xService.is() )
634 return NULL;
635
636 Sequence<Reference<XServiceConstructorDescription> > constructors(
637 xService->getConstructors());
638 Sequence<Reference<XPropertyTypeDescription> > properties;
639 Sequence<Reference<XServiceTypeDescription> > mandatoryServices;
640 Sequence<Reference<XServiceTypeDescription> > optionalServices;
641 Sequence<Reference<XInterfaceTypeDescription> > mandatoryInterfaces;
642 Sequence<Reference<XInterfaceTypeDescription> > optionalInterfaces;
643 sal_uInt16 methodCount = (sal_uInt16)constructors.getLength();
644 sal_uInt16 referenceCount = 0;
645 sal_uInt16 propertyCount = 0;
646
647 if ( !xService->isSingleInterfaceBased() ) {
648 mandatoryServices = xService->getMandatoryServices();
649 optionalServices = xService->getOptionalServices();
650 mandatoryInterfaces = xService->getMandatoryInterfaces();
651 optionalInterfaces = xService->getOptionalInterfaces();
652 properties = xService->getProperties();
653 referenceCount = (sal_uInt16)(
654 mandatoryServices.getLength()+
655 optionalServices.getLength()+
656 mandatoryInterfaces.getLength()+
657 optionalInterfaces.getLength());
658 propertyCount = (sal_uInt16)properties.getLength();
659 }
660
661 typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(),
662 RT_TYPE_SERVICE, xPublished->isPublished(),
663 uTypeName.replace('.', '/'),
664 (xService->isSingleInterfaceBased() ? 1 : 0),
665 propertyCount, methodCount, referenceCount);
666
667 sal_uInt16 i=0;
668 if ( xService->isSingleInterfaceBased() ) {
669 writer.setSuperTypeName(0, xService->getInterface()
670 ->getName().replace('.','/'));
671
672 sal_uInt16 j=0;
673 for ( i=0; i<methodCount; i++ ) {
674 Reference<XServiceConstructorDescription> xConstructor(
675 constructors[i], UNO_QUERY);
676 Sequence<Reference<XParameter> > parameters;
677 Sequence<Reference<XCompoundTypeDescription> > exceptions;
678 sal_uInt16 parameterCount=0;
679 sal_uInt16 exceptionCount=0;
680 if ( !xConstructor->isDefaultConstructor() ) {
681 parameters = xConstructor->getParameters();
682 parameterCount = (sal_uInt16)parameters.getLength();
683 }
684
685 writer.setMethodData(i, OUString(), RT_MODE_TWOWAY,
686 xConstructor->getName(),
687 OUString(
688 RTL_CONSTASCII_USTRINGPARAM("void")),
689 parameterCount, exceptionCount);
690
691 if ( !xConstructor->isDefaultConstructor() ) {
692 for ( j=0; j<parameterCount; j++ ) {
693 Reference<XParameter> xParam(parameters[j], UNO_QUERY);
694 RTParamMode paramMode = RT_PARAM_IN;
695 if (xParam->isRestParameter())
696 paramMode = RT_PARAM_REST;
697
698 writer.setMethodParameterData(
699 i, (sal_uInt16)xParam->getPosition(),
700 paramMode, xParam->getName(),
701 xParam->getType()->getName().replace('.', '/'));
702 }
703
704 for (j=0; j<exceptionCount; j++) {
705 Reference<XCompoundTypeDescription> xExcp(
706 exceptions[j], UNO_QUERY);
707
708 writer.setMethodExceptionTypeName(
709 i, j, xExcp->getName().replace('.', '/'));
710 }
711 }
712 }
713 } else
714 {
715 for (i=0; i<propertyCount; i++) {
716 Reference<XPropertyTypeDescription> xProp(
717 properties[i], UNO_QUERY);
718
719 RTFieldAccess propertyFlags = checkPropertyFlags(
720 xProp->getPropertyFlags());
721
722 writer.setFieldData(i, OUString(), OUString(),
723 propertyFlags,
724 xProp->getName().copy(xProp->getName().lastIndexOf('.')+1),
725 xProp->getPropertyTypeDescription()
726 ->getName().replace('.', '/'),
727 RTConstValue());
728 }
729
730 sal_uInt16 refIndex = 0;
731 sal_uInt16 length = (sal_uInt16)mandatoryServices.getLength();
732 for (i=0; i < length; i++) {
733 writer.setReferenceData(refIndex++, OUString(),
734 RT_REF_EXPORTS, RT_ACCESS_INVALID,
735 mandatoryServices[i]->getName()
736 .replace('.', '/'));
737 }
738 length = (sal_uInt16)optionalServices.getLength();
739 for (i=0; i < length; i++) {
740 writer.setReferenceData(refIndex++, OUString(),
741 RT_REF_EXPORTS, RT_ACCESS_OPTIONAL,
742 optionalServices[i]->getName()
743 .replace('.', '/'));
744 }
745 length = (sal_uInt16)mandatoryInterfaces.getLength();
746 for (i=0; i < length; i++) {
747 writer.setReferenceData(refIndex++, OUString(),
748 RT_REF_SUPPORTS, RT_ACCESS_INVALID,
749 mandatoryInterfaces[i]->getName()
750 .replace('.', '/'));
751 }
752 length = (sal_uInt16)optionalInterfaces.getLength();
753 for (i=0; i < length; i++) {
754 writer.setReferenceData(refIndex++, OUString(),
755 RT_REF_SUPPORTS, RT_ACCESS_OPTIONAL,
756 optionalInterfaces[i]->getName()
757 .replace('.', '/'));
758 }
759 }
760
761 const void* p = writer.getBlob(blobsize);
762 pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize);
763 rtl_copyMemory(pBlob, p, *blobsize);
764 }
765 break;
766 case TypeClass_SINGLETON:
767 {
768 Reference<XSingletonTypeDescription2> xSingleton(xType, UNO_QUERY);
769
770 if ( !xSingleton.is() )
771 return NULL;
772
773 typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(),
774 RT_TYPE_SINGLETON, xPublished->isPublished(),
775 uTypeName.replace('.', '/'),
776 1, 0, 0, 0);
777
778 if (xSingleton->isInterfaceBased()) {
779 writer.setSuperTypeName(0, xSingleton->getInterface()
780 ->getName().replace('.','/'));
781 } else {
782 writer.setSuperTypeName(0, xSingleton->getService()
783 ->getName().replace('.','/'));
784 }
785
786 const void* p = writer.getBlob(blobsize);
787 pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize);
788 rtl_copyMemory(pBlob, p, *blobsize);
789 }
790 break;
791 default:
792 OSL_ENSURE( 0, "unsupported type" );
793 break;
794 }
795
796 return pBlob;
797 }
798
799 } // end of namespace unodevtools
800