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_cppumaker.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