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