xref: /AOO41X/main/codemaker/source/cppumaker/cpputype.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 <algorithm>
28 #include <map>
29 #include <set>
30 #include <stdio.h>
31 #include <string.h>
32 #include <vector>
33 
34 #include "registry/reader.hxx"
35 #include "rtl/alloc.h"
36 #include "rtl/ustring.hxx"
37 #include "rtl/strbuf.hxx"
38 
39 #include "codemaker/dependencies.hxx"
40 #include "codemaker/exceptiontree.hxx"
41 #include "codemaker/generatedtypeset.hxx"
42 #include "codemaker/unotype.hxx"
43 
44 #include "cpputype.hxx"
45 #include "cppuoptions.hxx"
46 #include "dumputils.hxx"
47 #include "includes.hxx"
48 
49 using namespace rtl;
50 using namespace codemaker::cpp;
51 
52 namespace {
53 
translateSimpleUnoType(rtl::OString const & unoType,bool cppuUnoType=false)54 rtl::OString translateSimpleUnoType(rtl::OString const & unoType, bool cppuUnoType=false) {
55     static rtl::OString const trans[codemaker::UnoType::SORT_COMPLEX + 1] = {
56         "void", "::sal_Bool", "::sal_Int8", "::sal_Int16", "::sal_uInt16",
57         "::sal_Int32", "::sal_uInt32", "::sal_Int64", "::sal_uInt64", "float",
58         "double", "::sal_Unicode", "::rtl::OUString",
59         "::com::sun::star::uno::Type", "::com::sun::star::uno::Any",
60         rtl::OString() };
61 
62     const codemaker::UnoType::Sort sort = codemaker::UnoType::getSort(unoType);
63     if (cppuUnoType &&
64         (sort == codemaker::UnoType::SORT_UNSIGNED_SHORT ||
65          sort == codemaker::UnoType::SORT_CHAR) )
66     {
67         if (sort == codemaker::UnoType::SORT_CHAR)
68             return "::cppu::UnoCharType";
69         else
70             return "::cppu::UnoUnsignedShortType";
71     }
72 
73     return trans[sort];
74 }
75 
76 }
77 
78 //*************************************************************************
79 // CppuType
80 //*************************************************************************
CppuType(typereg::Reader & typeReader,const OString & typeName,const TypeManager & typeMgr)81 CppuType::CppuType(typereg::Reader& typeReader,
82                    const OString& typeName,
83                    const TypeManager& typeMgr)
84     : m_inheritedMemberCount(0)
85     , m_cppuTypeLeak(sal_False)
86     , m_cppuTypeDynamic(sal_True)
87     , m_indentLength(0)
88     , m_typeName(typeName)
89     , m_name(typeName.copy(typeName.lastIndexOf('/') + 1))
90     , m_reader(typeReader)
91     , m_typeMgr(typeMgr)
92     , m_dependencies(typeMgr, typeName)
93 {}
94 
~CppuType()95 CppuType::~CppuType()
96 {
97 
98 }
99 
addGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes) const100 void CppuType::addGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes)
101     const
102 {
103     if (m_typeName.equals("com/sun/star/uno/XInterface")
104         || m_typeName.equals("com/sun/star/uno/Exception"))
105     {
106         includes.addType();
107         includes.addCppuUnotypeHxx();
108         includes.addSalTypesH();
109         includes.addTypelibTypeclassH();
110         includes.addTypelibTypedescriptionH();
111     } else if (m_cppuTypeLeak) {
112         addLightGetCppuTypeIncludes(includes);
113     } else if (m_cppuTypeDynamic) {
114         addNormalGetCppuTypeIncludes(includes);
115     } else {
116         addComprehensiveGetCppuTypeIncludes(includes);
117     }
118 }
119 
dumpFiles(CppuOptions * options,rtl::OString const & outPath)120 bool CppuType::dumpFiles(CppuOptions * options, rtl::OString const & outPath) {
121     return dumpFile(options, ".hdl", m_typeName, outPath)
122         && dumpFile(options, ".hpp", m_typeName, outPath);
123 }
124 
addLightGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes) const125 void CppuType::addLightGetCppuTypeIncludes(
126     codemaker::cppumaker::Includes & includes) const
127 {
128     //TODO: Determine what is really needed, instead of relying on
129     // addDefaultHxxIncludes
130     includes.addCppuUnotypeHxx();
131 }
132 
addNormalGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes) const133 void CppuType::addNormalGetCppuTypeIncludes(
134     codemaker::cppumaker::Includes & includes) const
135 {
136     //TODO: Determine what is really needed, instead of relying on
137     // addDefaultHxxIncludes
138     includes.addCppuUnotypeHxx();
139 }
140 
addComprehensiveGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes) const141 void CppuType::addComprehensiveGetCppuTypeIncludes(
142     codemaker::cppumaker::Includes & includes) const
143 {
144     //TODO: Determine what is really needed, instead of relying on
145     // addDefaultHxxIncludes
146     includes.addCppuUnotypeHxx();
147 }
148 
isPolymorphic() const149 bool CppuType::isPolymorphic() const { return false; }
150 
dumpTemplateHead(FileStream &) const151 void CppuType::dumpTemplateHead(FileStream &) const {}
152 
dumpTemplateParameters(FileStream &) const153 void CppuType::dumpTemplateParameters(FileStream &) const {}
154 
dumpGetCppuTypePreamble(FileStream & out)155 void CppuType::dumpGetCppuTypePreamble(FileStream & out) {
156     if (isPolymorphic()) {
157         out << "namespace cppu {\n\n";
158         dumpTemplateHead(out);
159         out << "class UnoType< ";
160         dumpType(out, m_typeName);
161         dumpTemplateParameters(out);
162         out << " > {\npublic:\n";
163         inc();
164         out << indent()
165             << "static inline ::com::sun::star::uno::Type const & get() {\n";
166     } else {
167         if (codemaker::cppumaker::dumpNamespaceOpen(out, m_typeName, false)) {
168             out << "\n\n";
169         }
170         out << ("inline ::com::sun::star::uno::Type const &"
171                 " cppu_detail_getUnoType(");
172         dumpType(out, m_typeName, false, false, true);
173         out << " const *) {\n";
174     }
175     inc();
176 }
177 
dumpGetCppuTypePostamble(FileStream & out)178 void CppuType::dumpGetCppuTypePostamble(FileStream & out) {
179     dec();
180     if (isPolymorphic()) {
181         out << indent() << "}\n\nprivate:\n"
182             << indent() << "UnoType(UnoType &); // not defined\n"
183             << indent() << "~UnoType(); // not defined\n"
184             << indent()
185             << "void operator =(UnoType); // not defined\n};\n\n}\n\n";
186     } else {
187         out << "}\n\n";
188         if (codemaker::cppumaker::dumpNamespaceClose(out, m_typeName, false)) {
189             out << "\n\n";
190         }
191     }
192     dumpTemplateHead(out);
193     out << "inline ::com::sun::star::uno::Type const & SAL_CALL getCppuType(";
194     dumpType(out, m_typeName);
195     dumpTemplateParameters(out);
196     out << " const *) SAL_THROW(()) {\n";
197     inc();
198     out << indent() << "return ::cppu::UnoType< ";
199     dumpType(out, m_typeName);
200     dumpTemplateParameters(out);
201     out << " >::get();\n";
202     dec();
203     out << indent() << "}\n";
204 }
205 
dump(CppuOptions * pOptions)206 sal_Bool CppuType::dump(CppuOptions* pOptions)
207     throw( CannotDumpException )
208 {
209     if (!m_dependencies.isValid()) {
210         return false;
211     }
212     addSpecialDependencies();
213 
214     // -CS was used as an undocumented option to generate static getCppuType
215     // functions; since the introduction of cppu::UnoType this no longer is
216     // meaningful (getCppuType is just a forward to cppu::UnoType::get now), and
217     // -CS is handled the same way as -C now:
218     if (pOptions->isValid("-L"))
219         m_cppuTypeLeak = sal_True;
220     if (pOptions->isValid("-C") || pOptions->isValid("-CS"))
221         m_cppuTypeDynamic = sal_False;
222 
223     OString outPath;
224     if (pOptions->isValid("-O"))
225         outPath = pOptions->getOption("-O");
226 
227     return dumpFiles(pOptions, outPath);
228 }
229 
dumpFile(CppuOptions * pOptions,const OString & sExtension,const OString & sName,const OString & sOutPath)230 sal_Bool CppuType::dumpFile(CppuOptions* pOptions,
231                             const OString& sExtension,
232                             const OString& sName,
233                             const OString& sOutPath )
234     throw( CannotDumpException )
235 {
236     sal_Bool ret = sal_False;
237 
238     OString sTmpExt(".tml");
239     sal_Bool bHdl = sal_True;    ;
240     if (sExtension.equals(".hpp")) {
241         sTmpExt = ".tmp";
242         bHdl = sal_False;
243     }
244 
245     OString sFileName = createFileNameFromType(sOutPath, sName, sExtension);
246     if ( sFileName.isEmpty() )
247         return sal_False;
248 
249     sal_Bool bFileExists = fileExists( sFileName );
250     sal_Bool bFileCheck = sal_False;
251 
252     if ( bFileExists && pOptions->isValid("-G") )
253         return sal_True;
254 
255     if ( bFileExists && pOptions->isValid("-Gc") )
256         bFileCheck = sal_True;
257 
258     OString sTmpDir = getTempDir(sFileName);
259     FileStream oFile;
260     oFile.createTempFile(sTmpDir);
261     OString sTmpFileName;
262 
263     if(!oFile.isValid())
264     {
265         OString message("cannot open ");
266         message += sFileName + " for writing";
267         throw CannotDumpException(message);
268     } else
269         sTmpFileName = oFile.getName();
270 
271     codemaker::cppumaker::Includes includes(m_typeMgr, m_dependencies, !bHdl);
272     if (bHdl)
273         ret = dumpHFile(oFile, includes);
274     else {
275         addGetCppuTypeIncludes(includes);
276         ret = dumpHxxFile(oFile, includes);
277     }
278 
279     oFile.close();
280 
281     if (ret) {
282         ret = makeValidTypeFile(sFileName, sTmpFileName, bFileCheck);
283     } else {
284         // remove existing type file if something goes wrong to ensure consistency
285         if (fileExists(sFileName))
286             removeTypeFile(sFileName);
287 
288         // remove tmp file if something goes wrong
289         removeTypeFile(sTmpFileName);
290     }
291 
292     return ret;
293 }
294 
dumpDependedTypes(codemaker::GeneratedTypeSet & generated,CppuOptions * options)295 void CppuType::dumpDependedTypes(
296     codemaker::GeneratedTypeSet & generated, CppuOptions * options)
297 {
298     codemaker::Dependencies::Map const & map(m_dependencies.getMap());
299     for (codemaker::Dependencies::Map::const_iterator i(map.begin());
300          i != map.end(); ++i)
301     {
302         if (!produceType(i->first, m_typeMgr, generated, options)) {
303             fprintf(
304                 stderr, "%s ERROR: cannot dump Type '%s'\n",
305                 options->getProgramName().getStr(), i->first.getStr());
306             exit(99);
307         }
308     }
309 }
310 
dumpHeaderDefine(FileStream & o,char const * prefix,sal_Bool bExtended)311 OString CppuType::dumpHeaderDefine(
312     FileStream& o, char const * prefix, sal_Bool bExtended)
313 {
314     if (m_typeName.equals("/"))
315     {
316         bExtended = sal_False;
317         m_typeName = "global";
318     }
319 
320     sal_uInt32 length = 3 + m_typeName.getLength() + strlen(prefix);
321 
322     if (bExtended)
323         length += m_name.getLength() + 1;
324 
325     OStringBuffer tmpBuf(length);
326 
327     tmpBuf.append("INCLUDED_");
328     tmpBuf.append(m_typeName);
329     tmpBuf.append('_');
330     if (bExtended)
331     {
332         tmpBuf.append(m_name);
333         tmpBuf.append('_');
334     }
335     tmpBuf.append(prefix);
336 
337     OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase());
338 
339     o << "#ifndef " << tmp << "\n#define " << tmp << "\n";
340 
341     return tmp;
342 }
343 
addDefaultHIncludes(codemaker::cppumaker::Includes & includes) const344 void CppuType::addDefaultHIncludes(codemaker::cppumaker::Includes & includes)
345     const
346 {
347     //TODO: Only include what is really needed
348     includes.addCppuMacrosHxx();
349     if (m_typeMgr.getTypeClass(m_typeName) == RT_TYPE_INTERFACE) {
350         includes.addReference();
351     }
352 }
353 
addDefaultHxxIncludes(codemaker::cppumaker::Includes & includes) const354 void CppuType::addDefaultHxxIncludes(codemaker::cppumaker::Includes & includes)
355     const
356 {
357     //TODO: Only include what is really needed
358     includes.addOslMutexHxx();
359     includes.addType();
360     if (m_typeMgr.getTypeClass(m_typeName) == RT_TYPE_INTERFACE) {
361         includes.addReference();
362     }
363 }
364 
dumpInitializer(FileStream & out,bool parameterized,rtl::OUString const & type) const365 void CppuType::dumpInitializer(
366     FileStream & out, bool parameterized, rtl::OUString const & type) const
367 {
368     out << "(";
369     if (!parameterized) {
370         for (rtl::OString t(
371                  rtl::OUStringToOString(type, RTL_TEXTENCODING_UTF8));;)
372         {
373             sal_Int32 rank;
374             std::vector< rtl::OString > args;
375             t = codemaker::UnoType::decompose(t, &rank, &args);
376             if (rank == 0) {
377                 switch (codemaker::UnoType::getSort(t)) {
378                 case codemaker::UnoType::SORT_BOOLEAN:
379                     out << "false";
380                     break;
381 
382                 case codemaker::UnoType::SORT_BYTE:
383                 case codemaker::UnoType::SORT_SHORT:
384                 case codemaker::UnoType::SORT_UNSIGNED_SHORT:
385                 case codemaker::UnoType::SORT_LONG:
386                 case codemaker::UnoType::SORT_UNSIGNED_LONG:
387                 case codemaker::UnoType::SORT_HYPER:
388                 case codemaker::UnoType::SORT_UNSIGNED_HYPER:
389                 case codemaker::UnoType::SORT_FLOAT:
390                 case codemaker::UnoType::SORT_DOUBLE:
391                 case codemaker::UnoType::SORT_CHAR:
392                     out << "0";
393                     break;
394 
395                 case codemaker::UnoType::SORT_COMPLEX:
396                     switch (m_typeMgr.getTypeClass(t)) {
397                     case RT_TYPE_ENUM:
398                         {
399                             typereg::Reader reader(m_typeMgr.getTypeReader(t));
400                             OSL_ASSERT(reader.isValid());
401                             out << scopedCppName(t) << "_"
402                                 << rtl::OUStringToOString(
403                                     reader.getFieldName(0),
404                                     RTL_TEXTENCODING_UTF8);
405                             break;
406                         }
407 
408                     case RT_TYPE_TYPEDEF:
409                         t = resolveTypedefs(t);
410                         continue;
411 
412                     default:
413                         break;
414                     }
415                     break;
416 
417                 default:
418                     break;
419                 }
420             }
421             break;
422         }
423     }
424     out << ")";
425 }
426 
dumpGetCppuType(FileStream & out)427 void CppuType::dumpGetCppuType(FileStream & out) {
428     if (m_typeName.equals("com/sun/star/uno/XInterface")) {
429         out << indent()
430             << ("inline ::com::sun::star::uno::Type const & SAL_CALL"
431                 " getCppuType(");
432         dumpType(out, m_typeName, true, false);
433         out << " *) SAL_THROW(()) {\n";
434         inc();
435         out << indent()
436             << ("return ::cppu::UnoType< ::com::sun::star::uno::XInterface"
437                 " >::get();\n");
438         dec();
439         out << indent() << "}\n";
440     } else if (m_typeName.equals("com/sun/star/uno/Exception")) {
441         out << indent()
442             << ("inline ::com::sun::star::uno::Type const & SAL_CALL"
443                 " getCppuType(");
444         dumpType(out, m_typeName, true, false);
445         out << " *) SAL_THROW(()) {\n";
446         inc();
447         out << indent()
448             << ("return ::cppu::UnoType< ::com::sun::star::uno::Exception"
449                 " >::get();\n");
450         dec();
451         out << indent() << "}\n";
452     } else if (m_cppuTypeLeak) {
453         dumpLightGetCppuType(out);
454     } else if (m_cppuTypeDynamic) {
455         dumpNormalGetCppuType(out);
456     } else {
457         dumpComprehensiveGetCppuType(out);
458     }
459 }
460 
dumpLightGetCppuType(FileStream & o)461 void CppuType::dumpLightGetCppuType(FileStream& o)
462 {
463     dumpGetCppuTypePreamble(o);
464     o << indent()
465       << "static typelib_TypeDescriptionReference * the_type = 0;\n";
466 
467     o << indent() << "if ( !the_type )\n" << indent() << "{\n";
468     inc();
469     o << indent() << "typelib_static_type_init( &the_type, "
470       << getTypeClass(m_typeName, sal_True) << ", \"" << m_typeName.replace('/', '.') << "\" );\n";
471     dec();
472     o << indent() << "}\n";
473     o << indent()
474       << ("return * reinterpret_cast< ::com::sun::star::uno::Type * >("
475           " &the_type );\n");
476     dumpGetCppuTypePostamble(o);
477 }
478 
dumpNormalGetCppuType(FileStream & o)479 void CppuType::dumpNormalGetCppuType(FileStream& o)
480 {
481     dumpGetCppuTypePreamble(o);
482 
483     o << indent()
484       << "static typelib_TypeDescriptionReference * the_type = 0;\n";
485 
486     o << indent() << "if ( !the_type )\n" << indent() << "{\n";
487     inc();
488 
489     OString superType;
490     if (m_reader.getSuperTypeCount() >= 1) {
491         superType = rtl::OUStringToOString(
492             m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8);
493     }
494     sal_Bool bIsBaseException = sal_False;
495     if ( !superType.isEmpty() )
496     {
497         if ( superType.equals("com/sun/star/uno/Exception") )
498         {
499             bIsBaseException = sal_True;
500         } else
501         {
502             o << indent() << "const ::com::sun::star::uno::Type& rBaseType = ::cppu::UnoType< ";
503             dumpType(o, superType, true, false, false, true);
504             o << " >::get();\n\n";
505         }
506     }
507 
508     sal_uInt32 count = getMemberCount();
509     if (count)
510     {
511         o << indent() << "typelib_TypeDescriptionReference * aMemberRefs[" << count << "];\n";
512 
513         sal_uInt16      fieldCount = m_reader.getFieldCount();
514         RTFieldAccess   access = RT_ACCESS_INVALID;
515         OString         fieldType, fieldName;
516         OString         scope = m_typeName.replace('/', '.');
517         OString         modFieldType;
518         StringSet       generatedTypeSet;
519         StringSet::iterator findIter;
520 
521         for (sal_uInt16 i=0; i < fieldCount; i++)
522         {
523             access = m_reader.getFieldFlags(i);
524 
525             if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
526                 continue;
527 
528             fieldName = rtl::OUStringToOString(
529                 m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
530             fieldType = checkRealBaseType(
531                 rtl::OUStringToOString(
532                     m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8),
533                 sal_True);
534 
535             modFieldType = typeToIdentifier(fieldType);
536 
537             findIter = generatedTypeSet.find(fieldType);
538             if ( findIter == generatedTypeSet.end() )
539             {
540                 generatedTypeSet.insert(fieldType);
541                  o << indent() << "const ::com::sun::star::uno::Type& rMemberType_"
542                   << modFieldType/*i*/ << " = ::cppu::UnoType< ";
543                 dumpType(o, fieldType, false, false, false, true);
544                 o << " >::get();\n";
545             }
546 
547             o << indent() << "aMemberRefs[" << i << "] = rMemberType_"
548               << modFieldType/*i*/ << ".getTypeLibType();\n";
549         }
550         o << "\n";
551     }
552 
553     o << indent() << "typelib_static_compound_type_init( &the_type, "
554       << getTypeClass(m_typeName, sal_True) << ", \"" << m_typeName.replace('/', '.') << "\", ";
555     if ( !superType.isEmpty() || bIsBaseException )
556     {
557         if ( bIsBaseException )
558         {
559             o << "* ::typelib_static_type_getByTypeClass( typelib_TypeClass_EXCEPTION ), "
560               << count << ", ";
561         } else
562         {
563             o << "rBaseType.getTypeLibType(), " << count << ", ";
564         }
565     } else
566     {
567         o << "0, " << count << ", ";
568     }
569 
570     if (count)
571     {
572         o << " aMemberRefs );\n";
573     } else
574     {
575         o << " 0 );\n";
576     }
577     dec();
578     o << indent() << "}\n";
579     o << indent()
580       << ("return * reinterpret_cast< const ::com::sun::star::uno::Type * >("
581           " &the_type );\n");
582 
583     dumpGetCppuTypePostamble(o);
584 }
585 
dumpComprehensiveGetCppuType(FileStream & o)586 void CppuType::dumpComprehensiveGetCppuType(FileStream& o)
587 {
588     dumpGetCppuTypePreamble(o);
589 
590     o << indent() << "static ::com::sun::star::uno::Type * the_pType = 0;\n";
591 
592     o << indent() << "if (the_pType == 0)\n" << indent() << "{\n";
593     inc();
594     o << indent() << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n";
595 
596     o << indent() << "if (the_pType == 0)\n" << indent() << "{\n";
597     inc();
598     o << indent() << "::rtl::OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM(\""
599       << m_typeName.replace('/', '.') << "\") );\n\n";
600 
601     o << indent() << "// Start inline typedescription generation\n"
602       << indent() << "typelib_TypeDescription * pTD = 0;\n";
603 
604     OString superType;
605     if (m_reader.getSuperTypeCount() >= 1) {
606         superType = rtl::OUStringToOString(
607             m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8);
608     }
609     if ( !superType.isEmpty() ) {
610         o << indent()
611           << "const ::com::sun::star::uno::Type& rSuperType = ::cppu::UnoType< ";
612         dumpType(o, superType, false, false, false, true);
613         o << " >::get();\n";
614     }
615 
616     dumpCppuGetTypeMemberDecl(o, CPPUTYPEDECL_ALLTYPES);
617 
618     sal_uInt32 count = getMemberCount();
619     if (count)
620     {
621         o << "\n" << indent() << "typelib_CompoundMember_Init aMembers["
622           << count << "];\n";
623 
624         sal_uInt16      fieldCount = m_reader.getFieldCount();
625         RTFieldAccess   access = RT_ACCESS_INVALID;
626         OString         fieldType, fieldName;
627         OString         scope = m_typeName.replace('/', '.');
628         for (sal_uInt16 i=0; i < fieldCount; i++)
629         {
630             access = m_reader.getFieldFlags(i);
631 
632             if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) {
633                 continue;
634             }
635 
636             fieldName = rtl::OUStringToOString(
637                 m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
638             fieldType = checkRealBaseType(
639                 rtl::OUStringToOString(
640                     m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8),
641                 sal_True);
642 
643             o << indent() << "::rtl::OUString sMemberType" << i
644               << "( RTL_CONSTASCII_USTRINGPARAM(\""
645               << fieldType.replace('/', '.') << "\") );\n";
646             o << indent() << "::rtl::OUString sMemberName" << i
647               << "( RTL_CONSTASCII_USTRINGPARAM(\"";
648             o << fieldName << "\") );\n";
649             o << indent() << "aMembers[" << i << "].eTypeClass = "
650               << "(typelib_TypeClass)" << getTypeClass(fieldType) << ";\n"
651               << indent() << "aMembers[" << i << "].pTypeName = sMemberType"
652               << i << ".pData;\n"
653               << indent() << "aMembers[" << i << "].pMemberName = sMemberName"
654               << i << ".pData;\n";
655         }
656     }
657 
658     o << "\n" << indent() << "typelib_typedescription_new(\n";
659     inc();
660     o << indent() << "&pTD,\n" << indent() << "(typelib_TypeClass)"
661       << getTypeClass() << ", sTypeName.pData,\n";
662 
663     if ( !superType.isEmpty() ) {
664         o << indent() << "rSuperType.getTypeLibType(),\n";
665     } else {
666         o << indent() << "0,\n";
667     }
668 
669     if ( count ) {
670         o << indent() << count << ",\n" << indent() << "aMembers );\n\n";
671     } else {
672         o << indent() << count << ",\n" << indent() << "0 );\n\n";
673     }
674 
675     dec();
676     o << indent()
677       << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
678           " );\n\n");
679 
680     o << indent() << "typelib_typedescription_release( pTD );\n"
681       << indent() << "// End inline typedescription generation\n\n";
682 
683     o << indent() << "static ::com::sun::star::uno::Type the_staticType( "
684       << getTypeClass(m_typeName) << ", sTypeName );\n";
685     o << indent() << "the_pType = &the_staticType;\n";
686 
687     dec();
688     o << indent() << "}\n";
689     dec();
690     o << indent() << "}\n\n";
691     o << indent() << "return *the_pType;\n";
692     dumpGetCppuTypePostamble(o);
693 }
694 
dumpCppuGetTypeMemberDecl(FileStream & o,CppuTypeDecl eDeclFlag)695 void CppuType::dumpCppuGetTypeMemberDecl(FileStream& o, CppuTypeDecl eDeclFlag)
696 {
697     sal_uInt16      fieldCount = m_reader.getFieldCount();
698     RTFieldAccess   access = RT_ACCESS_INVALID;
699 
700     StringSet aFinishedTypes;
701     for (sal_uInt16 i=0; i < fieldCount; i++)
702     {
703         access = m_reader.getFieldFlags(i);
704 
705         if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID
706             || (access & RT_ACCESS_PARAMETERIZED_TYPE) != 0)
707             continue;
708 
709         rtl::OString typeName(
710             rtl::OUStringToOString(
711                 m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8));
712         if (aFinishedTypes.count(typeName) == 0)
713         {
714             aFinishedTypes.insert(typeName);
715             dumpCppuGetType(o, typeName, sal_True, eDeclFlag);
716         }
717     }
718 }
719 
isGlobal() const720 IdentifierTranslationMode CppuType::isGlobal() const {
721     if ( m_typeName.indexOf('/') < 0 )
722         return ITM_GLOBAL;
723     else
724         return ITM_NONGLOBAL;
725 }
726 
getMemberCount()727 sal_uInt32 CppuType::getMemberCount()
728 {
729     sal_uInt16 count = m_reader.getMethodCount();
730 
731     sal_uInt16 fieldCount = m_reader.getFieldCount();
732     RTFieldAccess access = RT_ACCESS_INVALID;
733     for (sal_uInt16 i=0; i < fieldCount; i++)
734     {
735         access = m_reader.getFieldFlags(i);
736 
737         if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
738             count++;
739     }
740     return count;
741 }
742 
checkInheritedMemberCount(const typereg::Reader * pReader)743 sal_uInt32 CppuType::checkInheritedMemberCount(const typereg::Reader* pReader)
744 {
745     sal_Bool bSelfCheck = sal_True;
746     if (!pReader)
747     {
748         bSelfCheck = sal_False;
749         pReader = &m_reader;
750     }
751 
752     sal_uInt32 count = 0;
753     OString superType;
754     if (pReader->getSuperTypeCount() >= 1) {
755         superType = rtl::OUStringToOString(
756             pReader->getSuperTypeName(0), RTL_TEXTENCODING_UTF8);
757     }
758     if ( !superType.isEmpty() )
759     {
760         typereg::Reader aSuperReader(m_typeMgr.getTypeReader(superType));
761         if ( aSuperReader.isValid() )
762         {
763             count = checkInheritedMemberCount(&aSuperReader);
764         }
765     }
766 
767     if (bSelfCheck)
768     {
769         count += pReader->getMethodCount();
770         sal_uInt16 fieldCount = pReader->getFieldCount();
771         RTFieldAccess access = RT_ACCESS_INVALID;
772         for (sal_uInt16 i=0; i < fieldCount; i++)
773         {
774             access = pReader->getFieldFlags(i);
775 
776             if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
777             {
778                 count++;
779             }
780         }
781     }
782 
783     return count;
784 }
785 
getInheritedMemberCount()786 sal_uInt32 CppuType::getInheritedMemberCount()
787 {
788     if (m_inheritedMemberCount == 0)
789     {
790         m_inheritedMemberCount = checkInheritedMemberCount(0);
791     }
792 
793     return m_inheritedMemberCount;
794 }
795 
getTypeClass(const OString & type,sal_Bool bCStyle)796 OString CppuType::getTypeClass(const OString& type, sal_Bool bCStyle)
797 {
798     OString     typeName = (!type.isEmpty() ? type : m_typeName);
799     RTTypeClass rtTypeClass = RT_TYPE_INVALID;
800 
801     if ( !type.isEmpty() )
802     {
803         typeName = type;
804         rtTypeClass = m_typeMgr.getTypeClass(typeName);
805     } else
806     {
807         typeName = m_typeName;
808         rtTypeClass = m_reader.getTypeClass();
809     }
810 
811     if (codemaker::UnoType::isSequenceType(typeName))
812         return bCStyle ? "typelib_TypeClass_SEQUENCE" : "::com::sun::star::uno::TypeClass_SEQUENCE";
813 
814     switch (rtTypeClass)
815     {
816         case RT_TYPE_INTERFACE:
817             return bCStyle ? "typelib_TypeClass_INTERFACE" : "::com::sun::star::uno::TypeClass_INTERFACE";
818         case RT_TYPE_MODULE:
819             return bCStyle ? "typelib_TypeClass_MODULE" : "::com::sun::star::uno::TypeClass_MODULE";
820         case RT_TYPE_STRUCT:
821             return bCStyle ? "typelib_TypeClass_STRUCT" : "::com::sun::star::uno::TypeClass_STRUCT";
822         case RT_TYPE_ENUM:
823             return bCStyle ? "typelib_TypeClass_ENUM" : "::com::sun::star::uno::TypeClass_ENUM";
824         case RT_TYPE_EXCEPTION:
825             return bCStyle ? "typelib_TypeClass_EXCEPTION" : "::com::sun::star::uno::TypeClass_EXCEPTION";
826         case RT_TYPE_TYPEDEF:
827             {
828                 OString realType = checkRealBaseType( typeName );
829                 return getTypeClass( realType, bCStyle );
830             }
831         case RT_TYPE_SERVICE:
832             return bCStyle ? "typelib_TypeClass_SERVICE" : "::com::sun::star::uno::TypeClass_SERVICE";
833         case RT_TYPE_INVALID:
834             {
835                 if (type.equals("long"))
836                     return bCStyle ? "typelib_TypeClass_LONG" : "::com::sun::star::uno::TypeClass_LONG";
837                 if (type.equals("short"))
838                     return bCStyle ? "typelib_TypeClass_SHORT" : "::com::sun::star::uno::TypeClass_SHORT";
839                 if (type.equals("hyper"))
840                     return bCStyle ? "typelib_TypeClass_HYPER" : "::com::sun::star::uno::TypeClass_HYPER";
841                 if (type.equals("string"))
842                     return bCStyle ? "typelib_TypeClass_STRING" : "::com::sun::star::uno::TypeClass_STRING";
843                 if (type.equals("boolean"))
844                     return bCStyle ? "typelib_TypeClass_BOOLEAN" : "::com::sun::star::uno::TypeClass_BOOLEAN";
845                 if (type.equals("char"))
846                     return bCStyle ? "typelib_TypeClass_CHAR" : "::com::sun::star::uno::TypeClass_CHAR";
847                 if (type.equals("byte"))
848                     return bCStyle ? "typelib_TypeClass_BYTE" : "::com::sun::star::uno::TypeClass_BYTE";
849                 if (type.equals("any"))
850                     return bCStyle ? "typelib_TypeClass_ANY" : "::com::sun::star::uno::TypeClass_ANY";
851                 if (type.equals("type"))
852                     return bCStyle ? "typelib_TypeClass_TYPE" : "::com::sun::star::uno::TypeClass_TYPE";
853                 if (type.equals("float"))
854                     return bCStyle ? "typelib_TypeClass_FLOAT" : "::com::sun::star::uno::TypeClass_FLOAT";
855                 if (type.equals("double"))
856                     return bCStyle ? "typelib_TypeClass_DOUBLE" : "::com::sun::star::uno::TypeClass_DOUBLE";
857                 if (type.equals("void"))
858                     return bCStyle ? "typelib_TypeClass_VOID" : "::com::sun::star::uno::TypeClass_VOID";
859                 if (type.equals("unsigned long"))
860                     return bCStyle ? "typelib_TypeClass_UNSIGNED_LONG" : "::com::sun::star::uno::TypeClass_UNSIGNED_LONG";
861                 if (type.equals("unsigned short"))
862                     return bCStyle ? "typelib_TypeClass_UNSIGNED_SHORT" : "::com::sun::star::uno::TypeClass_UNSIGNED_SHORT";
863                 if (type.equals("unsigned hyper"))
864                     return bCStyle ? "typelib_TypeClass_UNSIGNED_HYPER" : "::com::sun::star::uno::TypeClass_UNSIGNED_HYPER";
865             }
866             break;
867         default:
868             OSL_ASSERT(false);
869             break;
870     }
871 
872     return bCStyle ? "typelib_TypeClass_UNKNOWN" : "::com::sun::star::uno::TypeClass_UNKNOWN";
873 }
874 
dumpType(FileStream & o,const OString & type,bool bConst,bool bRef,bool bNative,bool cppuUnoType) const875 void CppuType::dumpType(FileStream& o, const OString& type,
876                         bool bConst, bool bRef, bool bNative, bool cppuUnoType)
877     const throw( CannotDumpException )
878 {
879     sal_Int32 seqNum;
880     std::vector< rtl::OString > args;
881     rtl::OString relType(
882         codemaker::UnoType::decompose(
883             checkRealBaseType(type, true), &seqNum, &args));
884 
885     RTTypeClass typeClass = m_typeMgr.getTypeClass(relType);
886 
887     if (bConst) o << "const ";
888 
889     {for (sal_Int32 i = 0; i < seqNum; ++i) {
890         if (cppuUnoType)
891             o << "::cppu::UnoSequenceType< ";
892         else
893             o << "::com::sun::star::uno::Sequence< ";
894     }}
895 
896     switch (typeClass)
897     {
898         case RT_TYPE_INTERFACE:
899             if (bNative)
900                 o << scopedCppName(relType);
901             else
902                 o << "::com::sun::star::uno::Reference< "
903                   << scopedCppName(relType) << " >";
904             break;
905         case RT_TYPE_INVALID:
906             {
907                 OString tmp(translateSimpleUnoType(relType, cppuUnoType));
908                 if ( !tmp.isEmpty() )
909                 {
910                     o << tmp;
911                 } else
912                     throw CannotDumpException("Unknown type '" + relType +
913                                               "', incomplete type library.");
914             }
915             break;
916         case RT_TYPE_STRUCT:
917         case RT_TYPE_ENUM:
918         case RT_TYPE_TYPEDEF:
919         case RT_TYPE_EXCEPTION:
920             {
921                 o << scopedCppName(relType);
922                 if (!args.empty()) {
923                     o << "< ";
924                     for (std::vector< rtl::OString >::iterator i(args.begin());
925                          i != args.end(); ++i)
926                     {
927                         if (i != args.begin()) {
928                             o << ", ";
929                         }
930                         dumpType(o, *i);
931                     }
932                     o << " >";
933                 }
934                 break;
935             }
936         default:
937             OSL_ASSERT(false);
938             break;
939     }
940 
941     {for (sal_Int32 i = 0; i < seqNum; ++i) {
942         o << " >";
943     }}
944 
945     if (bRef) o << "&";
946 }
947 
dumpCppuGetType(FileStream & o,const OString & type,sal_Bool bDecl,CppuTypeDecl eDeclFlag)948 void CppuType::dumpCppuGetType(FileStream& o, const OString& type, sal_Bool bDecl, CppuTypeDecl eDeclFlag)
949 {
950     rtl::OString relType(
951         codemaker::UnoType::decompose(checkRealBaseType(type, true)));
952 
953     if (eDeclFlag == CPPUTYPEDECL_ONLYINTERFACES)
954     {
955         if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE)
956         {
957             o << indent() << "::cppu::UnoType< ";
958             dumpType(o, type, false, false, false, true);
959             o << " >::get()";
960 
961             if (bDecl)
962                 o << ";\n";
963         }
964     } else
965     {
966         if (codemaker::UnoType::getSort(type)
967             != codemaker::UnoType::SORT_COMPLEX)
968         {
969             return;
970         } else
971         {
972             if (eDeclFlag == CPPUTYPEDECL_NOINTERFACES &&
973                 m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE)
974                 return;
975 
976 //          if (m_typeMgr.getTypeClass(type) == RT_TYPE_TYPEDEF)
977 //          {
978 //              o << indent() << "get_" << type.replace('/', '_') << "_Type()";
979 //          } else
980 //          {
981                 o << indent() << "::cppu::UnoType< ";
982                 dumpType(o, type, false, false, false, true);
983                 o << " >::get()";
984 //          }
985         }
986         if (bDecl)
987             o << ";\n";
988     }
989 }
990 
typeToIdentifier(const OString & type)991 OString CppuType::typeToIdentifier(const OString& type)
992 {
993     sal_Int32 seqNum;
994     rtl::OString relType(codemaker::UnoType::decompose(type, &seqNum));
995     OString sIdentifier;
996 
997     while( seqNum > 0 )
998     {
999         sIdentifier += OString("seq");
1000 
1001         if ( --seqNum == 0 )
1002         {
1003             sIdentifier += OString("_");
1004         }
1005     }
1006 
1007     sIdentifier += relType.replace(
1008         ((codemaker::UnoType::getSort(relType)
1009           == codemaker::UnoType::SORT_COMPLEX)
1010          ? '/' : ' '),
1011         '_');
1012 
1013     // TODO: find better solution to create an identifier
1014     sIdentifier = sIdentifier.replace('<', '_');
1015     sIdentifier = sIdentifier.replace('>', '_');
1016     sIdentifier = sIdentifier.replace(',', '_');
1017 
1018     return sIdentifier;
1019 }
1020 
passByReference(rtl::OString const & unoType)1021 bool CppuType::passByReference(rtl::OString const & unoType) {
1022     rtl::OString type(resolveTypedefs(unoType));
1023     switch (codemaker::UnoType::getSort(type)) {
1024     default:
1025         return false;
1026 
1027     case codemaker::UnoType::SORT_STRING:
1028     case codemaker::UnoType::SORT_TYPE:
1029     case codemaker::UnoType::SORT_ANY:
1030         return true;
1031 
1032     case codemaker::UnoType::SORT_COMPLEX:
1033         return m_typeMgr.getTypeClass(type) != RT_TYPE_ENUM;
1034     }
1035 }
1036 
resolveTypedefs(const OString & type) const1037 OString CppuType::resolveTypedefs(const OString& type) const
1038 {
1039     OString baseType(type);
1040 
1041     RegistryKey     key;
1042     RTTypeClass     typeClass;
1043     sal_Bool        isTypeDef = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF);
1044     typereg::Reader reader;
1045 
1046     while (isTypeDef)
1047     {
1048         reader = m_typeMgr.getTypeReader(baseType);
1049 
1050         if (reader.isValid())
1051         {
1052             typeClass = reader.getTypeClass();
1053 
1054             if (typeClass == RT_TYPE_TYPEDEF)
1055                 baseType = rtl::OUStringToOString(
1056                     reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8);
1057             else
1058                 isTypeDef = sal_False;
1059         } else
1060         {
1061             break;
1062         }
1063     }
1064 
1065     return baseType;
1066 }
1067 
checkRealBaseType(const OString & type,sal_Bool bResolveTypeOnly) const1068 OString CppuType::checkRealBaseType(const OString& type, sal_Bool bResolveTypeOnly) const
1069 {
1070     sal_Int32 rank;
1071     rtl::OString baseType(codemaker::UnoType::decompose(type, &rank));
1072 
1073     RegistryKey     key;
1074     RTTypeClass     typeClass;
1075     sal_Bool        mustBeChecked = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF);
1076     typereg::Reader reader;
1077 
1078     while (mustBeChecked)
1079     {
1080         reader = m_typeMgr.getTypeReader(baseType);
1081 
1082         if (reader.isValid())
1083         {
1084             typeClass = reader.getTypeClass();
1085 
1086             if (typeClass == RT_TYPE_TYPEDEF)
1087             {
1088                 sal_Int32 n;
1089                 baseType = codemaker::UnoType::decompose(
1090                     rtl::OUStringToOString(
1091                         reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8),
1092                     &n);
1093                 OSL_ASSERT(n <= SAL_MAX_INT32 - rank); //TODO
1094                 rank += n;
1095             } else
1096                 mustBeChecked = sal_False;
1097         } else
1098         {
1099             break;
1100         }
1101     }
1102 
1103     if (bResolveTypeOnly) {
1104         rtl::OStringBuffer buf;
1105         for (sal_Int32 i = 0; i < rank; ++i) {
1106             buf.append(RTL_CONSTASCII_STRINGPARAM("[]"));
1107         }
1108         baseType = buf.makeStringAndClear() + baseType;
1109     }
1110 
1111     return baseType;
1112 }
1113 
dumpConstantValue(FileStream & o,sal_uInt16 index)1114 void CppuType::dumpConstantValue(FileStream& o, sal_uInt16 index)
1115 {
1116     RTConstValue constValue = m_reader.getFieldValue(index);
1117 
1118     switch (constValue.m_type)
1119     {
1120         case RT_TYPE_NONE:
1121             break;
1122         case RT_TYPE_BOOL:
1123             if (constValue.m_value.aBool)
1124                 o << "sal_True";
1125             else
1126                 o << "sal_False";
1127             break;
1128         case RT_TYPE_BYTE:
1129             o << "(sal_Int8)"
1130               << sal::static_int_cast< sal_Int8 >(constValue.m_value.aByte);
1131             break;
1132         case RT_TYPE_INT16:
1133             o << "(sal_Int16)" << constValue.m_value.aShort;
1134             break;
1135         case RT_TYPE_UINT16:
1136             o << "(sal_uInt16)" << constValue.m_value.aUShort;
1137             break;
1138         case RT_TYPE_INT32:
1139             // Avoid C++ compiler warnings about (un)signedness of literal
1140             // -2^31:
1141             if (constValue.m_value.aLong == SAL_MIN_INT32) {
1142                 o << "SAL_MIN_INT32";
1143             } else {
1144                 o << "(sal_Int32)" << constValue.m_value.aLong;
1145             }
1146             break;
1147         case RT_TYPE_UINT32:
1148             o << "(sal_uInt32)"
1149               << OString::valueOf(
1150                   static_cast< sal_Int64 >(constValue.m_value.aULong)).getStr()
1151               << "U";
1152             break;
1153         case RT_TYPE_INT64:
1154             // Avoid C++ compiler warnings about (un)signedness of literal
1155             // -2^63:
1156             if (constValue.m_value.aHyper == SAL_MIN_INT64) {
1157                 o << "SAL_MIN_INT64";
1158             } else {
1159                 ::rtl::OString tmp(OString::valueOf(constValue.m_value.aHyper));
1160                 o << "(sal_Int64) SAL_CONST_INT64(" << tmp.getStr() << ")";
1161             }
1162             break;
1163         case RT_TYPE_UINT64:
1164             {
1165                 o << "SAL_CONST_UINT64(";
1166                 sal_uInt64 n = constValue.m_value.aUHyper;
1167                 if (n == 0) {
1168                     o << "0";
1169                 } else {
1170                     std::vector< char > buf;
1171                     for (; n != 0; n /= 10) {
1172                         buf.push_back('0' + static_cast< char >(n % 10));
1173                     }
1174                     for (std::vector< char >::reverse_iterator i(buf.rbegin());
1175                          i != buf.rend(); ++i)
1176                     {
1177                         o << rtl::OString::valueOf(*i).getStr();
1178                     }
1179                 }
1180                 o << ")";
1181             }
1182             break;
1183         case RT_TYPE_FLOAT:
1184             {
1185                 ::rtl::OString tmp( OString::valueOf(constValue.m_value.aFloat) );
1186                 o << "(float)" << tmp.getStr();
1187             }
1188             break;
1189         case RT_TYPE_DOUBLE:
1190             {
1191                 ::rtl::OString tmp( OString::valueOf(constValue.m_value.aDouble) );
1192                 o << "(double)" << tmp.getStr();
1193             }
1194             break;
1195         case RT_TYPE_STRING:
1196             {
1197                 ::rtl::OUString aUStr(constValue.m_value.aString);
1198                 ::rtl::OString aStr = ::rtl::OUStringToOString(aUStr, RTL_TEXTENCODING_ASCII_US);
1199                 o << "::rtl::OUString::createFromAscii(\"" << aStr.getStr() << "\")";
1200             }
1201             break;
1202     }
1203 }
1204 
inc(sal_Int32 num)1205 void CppuType::inc(sal_Int32 num)
1206 {
1207     m_indentLength += num;
1208 }
1209 
dec(sal_Int32 num)1210 void CppuType::dec(sal_Int32 num)
1211 {
1212     m_indentLength = std::max< sal_Int32 >(m_indentLength - num, 0);
1213 }
1214 
indent() const1215 OString CppuType::indent() const
1216 {
1217     OStringBuffer tmp(m_indentLength);
1218 
1219     for (sal_Int32 i=0; i < m_indentLength; i++)
1220     {
1221         tmp.append(' ');
1222     }
1223     return tmp.makeStringAndClear();
1224 }
1225 
1226 //*************************************************************************
1227 // InterfaceType
1228 //*************************************************************************
InterfaceType(typereg::Reader & typeReader,const OString & typeName,const TypeManager & typeMgr)1229 InterfaceType::InterfaceType(typereg::Reader& typeReader,
1230                              const OString& typeName,
1231                              const TypeManager& typeMgr)
1232     : CppuType(typeReader, typeName, typeMgr)
1233 {
1234     m_inheritedMemberCount = 0;
1235     m_hasAttributes = sal_False;
1236     m_hasMethods = sal_False;
1237 }
1238 
~InterfaceType()1239 InterfaceType::~InterfaceType()
1240 {
1241 
1242 }
1243 
dumpHFile(FileStream & o,codemaker::cppumaker::Includes & includes)1244 sal_Bool InterfaceType::dumpHFile(
1245     FileStream& o, codemaker::cppumaker::Includes & includes)
1246     throw( CannotDumpException )
1247 {
1248     OString headerDefine(dumpHeaderDefine(o, "HDL"));
1249     o << "\n";
1250 
1251     addDefaultHIncludes(includes);
1252     if (m_reader.getMethodCount() != 0) {
1253         includes.add("com/sun/star/uno/RuntimeException");
1254     }
1255     includes.dump(o, 0);
1256     o << ("\nnamespace com { namespace sun { namespace star { namespace uno {\n"
1257           "class Type;\n} } } }\n\n");
1258 
1259     if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) {
1260         o << "\n";
1261     }
1262     dumpDeclaration(o);
1263     if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) {
1264         o << "\n";
1265     }
1266 
1267     o << "\ninline const ::com::sun::star::uno::Type& SAL_CALL getCppuType( ";
1268     dumpType(o, m_typeName, sal_True, sal_False);
1269     o << "* ) SAL_THROW( () );\n\n";
1270 
1271     o << "#endif // "<< headerDefine << "\n";
1272     return sal_True;
1273 }
1274 
dumpDeclaration(FileStream & o)1275 sal_Bool InterfaceType::dumpDeclaration(FileStream& o)
1276     throw( CannotDumpException )
1277 {
1278 //     rtl::OString cppName(translateUnoToCppIdentifier(
1279 //                              m_name, "interface", ITM_KEYWORDSONLY, &m_name));
1280 
1281 //  o << "\nclass SAL_NO_VTABLE " << cppName;
1282     o << "\nclass SAL_NO_VTABLE " << m_name;
1283 
1284     for (sal_Int16 i = 0; i < m_reader.getSuperTypeCount(); ++i) {
1285         o << (i == 0 ? " :" : ",") << " public "
1286           << scopedCppName(rtl::OUStringToOString(
1287                             m_reader.getSuperTypeName(i), RTL_TEXTENCODING_UTF8));
1288     }
1289 
1290     o << "\n{\npublic:\n";
1291 
1292     inc();
1293 
1294     dumpAttributes(o);
1295     dumpMethods(o);
1296 
1297     o << "\n" << indent()
1298       << ("static inline ::com::sun::star::uno::Type const & SAL_CALL"
1299           " static_type(void * = 0);\n");
1300 
1301     dec();
1302     o << "};\n\n";
1303 
1304     return sal_True;
1305 }
1306 
dumpHxxFile(FileStream & o,codemaker::cppumaker::Includes & includes)1307 sal_Bool InterfaceType::dumpHxxFile(
1308     FileStream& o, codemaker::cppumaker::Includes & includes)
1309     throw( CannotDumpException )
1310 {
1311     OString headerDefine(dumpHeaderDefine(o, "HPP"));
1312     o << "\n";
1313 
1314     addDefaultHxxIncludes(includes);
1315     includes.dump(o, &m_typeName);
1316     o << "\n";
1317 
1318     dumpGetCppuType(o);
1319 
1320 //     rtl::OString cppName(translateUnoToCppIdentifier(
1321 //                              m_name, "interface", ITM_KEYWORDSONLY, &m_name));
1322 
1323     o << "\n::com::sun::star::uno::Type const & "
1324       << scopedCppName(m_typeName)
1325       << "::static_type(void *) {\n";
1326     inc();
1327     o << indent() << "return ::getCppuType(static_cast< ";
1328     dumpType(o, m_typeName);
1329     o << " * >(0));\n";
1330     dec();
1331     o << "}\n";
1332 
1333     o << "\n#endif // "<< headerDefine << "\n";
1334     return sal_True;
1335 }
1336 
dumpAttributes(FileStream & o)1337 void InterfaceType::dumpAttributes(FileStream& o)
1338 {
1339     sal_uInt16 fieldCount = m_reader.getFieldCount();
1340     sal_Bool first=sal_True;
1341 
1342     RTFieldAccess access = RT_ACCESS_INVALID;
1343     OString fieldName;
1344     OString fieldType;
1345     for (sal_uInt16 i=0; i < fieldCount; i++)
1346     {
1347         access = m_reader.getFieldFlags(i);
1348 
1349         if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
1350             continue;
1351 
1352         rtl::OUString name(m_reader.getFieldName(i));
1353         fieldName = rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8);
1354         fieldType = rtl::OUStringToOString(
1355             m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8);
1356 
1357         if (first)
1358         {
1359             first = sal_False;
1360             o << "\n" << indent() << "// Attributes\n";
1361         }
1362 
1363         o << indent() << "virtual ";
1364         dumpType(o, fieldType);
1365         o << " SAL_CALL get" << fieldName << "()";
1366         dumpAttributeExceptionSpecification(o, name, RT_MODE_ATTRIBUTE_GET);
1367         o << " = 0;\n";
1368 
1369         if ((access & RT_ACCESS_READONLY) == 0)
1370         {
1371             bool byRef = passByReference(fieldType);
1372             o << indent() << "virtual void SAL_CALL set" << fieldName << "( ";
1373             dumpType(o, fieldType, byRef, byRef);
1374             o << " _" << fieldName.toAsciiLowerCase() << " )";
1375             dumpAttributeExceptionSpecification(o, name, RT_MODE_ATTRIBUTE_SET);
1376             o << " = 0;\n";
1377         }
1378     }
1379 }
1380 
dumpMethods(FileStream & o)1381 void InterfaceType::dumpMethods(FileStream& o)
1382 {
1383     sal_uInt16 methodCount = m_reader.getMethodCount();
1384     sal_Bool first=sal_True;
1385 
1386     OString methodName, returnType, paramType, paramName;
1387     sal_uInt16 paramCount = 0;
1388     RTMethodMode methodMode = RT_MODE_INVALID;
1389     RTParamMode  paramMode = RT_PARAM_INVALID;
1390 
1391     sal_Bool bRef = sal_False;
1392     sal_Bool bConst = sal_False;
1393     sal_Bool bWithRunTimeExcp = sal_True;
1394 
1395     for (sal_uInt16 i=0; i < methodCount; i++)
1396     {
1397         methodMode = m_reader.getMethodFlags(i);
1398         if (methodMode == RT_MODE_ATTRIBUTE_GET
1399             || methodMode == RT_MODE_ATTRIBUTE_SET)
1400         {
1401             continue;
1402         }
1403 
1404         methodName = rtl::OUStringToOString(
1405             m_reader.getMethodName(i), RTL_TEXTENCODING_UTF8);
1406         returnType = rtl::OUStringToOString(
1407             m_reader.getMethodReturnTypeName(i), RTL_TEXTENCODING_UTF8);
1408         paramCount = m_reader.getMethodParameterCount(i);
1409 
1410         if ( methodName.equals("acquire") || methodName.equals("release") )
1411         {
1412             bWithRunTimeExcp = sal_False;
1413         }
1414 
1415         if (first)
1416         {
1417             first = sal_False;
1418             o << "\n" << indent() << "// Methods\n";
1419         }
1420 
1421         o << indent() << "virtual ";
1422         dumpType(o, returnType);
1423         o << " SAL_CALL " << methodName << "( ";
1424         for (sal_uInt16 j=0; j < paramCount; j++)
1425         {
1426             paramName = rtl::OUStringToOString(
1427                 m_reader.getMethodParameterName(i, j), RTL_TEXTENCODING_UTF8);
1428             paramType = rtl::OUStringToOString(
1429                 m_reader.getMethodParameterTypeName(i, j),
1430                 RTL_TEXTENCODING_UTF8);
1431             paramMode = m_reader.getMethodParameterFlags(i, j);
1432 
1433             switch (paramMode)
1434             {
1435                 case RT_PARAM_IN:
1436                     bConst = passByReference(paramType);
1437                     bRef = bConst;
1438                     break;
1439                 case RT_PARAM_OUT:
1440                 case RT_PARAM_INOUT:
1441                     bConst = sal_False;
1442                     bRef = sal_True;
1443                     break;
1444                 default:
1445                     break;
1446             }
1447 
1448             dumpType(o, paramType, bConst, bRef);
1449 //          o << " " << translateUnoToCppIdentifier(
1450 //                 paramName, "param", ITM_KEYWORDSONLY, NULL);
1451             o << " " << paramName;
1452 
1453             if (j+1 < (sal_uInt16)paramCount) o << ", ";
1454         }
1455         o << " )";
1456         dumpExceptionSpecification(o, i, bWithRunTimeExcp);
1457         o << " = 0;\n";
1458     }
1459 }
1460 
dumpNormalGetCppuType(FileStream & o)1461 void InterfaceType::dumpNormalGetCppuType(FileStream& o)
1462 {
1463     dumpGetCppuTypePreamble(o);
1464 
1465     o << indent()
1466       << "static typelib_TypeDescriptionReference * the_type = 0;\n";
1467 
1468     o << indent() << "if ( !the_type )\n" << indent() << "{\n";
1469     inc();
1470     sal_Int16 nBases = m_reader.getSuperTypeCount();
1471     OSL_ASSERT(nBases > 0);
1472     if (nBases == 1
1473         && m_reader.getSuperTypeName(0).equalsAsciiL(
1474             RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XInterface")))
1475     {
1476         nBases = 0;
1477     }
1478     if (nBases > 0) {
1479         o << indent() << "typelib_TypeDescriptionReference * aSuperTypes["
1480           << nBases << "];\n";
1481         for (sal_Int16 i = 0; i < nBases; ++i) {
1482             o << indent() << "aSuperTypes[" << i << "] = ::cppu::UnoType< ";
1483             dumpType(
1484                 o,
1485                 rtl::OUStringToOString(
1486                     m_reader.getSuperTypeName(i), RTL_TEXTENCODING_UTF8),
1487                 true, false, false, true);
1488             o << " >::get().getTypeLibType();\n";
1489         }
1490     }
1491 
1492     o << indent() << "typelib_static_mi_interface_type_init( &the_type, \""
1493       << m_typeName.replace('/', '.') << "\", " << nBases << ", ";
1494 
1495     if ( nBases > 0 )
1496     {
1497         o << "aSuperTypes );\n";
1498     } else
1499     {
1500         o << "0 );\n";
1501     }
1502 
1503     dec();
1504     o << indent() << "}\n";
1505     o << indent()
1506       << ("return * reinterpret_cast< ::com::sun::star::uno::Type * >("
1507           " &the_type );\n");
1508 
1509     dumpGetCppuTypePostamble(o);
1510 }
1511 
dumpComprehensiveGetCppuType(FileStream & o)1512 void InterfaceType::dumpComprehensiveGetCppuType(FileStream& o)
1513 {
1514     dumpGetCppuTypePreamble(o);
1515 
1516     o << indent() << "static ::com::sun::star::uno::Type * the_pType = 0;\n";
1517 
1518     o << indent() << "if (the_pType == 0)\n" << indent() << "{\n";
1519     inc();
1520     o << indent() << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n";
1521 
1522     o << indent() << "if (the_pType == 0)\n" << indent() << "{\n";
1523     inc();
1524     o << indent() << "::rtl::OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM(\""
1525       << m_typeName.replace('/', '.') << "\") );\n\n";
1526 
1527     o << indent() << "// Start inline typedescription generation\n"
1528       << indent() << "typelib_InterfaceTypeDescription * pTD = 0;\n\n";
1529 
1530     OSL_ASSERT(m_reader.getSuperTypeCount() > 0);
1531     o << indent() << "typelib_TypeDescriptionReference * aSuperTypes["
1532       << m_reader.getSuperTypeCount() << "];\n";
1533     for (sal_Int16 i = 0; i < m_reader.getSuperTypeCount(); ++i) {
1534         o << indent() << "aSuperTypes[" << i << "] = ::cppu::UnoType< ";
1535         dumpType(
1536             o,
1537             rtl::OUStringToOString(
1538                 m_reader.getSuperTypeName(i), RTL_TEXTENCODING_UTF8),
1539             false, false, false, true);
1540         o << " >::get().getTypeLibType();\n";
1541     }
1542 
1543     sal_uInt32 count = getMemberCount();
1544     if (count)
1545     {
1546         o << indent() << "typelib_TypeDescriptionReference * pMembers[" << count
1547           << "] = { ";
1548         for (sal_uInt32 i = 0; i < count; i++)
1549         {
1550             o << "0";
1551             if (i+1 < count) {
1552                 o << ",";
1553             } else {
1554                 o << " };\n";
1555             }
1556         }
1557 
1558         sal_uInt32 index = 0;
1559         dumpCppuAttributeRefs(o, index);
1560         dumpCppuMethodRefs(o, index);
1561     }
1562 
1563     o << "\n" << indent() << "typelib_typedescription_newMIInterface(\n";
1564     inc();
1565     o << indent() << "&pTD,\n" << indent() << "sTypeName.pData, ";
1566 
1567     o << "0x00000000, 0x0000, 0x0000, 0x00000000, 0x00000000,\n"; // UIK
1568 
1569     o << indent() << m_reader.getSuperTypeCount() << ", aSuperTypes,\n";
1570 
1571     if ( count ) {
1572         o << indent() << count << ",\n" << indent() << "pMembers );\n\n";
1573     } else {
1574         o << indent() << count << ",\n" << indent() << "0 );\n\n";
1575     }
1576     dec();
1577 
1578     o << indent()
1579       << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
1580           " );\n");
1581     if ( count )
1582     {
1583         for (sal_uInt16 i=0; i < count; i++)
1584         {
1585             o << indent()
1586               << "typelib_typedescriptionreference_release( pMembers[" << i
1587               << "] );\n";
1588         }
1589     }
1590     o << indent()
1591       << ("typelib_typedescription_release( (typelib_TypeDescription*)pTD"
1592           " );\n\n");
1593 
1594     o << indent() << "static ::com::sun::star::uno::Type the_staticType( "
1595       << getTypeClass(m_typeName) << ", sTypeName );\n";
1596     o << indent() << "the_pType = &the_staticType;\n";
1597 
1598     StringSet   aTypes;
1599     // type for RuntimeException is always needed
1600     OString     sRunTimeExceptionType("com/sun/star/uno/RuntimeException");
1601     aTypes.insert(sRunTimeExceptionType);
1602     dumpCppuGetType(o, sRunTimeExceptionType, sal_True, CPPUTYPEDECL_ALLTYPES);
1603 
1604     dumpAttributesCppuDecl(o, &aTypes, CPPUTYPEDECL_ALLTYPES);
1605     dumpMethodsCppuDecl(o, &aTypes, CPPUTYPEDECL_ALLTYPES);
1606 
1607     if (count)
1608     {
1609         sal_uInt32 index = getInheritedMemberCount();
1610         dumpCppuAttributes(o, index);
1611         dumpCppuMethods(o, index);
1612     }
1613 
1614     o << indent() << "// End inline typedescription generation\n";
1615 
1616     dec();
1617     o << indent() << "}\n";
1618     dec();
1619     o << indent() << "}\n\n"
1620       << indent() << "return *the_pType;\n";
1621 
1622     dumpGetCppuTypePostamble(o);
1623 }
1624 
dumpCppuAttributeRefs(FileStream & o,sal_uInt32 & index)1625 void InterfaceType::dumpCppuAttributeRefs(FileStream& o, sal_uInt32& index)
1626 {
1627     sal_uInt16 fieldCount = m_reader.getFieldCount();
1628 
1629     RTFieldAccess access = RT_ACCESS_INVALID;
1630     OString fieldName;
1631     OString scope = m_typeName.replace('/', '.');
1632 
1633     for (sal_uInt16 i=0; i < fieldCount; i++)
1634     {
1635         access = m_reader.getFieldFlags(i);
1636 
1637         if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
1638             continue;
1639 
1640         fieldName = rtl::OUStringToOString(
1641             m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
1642 
1643         o << indent() << "::rtl::OUString sAttributeName" << i << "( RTL_CONSTASCII_USTRINGPARAM(\""
1644           << scope.replace('/', '.') << "::" << fieldName << "\") );\n";
1645         o << indent() << "typelib_typedescriptionreference_new( &pMembers["
1646           << index << "],\n";
1647         inc(38);
1648         o << indent() << "(typelib_TypeClass)::com::sun::star::uno::TypeClass_INTERFACE_ATTRIBUTE,\n"
1649           << indent() << "sAttributeName" << i << ".pData );\n";
1650         dec(38);
1651         index++;
1652     }
1653 }
1654 
dumpCppuMethodRefs(FileStream & o,sal_uInt32 & index)1655 void InterfaceType::dumpCppuMethodRefs(FileStream& o, sal_uInt32& index)
1656 {
1657     sal_uInt16  methodCount = m_reader.getMethodCount();
1658     OString     methodName;
1659     OString     scope = m_typeName.replace('/', '.');
1660 
1661     for (sal_uInt16 i = 0; i < methodCount; i++)
1662     {
1663         RTMethodMode flags = m_reader.getMethodFlags(i);
1664         if (flags == RT_MODE_ATTRIBUTE_GET || flags == RT_MODE_ATTRIBUTE_SET) {
1665             continue;
1666         }
1667 
1668         methodName = rtl::OUStringToOString(
1669             m_reader.getMethodName(i), RTL_TEXTENCODING_UTF8);
1670 
1671         o << indent() << "::rtl::OUString sMethodName" << i << "( RTL_CONSTASCII_USTRINGPARAM(\""
1672           << scope.replace('/', '.') << "::" << methodName << "\") );\n";
1673         o << indent() << "typelib_typedescriptionreference_new( &pMembers["
1674           << index << "],\n";
1675         inc(38);
1676         o << indent() << "(typelib_TypeClass)::com::sun::star::uno::TypeClass_INTERFACE_METHOD,\n"
1677           << indent() << "sMethodName" << i << ".pData );\n";
1678         dec(38);
1679         index++;
1680     }
1681 }
1682 
getMemberCount()1683 sal_uInt32 InterfaceType::getMemberCount() {
1684     sal_uInt16 count = 0;
1685     sal_uInt16 methodCount = m_reader.getMethodCount();
1686     {for (sal_uInt16 i = 0; i < methodCount; ++i) {
1687         RTMethodMode flags = m_reader.getMethodFlags(i);
1688         if (flags != RT_MODE_ATTRIBUTE_GET && flags != RT_MODE_ATTRIBUTE_SET) {
1689             m_hasMethods = true;
1690             ++count;
1691         }
1692     }}
1693     sal_uInt16 fieldCount = m_reader.getFieldCount();
1694     {for (sal_uInt16 i = 0; i < fieldCount; ++i) {
1695         RTFieldAccess flags = m_reader.getFieldFlags(i);
1696         if (flags != RT_ACCESS_CONST && flags != RT_ACCESS_INVALID) {
1697             m_hasAttributes = true;
1698             ++count;
1699         }
1700     }}
1701     return count;
1702 }
1703 
1704 namespace {
1705 
1706 class BaseOffset {
1707 public:
1708     BaseOffset(TypeManager const & theManager, typereg::Reader const & reader);
1709 
get() const1710     sal_Int32 get() const { return offset; }
1711 
1712 private:
1713     void calculateBases(typereg::Reader const & reader);
1714 
1715     void calculate(typereg::Reader const & reader);
1716 
1717     TypeManager const & manager;
1718     std::set< rtl::OString > set;
1719     sal_Int32 offset;
1720 };
1721 
BaseOffset(TypeManager const & theManager,typereg::Reader const & reader)1722 BaseOffset::BaseOffset(
1723     TypeManager const & theManager, typereg::Reader const & reader):
1724     manager(theManager)
1725 {
1726     offset = 0;
1727     calculateBases(reader);
1728 }
1729 
calculateBases(typereg::Reader const & reader)1730 void BaseOffset::calculateBases(typereg::Reader const & reader) {
1731     for (sal_Int16 i = 0; i < reader.getSuperTypeCount(); ++i) {
1732         typereg::Reader super(
1733             manager.getTypeReader(
1734                 rtl::OUStringToOString(
1735                     reader.getSuperTypeName(i), RTL_TEXTENCODING_UTF8)));
1736         if (super.isValid()) {
1737             calculate(super);
1738         }
1739     }
1740 }
1741 
calculate(typereg::Reader const & reader)1742 void BaseOffset::calculate(typereg::Reader const & reader) {
1743     if (set.insert(
1744             rtl::OUStringToOString(reader.getTypeName(), RTL_TEXTENCODING_UTF8))
1745         .second)
1746     {
1747         calculateBases(reader);
1748         {for (sal_uInt16 i = 0; i < reader.getMethodCount(); ++i) {
1749             RTMethodMode flags = reader.getMethodFlags(i);
1750             if (flags != RT_MODE_ATTRIBUTE_GET
1751                 && flags != RT_MODE_ATTRIBUTE_SET)
1752             {
1753                 ++offset;
1754             }
1755         }}
1756         {for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) {
1757             RTFieldAccess flags = reader.getFieldFlags(i);
1758             if (flags != RT_ACCESS_CONST && flags != RT_ACCESS_INVALID) {
1759                 ++offset;
1760             }
1761         }}
1762     }
1763 }
1764 
1765 }
1766 
addSpecialDependencies()1767 void InterfaceType::addSpecialDependencies() {
1768     if (m_reader.getMethodCount() > 0 || m_reader.getFieldCount() > 0) {
1769         m_dependencies.add("com/sun/star/uno/RuntimeException");
1770     }
1771 }
1772 
addComprehensiveGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes) const1773 void InterfaceType::addComprehensiveGetCppuTypeIncludes(
1774     codemaker::cppumaker::Includes & includes) const
1775 {
1776     // The comprehensive getCppuType method always includes a line
1777     // "getCppuType( (const ::com::sun::star::uno::RuntimeException*)0 );":
1778     includes.addCppuUnotypeHxx();
1779     includes.add("com/sun/star/uno/RuntimeException");
1780 }
1781 
checkInheritedMemberCount(const typereg::Reader *)1782 sal_uInt32 InterfaceType::checkInheritedMemberCount(const typereg::Reader*)
1783 {
1784     return BaseOffset(m_typeMgr, m_reader).get();
1785 }
1786 
getInheritedMemberCount()1787 sal_uInt32 InterfaceType::getInheritedMemberCount()
1788 {
1789     if (m_inheritedMemberCount == 0)
1790     {
1791         m_inheritedMemberCount = checkInheritedMemberCount(0);
1792     }
1793 
1794     return m_inheritedMemberCount;
1795 }
1796 
dumpCppuAttributes(FileStream & o,sal_uInt32 & index)1797 void InterfaceType::dumpCppuAttributes(FileStream& o, sal_uInt32& index)
1798 {
1799     sal_uInt16 fieldCount = m_reader.getFieldCount();
1800 
1801     RTFieldAccess access = RT_ACCESS_INVALID;
1802     OString fieldName;
1803     OString fieldType;
1804     OString scope = m_typeName.replace('/', '.');
1805 
1806     sal_uInt32 absoluteIndex = index;
1807 
1808     if (m_hasAttributes)
1809     {
1810         o << "\n" << indent() << "typelib_InterfaceAttributeTypeDescription * pAttribute = 0;\n";
1811 
1812         for (sal_uInt16 i=0; i < fieldCount; i++)
1813         {
1814             access = m_reader.getFieldFlags(i);
1815 
1816             if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
1817                 continue;
1818 
1819             rtl::OUString name(m_reader.getFieldName(i));
1820             fieldName = rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8);
1821             fieldType = checkRealBaseType(
1822                 rtl::OUStringToOString(
1823                     m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8),
1824                 sal_True);
1825 
1826             o << indent() << "{\n";
1827             inc();
1828             o << indent() << "::rtl::OUString sAttributeType" << i << "( RTL_CONSTASCII_USTRINGPARAM(\""
1829               << fieldType.replace('/', '.') << "\") );\n";
1830             sal_Int32 getExceptions = dumpAttributeExceptionTypeNames(
1831                 o, "get", name, RT_MODE_ATTRIBUTE_GET);
1832             sal_Int32 setExceptions = dumpAttributeExceptionTypeNames(
1833                 o, "set", name, RT_MODE_ATTRIBUTE_SET);
1834             o << indent()
1835               << ("typelib_typedescription_newExtendedInterfaceAttribute("
1836                   " &pAttribute,\n");
1837             inc();
1838             o << indent() << absoluteIndex++ << ", sAttributeName" << i << ".pData,\n";
1839             o << indent() << "(typelib_TypeClass)" << getTypeClass(fieldType)
1840               << ", sAttributeType" << i << ".pData,\n";
1841             o << indent() << "sal_"
1842               << ((access & RT_ACCESS_READONLY) == 0 ? "False" : "True") << ", "
1843               << getExceptions << ", "
1844               << (getExceptions == 0 ? "0" : "the_getExceptions") << ", "
1845               << setExceptions << ", "
1846               << (setExceptions == 0 ? "0" : "the_setExceptions") << " );\n";
1847             dec();
1848             o << indent() << "typelib_typedescription_register( (typelib_TypeDescription**)&pAttribute );\n";
1849             dec();
1850             o << indent() << "}\n";
1851         }
1852         o << indent() << "typelib_typedescription_release( (typelib_TypeDescription*)pAttribute );\n";
1853 
1854         index = absoluteIndex;
1855     }
1856 }
1857 
dumpCppuMethods(FileStream & o,sal_uInt32 & index)1858 void InterfaceType::dumpCppuMethods(FileStream& o, sal_uInt32& index)
1859 {
1860     sal_uInt16      methodCount = m_reader.getMethodCount();
1861     OString         methodName, returnType, paramType, paramName;
1862     sal_uInt16      paramCount = 0;
1863     RTMethodMode    methodMode = RT_MODE_INVALID;
1864     RTParamMode     paramMode = RT_PARAM_INVALID;
1865     sal_Bool        bWithRuntimeException = sal_True;
1866 
1867     sal_uInt32 absoluteIndex = index;
1868 
1869     if (m_hasMethods)
1870     {
1871         o << "\n" << indent() << "typelib_InterfaceMethodTypeDescription * pMethod = 0;\n";
1872 
1873         for (sal_uInt16 i=0; i < methodCount; i++)
1874         {
1875             methodMode = m_reader.getMethodFlags(i);
1876             if (methodMode == RT_MODE_ATTRIBUTE_GET
1877                 || methodMode == RT_MODE_ATTRIBUTE_SET)
1878             {
1879                 continue;
1880             }
1881 
1882             methodName = rtl::OUStringToOString(
1883                 m_reader.getMethodName(i), RTL_TEXTENCODING_UTF8);
1884             returnType = checkRealBaseType(
1885                 rtl::OUStringToOString(
1886                     m_reader.getMethodReturnTypeName(i), RTL_TEXTENCODING_UTF8),
1887                 sal_True);
1888             paramCount = m_reader.getMethodParameterCount(i);
1889 
1890             if ( methodName.equals("acquire") || methodName.equals("release") )
1891             {
1892                 bWithRuntimeException = sal_False;
1893             }
1894 
1895             o << indent() << "{\n";
1896             inc();
1897 
1898             if (paramCount)
1899             {
1900                 o << indent() << "typelib_Parameter_Init aParameters[" << paramCount << "];\n";
1901             }
1902 
1903             sal_uInt16 j;
1904             for (j=0; j < paramCount; j++)
1905             {
1906                 paramName = rtl::OUStringToOString(
1907                     m_reader.getMethodParameterName(i, j),
1908                     RTL_TEXTENCODING_UTF8);
1909                 paramType = checkRealBaseType(
1910                     rtl::OUStringToOString(
1911                         m_reader.getMethodParameterTypeName(i, j),
1912                         RTL_TEXTENCODING_UTF8),
1913                     sal_True);
1914                 paramMode = m_reader.getMethodParameterFlags(i, j);
1915 
1916                 o << indent() << "::rtl::OUString sParamName" << j << "( RTL_CONSTASCII_USTRINGPARAM(\""
1917                   << paramName << "\") );\n";
1918                 o << indent() << "::rtl::OUString sParamType" << j << "( RTL_CONSTASCII_USTRINGPARAM(\""
1919                   << paramType.replace('/', '.') << "\") );\n";
1920                 o << indent() << "aParameters[" << j << "].pParamName = sParamName" << j << ".pData;\n";
1921                 o << indent() << "aParameters[" << j << "].eTypeClass = (typelib_TypeClass)"
1922                   << getTypeClass(paramType) << ";\n";
1923                 o << indent() << "aParameters[" << j << "].pTypeName = sParamType" << j << ".pData;\n";
1924 
1925                 if (paramMode == RT_PARAM_IN || paramMode == RT_PARAM_INOUT)
1926                     o << indent() << "aParameters[" << j << "].bIn = sal_True;\n";
1927                 else
1928                     o << indent() << "aParameters[" << j << "].bIn = sal_False;\n";
1929 
1930                 if (paramMode == RT_PARAM_OUT || paramMode == RT_PARAM_INOUT)
1931                     o << indent() << "aParameters[" << j << "].bOut = sal_True;\n";
1932                 else
1933                     o << indent() << "aParameters[" << j << "].bOut = sal_False;\n";
1934             }
1935 
1936             sal_Int32 excCount = dumpExceptionTypeNames(
1937                 o, "", i, bWithRuntimeException);
1938 
1939             o << indent() << "::rtl::OUString sReturnType" << i << "( RTL_CONSTASCII_USTRINGPARAM(\""
1940               << returnType.replace('/', '.') << "\") );\n";
1941             o << indent() << "typelib_typedescription_newInterfaceMethod( &pMethod,\n";
1942             inc();
1943             o << indent() << absoluteIndex++ << ", ";
1944             if (methodMode == RT_MODE_ONEWAY || methodMode == RT_MODE_ONEWAY_CONST)
1945                 o << "sal_True,\n";
1946             else
1947                 o << "sal_False,\n";
1948             o << indent() << "sMethodName" << i << ".pData,\n";
1949             o << indent() << "(typelib_TypeClass)" << getTypeClass(returnType)
1950               << ", sReturnType" << i << ".pData,\n";
1951             if (paramCount)
1952                 o << indent() << paramCount << ", aParameters,\n";
1953             else
1954                 o << indent() << "0, 0,\n";
1955             o << indent() << excCount << ", "
1956               << (excCount == 0 ? "0" : "the_Exceptions") << " );\n";
1957 
1958             dec();
1959             o << indent() << "typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );\n";
1960 
1961             dec();
1962             o << indent() << "}\n";
1963         }
1964         o << indent() << "typelib_typedescription_release( (typelib_TypeDescription*)pMethod );\n";
1965 
1966         index = absoluteIndex;
1967     }
1968 }
1969 
dumpAttributesCppuDecl(FileStream & o,StringSet * pFinishedTypes,CppuTypeDecl eDeclFlag)1970 void InterfaceType::dumpAttributesCppuDecl(FileStream& o, StringSet* pFinishedTypes, CppuTypeDecl eDeclFlag)
1971 {
1972     sal_uInt16 fieldCount = m_reader.getFieldCount();
1973 
1974     RTFieldAccess access = RT_ACCESS_INVALID;
1975     OString fieldName;
1976     OString fieldType;
1977     for (sal_uInt16 i=0; i < fieldCount; i++)
1978     {
1979         access = m_reader.getFieldFlags(i);
1980 
1981         if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
1982             continue;
1983 
1984         fieldName = rtl::OUStringToOString(
1985             m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
1986         fieldType = rtl::OUStringToOString(
1987             m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8);
1988 
1989         if (pFinishedTypes->count(fieldType) == 0)
1990         {
1991             pFinishedTypes->insert(fieldType);
1992             dumpCppuGetType(o, fieldType, sal_True, eDeclFlag);
1993         }
1994     }
1995 }
1996 
dumpMethodsCppuDecl(FileStream & o,StringSet * pFinishedTypes,CppuTypeDecl eDeclFlag)1997 void InterfaceType::dumpMethodsCppuDecl(FileStream& o, StringSet* pFinishedTypes, CppuTypeDecl eDeclFlag)
1998 {
1999     sal_uInt16      methodCount = m_reader.getMethodCount();
2000     OString         returnType, paramType, excType;
2001     sal_uInt16      paramCount = 0;
2002     sal_uInt16      excCount = 0;
2003 
2004     for (sal_uInt16 i=0; i < methodCount; i++)
2005     {
2006         returnType = rtl::OUStringToOString(
2007             m_reader.getMethodReturnTypeName(i), RTL_TEXTENCODING_UTF8);
2008         paramCount = m_reader.getMethodParameterCount(i);
2009         excCount = m_reader.getMethodExceptionCount(i);
2010 
2011         if (pFinishedTypes->count(returnType) == 0)
2012         {
2013             pFinishedTypes->insert(returnType);
2014             dumpCppuGetType(o, returnType, sal_True, eDeclFlag);
2015         }
2016         sal_uInt16 j;
2017         for (j=0; j < paramCount; j++)
2018         {
2019             paramType = rtl::OUStringToOString(
2020                 m_reader.getMethodParameterTypeName(i, j),
2021                 RTL_TEXTENCODING_UTF8);
2022 
2023             if (pFinishedTypes->count(paramType) == 0)
2024             {
2025                 pFinishedTypes->insert(paramType);
2026                 dumpCppuGetType(o, paramType, sal_True, eDeclFlag);
2027             }
2028         }
2029 
2030         for (j=0; j < excCount; j++)
2031         {
2032             excType = rtl::OUStringToOString(
2033                 m_reader.getMethodExceptionTypeName(i, j),
2034                 RTL_TEXTENCODING_UTF8);
2035             if (pFinishedTypes->count(excType) == 0)
2036             {
2037                 pFinishedTypes->insert(excType);
2038                 dumpCppuGetType(o, excType, sal_True, eDeclFlag);
2039             }
2040         }
2041     }
2042 }
2043 
dumpExceptionSpecification(FileStream & out,sal_uInt32 methodIndex,bool runtimeException)2044 void InterfaceType::dumpExceptionSpecification(
2045     FileStream & out, sal_uInt32 methodIndex, bool runtimeException)
2046 {
2047     out << " throw (";
2048     bool first = true;
2049     if (methodIndex <= SAL_MAX_UINT16) {
2050         sal_uInt16 count = m_reader.getMethodExceptionCount(
2051             static_cast< sal_uInt16 >(methodIndex));
2052         for (sal_uInt16 i = 0; i < count; ++i) {
2053             rtl::OUString name(
2054                 m_reader.getMethodExceptionTypeName(
2055                     static_cast< sal_uInt16 >(methodIndex), i));
2056             if (!name.equalsAsciiL(
2057                     RTL_CONSTASCII_STRINGPARAM(
2058                         "com/sun/star/uno/RuntimeException")))
2059             {
2060                 if (!first) {
2061                     out << ", ";
2062                 }
2063                 first = false;
2064                 out << scopedCppName(
2065                     rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8));
2066             }
2067         }
2068     }
2069     if (runtimeException) {
2070         if (!first) {
2071             out << ", ";
2072         }
2073         out << "::com::sun::star::uno::RuntimeException";
2074     }
2075     out << ")";
2076 }
2077 
dumpAttributeExceptionSpecification(FileStream & out,rtl::OUString const & name,RTMethodMode sort)2078 void InterfaceType::dumpAttributeExceptionSpecification(
2079     FileStream & out, rtl::OUString const & name, RTMethodMode sort)
2080 {
2081     sal_uInt16 methodCount = m_reader.getMethodCount();
2082     for (sal_uInt16 i = 0; i < methodCount; ++i) {
2083         if (m_reader.getMethodFlags(i) == sort
2084             && m_reader.getMethodName(i) == name)
2085         {
2086             dumpExceptionSpecification(out, i, true);
2087             return;
2088         }
2089     }
2090     dumpExceptionSpecification(out, 0xFFFFFFFF, true);
2091 }
2092 
dumpExceptionTypeName(FileStream & out,char const * prefix,sal_uInt32 index,rtl::OUString name)2093 void InterfaceType::dumpExceptionTypeName(
2094     FileStream & out, char const * prefix, sal_uInt32 index, rtl::OUString name)
2095 {
2096     out << indent() << "::rtl::OUString the_" << prefix << "ExceptionName"
2097         << index << "(RTL_CONSTASCII_USTRINGPARAM(\""
2098         << rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8).replace('/', '.')
2099         << "\"));\n";
2100 }
2101 
dumpExceptionTypeNames(FileStream & out,char const * prefix,sal_uInt16 methodIndex,bool runtimeException)2102 sal_Int32 InterfaceType::dumpExceptionTypeNames(
2103     FileStream & out, char const * prefix, sal_uInt16 methodIndex,
2104     bool runtimeException)
2105 {
2106     sal_Int32 count = 0;
2107     sal_uInt16 n = m_reader.getMethodExceptionCount(methodIndex);
2108     for (sal_uInt16 i = 0; i < n; ++i) {
2109         rtl::OUString name(m_reader.getMethodExceptionTypeName(methodIndex, i));
2110         if (!name.equalsAsciiL(
2111                 RTL_CONSTASCII_STRINGPARAM(
2112                     "com/sun/star/uno/RuntimeException")))
2113         {
2114             dumpExceptionTypeName(out, prefix, count++, name);
2115         }
2116     }
2117     if (runtimeException) {
2118         dumpExceptionTypeName(
2119             out, prefix, count++,
2120             rtl::OUString(
2121                 RTL_CONSTASCII_USTRINGPARAM(
2122                     "com/sun/star/uno/RuntimeException")));
2123     }
2124     if (count > 0) {
2125         out << indent() << "rtl_uString * the_" << prefix << "Exceptions[] = {";
2126         for (sal_Int32 i = 0; i < count; ++i) {
2127             out << (i == 0 ? " " : ", ") << "the_" << prefix << "ExceptionName"
2128                 << i << ".pData";
2129         }
2130         out << " };\n";
2131     }
2132     return count;
2133 }
2134 
dumpAttributeExceptionTypeNames(FileStream & out,char const * prefix,rtl::OUString const & name,RTMethodMode sort)2135 sal_Int32 InterfaceType::dumpAttributeExceptionTypeNames(
2136     FileStream & out, char const * prefix, rtl::OUString const & name,
2137     RTMethodMode sort)
2138 {
2139     sal_uInt16 methodCount = m_reader.getMethodCount();
2140     for (sal_uInt16 i = 0; i < methodCount; ++i) {
2141         if (m_reader.getMethodFlags(i) == sort
2142             && m_reader.getMethodName(i) == name)
2143         {
2144             return dumpExceptionTypeNames(out, prefix, i, false);
2145         }
2146     }
2147     return 0;
2148 }
2149 
2150 //*************************************************************************
2151 // ConstantsType
2152 //*************************************************************************
ConstantsType(typereg::Reader & typeReader,const OString & typeName,const TypeManager & typeMgr)2153 ConstantsType::ConstantsType(typereg::Reader& typeReader,
2154                              const OString& typeName,
2155                              const TypeManager& typeMgr)
2156     : CppuType(typeReader, typeName, typeMgr)
2157 {
2158 }
2159 
~ConstantsType()2160 ConstantsType::~ConstantsType()
2161 {
2162 
2163 }
2164 
dump(CppuOptions * pOptions)2165 sal_Bool ConstantsType::dump(CppuOptions* pOptions)
2166     throw( CannotDumpException )
2167 {
2168     if (!m_dependencies.isValid()) {
2169         return false;
2170     }
2171     addSpecialDependencies();
2172 
2173     if (pOptions->isValid("-U"))
2174         m_cppuTypeDynamic = sal_True;
2175 
2176     OString outPath;
2177     if (pOptions->isValid("-O"))
2178         outPath = pOptions->getOption("-O");
2179 
2180     return dumpFiles(pOptions, outPath);
2181 }
2182 
dumpHFile(FileStream & o,codemaker::cppumaker::Includes & includes)2183 sal_Bool ConstantsType::dumpHFile(
2184     FileStream& o, codemaker::cppumaker::Includes & includes)
2185     throw( CannotDumpException )
2186 {
2187     sal_Bool bSpecialDefine = sal_True;
2188 
2189     if (m_reader.getTypeClass() == RT_TYPE_CONSTANTS)
2190     {
2191         bSpecialDefine = sal_False;
2192     }
2193 
2194     OString headerDefine(dumpHeaderDefine(o, "HDL", bSpecialDefine));
2195     o << "\n";
2196 
2197     addDefaultHIncludes(includes);
2198     includes.dump(o, 0);
2199     o << "\n";
2200 
2201     if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, true)) {
2202         o << "\n";
2203     }
2204     o << "\n";
2205 
2206     dumpDeclaration(o);
2207     o << "\n";
2208 
2209     if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, true)) {
2210         o << "\n";
2211     }
2212     o << "\n#endif // "<< headerDefine << "\n";
2213 
2214     return sal_True;
2215 }
2216 
dumpDeclaration(FileStream & o)2217 sal_Bool ConstantsType::dumpDeclaration(FileStream& o)
2218     throw( CannotDumpException )
2219 {
2220     sal_uInt16      fieldCount = m_reader.getFieldCount();
2221     OString         fieldName;
2222     OString         fieldType;
2223     for (sal_uInt16 i=0; i < fieldCount; i++)
2224     {
2225         fieldName = rtl::OUStringToOString(
2226             m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
2227         fieldType = rtl::OUStringToOString(
2228             m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8);
2229 
2230         o << "static const ";
2231         dumpType(o, fieldType);
2232         o << " " << fieldName << " = ";
2233         dumpConstantValue(o, i);
2234         o << ";\n";
2235     }
2236 
2237     return sal_True;
2238 }
2239 
hasConstants()2240 sal_Bool ConstantsType::hasConstants()
2241 {
2242     return m_reader.getFieldCount() > 0;
2243 }
2244 
dumpHxxFile(FileStream & o,codemaker::cppumaker::Includes &)2245 sal_Bool ConstantsType::dumpHxxFile(
2246     FileStream& o, codemaker::cppumaker::Includes &)
2247     throw( CannotDumpException )
2248 {
2249     sal_Bool bSpecialDefine = sal_True;
2250 
2251     if (m_reader.getTypeClass() == RT_TYPE_CONSTANTS)
2252     {
2253         bSpecialDefine = sal_False;
2254     }
2255 
2256     OString headerDefine(dumpHeaderDefine(o, "HPP", bSpecialDefine));
2257     o << "\n";
2258 
2259     rtl::OString suffix;
2260     if (bSpecialDefine) {
2261         suffix = m_name;
2262     }
2263     codemaker::cppumaker::Includes::dumpInclude(o, m_typeName, false, suffix);
2264 
2265     o << "\n#endif // "<< headerDefine << "\n";
2266 
2267     return sal_True;
2268 }
2269 
2270 //*************************************************************************
2271 // ModuleType
2272 //*************************************************************************
ModuleType(typereg::Reader & typeReader,const OString & typeName,const TypeManager & typeMgr)2273 ModuleType::ModuleType(typereg::Reader& typeReader,
2274                        const OString& typeName,
2275                        const TypeManager& typeMgr)
2276     : ConstantsType(typeReader, typeName, typeMgr)
2277 {
2278 }
2279 
~ModuleType()2280 ModuleType::~ModuleType()
2281 {
2282 
2283 }
2284 
dumpFiles(CppuOptions * options,rtl::OString const & outPath)2285 bool ModuleType::dumpFiles(
2286     CppuOptions * options, rtl::OString const & outPath)
2287 {
2288     rtl::OString tmpName(m_typeName);
2289     if (tmpName.equals("/")) {
2290         tmpName = "global";
2291     } else {
2292         tmpName += "/" + m_typeName.copy(m_typeName.lastIndexOf('/') + 1);
2293     }
2294     return dumpFile(options, ".hdl", tmpName, outPath)
2295         && dumpFile(options, ".hpp", tmpName, outPath);
2296 }
2297 
2298 //*************************************************************************
2299 // StructureType
2300 //*************************************************************************
2301 
2302 namespace {
2303 
dumpTypeParameterName(FileStream & out,rtl::OString const & name)2304 void dumpTypeParameterName(FileStream & out, rtl::OString const & name) {
2305     // Prefix all type parameters with "typeparam_" to avoid problems when a
2306     // struct member has the same name as a type parameter, as in
2307     // struct<T> { T T; };
2308     out << "typeparam_" << name;
2309 }
2310 
2311 }
2312 
StructureType(typereg::Reader & typeReader,const OString & typeName,const TypeManager & typeMgr)2313 StructureType::StructureType(typereg::Reader& typeReader,
2314                              const OString& typeName,
2315                              const TypeManager& typeMgr)
2316     : CppuType(typeReader, typeName, typeMgr)
2317 {
2318 }
2319 
~StructureType()2320 StructureType::~StructureType()
2321 {
2322 
2323 }
2324 
dumpHFile(FileStream & o,codemaker::cppumaker::Includes & includes)2325 sal_Bool StructureType::dumpHFile(
2326     FileStream& o, codemaker::cppumaker::Includes & includes)
2327     throw( CannotDumpException )
2328 {
2329     OString headerDefine(dumpHeaderDefine(o, "HDL"));
2330     o << "\n";
2331 
2332     addDefaultHIncludes(includes);
2333     includes.dump(o, 0);
2334     o << "\n";
2335 
2336     if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) {
2337         o << "\n";
2338     }
2339 
2340     dumpDeclaration(o);
2341 
2342     if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) {
2343         o << "\n";
2344     }
2345 
2346     o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n"
2347       << "class Type;\n} } } }\n\n";
2348 
2349     dumpTemplateHead(o);
2350     o << "inline const ::com::sun::star::uno::Type& SAL_CALL getCppuType( ";
2351     dumpType(o, m_typeName, sal_True, sal_False);
2352     dumpTemplateParameters(o);
2353     o << "* );\n\n";
2354 
2355     o << "#endif // "<< headerDefine << "\n";
2356 
2357     return sal_True;
2358 }
2359 
dumpDeclaration(FileStream & o)2360 sal_Bool StructureType::dumpDeclaration(FileStream& o)
2361     throw( CannotDumpException )
2362 {
2363     o << "\n#ifdef SAL_W32\n"
2364       << "#   pragma pack(push, 8)\n"
2365       << "#elif defined(SAL_OS2)\n"
2366       << "#   pragma pack(8)\n"
2367       << "#endif\n\n";
2368 
2369     OSL_ASSERT(!isPolymorphic() || m_reader.getSuperTypeCount() == 0); //TODO
2370     o << indent();
2371     dumpTemplateHead(o);
2372     o << "struct " << m_name;
2373     rtl::OString base;
2374     if (m_reader.getSuperTypeCount() != 0) {
2375         base = rtl::OUStringToOString(
2376             m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8);
2377         OSL_ASSERT( !base.isEmpty() ); //TODO
2378     }
2379     if ( !base.isEmpty() ) {
2380         o << ": public " << scopedCppName(base);
2381     }
2382     o << " {\n";
2383     inc();
2384     o << indent() << "inline " << m_name << "() SAL_THROW(());\n";
2385     sal_uInt16 members = m_reader.getFieldCount();
2386     if (members > 0 || getInheritedMemberCount() > 0) {
2387         o << "\n" << indent() << "inline " << m_name << "(";
2388         bool prev = dumpSuperMember(o, base, true);
2389         for (sal_uInt16 i = 0; i < members; ++i) {
2390             if (prev) {
2391                 o << ", ";
2392             }
2393             prev = true;
2394             rtl::OString type(
2395                 rtl::OUStringToOString(
2396                     m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8));
2397             if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0)
2398             {
2399                 dumpTypeParameterName(o, type);
2400                 o << " const &";
2401             } else {
2402                 dumpType(o, type, true, true);
2403             }
2404             o << " "
2405               << rtl::OUStringToOString(
2406                   m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8)
2407               << "_";
2408         }
2409         o << ") SAL_THROW(());\n";
2410     }
2411     if (members > 0) {
2412         o << "\n";
2413         for (sal_uInt16 i = 0; i < members; ++i) {
2414             o << indent();
2415             bool parameterized
2416                 = ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE)
2417                    != 0);
2418             rtl::OString type(
2419                 rtl::OUStringToOString(
2420                     m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8));
2421             if (parameterized) {
2422                 dumpTypeParameterName(o, type);
2423             } else {
2424                 dumpType(o, type);
2425             }
2426             o << " "
2427                 << rtl::OUStringToOString(
2428                     m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
2429             if (i == 0 && !base.isEmpty() && type != "double"
2430                 && type != "hyper" && type != "unsigned hyper")
2431             {
2432                 OSL_ASSERT(!parameterized);
2433                 o << " CPPU_GCC3_ALIGN(" << scopedCppName(base) << ")";
2434             }
2435             o << ";\n";
2436         }
2437     }
2438     dec();
2439     o << "};\n\n";
2440 
2441     o << "#ifdef SAL_W32\n"
2442       << "#   pragma pack(pop)\n"
2443       << "#elif defined(SAL_OS2)\n"
2444       << "#   pragma pack()\n"
2445       << "#endif\n\n";
2446 
2447     return sal_True;
2448 }
2449 
dumpHxxFile(FileStream & o,codemaker::cppumaker::Includes & includes)2450 sal_Bool StructureType::dumpHxxFile(
2451     FileStream& o, codemaker::cppumaker::Includes & includes)
2452     throw( CannotDumpException )
2453 {
2454     OString headerDefine(dumpHeaderDefine(o, "HPP"));
2455     o << "\n";
2456 
2457     includes.dump(o, &m_typeName);
2458     o << "\n";
2459 
2460     if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) {
2461         o << "\n";
2462     }
2463     o << "\n";
2464 
2465     dumpTemplateHead(o);
2466     o << "inline " << m_name;
2467     dumpTemplateParameters(o);
2468     o << "::" << m_name << "() SAL_THROW( () )\n";
2469     inc();
2470     OString superType;
2471     if (m_reader.getSuperTypeCount() >= 1) {
2472         superType = rtl::OUStringToOString(
2473             m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8);
2474     }
2475     sal_Bool first = sal_True;
2476     if ( !superType.isEmpty() )
2477     {
2478         o << indent() << ": " << scopedCppName(superType) << "()\n";
2479         first = sal_False;
2480     }
2481 
2482     sal_uInt16      fieldCount = m_reader.getFieldCount();
2483     RTFieldAccess   access = RT_ACCESS_INVALID;
2484     OString         fieldName;
2485     OString         fieldType;
2486 
2487     for (sal_uInt16 i=0; i < fieldCount; i++)
2488     {
2489         access = m_reader.getFieldFlags(i);
2490 
2491         if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
2492             continue;
2493 
2494         fieldName = rtl::OUStringToOString(
2495             m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
2496 
2497         if (first)
2498         {
2499             first = sal_False;
2500             o << indent() << ": ";
2501         } else
2502             o << indent() << ", ";
2503 
2504         o << fieldName;
2505         dumpInitializer(
2506             o, (access & RT_ACCESS_PARAMETERIZED_TYPE) != 0,
2507             m_reader.getFieldTypeName(i));
2508         o << "\n";
2509     }
2510     dec();
2511     o << "{\n}\n\n";
2512 
2513     if (fieldCount > 0 || getInheritedMemberCount() > 0)
2514     {
2515         dumpTemplateHead(o);
2516         o << "inline " << m_name;
2517         dumpTemplateParameters(o);
2518         o << "::" << m_name << "(";
2519 
2520         sal_Bool superHasMember = dumpSuperMember(o, superType, sal_True);
2521 
2522         for (sal_uInt16 i=0; i < fieldCount; i++)
2523         {
2524             access = m_reader.getFieldFlags(i);
2525 
2526             if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
2527                 continue;
2528 
2529             fieldName = rtl::OUStringToOString(
2530                 m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
2531             fieldType = rtl::OUStringToOString(
2532                 m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8);
2533 
2534             if (superHasMember)
2535                 o << ", ";
2536             else
2537                 superHasMember = sal_True;
2538 
2539             if ((access & RT_ACCESS_PARAMETERIZED_TYPE) != 0) {
2540                 dumpTypeParameterName(o, fieldType);
2541                 o << " const &";
2542             } else {
2543                 dumpType(o, fieldType, sal_True, sal_True);
2544             }
2545 //          o << " __" << fieldName;
2546             o << " " << fieldName << "_";
2547         }
2548         o << ") SAL_THROW( () )\n";
2549 
2550         inc();
2551         first = sal_True;
2552         if ( !superType.isEmpty() )
2553         {
2554             o << indent() << ": " << scopedCppName(superType) << "(";
2555             dumpSuperMember(o, superType, sal_False);
2556             o << ")\n";
2557             first = sal_False;
2558         }
2559 
2560         for (sal_uInt16 i=0; i < fieldCount; i++)
2561         {
2562             access = m_reader.getFieldFlags(i);
2563 
2564             if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
2565                 continue;
2566 
2567             fieldName = rtl::OUStringToOString(
2568                 m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
2569 
2570             if (first)
2571             {
2572                 first = sal_False;
2573                 o << indent() << ": ";
2574             } else
2575                 o << indent() << ", ";
2576 
2577 //          o << fieldName << "(__" << fieldName << ")\n";
2578             o << fieldName << "(" << fieldName << "_)\n";
2579         }
2580 
2581         dec();
2582         o << "{\n}\n\n";
2583     }
2584 
2585     if (isPolymorphic() && fieldCount > 0) {
2586         o << indent();
2587         dumpTemplateHead(o);
2588         o << "\n";
2589         o << indent();
2590         o << "inline " << m_name;
2591         dumpTemplateParameters(o);
2592         o << "\n";
2593         o << indent();
2594         o << "make_" << m_name << "(";
2595         for (sal_uInt16 i = 0; i < fieldCount; ++i) {
2596             if (i > 0) {
2597                 o << ", ";
2598             }
2599             rtl::OString type(
2600                 rtl::OUStringToOString(
2601                     m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8));
2602             if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0)
2603             {
2604                 dumpTypeParameterName(o, type);
2605                 o << " const &";
2606             } else {
2607                 dumpType(o, type, true, true);
2608             }
2609             o << " "
2610               << rtl::OUStringToOString(
2611                   m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8)
2612               << "_";
2613         }
2614         o << ") SAL_THROW(())\n";
2615         o << indent() << "{\n";
2616         inc();
2617         o << indent() << "return " << m_name;
2618         dumpTemplateParameters(o);
2619         o << "(";
2620         for (sal_uInt16 i = 0; i < fieldCount; ++i) {
2621             if (i > 0) {
2622                 o << ", ";
2623             }
2624             o << rtl::OUStringToOString(
2625                   m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8)
2626               << "_";
2627         }
2628         o << ");\n";
2629         dec();
2630         o << indent() << "}\n\n";
2631     }
2632 
2633     if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) {
2634         o << "\n";
2635     }
2636 
2637     o << "\n";
2638     dumpGetCppuType(o);
2639 
2640     o << "\n#endif // "<< headerDefine << "\n";
2641 
2642     return sal_True;
2643 }
2644 
dumpLightGetCppuType(FileStream & out)2645 void StructureType::dumpLightGetCppuType(FileStream & out) {
2646     dumpGetCppuTypePreamble(out);
2647     out << indent()
2648         << ("//TODO: On certain platforms with weak memory models, the"
2649             " following code can result in some threads observing that the_type"
2650             " points to garbage\n")
2651         << indent()
2652         << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2653         << indent() << "if (the_type == 0) {\n";
2654     inc();
2655     if (isPolymorphic()) {
2656         out << indent() << "::rtl::OStringBuffer the_buffer(\""
2657             << m_typeName.replace('/', '.') << "<\");\n";
2658         sal_uInt16 n = m_reader.getReferenceCount();
2659         for (sal_uInt16 i = 0; i < n; ++i) {
2660             out << indent()
2661                 << ("the_buffer.append(::rtl::OUStringToOString("
2662                     "::cppu::getTypeFavourChar(static_cast< ");
2663             dumpTypeParameterName(
2664                 out,
2665                 rtl::OUStringToOString(
2666                     m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8));
2667             out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n";
2668             if (i != n - 1) {
2669                 out << indent() << "the_buffer.append(',');\n";
2670             }
2671         }
2672         out << indent() << "the_buffer.append('>');\n";
2673     }
2674     out << indent() << "::typelib_static_type_init(&the_type, "
2675         << getTypeClass(m_typeName, true) << ", ";
2676     if (isPolymorphic()) {
2677         out << "the_buffer.getStr()";
2678     } else {
2679         out << "\"" << m_typeName.replace('/', '.') << "\"";
2680     }
2681     out << ");\n";
2682     dec();
2683     out << indent() << "}\n" << indent()
2684         << ("return *reinterpret_cast< ::com::sun::star::uno::Type * >("
2685             "&the_type);\n");
2686     dumpGetCppuTypePostamble(out);
2687 }
2688 
dumpNormalGetCppuType(FileStream & out)2689 void StructureType::dumpNormalGetCppuType(FileStream & out) {
2690     dumpGetCppuTypePreamble(out);
2691     out << indent()
2692         << ("//TODO: On certain platforms with weak memory models, the"
2693             " following code can result in some threads observing that the_type"
2694             " points to garbage\n")
2695         << indent()
2696         << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2697         << indent() << "if (the_type == 0) {\n";
2698     inc();
2699     if (isPolymorphic()) {
2700         out << indent() << "::rtl::OStringBuffer the_buffer(\""
2701             << m_typeName.replace('/', '.') << "<\");\n";
2702         sal_uInt16 n = m_reader.getReferenceCount();
2703         for (sal_uInt16 i = 0; i < n; ++i) {
2704             out << indent()
2705                 << ("the_buffer.append(::rtl::OUStringToOString("
2706                     "::cppu::getTypeFavourChar(static_cast< ");
2707             dumpTypeParameterName(
2708                 out,
2709                 rtl::OUStringToOString(
2710                     m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8));
2711             out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n";
2712             if (i != n - 1) {
2713                 out << indent() << "the_buffer.append(',');\n";
2714             }
2715         }
2716         out << indent() << "the_buffer.append('>');\n";
2717     }
2718     out << indent()
2719         << "::typelib_TypeDescriptionReference * the_members[] = {\n";
2720     inc();
2721     sal_uInt16 fields = m_reader.getFieldCount();
2722     for (sal_uInt16 i = 0; i < fields; ++i) {
2723         out << indent();
2724         rtl::OString type(
2725             rtl::OUStringToOString(
2726                 m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8));
2727         if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0) {
2728             out << "::cppu::getTypeFavourChar(static_cast< ";
2729             dumpTypeParameterName(out, type);
2730             out << " * >(0))";
2731         } else {
2732             out << "::cppu::UnoType< ";
2733             dumpType(out, type, false, false, false, true);
2734             out << " >::get()";
2735         }
2736         out << ".getTypeLibType()" << (i == fields - 1 ? " };" : ",")
2737             << "\n";
2738     }
2739     dec();
2740     if (isPolymorphic()) {
2741         out << indent()
2742             << "static ::sal_Bool const the_parameterizedTypes[] = { ";
2743         for (sal_uInt16 i = 0; i < fields; ++i) {
2744             if (i != 0) {
2745                 out << ", ";
2746             }
2747             out << (((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE)
2748                      == 0)
2749                     ? "false" : "true");
2750         }
2751         out << " };\n";
2752     }
2753     out << indent() << "::typelib_static_struct_type_init(&the_type, ";
2754     if (isPolymorphic()) {
2755         out << "the_buffer.getStr()";
2756     } else {
2757         out << "\"" << m_typeName.replace('/', '.') << "\"";
2758     }
2759     out << ", ";
2760     if (m_reader.getSuperTypeCount() == 0) {
2761         out << "0";
2762     } else {
2763         out << "::cppu::UnoType< ";
2764         dumpType(
2765             out,
2766             rtl::OUStringToOString(
2767                 m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8),
2768             false, false, false, true);
2769         out << " >::get().getTypeLibType()";
2770     }
2771     out << ", " << fields << ", the_members, "
2772         << (isPolymorphic() ? "the_parameterizedTypes" : "0") << ");\n";
2773     dec();
2774     out << indent() << "}\n" << indent()
2775         << ("return *reinterpret_cast< ::com::sun::star::uno::Type * >("
2776             "&the_type);\n");
2777     dumpGetCppuTypePostamble(out);
2778 }
2779 
dumpComprehensiveGetCppuType(FileStream & out)2780 void StructureType::dumpComprehensiveGetCppuType(FileStream & out) {
2781     dumpGetCppuTypePreamble(out);
2782     out << indent() << "static ::com::sun::star::uno::Type * the_pType = 0;\n"
2783         << indent() << "if (the_pType == 0) {\n";
2784     inc();
2785     out << indent()
2786         << "::osl::MutexGuard the_guard(::osl::Mutex::getGlobalMutex());\n"
2787         << indent() << "if (the_pType == 0) {\n";
2788     inc();
2789     if (isPolymorphic()) {
2790         out << indent() << "::rtl::OUStringBuffer the_buffer;\n" << indent()
2791             << "the_buffer.appendAscii(RTL_CONSTASCII_STRINGPARAM(\""
2792             << m_typeName.replace('/', '.') << "<\"));\n";
2793         sal_uInt16 n = m_reader.getReferenceCount();
2794         for (sal_uInt16 i = 0; i < n; ++i) {
2795             out << indent()
2796                 << "the_buffer.append(::cppu::getTypeFavourChar(static_cast< ";
2797             dumpTypeParameterName(
2798                 out,
2799                 rtl::OUStringToOString(
2800                     m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8));
2801             out << " * >(0)).getTypeName());\n";
2802             if (i != n - 1) {
2803                 out << indent()
2804                     << ("the_buffer.append("
2805                         "static_cast< ::sal_Unicode >(','));\n");
2806             }
2807         }
2808         out << indent()
2809             << "the_buffer.append(static_cast< ::sal_Unicode >('>'));\n"
2810             << indent()
2811             << "::rtl::OUString the_name(the_buffer.makeStringAndClear());\n";
2812     } else {
2813         out << indent()
2814             << "::rtl::OUString the_name(RTL_CONSTASCII_USTRINGPARAM(\""
2815             << m_typeName.replace('/', '.') << "\"));\n";
2816     }
2817     sal_uInt16 fields = m_reader.getFieldCount();
2818     typedef std::map< rtl::OString, sal_uInt32 > Map;
2819     Map parameters;
2820     Map types;
2821     {for (sal_uInt16 i = 0; i < fields; ++i) {
2822         rtl::OString type(
2823             rtl::OUStringToOString(
2824                 m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8));
2825         if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0) {
2826             if (parameters.insert(
2827                     Map::value_type(
2828                         type, static_cast< sal_uInt32 >(parameters.size()))).
2829                 second)
2830             {
2831                 sal_uInt32 n = static_cast< sal_uInt32 >(parameters.size() - 1);
2832                 out << indent()
2833                     << "::com::sun::star::uno::Type const & the_ptype" << n
2834                     << " = ::cppu::getTypeFavourChar(static_cast< ";
2835                 dumpTypeParameterName(out, type);
2836                 out << " * >(0));\n" << indent()
2837                     << "::typelib_TypeClass the_pclass" << n
2838                     << " = (::typelib_TypeClass) the_ptype" << n
2839                     << ".getTypeClass();\n" << indent()
2840                     << "::rtl::OUString the_pname" << n << "(the_ptype" << n
2841                     << ".getTypeName());\n";
2842             }
2843         } else if (types.insert(
2844                        Map::value_type(
2845                            type, static_cast< sal_uInt32 >(types.size()))).
2846                    second)
2847         {
2848             if ((codemaker::UnoType::getSort(type) ==
2849                  codemaker::UnoType::SORT_COMPLEX) &&
2850                 codemaker::UnoType::decompose(type) != m_typeName)
2851                     // take care of recursion like struct S { sequence<S> x; };
2852             {
2853                 out << indent() << "::cppu::UnoType< ";
2854                 dumpType(out, type, false, false, false, true);
2855                 out << " >::get();\n";
2856             }
2857             // For typedefs, use the resolved type name, as there will be no
2858             // information available about the typedef itself at runtime (the
2859             // above getCppuType call will make available information about the
2860             // resolved type); no extra #include for the resolved type is
2861             // needed, as the header for the typedef includes it already:
2862             out << indent() << "::rtl::OUString the_tname"
2863                 << static_cast< sal_uInt32 >(types.size() - 1)
2864                 << "(RTL_CONSTASCII_USTRINGPARAM(\""
2865                 << checkRealBaseType(type, true).replace('/', '.') << "\"));\n";
2866         }
2867         out << indent() << "::rtl::OUString the_name" << i
2868             << "(RTL_CONSTASCII_USTRINGPARAM(\""
2869             << rtl::OUStringToOString(
2870                 m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8).replace(
2871                     '/', '.')
2872             << "\"));\n";
2873     }}
2874     out << indent() << "::typelib_StructMember_Init the_members[] = {\n";
2875     inc();
2876     {for (sal_uInt16 i = 0; i < fields; ++i) {
2877         out << indent() << "{ { ";
2878         rtl::OString type(
2879             rtl::OUStringToOString(
2880                 m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8));
2881         if ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0) {
2882             sal_uInt32 n = parameters.find(type)->second;
2883             out << "the_pclass" << n << ", the_pname" << n << ".pData";
2884         } else {
2885             out << getTypeClass(type, true) << ", the_tname"
2886                 << types.find(type)->second << ".pData";
2887         }
2888         out << ", the_name" << i << ".pData }, "
2889             << ((m_reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) == 0
2890                 ? "false" : "true")
2891             << " }" << (i == fields - 1 ? " };" : ",") << "\n";
2892     }}
2893     dec();
2894     out << indent() << "::typelib_TypeDescription * the_newType = 0;\n";
2895     out << indent()
2896         << "::typelib_typedescription_newStruct(&the_newType, the_name.pData, ";
2897     if (m_reader.getSuperTypeCount() == 0) {
2898         out << "0";
2899     } else {
2900         out << "::cppu::UnoType< ";
2901         dumpType(
2902             out,
2903             rtl::OUStringToOString(
2904                 m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8),
2905             false, false, false, true);
2906         out << " >::get().getTypeLibType()";
2907     }
2908     out << ", " << fields << ", the_members);\n";
2909     out << indent() << "::typelib_typedescription_register(&the_newType);\n";
2910     out << indent() << "::typelib_typedescription_release(the_newType);\n";
2911     out << indent() << "static ::com::sun::star::uno::Type the_staticType("
2912         << getTypeClass(m_typeName) << ", the_name);\n";
2913     out << indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n";
2914     out << indent() << "the_pType = &the_staticType;\n";
2915     dec();
2916     out << indent() << "}\n";
2917     dec();
2918     out << indent() << "} else {\n";
2919     inc();
2920     out << indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n";
2921     dec();
2922     out << indent() << "}\n" << indent() << "return *the_pType;\n";
2923     dumpGetCppuTypePostamble(out);
2924 }
2925 
dumpSuperMember(FileStream & o,const OString & superType,sal_Bool bWithType)2926 sal_Bool StructureType::dumpSuperMember(FileStream& o, const OString& superType, sal_Bool bWithType)
2927 {
2928     sal_Bool hasMember = sal_False;
2929 
2930     if ( !superType.isEmpty() )
2931     {
2932         typereg::Reader aSuperReader(m_typeMgr.getTypeReader(superType));
2933 
2934         if (aSuperReader.isValid())
2935         {
2936             rtl::OString superSuper;
2937             if (aSuperReader.getSuperTypeCount() >= 1) {
2938                 superSuper = rtl::OUStringToOString(
2939                     aSuperReader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8);
2940             }
2941             hasMember = dumpSuperMember(o, superSuper, bWithType);
2942 
2943             sal_uInt16      fieldCount = aSuperReader.getFieldCount();
2944             RTFieldAccess   access = RT_ACCESS_INVALID;
2945             OString         fieldName;
2946             OString         fieldType;
2947             for (sal_uInt16 i=0; i < fieldCount; i++)
2948             {
2949                 access = aSuperReader.getFieldFlags(i);
2950 
2951                 if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
2952                     continue;
2953 
2954                 fieldName = rtl::OUStringToOString(
2955                     aSuperReader.getFieldName(i), RTL_TEXTENCODING_UTF8);
2956                 fieldType = rtl::OUStringToOString(
2957                     aSuperReader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8);
2958 
2959                 if (hasMember)
2960                 {
2961                     o << ", ";
2962                 } else
2963                 {
2964                     hasMember = (fieldCount > 0);
2965                 }
2966 
2967                 if (bWithType)
2968                 {
2969                     dumpType(o, fieldType, sal_True, sal_True);
2970                     o << " ";
2971                 }
2972 //              o << "__" << fieldName;
2973                 o << fieldName << "_";
2974             }
2975         }
2976     }
2977 
2978     return hasMember;
2979 }
2980 
addLightGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes) const2981 void StructureType::addLightGetCppuTypeIncludes(
2982     codemaker::cppumaker::Includes & includes) const
2983 {
2984     includes.addType();
2985     includes.addCppuUnotypeHxx();
2986     includes.addSalTypesH();
2987     includes.addTypelibTypeclassH();
2988     includes.addTypelibTypedescriptionH();
2989     if (isPolymorphic()) {
2990         includes.addRtlStrbufHxx();
2991         includes.addRtlTextencH();
2992         includes.addRtlUstringHxx();
2993     }
2994 }
2995 
addNormalGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes) const2996 void StructureType::addNormalGetCppuTypeIncludes(
2997     codemaker::cppumaker::Includes & includes) const
2998 {
2999     includes.addType();
3000     includes.addCppuUnotypeHxx();
3001     includes.addSalTypesH();
3002     includes.addTypelibTypeclassH();
3003     includes.addTypelibTypedescriptionH();
3004     if (isPolymorphic()) {
3005         includes.addRtlStrbufHxx();
3006         includes.addRtlTextencH();
3007         includes.addRtlUstringHxx();
3008     }
3009 }
3010 
addComprehensiveGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes) const3011 void StructureType::addComprehensiveGetCppuTypeIncludes(
3012     codemaker::cppumaker::Includes & includes) const
3013 {
3014     includes.addType();
3015     includes.addCppuUnotypeHxx();
3016     includes.addOslDoublecheckedlockingH();
3017     includes.addOslMutexHxx();
3018     includes.addRtlUstringH();
3019     includes.addRtlUstringHxx();
3020     includes.addSalTypesH();
3021     includes.addTypelibTypeclassH();
3022     includes.addTypelibTypedescriptionH();
3023     if (isPolymorphic()) {
3024         includes.addRtlStringH();
3025         includes.addRtlUstrbufHxx();
3026     }
3027 }
3028 
isPolymorphic() const3029 bool StructureType::isPolymorphic() const {
3030     return m_reader.getReferenceCount() > 0;
3031 }
3032 
dumpTemplateHead(FileStream & out) const3033 void StructureType::dumpTemplateHead(FileStream & out) const {
3034     if (isPolymorphic()) {
3035         out << "template< ";
3036         for (sal_uInt16 i = 0; i < m_reader.getReferenceCount(); ++i) {
3037             if (i != 0) {
3038                 out << ", ";
3039             }
3040             OSL_ASSERT(
3041                 m_reader.getReferenceFlags(i) == RT_ACCESS_INVALID
3042                 && m_reader.getReferenceSort(i) == RT_REF_TYPE_PARAMETER);
3043             out << "typename ";
3044             dumpTypeParameterName(
3045                 out,
3046                 rtl::OUStringToOString(
3047                     m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8));
3048         }
3049         out << " > ";
3050     }
3051 }
3052 
dumpTemplateParameters(FileStream & out) const3053 void StructureType::dumpTemplateParameters(FileStream & out) const {
3054     if (isPolymorphic()) {
3055         out << "< ";
3056         for (sal_uInt16 i = 0; i < m_reader.getReferenceCount(); ++i) {
3057             if (i != 0) {
3058                 out << ", ";
3059             }
3060             OSL_ASSERT(
3061                 m_reader.getReferenceFlags(i) == RT_ACCESS_INVALID
3062                 && m_reader.getReferenceSort(i) == RT_REF_TYPE_PARAMETER);
3063             dumpTypeParameterName(
3064                 out,
3065                 rtl::OUStringToOString(
3066                     m_reader.getReferenceTypeName(i), RTL_TEXTENCODING_UTF8));
3067         }
3068         out << " >";
3069     }
3070 }
3071 
3072 //*************************************************************************
3073 // ExceptionType
3074 //*************************************************************************
ExceptionType(typereg::Reader & typeReader,const OString & typeName,const TypeManager & typeMgr)3075 ExceptionType::ExceptionType(typereg::Reader& typeReader,
3076                              const OString& typeName,
3077                              const TypeManager& typeMgr)
3078     : CppuType(typeReader, typeName, typeMgr)
3079 {
3080 }
3081 
~ExceptionType()3082 ExceptionType::~ExceptionType()
3083 {
3084 
3085 }
3086 
dumpHFile(FileStream & o,codemaker::cppumaker::Includes & includes)3087 sal_Bool ExceptionType::dumpHFile(
3088     FileStream& o, codemaker::cppumaker::Includes & includes)
3089     throw( CannotDumpException )
3090 {
3091     OString headerDefine(dumpHeaderDefine(o, "HDL"));
3092     o << "\n";
3093 
3094     addDefaultHIncludes(includes);
3095     includes.dump(o, 0);
3096     o << "\n";
3097 
3098     if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) {
3099         o << "\n";
3100     }
3101 
3102     dumpDeclaration(o);
3103 
3104     if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) {
3105         o << "\n";
3106     }
3107 
3108     o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n"
3109       << "class Type;\n} } } }\n\n";
3110 
3111     o << "inline const ::com::sun::star::uno::Type& SAL_CALL getCppuType( ";
3112     dumpType(o, m_typeName, sal_True, sal_False);
3113     o << "* ) SAL_THROW( () );\n\n";
3114 
3115     o << "#endif // "<< headerDefine << "\n";
3116 
3117     return sal_True;
3118 }
3119 
dumpDeclaration(FileStream & o)3120 sal_Bool ExceptionType::dumpDeclaration(FileStream& o)
3121     throw( CannotDumpException )
3122 {
3123     o << "\nclass CPPU_GCC_DLLPUBLIC_EXPORT " << m_name;
3124 
3125     OString superType;
3126     if (m_reader.getSuperTypeCount() >= 1) {
3127         superType = rtl::OUStringToOString(
3128             m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8);
3129     }
3130     if ( !superType.isEmpty() )
3131                     o << " : public " << scopedCppName(superType);
3132 
3133     o << "\n{\npublic:\n";
3134     inc();
3135     o << indent() << "inline CPPU_GCC_DLLPRIVATE " << m_name
3136       << "() SAL_THROW( () );\n\n";
3137 
3138     sal_uInt16      fieldCount = m_reader.getFieldCount();
3139     RTFieldAccess   access = RT_ACCESS_INVALID;
3140     OString         fieldName;
3141     OString         fieldType;
3142     sal_uInt16      i = 0;
3143 
3144     if (fieldCount > 0 || getInheritedMemberCount() > 0)
3145     {
3146         o << indent() << "inline CPPU_GCC_DLLPRIVATE " << m_name << "(";
3147 
3148         sal_Bool superHasMember = dumpSuperMember(o, superType, sal_True);
3149 
3150         for (i=0; i < fieldCount; i++)
3151         {
3152             access = m_reader.getFieldFlags(i);
3153 
3154             if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
3155                             continue;
3156 
3157             fieldName = rtl::OUStringToOString(
3158                 m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
3159             fieldType = rtl::OUStringToOString(
3160                 m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8);
3161 
3162             if (superHasMember)
3163                 o << ", ";
3164             else
3165                 superHasMember = sal_True;
3166 
3167             dumpType(o, fieldType, sal_True, sal_True);
3168 //          o << " __" << fieldName;
3169             o << " " << fieldName << "_";
3170         }
3171         o << ") SAL_THROW( () );\n\n";
3172     }
3173     o << indent() << "inline CPPU_GCC_DLLPRIVATE " << m_name << "(" << m_name
3174       << " const &);\n\n"
3175       << indent() << "inline CPPU_GCC_DLLPRIVATE ~" << m_name << "();\n\n"
3176       << indent() << "inline CPPU_GCC_DLLPRIVATE " << m_name << " & operator =("
3177       << m_name << " const &);\n\n";
3178 
3179     for (i=0; i < fieldCount; i++)
3180     {
3181         access = m_reader.getFieldFlags(i);
3182 
3183         if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
3184             continue;
3185 
3186         fieldName = rtl::OUStringToOString(
3187             m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
3188         fieldType = rtl::OUStringToOString(
3189             m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8);
3190 
3191         o << indent();
3192         dumpType(o, fieldType);
3193         o << " " << fieldName;
3194         if (i == 0 && !superType.isEmpty() &&
3195             !fieldType.equals("double") && !fieldType.equals("hyper") && !fieldType.equals("unsigned hyper"))
3196         {
3197             o << " CPPU_GCC3_ALIGN( " << scopedCppName(superType) << " )";
3198         }
3199         o << ";\n";
3200     }
3201 
3202 
3203     dec();
3204     o << "};\n\n";
3205 
3206     return sal_True;
3207 }
3208 
dumpHxxFile(FileStream & o,codemaker::cppumaker::Includes & includes)3209 sal_Bool ExceptionType::dumpHxxFile(
3210     FileStream& o, codemaker::cppumaker::Includes & includes)
3211     throw( CannotDumpException )
3212 {
3213     OString headerDefine(dumpHeaderDefine(o, "HPP"));
3214     o << "\n";
3215 
3216     addDefaultHxxIncludes(includes);
3217     includes.dump(o, &m_typeName);
3218     o << "\n";
3219 
3220     if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) {
3221         o << "\n";
3222     }
3223     o << "\n";
3224 
3225     o << "inline " << m_name << "::" << m_name << "() SAL_THROW( () )\n";
3226     inc();
3227     OString superType;
3228     if (m_reader.getSuperTypeCount() >= 1) {
3229         superType = rtl::OUStringToOString(
3230             m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8);
3231     }
3232     sal_Bool first = sal_True;
3233     if ( !superType.isEmpty() )
3234     {
3235         o << indent() << ": " << scopedCppName(superType) << "()\n";
3236         first = sal_False;
3237     }
3238 
3239     sal_uInt16      fieldCount = m_reader.getFieldCount();
3240     RTFieldAccess   access = RT_ACCESS_INVALID;
3241     OString         fieldName;
3242     OString         fieldType;
3243 
3244     for (sal_uInt16 i=0; i < fieldCount; i++)
3245     {
3246         access = m_reader.getFieldFlags(i);
3247 
3248         if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
3249             continue;
3250 
3251         fieldName = rtl::OUStringToOString(
3252             m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
3253 
3254         if (first)
3255         {
3256             first = sal_False;
3257             o << indent() << ": ";
3258         } else
3259             o << indent() << ", ";
3260 
3261         o << fieldName;
3262         dumpInitializer(o, false, m_reader.getFieldTypeName(i));
3263         o << "\n";
3264     }
3265     dec();
3266     if ( !m_cppuTypeDynamic )
3267     {
3268         o << "{\n";
3269         inc();
3270         dumpCppuGetType(o, m_typeName, sal_True);
3271         dec();
3272         o << "}\n\n";
3273     } else
3274     {
3275         o << "{ }\n\n";
3276     }
3277 
3278     if (fieldCount > 0 || getInheritedMemberCount() > 0)
3279     {
3280         o << indent() << "inline " << m_name << "::" << m_name << "(";
3281 
3282         sal_Bool superHasMember = dumpSuperMember(o, superType, sal_True);
3283 
3284         for (sal_uInt16 i=0; i < fieldCount; i++)
3285         {
3286             access = m_reader.getFieldFlags(i);
3287 
3288             if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
3289                 continue;
3290 
3291             fieldName = rtl::OUStringToOString(
3292                 m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
3293             fieldType = rtl::OUStringToOString(
3294                 m_reader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8);
3295 
3296             if (superHasMember)
3297                 o << ", ";
3298             else
3299                 superHasMember = sal_True;
3300 
3301             dumpType(o, fieldType, sal_True, sal_True);
3302 //          o << " __" << fieldName;
3303             o << " " << fieldName << "_";
3304         }
3305         o << ") SAL_THROW( () )\n";
3306 
3307         inc();
3308         first = sal_True;
3309         if ( !superType.isEmpty() )
3310         {
3311             o << indent() << ": " << scopedCppName(superType) << "(";
3312             dumpSuperMember(o, superType, sal_False);
3313             o << ")\n";
3314             first = sal_False;
3315         }
3316 
3317         for (sal_uInt16 i=0; i < fieldCount; i++)
3318         {
3319             access = m_reader.getFieldFlags(i);
3320 
3321             if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
3322                 continue;
3323 
3324             fieldName = rtl::OUStringToOString(
3325                 m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
3326 
3327             if (first)
3328             {
3329                 first = sal_False;
3330                 o << indent() << ": ";
3331             } else
3332                 o << indent() << ", ";
3333 
3334 //          o << fieldName << "(__" << fieldName << ")\n";
3335             o << fieldName << "(" << fieldName << "_)\n";
3336         }
3337 
3338         dec();
3339         if ( !m_cppuTypeDynamic )
3340         {
3341             o << "{\n";
3342             inc();
3343             dumpCppuGetType(o, m_typeName, sal_True);
3344             dec();
3345             o << "}\n\n";
3346         } else
3347         {
3348             o << "{ }\n\n";
3349         }
3350     }
3351     o << indent() << m_name << "::" << m_name << "(" << m_name
3352       << " const & the_other)";
3353     first = true;
3354     if ( !superType.isEmpty() ) {
3355         o << ": " << scopedCppName(superType) << "(the_other)";
3356         first = false;
3357     }
3358     for (sal_uInt16 i = 0; i < fieldCount; ++i) {
3359         rtl::OString name(
3360             rtl::OUStringToOString(
3361                 m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8));
3362         o << (first ? ": " : ", ") << name << "(the_other." << name << ")";
3363         first = false;
3364     }
3365     o << indent() << " {}\n\n"
3366       << indent() << m_name << "::~" << m_name << "() {}\n\n"
3367       << indent() << m_name << " & " << m_name << "::operator =(" << m_name
3368       << " const & the_other) {\n";
3369     inc();
3370     o << indent()
3371       << ("//TODO: Just like its implicitly-defined counterpart, this function"
3372           " definition is not exception-safe\n");
3373     if ( !superType.isEmpty() ) {
3374         o << indent() << scopedCppName(superType)
3375           << "::operator =(the_other);\n";
3376     }
3377     for (sal_uInt16 i = 0; i < fieldCount; ++i) {
3378         rtl::OString name(
3379             rtl::OUStringToOString(
3380                 m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8));
3381         o << indent() << name << " = the_other." << name << ";\n";
3382     }
3383     o << indent() << "return *this;\n";
3384     dec();
3385     o << indent() << "}\n\n";
3386 
3387     if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) {
3388         o << "\n";
3389     }
3390 
3391     o << "\n";
3392     dumpGetCppuType(o);
3393 
3394     o << "\n#endif // "<< headerDefine << "\n";
3395     return sal_True;
3396 }
3397 
dumpSuperMember(FileStream & o,const OString & superType,sal_Bool bWithType)3398 sal_Bool ExceptionType::dumpSuperMember(FileStream& o, const OString& superType, sal_Bool bWithType)
3399 {
3400     sal_Bool hasMember = sal_False;
3401 
3402     if ( !superType.isEmpty() )
3403     {
3404         typereg::Reader aSuperReader(m_typeMgr.getTypeReader(superType));
3405 
3406         if (aSuperReader.isValid())
3407         {
3408             rtl::OString superSuper;
3409             if (aSuperReader.getSuperTypeCount() >= 1) {
3410                 superSuper = rtl::OUStringToOString(
3411                     aSuperReader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8);
3412             }
3413             hasMember = dumpSuperMember(o, superSuper, bWithType);
3414 
3415             sal_uInt16      fieldCount = aSuperReader.getFieldCount();
3416             RTFieldAccess   access = RT_ACCESS_INVALID;
3417             OString         fieldName;
3418             OString         fieldType;
3419             for (sal_uInt16 i=0; i < fieldCount; i++)
3420             {
3421                 access = aSuperReader.getFieldFlags(i);
3422 
3423                 if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
3424                     continue;
3425 
3426                 fieldName = rtl::OUStringToOString(
3427                     aSuperReader.getFieldName(i), RTL_TEXTENCODING_UTF8);
3428                 fieldType = rtl::OUStringToOString(
3429                     aSuperReader.getFieldTypeName(i), RTL_TEXTENCODING_UTF8);
3430 
3431                 if (hasMember)
3432                 {
3433                     o << ", ";
3434                 } else
3435                 {
3436                     hasMember = (fieldCount > 0);
3437                 }
3438 
3439                 if (bWithType)
3440                 {
3441                     dumpType(o, fieldType, sal_True, sal_True);
3442                     o << " ";
3443                 }
3444 //              o << "__" << fieldName;
3445                 o << fieldName << "_";
3446             }
3447         }
3448     }
3449 
3450     return hasMember;
3451 }
3452 
3453 //*************************************************************************
3454 // EnumType
3455 //*************************************************************************
EnumType(typereg::Reader & typeReader,const OString & typeName,const TypeManager & typeMgr)3456 EnumType::EnumType(typereg::Reader& typeReader,
3457                    const OString& typeName,
3458                    const TypeManager& typeMgr)
3459     : CppuType(typeReader, typeName, typeMgr)
3460 {
3461 }
3462 
~EnumType()3463 EnumType::~EnumType()
3464 {
3465 
3466 }
3467 
dumpHFile(FileStream & o,codemaker::cppumaker::Includes & includes)3468 sal_Bool EnumType::dumpHFile(
3469     FileStream& o, codemaker::cppumaker::Includes & includes)
3470     throw( CannotDumpException )
3471 {
3472     OString headerDefine(dumpHeaderDefine(o, "HDL"));
3473     o << "\n";
3474 
3475     addDefaultHIncludes(includes);
3476     includes.dump(o, 0);
3477     o << "\n";
3478 
3479     if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) {
3480         o << "\n";
3481     }
3482 
3483     dumpDeclaration(o);
3484 
3485     if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) {
3486         o << "\n";
3487     }
3488 
3489     o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n"
3490       << "class Type;\n} } } }\n\n";
3491 
3492     o << "inline const ::com::sun::star::uno::Type& SAL_CALL getCppuType( ";
3493     dumpType(o, m_typeName, sal_True, sal_False);
3494     o << "* ) SAL_THROW( () );\n\n";
3495 
3496     o << "#endif // "<< headerDefine << "\n";
3497 
3498     return sal_True;
3499 }
3500 
dumpDeclaration(FileStream & o)3501 sal_Bool EnumType::dumpDeclaration(FileStream& o)
3502     throw( CannotDumpException )
3503 {
3504     o << "\nenum " << m_name << "\n{\n";
3505     inc();
3506 
3507     sal_uInt16      fieldCount = m_reader.getFieldCount();
3508     RTFieldAccess   access = RT_ACCESS_INVALID;
3509     RTConstValue    constValue;
3510     OString         fieldName;
3511     sal_Int32       value=0;
3512     for (sal_uInt16 i=0; i < fieldCount; i++)
3513     {
3514         access = m_reader.getFieldFlags(i);
3515 
3516         if (access != RT_ACCESS_CONST)
3517             continue;
3518 
3519         fieldName = rtl::OUStringToOString(
3520             m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8);
3521         constValue = m_reader.getFieldValue(i);
3522 
3523         if (constValue.m_type == RT_TYPE_INT32)
3524             value = constValue.m_value.aLong;
3525         else
3526             value++;
3527 
3528         o << indent() << m_name << "_" << fieldName << " = " << value << ",\n";
3529     }
3530 
3531     o << indent() << m_name << "_MAKE_FIXED_SIZE = SAL_MAX_ENUM\n";
3532 
3533     dec();
3534     o << "};\n\n";
3535 
3536     return sal_True;
3537 }
3538 
dumpHxxFile(FileStream & o,codemaker::cppumaker::Includes & includes)3539 sal_Bool EnumType::dumpHxxFile(
3540     FileStream& o, codemaker::cppumaker::Includes & includes)
3541     throw( CannotDumpException )
3542 {
3543     OString headerDefine(dumpHeaderDefine(o, "HPP"));
3544     o << "\n";
3545 
3546     addDefaultHxxIncludes(includes);
3547     includes.dump(o, &m_typeName);
3548     o << "\n";
3549 
3550     dumpGetCppuType(o);
3551 
3552     o << "\n#endif // "<< headerDefine << "\n";
3553     return sal_True;
3554 }
3555 
dumpNormalGetCppuType(FileStream & o)3556 void EnumType::dumpNormalGetCppuType(FileStream& o)
3557 {
3558     dumpGetCppuTypePreamble(o);
3559 
3560     o << indent()
3561       << "static typelib_TypeDescriptionReference * the_type = 0;\n";
3562 
3563     o << indent() << "if ( !the_type )\n" << indent() << "{\n";
3564     inc();
3565 
3566     o << indent() << "typelib_static_enum_type_init( &the_type,\n";
3567     inc(31);
3568     o << indent() << "\"" << m_typeName.replace('/', '.') << "\",\n"
3569       << indent() << scopedCppName(m_typeName) << "_"
3570       << rtl::OUStringToOString(m_reader.getFieldName(0), RTL_TEXTENCODING_UTF8)
3571       << " );\n";
3572     dec(31);
3573     dec();
3574     o << indent() << "}\n";
3575     o << indent()
3576       << ("return * reinterpret_cast< ::com::sun::star::uno::Type * >("
3577           " &the_type );\n");
3578     dumpGetCppuTypePostamble(o);
3579 }
3580 
dumpComprehensiveGetCppuType(FileStream & o)3581 void EnumType::dumpComprehensiveGetCppuType(FileStream& o)
3582 {
3583     dumpGetCppuTypePreamble(o);
3584 
3585     o << indent() << "static ::com::sun::star::uno::Type * the_pType = 0;\n";
3586 
3587     o << indent() << "if (the_pType == 0)\n" << indent() << "{\n";
3588     inc();
3589     o << indent() << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n";
3590 
3591     o << indent() << "if (the_pType == 0)\n" << indent() << "{\n";
3592     inc();
3593     o << indent() << "::rtl::OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM(\""
3594       << m_typeName.replace('/', '.') << "\") );\n\n";
3595 
3596     o << indent() << "// Start inline typedescription generation\n"
3597       << indent() << "typelib_TypeDescription * pTD = 0;\n\n";
3598 
3599     sal_uInt16 count = m_reader.getFieldCount();
3600     o << indent() << "rtl_uString* enumValueNames[" << count << "];\n";
3601     sal_uInt16 i;
3602     for (i = 0; i < count; i++)
3603     {
3604         o << indent() << "::rtl::OUString sEnumValue" << i
3605           << "( RTL_CONSTASCII_USTRINGPARAM(\""
3606           << rtl::OUStringToOString(
3607               m_reader.getFieldName(i), RTL_TEXTENCODING_UTF8)
3608           << "\") );\n";
3609         o << indent() << "enumValueNames[" << i << "] = sEnumValue" << i
3610           << ".pData;\n";
3611     }
3612 
3613     o << "\n" << indent() << "sal_Int32 enumValues[" << count << "];\n";
3614     RTConstValue    constValue;
3615     sal_Int32       value=0;
3616     for (i = 0; i < count; i++)
3617     {
3618         o << indent() << "enumValues[" << i << "] = ";
3619         constValue = m_reader.getFieldValue(i);
3620         if (constValue.m_type == RT_TYPE_INT32)
3621             value = constValue.m_value.aLong;
3622         else
3623             value++;
3624         o << value << ";\n";
3625     }
3626 
3627     o << "\n" << indent() << "typelib_typedescription_newEnum( &pTD,\n";
3628     inc();
3629     o << indent() << "sTypeName.pData,\n"
3630       << indent() << "(sal_Int32)" << scopedCppName(m_typeName, sal_False)
3631       << "_"
3632       << rtl::OUStringToOString(m_reader.getFieldName(0), RTL_TEXTENCODING_UTF8)
3633       << ",\n"
3634       << indent() << count << ", enumValueNames, enumValues );\n\n";
3635     dec();
3636 
3637     o << indent()
3638       << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
3639           " );\n");
3640     o << indent() << "typelib_typedescription_release( pTD );\n"
3641       << indent() << "// End inline typedescription generation\n\n";
3642 
3643     o << indent() << "static ::com::sun::star::uno::Type the_staticType( "
3644       << getTypeClass(m_typeName) << ", sTypeName );\n";
3645     o << indent() << "the_pType = &the_staticType;\n";
3646 
3647     dec();
3648     o << indent() << "}\n";
3649     dec();
3650     o << indent() << "}\n\n"
3651       << indent() << "return *the_pType;\n";
3652 
3653     dumpGetCppuTypePostamble(o);
3654 }
3655 
3656 //*************************************************************************
3657 // TypeDefType
3658 //*************************************************************************
TypeDefType(typereg::Reader & typeReader,const OString & typeName,const TypeManager & typeMgr)3659 TypeDefType::TypeDefType(typereg::Reader& typeReader,
3660                          const OString& typeName,
3661                          const TypeManager& typeMgr)
3662     : CppuType(typeReader, typeName, typeMgr)
3663 {
3664 }
3665 
~TypeDefType()3666 TypeDefType::~TypeDefType()
3667 {
3668 
3669 }
3670 
dumpHFile(FileStream & o,codemaker::cppumaker::Includes & includes)3671 sal_Bool TypeDefType::dumpHFile(
3672     FileStream& o, codemaker::cppumaker::Includes & includes)
3673     throw( CannotDumpException )
3674 {
3675     OString headerDefine(dumpHeaderDefine(o, "HDL"));
3676     o << "\n";
3677 
3678     addDefaultHIncludes(includes);
3679     includes.dump(o, 0);
3680     o << "\n";
3681 
3682     if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) {
3683         o << "\n";
3684     }
3685 
3686     dumpDeclaration(o);
3687 
3688     if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) {
3689         o << "\n";
3690     }
3691 
3692 //  o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n"
3693 //    << "class Type;\n} } } }\n\n";
3694 //  o << "inline const ::com::sun::star::uno::Type& SAL_CALL get_" << m_typeName.replace('/', '_')
3695 //    <<  "_Type( ) SAL_THROW( () );\n\n";
3696 
3697     o << "#endif // "<< headerDefine << "\n";
3698 
3699     return sal_True;
3700 }
3701 
dumpDeclaration(FileStream & o)3702 sal_Bool TypeDefType::dumpDeclaration(FileStream& o)
3703     throw( CannotDumpException )
3704 {
3705     o << "\ntypedef ";
3706     dumpType(
3707         o,
3708         rtl::OUStringToOString(
3709             m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8));
3710     o << " " << m_name << ";\n\n";
3711 
3712     return sal_True;
3713 }
3714 
dumpHxxFile(FileStream & o,codemaker::cppumaker::Includes & includes)3715 sal_Bool TypeDefType::dumpHxxFile(
3716     FileStream& o, codemaker::cppumaker::Includes & includes)
3717     throw( CannotDumpException )
3718 {
3719     OString headerDefine(dumpHeaderDefine(o, "HPP"));
3720     o << "\n";
3721 
3722     addDefaultHxxIncludes(includes);
3723     includes.dump(o, &m_typeName);
3724     o << "\n";
3725 
3726     o << "\n#endif // "<< headerDefine << "\n";
3727     return sal_True;
3728 }
3729 
3730 //*************************************************************************
3731 // ConstructiveType
3732 //*************************************************************************
3733 
dumpHFile(FileStream &,codemaker::cppumaker::Includes &)3734 sal_Bool ConstructiveType::dumpHFile(
3735     FileStream &, codemaker::cppumaker::Includes &) throw (CannotDumpException)
3736 {
3737     OSL_ASSERT(false);
3738     return false;
3739 }
3740 
dumpFiles(CppuOptions * options,rtl::OString const & outPath)3741 bool ConstructiveType::dumpFiles(
3742     CppuOptions * options, rtl::OString const & outPath)
3743 {
3744     return dumpFile(options, ".hpp", m_typeName, outPath);
3745 }
3746 
3747 //*************************************************************************
3748 // ServiceType
3749 //*************************************************************************
3750 
3751 namespace {
3752 
includeExceptions(codemaker::cppumaker::Includes & includes,codemaker::ExceptionTreeNode const * node)3753 void includeExceptions(
3754     codemaker::cppumaker::Includes & includes,
3755     codemaker::ExceptionTreeNode const * node)
3756 {
3757     if (node->present) {
3758         includes.add(node->name);
3759     } else {
3760         for (codemaker::ExceptionTreeNode::Children::const_iterator i(
3761                  node->children.begin());
3762              i != node->children.end(); ++i)
3763         {
3764             includeExceptions(includes, *i);
3765         }
3766     }
3767 }
3768 
3769 }
3770 
isSingleInterfaceBased()3771 bool ServiceType::isSingleInterfaceBased() {
3772     return m_reader.getSuperTypeCount() == 1;
3773 }
3774 
dumpHxxFile(FileStream & o,codemaker::cppumaker::Includes & includes)3775 sal_Bool ServiceType::dumpHxxFile(
3776     FileStream & o, codemaker::cppumaker::Includes & includes)
3777     throw (CannotDumpException)
3778 {
3779     sal_uInt16 ctors = m_reader.getMethodCount();
3780     if (ctors > 0) {
3781         //TODO: Decide whether the types added to includes should rather be
3782         // added to m_dependencies (and thus be generated during
3783         // dumpDependedTypes):
3784         includes.addReference();
3785         includes.addRtlUstringH();
3786         includes.addRtlUstringHxx();
3787         includes.add("com/sun/star/lang/XMultiComponentFactory");
3788         includes.add("com/sun/star/uno/DeploymentException");
3789         includes.add("com/sun/star/uno/XComponentContext");
3790         for (sal_uInt16 i = 0; i < ctors; ++i) {
3791             if (isDefaultConstructor(i)) {
3792                 includes.add("com/sun/star/uno/Exception");
3793                 includes.add("com/sun/star/uno/RuntimeException");
3794             } else {
3795                 if (!hasRestParameter(i)) {
3796                     includes.addAny();
3797                     includes.addSequence();
3798                     sal_uInt16 params = m_reader.getMethodParameterCount(i);
3799                     for (sal_uInt16 j = 0; j < params; ++j) {
3800                         if (codemaker::UnoType::getSort(
3801                                 codemaker::UnoType::decompose(
3802                                     rtl::OUStringToOString(
3803                                         m_reader.getMethodParameterTypeName(
3804                                             i, j),
3805                                         RTL_TEXTENCODING_UTF8),
3806                                     0, 0))
3807                             == codemaker::UnoType::SORT_CHAR)
3808                         {
3809                             includes.addCppuUnotypeHxx();
3810                             break;
3811                         }
3812                     }
3813                 }
3814                 codemaker::ExceptionTree tree;
3815                 for (sal_uInt16 j = 0; j < m_reader.getMethodExceptionCount(i);
3816                      ++j)
3817                 {
3818                     tree.add(
3819                         rtl::OUStringToOString(
3820                             m_reader.getMethodExceptionTypeName(i, j),
3821                             RTL_TEXTENCODING_UTF8),
3822                         m_typeMgr);
3823                 }
3824                 if (!tree.getRoot()->present) {
3825                     includes.add("com/sun/star/uno/Exception");
3826                     includes.add("com/sun/star/uno/RuntimeException");
3827                     includeExceptions(includes, tree.getRoot());
3828                 }
3829             }
3830         }
3831     }
3832     rtl::OString cppName(translateUnoToCppIdentifier(
3833                              m_name, "service", isGlobal()));
3834     rtl::OString headerDefine(dumpHeaderDefine(o, "HPP"));
3835     o << "\n";
3836     includes.dump(o, 0);
3837     o << "\n";
3838     if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) {
3839         o << "\n";
3840     }
3841     o << "\nclass " << cppName << " {\n";
3842     inc();
3843     if (ctors > 0) {
3844         rtl::OString fullName(m_typeName.replace('/', '.'));
3845         rtl::OString baseName(
3846             rtl::OUStringToOString(
3847                 m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8));
3848         rtl::OString fullBaseName(baseName.replace('/', '.'));
3849         rtl::OString scopedBaseName(scopedCppName(baseName));
3850         o << "public:\n";
3851         for (sal_uInt16 i = 0; i < ctors; ++i) {
3852             if (isDefaultConstructor(i)) {
3853                 o << indent() << "static ::com::sun::star::uno::Reference< "
3854                   << scopedBaseName << " > "
3855                   << translateUnoToCppIdentifier(
3856                       "create", "method", ITM_NONGLOBAL, &cppName)
3857                   << ("(::com::sun::star::uno::Reference<"
3858                       " ::com::sun::star::uno::XComponentContext > const &"
3859                       " the_context) {\n");
3860                 inc();
3861                 o << indent()
3862                   << ("::com::sun::star::uno::Reference<"
3863                       " ::com::sun::star::lang::XMultiComponentFactory >"
3864                       " the_factory(the_context->getServiceManager());\n")
3865                   << indent() << "if (!the_factory.is()) {\n";
3866                 inc();
3867                 o << indent()
3868                   << ("throw ::com::sun::star::uno::DeploymentException("
3869                       "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"component"
3870                       " context fails to supply service manager\")),"
3871                       " the_context);\n");
3872                 dec();
3873                 o << indent() << "}\n" << indent()
3874                   << "::com::sun::star::uno::Reference< " << scopedBaseName
3875                   << " > the_instance;\n" << indent() << "try {\n";
3876                 inc();
3877                 o << indent()
3878                   << "the_instance = ::com::sun::star::uno::Reference< "
3879                   << scopedBaseName
3880                   << (" >(the_factory->createInstanceWithContext("
3881                       "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"")
3882                   << fullName
3883                   << "\")), the_context), ::com::sun::star::uno::UNO_QUERY);\n";
3884                 dec();
3885                 o << indent()
3886                   << "} catch (::com::sun::star::uno::RuntimeException &) {\n";
3887                 inc();
3888                 o << indent() << "throw;\n";
3889                 dec();
3890                 o << indent()
3891                   << ("} catch (::com::sun::star::uno::Exception &"
3892                       " the_exception) {\n");
3893                 inc();
3894                 o << indent()
3895                   << ("throw ::com::sun::star::uno::DeploymentException("
3896                       "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("
3897                       "\"component context fails to supply service ")
3898                   << fullName << " of type " << fullBaseName
3899                   << ": \")) + the_exception.Message, the_context);\n";
3900                 dec();
3901                 o << indent() << "}\n" << indent()
3902                   << "if (!the_instance.is()) {\n";
3903                 inc();
3904                 o << indent()
3905                   << ("throw ::com::sun::star::uno::DeploymentException("
3906                       "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("
3907                       "\"component context fails to supply service ")
3908                   << fullName << " of type " << fullBaseName
3909                   << "\")), the_context);\n";
3910                 dec();
3911                 o << indent() << "}\n" << indent() << "return the_instance;\n";
3912                 dec();
3913                 o << indent() << "}\n\n";
3914             } else {
3915                 o << indent() << "static ::com::sun::star::uno::Reference< "
3916                   << scopedBaseName << " > "
3917                   << translateUnoToCppIdentifier(
3918                       rtl::OUStringToOString(
3919                           m_reader.getMethodName(i), RTL_TEXTENCODING_UTF8),
3920                       "method", ITM_NONGLOBAL, &cppName)
3921                   << ("(::com::sun::star::uno::Reference<"
3922                       " ::com::sun::star::uno::XComponentContext > const &"
3923                       " the_context");
3924                 sal_uInt16 params = m_reader.getMethodParameterCount(i);
3925                 bool rest = hasRestParameter(i);
3926                 for (sal_uInt16 j = 0; j < params; ++j) {
3927                     o << ", ";
3928                     rtl::OStringBuffer buf;
3929                     if ((m_reader.getMethodParameterFlags(i, j) & RT_PARAM_REST)
3930                         != 0)
3931                     {
3932                         buf.append(RTL_CONSTASCII_STRINGPARAM("[]"));
3933                     }
3934                     buf.append(
3935                         rtl::OUStringToOString(
3936                             m_reader.getMethodParameterTypeName(i, j),
3937                             RTL_TEXTENCODING_UTF8));
3938                     rtl::OString type(buf.makeStringAndClear());
3939                     bool byRef = passByReference(type);
3940                     dumpType(o, type, byRef, byRef);
3941                     o << " "
3942                       << translateUnoToCppIdentifier(
3943                           rtl::OUStringToOString(
3944                               m_reader.getMethodParameterName(i, j),
3945                               RTL_TEXTENCODING_UTF8),
3946                           "param", ITM_NONGLOBAL);
3947                 }
3948                 o << ") {\n";
3949                 inc();
3950                 o << indent()
3951                   << ("::com::sun::star::uno::Reference<"
3952                       " ::com::sun::star::lang::XMultiComponentFactory >"
3953                       " the_factory(the_context->getServiceManager());\n")
3954                   << indent() << "if (!the_factory.is()) {\n";
3955                 inc();
3956                 o << indent()
3957                   << ("throw com::sun::star::uno::DeploymentException("
3958                       "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("
3959                       "\"component context fails to supply service manager\")),"
3960                       " the_context);\n");
3961                 dec();
3962                 o << indent() << "}\n";
3963                 if (!rest && params > 0) {
3964                     o << indent()
3965                       << ("::com::sun::star::uno::Sequence<"
3966                           " ::com::sun::star::uno::Any > the_arguments(")
3967                       << params << ");\n";
3968                     for (sal_uInt16 j = 0; j < params; ++j) {
3969                         o << indent() << "the_arguments[" << j << "] ";
3970                         rtl::OString param(
3971                             translateUnoToCppIdentifier(
3972                                 rtl::OUStringToOString(
3973                                     m_reader.getMethodParameterName(i, j),
3974                                     RTL_TEXTENCODING_UTF8),
3975                                 "param", ITM_NONGLOBAL));
3976                         sal_Int32 rank;
3977                         if (codemaker::UnoType::getSort(
3978                                 codemaker::UnoType::decompose(
3979                                     rtl::OUStringToOString(
3980                                         m_reader.getMethodParameterTypeName(
3981                                             i, j),
3982                                         RTL_TEXTENCODING_UTF8),
3983                                     &rank, 0))
3984                             == codemaker::UnoType::SORT_CHAR)
3985                         {
3986                             o << "= ::com::sun::star::uno::Any(&" << param
3987                               << ", ::cppu::UnoType< ";
3988                             for (sal_Int32 k = 0; k < rank; ++k) {
3989                                 o << "::cppu::UnoSequenceType< ";
3990                             }
3991                             o << "::cppu::UnoCharType";
3992                             for (sal_Int32 k = 0; k < rank; ++k) {
3993                                 o << " >";
3994                             }
3995                             o << " >::get())";
3996                         } else {
3997                             o << "<<= " << param;
3998                         }
3999                         o << ";\n";
4000                     }
4001                 }
4002                 o << indent() << "::com::sun::star::uno::Reference< "
4003                   << scopedBaseName << " > the_instance;\n";
4004                 codemaker::ExceptionTree tree;
4005                 sal_uInt16 exceptions = m_reader.getMethodExceptionCount(i);
4006                 for (sal_uInt16 j = 0; j < exceptions; ++j) {
4007                     tree.add(
4008                         rtl::OUStringToOString(
4009                             m_reader.getMethodExceptionTypeName(i, j),
4010                             RTL_TEXTENCODING_UTF8),
4011                         m_typeMgr);
4012                 }
4013                 if (!tree.getRoot()->present) {
4014                     o << indent() << "try {\n";
4015                     inc();
4016                 }
4017                 o << indent()
4018                   << "the_instance = ::com::sun::star::uno::Reference< "
4019                   << scopedBaseName
4020                   << (" >(the_factory->createInstanceWithArgumentsAndContext("
4021                       "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"")
4022                   << fullName << "\")), ";
4023                 if (rest) {
4024                     o << translateUnoToCppIdentifier(
4025                         rtl::OUStringToOString(
4026                             m_reader.getMethodParameterName(i, 0),
4027                             RTL_TEXTENCODING_UTF8),
4028                         "param", ITM_NONGLOBAL);
4029                 } else if (params == 0) {
4030                     o << ("::com::sun::star::uno::Sequence<"
4031                           " ::com::sun::star::uno::Any >()");
4032                 } else {
4033                     o << "the_arguments";
4034                 }
4035                 o << ", the_context), ::com::sun::star::uno::UNO_QUERY);\n";
4036                 if (!tree.getRoot()->present) {
4037                     dec();
4038                     o << indent()
4039                       << ("} catch (::com::sun::star::uno::RuntimeException &)"
4040                           " {\n");
4041                     inc();
4042                     o << indent() << "throw;\n";
4043                     dec();
4044                     dumpCatchClauses(o, tree.getRoot());
4045                     o << indent()
4046                       << ("} catch (::com::sun::star::uno::Exception &"
4047                           " the_exception) {\n");
4048                     inc();
4049                     o << indent()
4050                       << ("throw ::com::sun::star::uno::DeploymentException("
4051                           "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("
4052                           "\"component context fails to supply service ")
4053                       << fullName << " of type " << fullBaseName
4054                       << ": \")) + the_exception.Message, the_context);\n";
4055                     dec();
4056                     o << indent() << "}\n";
4057                 }
4058                 o << indent() << "if (!the_instance.is()) {\n";
4059                 inc();
4060                 o << indent()
4061                   << ("throw ::com::sun::star::uno::DeploymentException("
4062                       "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("
4063                       "\"component context fails to supply service ")
4064                   << fullName << " of type " << fullBaseName
4065                   << "\")), the_context);\n";
4066                 dec();
4067                 o << indent() << "}\n" << indent() << "return the_instance;\n";
4068                 dec();
4069                 o << indent() << "}\n\n";
4070             }
4071         }
4072     }
4073     o << "private:\n";
4074     o << indent() << cppName << "(); // not implemented\n"
4075       << indent() << cppName << "(" << cppName << " &); // not implemented\n"
4076       << indent() << "~" << cppName << "(); // not implemented\n"
4077       << indent() << "void operator =(" << cppName << "); // not implemented\n";
4078     dec();
4079     o << "};\n\n";
4080     if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) {
4081         o << "\n";
4082     }
4083     o << "\n#endif // "<< headerDefine << "\n";
4084     return true;
4085 }
4086 
addSpecialDependencies()4087 void ServiceType::addSpecialDependencies() {
4088     if (m_reader.getMethodCount() > 0) {
4089         OSL_ASSERT(m_reader.getSuperTypeCount() == 1);
4090         m_dependencies.add(
4091             rtl::OUStringToOString(
4092                 m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8));
4093     }
4094 }
4095 
isDefaultConstructor(sal_uInt16 ctorIndex) const4096 bool ServiceType::isDefaultConstructor(sal_uInt16 ctorIndex) const {
4097     return m_reader.getMethodName(ctorIndex).isEmpty();
4098 }
4099 
hasRestParameter(sal_uInt16 ctorIndex) const4100 bool ServiceType::hasRestParameter(sal_uInt16 ctorIndex) const {
4101     return m_reader.getMethodParameterCount(ctorIndex) == 1
4102         && ((m_reader.getMethodParameterFlags(ctorIndex, 0) & RT_PARAM_REST)
4103             != 0);
4104 }
4105 
dumpCatchClauses(FileStream & out,codemaker::ExceptionTreeNode const * node)4106 void ServiceType::dumpCatchClauses(
4107     FileStream & out, codemaker::ExceptionTreeNode const * node)
4108 {
4109     if (node->present) {
4110         out << indent() << "} catch (";
4111         dumpType(out, node->name);
4112         out << " &) {\n";
4113         inc();
4114         out << indent() << "throw;\n";
4115         dec();
4116     } else {
4117         for (codemaker::ExceptionTreeNode::Children::const_iterator i(
4118                  node->children.begin());
4119              i != node->children.end(); ++i)
4120         {
4121             dumpCatchClauses(out, *i);
4122         }
4123     }
4124 }
4125 
4126 //*************************************************************************
4127 // SingletonType
4128 //*************************************************************************
4129 
isInterfaceBased()4130 bool SingletonType::isInterfaceBased() {
4131     return (m_typeMgr.getTypeClass(
4132                 rtl::OUStringToOString(
4133                     m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8)))
4134         == RT_TYPE_INTERFACE;
4135 }
4136 
dumpHxxFile(FileStream & o,codemaker::cppumaker::Includes & includes)4137 sal_Bool SingletonType::dumpHxxFile(
4138     FileStream & o, codemaker::cppumaker::Includes & includes)
4139     throw (CannotDumpException)
4140 {
4141     rtl::OString cppName(translateUnoToCppIdentifier(
4142                              m_name, "singleton", isGlobal()));
4143     rtl::OString fullName(m_typeName.replace('/', '.'));
4144     rtl::OString baseName(
4145         rtl::OUStringToOString(
4146             m_reader.getSuperTypeName(0), RTL_TEXTENCODING_UTF8));
4147     rtl::OString fullBaseName(baseName.replace('/', '.'));
4148     rtl::OString scopedBaseName(scopedCppName(baseName));
4149     rtl::OString headerDefine(dumpHeaderDefine(o, "HPP"));
4150     o << "\n";
4151     //TODO: Decide whether the types added to includes should rather be added to
4152     // m_dependencies (and thus be generated during dumpDependedTypes):
4153     includes.add("com/sun/star/uno/DeploymentException");
4154     includes.add("com/sun/star/uno/XComponentContext");
4155     includes.addAny();
4156     includes.addReference();
4157     includes.addRtlUstringH();
4158     includes.addRtlUstringHxx();
4159     includes.dump(o, 0);
4160     o << "\n";
4161     if (codemaker::cppumaker::dumpNamespaceOpen(o, m_typeName, false)) {
4162         o << "\n";
4163     }
4164     o << "\nclass " << cppName << " {\npublic:\n";
4165     inc();
4166     o << indent() << "static ::com::sun::star::uno::Reference< "
4167       << scopedBaseName << " > "
4168       << translateUnoToCppIdentifier("get", "method", ITM_NONGLOBAL, &cppName)
4169       << ("(::com::sun::star::uno::Reference<"
4170           " ::com::sun::star::uno::XComponentContext > const & context) {\n");
4171     inc();
4172     o << indent() << "::com::sun::star::uno::Reference< " << scopedBaseName
4173       << " > instance;\n" << indent()
4174       << ("if (!(context->getValueByName("
4175           "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"/singletons/")
4176       << fullName << "\"))) >>= instance) || !instance.is()) {\n";
4177     inc();
4178     o << indent()
4179       << ("throw ::com::sun::star::uno::DeploymentException("
4180           "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"component context"
4181           " fails to supply singleton ")
4182       << fullName << " of type " << fullBaseName << "\")), context);\n";
4183     dec();
4184     o << indent() << "}\n" << indent() << "return instance;\n";
4185     dec();
4186     o << indent() << "}\n\n";
4187     o << "private:\n";
4188     o << indent() << cppName << "(); // not implemented\n"
4189       << indent() << cppName << "(" << cppName << " &); // not implemented\n"
4190       << indent() << "~" << cppName << "(); // not implemented\n"
4191       << indent() << "void operator =(" << cppName << "); // not implemented\n";
4192     dec();
4193     o << "};\n\n";
4194     if (codemaker::cppumaker::dumpNamespaceClose(o, m_typeName, false)) {
4195         o << "\n";
4196     }
4197     o << "\n#endif // "<< headerDefine << "\n";
4198     return true;
4199 }
4200 
4201 //*************************************************************************
4202 // produceType
4203 //*************************************************************************
produceType(const OString & typeName,TypeManager const & typeMgr,codemaker::GeneratedTypeSet & generated,CppuOptions * pOptions)4204 bool produceType(const OString& typeName,
4205                  TypeManager const & typeMgr,
4206                  codemaker::GeneratedTypeSet & generated,
4207                  CppuOptions* pOptions)
4208     throw( CannotDumpException )
4209 {
4210     if (typeName.equals("/") || typeName.equals(typeMgr.getBase()) ||
4211         TypeManager::isBaseType(typeName) || generated.contains(typeName))
4212     {
4213         return true;
4214     }
4215 
4216     sal_Bool bIsExtraType = sal_False;
4217     typereg::Reader reader(typeMgr.getTypeReader(typeName, &bIsExtraType));
4218     if (bIsExtraType) {
4219         generated.add(typeName);
4220         return true;
4221     }
4222 
4223     if (!reader.isValid()) {
4224         return false;
4225     }
4226 
4227     RTTypeClass typeClass = reader.getTypeClass();
4228     bool ret = false;
4229     switch (typeClass)
4230     {
4231         case RT_TYPE_INTERFACE:
4232             {
4233                 InterfaceType iType(reader, typeName, typeMgr);
4234                 ret = iType.dump(pOptions);
4235                 if (ret) generated.add(typeName);
4236                 iType.dumpDependedTypes(generated, pOptions);
4237             }
4238             break;
4239         case RT_TYPE_MODULE:
4240             {
4241                 ModuleType mType(reader, typeName, typeMgr);
4242                 if (mType.hasConstants())
4243                 {
4244                     ret = mType.dump(pOptions);
4245                     if (ret) generated.add(typeName);
4246                 } else
4247                 {
4248                     generated.add(typeName);
4249                     ret = true;
4250                 }
4251             }
4252             break;
4253         case RT_TYPE_STRUCT:
4254             {
4255                 StructureType sType(reader, typeName, typeMgr);
4256                 ret = sType.dump(pOptions);
4257                 if (ret) generated.add(typeName);
4258                 sType.dumpDependedTypes(generated, pOptions);
4259             }
4260             break;
4261         case RT_TYPE_ENUM:
4262             {
4263                 EnumType enType(reader, typeName, typeMgr);
4264                 ret = enType.dump(pOptions);
4265                 if (ret) generated.add(typeName);
4266                 enType.dumpDependedTypes(generated, pOptions);
4267             }
4268             break;
4269         case RT_TYPE_EXCEPTION:
4270             {
4271                 ExceptionType eType(reader, typeName, typeMgr);
4272                 ret = eType.dump(pOptions);
4273                 if (ret) generated.add(typeName);
4274                 eType.dumpDependedTypes(generated, pOptions);
4275             }
4276             break;
4277         case RT_TYPE_TYPEDEF:
4278             {
4279                 TypeDefType tdType(reader, typeName, typeMgr);
4280                 ret = tdType.dump(pOptions);
4281                 if (ret) generated.add(typeName);
4282                 tdType.dumpDependedTypes(generated, pOptions);
4283             }
4284             break;
4285         case RT_TYPE_CONSTANTS:
4286             {
4287                 ConstantsType cType(reader, typeName, typeMgr);
4288                 if (cType.hasConstants())
4289                 {
4290                     ret = cType.dump(pOptions);
4291                     if (ret) generated.add(typeName);
4292                 } else
4293                 {
4294                     generated.add(typeName);
4295                     ret = true;
4296                 }
4297             }
4298             break;
4299         case RT_TYPE_SERVICE:
4300             {
4301                 ServiceType t(reader, typeName, typeMgr);
4302                 if (t.isSingleInterfaceBased()) {
4303                     ret = t.dump(pOptions);
4304                     if (ret) {
4305                         generated.add(typeName);
4306                         t.dumpDependedTypes(generated, pOptions);
4307                     }
4308                 } else {
4309                     ret = true;
4310                 }
4311             }
4312             break;
4313         case RT_TYPE_SINGLETON:
4314             {
4315                 SingletonType t(reader, typeName, typeMgr);
4316                 if (t.isInterfaceBased()) {
4317                     ret = t.dump(pOptions);
4318                     if (ret) {
4319                         generated.add(typeName);
4320                         t.dumpDependedTypes(generated, pOptions);
4321                     }
4322                 } else {
4323                     ret = true;
4324                 }
4325             }
4326             break;
4327         case RT_TYPE_OBJECT:
4328             ret = true;
4329             break;
4330         default:
4331             OSL_ASSERT(false);
4332             break;
4333     }
4334 
4335     return ret;
4336 }
4337 
produceType(RegistryKey & rTypeKey,bool bIsExtraType,TypeManager const & typeMgr,codemaker::GeneratedTypeSet & generated,CppuOptions * pOptions)4338 bool produceType(RegistryKey& rTypeKey, bool bIsExtraType,
4339                      TypeManager const & typeMgr,
4340                      codemaker::GeneratedTypeSet & generated,
4341                      CppuOptions* pOptions)
4342     throw( CannotDumpException )
4343 {
4344     OString typeName = typeMgr.getTypeName(rTypeKey);
4345 
4346     if (typeName.equals("/") ||typeName.equals(typeMgr.getBase()) ||
4347         TypeManager::isBaseType(typeName) || generated.contains(typeName))
4348     {
4349         return true;
4350     }
4351 
4352     if (bIsExtraType) {
4353         generated.add(typeName);
4354         return true;
4355     }
4356 
4357     typereg::Reader reader(typeMgr.getTypeReader(rTypeKey));
4358     if (!reader.isValid()) {
4359         return false;
4360     }
4361 
4362     RTTypeClass typeClass = reader.getTypeClass();
4363     bool ret = false;
4364     switch (typeClass)
4365     {
4366         case RT_TYPE_INTERFACE:
4367             {
4368                 InterfaceType iType(reader, typeName, typeMgr);
4369                 ret = iType.dump(pOptions);
4370                 if (ret) generated.add(typeName);
4371                 iType.dumpDependedTypes(generated, pOptions);
4372             }
4373             break;
4374         case RT_TYPE_MODULE:
4375             {
4376                 ModuleType mType(reader, typeName, typeMgr);
4377                 if (mType.hasConstants())
4378                 {
4379                     ret = mType.dump(pOptions);
4380                     if (ret) generated.add(typeName);
4381                 } else
4382                 {
4383                     generated.add(typeName);
4384                     ret = true;
4385                 }
4386             }
4387             break;
4388         case RT_TYPE_STRUCT:
4389             {
4390                 StructureType sType(reader, typeName, typeMgr);
4391                 ret = sType.dump(pOptions);
4392                 if (ret) generated.add(typeName);
4393                 sType.dumpDependedTypes(generated, pOptions);
4394             }
4395             break;
4396         case RT_TYPE_ENUM:
4397             {
4398                 EnumType enType(reader, typeName, typeMgr);
4399                 ret = enType.dump(pOptions);
4400                 if (ret) generated.add(typeName);
4401                 enType.dumpDependedTypes(generated, pOptions);
4402             }
4403             break;
4404         case RT_TYPE_EXCEPTION:
4405             {
4406                 ExceptionType eType(reader, typeName, typeMgr);
4407                 ret = eType.dump(pOptions);
4408                 if (ret) generated.add(typeName);
4409                 eType.dumpDependedTypes(generated, pOptions);
4410             }
4411             break;
4412         case RT_TYPE_TYPEDEF:
4413             {
4414                 TypeDefType tdType(reader, typeName, typeMgr);
4415                 ret = tdType.dump(pOptions);
4416                 if (ret) generated.add(typeName);
4417                 tdType.dumpDependedTypes(generated, pOptions);
4418             }
4419             break;
4420         case RT_TYPE_CONSTANTS:
4421             {
4422                 ConstantsType cType(reader, typeName, typeMgr);
4423                 if (cType.hasConstants())
4424                 {
4425                     ret = cType.dump(pOptions);
4426                     if (ret) generated.add(typeName);
4427                 } else
4428                 {
4429                     generated.add(typeName);
4430                     ret = true;
4431                 }
4432             }
4433             break;
4434         case RT_TYPE_SERVICE:
4435             {
4436                 ServiceType t(reader, typeName, typeMgr);
4437                 if (t.isSingleInterfaceBased()) {
4438                     ret = t.dump(pOptions);
4439                     if (ret) {
4440                         generated.add(typeName);
4441                         t.dumpDependedTypes(generated, pOptions);
4442                     }
4443                 } else {
4444                     ret = true;
4445                 }
4446             }
4447             break;
4448         case RT_TYPE_SINGLETON:
4449             {
4450                 SingletonType t(reader, typeName, typeMgr);
4451                 if (t.isInterfaceBased()) {
4452                     ret = t.dump(pOptions);
4453                     if (ret) {
4454                         generated.add(typeName);
4455                         t.dumpDependedTypes(generated, pOptions);
4456                     }
4457                 } else {
4458                     ret = true;
4459                 }
4460             }
4461             break;
4462         case RT_TYPE_OBJECT:
4463             ret = true;
4464             break;
4465         default:
4466             OSL_ASSERT(false);
4467             break;
4468     }
4469 
4470     return ret;
4471 }
4472 
4473 //*************************************************************************
4474 // scopedName
4475 //*************************************************************************
4476 /*
4477 OString scopedName(const OString& scope, const OString& type,
4478                    sal_Bool bNoNameSpace)
4479 {
4480     sal_Int32 nPos = type.lastIndexOf( '/' );
4481     if (nPos == -1)
4482         return type;
4483 
4484     OStringBuffer tmpBuf(type.getLength()*2);
4485     nPos = 0;
4486     do
4487     {
4488         tmpBuf.append("::");
4489         OString token(type.getToken(0, '/', nPos));
4490         if (nPos != -1)
4491             tmpBuf.append(translateUnoToCppIndentifier(
4492                               token, "module", ITM_KEYWORDSONLY));
4493         else
4494             tmpBuf.append(translateUnoToCppIndentifier(
4495                               token, "interface", ITM_KEYWORDSONLY));
4496     } while( nPos != -1 );
4497 
4498     return tmpBuf.makeStringAndClear();
4499 }
4500 */
4501