1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
24 #include <sal/types.h>
25 #include <sal/macros.h>
26 #include <osl/endian.h>
27 #include <rtl/alloc.h>
28 #include <rtl/string.hxx>
29 #include <rtl/ustring.hxx>
31 #include "reflwrit.hxx"
32 #include <registry/version.h>
33 #include <registry/writer.h>
35 #include "reflcnst.hxx"
40 inline OString
toByteString(rtl_uString
const * str
) {
42 str
->buffer
, str
->length
, RTL_TEXTENCODING_UTF8
,
43 OUSTRING_TO_OSTRING_CVTFLAGS
);
48 static sal_Unicode NULL_WSTRING
[1] = { 0 };
50 #define BLOP_OFFSET_MAGIC 0
51 #define BLOP_OFFSET_SIZE (BLOP_OFFSET_MAGIC + sizeof(sal_uInt32))
52 #define BLOP_OFFSET_MINOR (BLOP_OFFSET_SIZE + sizeof(sal_uInt32))
53 #define BLOP_OFFSET_MAJOR (BLOP_OFFSET_MINOR + sizeof(sal_uInt16))
54 #define BLOP_OFFSET_N_ENTRIES (BLOP_OFFSET_MAJOR + sizeof(sal_uInt16))
55 #define BLOP_HEADER_N_ENTRIES 6
57 #define BLOP_FIELD_N_ENTRIES 6
59 #define BLOP_METHOD_N_ENTRIES 5
61 #define BLOP_PARAM_N_ENTRIES 3
63 #define BLOP_REFERENCE_N_ENTRIES 4
65 sal_uInt32
UINT16StringLen(const sal_uInt8
* wstring
)
67 if (!wstring
) return 0;
69 const sal_uInt8
* b
= wstring
;
71 while (b
[0] || b
[1]) b
+= sizeof(sal_uInt16
);
73 return ((b
- wstring
) / sizeof(sal_uInt16
));
76 sal_uInt32
writeString(sal_uInt8
* buffer
, const sal_Unicode
* v
)
78 sal_uInt32 len
= rtl_ustr_getLength(v
) + 1;
80 sal_uInt8
* buff
= buffer
;
82 for (i
= 0; i
< len
; i
++)
84 buff
+= writeUINT16(buff
, static_cast<sal_uInt16
>(v
[i
]));
87 return (buff
- buffer
);
90 sal_uInt32
readString(const sal_uInt8
* buffer
, sal_Unicode
* v
, sal_uInt32 maxSize
)
92 sal_uInt32 len
= UINT16StringLen(buffer
) + 1;
94 sal_uInt8
* buff
= const_cast<sal_uInt8
*>(buffer
);
101 for (i
= 0; i
< (len
- 1); i
++)
105 buff
+= readUINT16(buff
, aChar
);
107 v
[i
] = static_cast<sal_Unicode
>(aChar
);
112 return (buff
- buffer
);
115 sal_uInt32
writeFloat(sal_uInt8
* buffer
, float v
)
125 #ifdef REGTYPE_IEEE_NATIVE
126 writeUINT32(buffer
, x
.b
);
131 return sizeof(sal_uInt32
);
134 sal_uInt32
writeDouble(sal_uInt8
* buffer
, double v
)
148 #ifdef REGTYPE_IEEE_NATIVE
149 # ifdef OSL_BIGENDIAN
150 writeUINT32(buffer
, x
.b
.b1
);
151 writeUINT32(buffer
+ sizeof(sal_uInt32
), x
.b
.b2
);
153 writeUINT32(buffer
, x
.b
.b2
);
154 writeUINT32(buffer
+ sizeof(sal_uInt32
), x
.b
.b1
);
160 return (sizeof(sal_uInt32
) + sizeof(sal_uInt32
));
163 /**************************************************************************
165 buffer write functions
167 **************************************************************************/
170 /**************************************************************************
174 **************************************************************************/
181 const sal_Char
* aUtf8
;
183 RTConstValueUnion aConst
;
187 struct CPInfo
* m_next
;
189 CPInfo(CPInfoTag tag
, struct CPInfo
* prev
);
191 sal_uInt32
getBlopSize() const;
193 sal_uInt32
toBlop(sal_uInt8
* buffer
);
196 CPInfo::CPInfo(CPInfoTag tag
, struct CPInfo
* prev
)
203 m_index
= prev
->m_index
+ 1;
208 sal_uInt32
CPInfo::getBlopSize() const
210 sal_uInt32 size
= sizeof(sal_uInt32
) /* size */ + sizeof(sal_uInt16
) /* tag */;
214 case CP_TAG_CONST_BOOL
:
215 size
+= sizeof(sal_uInt8
);
217 case CP_TAG_CONST_BYTE
:
218 size
+= sizeof(sal_uInt8
);
220 case CP_TAG_CONST_INT16
:
221 size
+= sizeof(sal_Int16
);
223 case CP_TAG_CONST_UINT16
:
224 size
+= sizeof(sal_uInt16
);
226 case CP_TAG_CONST_INT32
:
227 size
+= sizeof(sal_Int32
);
229 case CP_TAG_CONST_UINT32
:
230 size
+= sizeof(sal_uInt32
);
232 case CP_TAG_CONST_INT64
:
233 size
+= sizeof(sal_Int64
);
235 case CP_TAG_CONST_UINT64
:
236 size
+= sizeof(sal_uInt64
);
238 case CP_TAG_CONST_FLOAT
:
239 size
+= sizeof(sal_uInt32
);
241 case CP_TAG_CONST_DOUBLE
:
242 size
+= sizeof(sal_uInt32
) + sizeof(sal_uInt32
);
244 case CP_TAG_CONST_STRING
:
245 size
+= (rtl_ustr_getLength(m_value
.aConst
.aString
) + 1) * sizeof(sal_uInt16
);
247 case CP_TAG_UTF8_NAME
:
248 size
+= strlen(m_value
.aUtf8
) + 1;
251 size
+= sizeof(sal_uInt32
) + sizeof(sal_uInt16
) + sizeof(sal_uInt16
) + sizeof(sal_uInt32
) + sizeof(sal_uInt32
);
261 sal_uInt32
CPInfo::toBlop(sal_uInt8
* buffer
)
263 sal_uInt8
* buff
= buffer
;
265 buff
+= writeUINT32(buff
, getBlopSize());
266 buff
+= writeUINT16(buff
, static_cast<sal_uInt16
>(m_tag
));
270 case CP_TAG_CONST_BOOL
:
271 buff
+= writeBYTE(buff
, static_cast<sal_uInt8
>(m_value
.aConst
.aBool
));
273 case CP_TAG_CONST_BYTE
:
275 buff
, static_cast< sal_uInt8
>(m_value
.aConst
.aByte
));
277 case CP_TAG_CONST_INT16
:
278 buff
+= writeINT16(buff
, m_value
.aConst
.aShort
);
280 case CP_TAG_CONST_UINT16
:
281 buff
+= writeINT16(buff
, m_value
.aConst
.aUShort
);
283 case CP_TAG_CONST_INT32
:
284 buff
+= writeINT32(buff
, m_value
.aConst
.aLong
);
286 case CP_TAG_CONST_UINT32
:
287 buff
+= writeUINT32(buff
, m_value
.aConst
.aULong
);
289 case CP_TAG_CONST_INT64
:
290 buff
+= writeUINT64(buff
, m_value
.aConst
.aHyper
);
292 case CP_TAG_CONST_UINT64
:
293 buff
+= writeUINT64(buff
, m_value
.aConst
.aUHyper
);
295 case CP_TAG_CONST_FLOAT
:
296 buff
+= writeFloat(buff
, m_value
.aConst
.aFloat
);
298 case CP_TAG_CONST_DOUBLE
:
299 buff
+= writeDouble(buff
, m_value
.aConst
.aDouble
);
301 case CP_TAG_CONST_STRING
:
302 buff
+= writeString(buff
, m_value
.aConst
.aString
);
304 case CP_TAG_UTF8_NAME
:
305 buff
+= writeUtf8(buff
, m_value
.aUtf8
);
308 buff
+= writeUINT32(buff
, m_value
.aUik
->m_Data1
);
309 buff
+= writeUINT16(buff
, m_value
.aUik
->m_Data2
);
310 buff
+= writeUINT16(buff
, m_value
.aUik
->m_Data3
);
311 buff
+= writeUINT32(buff
, m_value
.aUik
->m_Data4
);
312 buff
+= writeUINT32(buff
, m_value
.aUik
->m_Data5
);
318 return (buff
- buffer
);
322 /**************************************************************************
326 **************************************************************************/
337 RTFieldAccess m_access
;
338 RTValueType m_constValueType
;
339 RTConstValueUnion m_constValue
;
344 void setData(const OString
& name
,
345 const OString
& typeName
,
347 const OString
& fileName
,
348 RTFieldAccess access
,
349 RTValueType constValueType
,
350 RTConstValueUnion constValue
);
351 // throws std::bad_alloc
354 FieldEntry::FieldEntry()
355 : m_access(RTFieldAccess::INVALID
)
356 , m_constValueType(RT_TYPE_NONE
)
360 FieldEntry::~FieldEntry()
363 (m_constValueType
== RT_TYPE_STRING
) &&
364 m_constValue
.aString
&&
365 (m_constValue
.aString
!= NULL_WSTRING
)
368 delete[] m_constValue
.aString
;
372 void FieldEntry::setData(const OString
& name
,
373 const OString
& typeName
,
375 const OString
& fileName
,
376 RTFieldAccess access
,
377 RTValueType constValueType
,
378 RTConstValueUnion constValue
)
380 sal_Unicode
* newValue
= nullptr;
381 if (constValueType
== RT_TYPE_STRING
&& constValue
.aString
!= nullptr) {
382 sal_Int32 n
= rtl_ustr_getLength(constValue
.aString
) + 1;
383 newValue
= new sal_Unicode
[n
];
384 memcpy(newValue
, constValue
.aString
, n
* sizeof (sal_Unicode
));
388 m_typeName
= typeName
;
390 m_fileName
= fileName
;
393 (m_constValueType
== RT_TYPE_STRING
) &&
394 m_constValue
.aString
&&
395 (m_constValue
.aString
!= NULL_WSTRING
)
398 delete[] m_constValue
.aString
;
402 m_constValueType
= constValueType
;
404 if (m_constValueType
== RT_TYPE_STRING
)
406 if (constValue
.aString
== nullptr)
407 m_constValue
.aString
= NULL_WSTRING
;
410 m_constValue
.aString
= newValue
;
415 m_constValue
= constValue
;
419 /**************************************************************************
423 **************************************************************************/
435 void setData(const OString
& typeName
,
440 ParamEntry::ParamEntry()
441 : m_mode(RT_PARAM_INVALID
)
445 void ParamEntry::setData(const OString
& typeName
,
450 m_typeName
= typeName
;
454 /**************************************************************************
458 **************************************************************************/
466 RTReferenceType m_type
;
467 RTFieldAccess m_access
;
471 void setData(const OString
& name
,
472 RTReferenceType refType
,
474 RTFieldAccess access
);
477 ReferenceEntry::ReferenceEntry()
478 : m_type(RTReferenceType::INVALID
)
479 , m_access(RTFieldAccess::INVALID
)
483 void ReferenceEntry::setData(const OString
& name
,
484 RTReferenceType refType
,
486 RTFieldAccess access
)
494 /**************************************************************************
498 **************************************************************************/
505 OString m_returnTypeName
;
507 sal_uInt16 m_paramCount
;
508 std::unique_ptr
<ParamEntry
[]> m_params
;
509 sal_uInt16 m_excCount
;
510 std::unique_ptr
<OString
[]> m_excNames
;
515 void setData(const OString
& name
,
516 const OString
& returnTypeName
,
518 sal_uInt16 paramCount
,
520 const OString
& doku
);
522 void setExcName(sal_uInt16 excIndex
, const OString
& name
) const;
526 void reallocParams(sal_uInt16 size
);
527 void reallocExcs(sal_uInt16 size
);
530 MethodEntry::MethodEntry()
531 : m_mode(RTMethodMode::INVALID
)
537 void MethodEntry::setData(const OString
& name
,
538 const OString
& returnTypeName
,
540 sal_uInt16 paramCount
,
545 m_returnTypeName
= returnTypeName
;
550 reallocParams(paramCount
);
551 reallocExcs(excCount
);
554 void MethodEntry::setExcName(sal_uInt16 excIndex
, const OString
& name
) const
556 if (excIndex
< m_excCount
)
558 m_excNames
[excIndex
] = name
;
562 void MethodEntry::reallocParams(sal_uInt16 size
)
564 ParamEntry
* newParams
;
567 newParams
= new ParamEntry
[size
];
574 sal_uInt16 mn
= std::min(size
, m_paramCount
);
576 for (i
= 0; i
< mn
; i
++)
578 newParams
[i
].setData(m_params
[i
].m_typeName
, m_params
[i
].m_name
, m_params
[i
].m_mode
);
585 m_params
.reset( newParams
);
588 void MethodEntry::reallocExcs(sal_uInt16 size
)
590 OString
* newExcNames
;
593 newExcNames
= new OString
[size
];
595 newExcNames
= nullptr;
598 sal_uInt16 mn
= std::min(size
, m_excCount
);
600 for (i
= 0; i
< mn
; i
++)
602 newExcNames
[i
] = m_excNames
[i
];
606 m_excNames
.reset( newExcNames
);
610 /**************************************************************************
612 class TypeRegistryEntry
614 **************************************************************************/
621 sal_uInt32 m_refCount
;
622 typereg_Version m_version
;
623 RTTypeClass m_typeClass
;
625 sal_uInt16 m_nSuperTypes
;
626 std::unique_ptr
<OString
[]>
630 sal_uInt16 m_fieldCount
;
631 FieldEntry
* m_fields
;
632 sal_uInt16 m_methodCount
;
633 MethodEntry
* m_methods
;
634 sal_uInt16 m_referenceCount
;
635 ReferenceEntry
* m_references
;
637 std::unique_ptr
<sal_uInt8
[]> m_blop
;
638 sal_uInt32 m_blopSize
;
640 TypeWriter(typereg_Version version
,
641 OString
const & documentation
,
642 OString
const & fileName
,
643 RTTypeClass RTTypeClass
,
645 const OString
& typeName
,
646 sal_uInt16 superTypeCount
,
647 sal_uInt16 FieldCount
,
648 sal_uInt16 methodCount
,
649 sal_uInt16 referenceCount
);
653 void setSuperType(sal_uInt16 index
, OString
const & name
) const;
655 void createBlop(); // throws std::bad_alloc
658 TypeWriter::TypeWriter(typereg_Version version
,
659 OString
const & documentation
,
660 OString
const & fileName
,
661 RTTypeClass RTTypeClass
,
663 const OString
& typeName
,
664 sal_uInt16 superTypeCount
,
665 sal_uInt16 fieldCount
,
666 sal_uInt16 methodCount
,
667 sal_uInt16 referenceCount
)
671 static_cast< enum RTTypeClass
>(
672 RTTypeClass
| (published
? RT_TYPE_PUBLISHED
: 0)))
673 , m_typeName(typeName
)
674 , m_nSuperTypes(superTypeCount
)
675 , m_doku(documentation
)
676 , m_fileName(fileName
)
677 , m_fieldCount(fieldCount
)
679 , m_methodCount(methodCount
)
681 , m_referenceCount(referenceCount
)
682 , m_references(nullptr)
685 if (m_nSuperTypes
> 0)
687 m_superTypeNames
.reset( new OString
[m_nSuperTypes
] );
691 m_fields
= new FieldEntry
[fieldCount
];
694 m_methods
= new MethodEntry
[methodCount
];
696 if (m_referenceCount
)
697 m_references
= new ReferenceEntry
[referenceCount
];
700 TypeWriter::~TypeWriter()
708 if (m_referenceCount
)
709 delete[] m_references
;
712 void TypeWriter::setSuperType(sal_uInt16 index
, OString
const & name
) const
714 m_superTypeNames
[index
] = name
;
717 void TypeWriter::createBlop()
719 //TODO: Fix memory leaks that occur when std::bad_alloc is thrown
721 sal_uInt8
* pBlopFields
= nullptr;
722 sal_uInt8
* pBlopMethods
= nullptr;
723 sal_uInt8
* pBlopReferences
= nullptr;
724 sal_uInt8
* pBuffer
= nullptr;
725 sal_uInt32 blopFieldsSize
= 0;
726 sal_uInt32 blopMethodsSize
= 0;
727 sal_uInt32 blopReferenceSize
= 0;
729 CPInfo
root(CP_TAG_INVALID
, nullptr);
730 sal_uInt16 cpIndexThisName
= 0;
731 sal_uInt16
* cpIndexSuperNames
= nullptr;
732 sal_uInt16 cpIndexDoku
= 0;
733 sal_uInt16 cpIndexFileName
= 0;
734 CPInfo
* pInfo
= nullptr;
736 sal_uInt16 entrySize
= sizeof(sal_uInt16
);
737 sal_uInt32 blopHeaderEntrySize
= BLOP_OFFSET_N_ENTRIES
+ entrySize
+ (BLOP_HEADER_N_ENTRIES
* entrySize
);
738 sal_uInt32 blopFieldEntrySize
= BLOP_FIELD_N_ENTRIES
* entrySize
;
739 sal_uInt32 blopMethodEntrySize
= BLOP_METHOD_N_ENTRIES
* entrySize
;
740 sal_uInt32 blopParamEntrySize
= BLOP_PARAM_N_ENTRIES
* entrySize
;
741 sal_uInt32 blopReferenceEntrySize
= BLOP_REFERENCE_N_ENTRIES
* entrySize
;
743 sal_uInt32 blopSize
= blopHeaderEntrySize
;
745 // create CP entry for this name
746 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, &root
);
747 pInfo
->m_value
.aUtf8
= m_typeName
.getStr();
748 cpIndexThisName
= pInfo
->m_index
;
751 blopSize
+= entrySize
;
753 // create CP entry for super names
756 blopSize
+= m_nSuperTypes
* entrySize
;
758 cpIndexSuperNames
= new sal_uInt16
[m_nSuperTypes
];
760 for (sal_uInt32 i
=0; i
< m_nSuperTypes
; i
++)
762 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
763 pInfo
->m_value
.aUtf8
= m_superTypeNames
[i
].getStr();
764 cpIndexSuperNames
[i
] = pInfo
->m_index
;
768 // create CP entry for doku
769 if (!m_doku
.isEmpty())
771 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
772 pInfo
->m_value
.aUtf8
= m_doku
.getStr();
773 cpIndexDoku
= pInfo
->m_index
;
776 // create CP entry for idl source filename
777 if (!m_fileName
.isEmpty())
779 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
780 pInfo
->m_value
.aUtf8
= m_fileName
.getStr();
781 cpIndexFileName
= pInfo
->m_index
;
785 blopSize
+= sizeof(sal_uInt16
); // fieldCount + nFieldEntries
789 sal_uInt16 cpIndexName
= 0;
790 sal_uInt16 cpIndexTypeName
= 0;
791 sal_uInt16 cpIndexValue
= 0;
792 sal_uInt16 cpIndexDoku2
= 0;
793 sal_uInt16 cpIndexFileName2
= 0;
795 // nFieldEntries + n fields
796 blopFieldsSize
= sizeof(sal_uInt16
) + (m_fieldCount
* blopFieldEntrySize
);
798 blopSize
+= blopFieldsSize
;
800 pBlopFields
= new sal_uInt8
[blopFieldsSize
];
801 pBuffer
= pBlopFields
;
803 pBuffer
+= writeUINT16(pBuffer
, BLOP_FIELD_N_ENTRIES
);
805 for (sal_uInt16 i
= 0; i
< m_fieldCount
; i
++)
811 cpIndexFileName2
= 0;
813 pBuffer
+= writeUINT16(pBuffer
, static_cast<sal_uInt16
>(m_fields
[i
].m_access
));
815 if (!m_fields
[i
].m_name
.isEmpty())
817 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
818 pInfo
->m_value
.aUtf8
= m_fields
[i
].m_name
.getStr();
819 cpIndexName
= pInfo
->m_index
;
821 pBuffer
+= writeUINT16(pBuffer
, cpIndexName
);
823 if (!m_fields
[i
].m_typeName
.isEmpty())
825 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
826 pInfo
->m_value
.aUtf8
= m_fields
[i
].m_typeName
.getStr();
827 cpIndexTypeName
= pInfo
->m_index
;
829 pBuffer
+= writeUINT16(pBuffer
, cpIndexTypeName
);
831 if (m_fields
[i
].m_constValueType
!= RT_TYPE_NONE
)
833 pInfo
= new CPInfo(static_cast<CPInfoTag
>(m_fields
[i
].m_constValueType
), pInfo
);
834 pInfo
->m_value
.aConst
= m_fields
[i
].m_constValue
;
835 cpIndexValue
= pInfo
->m_index
;
837 pBuffer
+= writeUINT16(pBuffer
, cpIndexValue
);
839 if (!m_fields
[i
].m_doku
.isEmpty())
841 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
842 pInfo
->m_value
.aUtf8
= m_fields
[i
].m_doku
.getStr();
843 cpIndexDoku2
= pInfo
->m_index
;
845 pBuffer
+= writeUINT16(pBuffer
, cpIndexDoku2
);
847 if (!m_fields
[i
].m_fileName
.isEmpty())
849 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
850 pInfo
->m_value
.aUtf8
= m_fields
[i
].m_fileName
.getStr();
851 cpIndexFileName2
= pInfo
->m_index
;
853 pBuffer
+= writeUINT16(pBuffer
, cpIndexFileName2
);
858 blopSize
+= sizeof(sal_uInt16
); // methodCount
862 std::unique_ptr
<sal_uInt16
[]> pMethodEntrySize( new sal_uInt16
[m_methodCount
] );
863 sal_uInt16 cpIndexName
= 0;
864 sal_uInt16 cpIndexReturn
= 0;
865 sal_uInt16 cpIndexDoku2
= 0;
867 // nMethodEntries + nParamEntries
868 blopMethodsSize
= (2 * sizeof(sal_uInt16
));
870 for (sal_uInt16 i
= 0; i
< m_methodCount
; i
++)
872 pMethodEntrySize
[i
] = static_cast<sal_uInt16
>( blopMethodEntrySize
+ // header
873 sizeof(sal_uInt16
) + // parameterCount
874 (m_methods
[i
].m_paramCount
* blopParamEntrySize
) + // exceptions
875 sizeof(sal_uInt16
) + // exceptionCount
876 (m_methods
[i
].m_excCount
* sizeof(sal_uInt16
)) ); // exceptions
878 blopMethodsSize
+= pMethodEntrySize
[i
];
881 pBlopMethods
= new sal_uInt8
[blopMethodsSize
];
883 blopSize
+= blopMethodsSize
;
885 pBuffer
= pBlopMethods
;
887 pBuffer
+= writeUINT16(pBuffer
, BLOP_METHOD_N_ENTRIES
);
888 pBuffer
+= writeUINT16(pBuffer
, BLOP_PARAM_N_ENTRIES
);
890 for (sal_uInt16 i
= 0; i
< m_methodCount
; i
++)
895 pBuffer
+= writeUINT16(pBuffer
, pMethodEntrySize
[i
]);
896 pBuffer
+= writeUINT16(
898 sal::static_int_cast
< sal_uInt16
>(m_methods
[i
].m_mode
));
900 if (!m_methods
[i
].m_name
.isEmpty())
902 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
903 pInfo
->m_value
.aUtf8
= m_methods
[i
].m_name
.getStr();
904 cpIndexName
= pInfo
->m_index
;
906 pBuffer
+= writeUINT16(pBuffer
, cpIndexName
);
909 if (!m_methods
[i
].m_returnTypeName
.isEmpty())
911 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
912 pInfo
->m_value
.aUtf8
= m_methods
[i
].m_returnTypeName
.getStr();
913 cpIndexReturn
= pInfo
->m_index
;
915 pBuffer
+= writeUINT16(pBuffer
, cpIndexReturn
);
917 if (!m_methods
[i
].m_doku
.isEmpty())
919 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
920 pInfo
->m_value
.aUtf8
= m_methods
[i
].m_doku
.getStr();
921 cpIndexDoku2
= pInfo
->m_index
;
923 pBuffer
+= writeUINT16(pBuffer
, cpIndexDoku2
);
927 pBuffer
+= writeUINT16(pBuffer
, m_methods
[i
].m_paramCount
);
929 for (j
= 0; j
< m_methods
[i
].m_paramCount
; j
++)
931 if (!m_methods
[i
].m_params
[j
].m_typeName
.isEmpty())
933 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
934 pInfo
->m_value
.aUtf8
= m_methods
[i
].m_params
[j
].m_typeName
.getStr();
935 cpIndexName
= pInfo
->m_index
;
937 pBuffer
+= writeUINT16(pBuffer
, cpIndexName
);
940 pBuffer
+= writeUINT16(
942 sal::static_int_cast
< sal_uInt16
>(
943 m_methods
[i
].m_params
[j
].m_mode
));
945 if (!m_methods
[i
].m_params
[j
].m_name
.isEmpty())
947 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
948 pInfo
->m_value
.aUtf8
= m_methods
[i
].m_params
[j
].m_name
.getStr();
949 cpIndexName
= pInfo
->m_index
;
951 pBuffer
+= writeUINT16(pBuffer
, cpIndexName
);
955 pBuffer
+= writeUINT16(pBuffer
, m_methods
[i
].m_excCount
);
957 for (j
= 0; j
< m_methods
[i
].m_excCount
; j
++)
959 if (!m_methods
[i
].m_excNames
[j
].isEmpty())
961 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
962 pInfo
->m_value
.aUtf8
= m_methods
[i
].m_excNames
[j
].getStr();
963 cpIndexName
= pInfo
->m_index
;
965 pBuffer
+= writeUINT16(pBuffer
, cpIndexName
);
972 blopSize
+= entrySize
; // referenceCount
974 if (m_referenceCount
)
976 sal_uInt16 cpIndexName
= 0;
977 sal_uInt16 cpIndexDoku2
= 0;
979 // nReferenceEntries + n references
980 blopReferenceSize
= entrySize
+ (m_referenceCount
* blopReferenceEntrySize
);
982 blopSize
+= blopReferenceSize
;
984 pBlopReferences
= new sal_uInt8
[blopReferenceSize
];
985 pBuffer
= pBlopReferences
;
987 pBuffer
+= writeUINT16(pBuffer
, BLOP_REFERENCE_N_ENTRIES
);
989 for (sal_uInt16 i
= 0; i
< m_referenceCount
; i
++)
991 pBuffer
+= writeUINT16(
993 sal::static_int_cast
< sal_uInt16
>(m_references
[i
].m_type
));
998 if (!m_references
[i
].m_name
.isEmpty())
1000 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
1001 pInfo
->m_value
.aUtf8
= m_references
[i
].m_name
.getStr();
1002 cpIndexName
= pInfo
->m_index
;
1004 pBuffer
+= writeUINT16(pBuffer
, cpIndexName
);
1006 if (!m_references
[i
].m_doku
.isEmpty())
1008 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
1009 pInfo
->m_value
.aUtf8
= m_references
[i
].m_doku
.getStr();
1010 cpIndexDoku2
= pInfo
->m_index
;
1012 pBuffer
+= writeUINT16(pBuffer
, cpIndexDoku2
);
1014 pBuffer
+= writeUINT16(pBuffer
, static_cast<sal_uInt16
>(m_references
[i
].m_access
));
1019 // get CP infos blop-length
1020 pInfo
= root
.m_next
;
1021 sal_uInt32 cpBlopSize
= 0;
1022 sal_uInt16 cpCount
= 0;
1026 cpBlopSize
+= pInfo
->getBlopSize();
1028 pInfo
= pInfo
->m_next
;
1031 blopSize
+= cpBlopSize
;
1032 blopSize
+= sizeof(sal_uInt16
); // constantPoolCount
1034 // write all in flat buffer
1036 sal_uInt8
* blop
= new sal_uInt8
[blopSize
];
1040 // Assumes two's complement arithmetic with modulo-semantics:
1041 pBuffer
+= writeUINT32(pBuffer
, magic
+ m_version
);
1042 pBuffer
+= writeUINT32(pBuffer
, blopSize
);
1043 pBuffer
+= writeUINT16(pBuffer
, minorVersion
);
1044 pBuffer
+= writeUINT16(pBuffer
, majorVersion
);
1045 pBuffer
+= writeUINT16(pBuffer
, BLOP_HEADER_N_ENTRIES
);
1047 pBuffer
+= writeUINT16(pBuffer
, sal_uInt16(RT_UNO_IDL
));
1048 pBuffer
+= writeUINT16(pBuffer
, static_cast<sal_uInt16
>(m_typeClass
));
1049 pBuffer
+= writeUINT16(pBuffer
, cpIndexThisName
);
1050 pBuffer
+= writeUINT16(pBuffer
, 0); // cpIndexUik
1051 pBuffer
+= writeUINT16(pBuffer
, cpIndexDoku
);
1052 pBuffer
+= writeUINT16(pBuffer
, cpIndexFileName
);
1055 pBuffer
+= writeUINT16(pBuffer
, m_nSuperTypes
);
1058 for (sal_uInt32 i
=0; i
< m_nSuperTypes
; i
++)
1060 pBuffer
+= writeUINT16(pBuffer
, cpIndexSuperNames
[i
]);
1062 delete[] cpIndexSuperNames
;
1065 pBuffer
+= writeUINT16(pBuffer
, cpCount
);
1067 // write and delete CP infos
1068 pInfo
= root
.m_next
;
1072 CPInfo
* pNextInfo
= pInfo
->m_next
;
1074 pBuffer
+= pInfo
->toBlop(pBuffer
);
1080 auto writeList
= [&pBuffer
](
1081 sal_uInt16 count
, sal_uInt8
* data
, sal_uInt32 size
)
1083 pBuffer
+= writeUINT16(pBuffer
, count
);
1085 memcpy(pBuffer
, data
, size
);
1091 writeList(m_fieldCount
, pBlopFields
, blopFieldsSize
);
1094 writeList(m_methodCount
, pBlopMethods
, blopMethodsSize
);
1097 writeList(m_referenceCount
, pBlopReferences
, blopReferenceSize
);
1099 delete[] pBlopFields
;
1100 delete[] pBlopMethods
;
1101 delete[] pBlopReferences
;
1103 m_blop
.reset( blop
);
1104 m_blopSize
= blopSize
;
1108 /**************************************************************************
1112 **************************************************************************/
1116 static void TYPEREG_CALLTYPE
release(TypeWriterImpl hEntry
)
1118 TypeWriter
* pEntry
= static_cast<TypeWriter
*>(hEntry
);
1120 if (pEntry
!= nullptr)
1122 if (--pEntry
->m_refCount
== 0)
1127 sal_Bool TYPEREG_CALLTYPE
typereg_writer_setFieldData(
1128 void * handle
, sal_uInt16 index
, rtl_uString
const * documentation
,
1129 rtl_uString
const * fileName
, RTFieldAccess flags
, rtl_uString
const * name
,
1130 rtl_uString
const * typeName
, RTValueType valueType
,
1131 RTConstValueUnion valueValue
)
1132 SAL_THROW_EXTERN_C()
1135 static_cast< TypeWriter
* >(handle
)->m_fields
[index
].setData(
1136 toByteString(name
), toByteString(typeName
),
1137 toByteString(documentation
), toByteString(fileName
), flags
,
1138 valueType
, valueValue
);
1139 } catch (std::bad_alloc
&) {
1145 static void TYPEREG_CALLTYPE
setFieldData(TypeWriterImpl hEntry
,
1147 rtl_uString
const * name
,
1148 rtl_uString
const * typeName
,
1149 rtl_uString
const * doku
,
1150 rtl_uString
const * fileName
,
1151 RTFieldAccess access
,
1152 RTValueType valueType
,
1153 RTConstValueUnion constValue
)
1155 typereg_writer_setFieldData(
1156 hEntry
, index
, doku
, fileName
, access
, name
, typeName
, valueType
,
1160 sal_Bool TYPEREG_CALLTYPE
typereg_writer_setMethodData(
1161 void * handle
, sal_uInt16 index
, rtl_uString
const * documentation
,
1162 RTMethodMode flags
, rtl_uString
const * name
,
1163 rtl_uString
const * returnTypeName
, sal_uInt16 parameterCount
,
1164 sal_uInt16 exceptionCount
)
1165 SAL_THROW_EXTERN_C()
1168 static_cast< TypeWriter
* >(handle
)->m_methods
[index
].setData(
1169 toByteString(name
), toByteString(returnTypeName
), flags
,
1170 parameterCount
, exceptionCount
, toByteString(documentation
));
1171 } catch (std::bad_alloc
&) {
1177 sal_Bool TYPEREG_CALLTYPE
typereg_writer_setMethodParameterData(
1178 void const * handle
, sal_uInt16 methodIndex
, sal_uInt16 parameterIndex
,
1179 RTParamMode flags
, rtl_uString
const * name
, rtl_uString
const * typeName
)
1180 SAL_THROW_EXTERN_C()
1183 static_cast< TypeWriter
const * >(handle
)->
1184 m_methods
[methodIndex
].m_params
[parameterIndex
].setData(
1185 toByteString(typeName
), toByteString(name
), flags
);
1186 } catch (std::bad_alloc
&) {
1192 sal_Bool TYPEREG_CALLTYPE
typereg_writer_setMethodExceptionTypeName(
1193 void const * handle
, sal_uInt16 methodIndex
, sal_uInt16 exceptionIndex
,
1194 rtl_uString
const * typeName
)
1195 SAL_THROW_EXTERN_C()
1198 static_cast< TypeWriter
const * >(handle
)->m_methods
[methodIndex
].setExcName(
1199 exceptionIndex
, toByteString(typeName
));
1200 } catch (std::bad_alloc
&) {
1206 void const * TYPEREG_CALLTYPE
typereg_writer_getBlob(void * handle
, sal_uInt32
* size
)
1207 SAL_THROW_EXTERN_C()
1209 TypeWriter
* writer
= static_cast< TypeWriter
* >(handle
);
1210 if (!writer
->m_blop
) {
1212 writer
->createBlop();
1213 } catch (std::bad_alloc
&) {
1217 *size
= writer
->m_blopSize
;
1218 return writer
->m_blop
.get();
1221 static const sal_uInt8
* TYPEREG_CALLTYPE
getBlop(TypeWriterImpl hEntry
)
1224 return static_cast< sal_uInt8
const * >(
1225 typereg_writer_getBlob(hEntry
, &size
));
1228 static sal_uInt32 TYPEREG_CALLTYPE
getBlopSize(TypeWriterImpl hEntry
)
1231 typereg_writer_getBlob(hEntry
, &size
);
1235 sal_Bool TYPEREG_CALLTYPE
typereg_writer_setReferenceData(
1236 void * handle
, sal_uInt16 index
, rtl_uString
const * documentation
,
1237 RTReferenceType sort
, RTFieldAccess flags
, rtl_uString
const * typeName
)
1238 SAL_THROW_EXTERN_C()
1241 static_cast< TypeWriter
* >(handle
)->m_references
[index
].setData(
1242 toByteString(typeName
), sort
, toByteString(documentation
), flags
);
1243 } catch (std::bad_alloc
&) {
1249 void * TYPEREG_CALLTYPE
typereg_writer_create(
1250 typereg_Version version
, rtl_uString
const * documentation
,
1251 rtl_uString
const * fileName
, RTTypeClass typeClass
, sal_Bool published
,
1252 rtl_uString
const * typeName
, sal_uInt16 superTypeCount
,
1253 sal_uInt16 fieldCount
, sal_uInt16 methodCount
, sal_uInt16 referenceCount
)
1254 SAL_THROW_EXTERN_C()
1257 return new TypeWriter(
1258 version
, toByteString(documentation
), toByteString(fileName
),
1259 typeClass
, published
, toByteString(typeName
), superTypeCount
,
1260 fieldCount
, methodCount
, referenceCount
);
1261 } catch (std::bad_alloc
&) {
1266 void TYPEREG_CALLTYPE
typereg_writer_destroy(void * handle
) SAL_THROW_EXTERN_C() {
1267 delete static_cast< TypeWriter
* >(handle
);
1270 sal_Bool TYPEREG_CALLTYPE
typereg_writer_setSuperTypeName(
1271 void const * handle
, sal_uInt16 index
, rtl_uString
const * typeName
)
1272 SAL_THROW_EXTERN_C()
1275 static_cast< TypeWriter
const * >(handle
)->setSuperType(
1276 index
, toByteString(typeName
));
1277 } catch (std::bad_alloc
&) {
1283 static TypeWriterImpl TYPEREG_CALLTYPE
createEntry(
1284 RTTypeClass typeClass
, rtl_uString
const * typeName
, rtl_uString
const * superTypeName
,
1285 sal_uInt16 fieldCount
)
1288 sal_uInt16 superTypeCount
= rtl_uString_getLength(superTypeName
) == 0
1290 TypeWriterImpl t
= typereg_writer_create(
1291 TYPEREG_VERSION_0
, empty
.pData
, empty
.pData
, typeClass
, false, typeName
,
1292 superTypeCount
, fieldCount
, 0/*methodCount*/, 0/*referenceCount*/);
1293 if (superTypeCount
> 0) {
1294 typereg_writer_setSuperTypeName(t
, 0, superTypeName
);
1301 RegistryTypeWriter::RegistryTypeWriter(RTTypeClass RTTypeClass
,
1302 const rtl::OUString
& typeName
,
1303 const rtl::OUString
& superTypeName
,
1304 sal_uInt16 fieldCount
)
1307 m_hImpl
= createEntry(RTTypeClass
,
1309 superTypeName
.pData
,
1313 RegistryTypeWriter::~RegistryTypeWriter()
1318 void RegistryTypeWriter::setFieldData( sal_uInt16 index
,
1319 const rtl::OUString
& name
,
1320 const rtl::OUString
& typeName
,
1321 const rtl::OUString
& doku
,
1322 const rtl::OUString
& fileName
,
1323 RTFieldAccess access
,
1324 const RTConstValue
& constValue
)
1326 ::setFieldData(m_hImpl
, index
, name
.pData
, typeName
.pData
, doku
.pData
, fileName
.pData
, access
, constValue
.m_type
, constValue
.m_value
);
1329 const sal_uInt8
* RegistryTypeWriter::getBlop()
1331 return ::getBlop(m_hImpl
);
1334 sal_uInt32
RegistryTypeWriter::getBlopSize()
1336 return ::getBlopSize(m_hImpl
);
1339 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */