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