xref: /aoo41x/main/registry/source/reflwrit.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_registry.hxx"
30 
31 #include <new>
32 #include <sal/types.h>
33 #include <sal/macros.h>
34 #include <osl/endian.h>
35 #include <rtl/alloc.h>
36 #include "rtl/string.hxx"
37 #include "rtl/ustring.hxx"
38 
39 #include "registry/reflwrit.hxx"
40 #include "registry/version.h"
41 #include "registry/writer.h"
42 
43 #include "reflcnst.hxx"
44 
45 using namespace rtl;
46 
47 namespace {
48 
49 // Throws std::bad_alloc:
50 inline rtl::OString toByteString(rtl_uString const * str) {
51     return rtl::OString(
52         str->buffer, str->length, RTL_TEXTENCODING_UTF8,
53         OUSTRING_TO_OSTRING_CVTFLAGS);
54 }
55 
56 }
57 
58 static sal_Unicode NULL_WSTRING[1] = { 0 };
59 
60 #if defined ( GCC ) && ( defined ( SCO ) )
61 ORealDynamicLoader* ODynamicLoader<RegistryTypeWriter_Api>::m_pLoader = NULL;
62 #endif
63 
64 #define BLOP_OFFSET_MAGIC       0
65 #define BLOP_OFFSET_SIZE        (BLOP_OFFSET_MAGIC + sizeof(sal_uInt32))
66 #define BLOP_OFFSET_MINOR       (BLOP_OFFSET_SIZE + sizeof(sal_uInt32))
67 #define BLOP_OFFSET_MAJOR       (BLOP_OFFSET_MINOR + sizeof(sal_uInt16))
68 #define BLOP_OFFSET_N_ENTRIES	(BLOP_OFFSET_MAJOR + sizeof(sal_uInt16))
69 #define BLOP_OFFSET_TYPE_SOURCE (BLOP_OFFSET_N_ENTRIES + sizeof(sal_uInt16))
70 #define BLOP_OFFSET_TYPE_CLASS  (BLOP_OFFSET_TYPE_SOURCE + sizeof(sal_uInt16))
71 #define BLOP_OFFSET_THIS        (BLOP_OFFSET_TYPE_CLASS + sizeof(sal_uInt16))
72 #define BLOP_OFFSET_UIK         (BLOP_OFFSET_THIS + sizeof(sal_uInt16))
73 #define BLOP_OFFSET_DOKU        (BLOP_OFFSET_UIK + sizeof(sal_uInt16))
74 #define BLOP_OFFSET_FILENAME    (BLOP_OFFSET_DOKU + sizeof(sal_uInt16))
75 #define BLOP_HEADER_N_ENTRIES   6
76 
77 #define BLOP_OFFSET_N_SUPERTYPES 	0
78 #define BLOP_OFFSET_SUPERTYPES 		(BLOP_OFFSET_N_SUPERTYPES + sizeof(sal_uInt16))
79 
80 #define BLOP_FIELD_ENTRY_ACCESS 	0
81 #define BLOP_FIELD_ENTRY_NAME       (BLOP_FIELD_ENTRY_ACCESS + sizeof(sal_uInt16))
82 #define BLOP_FIELD_ENTRY_TYPE       (BLOP_FIELD_ENTRY_NAME + sizeof(sal_uInt16))
83 #define BLOP_FIELD_ENTRY_VALUE      (BLOP_FIELD_ENTRY_TYPE + sizeof(sal_uInt16))
84 #define BLOP_FIELD_ENTRY_DOKU       (BLOP_FIELD_ENTRY_VALUE + sizeof(sal_uInt16))
85 #define BLOP_FIELD_ENTRY_FILENAME   (BLOP_FIELD_ENTRY_DOKU + sizeof(sal_uInt16))
86 #define BLOP_FIELD_N_ENTRIES   		6
87 
88 #define BLOP_METHOD_SIZE        0
89 #define BLOP_METHOD_MODE        (BLOP_METHOD_SIZE + sizeof(sal_uInt16))
90 #define BLOP_METHOD_NAME        (BLOP_METHOD_MODE + sizeof(sal_uInt16))
91 #define BLOP_METHOD_RETURN      (BLOP_METHOD_NAME + sizeof(sal_uInt16))
92 #define BLOP_METHOD_DOKU        (BLOP_METHOD_RETURN + sizeof(sal_uInt16))
93 #define BLOP_METHOD_N_ENTRIES   5
94 
95 #define BLOP_PARAM_TYPE         0
96 #define BLOP_PARAM_MODE         (BLOP_PARAM_TYPE + sizeof(sal_uInt16))
97 #define BLOP_PARAM_NAME         (BLOP_PARAM_MODE + sizeof(sal_uInt16))
98 #define BLOP_PARAM_N_ENTRIES    3
99 
100 #define BLOP_REFERENCE_TYPE         0
101 #define BLOP_REFERENCE_NAME         (BLOP_REFERENCE_TYPE + sizeof(sal_uInt16))
102 #define BLOP_REFERENCE_DOKU         (BLOP_REFERENCE_NAME + sizeof(sal_uInt16))
103 #define BLOP_REFERENCE_ACCESS   	(BLOP_REFERENCE_DOKU + sizeof(sal_uInt16))
104 #define BLOP_REFERENCE_N_ENTRIES    4
105 
106 sal_uInt32 UINT16StringLen(const sal_uInt8* wstring)
107 {
108     if (!wstring) return 0;
109 
110     const sal_uInt8* b = wstring;
111 
112     while (b[0] || b[1]) b += sizeof(sal_uInt16);
113 
114     return ((b - wstring) / sizeof(sal_uInt16));
115 }
116 
117 sal_uInt32 writeString(sal_uInt8* buffer, const sal_Unicode* v)
118 {
119     sal_uInt32 len = rtl_ustr_getLength(v) + 1;
120     sal_uInt32 i;
121     sal_uInt8* buff = buffer;
122 
123     for (i = 0; i < len; i++)
124     {
125         buff += writeUINT16(buff, (sal_uInt16) v[i]);
126     }
127 
128     return (buff - buffer);
129 }
130 
131 sal_uInt32 readString(const sal_uInt8* buffer, sal_Unicode* v, sal_uInt32 maxSize)
132 {
133     sal_uInt32 len = SAL_MIN(UINT16StringLen(buffer) + 1, maxSize / 2);
134     sal_uInt32 i;
135     sal_uInt8* buff = (sal_uInt8*)buffer;
136 
137     for (i = 0; i < (len - 1); i++)
138     {
139         sal_uInt16 aChar;
140 
141         buff += readUINT16(buff, aChar);
142 
143         v[i] = (sal_Unicode) aChar;
144     }
145 
146     v[len - 1] = L'\0';
147 
148     return (buff - ((sal_uInt8*)buffer));
149 }
150 
151 sal_uInt32 writeFloat(sal_uInt8* buffer, float v)
152 {
153     union
154     {
155         float   v;
156         sal_uInt32  b;
157     } x;
158 
159     x.v = v;
160 
161 #ifdef REGTYPE_IEEE_NATIVE
162     writeUINT32(buffer, x.b);
163 #else
164 #   error no IEEE
165 #endif
166 
167     return sizeof(sal_uInt32);
168 }
169 
170 sal_uInt32 writeDouble(sal_uInt8* buffer, double v)
171 {
172     union
173     {
174         double v;
175         struct
176         {
177             sal_uInt32  b1;
178             sal_uInt32  b2;
179         } b;
180     } x;
181 
182     x.v = v;
183 
184 #ifdef REGTYPE_IEEE_NATIVE
185 #   ifdef OSL_BIGENDIAN
186     writeUINT32(buffer, x.b.b1);
187     writeUINT32(buffer + sizeof(sal_uInt32), x.b.b2);
188 #   else
189     writeUINT32(buffer, x.b.b2);
190     writeUINT32(buffer + sizeof(sal_uInt32), x.b.b1);
191 #   endif
192 #else
193 #   error no IEEE
194 #endif
195 
196     return (sizeof(sal_uInt32) + sizeof(sal_uInt32));
197 }
198 
199 /**************************************************************************
200 
201     buffer write functions
202 
203 **************************************************************************/
204 
205 
206 /**************************************************************************
207 
208     struct CPInfo
209 
210 **************************************************************************/
211 
212 struct CPInfo
213 {
214     CPInfoTag   m_tag;
215     union
216     {
217         const sal_Char*     aUtf8;
218         RTUik*          	aUik;
219         RTConstValueUnion   aConst;
220     } m_value;
221 
222     sal_uInt16		m_index;
223     struct CPInfo*	m_next;
224 
225     CPInfo(CPInfoTag tag, struct CPInfo* prev);
226 
227     sal_uInt32 getBlopSize();
228 
229     sal_uInt32 toBlop(sal_uInt8* buffer);
230 };
231 
232 CPInfo::CPInfo(CPInfoTag tag, struct CPInfo* prev)
233     : m_tag(tag)
234     , m_index(0)
235     , m_next(NULL)
236 {
237     if (prev)
238     {
239         m_index = prev->m_index + 1;
240         prev->m_next = this;
241     }
242 }
243 
244 sal_uInt32 CPInfo::getBlopSize()
245 {
246     sal_uInt32 size = sizeof(sal_uInt32) /* size */ + sizeof(sal_uInt16) /* tag */;
247 
248     switch (m_tag)
249     {
250         case CP_TAG_CONST_BOOL:
251             size += sizeof(sal_uInt8);
252             break;
253         case CP_TAG_CONST_BYTE:
254             size += sizeof(sal_uInt8);
255             break;
256         case CP_TAG_CONST_INT16:
257             size += sizeof(sal_Int16);
258             break;
259         case CP_TAG_CONST_UINT16:
260             size += sizeof(sal_uInt16);
261             break;
262         case CP_TAG_CONST_INT32:
263             size += sizeof(sal_Int32);
264             break;
265         case CP_TAG_CONST_UINT32:
266             size += sizeof(sal_uInt32);
267             break;
268         case CP_TAG_CONST_INT64:
269           	size += sizeof(sal_Int64);
270             break;
271         case CP_TAG_CONST_UINT64:
272 			size += sizeof(sal_uInt64);
273             break;
274         case CP_TAG_CONST_FLOAT:
275             size += sizeof(sal_uInt32);
276             break;
277         case CP_TAG_CONST_DOUBLE:
278             size += sizeof(sal_uInt32) + sizeof(sal_uInt32);
279             break;
280         case CP_TAG_CONST_STRING:
281             size += (rtl_ustr_getLength(m_value.aConst.aString) + 1) * sizeof(sal_uInt16);
282             break;
283         case CP_TAG_UTF8_NAME:
284             size += strlen(m_value.aUtf8) + 1;
285             break;
286         case CP_TAG_UIK:
287             size += sizeof(sal_uInt32) + sizeof(sal_uInt16) + sizeof(sal_uInt16) + sizeof(sal_uInt32) + sizeof(sal_uInt32);
288             break;
289         default:
290             break;
291     }
292 
293     return size;
294 }
295 
296 
297 sal_uInt32 CPInfo::toBlop(sal_uInt8* buffer)
298 {
299     sal_uInt8* buff = buffer;
300 
301     buff += writeUINT32(buff, getBlopSize());
302     buff += writeUINT16(buff, (sal_uInt16) m_tag);
303 
304     switch (m_tag)
305     {
306         case CP_TAG_CONST_BOOL:
307             buff += writeBYTE(buff, (sal_uInt8) m_value.aConst.aBool);
308             break;
309         case CP_TAG_CONST_BYTE:
310             buff += writeBYTE(buff, m_value.aConst.aByte);
311             break;
312         case CP_TAG_CONST_INT16:
313             buff += writeINT16(buff, m_value.aConst.aShort);
314             break;
315         case CP_TAG_CONST_UINT16:
316             buff += writeINT16(buff, m_value.aConst.aUShort);
317             break;
318         case CP_TAG_CONST_INT32:
319             buff += writeINT32(buff, m_value.aConst.aLong);
320             break;
321         case CP_TAG_CONST_UINT32:
322             buff += writeUINT32(buff, m_value.aConst.aULong);
323             break;
324         case CP_TAG_CONST_INT64:
325 			buff += writeUINT64(buff, m_value.aConst.aHyper);
326             break;
327         case CP_TAG_CONST_UINT64:
328 			buff += writeUINT64(buff, m_value.aConst.aUHyper);
329             break;
330         case CP_TAG_CONST_FLOAT:
331             buff += writeFloat(buff, m_value.aConst.aFloat);
332             break;
333         case CP_TAG_CONST_DOUBLE:
334             buff += writeDouble(buff, m_value.aConst.aDouble);
335             break;
336         case CP_TAG_CONST_STRING:
337             buff += writeString(buff, m_value.aConst.aString);
338             break;
339         case CP_TAG_UTF8_NAME:
340             buff += writeUtf8(buff, m_value.aUtf8);
341             break;
342         case CP_TAG_UIK:
343             buff += writeUINT32(buff, m_value.aUik->m_Data1);
344             buff += writeUINT16(buff, m_value.aUik->m_Data2);
345             buff += writeUINT16(buff, m_value.aUik->m_Data3);
346             buff += writeUINT32(buff, m_value.aUik->m_Data4);
347             buff += writeUINT32(buff, m_value.aUik->m_Data5);
348             break;
349         default:
350             break;
351     }
352 
353     return (buff - buffer);
354 }
355 
356 
357 /**************************************************************************
358 
359     class FieldEntry
360 
361 **************************************************************************/
362 
363 class FieldEntry
364 {
365 
366 public:
367 
368     OString           m_name;
369     OString           m_typeName;
370     OString           m_doku;
371     OString           m_fileName;
372     RTFieldAccess     m_access;
373     RTValueType       m_constValueType;
374     RTConstValueUnion m_constValue;
375 
376     FieldEntry();
377     ~FieldEntry();
378 
379     void setData(const OString&    name,
380                  const OString&    typeName,
381                  const OString&    doku,
382                  const OString&    fileName,
383                  RTFieldAccess     access,
384                  RTValueType       constValueType,
385                  RTConstValueUnion constValue);
386         // throws std::bad_alloc
387 };
388 
389 FieldEntry::FieldEntry()
390     : m_access(RT_ACCESS_INVALID)
391     , m_constValueType(RT_TYPE_NONE)
392 {
393 }
394 
395 FieldEntry::~FieldEntry()
396 {
397     if (
398         (m_constValueType == RT_TYPE_STRING) &&
399         m_constValue.aString &&
400         (m_constValue.aString != NULL_WSTRING)
401        )
402     {
403         delete[] (sal_Unicode*)m_constValue.aString;
404     }
405 }
406 
407 void FieldEntry::setData(const OString&    name,
408                          const OString&    typeName,
409                          const OString&    doku,
410                          const OString&    fileName,
411                          RTFieldAccess      access,
412                          RTValueType        constValueType,
413                          RTConstValueUnion  constValue)
414 {
415     sal_Unicode * newValue = 0;
416     if (constValueType == RT_TYPE_STRING && constValue.aString != 0) {
417         sal_Int32 n = rtl_ustr_getLength(constValue.aString) + 1;
418         newValue = new sal_Unicode[n];
419         rtl_copyMemory(newValue, constValue.aString, n * sizeof (sal_Unicode));
420     }
421 
422 	m_name = name;
423     m_typeName = typeName;
424     m_doku = doku;
425     m_fileName = fileName;
426 
427     if (
428         (m_constValueType == RT_TYPE_STRING) &&
429         m_constValue.aString &&
430         (m_constValue.aString != NULL_WSTRING)
431        )
432     {
433         delete[] (sal_Unicode*)m_constValue.aString;
434     }
435 
436     m_access = access;
437     m_constValueType = constValueType;
438 
439     if (m_constValueType == RT_TYPE_STRING)
440     {
441         if (constValue.aString == NULL)
442             m_constValue.aString = NULL_WSTRING;
443         else
444         {
445             m_constValue.aString = newValue;
446         }
447     }
448     else
449     {
450         m_constValue = constValue;
451     }
452 }
453 
454 /**************************************************************************
455 
456     class ParamEntry
457 
458 **************************************************************************/
459 
460 class ParamEntry
461 {
462 public:
463 
464     OString    	m_typeName;
465     OString     m_name;
466     RTParamMode m_mode;
467 
468     ParamEntry();
469     ~ParamEntry();
470 
471     void setData(const OString& typeName,
472                  const OString&	name,
473                  RTParamMode    mode);
474 };
475 
476 ParamEntry::ParamEntry()
477     : m_mode(RT_PARAM_INVALID)
478 {
479 }
480 
481 ParamEntry::~ParamEntry()
482 {
483 }
484 
485 void ParamEntry::setData(const OString& typeName,
486                          const OString&	name,
487                          RTParamMode   	mode)
488 {
489     m_name = name;
490     m_typeName = typeName;
491     m_mode = mode;
492 }
493 
494 /**************************************************************************
495 
496     class ReferenceEntry
497 
498 **************************************************************************/
499 
500 class ReferenceEntry
501 {
502 public:
503 
504     OString     	m_name;
505     OString			m_doku;
506     RTReferenceType m_type;
507     RTFieldAccess   m_access;
508 
509     ReferenceEntry();
510     ~ReferenceEntry();
511 
512     void setData(const OString&		name,
513                  RTReferenceType    refType,
514                  const OString&   	doku,
515 				 RTFieldAccess     	access);
516 };
517 
518 ReferenceEntry::ReferenceEntry()
519     : m_type(RT_REF_INVALID)
520 	, m_access(RT_ACCESS_INVALID)
521 {
522 }
523 
524 ReferenceEntry::~ReferenceEntry()
525 {
526 }
527 
528 void ReferenceEntry::setData(const OString&    name,
529                              RTReferenceType   refType,
530                              const OString&    doku,
531 							 RTFieldAccess     access)
532 {
533     m_name = name;
534     m_doku = doku;
535     m_type = refType;
536 	m_access = access;
537 }
538 
539 /**************************************************************************
540 
541     class MethodEntry
542 
543 **************************************************************************/
544 
545 class MethodEntry
546 {
547 public:
548 
549     OString       	m_name;
550     OString       	m_returnTypeName;
551     RTMethodMode    m_mode;
552     sal_uInt16      m_paramCount;
553     ParamEntry* 	m_params;
554     sal_uInt16    	m_excCount;
555     OString*      	m_excNames;
556     OString      	m_doku;
557 
558     MethodEntry();
559     ~MethodEntry();
560 
561     void setData(const OString&    name,
562                  const OString&    returnTypeName,
563                  RTMethodMode      mode,
564                  sal_uInt16        paramCount,
565                  sal_uInt16        excCount,
566                  const OString&    doku);
567 
568     void setExcName(sal_uInt16 excIndex, const OString& name);
569 
570 protected:
571 
572     void reallocParams(sal_uInt16 size);
573     void reallocExcs(sal_uInt16 size);
574 };
575 
576 MethodEntry::MethodEntry()
577     : m_mode(RT_MODE_INVALID)
578     , m_paramCount(0)
579     , m_params(NULL)
580     , m_excCount(0)
581     , m_excNames(NULL)
582 {
583 }
584 
585 MethodEntry::~MethodEntry()
586 {
587     if (m_params)
588         delete[] m_params;
589 
590     if (m_excNames)
591         delete[] m_excNames;
592 }
593 
594 void MethodEntry::setData(const OString&   	name,
595                           const OString&   	returnTypeName,
596                           RTMethodMode  	mode,
597                           sal_uInt16        paramCount,
598                           sal_uInt16        excCount,
599                           const OString&   	doku)
600 {
601 	m_name = name;
602 	m_returnTypeName = returnTypeName;
603 	m_doku = doku;
604 
605     m_mode = mode;
606 
607     reallocParams(paramCount);
608     reallocExcs(excCount);
609 }
610 
611 void MethodEntry::setExcName(sal_uInt16 excIndex, const OString& name)
612 {
613     if (excIndex < m_excCount)
614     {
615 		m_excNames[excIndex] = name;
616     }
617 }
618 
619 void MethodEntry::reallocParams(sal_uInt16 size)
620 {
621     ParamEntry* newParams;
622 
623     if (size)
624         newParams = new ParamEntry[size];
625     else
626         newParams = NULL;
627 
628     if (m_paramCount)
629     {
630         sal_uInt16 i;
631 
632         for (i = 0; i < SAL_MIN(size, m_paramCount); i++)
633         {
634             newParams[i].setData(m_params[i].m_typeName, m_params[i].m_name, m_params[i].m_mode);
635         }
636 
637         delete[] m_params;
638     }
639 
640     m_paramCount = size;
641     m_params = newParams;
642 }
643 
644 void MethodEntry::reallocExcs(sal_uInt16 size)
645 {
646     OString* newExcNames;
647 
648     if (size)
649         newExcNames = new OString[size];
650     else
651         newExcNames = NULL;
652 
653     sal_uInt16 i;
654 
655     for (i = 0; i < SAL_MIN(size, m_excCount); i++)
656     {
657         newExcNames[i] = m_excNames[i];
658     }
659 
660     delete[] m_excNames;
661 
662     m_excCount = size;
663     m_excNames = newExcNames;
664 }
665 
666 
667 /**************************************************************************
668 
669     class TypeRegistryEntry
670 
671 **************************************************************************/
672 
673 class TypeWriter
674 {
675 
676 public:
677 
678     sal_uInt32          m_refCount;
679     typereg_Version     m_version;
680     RTTypeClass         m_typeClass;
681     OString		        m_typeName;
682 	sal_uInt16			m_nSuperTypes;
683     OString*            m_superTypeNames;
684     RTUik*              m_pUik;
685     OString		        m_doku;
686     OString		        m_fileName;
687     sal_uInt16          m_fieldCount;
688     FieldEntry*         m_fields;
689     sal_uInt16          m_methodCount;
690     MethodEntry*        m_methods;
691     sal_uInt16          m_referenceCount;
692     ReferenceEntry*     m_references;
693 
694     sal_uInt8*          m_blop;
695     sal_uInt32          m_blopSize;
696 
697     TypeWriter(typereg_Version version,
698                rtl::OString const & documentation,
699                rtl::OString const & fileName,
700 			   RTTypeClass  	RTTypeClass,
701                bool             published,
702                const OString& 	typeName,
703                sal_uInt16       superTypeCount,
704                sal_uInt16  		FieldCount,
705                sal_uInt16   	methodCount,
706                sal_uInt16   	referenceCount);
707 
708     ~TypeWriter();
709 
710     void setSuperType(sal_uInt16 index, OString const & name);
711 
712     void createBlop(); // throws std::bad_alloc
713 };
714 
715 TypeWriter::TypeWriter(typereg_Version version,
716                        rtl::OString const & documentation,
717                        rtl::OString const & fileName,
718 					   RTTypeClass  	RTTypeClass,
719                        bool             published,
720                        const OString& 	typeName,
721                        sal_uInt16       superTypeCount,
722                        sal_uInt16   	fieldCount,
723                        sal_uInt16   	methodCount,
724                        sal_uInt16   	referenceCount)
725     : m_refCount(1)
726     , m_version(version)
727     , m_typeClass(
728         static_cast< enum RTTypeClass >(
729             RTTypeClass | (published ? RT_TYPE_PUBLISHED : 0)))
730  	, m_typeName(typeName)
731 	, m_nSuperTypes(superTypeCount)
732     , m_pUik(NULL)
733     , m_doku(documentation)
734     , m_fileName(fileName)
735     , m_fieldCount(fieldCount)
736     , m_methodCount(methodCount)
737     , m_referenceCount(referenceCount)
738     , m_blop(NULL)
739     , m_blopSize(0)
740 {
741 	if (m_nSuperTypes > 0)
742 	{
743 		m_superTypeNames = new OString[m_nSuperTypes];
744 	} else
745 	{
746 		m_superTypeNames = NULL;
747 	}
748 
749     if (m_fieldCount)
750         m_fields = new FieldEntry[fieldCount];
751 
752     if (m_methodCount)
753         m_methods = new MethodEntry[methodCount];
754 
755     if (m_referenceCount)
756         m_references = new ReferenceEntry[referenceCount];
757 }
758 
759 TypeWriter::~TypeWriter()
760 {
761 	if (m_superTypeNames)
762         delete[] m_superTypeNames;
763 
764     if (m_blop)
765         delete[] m_blop;
766 
767     if (m_fieldCount)
768         delete[] m_fields;
769 
770     if (m_methodCount)
771         delete[] m_methods;
772 
773     if (m_referenceCount)
774         delete[] m_references;
775 
776     if (m_pUik)
777         delete m_pUik;
778 }
779 
780 void TypeWriter::setSuperType(sal_uInt16 index, OString const & name)
781 {
782     m_superTypeNames[index] = name;
783 }
784 
785 void TypeWriter::createBlop()
786 {
787     //TODO: Fix memory leaks that occur when std::bad_alloc is thrown
788 
789     sal_uInt8*  pBlopFields         = NULL;
790     sal_uInt8*  pBlopMethods        = NULL;
791     sal_uInt8*  pBlopReferences     = NULL;
792     sal_uInt8*  pBuffer             = NULL;
793     sal_uInt32  blopFieldsSize      = 0;
794     sal_uInt32  blopMethodsSize     = 0;
795     sal_uInt32  blopReferenceSize   = 0;
796 
797     CPInfo  root(CP_TAG_INVALID, NULL);
798     sal_uInt16  cpIndexThisName = 0;
799 	sal_uInt16* cpIndexSuperNames = NULL;
800     sal_uInt16  cpIndexUik = 0;
801     sal_uInt16  cpIndexDoku = 0;
802     sal_uInt16  cpIndexFileName = 0;
803     CPInfo* pInfo = NULL;
804 
805 	sal_uInt16  entrySize = sizeof(sal_uInt16);
806 	sal_uInt32  blopHeaderEntrySize = BLOP_OFFSET_N_ENTRIES + entrySize + (BLOP_HEADER_N_ENTRIES * entrySize);
807 	sal_uInt32  blopFieldEntrySize = BLOP_FIELD_N_ENTRIES * entrySize;
808 	sal_uInt32  blopMethodEntrySize = BLOP_METHOD_N_ENTRIES * entrySize;
809 	sal_uInt32  blopParamEntrySize = BLOP_PARAM_N_ENTRIES * entrySize;
810 	sal_uInt32  blopReferenceEntrySize = BLOP_REFERENCE_N_ENTRIES * entrySize;
811 
812 	sal_uInt32 blopSize = blopHeaderEntrySize;
813 
814     // create CP entry for this name
815     pInfo = new CPInfo(CP_TAG_UTF8_NAME, &root);
816     pInfo->m_value.aUtf8 = m_typeName.getStr();
817     cpIndexThisName = pInfo->m_index;
818 
819 	// nSuperTypes
820 	blopSize += entrySize;
821 
822     // create CP entry for super names
823     if (m_nSuperTypes)
824     {
825 		blopSize += m_nSuperTypes * entrySize;
826 
827 		cpIndexSuperNames = new sal_uInt16[m_nSuperTypes];
828 
829 		for (sal_uInt32 i=0; i < m_nSuperTypes; i++)
830 		{
831 	        pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
832     	    pInfo->m_value.aUtf8 = m_superTypeNames[i].getStr();
833         	cpIndexSuperNames[i] = pInfo->m_index;
834 		}
835     }
836 
837     // create CP entry for uik
838     if (m_pUik != NULL)
839     {
840         pInfo = new CPInfo(CP_TAG_UIK, pInfo);
841         pInfo->m_value.aUik = m_pUik;
842         cpIndexUik = pInfo->m_index;
843     }
844 
845     // create CP entry for doku
846     if (m_doku.getLength())
847     {
848         pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
849         pInfo->m_value.aUtf8 = m_doku.getStr();
850         cpIndexDoku = pInfo->m_index;
851     }
852 
853     // create CP entry for idl source filename
854     if (m_fileName.getLength())
855     {
856         pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
857         pInfo->m_value.aUtf8 = m_fileName.getStr();
858         cpIndexFileName = pInfo->m_index;
859     }
860 
861     // fields blop
862     blopSize += sizeof(sal_uInt16); // fieldCount + nFieldEntries
863 
864     if (m_fieldCount)
865     {
866         sal_uInt16 cpIndexName = 0;
867         sal_uInt16 cpIndexTypeName = 0;
868         sal_uInt16 cpIndexValue = 0;
869         sal_uInt16 cpIndexDoku2 = 0;
870         sal_uInt16 cpIndexFileName2 = 0;
871 
872 		// nFieldEntries + n fields
873         blopFieldsSize = sizeof(sal_uInt16) + (m_fieldCount * blopFieldEntrySize);
874 
875         blopSize += blopFieldsSize;
876 
877         pBlopFields = new sal_uInt8[blopFieldsSize];
878         pBuffer = pBlopFields;
879 
880 	    pBuffer += writeUINT16(pBuffer, BLOP_FIELD_N_ENTRIES);
881 
882         for (sal_uInt16 i = 0; i < m_fieldCount; i++)
883         {
884             cpIndexName = 0;
885             cpIndexTypeName = 0;
886             cpIndexValue = 0;
887             cpIndexDoku2 = 0;
888             cpIndexFileName2 = 0;
889 
890             pBuffer += writeUINT16(pBuffer, m_fields[i].m_access);
891 
892             if (m_fields[i].m_name.getLength())
893             {
894                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
895                 pInfo->m_value.aUtf8 = m_fields[i].m_name.getStr();
896                 cpIndexName = pInfo->m_index;
897             }
898             pBuffer += writeUINT16(pBuffer, cpIndexName);
899 
900             if (m_fields[i].m_typeName.getLength())
901             {
902                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
903                 pInfo->m_value.aUtf8 = m_fields[i].m_typeName.getStr();
904                 cpIndexTypeName = pInfo->m_index;
905             }
906             pBuffer += writeUINT16(pBuffer, cpIndexTypeName);
907 
908             if (m_fields[i].m_constValueType != RT_TYPE_NONE)
909             {
910                 pInfo = new CPInfo((CPInfoTag)m_fields[i].m_constValueType, pInfo);
911                 pInfo->m_value.aConst = m_fields[i].m_constValue;
912                 cpIndexValue = pInfo->m_index;
913             }
914             pBuffer += writeUINT16(pBuffer, cpIndexValue);
915 
916             if (m_fields[i].m_doku.getLength())
917             {
918                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
919                 pInfo->m_value.aUtf8 = m_fields[i].m_doku.getStr();
920                 cpIndexDoku2 = pInfo->m_index;
921             }
922             pBuffer += writeUINT16(pBuffer, cpIndexDoku2);
923 
924             if (m_fields[i].m_fileName.getLength())
925             {
926                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
927                 pInfo->m_value.aUtf8 = m_fields[i].m_fileName.getStr();
928                 cpIndexFileName2 = pInfo->m_index;
929             }
930             pBuffer += writeUINT16(pBuffer, cpIndexFileName2);
931         }
932     }
933 
934     // methods blop
935     blopSize += sizeof(sal_uInt16); // methodCount
936 
937     if (m_methodCount)
938     {
939         sal_uInt16* pMethodEntrySize = new sal_uInt16[m_methodCount];
940         sal_uInt16  cpIndexName = 0;
941         sal_uInt16  cpIndexReturn = 0;
942         sal_uInt16  cpIndexDoku2 = 0;
943 
944 		// nMethodEntries + nParamEntries
945         blopMethodsSize = (2 * sizeof(sal_uInt16));
946 
947         for (sal_uInt16 i = 0; i < m_methodCount; i++)
948         {
949             pMethodEntrySize[i] = (sal_uInt16)
950                 ( blopMethodEntrySize +                   				// header
951                   sizeof(sal_uInt16) +                                 	// parameterCount
952                   (m_methods[i].m_paramCount * blopParamEntrySize) + 	// exceptions
953                   sizeof(sal_uInt16) +                                 	// exceptionCount
954                   (m_methods[i].m_excCount * sizeof(sal_uInt16)) );   	// exceptions
955 
956             blopMethodsSize += pMethodEntrySize[i];
957         }
958 
959         pBlopMethods = new sal_uInt8[blopMethodsSize];
960 
961         blopSize += blopMethodsSize;
962 
963         pBuffer = pBlopMethods;
964 
965 	    pBuffer += writeUINT16(pBuffer, BLOP_METHOD_N_ENTRIES);
966     	pBuffer += writeUINT16(pBuffer, BLOP_PARAM_N_ENTRIES );
967 
968         for (sal_uInt16 i = 0; i < m_methodCount; i++)
969         {
970             cpIndexReturn = 0;
971             cpIndexDoku2 = 0;
972 
973             pBuffer += writeUINT16(pBuffer, pMethodEntrySize[i]);
974             pBuffer += writeUINT16(
975                 pBuffer,
976                 sal::static_int_cast< sal_uInt16 >(m_methods[i].m_mode));
977 
978             if (m_methods[i].m_name.getLength())
979             {
980                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
981                 pInfo->m_value.aUtf8 = m_methods[i].m_name.getStr();
982                 cpIndexName = pInfo->m_index;
983             }
984             pBuffer += writeUINT16(pBuffer, cpIndexName);
985             cpIndexName = 0;
986 
987             if (m_methods[i].m_returnTypeName.getLength())
988             {
989                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
990                 pInfo->m_value.aUtf8 = m_methods[i].m_returnTypeName.getStr();
991                 cpIndexReturn = pInfo->m_index;
992             }
993             pBuffer += writeUINT16(pBuffer, cpIndexReturn);
994 
995             if (m_methods[i].m_doku.getLength())
996             {
997                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
998                 pInfo->m_value.aUtf8 = m_methods[i].m_doku.getStr();
999                 cpIndexDoku2 = pInfo->m_index;
1000             }
1001             pBuffer += writeUINT16(pBuffer, cpIndexDoku2);
1002 
1003             sal_uInt16 j;
1004 
1005             pBuffer += writeUINT16(pBuffer, m_methods[i].m_paramCount);
1006 
1007             for (j = 0; j < m_methods[i].m_paramCount; j++)
1008             {
1009                 if (m_methods[i].m_params[j].m_typeName.getLength())
1010                 {
1011                     pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
1012                     pInfo->m_value.aUtf8 = m_methods[i].m_params[j].m_typeName.getStr();
1013                     cpIndexName = pInfo->m_index;
1014                 }
1015                 pBuffer += writeUINT16(pBuffer, cpIndexName);
1016                 cpIndexName = 0;
1017 
1018                 pBuffer += writeUINT16(
1019                     pBuffer,
1020                     sal::static_int_cast< sal_uInt16 >(
1021                         m_methods[i].m_params[j].m_mode));
1022 
1023                 if (m_methods[i].m_params[j].m_name.getLength())
1024                 {
1025                     pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
1026                     pInfo->m_value.aUtf8 = m_methods[i].m_params[j].m_name.getStr();
1027                     cpIndexName = pInfo->m_index;
1028                 }
1029                 pBuffer += writeUINT16(pBuffer, cpIndexName);
1030                 cpIndexName = 0;
1031             }
1032 
1033             pBuffer += writeUINT16(pBuffer, m_methods[i].m_excCount);
1034 
1035             for (j = 0; j < m_methods[i].m_excCount; j++)
1036             {
1037                 if (m_methods[i].m_excNames[j].getLength())
1038                 {
1039                     pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
1040                     pInfo->m_value.aUtf8 = m_methods[i].m_excNames[j].getStr();
1041                     cpIndexName = pInfo->m_index;
1042                 }
1043                 pBuffer += writeUINT16(pBuffer, cpIndexName);
1044                 cpIndexName = 0;
1045             }
1046         }
1047 
1048         delete[] pMethodEntrySize;
1049     }
1050 
1051     // reference blop
1052     blopSize += entrySize; // referenceCount
1053 
1054     if (m_referenceCount)
1055     {
1056         sal_uInt16 cpIndexName = 0;
1057         sal_uInt16 cpIndexDoku2 = 0;
1058 
1059 		// nReferenceEntries + n references
1060 		blopReferenceSize = entrySize + (m_referenceCount * blopReferenceEntrySize);
1061 
1062         blopSize += blopReferenceSize;
1063 
1064         pBlopReferences = new sal_uInt8[blopReferenceSize];
1065         pBuffer = pBlopReferences;
1066 
1067 	    pBuffer += writeUINT16(pBuffer, BLOP_REFERENCE_N_ENTRIES);
1068 
1069         for (sal_uInt16 i = 0; i < m_referenceCount; i++)
1070         {
1071             pBuffer += writeUINT16(
1072                 pBuffer,
1073                 sal::static_int_cast< sal_uInt16 >(m_references[i].m_type));
1074 
1075             cpIndexName = 0;
1076             cpIndexDoku2 = 0;
1077 
1078             if (m_references[i].m_name.getLength())
1079             {
1080                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
1081                 pInfo->m_value.aUtf8 = m_references[i].m_name.getStr();
1082                 cpIndexName = pInfo->m_index;
1083             }
1084             pBuffer += writeUINT16(pBuffer, cpIndexName);
1085 
1086             if (m_references[i].m_doku.getLength())
1087             {
1088                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
1089                 pInfo->m_value.aUtf8 = m_references[i].m_doku.getStr();
1090                 cpIndexDoku2 = pInfo->m_index;
1091             }
1092             pBuffer += writeUINT16(pBuffer, cpIndexDoku2);
1093 
1094             pBuffer += writeUINT16(pBuffer, m_references[i].m_access);
1095         }
1096     }
1097 
1098 
1099     // get CP infos blop-length
1100     pInfo = root.m_next;
1101     sal_uInt32 cpBlopSize = 0;
1102     sal_uInt16 cpCount = 0;
1103 
1104     while (pInfo)
1105     {
1106         cpBlopSize += pInfo->getBlopSize();
1107         cpCount++;
1108         pInfo = pInfo->m_next;
1109     }
1110 
1111     blopSize += cpBlopSize;
1112     blopSize += sizeof(sal_uInt16);   // constantPoolCount
1113 
1114     // write all in flat buffer
1115 
1116     sal_uInt8 * blop = new sal_uInt8[blopSize];
1117 
1118     pBuffer = blop;
1119 
1120     // Assumes two's complement arithmetic with modulo-semantics:
1121     pBuffer += writeUINT32(pBuffer, magic + m_version);
1122     pBuffer += writeUINT32(pBuffer, blopSize);
1123     pBuffer += writeUINT16(pBuffer, minorVersion);
1124     pBuffer += writeUINT16(pBuffer, majorVersion);
1125     pBuffer += writeUINT16(pBuffer, BLOP_HEADER_N_ENTRIES);
1126 
1127     pBuffer += writeUINT16(pBuffer, (sal_uInt16)RT_UNO_IDL);
1128     pBuffer += writeUINT16(pBuffer, (sal_uInt16)m_typeClass);
1129     pBuffer += writeUINT16(pBuffer, cpIndexThisName);
1130     pBuffer += writeUINT16(pBuffer, cpIndexUik);
1131     pBuffer += writeUINT16(pBuffer, cpIndexDoku);
1132     pBuffer += writeUINT16(pBuffer, cpIndexFileName);
1133 
1134 	// write supertypes
1135     pBuffer += writeUINT16(pBuffer, m_nSuperTypes);
1136 	if (m_nSuperTypes)
1137 	{
1138 		for (sal_uInt32 i=0; i < m_nSuperTypes; i++)
1139 		{
1140 		    pBuffer += writeUINT16(pBuffer, cpIndexSuperNames[i]);
1141 		}
1142 		delete[] cpIndexSuperNames;
1143 	}
1144 
1145     pBuffer += writeUINT16(pBuffer, cpCount);
1146 
1147     // write and delete CP infos
1148     pInfo = root.m_next;
1149 
1150     while (pInfo)
1151     {
1152         CPInfo* pNextInfo = pInfo->m_next;
1153 
1154         pBuffer += pInfo->toBlop(pBuffer);
1155         delete pInfo;
1156 
1157         pInfo = pNextInfo;
1158     }
1159 
1160     // write fields
1161     pBuffer += writeUINT16(pBuffer, m_fieldCount);
1162     if (blopFieldsSize)
1163     {
1164         memcpy(pBuffer, pBlopFields, blopFieldsSize);
1165         pBuffer += blopFieldsSize;
1166     }
1167 
1168     // write methods
1169     pBuffer += writeUINT16(pBuffer, m_methodCount);
1170     if (blopMethodsSize)
1171     {
1172         memcpy(pBuffer, pBlopMethods, blopMethodsSize);
1173         pBuffer += blopMethodsSize;
1174     }
1175 
1176     // write references
1177     pBuffer += writeUINT16(pBuffer, m_referenceCount);
1178     if (blopReferenceSize)
1179     {
1180         memcpy(pBuffer, pBlopReferences, blopReferenceSize);
1181         pBuffer += blopReferenceSize;
1182     }
1183 
1184     delete[] pBlopFields;
1185     delete[] pBlopMethods;
1186     delete[] pBlopReferences;
1187 
1188     delete[] m_blop;
1189     m_blop = blop;
1190     m_blopSize = blopSize;
1191 }
1192 
1193 
1194 /**************************************************************************
1195 
1196     C-API
1197 
1198 **************************************************************************/
1199 
1200 extern "C" {
1201 
1202 static void TYPEREG_CALLTYPE acquire(TypeWriterImpl hEntry)
1203 {
1204     TypeWriter* pEntry = (TypeWriter*) hEntry;
1205 
1206     if (pEntry != NULL)
1207         pEntry->m_refCount++;
1208 }
1209 
1210 static void TYPEREG_CALLTYPE release(TypeWriterImpl hEntry)
1211 {
1212     TypeWriter* pEntry = (TypeWriter*) hEntry;
1213 
1214     if (pEntry != NULL)
1215     {
1216         if (--pEntry->m_refCount == 0)
1217             delete pEntry;
1218     }
1219 }
1220 
1221 static void TYPEREG_CALLTYPE setUik(TypeWriterImpl  hEntry, const RTUik* uik)
1222 {
1223     TypeWriter* pEntry = (TypeWriter*) hEntry;
1224 
1225     if (pEntry != NULL)
1226     {
1227         if (pEntry->m_pUik)
1228         {
1229             pEntry->m_pUik->m_Data1 = uik->m_Data1;
1230             pEntry->m_pUik->m_Data2 = uik->m_Data2;
1231             pEntry->m_pUik->m_Data3 = uik->m_Data3;
1232             pEntry->m_pUik->m_Data4 = uik->m_Data4;
1233             pEntry->m_pUik->m_Data5 = uik->m_Data5;
1234         }
1235         else
1236             pEntry->m_pUik = new RTUik(*uik);
1237     }
1238 }
1239 
1240 static void TYPEREG_CALLTYPE setDoku(TypeWriterImpl hEntry, rtl_uString* doku)
1241 {
1242     static_cast< TypeWriter * >(hEntry)->m_doku = toByteString(doku);
1243 }
1244 
1245 static void TYPEREG_CALLTYPE setFileName(TypeWriterImpl hEntry, rtl_uString* fileName)
1246 {
1247     static_cast< TypeWriter * >(hEntry)->m_fileName = toByteString(fileName);
1248 }
1249 
1250 sal_Bool typereg_writer_setFieldData(
1251     void * handle, sal_uInt16 index, rtl_uString const * documentation,
1252     rtl_uString const * fileName, RTFieldAccess flags, rtl_uString const * name,
1253     rtl_uString const * typeName, RTValueType valueType,
1254     RTConstValueUnion valueValue)
1255     SAL_THROW_EXTERN_C()
1256 {
1257     try {
1258         static_cast< TypeWriter * >(handle)->m_fields[index].setData(
1259             toByteString(name), toByteString(typeName),
1260             toByteString(documentation), toByteString(fileName), flags,
1261             valueType, valueValue);
1262     } catch (std::bad_alloc &) {
1263         return false;
1264     }
1265     return true;
1266 }
1267 
1268 static void TYPEREG_CALLTYPE setFieldData(TypeWriterImpl    hEntry,
1269                                           sal_uInt16       	index,
1270                                           rtl_uString*     	name,
1271                                           rtl_uString*     	typeName,
1272                                           rtl_uString*     	doku,
1273                                           rtl_uString*     	fileName,
1274                                           RTFieldAccess    	access,
1275                                           RTValueType       valueType,
1276                                           RTConstValueUnion	constValue)
1277 {
1278     typereg_writer_setFieldData(
1279         hEntry, index, doku, fileName, access, name, typeName, valueType,
1280         constValue);
1281 }
1282 
1283 sal_Bool typereg_writer_setMethodData(
1284     void * handle, sal_uInt16 index, rtl_uString const * documentation,
1285     RTMethodMode flags, rtl_uString const * name,
1286     rtl_uString const * returnTypeName, sal_uInt16 parameterCount,
1287     sal_uInt16 exceptionCount)
1288     SAL_THROW_EXTERN_C()
1289 {
1290     try {
1291         static_cast< TypeWriter * >(handle)->m_methods[index].setData(
1292             toByteString(name), toByteString(returnTypeName), flags,
1293             parameterCount, exceptionCount, toByteString(documentation));
1294     } catch (std::bad_alloc &) {
1295         return false;
1296     }
1297     return true;
1298 }
1299 
1300 static void TYPEREG_CALLTYPE setMethodData(TypeWriterImpl   hEntry,
1301                                            sal_uInt16       index,
1302                                            rtl_uString*  	name,
1303                                            rtl_uString*  	returnTypeName,
1304                                            RTMethodMode 	mode,
1305                                            sal_uInt16       paramCount,
1306                                            sal_uInt16       excCount,
1307                                            rtl_uString*  	doku)
1308 {
1309     typereg_writer_setMethodData(
1310         hEntry, index, doku, mode, name, returnTypeName, paramCount, excCount);
1311 }
1312 
1313 sal_Bool typereg_writer_setMethodParameterData(
1314     void * handle, sal_uInt16 methodIndex, sal_uInt16 parameterIndex,
1315     RTParamMode flags, rtl_uString const * name, rtl_uString const * typeName)
1316     SAL_THROW_EXTERN_C()
1317 {
1318     try {
1319         static_cast< TypeWriter * >(handle)->
1320             m_methods[methodIndex].m_params[parameterIndex].setData(
1321                 toByteString(typeName), toByteString(name), flags);
1322     } catch (std::bad_alloc &) {
1323         return false;
1324     }
1325     return true;
1326 }
1327 
1328 static void TYPEREG_CALLTYPE setParamData(TypeWriterImpl    hEntry,
1329                                           sal_uInt16       	index,
1330                                           sal_uInt16  		paramIndex,
1331                                           rtl_uString*     	type,
1332                                           rtl_uString*     	name,
1333                                           RTParamMode      	mode)
1334 {
1335     typereg_writer_setMethodParameterData(
1336         hEntry, index, paramIndex, mode, name, type);
1337 }
1338 
1339 sal_Bool typereg_writer_setMethodExceptionTypeName(
1340     void * handle, sal_uInt16 methodIndex, sal_uInt16 exceptionIndex,
1341     rtl_uString const * typeName)
1342     SAL_THROW_EXTERN_C()
1343 {
1344     try {
1345         static_cast< TypeWriter * >(handle)->m_methods[methodIndex].setExcName(
1346             exceptionIndex, toByteString(typeName));
1347     } catch (std::bad_alloc &) {
1348         return false;
1349     }
1350     return true;
1351 }
1352 
1353 static void TYPEREG_CALLTYPE setExcData(TypeWriterImpl  hEntry,
1354                                         sal_uInt16      index,
1355                                         sal_uInt16      excIndex,
1356                                         rtl_uString* 	type)
1357 {
1358     typereg_writer_setMethodExceptionTypeName(hEntry, index, excIndex, type);
1359 }
1360 
1361 void const * typereg_writer_getBlob(void * handle, sal_uInt32 * size)
1362     SAL_THROW_EXTERN_C()
1363 {
1364     TypeWriter * writer = static_cast< TypeWriter * >(handle);
1365     if (writer->m_blop == 0) {
1366         try {
1367             writer->createBlop();
1368         } catch (std::bad_alloc &) {
1369             return 0;
1370         }
1371     }
1372     *size = writer->m_blopSize;
1373     return writer->m_blop;
1374 }
1375 
1376 static const sal_uInt8* TYPEREG_CALLTYPE getBlop(TypeWriterImpl hEntry)
1377 {
1378     sal_uInt32 size;
1379     return static_cast< sal_uInt8 const * >(
1380         typereg_writer_getBlob(hEntry, &size));
1381 }
1382 
1383 static sal_uInt32 TYPEREG_CALLTYPE getBlopSize(TypeWriterImpl hEntry)
1384 {
1385     sal_uInt32 size;
1386     typereg_writer_getBlob(hEntry, &size);
1387     return size;
1388 }
1389 
1390 sal_Bool typereg_writer_setReferenceData(
1391     void * handle, sal_uInt16 index, rtl_uString const * documentation,
1392     RTReferenceType sort, RTFieldAccess flags, rtl_uString const * typeName)
1393     SAL_THROW_EXTERN_C()
1394 {
1395     try {
1396         static_cast< TypeWriter * >(handle)->m_references[index].setData(
1397             toByteString(typeName), sort, toByteString(documentation), flags);
1398     } catch (std::bad_alloc &) {
1399         return false;
1400     }
1401     return true;
1402 }
1403 
1404 static void TYPEREG_CALLTYPE setReferenceData(TypeWriterImpl    hEntry,
1405                                               sal_uInt16        index,
1406                                               rtl_uString*   	name,
1407                                               RTReferenceType   refType,
1408                                               rtl_uString*   	doku,
1409 											  RTFieldAccess 	access)
1410 {
1411     typereg_writer_setReferenceData(hEntry, index, doku, refType, access, name);
1412 }
1413 
1414 void * typereg_writer_create(
1415     typereg_Version version, rtl_uString const * documentation,
1416     rtl_uString const * fileName, RTTypeClass typeClass, sal_Bool published,
1417     rtl_uString const * typeName, sal_uInt16 superTypeCount,
1418     sal_uInt16 fieldCount, sal_uInt16 methodCount, sal_uInt16 referenceCount)
1419     SAL_THROW_EXTERN_C()
1420 {
1421     try {
1422         return new TypeWriter(
1423             version, toByteString(documentation), toByteString(fileName),
1424             typeClass, published, toByteString(typeName), superTypeCount,
1425             fieldCount, methodCount, referenceCount);
1426     } catch (std::bad_alloc &) {
1427         return 0;
1428     }
1429 }
1430 
1431 void typereg_writer_destroy(void * handle) SAL_THROW_EXTERN_C() {
1432     delete static_cast< TypeWriter * >(handle);
1433 }
1434 
1435 sal_Bool typereg_writer_setSuperTypeName(
1436     void * handle, sal_uInt16 index, rtl_uString const * typeName)
1437     SAL_THROW_EXTERN_C()
1438 {
1439     try {
1440         static_cast< TypeWriter * >(handle)->setSuperType(
1441             index, toByteString(typeName));
1442     } catch (std::bad_alloc &) {
1443         return false;
1444     }
1445     return true;
1446 }
1447 
1448 static TypeWriterImpl TYPEREG_CALLTYPE createEntry(
1449     RTTypeClass typeClass, rtl_uString * typeName, rtl_uString * superTypeName,
1450     sal_uInt16 fieldCount, sal_uInt16 methodCount, sal_uInt16 referenceCount)
1451 {
1452     rtl::OUString empty;
1453     sal_uInt16 superTypeCount = rtl_uString_getLength(superTypeName) == 0
1454         ? 0 : 1;
1455     TypeWriterImpl t = typereg_writer_create(
1456         TYPEREG_VERSION_0, empty.pData, empty.pData, typeClass, false, typeName,
1457         superTypeCount, fieldCount, methodCount, referenceCount);
1458     if (superTypeCount > 0) {
1459         typereg_writer_setSuperTypeName(t, 0, superTypeName);
1460     }
1461     return t;
1462 }
1463 
1464 RegistryTypeWriter_Api* TYPEREG_CALLTYPE initRegistryTypeWriter_Api(void)
1465 {
1466     static RegistryTypeWriter_Api aApi= {0,0,0,0,0,0,0,0,0,0,0,0,0};
1467     if (!aApi.acquire)
1468     {
1469         aApi.createEntry        = &createEntry;
1470         aApi.acquire            = &acquire;
1471         aApi.release            = &release;
1472         aApi.setUik             = &setUik;
1473         aApi.setDoku            = &setDoku;
1474         aApi.setFileName        = &setFileName;
1475         aApi.setFieldData       = &setFieldData;
1476         aApi.setMethodData      = &setMethodData;
1477         aApi.setParamData       = &setParamData;
1478         aApi.setExcData         = &setExcData;
1479         aApi.getBlop            = &getBlop;
1480         aApi.getBlopSize        = &getBlopSize;
1481         aApi.setReferenceData   = &setReferenceData;
1482 
1483         return (&aApi);
1484     }
1485     else
1486     {
1487         return (&aApi);
1488     }
1489 }
1490 
1491 }
1492