Stop leaking all ScPostIt instances.
[LibreOffice.git] / registry / source / reflwrit.cxx
blob23b065d5614e485e9fec8ef7db42c91301d2ae9e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <new>
22 #include <sal/types.h>
23 #include <sal/macros.h>
24 #include <osl/endian.h>
25 #include <rtl/alloc.h>
26 #include "rtl/string.hxx"
27 #include "rtl/ustring.hxx"
29 #include "registry/reflwrit.hxx"
30 #include "registry/version.h"
31 #include "registry/writer.h"
33 #include "reflcnst.hxx"
37 namespace {
39 inline OString toByteString(rtl_uString const * str) {
40 return OString(
41 str->buffer, str->length, RTL_TEXTENCODING_UTF8,
42 OUSTRING_TO_OSTRING_CVTFLAGS);
47 static sal_Unicode NULL_WSTRING[1] = { 0 };
49 #define BLOP_OFFSET_MAGIC 0
50 #define BLOP_OFFSET_SIZE (BLOP_OFFSET_MAGIC + sizeof(sal_uInt32))
51 #define BLOP_OFFSET_MINOR (BLOP_OFFSET_SIZE + sizeof(sal_uInt32))
52 #define BLOP_OFFSET_MAJOR (BLOP_OFFSET_MINOR + sizeof(sal_uInt16))
53 #define BLOP_OFFSET_N_ENTRIES (BLOP_OFFSET_MAJOR + sizeof(sal_uInt16))
54 #define BLOP_HEADER_N_ENTRIES 6
56 #define BLOP_FIELD_N_ENTRIES 6
58 #define BLOP_METHOD_N_ENTRIES 5
60 #define BLOP_PARAM_N_ENTRIES 3
62 #define BLOP_REFERENCE_N_ENTRIES 4
64 sal_uInt32 UINT16StringLen(const sal_uInt8* wstring)
66 if (!wstring) return 0;
68 const sal_uInt8* b = wstring;
70 while (b[0] || b[1]) b += sizeof(sal_uInt16);
72 return ((b - wstring) / sizeof(sal_uInt16));
75 sal_uInt32 writeString(sal_uInt8* buffer, const sal_Unicode* v)
77 sal_uInt32 len = rtl_ustr_getLength(v) + 1;
78 sal_uInt32 i;
79 sal_uInt8* buff = buffer;
81 for (i = 0; i < len; i++)
83 buff += writeUINT16(buff, (sal_uInt16) v[i]);
86 return (buff - buffer);
89 sal_uInt32 readString(const sal_uInt8* buffer, sal_Unicode* v, sal_uInt32 maxSize)
91 sal_uInt32 len = UINT16StringLen(buffer) + 1;
92 sal_uInt32 i;
93 sal_uInt8* buff = (sal_uInt8*)buffer;
95 if(len > maxSize / 2)
97 len = maxSize / 2;
100 for (i = 0; i < (len - 1); i++)
102 sal_uInt16 aChar;
104 buff += readUINT16(buff, aChar);
106 v[i] = (sal_Unicode) aChar;
109 v[len - 1] = L'\0';
111 return (buff - ((sal_uInt8*)buffer));
114 sal_uInt32 writeFloat(sal_uInt8* buffer, float v)
116 union
118 float v;
119 sal_uInt32 b;
120 } x;
122 x.v = v;
124 #ifdef REGTYPE_IEEE_NATIVE
125 writeUINT32(buffer, x.b);
126 #else
127 # error no IEEE
128 #endif
130 return sizeof(sal_uInt32);
133 sal_uInt32 writeDouble(sal_uInt8* buffer, double v)
135 union
137 double v;
138 struct
140 sal_uInt32 b1;
141 sal_uInt32 b2;
142 } b;
143 } x;
145 x.v = v;
147 #ifdef REGTYPE_IEEE_NATIVE
148 # ifdef OSL_BIGENDIAN
149 writeUINT32(buffer, x.b.b1);
150 writeUINT32(buffer + sizeof(sal_uInt32), x.b.b2);
151 # else
152 writeUINT32(buffer, x.b.b2);
153 writeUINT32(buffer + sizeof(sal_uInt32), x.b.b1);
154 # endif
155 #else
156 # error no IEEE
157 #endif
159 return (sizeof(sal_uInt32) + sizeof(sal_uInt32));
162 /**************************************************************************
164 buffer write functions
166 **************************************************************************/
169 /**************************************************************************
171 struct CPInfo
173 **************************************************************************/
175 struct CPInfo
177 CPInfoTag m_tag;
178 union
180 const sal_Char* aUtf8;
181 RTUik* aUik;
182 RTConstValueUnion aConst;
183 } m_value;
185 sal_uInt16 m_index;
186 struct CPInfo* m_next;
188 CPInfo(CPInfoTag tag, struct CPInfo* prev);
190 sal_uInt32 getBlopSize();
192 sal_uInt32 toBlop(sal_uInt8* buffer);
195 CPInfo::CPInfo(CPInfoTag tag, struct CPInfo* prev)
196 : m_tag(tag)
197 , m_index(0)
198 , m_next(NULL)
200 if (prev)
202 m_index = prev->m_index + 1;
203 prev->m_next = this;
207 sal_uInt32 CPInfo::getBlopSize()
209 sal_uInt32 size = sizeof(sal_uInt32) /* size */ + sizeof(sal_uInt16) /* tag */;
211 switch (m_tag)
213 case CP_TAG_CONST_BOOL:
214 size += sizeof(sal_uInt8);
215 break;
216 case CP_TAG_CONST_BYTE:
217 size += sizeof(sal_uInt8);
218 break;
219 case CP_TAG_CONST_INT16:
220 size += sizeof(sal_Int16);
221 break;
222 case CP_TAG_CONST_UINT16:
223 size += sizeof(sal_uInt16);
224 break;
225 case CP_TAG_CONST_INT32:
226 size += sizeof(sal_Int32);
227 break;
228 case CP_TAG_CONST_UINT32:
229 size += sizeof(sal_uInt32);
230 break;
231 case CP_TAG_CONST_INT64:
232 size += sizeof(sal_Int64);
233 break;
234 case CP_TAG_CONST_UINT64:
235 size += sizeof(sal_uInt64);
236 break;
237 case CP_TAG_CONST_FLOAT:
238 size += sizeof(sal_uInt32);
239 break;
240 case CP_TAG_CONST_DOUBLE:
241 size += sizeof(sal_uInt32) + sizeof(sal_uInt32);
242 break;
243 case CP_TAG_CONST_STRING:
244 size += (rtl_ustr_getLength(m_value.aConst.aString) + 1) * sizeof(sal_uInt16);
245 break;
246 case CP_TAG_UTF8_NAME:
247 size += strlen(m_value.aUtf8) + 1;
248 break;
249 case CP_TAG_UIK:
250 size += sizeof(sal_uInt32) + sizeof(sal_uInt16) + sizeof(sal_uInt16) + sizeof(sal_uInt32) + sizeof(sal_uInt32);
251 break;
252 default:
253 break;
256 return size;
260 sal_uInt32 CPInfo::toBlop(sal_uInt8* buffer)
262 sal_uInt8* buff = buffer;
264 buff += writeUINT32(buff, getBlopSize());
265 buff += writeUINT16(buff, (sal_uInt16) m_tag);
267 switch (m_tag)
269 case CP_TAG_CONST_BOOL:
270 buff += writeBYTE(buff, (sal_uInt8) m_value.aConst.aBool);
271 break;
272 case CP_TAG_CONST_BYTE:
273 buff += writeBYTE(
274 buff, static_cast< sal_uInt8 >(m_value.aConst.aByte));
275 break;
276 case CP_TAG_CONST_INT16:
277 buff += writeINT16(buff, m_value.aConst.aShort);
278 break;
279 case CP_TAG_CONST_UINT16:
280 buff += writeINT16(buff, m_value.aConst.aUShort);
281 break;
282 case CP_TAG_CONST_INT32:
283 buff += writeINT32(buff, m_value.aConst.aLong);
284 break;
285 case CP_TAG_CONST_UINT32:
286 buff += writeUINT32(buff, m_value.aConst.aULong);
287 break;
288 case CP_TAG_CONST_INT64:
289 buff += writeUINT64(buff, m_value.aConst.aHyper);
290 break;
291 case CP_TAG_CONST_UINT64:
292 buff += writeUINT64(buff, m_value.aConst.aUHyper);
293 break;
294 case CP_TAG_CONST_FLOAT:
295 buff += writeFloat(buff, m_value.aConst.aFloat);
296 break;
297 case CP_TAG_CONST_DOUBLE:
298 buff += writeDouble(buff, m_value.aConst.aDouble);
299 break;
300 case CP_TAG_CONST_STRING:
301 buff += writeString(buff, m_value.aConst.aString);
302 break;
303 case CP_TAG_UTF8_NAME:
304 buff += writeUtf8(buff, m_value.aUtf8);
305 break;
306 case CP_TAG_UIK:
307 buff += writeUINT32(buff, m_value.aUik->m_Data1);
308 buff += writeUINT16(buff, m_value.aUik->m_Data2);
309 buff += writeUINT16(buff, m_value.aUik->m_Data3);
310 buff += writeUINT32(buff, m_value.aUik->m_Data4);
311 buff += writeUINT32(buff, m_value.aUik->m_Data5);
312 break;
313 default:
314 break;
317 return (buff - buffer);
321 /**************************************************************************
323 class FieldEntry
325 **************************************************************************/
327 class FieldEntry
330 public:
332 OString m_name;
333 OString m_typeName;
334 OString m_doku;
335 OString m_fileName;
336 RTFieldAccess m_access;
337 RTValueType m_constValueType;
338 RTConstValueUnion m_constValue;
340 FieldEntry();
341 ~FieldEntry();
343 void setData(const OString& name,
344 const OString& typeName,
345 const OString& doku,
346 const OString& fileName,
347 RTFieldAccess access,
348 RTValueType constValueType,
349 RTConstValueUnion constValue);
350 // throws std::bad_alloc
353 FieldEntry::FieldEntry()
354 : m_access(RT_ACCESS_INVALID)
355 , m_constValueType(RT_TYPE_NONE)
359 FieldEntry::~FieldEntry()
361 if (
362 (m_constValueType == RT_TYPE_STRING) &&
363 m_constValue.aString &&
364 (m_constValue.aString != NULL_WSTRING)
367 delete[] (sal_Unicode*)m_constValue.aString;
371 void FieldEntry::setData(const OString& name,
372 const OString& typeName,
373 const OString& doku,
374 const OString& fileName,
375 RTFieldAccess access,
376 RTValueType constValueType,
377 RTConstValueUnion constValue)
379 sal_Unicode * newValue = 0;
380 if (constValueType == RT_TYPE_STRING && constValue.aString != 0) {
381 sal_Int32 n = rtl_ustr_getLength(constValue.aString) + 1;
382 newValue = new sal_Unicode[n];
383 memcpy(newValue, constValue.aString, n * sizeof (sal_Unicode));
386 m_name = name;
387 m_typeName = typeName;
388 m_doku = doku;
389 m_fileName = fileName;
391 if (
392 (m_constValueType == RT_TYPE_STRING) &&
393 m_constValue.aString &&
394 (m_constValue.aString != NULL_WSTRING)
397 delete[] (sal_Unicode*)m_constValue.aString;
400 m_access = access;
401 m_constValueType = constValueType;
403 if (m_constValueType == RT_TYPE_STRING)
405 if (constValue.aString == NULL)
406 m_constValue.aString = NULL_WSTRING;
407 else
409 m_constValue.aString = newValue;
412 else
414 m_constValue = constValue;
418 /**************************************************************************
420 class ParamEntry
422 **************************************************************************/
424 class ParamEntry
426 public:
428 OString m_typeName;
429 OString m_name;
430 RTParamMode m_mode;
432 ParamEntry();
433 ~ParamEntry();
435 void setData(const OString& typeName,
436 const OString& name,
437 RTParamMode mode);
440 ParamEntry::ParamEntry()
441 : m_mode(RT_PARAM_INVALID)
445 ParamEntry::~ParamEntry()
449 void ParamEntry::setData(const OString& typeName,
450 const OString& name,
451 RTParamMode mode)
453 m_name = name;
454 m_typeName = typeName;
455 m_mode = mode;
458 /**************************************************************************
460 class ReferenceEntry
462 **************************************************************************/
464 class ReferenceEntry
466 public:
468 OString m_name;
469 OString m_doku;
470 RTReferenceType m_type;
471 RTFieldAccess m_access;
473 ReferenceEntry();
474 ~ReferenceEntry();
476 void setData(const OString& name,
477 RTReferenceType refType,
478 const OString& doku,
479 RTFieldAccess access);
482 ReferenceEntry::ReferenceEntry()
483 : m_type(RT_REF_INVALID)
484 , m_access(RT_ACCESS_INVALID)
488 ReferenceEntry::~ReferenceEntry()
492 void ReferenceEntry::setData(const OString& name,
493 RTReferenceType refType,
494 const OString& doku,
495 RTFieldAccess access)
497 m_name = name;
498 m_doku = doku;
499 m_type = refType;
500 m_access = access;
503 /**************************************************************************
505 class MethodEntry
507 **************************************************************************/
509 class MethodEntry
511 public:
513 OString m_name;
514 OString m_returnTypeName;
515 RTMethodMode m_mode;
516 sal_uInt16 m_paramCount;
517 ParamEntry* m_params;
518 sal_uInt16 m_excCount;
519 OString* m_excNames;
520 OString m_doku;
522 MethodEntry();
523 ~MethodEntry();
525 void setData(const OString& name,
526 const OString& returnTypeName,
527 RTMethodMode mode,
528 sal_uInt16 paramCount,
529 sal_uInt16 excCount,
530 const OString& doku);
532 void setExcName(sal_uInt16 excIndex, const OString& name);
534 protected:
536 void reallocParams(sal_uInt16 size);
537 void reallocExcs(sal_uInt16 size);
540 MethodEntry::MethodEntry()
541 : m_mode(RT_MODE_INVALID)
542 , m_paramCount(0)
543 , m_params(NULL)
544 , m_excCount(0)
545 , m_excNames(NULL)
549 MethodEntry::~MethodEntry()
551 if (m_params)
552 delete[] m_params;
554 if (m_excNames)
555 delete[] m_excNames;
558 void MethodEntry::setData(const OString& name,
559 const OString& returnTypeName,
560 RTMethodMode mode,
561 sal_uInt16 paramCount,
562 sal_uInt16 excCount,
563 const OString& doku)
565 m_name = name;
566 m_returnTypeName = returnTypeName;
567 m_doku = doku;
569 m_mode = mode;
571 reallocParams(paramCount);
572 reallocExcs(excCount);
575 void MethodEntry::setExcName(sal_uInt16 excIndex, const OString& name)
577 if (excIndex < m_excCount)
579 m_excNames[excIndex] = name;
583 void MethodEntry::reallocParams(sal_uInt16 size)
585 ParamEntry* newParams;
587 if (size)
588 newParams = new ParamEntry[size];
589 else
590 newParams = NULL;
592 if (m_paramCount)
594 sal_uInt16 i;
595 sal_uInt16 mn = size < m_paramCount ? size : m_paramCount;
597 for (i = 0; i < mn; i++)
599 newParams[i].setData(m_params[i].m_typeName, m_params[i].m_name, m_params[i].m_mode);
602 delete[] m_params;
605 m_paramCount = size;
606 m_params = newParams;
609 void MethodEntry::reallocExcs(sal_uInt16 size)
611 OString* newExcNames;
613 if (size)
614 newExcNames = new OString[size];
615 else
616 newExcNames = NULL;
618 sal_uInt16 i;
619 sal_uInt16 mn = size < m_excCount ? size : m_excCount;
621 for (i = 0; i < mn; i++)
623 newExcNames[i] = m_excNames[i];
626 delete[] m_excNames;
628 m_excCount = size;
629 m_excNames = newExcNames;
633 /**************************************************************************
635 class TypeRegistryEntry
637 **************************************************************************/
639 class TypeWriter
642 public:
644 sal_uInt32 m_refCount;
645 typereg_Version m_version;
646 RTTypeClass m_typeClass;
647 OString m_typeName;
648 sal_uInt16 m_nSuperTypes;
649 OString* m_superTypeNames;
650 RTUik* m_pUik;
651 OString m_doku;
652 OString m_fileName;
653 sal_uInt16 m_fieldCount;
654 FieldEntry* m_fields;
655 sal_uInt16 m_methodCount;
656 MethodEntry* m_methods;
657 sal_uInt16 m_referenceCount;
658 ReferenceEntry* m_references;
660 sal_uInt8* m_blop;
661 sal_uInt32 m_blopSize;
663 TypeWriter(typereg_Version version,
664 OString const & documentation,
665 OString const & fileName,
666 RTTypeClass RTTypeClass,
667 bool published,
668 const OString& typeName,
669 sal_uInt16 superTypeCount,
670 sal_uInt16 FieldCount,
671 sal_uInt16 methodCount,
672 sal_uInt16 referenceCount);
674 ~TypeWriter();
676 void setSuperType(sal_uInt16 index, OString const & name);
678 void createBlop(); // throws std::bad_alloc
681 TypeWriter::TypeWriter(typereg_Version version,
682 OString const & documentation,
683 OString const & fileName,
684 RTTypeClass RTTypeClass,
685 bool published,
686 const OString& typeName,
687 sal_uInt16 superTypeCount,
688 sal_uInt16 fieldCount,
689 sal_uInt16 methodCount,
690 sal_uInt16 referenceCount)
691 : m_refCount(1)
692 , m_version(version)
693 , m_typeClass(
694 static_cast< enum RTTypeClass >(
695 RTTypeClass | (published ? RT_TYPE_PUBLISHED : 0)))
696 , m_typeName(typeName)
697 , m_nSuperTypes(superTypeCount)
698 , m_pUik(NULL)
699 , m_doku(documentation)
700 , m_fileName(fileName)
701 , m_fieldCount(fieldCount)
702 , m_methodCount(methodCount)
703 , m_referenceCount(referenceCount)
704 , m_blop(NULL)
705 , m_blopSize(0)
707 if (m_nSuperTypes > 0)
709 m_superTypeNames = new OString[m_nSuperTypes];
710 } else
712 m_superTypeNames = NULL;
715 if (m_fieldCount)
716 m_fields = new FieldEntry[fieldCount];
718 if (m_methodCount)
719 m_methods = new MethodEntry[methodCount];
721 if (m_referenceCount)
722 m_references = new ReferenceEntry[referenceCount];
725 TypeWriter::~TypeWriter()
727 if (m_superTypeNames)
728 delete[] m_superTypeNames;
730 if (m_blop)
731 delete[] m_blop;
733 if (m_fieldCount)
734 delete[] m_fields;
736 if (m_methodCount)
737 delete[] m_methods;
739 if (m_referenceCount)
740 delete[] m_references;
742 if (m_pUik)
743 delete m_pUik;
746 void TypeWriter::setSuperType(sal_uInt16 index, OString const & name)
748 m_superTypeNames[index] = name;
751 void TypeWriter::createBlop()
753 //TODO: Fix memory leaks that occur when std::bad_alloc is thrown
755 sal_uInt8* pBlopFields = NULL;
756 sal_uInt8* pBlopMethods = NULL;
757 sal_uInt8* pBlopReferences = NULL;
758 sal_uInt8* pBuffer = NULL;
759 sal_uInt32 blopFieldsSize = 0;
760 sal_uInt32 blopMethodsSize = 0;
761 sal_uInt32 blopReferenceSize = 0;
763 CPInfo root(CP_TAG_INVALID, NULL);
764 sal_uInt16 cpIndexThisName = 0;
765 sal_uInt16* cpIndexSuperNames = NULL;
766 sal_uInt16 cpIndexUik = 0;
767 sal_uInt16 cpIndexDoku = 0;
768 sal_uInt16 cpIndexFileName = 0;
769 CPInfo* pInfo = NULL;
771 sal_uInt16 entrySize = sizeof(sal_uInt16);
772 sal_uInt32 blopHeaderEntrySize = BLOP_OFFSET_N_ENTRIES + entrySize + (BLOP_HEADER_N_ENTRIES * entrySize);
773 sal_uInt32 blopFieldEntrySize = BLOP_FIELD_N_ENTRIES * entrySize;
774 sal_uInt32 blopMethodEntrySize = BLOP_METHOD_N_ENTRIES * entrySize;
775 sal_uInt32 blopParamEntrySize = BLOP_PARAM_N_ENTRIES * entrySize;
776 sal_uInt32 blopReferenceEntrySize = BLOP_REFERENCE_N_ENTRIES * entrySize;
778 sal_uInt32 blopSize = blopHeaderEntrySize;
780 // create CP entry for this name
781 pInfo = new CPInfo(CP_TAG_UTF8_NAME, &root);
782 pInfo->m_value.aUtf8 = m_typeName.getStr();
783 cpIndexThisName = pInfo->m_index;
785 // nSuperTypes
786 blopSize += entrySize;
788 // create CP entry for super names
789 if (m_nSuperTypes)
791 blopSize += m_nSuperTypes * entrySize;
793 cpIndexSuperNames = new sal_uInt16[m_nSuperTypes];
795 for (sal_uInt32 i=0; i < m_nSuperTypes; i++)
797 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
798 pInfo->m_value.aUtf8 = m_superTypeNames[i].getStr();
799 cpIndexSuperNames[i] = pInfo->m_index;
803 // create CP entry for uik
804 if (m_pUik != NULL)
806 pInfo = new CPInfo(CP_TAG_UIK, pInfo);
807 pInfo->m_value.aUik = m_pUik;
808 cpIndexUik = pInfo->m_index;
811 // create CP entry for doku
812 if (!m_doku.isEmpty())
814 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
815 pInfo->m_value.aUtf8 = m_doku.getStr();
816 cpIndexDoku = pInfo->m_index;
819 // create CP entry for idl source filename
820 if (!m_fileName.isEmpty())
822 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
823 pInfo->m_value.aUtf8 = m_fileName.getStr();
824 cpIndexFileName = pInfo->m_index;
827 // fields blop
828 blopSize += sizeof(sal_uInt16); // fieldCount + nFieldEntries
830 if (m_fieldCount)
832 sal_uInt16 cpIndexName = 0;
833 sal_uInt16 cpIndexTypeName = 0;
834 sal_uInt16 cpIndexValue = 0;
835 sal_uInt16 cpIndexDoku2 = 0;
836 sal_uInt16 cpIndexFileName2 = 0;
838 // nFieldEntries + n fields
839 blopFieldsSize = sizeof(sal_uInt16) + (m_fieldCount * blopFieldEntrySize);
841 blopSize += blopFieldsSize;
843 pBlopFields = new sal_uInt8[blopFieldsSize];
844 pBuffer = pBlopFields;
846 pBuffer += writeUINT16(pBuffer, BLOP_FIELD_N_ENTRIES);
848 for (sal_uInt16 i = 0; i < m_fieldCount; i++)
850 cpIndexName = 0;
851 cpIndexTypeName = 0;
852 cpIndexValue = 0;
853 cpIndexDoku2 = 0;
854 cpIndexFileName2 = 0;
856 pBuffer += writeUINT16(pBuffer, m_fields[i].m_access);
858 if (!m_fields[i].m_name.isEmpty())
860 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
861 pInfo->m_value.aUtf8 = m_fields[i].m_name.getStr();
862 cpIndexName = pInfo->m_index;
864 pBuffer += writeUINT16(pBuffer, cpIndexName);
866 if (!m_fields[i].m_typeName.isEmpty())
868 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
869 pInfo->m_value.aUtf8 = m_fields[i].m_typeName.getStr();
870 cpIndexTypeName = pInfo->m_index;
872 pBuffer += writeUINT16(pBuffer, cpIndexTypeName);
874 if (m_fields[i].m_constValueType != RT_TYPE_NONE)
876 pInfo = new CPInfo((CPInfoTag)m_fields[i].m_constValueType, pInfo);
877 pInfo->m_value.aConst = m_fields[i].m_constValue;
878 cpIndexValue = pInfo->m_index;
880 pBuffer += writeUINT16(pBuffer, cpIndexValue);
882 if (!m_fields[i].m_doku.isEmpty())
884 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
885 pInfo->m_value.aUtf8 = m_fields[i].m_doku.getStr();
886 cpIndexDoku2 = pInfo->m_index;
888 pBuffer += writeUINT16(pBuffer, cpIndexDoku2);
890 if (!m_fields[i].m_fileName.isEmpty())
892 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
893 pInfo->m_value.aUtf8 = m_fields[i].m_fileName.getStr();
894 cpIndexFileName2 = pInfo->m_index;
896 pBuffer += writeUINT16(pBuffer, cpIndexFileName2);
900 // methods blop
901 blopSize += sizeof(sal_uInt16); // methodCount
903 if (m_methodCount)
905 sal_uInt16* pMethodEntrySize = new sal_uInt16[m_methodCount];
906 sal_uInt16 cpIndexName = 0;
907 sal_uInt16 cpIndexReturn = 0;
908 sal_uInt16 cpIndexDoku2 = 0;
910 // nMethodEntries + nParamEntries
911 blopMethodsSize = (2 * sizeof(sal_uInt16));
913 for (sal_uInt16 i = 0; i < m_methodCount; i++)
915 pMethodEntrySize[i] = (sal_uInt16)
916 ( blopMethodEntrySize + // header
917 sizeof(sal_uInt16) + // parameterCount
918 (m_methods[i].m_paramCount * blopParamEntrySize) + // exceptions
919 sizeof(sal_uInt16) + // exceptionCount
920 (m_methods[i].m_excCount * sizeof(sal_uInt16)) ); // exceptions
922 blopMethodsSize += pMethodEntrySize[i];
925 pBlopMethods = new sal_uInt8[blopMethodsSize];
927 blopSize += blopMethodsSize;
929 pBuffer = pBlopMethods;
931 pBuffer += writeUINT16(pBuffer, BLOP_METHOD_N_ENTRIES);
932 pBuffer += writeUINT16(pBuffer, BLOP_PARAM_N_ENTRIES );
934 for (sal_uInt16 i = 0; i < m_methodCount; i++)
936 cpIndexReturn = 0;
937 cpIndexDoku2 = 0;
939 pBuffer += writeUINT16(pBuffer, pMethodEntrySize[i]);
940 pBuffer += writeUINT16(
941 pBuffer,
942 sal::static_int_cast< sal_uInt16 >(m_methods[i].m_mode));
944 if (!m_methods[i].m_name.isEmpty())
946 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
947 pInfo->m_value.aUtf8 = m_methods[i].m_name.getStr();
948 cpIndexName = pInfo->m_index;
950 pBuffer += writeUINT16(pBuffer, cpIndexName);
951 cpIndexName = 0;
953 if (!m_methods[i].m_returnTypeName.isEmpty())
955 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
956 pInfo->m_value.aUtf8 = m_methods[i].m_returnTypeName.getStr();
957 cpIndexReturn = pInfo->m_index;
959 pBuffer += writeUINT16(pBuffer, cpIndexReturn);
961 if (!m_methods[i].m_doku.isEmpty())
963 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
964 pInfo->m_value.aUtf8 = m_methods[i].m_doku.getStr();
965 cpIndexDoku2 = pInfo->m_index;
967 pBuffer += writeUINT16(pBuffer, cpIndexDoku2);
969 sal_uInt16 j;
971 pBuffer += writeUINT16(pBuffer, m_methods[i].m_paramCount);
973 for (j = 0; j < m_methods[i].m_paramCount; j++)
975 if (!m_methods[i].m_params[j].m_typeName.isEmpty())
977 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
978 pInfo->m_value.aUtf8 = m_methods[i].m_params[j].m_typeName.getStr();
979 cpIndexName = pInfo->m_index;
981 pBuffer += writeUINT16(pBuffer, cpIndexName);
982 cpIndexName = 0;
984 pBuffer += writeUINT16(
985 pBuffer,
986 sal::static_int_cast< sal_uInt16 >(
987 m_methods[i].m_params[j].m_mode));
989 if (!m_methods[i].m_params[j].m_name.isEmpty())
991 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
992 pInfo->m_value.aUtf8 = m_methods[i].m_params[j].m_name.getStr();
993 cpIndexName = pInfo->m_index;
995 pBuffer += writeUINT16(pBuffer, cpIndexName);
996 cpIndexName = 0;
999 pBuffer += writeUINT16(pBuffer, m_methods[i].m_excCount);
1001 for (j = 0; j < m_methods[i].m_excCount; j++)
1003 if (!m_methods[i].m_excNames[j].isEmpty())
1005 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
1006 pInfo->m_value.aUtf8 = m_methods[i].m_excNames[j].getStr();
1007 cpIndexName = pInfo->m_index;
1009 pBuffer += writeUINT16(pBuffer, cpIndexName);
1010 cpIndexName = 0;
1014 delete[] pMethodEntrySize;
1017 // reference blop
1018 blopSize += entrySize; // referenceCount
1020 if (m_referenceCount)
1022 sal_uInt16 cpIndexName = 0;
1023 sal_uInt16 cpIndexDoku2 = 0;
1025 // nReferenceEntries + n references
1026 blopReferenceSize = entrySize + (m_referenceCount * blopReferenceEntrySize);
1028 blopSize += blopReferenceSize;
1030 pBlopReferences = new sal_uInt8[blopReferenceSize];
1031 pBuffer = pBlopReferences;
1033 pBuffer += writeUINT16(pBuffer, BLOP_REFERENCE_N_ENTRIES);
1035 for (sal_uInt16 i = 0; i < m_referenceCount; i++)
1037 pBuffer += writeUINT16(
1038 pBuffer,
1039 sal::static_int_cast< sal_uInt16 >(m_references[i].m_type));
1041 cpIndexName = 0;
1042 cpIndexDoku2 = 0;
1044 if (!m_references[i].m_name.isEmpty())
1046 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
1047 pInfo->m_value.aUtf8 = m_references[i].m_name.getStr();
1048 cpIndexName = pInfo->m_index;
1050 pBuffer += writeUINT16(pBuffer, cpIndexName);
1052 if (!m_references[i].m_doku.isEmpty())
1054 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
1055 pInfo->m_value.aUtf8 = m_references[i].m_doku.getStr();
1056 cpIndexDoku2 = pInfo->m_index;
1058 pBuffer += writeUINT16(pBuffer, cpIndexDoku2);
1060 pBuffer += writeUINT16(pBuffer, m_references[i].m_access);
1065 // get CP infos blop-length
1066 pInfo = root.m_next;
1067 sal_uInt32 cpBlopSize = 0;
1068 sal_uInt16 cpCount = 0;
1070 while (pInfo)
1072 cpBlopSize += pInfo->getBlopSize();
1073 cpCount++;
1074 pInfo = pInfo->m_next;
1077 blopSize += cpBlopSize;
1078 blopSize += sizeof(sal_uInt16); // constantPoolCount
1080 // write all in flat buffer
1082 sal_uInt8 * blop = new sal_uInt8[blopSize];
1084 pBuffer = blop;
1086 // Assumes two's complement arithmetic with modulo-semantics:
1087 pBuffer += writeUINT32(pBuffer, magic + m_version);
1088 pBuffer += writeUINT32(pBuffer, blopSize);
1089 pBuffer += writeUINT16(pBuffer, minorVersion);
1090 pBuffer += writeUINT16(pBuffer, majorVersion);
1091 pBuffer += writeUINT16(pBuffer, BLOP_HEADER_N_ENTRIES);
1093 pBuffer += writeUINT16(pBuffer, (sal_uInt16)RT_UNO_IDL);
1094 pBuffer += writeUINT16(pBuffer, (sal_uInt16)m_typeClass);
1095 pBuffer += writeUINT16(pBuffer, cpIndexThisName);
1096 pBuffer += writeUINT16(pBuffer, cpIndexUik);
1097 pBuffer += writeUINT16(pBuffer, cpIndexDoku);
1098 pBuffer += writeUINT16(pBuffer, cpIndexFileName);
1100 // write supertypes
1101 pBuffer += writeUINT16(pBuffer, m_nSuperTypes);
1102 if (m_nSuperTypes)
1104 for (sal_uInt32 i=0; i < m_nSuperTypes; i++)
1106 pBuffer += writeUINT16(pBuffer, cpIndexSuperNames[i]);
1108 delete[] cpIndexSuperNames;
1111 pBuffer += writeUINT16(pBuffer, cpCount);
1113 // write and delete CP infos
1114 pInfo = root.m_next;
1116 while (pInfo)
1118 CPInfo* pNextInfo = pInfo->m_next;
1120 pBuffer += pInfo->toBlop(pBuffer);
1121 delete pInfo;
1123 pInfo = pNextInfo;
1126 // write fields
1127 pBuffer += writeUINT16(pBuffer, m_fieldCount);
1128 if (blopFieldsSize)
1130 memcpy(pBuffer, pBlopFields, blopFieldsSize);
1131 pBuffer += blopFieldsSize;
1134 // write methods
1135 pBuffer += writeUINT16(pBuffer, m_methodCount);
1136 if (blopMethodsSize)
1138 memcpy(pBuffer, pBlopMethods, blopMethodsSize);
1139 pBuffer += blopMethodsSize;
1142 // write references
1143 pBuffer += writeUINT16(pBuffer, m_referenceCount);
1144 if (blopReferenceSize)
1146 memcpy(pBuffer, pBlopReferences, blopReferenceSize);
1147 pBuffer += blopReferenceSize;
1150 delete[] pBlopFields;
1151 delete[] pBlopMethods;
1152 delete[] pBlopReferences;
1154 delete[] m_blop;
1155 m_blop = blop;
1156 m_blopSize = blopSize;
1160 /**************************************************************************
1162 C-API
1164 **************************************************************************/
1166 extern "C" {
1168 static void TYPEREG_CALLTYPE acquire(TypeWriterImpl hEntry)
1170 TypeWriter* pEntry = (TypeWriter*) hEntry;
1172 if (pEntry != NULL)
1173 pEntry->m_refCount++;
1176 static void TYPEREG_CALLTYPE release(TypeWriterImpl hEntry)
1178 TypeWriter* pEntry = (TypeWriter*) hEntry;
1180 if (pEntry != NULL)
1182 if (--pEntry->m_refCount == 0)
1183 delete pEntry;
1187 static void TYPEREG_CALLTYPE setUik(TypeWriterImpl hEntry, const RTUik* uik)
1189 TypeWriter* pEntry = (TypeWriter*) hEntry;
1191 if (pEntry != NULL)
1193 if (pEntry->m_pUik)
1195 pEntry->m_pUik->m_Data1 = uik->m_Data1;
1196 pEntry->m_pUik->m_Data2 = uik->m_Data2;
1197 pEntry->m_pUik->m_Data3 = uik->m_Data3;
1198 pEntry->m_pUik->m_Data4 = uik->m_Data4;
1199 pEntry->m_pUik->m_Data5 = uik->m_Data5;
1201 else
1202 pEntry->m_pUik = new RTUik(*uik);
1206 static void TYPEREG_CALLTYPE setDoku(TypeWriterImpl hEntry, rtl_uString* doku)
1208 static_cast< TypeWriter * >(hEntry)->m_doku = toByteString(doku);
1211 static void TYPEREG_CALLTYPE setFileName(TypeWriterImpl hEntry, rtl_uString* fileName)
1213 static_cast< TypeWriter * >(hEntry)->m_fileName = toByteString(fileName);
1216 REG_DLLPUBLIC sal_Bool TYPEREG_CALLTYPE typereg_writer_setFieldData(
1217 void * handle, sal_uInt16 index, rtl_uString const * documentation,
1218 rtl_uString const * fileName, RTFieldAccess flags, rtl_uString const * name,
1219 rtl_uString const * typeName, RTValueType valueType,
1220 RTConstValueUnion valueValue)
1221 SAL_THROW_EXTERN_C()
1223 try {
1224 static_cast< TypeWriter * >(handle)->m_fields[index].setData(
1225 toByteString(name), toByteString(typeName),
1226 toByteString(documentation), toByteString(fileName), flags,
1227 valueType, valueValue);
1228 } catch (std::bad_alloc &) {
1229 return false;
1231 return true;
1234 static void TYPEREG_CALLTYPE setFieldData(TypeWriterImpl hEntry,
1235 sal_uInt16 index,
1236 rtl_uString* name,
1237 rtl_uString* typeName,
1238 rtl_uString* doku,
1239 rtl_uString* fileName,
1240 RTFieldAccess access,
1241 RTValueType valueType,
1242 RTConstValueUnion constValue)
1244 typereg_writer_setFieldData(
1245 hEntry, index, doku, fileName, access, name, typeName, valueType,
1246 constValue);
1249 REG_DLLPUBLIC sal_Bool TYPEREG_CALLTYPE typereg_writer_setMethodData(
1250 void * handle, sal_uInt16 index, rtl_uString const * documentation,
1251 RTMethodMode flags, rtl_uString const * name,
1252 rtl_uString const * returnTypeName, sal_uInt16 parameterCount,
1253 sal_uInt16 exceptionCount)
1254 SAL_THROW_EXTERN_C()
1256 try {
1257 static_cast< TypeWriter * >(handle)->m_methods[index].setData(
1258 toByteString(name), toByteString(returnTypeName), flags,
1259 parameterCount, exceptionCount, toByteString(documentation));
1260 } catch (std::bad_alloc &) {
1261 return false;
1263 return true;
1266 static void TYPEREG_CALLTYPE setMethodData(TypeWriterImpl hEntry,
1267 sal_uInt16 index,
1268 rtl_uString* name,
1269 rtl_uString* returnTypeName,
1270 RTMethodMode mode,
1271 sal_uInt16 paramCount,
1272 sal_uInt16 excCount,
1273 rtl_uString* doku)
1275 typereg_writer_setMethodData(
1276 hEntry, index, doku, mode, name, returnTypeName, paramCount, excCount);
1279 REG_DLLPUBLIC sal_Bool TYPEREG_CALLTYPE typereg_writer_setMethodParameterData(
1280 void * handle, sal_uInt16 methodIndex, sal_uInt16 parameterIndex,
1281 RTParamMode flags, rtl_uString const * name, rtl_uString const * typeName)
1282 SAL_THROW_EXTERN_C()
1284 try {
1285 static_cast< TypeWriter * >(handle)->
1286 m_methods[methodIndex].m_params[parameterIndex].setData(
1287 toByteString(typeName), toByteString(name), flags);
1288 } catch (std::bad_alloc &) {
1289 return false;
1291 return true;
1294 static void TYPEREG_CALLTYPE setParamData(TypeWriterImpl hEntry,
1295 sal_uInt16 index,
1296 sal_uInt16 paramIndex,
1297 rtl_uString* type,
1298 rtl_uString* name,
1299 RTParamMode mode)
1301 typereg_writer_setMethodParameterData(
1302 hEntry, index, paramIndex, mode, name, type);
1305 REG_DLLPUBLIC sal_Bool TYPEREG_CALLTYPE typereg_writer_setMethodExceptionTypeName(
1306 void * handle, sal_uInt16 methodIndex, sal_uInt16 exceptionIndex,
1307 rtl_uString const * typeName)
1308 SAL_THROW_EXTERN_C()
1310 try {
1311 static_cast< TypeWriter * >(handle)->m_methods[methodIndex].setExcName(
1312 exceptionIndex, toByteString(typeName));
1313 } catch (std::bad_alloc &) {
1314 return false;
1316 return true;
1319 static void TYPEREG_CALLTYPE setExcData(TypeWriterImpl hEntry,
1320 sal_uInt16 index,
1321 sal_uInt16 excIndex,
1322 rtl_uString* type)
1324 typereg_writer_setMethodExceptionTypeName(hEntry, index, excIndex, type);
1327 REG_DLLPUBLIC void const * TYPEREG_CALLTYPE typereg_writer_getBlob(void * handle, sal_uInt32 * size)
1328 SAL_THROW_EXTERN_C()
1330 TypeWriter * writer = static_cast< TypeWriter * >(handle);
1331 if (writer->m_blop == 0) {
1332 try {
1333 writer->createBlop();
1334 } catch (std::bad_alloc &) {
1335 return 0;
1338 *size = writer->m_blopSize;
1339 return writer->m_blop;
1342 static const sal_uInt8* TYPEREG_CALLTYPE getBlop(TypeWriterImpl hEntry)
1344 sal_uInt32 size;
1345 return static_cast< sal_uInt8 const * >(
1346 typereg_writer_getBlob(hEntry, &size));
1349 static sal_uInt32 TYPEREG_CALLTYPE getBlopSize(TypeWriterImpl hEntry)
1351 sal_uInt32 size;
1352 typereg_writer_getBlob(hEntry, &size);
1353 return size;
1356 REG_DLLPUBLIC sal_Bool TYPEREG_CALLTYPE typereg_writer_setReferenceData(
1357 void * handle, sal_uInt16 index, rtl_uString const * documentation,
1358 RTReferenceType sort, RTFieldAccess flags, rtl_uString const * typeName)
1359 SAL_THROW_EXTERN_C()
1361 try {
1362 static_cast< TypeWriter * >(handle)->m_references[index].setData(
1363 toByteString(typeName), sort, toByteString(documentation), flags);
1364 } catch (std::bad_alloc &) {
1365 return false;
1367 return true;
1370 static void TYPEREG_CALLTYPE setReferenceData(TypeWriterImpl hEntry,
1371 sal_uInt16 index,
1372 rtl_uString* name,
1373 RTReferenceType refType,
1374 rtl_uString* doku,
1375 RTFieldAccess access)
1377 typereg_writer_setReferenceData(hEntry, index, doku, refType, access, name);
1380 REG_DLLPUBLIC void * TYPEREG_CALLTYPE typereg_writer_create(
1381 typereg_Version version, rtl_uString const * documentation,
1382 rtl_uString const * fileName, RTTypeClass typeClass, sal_Bool published,
1383 rtl_uString const * typeName, sal_uInt16 superTypeCount,
1384 sal_uInt16 fieldCount, sal_uInt16 methodCount, sal_uInt16 referenceCount)
1385 SAL_THROW_EXTERN_C()
1387 try {
1388 return new TypeWriter(
1389 version, toByteString(documentation), toByteString(fileName),
1390 typeClass, published, toByteString(typeName), superTypeCount,
1391 fieldCount, methodCount, referenceCount);
1392 } catch (std::bad_alloc &) {
1393 return 0;
1397 REG_DLLPUBLIC void TYPEREG_CALLTYPE typereg_writer_destroy(void * handle) SAL_THROW_EXTERN_C() {
1398 delete static_cast< TypeWriter * >(handle);
1401 REG_DLLPUBLIC sal_Bool TYPEREG_CALLTYPE typereg_writer_setSuperTypeName(
1402 void * handle, sal_uInt16 index, rtl_uString const * typeName)
1403 SAL_THROW_EXTERN_C()
1405 try {
1406 static_cast< TypeWriter * >(handle)->setSuperType(
1407 index, toByteString(typeName));
1408 } catch (std::bad_alloc &) {
1409 return false;
1411 return true;
1414 static TypeWriterImpl TYPEREG_CALLTYPE createEntry(
1415 RTTypeClass typeClass, rtl_uString * typeName, rtl_uString * superTypeName,
1416 sal_uInt16 fieldCount, sal_uInt16 methodCount, sal_uInt16 referenceCount)
1418 OUString empty;
1419 sal_uInt16 superTypeCount = rtl_uString_getLength(superTypeName) == 0
1420 ? 0 : 1;
1421 TypeWriterImpl t = typereg_writer_create(
1422 TYPEREG_VERSION_0, empty.pData, empty.pData, typeClass, false, typeName,
1423 superTypeCount, fieldCount, methodCount, referenceCount);
1424 if (superTypeCount > 0) {
1425 typereg_writer_setSuperTypeName(t, 0, superTypeName);
1427 return t;
1430 REG_DLLPUBLIC RegistryTypeWriter_Api* TYPEREG_CALLTYPE initRegistryTypeWriter_Api(void)
1432 static RegistryTypeWriter_Api aApi= {0,0,0,0,0,0,0,0,0,0,0,0,0};
1433 if (!aApi.acquire)
1435 aApi.createEntry = &createEntry;
1436 aApi.acquire = &acquire;
1437 aApi.release = &release;
1438 aApi.setUik = &setUik;
1439 aApi.setDoku = &setDoku;
1440 aApi.setFileName = &setFileName;
1441 aApi.setFieldData = &setFieldData;
1442 aApi.setMethodData = &setMethodData;
1443 aApi.setParamData = &setParamData;
1444 aApi.setExcData = &setExcData;
1445 aApi.getBlop = &getBlop;
1446 aApi.getBlopSize = &getBlopSize;
1447 aApi.setReferenceData = &setReferenceData;
1449 return (&aApi);
1451 else
1453 return (&aApi);
1459 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */