xref: /AOO41X/main/codemaker/source/cunomaker/cunotype.cxx (revision 9d8e7fba6924780c2093139852107433cac37537)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_codemaker.hxx"
26 
27 #include <stdio.h>
28 #include    <rtl/alloc.h>
29 #include    <rtl/ustring.hxx>
30 #include    <rtl/strbuf.hxx>
31 
32 #include    "cunotype.hxx"
33 #include    "cunooptions.hxx"
34 
35 using namespace rtl;
36 
37 //*************************************************************************
38 // CunoType
39 //*************************************************************************
CunoType(TypeReader & typeReader,const OString & typeName,const TypeManager & typeMgr,const TypeDependency & typeDependencies)40 CunoType::CunoType(TypeReader& typeReader,
41                    const OString& typeName,
42                    const TypeManager& typeMgr,
43                    const TypeDependency& typeDependencies)
44     : m_inheritedMemberCount(0)
45     , m_cunoTypeLib(sal_False)
46     , m_cunoTypeLeak(sal_False)
47     , m_cunoTypeDynamic(sal_True)
48     , m_indentLength(0)
49     , m_typeName(typeName)
50 //  , m_name(typeName.getToken(typeName.getTokenCount('/') - 1, '/'))
51     , m_name(typeName.replace('/', '_'))
52     , m_reader(typeReader)
53     , m_typeMgr((TypeManager&)typeMgr)
54     , m_dependencies(typeDependencies)
55     , m_bIsNestedType(sal_False)
56 {
57     // check if this type is nested
58     sal_Int32 i = typeName.lastIndexOf('/');
59 
60     if (i >= 0)
61     {
62         OString outerTypeName(typeName.copy(0, i));
63         m_bIsNestedType = (m_typeMgr.getTypeClass(outerTypeName) == RT_TYPE_INTERFACE);
64     }
65 
66     // check if this type has nested types
67     RegistryKey key = m_typeMgr.getTypeKey(typeName);
68 
69     key.getKeyNames(OUString(), m_nestedTypeNames);
70 }
71 
~CunoType()72 CunoType::~CunoType()
73 {
74 
75 }
76 
isNestedTypeByName(const::rtl::OString & type)77 sal_Bool CunoType::isNestedTypeByName(const ::rtl::OString& type)
78 {
79     sal_Bool ret = sal_False;
80 
81     sal_Int32 i = type.lastIndexOf('/');
82 
83     if (i >= 0)
84     {
85         OString outerTypeName(type.copy(0, i));
86         ret = (m_typeMgr.getTypeClass(outerTypeName) == RT_TYPE_INTERFACE);
87     }
88 
89     return ret;
90 }
91 
hasNestedType(const::rtl::OString & type)92 sal_Bool CunoType::hasNestedType(const ::rtl::OString& type)
93 {
94     sal_Bool ret = sal_False;
95 
96     if (m_nestedTypeNames.getLength() > 0)
97     {
98         OUString typeName(OStringToOUString(type, RTL_TEXTENCODING_UTF8));
99 
100         for (sal_uInt32 i = 0; !ret && (i < m_nestedTypeNames.getLength()); i++)
101             ret = typeName.equals(m_nestedTypeNames.getElement(i).copy(5));
102     }
103 
104     return ret;
105 }
106 
dump(CunoOptions * pOptions)107 sal_Bool CunoType::dump(CunoOptions* pOptions)
108     throw( CannotDumpException )
109 {
110     sal_Bool ret = sal_False;
111 
112     if (isNestedType())
113         return sal_True;
114 
115     if (pOptions->isValid("-U"))
116         m_cunoTypeLib = sal_True;
117     if (pOptions->isValid("-L"))
118         m_cunoTypeLeak = sal_True;
119     if (pOptions->isValid("-C"))
120         m_cunoTypeDynamic = sal_False;
121 
122     OString outPath;
123     if (pOptions->isValid("-O"))
124         outPath = pOptions->getOption("-O");
125 
126     OString tmpFileName;
127     OString hFileName = createFileNameFromType(outPath, m_typeName, ".h");
128 
129     sal_Bool bFileExists = sal_False;
130     sal_Bool bFileCheck = sal_False;
131 
132     if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") )
133     {
134         bFileExists = fileExists( hFileName );
135         ret = sal_True;
136     }
137 
138     if ( bFileExists && pOptions->isValid("-Gc") )
139     {
140         tmpFileName  = createFileNameFromType(outPath, m_typeName, ".tmh");
141         bFileCheck = sal_True;
142     }
143 
144     if ( !bFileExists || bFileCheck )
145     {
146         FileStream hFile;
147 
148         if ( bFileCheck )
149             hFile.open(tmpFileName);
150         else
151             hFile.open(hFileName);
152 
153         if(!hFile.isValid())
154         {
155             OString message("cannot open ");
156             message += hFileName + " for writing";
157             throw CannotDumpException(message);
158         }
159 
160         ret = dumpHFile(hFile);
161 
162         hFile.close();
163         if (ret && bFileCheck)
164         {
165             ret = checkFileContent(hFileName, tmpFileName);
166         }
167     }
168 
169     if ( m_cunoTypeLib )
170     {
171         bFileExists = sal_False;
172         bFileCheck = sal_False;
173 
174         if (pOptions->isValid("-OC"))
175             outPath = pOptions->getOption("-OC");
176         else
177             outPath = OString();
178 
179         OString cFileName = createFileNameFromType(outPath, m_typeName, ".c");
180 
181         if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") )
182         {
183             bFileExists = fileExists( cFileName );
184             ret = sal_True;
185         }
186 
187         if ( bFileExists && pOptions->isValid("-Gc") )
188         {
189             tmpFileName  = createFileNameFromType(outPath, m_typeName, ".tmc");
190             bFileCheck = sal_True;
191         }
192 
193         if ( !bFileExists || bFileCheck )
194         {
195             FileStream cFile;
196 
197             if ( bFileCheck )
198                 cFile.open(tmpFileName);
199             else
200                 cFile.open(cFileName);
201 
202             if(!cFile.isValid())
203             {
204                 OString message("cannot open ");
205                 message += cFileName + " for writing";
206                 throw CannotDumpException(message);
207             }
208 
209             ret = dumpCFile(cFile);
210 
211             cFile.close();
212             if (ret && bFileCheck)
213             {
214                 ret = checkFileContent(cFileName, tmpFileName);
215             }
216         }
217     }
218     return ret;
219 }
dumpDependedTypes(CunoOptions * pOptions)220 sal_Bool CunoType::dumpDependedTypes(CunoOptions* pOptions)
221     throw( CannotDumpException )
222 {
223     sal_Bool ret = sal_True;
224 
225     TypeUsingSet usingSet(m_dependencies.getDependencies(m_typeName));
226 
227     TypeUsingSet::const_iterator iter = usingSet.begin();
228     OString typeName;
229     sal_uInt32 index = 0;
230     while (iter != usingSet.end())
231     {
232         typeName = (*iter).m_type;
233         if ((index = typeName.lastIndexOf(']')) > 0)
234             typeName = typeName.copy(index + 1);
235 
236         if ( getBaseType(typeName).isEmpty() )
237         {
238             if (!produceType(typeName,
239                              m_typeMgr,
240                              m_dependencies,
241                              pOptions))
242             {
243                 fprintf(stderr, "%s ERROR: %s\n",
244                         pOptions->getProgramName().getStr(),
245                         OString("cannot dump Type '" + typeName + "'").getStr());
246                 exit(99);
247             }
248         }
249         ++iter;
250     }
251 
252     return ret;
253 }
254 
dumpHeaderDefine(FileStream & o,sal_Char * prefix,sal_Bool bExtended)255 OString CunoType::dumpHeaderDefine(FileStream& o, sal_Char* prefix, sal_Bool bExtended)
256 {
257     if (m_typeName.equals("/"))
258     {
259         bExtended = sal_False;
260         m_typeName = "global";
261     }
262 
263     sal_uInt32 length = 3 + m_typeName.getLength() + strlen(prefix);
264 
265     if (bExtended)
266         length += m_name.getLength() + 1;
267 
268     OStringBuffer tmpBuf(length);
269 
270     tmpBuf.append('_');
271     tmpBuf.append(m_typeName);
272     tmpBuf.append('_');
273     if (bExtended)
274     {
275         tmpBuf.append(m_name);
276         tmpBuf.append('_');
277     }
278     tmpBuf.append(prefix);
279     tmpBuf.append('_');
280 
281     OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase());
282 
283     o << "#ifndef " << tmp << "\n#define " << tmp << "\n";
284 
285     return tmp;
286 }
287 
dumpDefaultHIncludes(FileStream & o)288 void CunoType::dumpDefaultHIncludes(FileStream& o)
289 {
290     o << "#ifndef _UNO_CUNO_H_\n"
291       << "#include <uno/cuno.h>\n"
292       << "#endif\n";
293 /*
294     if (m_typeMgr.getTypeClass(m_typeName) == RT_TYPE_INTERFACE &&
295         !m_typeName.equals("com/sun/star/uno/XInterface") )
296     {
297         o << "#ifndef _COM_SUN_STAR_UNO_XINTERFACE_H_\n"
298           << "#include <com/sun/star/uno/XInterface.h>\n"
299           << "#endif\n";
300     }
301 */
302 }
303 
dumpDefaultCIncludes(FileStream & o)304 void CunoType::dumpDefaultCIncludes(FileStream& o)
305 {
306     o << "#ifndef _OSL_MUTEX_H_\n"
307       << "#include <osl/mutex.h>\n"
308       << "#endif\n\n";
309 }
310 
dumpInclude(FileStream & o,const OString & typeName,sal_Char * prefix,sal_Bool bExtended,sal_Bool bCaseSensitive)311 void CunoType::dumpInclude(FileStream& o, const OString& typeName, sal_Char* prefix, sal_Bool bExtended, sal_Bool bCaseSensitive)
312 {
313     sal_uInt32 length = 3+ m_typeName.getLength() + strlen(prefix);
314 
315     if (bExtended)
316         length += m_name.getLength() + 1;
317 
318     OStringBuffer tmpBuf(length);
319 
320     tmpBuf.append('_');
321     tmpBuf.append(typeName);
322     tmpBuf.append('_');
323     if (bExtended)
324     {
325         tmpBuf.append(m_name);
326         tmpBuf.append('_');
327     }
328     tmpBuf.append(prefix);
329     tmpBuf.append('_');
330 
331     OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase());
332 
333     length = 1 + typeName.getLength() + strlen(prefix);
334     if (bExtended)
335         length += m_name.getLength() + 1;
336 
337     tmpBuf.ensureCapacity(length);
338     tmpBuf.append(typeName);
339     if (bExtended)
340     {
341         tmpBuf.append('/');
342         tmpBuf.append(m_name);
343     }
344     tmpBuf.append('.');
345     tmpBuf.append(prefix);
346 
347     o << "#ifndef " << tmp << "\n#include <";
348     if (bCaseSensitive)
349     {
350         o << tmpBuf.makeStringAndClear();
351     } else
352     {
353         o << tmpBuf.makeStringAndClear();
354     }
355     o << ">\n#endif\n";
356 }
357 
dumpDepIncludes(FileStream & o,const OString & typeName,sal_Char * prefix)358 void CunoType::dumpDepIncludes(FileStream& o, const OString& typeName, sal_Char* prefix)
359 {
360     TypeUsingSet usingSet(m_dependencies.getDependencies(typeName));
361 
362     TypeUsingSet::const_iterator iter = usingSet.begin();
363 
364     OString     sPrefix(OString(prefix).toAsciiUpperCase());
365     sal_Bool    bSequenceDumped = sal_False;
366     sal_uInt32  index = 0;
367     sal_uInt32  seqNum = 0;
368     OString     relType;
369     while (iter != usingSet.end())
370     {
371         sal_Bool bDumpThisType = sal_True;
372         index = (*iter).m_type.lastIndexOf(']');
373         seqNum = (index > 0 ? ((index+1) / 2) : 0);
374 
375         relType = (*iter).m_type;
376         if (index > 0)
377             relType = relType.copy(index+1);
378 
379         if (isNestedTypeByName(relType) && hasNestedType(relType))
380             bDumpThisType = sal_False;
381 
382         if (bDumpThisType)
383         {
384             OString defPrefix("H");
385             if (sPrefix.equals("H"))
386                 defPrefix = "H";
387 
388             if (seqNum > 0 && !bSequenceDumped)
389             {
390                 bSequenceDumped = sal_True;
391                 o << "#ifndef _UNO_SEQUENCE2_" << defPrefix
392                   << "_\n#include <uno/sequence2." << defPrefix.toAsciiLowerCase()
393                   << ">\n#endif\n";
394             }
395 
396             if (getBaseType(relType).isEmpty() &&
397                 m_typeName != relType)
398             {
399                 if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE
400                     && sPrefix.equals("H"))
401                 {
402                     if (!((*iter).m_use & TYPEUSE_SUPER))
403                     {
404                         if (isNestedTypeByName(relType))
405                         {
406                             sal_Int32 iLastS = relType.lastIndexOf('/');
407 
408                             OString outerNamespace(relType.copy(0,iLastS));
409                             OString innerClass(relType.copy(iLastS+1));
410 
411                             iLastS = outerNamespace.lastIndexOf('/');
412                             OString outerClass(outerNamespace.copy(iLastS+1));
413 
414 //                          o << "\n";
415 //                          dumpNameSpace(o, sal_True, sal_False, outerNamespace);
416 //                          o << "\nclass " << outerClass << "::" << innerClass << ";\n";
417 //                          dumpNameSpace(o, sal_False, sal_False, outerNamespace);
418 //                          o << "\n\n";
419                         }
420                         else
421                         {
422 //                          dumpInclude(o, relType, prefix);
423                             OString type(relType.replace('/', '_'));
424                             o << "\n#ifndef " << type.toAsciiUpperCase() << "\n";
425                             o << "#define " << type.toAsciiUpperCase() << "\n";
426                             o << "struct _" << type << ";\n"
427                               << "typedef struct _" << type << "_ftab * " << type << ";\n";
428                             o << "#endif\n\n";
429                         }
430                     } else
431                     {
432                         if (isNestedTypeByName(relType))
433                         {
434                             sal_Int32 iLastS = relType.lastIndexOf('/');
435 
436                             OString outerNamespace(relType.copy(0,iLastS));
437 
438                             dumpInclude(o, outerNamespace, prefix);
439                         }
440                         else
441                             dumpInclude(o, relType, prefix);
442                     }
443                 } else
444                 {
445                     if (isNestedTypeByName(relType))
446                     {
447                         sal_Int32 iLastS = relType.lastIndexOf('/');
448 
449                         OString outerNamespace(relType.copy(0,iLastS));
450 
451                         dumpInclude(o, outerNamespace, prefix);
452                     }
453                     else
454                         dumpInclude(o, relType, prefix);
455                 }
456             } else
457             if (relType == "any")
458             {
459                 o << "#ifndef _UNO_ANY2_H_\n"
460                   << "#include <uno/any2.h>\n"
461                   << "#endif\n";
462             } else
463             if (relType == "type")
464             {
465                 o << "#ifndef _TYPELIB_TYPEDESCRIPTION_H_\n"
466                   << "#include <typelib/typedescription.h>\n"
467                   << "#endif\n";
468             } else
469             if (relType == "string" && sPrefix.equals("H"))
470             {
471                 o << "#ifndef _RTL_USTRING_H_\n"
472                   << "#include <rtl/ustring.h>\n"
473                   << "#endif\n";
474             }
475         }
476         ++iter;
477     }
478     if (m_typeName.equals(typeName) && (getNestedTypeNames().getLength() > 0))
479     {
480         o << "// includes for nested types\n\n";
481 
482         for (sal_uInt32 i = 0; i < getNestedTypeNames().getLength(); i++)
483         {
484             OUString s(getNestedTypeNames().getElement(i));
485 
486             OString nestedName(s.getStr(), s.getLength(), RTL_TEXTENCODING_UTF8);
487 
488             dumpDepIncludes(o, nestedName, prefix);
489         }
490     }
491 }
492 
dumpOpenExternC(FileStream & o)493 void CunoType::dumpOpenExternC(FileStream& o)
494 {
495     o << "#ifdef __cplusplus\n"
496       << "extern \"C\" {\n"
497       << "#endif\n\n";
498 }
499 
dumpCloseExternC(FileStream & o)500 void CunoType::dumpCloseExternC(FileStream& o)
501 {
502     o << "#ifdef __cplusplus\n"
503       << "}\n"
504       << "#endif\n\n";
505 }
506 
dumpLGetCunoType(FileStream & o)507 void CunoType::dumpLGetCunoType(FileStream& o)
508 {
509     OString typeName(m_typeName.replace('/', '_'));
510 
511     o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
512       << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
513       << "#endif\n\n";
514 
515     if (m_reader.getTypeClass() == RT_TYPE_TYPEDEF)
516     {
517         o << "inline const ::com::sun::star::uno::Type& SAL_CALL get_" << typeName << "_Type( ) SAL_THROW( () )\n{\n";
518     } else
519     {
520         o << "inline const ::com::sun::star::uno::Type& SAL_CALL getCunoType( ";
521         dumpType(o, m_typeName, sal_True, sal_False);
522         o << "* ) SAL_THROW( () )\n{\n";
523     }
524     inc();
525 
526     o << indent() << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
527       << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
528       << indent() << "#endif\n\n";
529 
530     o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n";
531     inc();
532     o << indent() << "typelib_static_type_init( &s_pType_" << typeName << ", "
533       << getTypeClass(m_typeName, sal_True) << ", \"" << m_typeName.replace('/', '.') << "\" );\n";
534     dec();
535     o << indent() << "}\n";
536     o << indent() << "return * reinterpret_cast< ::com::sun::star::uno::Type * >( &s_pType_"
537       << typeName <<" );\n";
538     dec();
539     o << indent() << "}\n";
540 
541     return;
542 }
543 
dumpGetCunoType(FileStream & o)544 void CunoType::dumpGetCunoType(FileStream& o)
545 {
546     OString typeName(m_typeName.replace('/', '_'));
547 
548     if ( m_cunoTypeLeak )
549     {
550         dumpLGetCunoType(o);
551         return;
552     }
553     if ( !m_cunoTypeDynamic )
554     {
555         dumpCGetCunoType(o);
556         return;
557     }
558 
559     dumpOpenExternC(o);
560 
561     if ( !m_typeName.equals("com/sun/star/uno/Exception") )
562     {
563         o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
564           << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
565           << "#endif\n\n";
566     }
567 
568     o << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () )\n{\n";
569     inc();
570 
571     if ( m_typeName.equals("com/sun/star/uno/Exception") )
572     {
573         o << indent() << "return typelib_static_type_getByTypeClass( typelib_TypeClass_EXCEPTION );\n";
574     } else
575     {
576         o << indent() << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
577           << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
578           << indent() << "#endif\n\n";
579 
580         o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n";
581         inc();
582 
583         OString superType(m_reader.getSuperTypeName());
584         sal_Bool bIsBaseException = sal_False;
585         if ( !superType.isEmpty() )
586         {
587             if ( superType.equals("com/sun/star/uno/Exception") )
588             {
589                 bIsBaseException = sal_True;
590             } else
591             {
592                 o << indent() << "typelib_TypeDescriptionReference * pBaseType = 0;\n";
593             }
594         }
595 
596         sal_uInt32 count = getMemberCount();
597         if (count)
598         {
599             o << indent() << "typelib_TypeDescriptionReference * aMemberRefs[" << count << "];\n";
600         }
601 
602         if ( !bIsBaseException )
603         {
604             o << indent() << "typelib_typedescriptionreference_newByAsciiName(&pBaseType, typelib_TypeClass_INTERFACE, \""
605               << superType.replace('/', '.') << "\" );\n";
606         }
607 
608         if (count)
609         {
610             sal_uInt32      fieldCount = m_reader.getFieldCount();
611             RTFieldAccess   access = RT_ACCESS_INVALID;
612             OString         fieldType, fieldName;
613             OString         scope = m_typeName.replace('/', '.');
614             sal_Bool        bWithScope = sal_True;
615             OString         modFieldType;
616             StringSet       generatedTypeSet;
617             StringSet::iterator findIter;
618 
619             for (sal_uInt16 i=0; i < fieldCount; i++)
620             {
621                 access = m_reader.getFieldAccess(i);
622 
623                 if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
624                     continue;
625 
626                 fieldName = m_reader.getFieldName(i);
627                 fieldType = checkRealBaseType(m_reader.getFieldType(i), sal_True);
628 
629 //              modFieldType = typeToIdentifier(fieldType);
630 
631                 findIter = generatedTypeSet.find(fieldType);
632                 if ( findIter == generatedTypeSet.end() )
633                 {
634                     generatedTypeSet.insert(fieldType);
635                     o << indent() << "typelib_typedescriptionreference_newByAsciiName(&aMemberRefs["
636                       << i << "], " << getTypeClass(fieldType, sal_True);
637                     o << "  , \"" << fieldType.replace('/', '.') << "\" );\n";
638                 }
639             }
640             o << "\n";
641         }
642 
643         o << indent() << "typelib_static_compound_type_init( &s_pType_" << typeName << ", "
644           << getTypeClass(m_typeName, sal_True) << ", \"" << m_typeName.replace('/', '.') << "\", ";
645         if ( !superType.isEmpty() || bIsBaseException )
646         {
647             if ( bIsBaseException )
648             {
649                 o << "* typelib_static_type_getByTypeClass( typelib_TypeClass_EXCEPTION ), "
650                   << count << ", ";
651             } else
652             {
653                 o << "pBaseType, " << count << ", ";
654             }
655         } else
656         {
657             o << "0, " << count << ", ";
658         }
659 
660         if (count)
661         {
662             o << " aMemberRefs );\n";
663         } else
664         {
665             o << " 0 );\n";
666         }
667         dec();
668         o << indent() << "}\n"
669           << indent() << "typelib_typedescriptionreference_acquire( s_pType_" << typeName << " );\n"
670           << indent() << "return &_pType_" << typeName <<" );\n";
671     }
672     dec();
673     o << indent() << "}\n";
674 
675     dumpCloseExternC(o);
676 }
677 
dumpCGetCunoType(FileStream & o)678 void CunoType::dumpCGetCunoType(FileStream& o)
679 {
680     OString typeName(m_typeName.replace('/', '_'));
681 
682     dumpOpenExternC(o);
683 
684     o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
685       << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
686       << "#endif\n\n";
687 
688     o << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () )\n{\n";
689     inc();
690 
691     o << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
692       << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
693       << "#endif\n\n";
694 
695     o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n";
696     inc();
697     o << indent() << "oslMutex * pMutex = osl_getGlobalMutex();\n"
698       << indent() << "osl_acquireMutex( pMutex );\n";
699 
700     o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n";
701     inc();
702     o << indent() << "rtl_uString * pTypeName = 0;\n"
703       << indent() << "typelib_TypeDescription * pTD = 0;\n";
704 
705     OString superType(m_reader.getSuperTypeName());
706     if ( !superType.isEmpty() )
707         o << indent() << "typelib_TypeDescriptionReference * pSuperType = 0;\n";
708 
709     sal_uInt32      count = getMemberCount();
710     sal_uInt32      fieldCount = m_reader.getFieldCount();
711     RTFieldAccess   access = RT_ACCESS_INVALID;
712     if (count)
713     {
714         o << indent() << "typelib_CompoundMember_Init aMembers["
715           << count << "];\n";
716 
717         for (sal_uInt16 i=0; i < fieldCount; i++)
718         {
719             access = m_reader.getFieldAccess(i);
720 
721             if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
722                 continue;
723 
724             o << indent() << "rtl_uString * pMemberName" << i << " = 0;\n"
725               << indent() << "rtl_uString * pMemberType" << i << " = 0;\n";
726         }
727     }
728 
729     o << indent() << "rtl_uString_newFromAscii( &pTypeName, \"" << m_typeName.replace('/', '.') << "\" );\n";
730 
731     if ( !superType.isEmpty() )
732     {
733         o << indent() << "typelib_typedescriptionreference_newByAsciiName(&pSuperType, typelib_TypeClass_INTERFACE, \""
734           << superType.replace('/', '.') << "\" );\n";
735     }
736 
737     dumpCppuGetTypeMemberDecl(o, CUNOTYPEDECL_ALLTYPES);
738 
739     if (count)
740     {
741         OString         fieldType, fieldName;
742         OString         scope = m_typeName.replace('/', '.');
743 
744         for (sal_uInt16 i=0; i < fieldCount; i++)
745         {
746             access = m_reader.getFieldAccess(i);
747 
748             if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
749                 continue;
750 
751             fieldName = m_reader.getFieldName(i);
752             fieldType = checkRealBaseType(m_reader.getFieldType(i), sal_True);
753 
754             o << indent() << "rtl_uString_newFromAscii( &pMemberType" << i << ", \""
755               << fieldType.replace('/', '.') << "\") );\n";
756             o << indent() << "rtl_uString_newFromAscii( &pMemberName" << i << ", \"";
757             o << fieldName << "\") );\n";
758             o << indent() << "aMembers[" << i << "].eTypeClass = "
759               << getTypeClass(fieldType, sal_True) << ";\n"
760               << indent() << "aMembers[" << i << "].pTypeName = pMemberType" << i << ";\n"
761               << indent() << "aMembers[" << i << "].pMemberName = pMemberName" << i << ";\n";
762         }
763 
764         o << "\n" << indent() << "typelib_typedescription_new(\n";
765         inc();
766         o << indent() << "&pTD,\n" << indent()
767           << getTypeClass(OString(), sal_True) << ", pTypeName,\n";
768 
769         if ( !superType.isEmpty() )
770             o << indent() << "pSuperType,\n";
771         else
772             o << indent() << "0,\n";
773 
774         if ( count )
775         {
776             o << indent() << count << ",\n" << indent() << "aMembers );\n\n";
777         } else
778         {
779             o << indent() << count << ",\n" << indent() << "0 );\n\n";
780         }
781 
782         dec();
783         o << indent() << "typelib_typedescription_register( &pTD );\n\n";
784 
785         o << indent() << "typelib_typedescriptionreference_new( &s_pType_ " << typeName
786           << getTypeClass(OString(), sal_True) << ", pTD);\n\n";
787 
788         o << indent() << "typelib_typedescription_release( pTD );\n"
789           << indent() << "typelib_typedescriptionreference_release( pSuperType );\n"
790           << indent() << "rtl_uString_release( pTypeName );\n";
791 
792         for (i=0; i < fieldCount; i++)
793         {
794             access = m_reader.getFieldAccess(i);
795 
796             if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
797                 continue;
798 
799             o << indent() << "rtl_uString_release( pMemberName" << i << " );\n"
800               << indent() << "rtl_uString_release( pMemberType" << i << " );\n";
801         }
802     }
803 
804     dec();
805     o << indent() << "}\n";
806     o << indent() << "osl_releaseMutex( pMutex );\n";
807     dec();
808     o << indent() << "}\n"
809       << indent() << "typelib_typedescriptionreference_acquire( s_pType_" << typeName << " );\n"
810       << indent() << "return &s_pType_" << typeName <<" );\n";
811     dec();
812     o << "}\n";
813 
814     dumpCloseExternC(o);
815 }
816 
dumpCppuGetTypeMemberDecl(FileStream & o,CunoTypeDecl eDeclFlag)817 void CunoType::dumpCppuGetTypeMemberDecl(FileStream& o, CunoTypeDecl eDeclFlag)
818 {
819     sal_uInt32      fieldCount = m_reader.getFieldCount();
820     RTFieldAccess   access = RT_ACCESS_INVALID;
821 
822     if ( fieldCount )
823     {
824         o << indent() << "{\n" << indent() << "typelib_TypeDescriptionReference ** ppTypeRef = 0;\n";
825 
826         StringSet aFinishedTypes;
827         for (sal_uInt16 i=0; i < fieldCount; i++)
828         {
829             access = m_reader.getFieldAccess(i);
830 
831             if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
832                 continue;
833 
834             if (aFinishedTypes.count(m_reader.getFieldType(i)) == 0)
835             {
836                 aFinishedTypes.insert(m_reader.getFieldType(i));
837                 dumpCppuGetType(o, m_reader.getFieldType(i), sal_True, eDeclFlag);
838             }
839         }
840         o << indent() << "}\n";
841     }
842 }
843 
getMemberCount()844 sal_uInt32 CunoType::getMemberCount()
845 {
846     sal_uInt32 count = m_reader.getMethodCount();
847 
848     sal_uInt32 fieldCount = m_reader.getFieldCount();
849     RTFieldAccess access = RT_ACCESS_INVALID;
850     for (sal_uInt16 i=0; i < fieldCount; i++)
851     {
852         access = m_reader.getFieldAccess(i);
853 
854         if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
855             count++;
856     }
857     return count;
858 }
859 
checkInheritedMemberCount(const TypeReader * pReader)860 sal_uInt32 CunoType::checkInheritedMemberCount(const TypeReader* pReader)
861 {
862     sal_Bool bSelfCheck = sal_True;
863     if (!pReader)
864     {
865         bSelfCheck = sal_False;
866         pReader = &m_reader;
867     }
868 
869     sal_uInt32 count = 0;
870     OString superType(pReader->getSuperTypeName());
871     if ( !superType.isEmpty() )
872     {
873         TypeReader aSuperReader(m_typeMgr.getTypeReader(superType));
874         if ( aSuperReader.isValid() )
875         {
876             count = checkInheritedMemberCount(&aSuperReader);
877         }
878     }
879 
880     if (bSelfCheck)
881     {
882         count += pReader->getMethodCount();
883         sal_uInt32 fieldCount = pReader->getFieldCount();
884         RTFieldAccess access = RT_ACCESS_INVALID;
885         for (sal_uInt16 i=0; i < fieldCount; i++)
886         {
887             access = pReader->getFieldAccess(i);
888 
889             if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
890             {
891                 count++;
892             }
893         }
894     }
895 
896     return count;
897 }
898 
getInheritedMemberCount()899 sal_uInt32 CunoType::getInheritedMemberCount()
900 {
901     if (m_inheritedMemberCount == 0)
902     {
903         m_inheritedMemberCount = checkInheritedMemberCount(0);
904     }
905 
906     return m_inheritedMemberCount;
907 }
908 
dumpInheritedMembers(FileStream & o,rtl::OString & superType)909 void CunoType::dumpInheritedMembers(FileStream& o, rtl::OString& superType)
910 {
911     TypeReader aSuperReader(m_typeMgr.getTypeReader(superType));
912 
913     OString baseType(aSuperReader.getSuperTypeName());
914     if ( !baseType.isEmpty() )
915     {
916         dumpInheritedMembers(o, baseType);
917     }
918 
919     sal_uInt32 fieldCount = aSuperReader.getFieldCount();
920     RTFieldAccess access = RT_ACCESS_INVALID;
921     OString fieldName;
922     OString fieldType;
923     for (sal_uInt16 i=0; i < fieldCount; i++)
924     {
925         access = aSuperReader.getFieldAccess(i);
926 
927         if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
928         {
929             fieldName = aSuperReader.getFieldName(i);
930             fieldType = aSuperReader.getFieldType(i);
931 
932             o << indent();
933             dumpType(o, fieldType);
934             o << " " << fieldName << ";\n";
935         }
936     }
937 }
938 
getTypeClass(const OString & type,sal_Bool bCStyle)939 OString CunoType::getTypeClass(const OString& type, sal_Bool bCStyle)
940 {
941     OString     typeName = ( !type.isEmpty() ? type : m_typeName );
942     RTTypeClass rtTypeClass = RT_TYPE_INVALID;
943 
944     if ( !type.isEmpty() )
945     {
946         typeName = type;
947         rtTypeClass = m_typeMgr.getTypeClass(typeName);
948     } else
949     {
950         typeName = m_typeName;
951         rtTypeClass = m_reader.getTypeClass();
952     }
953 
954     if (typeName.lastIndexOf(']') > 0)
955         return bCStyle ? "typelib_TypeClass_SEQUENCE" : "::com::sun::star::uno::TypeClass_SEQUENCE";
956 
957     switch (rtTypeClass)
958     {
959         case RT_TYPE_INTERFACE:
960             return bCStyle ? "typelib_TypeClass_INTERFACE" : "::com::sun::star::uno::TypeClass_INTERFACE";
961             break;
962         case RT_TYPE_MODULE:
963             return bCStyle ? "typelib_TypeClass_MODULE" : "::com::sun::star::uno::TypeClass_MODULE";
964             break;
965         case RT_TYPE_STRUCT:
966             return bCStyle ? "typelib_TypeClass_STRUCT" : "::com::sun::star::uno::TypeClass_STRUCT";
967             break;
968         case RT_TYPE_ENUM:
969             return bCStyle ? "typelib_TypeClass_ENUM" : "::com::sun::star::uno::TypeClass_ENUM";
970             break;
971         case RT_TYPE_EXCEPTION:
972             return bCStyle ? "typelib_TypeClass_EXCEPTION" : "::com::sun::star::uno::TypeClass_EXCEPTION";
973             break;
974         case RT_TYPE_TYPEDEF:
975             {
976                 OString realType = checkRealBaseType( typeName );
977                 return getTypeClass( realType, bCStyle );
978             }
979 //          return bCStyle ? "typelib_TypeClass_TYPEDEF" : "::com::sun::star::uno::TypeClass_TYPEDEF";
980             break;
981         case RT_TYPE_SERVICE:
982             return bCStyle ? "typelib_TypeClass_SERVICE" : "::com::sun::star::uno::TypeClass_SERVICE";
983             break;
984         case RT_TYPE_INVALID:
985             {
986                 if (type.equals("long"))
987                     return bCStyle ? "typelib_TypeClass_LONG" : "::com::sun::star::uno::TypeClass_LONG";
988                 if (type.equals("short"))
989                     return bCStyle ? "typelib_TypeClass_SHORT" : "::com::sun::star::uno::TypeClass_SHORT";
990                 if (type.equals("hyper"))
991                     return bCStyle ? "typelib_TypeClass_HYPER" : "::com::sun::star::uno::TypeClass_HYPER";
992                 if (type.equals("string"))
993                     return bCStyle ? "typelib_TypeClass_STRING" : "::com::sun::star::uno::TypeClass_STRING";
994                 if (type.equals("boolean"))
995                     return bCStyle ? "typelib_TypeClass_BOOLEAN" : "::com::sun::star::uno::TypeClass_BOOLEAN";
996                 if (type.equals("char"))
997                     return bCStyle ? "typelib_TypeClass_CHAR" : "::com::sun::star::uno::TypeClass_CHAR";
998                 if (type.equals("byte"))
999                     return bCStyle ? "typelib_TypeClass_BYTE" : "::com::sun::star::uno::TypeClass_BYTE";
1000                 if (type.equals("any"))
1001                     return bCStyle ? "typelib_TypeClass_ANY" : "::com::sun::star::uno::TypeClass_ANY";
1002                 if (type.equals("type"))
1003                     return bCStyle ? "typelib_TypeClass_TYPE" : "::com::sun::star::uno::TypeClass_TYPE";
1004                 if (type.equals("float"))
1005                     return bCStyle ? "typelib_TypeClass_FLOAT" : "::com::sun::star::uno::TypeClass_FLOAT";
1006                 if (type.equals("double"))
1007                     return bCStyle ? "typelib_TypeClass_DOUBLE" : "::com::sun::star::uno::TypeClass_DOUBLE";
1008                 if (type.equals("void"))
1009                     return bCStyle ? "typelib_TypeClass_VOID" : "::com::sun::star::uno::TypeClass_VOID";
1010                 if (type.equals("unsigned long"))
1011                     return bCStyle ? "typelib_TypeClass_UNSIGNED_LONG" : "::com::sun::star::uno::TypeClass_UNSIGNED_LONG";
1012                 if (type.equals("unsigned short"))
1013                     return bCStyle ? "typelib_TypeClass_UNSIGNED_SHORT" : "::com::sun::star::uno::TypeClass_UNSIGNED_SHORT";
1014                 if (type.equals("unsigned hyper"))
1015                     return bCStyle ? "typelib_TypeClass_UNSIGNED_HYPER" : "::com::sun::star::uno::TypeClass_UNSIGNED_HYPER";
1016             }
1017             break;
1018     }
1019 
1020     return bCStyle ? "typelib_TypeClass_UNKNOWN" : "::com::sun::star::uno::TypeClass_UNKNOWN";
1021 }
1022 
dumpType(FileStream & o,const OString & type,sal_Bool bConst,sal_Bool bPointer,sal_Bool bParam)1023 void CunoType::dumpType(FileStream& o, const OString& type,
1024                         sal_Bool bConst, sal_Bool bPointer, sal_Bool bParam)
1025     throw( CannotDumpException )
1026 {
1027     OString sType(checkRealBaseType(type, sal_True));
1028     sal_uInt32 index = sType.lastIndexOf(']');
1029     sal_uInt32 seqNum = (index > 0 ? ((index+1) / 2) : 0);
1030 
1031     OString relType = (index > 0 ? (sType).copy(index+1) : type);
1032 
1033     RTTypeClass typeClass = m_typeMgr.getTypeClass(relType);
1034 
1035 //  if (bConst) o << "const ";
1036 
1037     if ( seqNum )
1038     {
1039         o << "/*";
1040         sal_uInt32 i;
1041         for (i=0; i < seqNum; i++)
1042         {
1043             o << "sequence< ";
1044         }
1045         o << relType.replace( '/', '.');
1046         for (i=0; i < seqNum; i++)
1047         {
1048             o << " >";
1049         }
1050         o << "*/ uno_Sequence *";
1051         if (bPointer) o << "*";
1052         return;
1053     }
1054     switch (typeClass)
1055     {
1056         case RT_TYPE_INTERFACE:
1057             o << relType.replace('/', '_') << " *";
1058             break;
1059         case RT_TYPE_INVALID:
1060             {
1061                 OString tmp(getBaseType(relType));
1062                 if ( !tmp.isEmpty() )
1063                 {
1064                     o << tmp.getStr();
1065                     if ( bParam && !bPointer && relType.equals("any") )
1066                         o << " *";
1067                 } else
1068                     throw CannotDumpException("Unknown type '" + relType + "', incomplete type library.");
1069             }
1070             break;
1071         case RT_TYPE_STRUCT:
1072         case RT_TYPE_EXCEPTION:
1073             o << relType.replace('/', '_');
1074             if ( bParam && !bPointer ) o << " *";
1075             break;
1076         case RT_TYPE_ENUM:
1077         case RT_TYPE_TYPEDEF:
1078             o << relType.replace('/', '_');
1079             break;
1080     }
1081 
1082     if (bPointer) o << "*";
1083 }
1084 
getBaseType(const OString & type)1085 OString CunoType::getBaseType(const OString& type)
1086 {
1087     if (type.equals("long"))
1088         return "sal_Int32";
1089     if (type.equals("short"))
1090         return "sal_Int16";
1091     if (type.equals("hyper"))
1092         return "sal_Int64";
1093     if (type.equals("string"))
1094         return "rtl_uString *";
1095     if (type.equals("boolean"))
1096         return "sal_Bool";
1097     if (type.equals("char"))
1098         return "sal_Unicode";
1099     if (type.equals("byte"))
1100         return "sal_Int8";
1101     if (type.equals("any"))
1102         return "uno_Any";
1103     if (type.equals("type"))
1104         return "typelib_TypeDescriptionReference *";
1105     if (type.equals("float"))
1106         return "float";
1107     if (type.equals("double"))
1108         return "double";
1109     if (type.equals("octet"))
1110         return "sal_Int8";
1111     if (type.equals("void"))
1112         return type;
1113     if (type.equals("unsigned long"))
1114         return "sal_uInt32";
1115     if (type.equals("unsigned short"))
1116         return "sal_uInt16";
1117     if (type.equals("unsigned hyper"))
1118         return "sal_uInt64";
1119 
1120     return OString();
1121 }
1122 
dumpCppuGetType(FileStream & o,const OString & type,sal_Bool bDecl,CunoTypeDecl eDeclFlag)1123 void CunoType::dumpCppuGetType(FileStream& o, const OString& type, sal_Bool bDecl, CunoTypeDecl eDeclFlag)
1124 {
1125     OString sType( checkRealBaseType(type, sal_True) );
1126     sal_uInt32 index = sType.lastIndexOf(']');
1127     OString relType = (index > 0 ? (sType).copy(index+1) : type);
1128 
1129     if (eDeclFlag == CUNOTYPEDECL_ONLYINTERFACES)
1130     {
1131         if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE)
1132         {
1133             if (bDecl)
1134                 o << indent() << "ppTypeRef = ";
1135             else
1136                 o << indent();
1137 
1138             o << "getCUnoType_" << type.replace('/', '_') << "()";
1139 
1140             if (bDecl)
1141                 o << ";\n" << indent() << "typelib_typedescriptionreference_release( *ppTypeRef );\n";
1142         }
1143     } else
1144     {
1145         if (isBaseType(type))
1146         {
1147             return;
1148         } else
1149         {
1150             if (eDeclFlag == CUNOTYPEDECL_NOINTERFACES &&
1151                 m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE)
1152                 return;
1153 
1154             if ( type.equals("type") )
1155                 return;
1156 
1157             if (bDecl)
1158                 o << indent() << "ppTypeRef = ";
1159             else
1160                 o << indent();
1161 
1162             o << indent() << "getCUnoType_" << type.replace('/', '_') << "()";
1163         }
1164         if (bDecl)
1165             o << ";\n" << indent() << "typelib_typedescriptionreference_release( *ppTypeRef );\n";
1166     }
1167 }
1168 
dumpTypeInit(FileStream & o,const OString & typeName)1169 void CunoType::dumpTypeInit(FileStream& o, const OString& typeName)
1170 {
1171     OString type(checkSpecialCunoType(typeName));
1172 
1173     BASETYPE baseType = isBaseType(type);
1174 
1175     switch (baseType)
1176     {
1177         case BT_BOOLEAN:
1178             o << "(sal_False)";
1179             return;
1180             break;
1181         case BT_ANY:
1182         case BT_STRING:
1183             o << "()";
1184             return;
1185             break;
1186         case BT_INVALID:
1187             break;
1188         default:
1189             o << "((";
1190             dumpType(o, type);
1191             o << ")" << "0)";
1192             return;
1193     }
1194 
1195     RTTypeClass typeClass = m_typeMgr.getTypeClass(type);
1196 
1197     if (typeClass == RT_TYPE_ENUM)
1198     {
1199         RegistryTypeReaderLoader aReaderLoader;
1200 
1201         if (aReaderLoader.isLoaded())
1202         {
1203             TypeReader reader(m_typeMgr.getTypeReader(type));
1204 
1205             if ( reader.isValid() )
1206             {
1207                 sal_Int32 i = type.lastIndexOf('/');
1208                 o << "(" << shortScopedName("", type, sal_False)
1209                   << "::" << type.copy( i != -1 ? i+1 :0 )
1210                   << "_" << reader.getFieldName(0) << ")";
1211                 return;
1212             }
1213         }
1214     }
1215 
1216     o << "()";
1217 }
1218 
isBaseType(const OString & type)1219 BASETYPE CunoType::isBaseType(const OString& type)
1220 {
1221     if (type.equals("long"))
1222         return BT_LONG;
1223     if (type.equals("short"))
1224         return BT_SHORT;
1225     if (type.equals("hyper"))
1226         return BT_HYPER;
1227     if (type.equals("string"))
1228         return BT_STRING;
1229     if (type.equals("boolean"))
1230         return BT_BOOLEAN;
1231     if (type.equals("char"))
1232         return BT_CHAR;
1233     if (type.equals("byte"))
1234         return BT_BYTE;
1235     if (type.equals("any"))
1236         return BT_ANY;
1237     if (type.equals("float"))
1238         return BT_FLOAT;
1239     if (type.equals("double"))
1240         return BT_DOUBLE;
1241     if (type.equals("void"))
1242         return BT_VOID;
1243     if (type.equals("unsigned long"))
1244         return BT_UNSIGNED_LONG;
1245     if (type.equals("unsigned short"))
1246         return BT_UNSIGNED_SHORT;
1247     if (type.equals("unsigned hyper"))
1248         return BT_UNSIGNED_HYPER;
1249 
1250     return BT_INVALID;
1251 }
1252 
typeToIdentifier(const OString & type)1253 OString CunoType::typeToIdentifier(const OString& type)
1254 {
1255     sal_uInt32 index = type.lastIndexOf(']');
1256     sal_uInt32 seqNum = (index > 0 ? ((index+1) / 2) : 0);
1257 
1258     OString relType = (index > 0 ? ((OString)type).copy(index+1) : type);
1259     OString sIdentifier;
1260 
1261     while( seqNum > 0 )
1262     {
1263         sIdentifier += OString("seq");
1264 
1265         if ( --seqNum == 0 )
1266         {
1267             sIdentifier += OString("_");
1268         }
1269     }
1270 
1271     if ( isBaseType(relType) )
1272     {
1273         sIdentifier += relType.replace(' ', '_');
1274     } else
1275     {
1276         sIdentifier += relType.replace('/', '_');
1277     }
1278 
1279 
1280     return sIdentifier;
1281 }
1282 
checkSpecialCunoType(const OString & type)1283 OString CunoType::checkSpecialCunoType(const OString& type)
1284 {
1285     OString baseType(type);
1286 
1287     RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader();
1288 
1289     RegistryKey     key;
1290     sal_uInt8*      pBuffer=NULL;
1291     RTTypeClass     typeClass;
1292     sal_Bool        isTypeDef = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF);
1293     TypeReader      reader;
1294 
1295     while (isTypeDef)
1296     {
1297         reader = m_typeMgr.getTypeReader(baseType);
1298 
1299         if (reader.isValid())
1300         {
1301             typeClass = reader.getTypeClass();
1302 
1303             if (typeClass == RT_TYPE_TYPEDEF)
1304                 baseType = reader.getSuperTypeName();
1305             else
1306                 isTypeDef = sal_False;
1307         } else
1308         {
1309             break;
1310         }
1311     }
1312 
1313     return baseType;
1314 }
1315 
isSeqType(const OString & type,OString & baseType,OString & seqPrefix)1316 sal_Bool CunoType::isSeqType(const OString& type, OString& baseType, OString& seqPrefix)
1317 {
1318     if ( type.getStr()[0] == '[' )
1319     {
1320         sal_uInt32 index = type.lastIndexOf(']');
1321         baseType = ((OString)type).copy(index+1);
1322         seqPrefix = ((OString)type).copy(0, index+1);
1323         return sal_True;
1324     } else
1325     {
1326         baseType = type;
1327         seqPrefix = OString();
1328     }
1329     return sal_False;
1330 }
1331 
isArrayType(const OString & type,OString & baseType,OString & arrayPrefix)1332 sal_Bool CunoType::isArrayType(const OString& type, OString& baseType, OString& arrayPrefix)
1333 {
1334     if ( type.getStr()[type.getLength()-1] == ']' )
1335     {
1336         sal_uInt32 index = type.indexOf('[');
1337         baseType = ((OString)type).copy(0, index-1);
1338         arrayPrefix = ((OString)type).copy(index);
1339         return sal_True;
1340     } else
1341     {
1342         baseType = type;
1343         arrayPrefix = OString();
1344     }
1345     return sal_False;
1346 }
1347 
checkRealBaseType(const OString & type,sal_Bool bResolveTypeOnly)1348 OString CunoType::checkRealBaseType(const OString& type, sal_Bool bResolveTypeOnly)
1349 {
1350     OString realType;
1351     OString baseType;
1352     OString completePrefix;
1353     OString prefix;
1354     sal_Bool bSeqType = sal_True;
1355 
1356     if ( !isSeqType(type, baseType, completePrefix) )
1357         isArrayType(type, baseType, completePrefix);
1358 
1359     RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader();
1360 
1361     RegistryKey     key;
1362     sal_uInt8*      pBuffer=NULL;
1363     RTTypeClass     typeClass;
1364     sal_Bool        mustBeChecked = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF);
1365     TypeReader      reader;
1366     while (mustBeChecked)
1367     {
1368         reader = m_typeMgr.getTypeReader(baseType);
1369 
1370         if (reader.isValid())
1371         {
1372             typeClass = reader.getTypeClass();
1373 
1374             if (typeClass == RT_TYPE_TYPEDEF)
1375             {
1376                 realType = reader.getSuperTypeName();
1377                 if ( isSeqType(realType, baseType, prefix) ||
1378                      isArrayType(realType, baseType, prefix) )
1379                 {
1380                     completePrefix += prefix;
1381                 }
1382             } else
1383                 mustBeChecked = sal_False;
1384         } else
1385         {
1386             break;
1387         }
1388     }
1389 
1390     if ( bResolveTypeOnly )
1391     {
1392         if ( !completePrefix.isEmpty() )
1393         {
1394             baseType = bSeqType ? (completePrefix + baseType) : ( baseType + completePrefix);
1395         }
1396     }
1397     return baseType;
1398 }
1399 
dumpConstantValue(FileStream & o,sal_uInt16 index)1400 void CunoType::dumpConstantValue(FileStream& o, sal_uInt16 index)
1401 {
1402     RTConstValue constValue = m_reader.getFieldConstValue(index);
1403 
1404     switch (constValue.m_type)
1405     {
1406         case RT_TYPE_BOOL:
1407             if (constValue.m_value.aBool)
1408                 o << "sal_True";
1409             else
1410                 o << "sal_False";
1411             break;
1412         case RT_TYPE_BYTE:
1413             {
1414                 char tmp[16];
1415                 snprintf(tmp, sizeof(tmp), "0x%x", (sal_Int8)constValue.m_value.aByte);
1416                 o << "(sal_Int8)" << tmp;
1417             }
1418             break;
1419         case RT_TYPE_INT16:
1420             o << "(sal_Int16)" << constValue.m_value.aShort;
1421             break;
1422         case RT_TYPE_UINT16:
1423             o << "(sal_uInt16)" << constValue.m_value.aUShort;
1424             break;
1425         case RT_TYPE_INT32:
1426             o << "(sal_Int32)" << constValue.m_value.aLong;
1427             break;
1428         case RT_TYPE_UINT32:
1429             o << "(sal_uInt32)" << constValue.m_value.aULong;
1430             break;
1431         case RT_TYPE_INT64:
1432             {
1433                 ::rtl::OString tmp( OString::valueOf(constValue.m_value.aHyper) );
1434                 o << "(sal_Int64)" << tmp.getStr() << "L";
1435             }
1436             break;
1437         case RT_TYPE_UINT64:
1438             {
1439                 ::rtl::OString tmp( OString::valueOf((sal_Int64)constValue.m_value.aUHyper) );
1440                 o << "(sal_uInt64)" << tmp.getStr() << "L";
1441             }
1442             break;
1443         case RT_TYPE_FLOAT:
1444             {
1445                 ::rtl::OString tmp( OString::valueOf(constValue.m_value.aFloat) );
1446                 o << "(float)" << tmp.getStr();
1447             }
1448             break;
1449         case RT_TYPE_DOUBLE:
1450             {
1451                 ::rtl::OString tmp( OString::valueOf(constValue.m_value.aDouble) );
1452                 o << "(double)" << tmp.getStr();
1453             }
1454             break;
1455         case RT_TYPE_STRING:
1456             {
1457                 ::rtl::OUString aUStr(constValue.m_value.aString);
1458                 ::rtl::OString aStr = ::rtl::OUStringToOString(aUStr, RTL_TEXTENCODING_ASCII_US);
1459                 o << "::rtl::OUString::createFromAscii(\"" << aStr.getStr() << "\")";
1460             }
1461             break;
1462     }
1463 }
1464 
inc(sal_uInt32 num)1465 void CunoType::inc(sal_uInt32 num)
1466 {
1467     m_indentLength += num;
1468 }
1469 
dec(sal_uInt32 num)1470 void CunoType::dec(sal_uInt32 num)
1471 {
1472     if (m_indentLength - num < 0)
1473         m_indentLength = 0;
1474     else
1475         m_indentLength -= num;
1476 }
1477 
indent()1478 OString CunoType::indent()
1479 {
1480     OStringBuffer tmp(m_indentLength);
1481 
1482     for (sal_uInt32 i=0; i < m_indentLength; i++)
1483     {
1484         tmp.append(' ');
1485     }
1486     return tmp.makeStringAndClear();
1487 }
1488 
indent(sal_uInt32 num)1489 OString CunoType::indent(sal_uInt32 num)
1490 {
1491     OStringBuffer tmp(m_indentLength + num);
1492 
1493     for (sal_uInt32 i=0; i < m_indentLength + num; i++)
1494     {
1495         tmp.append(' ');
1496     }
1497     return tmp.makeStringAndClear();
1498 }
1499 
1500 //*************************************************************************
1501 // InterfaceType
1502 //*************************************************************************
InterfaceType(TypeReader & typeReader,const OString & typeName,const TypeManager & typeMgr,const TypeDependency & typeDependencies)1503 InterfaceType::InterfaceType(TypeReader& typeReader,
1504                              const OString& typeName,
1505                              const TypeManager& typeMgr,
1506                              const TypeDependency& typeDependencies)
1507     : CunoType(typeReader, typeName, typeMgr, typeDependencies)
1508 {
1509     m_inheritedMemberCount = 0;
1510     m_hasAttributes = sal_False;
1511     m_hasMethods = sal_False;
1512 }
1513 
~InterfaceType()1514 InterfaceType::~InterfaceType()
1515 {
1516 
1517 }
1518 
dumpHFile(FileStream & o)1519 sal_Bool InterfaceType::dumpHFile(FileStream& o)
1520     throw( CannotDumpException )
1521 {
1522     OString headerDefine(dumpHeaderDefine(o, "H"));
1523     o << "\n";
1524 
1525     dumpDefaultHIncludes(o);
1526     o << "\n";
1527     dumpDepIncludes(o, m_typeName, "h");
1528     o << "\n";
1529     dumpOpenExternC(o);
1530 
1531     o << "#ifndef " << m_name.toAsciiUpperCase() << "\n";
1532     o << "#define " << m_name.toAsciiUpperCase() << "\n";
1533     o << "struct _" << m_name << "_ftab;\n"
1534       << "typedef struct _" << m_name << "_ftab * " << m_name << ";\n";
1535     o << "#endif\n\n";
1536 
1537     dumpDeclaration(o);
1538 
1539     if ( m_cunoTypeLib )
1540     {
1541         o << "#ifdef CUNO_TYPELIB\n"
1542           << "typelib_TypeDescriptionReference * SAL_CALL getCUnoType_" << m_name << "() SAL_THROW( () );\n"
1543           << "#endif\n\n";
1544     }
1545 
1546 /*
1547     if (getNestedTypeNames().getLength() > 0)
1548     {
1549         o << indent() << "// nested types\n\n";
1550         for (sal_uInt32 i = 0; i < getNestedTypeNames().getLength(); i++)
1551         {
1552             OUString s(getNestedTypeNames().getElement(i));
1553 
1554             OString nestedName(s.getStr(), s.getLength(), RTL_TEXTENCODING_UTF8);
1555 
1556             nestedName = checkRealBaseType(nestedName.copy(5));
1557 
1558             if (nestedName.lastIndexOf(']') < 0)
1559             {
1560                 o << "inline const ::com::sun::star::uno::Type& SAL_CALL getCunoType( ";
1561                 dumpType(o, nestedName, sal_True, sal_False);
1562                 o << "* ) SAL_THROW( () );\n\n";
1563             }
1564         }
1565     }
1566 */
1567     dumpCloseExternC(o);
1568 
1569     o << "#endif /* "<< headerDefine << " */\n";
1570     return sal_True;
1571 }
1572 
dumpInheritedFunctions(FileStream & o,rtl::OString & superType)1573 void InterfaceType::dumpInheritedFunctions(FileStream& o, rtl::OString& superType)
1574 {
1575     TypeReader aSuperReader(m_typeMgr.getTypeReader(superType));
1576 
1577     OString baseType(aSuperReader.getSuperTypeName());
1578     if ( !baseType.isEmpty() )
1579     {
1580         dumpInheritedFunctions(o, baseType);
1581     }
1582 
1583     dumpAttributes(o, superType.replace('/', '_'), aSuperReader);
1584     dumpMethods(o, superType.replace('/', '_'), aSuperReader);
1585 }
1586 
dumpDeclaration(FileStream & o)1587 sal_Bool InterfaceType::dumpDeclaration(FileStream& o)
1588     throw( CannotDumpException )
1589 {
1590     o << "typedef struct _" << m_name << "_ftab\n" << indent() << "{";
1591     inc();
1592 
1593     OString superType(m_reader.getSuperTypeName());
1594     if ( !superType.isEmpty() )
1595         dumpInheritedFunctions(o, superType);
1596 /*
1597     if (getNestedTypeNames().getLength() > 0)
1598     {
1599         inc();
1600         o << indent() << "// nested types\n\n";
1601         for (sal_uInt32 i = 0; i < getNestedTypeNames().getLength(); i++)
1602         {
1603             OUString s(getNestedTypeNames().getElement(i));
1604 
1605             OString nestedName(s.getStr(), s.getLength(), RTL_TEXTENCODING_UTF8);
1606 
1607             nestedName = nestedName.copy(5);
1608 
1609             o << indent() << "// " << nestedName.getStr() << "\n";
1610 
1611             TypeReader reader(m_typeMgr.getTypeReader(nestedName));
1612 
1613             if (reader.isValid())
1614             {
1615                 RTTypeClass typeClass = reader.getTypeClass();
1616                 switch (typeClass) {
1617                     case RT_TYPE_INTERFACE:
1618                         {
1619                             InterfaceType iType(reader, nestedName, m_typeMgr, m_dependencies);
1620                             iType.dumpDeclaration(o);
1621                         }
1622                         break;
1623                     case RT_TYPE_STRUCT:
1624                         {
1625                             StructureType sType(reader, nestedName, m_typeMgr, m_dependencies);
1626                             sType.dumpDeclaration(o);
1627                         }
1628                         break;
1629                     case RT_TYPE_ENUM:
1630                         {
1631                             EnumType enType(reader, nestedName, m_typeMgr, m_dependencies);
1632                             enType.dumpDeclaration(o);
1633                         }
1634                         break;
1635                     case RT_TYPE_EXCEPTION:
1636                         {
1637                             ExceptionType eType(reader, nestedName, m_typeMgr, m_dependencies);
1638                             eType.dumpDeclaration(o);
1639                         }
1640                         break;
1641                     case RT_TYPE_TYPEDEF:
1642                         {
1643                             TypeDefType tdType(reader, nestedName, m_typeMgr, m_dependencies);
1644                             tdType.dumpDeclaration(o);
1645                         }
1646                         break;
1647                     default:
1648                         break;
1649                 }
1650             }
1651         }
1652         dec();
1653     }
1654 */
1655     dumpAttributes(o, m_name, m_reader);
1656     dumpMethods(o, m_name, m_reader);
1657 
1658     dec();
1659     o << "} " << m_name << "_ftab;\n\n";
1660 
1661     return sal_True;
1662 }
1663 
dumpCFile(FileStream & o)1664 sal_Bool InterfaceType::dumpCFile(FileStream& o)
1665     throw( CannotDumpException )
1666 {
1667     dumpInclude(o, m_typeName, "h");
1668     o << "\n";
1669     dumpDefaultCIncludes(o);
1670     o << "\n";
1671     dumpDepIncludes(o, m_typeName, "h");
1672     o << "\n";
1673     dumpGetCunoType(o);
1674 /*
1675     if (getNestedTypeNames().getLength() > 0)
1676     {
1677         o << indent() << "// nested types\n\n";
1678         for (sal_uInt32 i = 0; i < getNestedTypeNames().getLength(); i++)
1679         {
1680             OUString s(getNestedTypeNames().getElement(i));
1681 
1682             OString nestedName(s.getStr(), s.getLength(), RTL_TEXTENCODING_UTF8);
1683 
1684             nestedName = nestedName.copy(5);
1685 
1686             o << indent() << "// " << nestedName.getStr() << "\n";
1687 
1688             TypeReader reader(m_typeMgr.getTypeReader(nestedName));
1689 
1690             if (reader.isValid())
1691             {
1692                 RTTypeClass typeClass = reader.getTypeClass();
1693                 switch (typeClass) {
1694                     case RT_TYPE_INTERFACE:
1695                         {
1696                             InterfaceType iType(reader, nestedName, m_typeMgr, m_dependencies);
1697                             iType.dumpGetCunoType(o);
1698                         }
1699                         break;
1700                     case RT_TYPE_STRUCT:
1701                         {
1702                             StructureType sType(reader, nestedName, m_typeMgr, m_dependencies);
1703                             sType.dumpGetCunoType(o);
1704                         }
1705                         break;
1706                     case RT_TYPE_ENUM:
1707                         {
1708                             EnumType enType(reader, nestedName, m_typeMgr, m_dependencies);
1709                             enType.dumpGetCunoType(o);
1710                         }
1711                         break;
1712                     case RT_TYPE_EXCEPTION:
1713                         {
1714                             ExceptionType eType(reader, nestedName, m_typeMgr, m_dependencies);
1715                             eType.dumpGetCunoType(o);
1716                         }
1717                         break;
1718                     case RT_TYPE_TYPEDEF:
1719                         {
1720                             TypeDefType tdType(reader, nestedName, m_typeMgr, m_dependencies);
1721                             tdType.dumpGetCunoType(o);
1722                         }
1723                         break;
1724                     default:
1725                         break;
1726                 }
1727             }
1728         }
1729     }
1730 */
1731     return sal_True;
1732 }
1733 
dumpAttributes(FileStream & o,const OString & interfaceType,TypeReader & reader)1734 void InterfaceType::dumpAttributes(FileStream& o, const OString& interfaceType, TypeReader& reader )
1735 {
1736     sal_uInt32 fieldCount = reader.getFieldCount();
1737     sal_Bool first=sal_True;
1738 
1739     RTFieldAccess access = RT_ACCESS_INVALID;
1740     OString fieldName;
1741     OString fieldType;
1742     for (sal_uInt16 i=0; i < fieldCount; i++)
1743     {
1744         access = reader.getFieldAccess(i);
1745 
1746         if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
1747             continue;
1748 
1749         fieldName = reader.getFieldName(i);
1750         fieldType = reader.getFieldType(i);
1751 
1752         if (first)
1753         {
1754             first = sal_False;
1755             o << "\n" << indent() << "/* Attributes of " << interfaceType << " */\n";
1756         }
1757 
1758         o << indent() << "cuno_ErrorCode (SAL_CALL *get" << fieldName << ")( "
1759           << interfaceType << " *, uno_Any *, ";
1760         dumpType(o, fieldType, sal_False, sal_True);
1761         o << " );\n";
1762 
1763         if (access != RT_ACCESS_READONLY)
1764         {
1765             OString relType = checkSpecialCunoType(fieldType);
1766             sal_Bool bParam = sal_False;
1767 
1768             if ( m_typeMgr.getTypeClass(relType) == RT_TYPE_STRUCT ||
1769                  m_typeMgr.getTypeClass(relType) == RT_TYPE_EXCEPTION ||
1770                 (isBaseType(relType) && relType.equals("any")))
1771             {
1772                 bParam = sal_True;
1773             } else
1774             {
1775                 bParam = sal_False;
1776             }
1777 
1778             o << indent() << "cuno_ErrorCode (SAL_CALL *set" << fieldName << ")( "
1779               << interfaceType << " *, uno_Any *, ";
1780             dumpType(o, fieldType, sal_False, sal_False, bParam);
1781             o << " );\n";
1782         }
1783     }
1784 }
1785 
dumpMethods(FileStream & o,const OString & interfaceType,TypeReader & reader)1786 void InterfaceType::dumpMethods(FileStream& o, const OString& interfaceType, TypeReader& reader )
1787 {
1788     sal_uInt32 methodCount = reader.getMethodCount();
1789     sal_Bool first=sal_True;
1790 
1791     OString methodName, returnType, paramType, paramName;
1792     sal_uInt32 paramCount = 0;
1793     sal_uInt32 excCount = 0;
1794     RTMethodMode methodMode = RT_MODE_INVALID;
1795     RTParamMode  paramMode = RT_PARAM_INVALID;
1796 
1797     sal_Bool bPointer = sal_False;
1798     sal_Bool bParam = sal_False;
1799     sal_Bool bWithRunTimeExcp = sal_True;
1800 
1801     for (sal_uInt16 i=0; i < methodCount; i++)
1802     {
1803         methodName = reader.getMethodName(i);
1804         returnType = reader.getMethodReturnType(i);
1805         paramCount = reader.getMethodParamCount(i);
1806         excCount = reader.getMethodExcCount(i);
1807         methodMode = reader.getMethodMode(i);
1808 
1809         if ( methodName.equals("queryInterface") )
1810         {
1811             first = sal_False;
1812             o << "\n" << indent() << "/* Methods of " << interfaceType << " */\n";
1813             o << indent() << "cuno_ErrorCode (SAL_CALL *queryInterface)( com_sun_star_uno_XInterface *, "
1814               << "uno_Any *, com_sun_star_uno_XInterface **, typelib_TypeDescriptionReference * );\n";
1815             continue;
1816         }
1817 
1818         if ( methodName.equals("acquire") || methodName.equals("release") )
1819         {
1820             bWithRunTimeExcp = sal_False;
1821         }
1822 
1823         if (first)
1824         {
1825             first = sal_False;
1826             o << "\n" << indent() << "/* Methods of " << interfaceType << " */\n";
1827         }
1828 
1829         o << indent() << "cuno_ErrorCode (SAL_CALL *" << methodName << ")( "
1830           << interfaceType << " *";
1831         if ( excCount || bWithRunTimeExcp )
1832         {
1833             o << ", uno_Any *";
1834         }
1835         if ( !isVoid(returnType) )
1836         {
1837             o << ", ";
1838             dumpType(o, returnType, sal_False, sal_True);
1839         }
1840 
1841         sal_uInt16 j;
1842         for (j=0; j < paramCount; j++)
1843         {
1844             paramName = reader.getMethodParamName(i, j);
1845             paramType = reader.getMethodParamType(i, j);
1846             paramMode = reader.getMethodParamMode(i, j);
1847 
1848             if (j < (sal_uInt16)paramCount) o << ", ";
1849 
1850             switch (paramMode)
1851             {
1852                 case RT_PARAM_IN:
1853                 {
1854                     OString relType = checkSpecialCunoType(paramType);
1855                     if (m_typeMgr.getTypeClass(relType) == RT_TYPE_STRUCT ||
1856                         m_typeMgr.getTypeClass(relType) == RT_TYPE_EXCEPTION ||
1857                         (isBaseType(relType) && relType.equals("any")))
1858                     {
1859                         bParam = sal_True;
1860                     } else
1861                     {
1862                         bParam = sal_False;
1863                     }
1864                     break;
1865                 }
1866                 case RT_PARAM_OUT:
1867                 case RT_PARAM_INOUT:
1868                     bPointer = sal_True;
1869                     break;
1870             }
1871 
1872             dumpType(o, paramType, sal_False, bPointer, bParam);
1873         }
1874         o << " );\n";
1875     }
1876 }
1877 
dumpGetCunoType(FileStream & o)1878 void InterfaceType::dumpGetCunoType(FileStream& o)
1879 {
1880     OString typeName(m_typeName.replace('/', '_'));
1881 
1882     if ( m_cunoTypeLeak )
1883     {
1884         dumpLGetCunoType(o);
1885         return;
1886     }
1887     if ( !m_cunoTypeDynamic )
1888     {
1889         dumpCGetCunoType(o);
1890         return;
1891     }
1892 
1893     dumpOpenExternC(o);
1894 
1895     if ( !m_typeName.equals("com/sun/star/uno/XInterface") )
1896     {
1897         o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
1898           << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
1899           << "#endif\n\n";
1900     }
1901 
1902     o << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () )\n{\n";
1903     inc();
1904 
1905     if ( m_typeName.equals("com/sun/star/uno/XInterface") )
1906     {
1907         o << indent() << "return typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE );\n";
1908     } else
1909     {
1910         o << indent() << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
1911           << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
1912           << indent() << "#endif\n\n";
1913 
1914         o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n";
1915         inc();
1916         OString superType(m_reader.getSuperTypeName());
1917         sal_Bool bWithBase = sal_False;
1918         if ( !superType.isEmpty() && !superType.equals("com/sun/star/uno/XInterface"))
1919         {
1920             bWithBase = sal_True;
1921             o << indent() << "typelib_TypeDescriptionReference * pSuperType = 0;\n"
1922               << indent() << "typelib_typedescriptionreference_newByAsciiName(&pSuperType, typelib_TypeClass_INTERFACE, \""
1923               << superType.replace('/', '.') << "\" );\n";
1924         }
1925 
1926         o << indent() << "typelib_static_interface_type_init( &s_pType_" << typeName
1927           << ", \"" << m_typeName.replace('/', '.') << "\", ";
1928 
1929         if ( bWithBase )
1930         {
1931             o << "pSuperType );\n";
1932         } else
1933         {
1934             o << "0 );\n";
1935         }
1936 
1937         dec();
1938         o << indent() << "}\n"
1939           << indent() << "typelib_typedescriptionreference_acquire( s_pType_" << typeName << " );\n"
1940           << indent() << "return &s_pType_" << typeName <<" );\n";
1941     }
1942     dec();
1943     o << indent() << "}\n";
1944 
1945     dumpCloseExternC(o);
1946 }
1947 
dumpCGetCunoType(FileStream & o)1948 void InterfaceType::dumpCGetCunoType(FileStream& o)
1949 {
1950     OString typeName(m_typeName.replace('/', '_'));
1951 
1952     dumpOpenExternC(o);
1953 
1954     o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
1955       <<  "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
1956       << "#endif\n\n";
1957 
1958     o << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () )\n{\n";
1959     inc();
1960 
1961     o << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
1962       << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
1963       << "#endif\n\n";
1964 
1965     o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n";
1966     inc();
1967     o << indent() << "oslMutex * pMutex = osl_getGlobalMutex();\n"
1968       << indent() << "osl_acquireMutex( pMutex );\n";
1969 
1970     o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n";
1971     inc();
1972     o << indent() << "rtl_uString * pTypeName = 0;\n"
1973       << indent() << "typelib_InterfaceTypeDescription * pTD = 0;\n";
1974 
1975     OString superType(m_reader.getSuperTypeName());
1976     sal_uInt32 count = getMemberCount();
1977 
1978     if ( !superType.isEmpty() )
1979         o << indent() << "typelib_TypeDescriptionReference * pSuperType = 0;\n";
1980 
1981     if (count)
1982     {
1983         o << indent() << "typelib_TypeDescriptionReference * pMembers[" << count << "] = { ";
1984         for (sal_uInt32 i = 0; i < count; i++)
1985         {
1986             o << "0";
1987             if (i+1 < count)
1988                 o << ",";
1989             else
1990                 o << " };\n";
1991         }
1992 
1993         dumpCUnoAttributeTypeNames(o);
1994         dumpCUnoMethodTypeNames(o);
1995     }
1996 
1997     o << indent() << "rtl_uString_newFromAscii( &pTypeName, \"" << m_typeName.replace('/', '.') << "\" );\n";
1998 
1999     if ( !superType.isEmpty() )
2000     {
2001         o << indent() << "typelib_typedescriptionreference_newByAsciiName(&pSuperType, typelib_TypeClass_INTERFACE, \""
2002           << superType.replace('/', '.') << "\" );\n";
2003     }
2004 
2005     if (count)
2006     {
2007         sal_uInt32 index = 0;
2008         dumpCUnoAttributeRefs(o, index);
2009         dumpCUnoMethodRefs(o, index);
2010     }
2011 
2012     o << "\n" << indent() << "typelib_typedescription_newInterface(\n";
2013     inc();
2014     o << indent() << "&pTD,\n"
2015       << indent() << "pTypeName, ";
2016 
2017     RTUik uik;
2018     m_reader.getUik(uik);
2019     sal_Char buffer[53];
2020     snprintf(buffer, sizeof(buffer), "0x%.8x, 0x%.4x, 0x%.4x, 0x%.8x, 0x%.8x,\n",
2021             uik.m_Data1, uik.m_Data2, uik.m_Data3, uik.m_Data4, uik.m_Data5);
2022     o << buffer;
2023 
2024     if ( !superType.isEmpty() )
2025         o << indent() << "pSuperType,\n";
2026     else
2027         o << indent() << "0,\n";
2028 
2029     if ( count )
2030     {
2031         o << indent() << count << ",\n" << indent() << "pMembers );\n\n";
2032     } else
2033     {
2034         o << indent() << count << ",\n" << indent() << "0 );\n\n";
2035     }
2036     dec();
2037 
2038     o << indent() << "typelib_typedescription_register( (typelib_TypeDescription**)&pTD );\n";
2039     if ( count )
2040     {
2041         for (sal_uInt16 i=0; i < count; i++)
2042         {
2043             o << indent() << "typelib_typedescriptionreference_release( pMembers["
2044               << i << "] );\n";
2045         }
2046     }
2047     o << indent() << "typelib_typedescription_release( (typelib_TypeDescription*)pTD );\n";
2048 
2049     if ( !superType.isEmpty() )
2050         o << indent() << "typelib_typedescription_release( pSuperType );\n\n";
2051     else
2052         o << "\n";
2053 
2054     o << indent() << "typelib_typedescriptionreference_new( &s_pType_ " << typeName
2055       << "typelib_TypeClass_INTERFACE, (typelib_TypeDescription*)pTD);\n\n";
2056 
2057     o << indent() << "typelib_TypeDescriptionReference ** ppTypeRef = 0;\n";
2058     StringSet   aTypes;
2059     // type for RuntimeException is always needed
2060     OString     sRunTimeExceptionType("com/sun/star/uno/RuntimeException");
2061     aTypes.insert(sRunTimeExceptionType);
2062     dumpCppuGetType(o, sRunTimeExceptionType, sal_True, CUNOTYPEDECL_ALLTYPES);
2063 
2064     dumpAttributesCppuDecl(o, &aTypes, CUNOTYPEDECL_ALLTYPES);
2065     dumpMethodsCppuDecl(o, &aTypes, CUNOTYPEDECL_ALLTYPES);
2066 
2067     if (count)
2068     {
2069         sal_uInt32 index = getInheritedMemberCount();
2070         dumpCUnoAttributes(o, index);
2071         dumpCUnoMethods(o, index);
2072     }
2073 
2074     // release strings for names
2075     dumpCUnoAttributeTypeNames(o, sal_True);
2076     dumpCUnoMethodTypeNames(o, sal_True);
2077 
2078     dec();
2079     o << indent() << "}\n";
2080     o << indent() << "osl_releaseMutex( pMutex );\n";
2081     dec();
2082     o << indent() << "}\n\n"
2083       << indent() << "typelib_typedescriptionreference_acquire( s_pType_" << typeName << " );\n"
2084       << indent() << "return &s_pType_" << typeName << ";\n";
2085 
2086     dec();
2087     o << "}\n";
2088 
2089     dumpCloseExternC(o);
2090 }
2091 
dumpCUnoAttributeTypeNames(FileStream & o,sal_Bool bRelease)2092 void InterfaceType::dumpCUnoAttributeTypeNames(FileStream&o, sal_Bool bRelease)
2093 {
2094     sal_uInt32 fieldCount = m_reader.getFieldCount();
2095     RTFieldAccess access = RT_ACCESS_INVALID;
2096 
2097     for (sal_uInt16 i=0; i < fieldCount; i++)
2098     {
2099         access = m_reader.getFieldAccess(i);
2100         if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
2101             continue;
2102         if ( bRelease )
2103         {
2104             o << indent() << "rtl_uString_release( pAttributeName" << i << " );\n";
2105         } else
2106         {
2107             o << indent() << "rtl_uString * pAttributeName" << i << " = 0;\n";
2108         }
2109     }
2110 }
2111 
dumpCUnoMethodTypeNames(FileStream & o,sal_Bool bRelease)2112 void InterfaceType::dumpCUnoMethodTypeNames(FileStream&o, sal_Bool bRelease)
2113 {
2114     sal_uInt32  methodCount = m_reader.getMethodCount();
2115 
2116     for (sal_uInt16 i = 0; i < methodCount; i++)
2117     {
2118         if ( bRelease )
2119         {
2120             o << indent() << "rtl_uString_release( pMethodName" << i << " );\n";
2121         } else
2122         {
2123             o << indent() << "rtl_uString * pMethodName" << i << " = 0;\n";
2124         }
2125     }
2126 }
2127 
dumpCUnoAttributeRefs(FileStream & o,sal_uInt32 & index)2128 void InterfaceType::dumpCUnoAttributeRefs(FileStream& o, sal_uInt32& index)
2129 {
2130     sal_uInt32 fieldCount = m_reader.getFieldCount();
2131     RTFieldAccess access = RT_ACCESS_INVALID;
2132     OString fieldName;
2133     OString scope = m_typeName.replace('/', '.');
2134 
2135     for (sal_uInt16 i=0; i < fieldCount; i++)
2136     {
2137         access = m_reader.getFieldAccess(i);
2138         if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
2139             continue;
2140         fieldName = m_reader.getFieldName(i);
2141 
2142         o << indent() << "rtl_uString_newFromAscii( &pAttributeName" << i << ", \""
2143           << scope << "::" << fieldName << "\" );\n";
2144         o << indent() << "typelib_typedescriptionreference_new( &pMembers["
2145           << index << "],\n";
2146         inc(38);
2147         o << indent() << "typelib_TypeClass_INTERFACE_ATTRIBUTE,\n"
2148           << indent() << "pAttributeName" << i << " );\n";
2149         dec(38);
2150         index++;
2151     }
2152 }
2153 
dumpCUnoMethodRefs(FileStream & o,sal_uInt32 & index)2154 void InterfaceType::dumpCUnoMethodRefs(FileStream& o, sal_uInt32& index)
2155 {
2156     sal_uInt32  methodCount = m_reader.getMethodCount();
2157     OString     methodName; //, returnType, paramType, paramName;
2158     OString     scope = m_typeName.replace('/', '.');
2159 
2160     for (sal_uInt16 i = 0; i < methodCount; i++)
2161     {
2162         methodName = m_reader.getMethodName(i);
2163 
2164         o << indent() << "rtl_uString_newFromAscii( &pMethodName" << i << ", \""
2165           << scope.replace('/', '.') << "::" << methodName << "\" );\n";
2166         o << indent() << "typelib_typedescriptionreference_new( &pMembers["
2167           << index << "],\n";
2168         inc(38);
2169         o << indent() << "typelib_TypeClass_INTERFACE_METHOD,\n"
2170           << indent() << "pMethodName" << i << " );\n";
2171         dec(38);
2172         index++;
2173     }
2174 }
2175 
getMemberCount()2176 sal_uInt32 InterfaceType::getMemberCount()
2177 {
2178     sal_uInt32 count = m_reader.getMethodCount();
2179 
2180     if (count)
2181         m_hasMethods = sal_True;
2182 
2183     sal_uInt32 fieldCount = m_reader.getFieldCount();
2184     RTFieldAccess access = RT_ACCESS_INVALID;
2185     for (sal_uInt16 i=0; i < fieldCount; i++)
2186     {
2187         access = m_reader.getFieldAccess(i);
2188 
2189         if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
2190         {
2191             m_hasAttributes = sal_True;
2192             count++;
2193         }
2194     }
2195     return count;
2196 }
2197 
checkInheritedMemberCount(const TypeReader * pReader)2198 sal_uInt32 InterfaceType::checkInheritedMemberCount(const TypeReader* pReader)
2199 {
2200     sal_uInt32 cout = 0;
2201     sal_Bool bSelfCheck = sal_True;
2202     if (!pReader)
2203     {
2204         bSelfCheck = sal_False;
2205         pReader = &m_reader;
2206     }
2207 
2208     sal_uInt32 count = 0;
2209     OString superType(pReader->getSuperTypeName());
2210     if ( !superType.isEmpty() )
2211     {
2212         TypeReader aSuperReader(m_typeMgr.getTypeReader(superType));
2213         if (aSuperReader.isValid())
2214         {
2215             count = checkInheritedMemberCount(&aSuperReader);
2216         }
2217     }
2218 
2219     if (bSelfCheck)
2220     {
2221         count += pReader->getMethodCount();
2222         sal_uInt32 fieldCount = pReader->getFieldCount();
2223         RTFieldAccess access = RT_ACCESS_INVALID;
2224         for (sal_uInt16 i=0; i < fieldCount; i++)
2225         {
2226             access = pReader->getFieldAccess(i);
2227 
2228             if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
2229             {
2230                 count++;
2231             }
2232         }
2233     }
2234 
2235     return count;
2236 }
2237 
getInheritedMemberCount()2238 sal_uInt32 InterfaceType::getInheritedMemberCount()
2239 {
2240     if (m_inheritedMemberCount == 0)
2241     {
2242         m_inheritedMemberCount = checkInheritedMemberCount(0);
2243     }
2244 
2245     return m_inheritedMemberCount;
2246 }
2247 
dumpCUnoAttributes(FileStream & o,sal_uInt32 & index)2248 void InterfaceType::dumpCUnoAttributes(FileStream& o, sal_uInt32& index)
2249 {
2250     sal_uInt32 fieldCount = m_reader.getFieldCount();
2251 
2252     RTFieldAccess access = RT_ACCESS_INVALID;
2253     OString fieldType;
2254 
2255     sal_uInt32 absoluteIndex = index;
2256 
2257     if (m_hasAttributes)
2258     {
2259         o << "\n" << indent() << "{\n" << indent() << "typelib_InterfaceAttributeTypeDescription * pAttribute = 0;\n";
2260 
2261         for (sal_uInt16 i=0; i < fieldCount; i++)
2262         {
2263             access = m_reader.getFieldAccess(i);
2264 
2265             if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
2266                 continue;
2267 
2268             fieldType = checkRealBaseType(m_reader.getFieldType(i), sal_True);
2269             o << indent() << "{\n";
2270             o << indent() << "rtl_uString * pAttributeType" << i << " = 0;\n";
2271             o << indent() << "rtl_uString_newFromAscii( &pAttributeType" << i << ", \""
2272               << fieldType.replace('/', '.') << "\" );\n";
2273             o << indent() << "typelib_typedescription_newInterfaceAttribute( &pAttribute,\n";
2274             inc();
2275             o << indent() << absoluteIndex++ << ", pAttributeName" << i << ",\n";
2276             o << indent() << getTypeClass(fieldType, sal_True) << ", pAttributeType" << i << ",\n";
2277             if (access == RT_ACCESS_READONLY)
2278                 o << indent() << "sal_True );\n";
2279             else
2280                 o << indent() << "sal_False );\n";
2281             dec();
2282             o << indent() << "typelib_typedescription_register( (typelib_TypeDescription**)&pAttribute );\n\n";
2283             o << indent() << "}\n";
2284         }
2285         o << indent() << "typelib_typedescription_release( (typelib_TypeDescription*)pAttribute );\n";
2286         o << indent() << "}\n";
2287         index = absoluteIndex;
2288     }
2289 }
2290 
dumpCUnoMethods(FileStream & o,sal_uInt32 & index)2291 void InterfaceType::dumpCUnoMethods(FileStream& o, sal_uInt32& index)
2292 {
2293     sal_uInt32      methodCount = m_reader.getMethodCount();
2294     OString         methodName, returnType, paramType, paramName;
2295     sal_uInt32      paramCount = 0;
2296     sal_uInt32      excCount = 0;
2297     RTMethodMode    methodMode = RT_MODE_INVALID;
2298     RTParamMode     paramMode = RT_PARAM_INVALID;
2299     sal_Bool        bWithRuntimeException = sal_True;
2300 
2301     sal_uInt32 absoluteIndex = index;
2302 
2303     if (m_hasMethods)
2304     {
2305         o << "\n" << indent() << "{\n" << indent() << "typelib_InterfaceMethodTypeDescription * pMethod = 0;\n";
2306 
2307         for (sal_uInt16 i=0; i < methodCount; i++)
2308         {
2309             methodName = m_reader.getMethodName(i);
2310             returnType = checkRealBaseType(m_reader.getMethodReturnType(i), sal_True);
2311             paramCount = m_reader.getMethodParamCount(i);
2312             excCount = m_reader.getMethodExcCount(i);
2313             methodMode = m_reader.getMethodMode(i);
2314 
2315             if ( methodName.equals("acquire") || methodName.equals("release") )
2316             {
2317                 bWithRuntimeException = sal_False;
2318             }
2319             o << indent() << "{\n";
2320             inc();
2321 
2322             if (paramCount)
2323             {
2324                 o << indent() << "typelib_Parameter_Init pParameters[" << paramCount << "];\n";
2325             }
2326             if ( excCount || bWithRuntimeException )
2327             {
2328                 o << indent() << "rtl_uString * pExceptions[" << excCount + 1 << "];\n";
2329             }
2330             o << indent() << "rtl_uString * pReturnType" << i << " = 0;\n";
2331 
2332             sal_uInt16 j;
2333             for (j=0; j < paramCount; j++)
2334             {
2335                 o << indent() << "rtl_uString * pParamName" << j << " = 0;\n"
2336                   << indent() << "rtl_uString * pParamType" << j << " = 0;\n";
2337             }
2338 
2339             for (j=0; j < excCount; j++)
2340             {
2341                 o << indent() << "rtl_uString * pExceptionName" << j << " = 0;\n";
2342             }
2343             if ( excCount || bWithRuntimeException )
2344             {
2345                 o << indent() << "rtl_uString * pExceptionName" << excCount << " = 0;\n";
2346             }
2347             for (j=0; j < paramCount; j++)
2348             {
2349                 paramName = m_reader.getMethodParamName(i, j);
2350                 paramType = checkRealBaseType(m_reader.getMethodParamType(i, j), sal_True);
2351                 paramMode = m_reader.getMethodParamMode(i, j);
2352                 o << indent() << "rtl_uString_newFromAscii( &pParamName" << j << ", \""
2353                   << paramName << "\" );\n";
2354                 o << indent() << "rtl_uString_newFromAscii( &pParamType" << j << ", \""
2355                   << paramType.replace('/', '.') << "\" );\n";
2356                 o << indent() << "pParameters[" << j << "].pParamName = pParamName" << j << ";\n";
2357                 o << indent() << "pParameters[" << j << "].eTypeClass = "
2358                   << getTypeClass(paramType, sal_True) << ";\n";
2359                 o << indent() << "pParameters[" << j << "].pTypeName = sParamType" << j << ";\n";
2360 
2361                 if (paramMode == RT_PARAM_IN || paramMode == RT_PARAM_INOUT)
2362                     o << indent() << "pParameters[" << j << "].bIn = sal_True;\n";
2363                 else
2364                     o << indent() << "pParameters[" << j << "].bIn = sal_False;\n";
2365 
2366                 if (paramMode == RT_PARAM_OUT || paramMode == RT_PARAM_INOUT)
2367                     o << indent() << "pParameters[" << j << "].bOut = sal_True;\n";
2368                 else
2369                     o << indent() << "pParameters[" << j << "].bOut = sal_False;\n";
2370             }
2371 
2372             for (j=0; j < excCount; j++)
2373             {
2374                 if (!m_reader.getMethodExcType(i, j).equals("com/sun/star/uno/RuntimeException"))
2375                 {
2376                     o << indent() << "rtl_uString_newFromAscii( & pExceptionName" << j << ", \""
2377                       << OString(m_reader.getMethodExcType(i, j)).replace('/', '.') << "\" );\n";
2378                     o << indent() << "pExceptions[" << j << "] = pExceptionName" << j << ";\n";
2379                 }
2380             }
2381             if ( excCount || bWithRuntimeException )
2382             {
2383                 o << indent() << "rtl_uString_newFromAscii( & pExceptionName" << excCount
2384                   << ", \"com.sun.star.uno.RuntimeException\") );\n";
2385                 o << indent() << "pExceptions[" << excCount << "] = pExceptionName" << excCount << ";\n";
2386             }
2387             o << indent() << "rtl_uString_newFromAscii( &pReturnType" << i << ", \""
2388               << returnType.replace('/', '.') << "\" );\n";
2389             o << indent() << "typelib_typedescription_newInterfaceMethod( &pMethod,\n";
2390             inc();
2391             o << indent() << absoluteIndex++ << ", ";
2392             if (methodMode == RT_MODE_ONEWAY || methodMode == RT_MODE_ONEWAY_CONST)
2393                 o << "sal_True,\n";
2394             else
2395                 o << "sal_False,\n";
2396             o << indent() << "pMethodName" << i << ",\n";
2397             o << indent() << getTypeClass(returnType, sal_True) << ", pReturnType" << i << ",\n";
2398             if (paramCount)
2399                 o << indent() << paramCount << ", pParameters,\n";
2400             else
2401                 o << indent() << "0, 0,\n";
2402 
2403             if ( excCount || bWithRuntimeException )
2404             {
2405                 o << indent() << excCount + 1 << ", pExceptions );\n";
2406             } else
2407             {
2408                 o << indent() << "0, 0 );\n";
2409             }
2410 
2411             dec();
2412             o << indent() << "typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );\n";
2413 
2414             o << indent() << "rtl_uString_release( pReturnType );\n";
2415             for (j=0; j < paramCount; j++)
2416             {
2417                 o << indent() << "rtl_uString_release( pParamName" << j << " );\n"
2418                   << indent() << "rtl_uString_release( pParamType" << j << " );\n";
2419             }
2420 
2421             for (j=0; j < excCount; j++)
2422             {
2423                 o << indent() << "rtl_uString_release( pExceptionName" << j << " );\n";
2424             }
2425             if ( excCount || bWithRuntimeException )
2426             {
2427                 o << indent() << "rtl_uString_release( pExceptionName" << excCount << " );\n";
2428             }
2429             dec();
2430             o << indent() << "}\n";
2431         }
2432         o << indent() << "typelib_typedescription_release( (typelib_TypeDescription*)pMethod );\n";
2433 
2434         o << indent() << "}\n";
2435         index = absoluteIndex;
2436     }
2437 }
2438 
dumpAttributesCppuDecl(FileStream & o,StringSet * pFinishedTypes,CunoTypeDecl eDeclFlag)2439 void InterfaceType::dumpAttributesCppuDecl(FileStream& o, StringSet* pFinishedTypes, CunoTypeDecl eDeclFlag)
2440 {
2441     sal_uInt32 fieldCount = m_reader.getFieldCount();
2442 
2443     RTFieldAccess access = RT_ACCESS_INVALID;
2444     OString fieldName;
2445     OString fieldType;
2446     for (sal_uInt16 i=0; i < fieldCount; i++)
2447     {
2448         access = m_reader.getFieldAccess(i);
2449 
2450         if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
2451             continue;
2452 
2453         fieldName = m_reader.getFieldName(i);
2454         fieldType = m_reader.getFieldType(i);
2455 
2456         if (pFinishedTypes->count(fieldType) == 0)
2457         {
2458             pFinishedTypes->insert(fieldType);
2459             dumpCppuGetType(o, fieldType, sal_True, eDeclFlag);
2460         }
2461     }
2462 }
2463 
dumpMethodsCppuDecl(FileStream & o,StringSet * pFinishedTypes,CunoTypeDecl eDeclFlag)2464 void InterfaceType::dumpMethodsCppuDecl(FileStream& o, StringSet* pFinishedTypes, CunoTypeDecl eDeclFlag)
2465 {
2466     sal_uInt32      methodCount = m_reader.getMethodCount();
2467     OString         returnType, paramType, excType;
2468     sal_uInt32      paramCount = 0;
2469     sal_uInt32      excCount = 0;
2470 
2471     for (sal_uInt16 i=0; i < methodCount; i++)
2472     {
2473         returnType = m_reader.getMethodReturnType(i);
2474         paramCount = m_reader.getMethodParamCount(i);
2475         excCount = m_reader.getMethodExcCount(i);
2476 
2477         if (pFinishedTypes->count(returnType) == 0)
2478         {
2479             pFinishedTypes->insert(returnType);
2480             dumpCppuGetType(o, returnType, sal_True, eDeclFlag);
2481         }
2482         sal_uInt16 j;
2483         for (j=0; j < paramCount; j++)
2484         {
2485             paramType = m_reader.getMethodParamType(i, j);
2486 
2487             if (pFinishedTypes->count(paramType) == 0)
2488             {
2489                 pFinishedTypes->insert(paramType);
2490                 dumpCppuGetType(o, paramType, sal_True, eDeclFlag);
2491             }
2492         }
2493 
2494         for (j=0; j < excCount; j++)
2495         {
2496             excType = m_reader.getMethodExcType(i, j);
2497             if (pFinishedTypes->count(excType) == 0)
2498             {
2499                 pFinishedTypes->insert(excType);
2500                 dumpCppuGetType(o, excType, sal_True, eDeclFlag);
2501             }
2502         }
2503     }
2504 }
2505 
2506 //*************************************************************************
2507 // ModuleType
2508 //*************************************************************************
ModuleType(TypeReader & typeReader,const OString & typeName,const TypeManager & typeMgr,const TypeDependency & typeDependencies)2509 ModuleType::ModuleType(TypeReader& typeReader,
2510                        const OString& typeName,
2511                        const TypeManager& typeMgr,
2512                        const TypeDependency& typeDependencies)
2513     : CunoType(typeReader, typeName, typeMgr, typeDependencies)
2514 {
2515 }
2516 
~ModuleType()2517 ModuleType::~ModuleType()
2518 {
2519 
2520 }
2521 
dump(CunoOptions * pOptions)2522 sal_Bool ModuleType::dump(CunoOptions* pOptions)
2523     throw( CannotDumpException )
2524 {
2525     sal_Bool ret = sal_False;
2526 
2527     if (pOptions->isValid("-U"))
2528         m_cunoTypeDynamic = sal_True;
2529 
2530     OString outPath;
2531     if (pOptions->isValid("-O"))
2532         outPath = pOptions->getOption("-O");
2533 
2534     OString tmpName(m_typeName);
2535 
2536     if (tmpName.equals("/"))
2537         tmpName = "global";
2538     else
2539 //      tmpName += "/" + m_typeName.getToken(m_typeName.getTokenCount('/') - 1, '/');
2540         tmpName += "/" + m_name;
2541 
2542     OString tmpFileName;
2543     OString hFileName = createFileNameFromType(outPath, tmpName, ".hdl");
2544 
2545     sal_Bool bFileExists = sal_False;
2546     sal_Bool bFileCheck = sal_False;
2547 
2548     if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") )
2549     {
2550         bFileExists = fileExists( hFileName );
2551         ret = sal_True;
2552     }
2553 
2554     if ( bFileExists && pOptions->isValid("-Gc") )
2555     {
2556         tmpFileName  = createFileNameFromType(outPath, m_typeName, ".tml");
2557         bFileCheck = sal_True;
2558     }
2559 
2560     if ( !bFileExists || bFileCheck )
2561     {
2562         FileStream hFile;
2563 
2564         if ( bFileCheck )
2565             hFile.open(tmpFileName);
2566         else
2567             hFile.open(hFileName);
2568 
2569         if(!hFile.isValid())
2570         {
2571             OString message("cannot open ");
2572             message += hFileName + " for writing";
2573             throw CannotDumpException(message);
2574         }
2575 
2576         ret = dumpHFile(hFile);
2577 
2578         hFile.close();
2579         if (ret && bFileCheck)
2580         {
2581             ret = checkFileContent(hFileName, tmpFileName);
2582         }
2583     }
2584 /*
2585     bFileExists = sal_False;
2586     bFileCheck = sal_False;
2587     OString cFileName = createFileNameFromType(outPath, tmpName, ".c");
2588 
2589     if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") )
2590     {
2591         bFileExists = fileExists( cFileName );
2592         ret = sal_True;
2593     }
2594 
2595     if ( bFileExists && pOptions->isValid("-Gc") )
2596     {
2597         tmpFileName  = createFileNameFromType(outPath, m_typeName, ".tmc");
2598         bFileCheck = sal_True;
2599     }
2600 
2601 
2602     if ( !bFileExists || bFileCheck )
2603     {
2604         FileStream hxxFile;
2605 
2606         if ( bFileCheck )
2607             cFile.open(tmpFileName);
2608         else
2609             cFile.open(cFileName);
2610 
2611         if(!cFile.isValid())
2612         {
2613             OString message("cannot open ");
2614             message += cFileName + " for writing";
2615             throw CannotDumpException(message);
2616         }
2617 
2618         ret = dumpCFile(cFile);
2619 
2620         cFile.close();
2621         if (ret && bFileCheck)
2622         {
2623             ret = checkFileContent(cFileName, tmpFileName);
2624         }
2625     }
2626 */
2627     return ret;
2628 }
2629 
dumpHFile(FileStream & o)2630 sal_Bool ModuleType::dumpHFile(FileStream& o)
2631     throw( CannotDumpException )
2632 {
2633     sal_Bool bSpecialDefine = sal_True;
2634 
2635     if (m_reader.getTypeClass() == RT_TYPE_CONSTANTS)
2636     {
2637         bSpecialDefine = sal_False;
2638     }
2639 
2640     OString headerDefine(dumpHeaderDefine(o, "H", bSpecialDefine));
2641     o << "\n";
2642 
2643     dumpDefaultHIncludes(o);
2644     o << "\n";
2645     dumpDepIncludes(o, m_typeName, "h");
2646     o << "\n";
2647 
2648     dumpOpenExternC(o);
2649     dumpDeclaration(o);
2650     o << "\n";
2651     dumpCloseExternC(o);
2652 
2653     o << "\n#endif /* "<< headerDefine << " */\n";
2654 
2655     return sal_True;
2656 }
2657 
dumpDeclaration(FileStream & o)2658 sal_Bool ModuleType::dumpDeclaration(FileStream& o)
2659     throw( CannotDumpException )
2660 {
2661     sal_uInt32      fieldCount = m_reader.getFieldCount();
2662     RTFieldAccess   access = RT_ACCESS_INVALID;
2663     OString         fieldName;
2664     OString         fieldType;
2665     for (sal_uInt16 i=0; i < fieldCount; i++)
2666     {
2667         access = m_reader.getFieldAccess(i);
2668 
2669         if (access == RT_ACCESS_CONST)
2670         {
2671             fieldName = m_reader.getFieldName(i);
2672             fieldType = m_reader.getFieldType(i);
2673 
2674             o << "static const ";
2675             dumpType(o, fieldType);
2676             o << " " << m_name << "_" << fieldName << " = ";
2677             dumpConstantValue(o, i);
2678             o << ";\n";
2679         }
2680     }
2681 
2682     return sal_True;
2683 }
2684 
hasConstants()2685 sal_Bool ModuleType::hasConstants()
2686 {
2687     sal_uInt32      fieldCount = m_reader.getFieldCount();
2688     RTFieldAccess   access = RT_ACCESS_INVALID;
2689 
2690     for (sal_uInt16 i=0; i < fieldCount; i++)
2691     {
2692         access = m_reader.getFieldAccess(i);
2693 
2694         if (access == RT_ACCESS_CONST)
2695             return sal_True;
2696     }
2697 
2698     return sal_False;
2699 }
2700 
dumpCFile(FileStream & o)2701 sal_Bool ModuleType::dumpCFile(FileStream& o)
2702     throw( CannotDumpException )
2703 {
2704     return sal_True;
2705 }
2706 
2707 //*************************************************************************
2708 // ConstantsType
2709 //*************************************************************************
ConstantsType(TypeReader & typeReader,const OString & typeName,const TypeManager & typeMgr,const TypeDependency & typeDependencies)2710 ConstantsType::ConstantsType(TypeReader& typeReader,
2711                              const OString& typeName,
2712                              const TypeManager& typeMgr,
2713                              const TypeDependency& typeDependencies)
2714     : ModuleType(typeReader, typeName, typeMgr, typeDependencies)
2715 {
2716 }
2717 
~ConstantsType()2718 ConstantsType::~ConstantsType()
2719 {
2720 
2721 }
2722 
dump(CunoOptions * pOptions)2723 sal_Bool ConstantsType::dump(CunoOptions* pOptions)
2724     throw( CannotDumpException )
2725 {
2726     sal_Bool ret = sal_False;
2727 
2728     if (pOptions->isValid("-U"))
2729         m_cunoTypeDynamic = sal_True;
2730 
2731     OString outPath;
2732     if (pOptions->isValid("-O"))
2733         outPath = pOptions->getOption("-O");
2734 
2735     OString tmpFileName;
2736     OString hFileName = createFileNameFromType(outPath, m_typeName, ".h");
2737 
2738     sal_Bool bFileExists = sal_False;
2739     sal_Bool bFileCheck = sal_False;
2740 
2741     if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") )
2742     {
2743         bFileExists = fileExists( hFileName );
2744         ret = sal_True;
2745     }
2746 
2747     if ( bFileExists && pOptions->isValid("-Gc") )
2748     {
2749         tmpFileName  = createFileNameFromType(outPath, m_typeName, ".tmh");
2750         bFileCheck = sal_True;
2751     }
2752 
2753     if ( !bFileExists || bFileCheck )
2754     {
2755         FileStream hFile;
2756 
2757         if ( bFileCheck )
2758             hFile.open(tmpFileName);
2759         else
2760             hFile.open(hFileName);
2761 
2762         if(!hFile.isValid())
2763         {
2764             OString message("cannot open ");
2765             message += hFileName + " for writing";
2766             throw CannotDumpException(message);
2767         }
2768 
2769         ret = dumpHFile(hFile);
2770 
2771         hFile.close();
2772         if (ret && bFileCheck)
2773         {
2774             ret = checkFileContent(hFileName, tmpFileName);
2775         }
2776     }
2777 /*
2778     bFileExists = sal_False;
2779     bFileCheck = sal_False;
2780     OString cFileName = createFileNameFromType(outPath, m_typeName, ".c");
2781 
2782     if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") )
2783     {
2784         bFileExists = fileExists( cFileName );
2785         ret = sal_True;
2786     }
2787 
2788     if ( bFileExists && pOptions->isValid("-Gc") )
2789     {
2790         tmpFileName  = createFileNameFromType(outPath, m_typeName, ".tmc");
2791         bFileCheck = sal_True;
2792     }
2793 
2794     if ( !bFileExists || bFileCheck )
2795     {
2796         FileStream cFile;
2797 
2798         if ( bFileCheck )
2799             cFile.open(tmpFileName);
2800         else
2801             cFile.open(cFileName);
2802 
2803         if(!cFile.isValid())
2804         {
2805             OString message("cannot open ");
2806             message += cFileName + " for writing";
2807             throw CannotDumpException(message);
2808         }
2809 
2810         ret = dumpCFile(cFile);
2811 
2812         cFile.close();
2813         if (ret && bFileCheck)
2814         {
2815             ret = checkFileContent(cFileName, tmpFileName);
2816         }
2817     }
2818 */
2819     return ret;
2820 }
2821 
2822 //*************************************************************************
2823 // StructureType
2824 //*************************************************************************
StructureType(TypeReader & typeReader,const OString & typeName,const TypeManager & typeMgr,const TypeDependency & typeDependencies)2825 StructureType::StructureType(TypeReader& typeReader,
2826                              const OString& typeName,
2827                              const TypeManager& typeMgr,
2828                              const TypeDependency& typeDependencies)
2829     : CunoType(typeReader, typeName, typeMgr, typeDependencies)
2830 {
2831 }
2832 
~StructureType()2833 StructureType::~StructureType()
2834 {
2835 
2836 }
2837 
dumpHFile(FileStream & o)2838 sal_Bool StructureType::dumpHFile(FileStream& o)
2839     throw( CannotDumpException )
2840 {
2841     OString headerDefine(dumpHeaderDefine(o, "H"));
2842     o << "\n";
2843 
2844     dumpDefaultHIncludes(o);
2845     o << "\n";
2846     dumpDepIncludes(o, m_typeName, "h");
2847     o << "\n";
2848 
2849     dumpOpenExternC(o);
2850 
2851     dumpDeclaration(o);
2852 
2853     if ( m_cunoTypeLib )
2854     {
2855         o << "#ifdef CUNO_TYPELIB\n"
2856           << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () );\n"
2857           << "#endif\n\n";
2858     }
2859 
2860     dumpCloseExternC(o);
2861 
2862     o << "#endif /* "<< headerDefine << " */\n";
2863 
2864     return sal_True;
2865 }
2866 
dumpDeclaration(FileStream & o)2867 sal_Bool StructureType::dumpDeclaration(FileStream& o)
2868     throw( CannotDumpException )
2869 {
2870     o << "#ifdef SAL_W32\n"
2871       << "#   pragma pack(push, 8)\n"
2872       << "#elif defined(SAL_OS2)\n"
2873       << "#   pragma pack(8)\n"
2874       << "#endif\n\n";
2875 
2876     o << "typedef struct _" << m_name << "\n{\n";
2877     inc();
2878 
2879     OString superType(m_reader.getSuperTypeName());
2880     if ( !superType.isEmpty() )
2881         o << indent() << superType.replace('/', '_').getStr() << " _Base;\n";
2882         //dumpInheritedMembers(o, superType);
2883 
2884     sal_uInt32      fieldCount = m_reader.getFieldCount();
2885     RTFieldAccess   access = RT_ACCESS_INVALID;
2886     OString         fieldName;
2887     OString         fieldType;
2888     sal_uInt16      i=0;
2889 
2890     for (i=0; i < fieldCount; i++)
2891     {
2892         access = m_reader.getFieldAccess(i);
2893 
2894         if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
2895             continue;
2896 
2897         fieldName = m_reader.getFieldName(i);
2898         fieldType = m_reader.getFieldType(i);
2899 
2900         o << indent();
2901         dumpType(o, fieldType);
2902         o << " " << fieldName << ";\n";
2903     }
2904 
2905     dec();
2906     o << "} " << m_name << ";\n\n";
2907 
2908     o << "#ifdef SAL_W32\n"
2909       << "#   pragma pack(pop)\n"
2910       << "#elif defined(SAL_OS2)\n"
2911       << "#   pragma pack()\n"
2912       << "#endif\n\n";
2913 
2914     return sal_True;
2915 }
2916 
dumpCFile(FileStream & o)2917 sal_Bool StructureType::dumpCFile(FileStream& o)
2918     throw( CannotDumpException )
2919 {
2920     dumpInclude(o, m_typeName, "h");
2921     o << "\n";
2922     dumpDefaultCIncludes(o);
2923     o << "\n";
2924     dumpDepIncludes(o, m_typeName, "h");
2925     o << "\n";
2926 
2927     dumpGetCunoType(o);
2928 
2929     return sal_True;
2930 }
2931 
2932 //*************************************************************************
2933 // ExceptionType
2934 //*************************************************************************
ExceptionType(TypeReader & typeReader,const OString & typeName,const TypeManager & typeMgr,const TypeDependency & typeDependencies)2935 ExceptionType::ExceptionType(TypeReader& typeReader,
2936                              const OString& typeName,
2937                              const TypeManager& typeMgr,
2938                              const TypeDependency& typeDependencies)
2939     : CunoType(typeReader, typeName, typeMgr, typeDependencies)
2940 {
2941 }
2942 
~ExceptionType()2943 ExceptionType::~ExceptionType()
2944 {
2945 
2946 }
2947 
dumpHFile(FileStream & o)2948 sal_Bool ExceptionType::dumpHFile(FileStream& o)
2949     throw( CannotDumpException )
2950 {
2951     OString headerDefine(dumpHeaderDefine(o, "H"));
2952     o << "\n";
2953 
2954     dumpDefaultHIncludes(o);
2955     o << "\n";
2956     dumpDepIncludes(o, m_typeName, "h");
2957     o << "\n";
2958 
2959     dumpOpenExternC(o);
2960 
2961     dumpDeclaration(o);
2962 
2963     if ( m_cunoTypeLib )
2964     {
2965         o << "#ifdef CUNO_TYPELIB\n"
2966           << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () );\n"
2967           << "#endif\n\n";
2968     }
2969 
2970     dumpCloseExternC(o);
2971 
2972     o << "#endif /* "<< headerDefine << " */\n";
2973 
2974     return sal_True;
2975 }
2976 
dumpDeclaration(FileStream & o)2977 sal_Bool ExceptionType::dumpDeclaration(FileStream& o)
2978     throw( CannotDumpException )
2979 {
2980     o << "#ifdef SAL_W32\n"
2981       << "#   pragma pack(push, 8)\n"
2982       << "#elif defined(SAL_OS2)\n"
2983       << "#   pragma pack(8)\n"
2984       << "#endif\n\n";
2985 
2986     o << "\n/* Exception type */\ntypedef struct _" << m_name << "\n{\n";
2987     inc();
2988 
2989     OString superType(m_reader.getSuperTypeName());
2990     if ( !superType.isEmpty() )
2991         o << indent() << superType.replace('/', '_').getStr() << " _Base;\n";
2992         //dumpInheritedMembers(o, superType);
2993 
2994     sal_uInt32      fieldCount = m_reader.getFieldCount();
2995     RTFieldAccess   access = RT_ACCESS_INVALID;
2996     OString         fieldName;
2997     OString         fieldType;
2998     sal_uInt16      i = 0;
2999 
3000     for (i=0; i < fieldCount; i++)
3001     {
3002         access = m_reader.getFieldAccess(i);
3003 
3004         if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
3005             continue;
3006 
3007         fieldName = m_reader.getFieldName(i);
3008         fieldType = m_reader.getFieldType(i);
3009 
3010         o << indent();
3011         dumpType(o, fieldType);
3012         o << " " << fieldName << ";\n";
3013     }
3014 
3015     dec();
3016     o << "} " << m_name << ";\n\n";
3017 
3018     o << "#ifdef SAL_W32\n"
3019       << "#   pragma pack(pop)\n"
3020       << "#elif defined(SAL_OS2)\n"
3021       << "#   pragma pack()\n"
3022       << "#endif\n\n";
3023 
3024     return sal_True;
3025 }
3026 
dumpCFile(FileStream & o)3027 sal_Bool ExceptionType::dumpCFile(FileStream& o)
3028     throw( CannotDumpException )
3029 {
3030     dumpInclude(o, m_typeName, "h");
3031     o << "\n";
3032     dumpDefaultCIncludes(o);
3033     o << "\n";
3034     dumpDepIncludes(o, m_typeName, "h");
3035     o << "\n";
3036 
3037     dumpGetCunoType(o);
3038 
3039     return sal_True;
3040 }
3041 
3042 
3043 //*************************************************************************
3044 // EnumType
3045 //*************************************************************************
EnumType(TypeReader & typeReader,const OString & typeName,const TypeManager & typeMgr,const TypeDependency & typeDependencies)3046 EnumType::EnumType(TypeReader& typeReader,
3047                    const OString& typeName,
3048                    const TypeManager& typeMgr,
3049                    const TypeDependency& typeDependencies)
3050     : CunoType(typeReader, typeName, typeMgr, typeDependencies)
3051 {
3052 }
3053 
~EnumType()3054 EnumType::~EnumType()
3055 {
3056 
3057 }
3058 
dumpHFile(FileStream & o)3059 sal_Bool EnumType::dumpHFile(FileStream& o)
3060     throw( CannotDumpException )
3061 {
3062     OString headerDefine(dumpHeaderDefine(o, "H"));
3063     o << "\n";
3064 
3065     dumpDefaultHIncludes(o);
3066     o << "\n";
3067     dumpOpenExternC(o);
3068 
3069     dumpDeclaration(o);
3070 
3071     if ( m_cunoTypeLib )
3072     {
3073         o << "#ifdef CUNO_TYPELIB\n"
3074           << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () );\n"
3075           << "#endif\n\n";
3076     }
3077 
3078     dumpCloseExternC(o);
3079 
3080     o << "#endif /* "<< headerDefine << " */\n";
3081 
3082     return sal_True;
3083 }
3084 
dumpDeclaration(FileStream & o)3085 sal_Bool EnumType::dumpDeclaration(FileStream& o)
3086     throw( CannotDumpException )
3087 {
3088     o << "\ntypedef enum _" << m_name << "\n{\n";
3089     inc();
3090 
3091     sal_uInt32      fieldCount = m_reader.getFieldCount();
3092     RTFieldAccess   access = RT_ACCESS_INVALID;
3093     RTConstValue    constValue;
3094     OString         fieldName;
3095     sal_Int32       value=0;
3096     for (sal_uInt16 i=0; i < fieldCount; i++)
3097     {
3098         access = m_reader.getFieldAccess(i);
3099 
3100         if (access != RT_ACCESS_CONST)
3101             continue;
3102 
3103         fieldName = m_reader.getFieldName(i);
3104         constValue = m_reader.getFieldConstValue(i);
3105 
3106         if (constValue.m_type == RT_TYPE_INT32)
3107             value = constValue.m_value.aLong;
3108         else
3109             value++;
3110 
3111         o << indent() << m_name << "_" << fieldName << " = " << value << ",\n";
3112     }
3113 
3114     o << indent() << m_name << "_MAKE_FIXED_SIZE = SAL_MAX_ENUM\n";
3115 
3116     dec();
3117     o << "} " << m_name << ";\n\n";
3118 
3119     return sal_True;
3120 }
3121 
dumpCFile(FileStream & o)3122 sal_Bool EnumType::dumpCFile(FileStream& o)
3123     throw( CannotDumpException )
3124 {
3125     dumpInclude(o, m_typeName, "h");
3126     o << "\n";
3127     dumpDefaultCIncludes(o);
3128     o << "\n";
3129     dumpGetCunoType(o);
3130     return sal_True;
3131 }
3132 
dumpGetCunoType(FileStream & o)3133 void EnumType::dumpGetCunoType(FileStream& o)
3134 {
3135     OString typeName(m_typeName.replace('/', '_'));
3136 
3137     if ( m_cunoTypeLeak )
3138     {
3139         dumpLGetCunoType(o);
3140         return;
3141     }
3142     if ( !m_cunoTypeDynamic )
3143     {
3144         dumpCGetCunoType(o);
3145         return;
3146     }
3147 
3148     dumpOpenExternC(o);
3149 
3150     o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
3151       << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
3152       << "#endif\n\n";
3153 
3154     o << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () )\n{\n";
3155     inc();
3156 
3157     o << indent() << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
3158       << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
3159       << indent() << "#endif\n\n";
3160 
3161     o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n";
3162     inc();
3163 
3164     o << indent() << "typelib_static_enum_type_init( &s_pType_" << typeName << ",\n";
3165     inc(31);
3166     o << indent() << "\"" << m_typeName.replace('/', '.') << "\",\n"
3167       << indent() << m_name << "_" << m_reader.getFieldName(0) << " );\n";
3168     dec(31);
3169     dec();
3170     o << indent() << "}\n"
3171       << indent() << "typelib_typedescriptionreference_acquire( s_pType_" << typeName <<" );\n"
3172       << indent() << "return &s_pType_" << typeName <<" );\n";
3173     dec();
3174     o << indent() << "}\n";
3175 
3176     dumpCloseExternC(o);
3177 }
3178 
dumpCGetCunoType(FileStream & o)3179 void EnumType::dumpCGetCunoType(FileStream& o)
3180 {
3181     OString typeName(m_typeName.replace('/', '_'));
3182 
3183     dumpOpenExternC(o);
3184 
3185     o << "#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
3186       << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
3187       << "#endif\n\n";
3188 
3189     o << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () )\n{\n";
3190     inc();
3191 
3192     o << "#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))\n"
3193       << indent() << "static typelib_TypeDescriptionReference * s_pType_" << typeName << " = 0;\n"
3194       << "#endif\n\n";
3195 
3196     o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n";
3197     inc();
3198     o << indent() << "oslMutex * pMutex = osl_getGlobalMutex();\n"
3199       << indent() << "osl_acquireMutex( pMutex );\n";
3200 
3201     o << indent() << "if ( !s_pType_" << typeName << " )\n" << indent() << "{\n";
3202     inc();
3203     o << indent() << "rtl_uString * pTypeName = 0;\n"
3204       << indent() << "_typelib_TypeDescription * pTD = 0;\n";
3205 
3206     sal_uInt32 count = m_reader.getFieldCount();
3207     o << indent() << "rtl_uString* enumValueNames[" << count << "];\n"
3208       << indent() << "sal_Int32 enumValues[" << count << "];\n";
3209     sal_uInt32 i;
3210     for (i = 0; i < count; i++)
3211     {
3212         o << indent() << "rtl_uString * pEnumValue" << i << " = 0;\n";
3213     }
3214 
3215     o << indent() << "rtl_uString_newFromAscii( &pTypeName, \""
3216       << m_typeName.replace('/', '.') << "\") );\n\n";
3217 
3218     for (i = 0; i < count; i++)
3219     {
3220         o << indent() << "rtl_uString_newFromAscii( &pEnumValue" << i << ", \""
3221           << m_reader.getFieldName((sal_uInt16)i) << "\" );\n";
3222         o << indent() << "enumValueNames[" << i << "] = pEnumValue" << i << ";\n";
3223     }
3224 
3225     RTConstValue    constValue;
3226     sal_Int32       value=0;
3227     for (i = 0; i < count; i++)
3228     {
3229         o << indent() << "enumValues[" << i << "] = ";
3230         constValue = m_reader.getFieldConstValue((sal_uInt16)i);
3231         if (constValue.m_type == RT_TYPE_INT32)
3232             value = constValue.m_value.aLong;
3233         else
3234             value++;
3235         o << value << ";\n";
3236     }
3237 
3238     o << "\n" << indent() << "typelib_typedescription_newEnum( &pTD,\n";
3239     inc();
3240     o << indent() << "pTypeName,\n"
3241       << indent() << "(sal_Int32)" << m_name << "_" << m_reader.getFieldName(0) << ",\n"
3242       << indent() << count << ", enumValueNames, enumValues );\n\n";
3243     dec();
3244 
3245     o << indent() << "typelib_typedescription_register( &pTD );\n";
3246 
3247     o << indent() << "typelib_typedescriptionreference_new( &s_pType_ " << typeName
3248       << getTypeClass(OString(), sal_True) << ", pTD);\n\n";
3249 
3250     o << indent() << "typelib_typedescription_release( pTD );\n"
3251       << indent() << "rtl_uString_release( pTypeName );\n";
3252     for (i = 0; i < count; i++)
3253     {
3254         o << indent() << "rtl_uString_release(  pEnumValue" << i << " );\n";
3255     }
3256 
3257     dec();
3258     o << indent() << "}\n";
3259     o << indent() << "osl_releaseMutex( pMutex );\n";
3260     dec();
3261     o << indent() << "}\n\n"
3262       << indent() << "typelib_typedescriptionreference_acquire( s_pType_" << typeName <<" );\n"
3263       << indent() << "return &s_pType_" << typeName <<" );\n";
3264 
3265     dec();
3266     o << "}\n";
3267 
3268     dumpCloseExternC(o);
3269 }
3270 
3271 //*************************************************************************
3272 // TypeDefType
3273 //*************************************************************************
TypeDefType(TypeReader & typeReader,const OString & typeName,const TypeManager & typeMgr,const TypeDependency & typeDependencies)3274 TypeDefType::TypeDefType(TypeReader& typeReader,
3275                          const OString& typeName,
3276                          const TypeManager& typeMgr,
3277                          const TypeDependency& typeDependencies)
3278     : CunoType(typeReader, typeName, typeMgr, typeDependencies)
3279 {
3280 }
3281 
~TypeDefType()3282 TypeDefType::~TypeDefType()
3283 {
3284 
3285 }
3286 
dumpHFile(FileStream & o)3287 sal_Bool TypeDefType::dumpHFile(FileStream& o)
3288     throw( CannotDumpException )
3289 {
3290     OString headerDefine(dumpHeaderDefine(o, "H"));
3291     o << "\n";
3292 
3293     dumpDefaultHIncludes(o);
3294     o << "\n";
3295     dumpDepIncludes(o, m_typeName, "h");
3296     o << "\n";
3297 
3298     dumpOpenExternC(o);
3299 
3300     dumpDeclaration(o);
3301 
3302     if ( m_cunoTypeLib )
3303     {
3304         o << "#ifdef CUNO_TYPELIB\n"
3305           << "typelib_TypeDescriptionReference ** SAL_CALL getCUnoType_" << m_name << "() SAL_THROW_EXTERN_C( () );\n"
3306           << "#endif\n\n";
3307     }
3308 
3309     dumpCloseExternC(o);
3310 
3311     o << "#endif /* "<< headerDefine << " */\n";
3312 
3313     return sal_True;
3314 }
3315 
dumpDeclaration(FileStream & o)3316 sal_Bool TypeDefType::dumpDeclaration(FileStream& o)
3317     throw( CannotDumpException )
3318 {
3319     o << "\ntypedef ";
3320     dumpType(o, m_reader.getSuperTypeName());
3321     o << " " << m_name << ";\n\n";
3322 
3323     return sal_True;
3324 }
3325 
dumpCFile(FileStream & o)3326 sal_Bool TypeDefType::dumpCFile(FileStream& o)
3327     throw( CannotDumpException )
3328 {
3329     dumpInclude(o, m_typeName, "h");
3330     o << "\n";
3331     dumpDefaultCIncludes(o);
3332     o << "\n";
3333     dumpDepIncludes(o, m_typeName, "h");
3334     o << "\n";
3335     dumpGetCunoType(o);
3336     return sal_True;
3337 }
3338 
dumpGetCunoType(FileStream & o)3339 void TypeDefType::dumpGetCunoType(FileStream& o)
3340 {
3341     if ( m_cunoTypeLeak )
3342     {
3343         dumpLGetCunoType(o);
3344         return;
3345     }
3346     if ( !m_cunoTypeDynamic )
3347     {
3348         dumpCGetCunoType(o);
3349         return;
3350     }
3351 }
3352 
dumpCGetCunoType(FileStream & o)3353 void TypeDefType::dumpCGetCunoType(FileStream& o)
3354 {
3355 }
3356 
dumpLGetCunoType(FileStream & o)3357 void TypeDefType::dumpLGetCunoType(FileStream& o)
3358 {
3359 }
3360 
3361 //*************************************************************************
3362 // produceType
3363 //*************************************************************************
produceType(const OString & typeName,TypeManager & typeMgr,TypeDependency & typeDependencies,CunoOptions * pOptions)3364 sal_Bool produceType(const OString& typeName,
3365                      TypeManager& typeMgr,
3366                      TypeDependency& typeDependencies,
3367                      CunoOptions* pOptions)
3368     throw( CannotDumpException )
3369 {
3370     if (typeDependencies.isGenerated(typeName))
3371         return sal_True;
3372 
3373     TypeReader reader(typeMgr.getTypeReader(typeName));
3374 
3375     if (!reader.isValid())
3376     {
3377         if (typeName.equals("/"))
3378             return sal_True;
3379         else
3380             return sal_False;
3381     }
3382 
3383     if( !checkTypeDependencies(typeMgr, typeDependencies, typeName))
3384         return sal_False;
3385 
3386     RTTypeClass typeClass = reader.getTypeClass();
3387     sal_Bool    ret = sal_False;
3388     switch (typeClass)
3389     {
3390         case RT_TYPE_INTERFACE:
3391             {
3392                 InterfaceType iType(reader, typeName, typeMgr, typeDependencies);
3393                 ret = iType.dump(pOptions);
3394                 if (ret) typeDependencies.setGenerated(typeName);
3395                 ret = iType.dumpDependedTypes(pOptions);
3396             }
3397             break;
3398         case RT_TYPE_MODULE:
3399             {
3400                 ModuleType mType(reader, typeName, typeMgr, typeDependencies);
3401                 if (mType.hasConstants())
3402                 {
3403                     ret = mType.dump(pOptions);
3404                     if (ret) typeDependencies.setGenerated(typeName);
3405 //                  ret = mType.dumpDependedTypes(pOptions);
3406                 } else
3407                 {
3408                     typeDependencies.setGenerated(typeName);
3409                     ret = sal_True;
3410                 }
3411             }
3412             break;
3413         case RT_TYPE_STRUCT:
3414             {
3415                 StructureType sType(reader, typeName, typeMgr, typeDependencies);
3416                 ret = sType.dump(pOptions);
3417                 if (ret) typeDependencies.setGenerated(typeName);
3418                 ret = sType.dumpDependedTypes(pOptions);
3419             }
3420             break;
3421         case RT_TYPE_ENUM:
3422             {
3423                 EnumType enType(reader, typeName, typeMgr, typeDependencies);
3424                 ret = enType.dump(pOptions);
3425                 if (ret) typeDependencies.setGenerated(typeName);
3426                 ret = enType.dumpDependedTypes(pOptions);
3427             }
3428             break;
3429         case RT_TYPE_EXCEPTION:
3430             {
3431                 ExceptionType eType(reader, typeName, typeMgr, typeDependencies);
3432                 ret = eType.dump(pOptions);
3433                 if (ret) typeDependencies.setGenerated(typeName);
3434                 ret = eType.dumpDependedTypes(pOptions);
3435             }
3436             break;
3437         case RT_TYPE_TYPEDEF:
3438             {
3439                 TypeDefType tdType(reader, typeName, typeMgr, typeDependencies);
3440                 ret = tdType.dump(pOptions);
3441                 if (ret) typeDependencies.setGenerated(typeName);
3442                 ret = tdType.dumpDependedTypes(pOptions);
3443             }
3444             break;
3445         case RT_TYPE_CONSTANTS:
3446             {
3447                 ConstantsType cType(reader, typeName, typeMgr, typeDependencies);
3448                 if (cType.hasConstants())
3449                 {
3450                     ret = cType.dump(pOptions);
3451                     if (ret) typeDependencies.setGenerated(typeName);
3452 //                  ret = cType.dumpDependedTypes(pOptions);
3453                 } else
3454                 {
3455                     typeDependencies.setGenerated(typeName);
3456                     ret = sal_True;
3457                 }
3458             }
3459             break;
3460         case RT_TYPE_SERVICE:
3461         case RT_TYPE_OBJECT:
3462             ret = sal_True;
3463             break;
3464     }
3465 
3466     return ret;
3467 }
3468 
3469 //*************************************************************************
3470 // scopedName
3471 //*************************************************************************
scopedName(const OString & scope,const OString & type,sal_Bool bNoNameSpace)3472 OString scopedName(const OString& scope, const OString& type,
3473                    sal_Bool bNoNameSpace)
3474 {
3475     sal_Int32 nPos = type.lastIndexOf( '/' );
3476     if (nPos == -1)
3477         return type;
3478 
3479     if (bNoNameSpace)
3480         return type.copy(nPos+1);
3481 
3482     OStringBuffer tmpBuf(type.getLength()*2);
3483     nPos = 0;
3484     do
3485     {
3486         tmpBuf.append("::");
3487         tmpBuf.append(type.getToken(0, '/', nPos));
3488     } while( nPos != -1 );
3489 
3490     return tmpBuf.makeStringAndClear();
3491 }
3492 
3493 //*************************************************************************
3494 // shortScopedName
3495 //*************************************************************************
shortScopedName(const OString & scope,const OString & type,sal_Bool bNoNameSpace)3496 OString shortScopedName(const OString& scope, const OString& type,
3497                         sal_Bool bNoNameSpace)
3498 {
3499     sal_Int32 nPos = type.lastIndexOf( '/' );
3500     if( nPos == -1 )
3501         return OString();
3502 
3503     if (bNoNameSpace)
3504         return OString();
3505 
3506     // scoped name only if the namespace is not equal
3507     if (scope.lastIndexOf('/') > 0)
3508     {
3509         OString tmpScp(scope.copy(0, scope.lastIndexOf('/')));
3510         OString tmpScp2(type.copy(0, nPos));
3511 
3512         if (tmpScp == tmpScp2)
3513             return OString();
3514     }
3515 
3516     OString aScope( type.copy( 0, nPos ) );
3517     OStringBuffer tmpBuf(aScope.getLength()*2);
3518 
3519     nPos = 0;
3520     do
3521     {
3522         tmpBuf.append("::");
3523         tmpBuf.append(aScope.getToken(0, '/', nPos));
3524     } while( nPos != -1 );
3525 
3526     return tmpBuf.makeStringAndClear();
3527 }
3528 
3529 
3530