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 <osl/endian.h>
26 #include <rtl/string.hxx>
27 #include <rtl/ustring.hxx>
29 #include "reflwrit.hxx"
30 #include <registry/refltype.hxx>
31 #include <registry/version.h>
32 #include <registry/writer.h>
34 #include "reflcnst.hxx"
39 OString
toByteString(rtl_uString
const * str
) {
41 str
->buffer
, str
->length
, RTL_TEXTENCODING_UTF8
,
42 OUSTRING_TO_OSTRING_CVTFLAGS
);
47 const 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;
79 sal_uInt8
* buff
= buffer
;
81 for (i
= 0; i
< len
; i
++)
83 buff
+= writeUINT16(buff
, static_cast<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;
93 sal_uInt8
* buff
= const_cast<sal_uInt8
*>(buffer
);
100 for (i
= 0; i
< (len
- 1); i
++)
104 buff
+= readUINT16(buff
, aChar
);
106 v
[i
] = static_cast<sal_Unicode
>(aChar
);
111 return (buff
- buffer
);
114 sal_uInt32
writeFloat(sal_uInt8
* buffer
, float v
)
124 #ifdef REGTYPE_IEEE_NATIVE
125 writeUINT32(buffer
, x
.b
);
130 return sizeof(sal_uInt32
);
133 sal_uInt32
writeDouble(sal_uInt8
* buffer
, double 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
);
152 writeUINT32(buffer
, x
.b
.b2
);
153 writeUINT32(buffer
+ sizeof(sal_uInt32
), x
.b
.b1
);
159 return (sizeof(sal_uInt32
) + sizeof(sal_uInt32
));
162 /**************************************************************************
164 buffer write functions
166 **************************************************************************/
170 /**************************************************************************
174 **************************************************************************/
182 RTConstValueUnion aConst
;
184 struct CPInfo
* m_next
;
188 CPInfo(CPInfoTag tag
, struct CPInfo
* prev
);
190 sal_uInt32
getBlopSize() const;
192 sal_uInt32
toBlop(sal_uInt8
* buffer
);
195 CPInfo::CPInfo(CPInfoTag tag
, struct CPInfo
* prev
)
202 m_index
= prev
->m_index
+ 1;
207 sal_uInt32
CPInfo::getBlopSize() const
209 sal_uInt32 size
= sizeof(sal_uInt32
) /* size */ + sizeof(sal_uInt16
) /* tag */;
213 case CP_TAG_CONST_BOOL
:
214 size
+= sizeof(sal_uInt8
);
216 case CP_TAG_CONST_BYTE
:
217 size
+= sizeof(sal_uInt8
);
219 case CP_TAG_CONST_INT16
:
220 size
+= sizeof(sal_Int16
);
222 case CP_TAG_CONST_UINT16
:
223 size
+= sizeof(sal_uInt16
);
225 case CP_TAG_CONST_INT32
:
226 size
+= sizeof(sal_Int32
);
228 case CP_TAG_CONST_UINT32
:
229 size
+= sizeof(sal_uInt32
);
231 case CP_TAG_CONST_INT64
:
232 size
+= sizeof(sal_Int64
);
234 case CP_TAG_CONST_UINT64
:
235 size
+= sizeof(sal_uInt64
);
237 case CP_TAG_CONST_FLOAT
:
238 size
+= sizeof(sal_uInt32
);
240 case CP_TAG_CONST_DOUBLE
:
241 size
+= sizeof(sal_uInt32
) + sizeof(sal_uInt32
);
243 case CP_TAG_CONST_STRING
:
244 size
+= (rtl_ustr_getLength(m_value
.aConst
.aString
) + 1) * sizeof(sal_uInt16
);
246 case CP_TAG_UTF8_NAME
:
247 size
+= strlen(m_value
.aUtf8
) + 1;
250 size
+= sizeof(sal_uInt32
) + sizeof(sal_uInt16
) + sizeof(sal_uInt16
) + sizeof(sal_uInt32
) + sizeof(sal_uInt32
);
260 sal_uInt32
CPInfo::toBlop(sal_uInt8
* buffer
)
262 sal_uInt8
* buff
= buffer
;
264 buff
+= writeUINT32(buff
, getBlopSize());
265 buff
+= writeUINT16(buff
, static_cast<sal_uInt16
>(m_tag
));
269 case CP_TAG_CONST_BOOL
:
270 buff
+= writeBYTE(buff
, static_cast<sal_uInt8
>(m_value
.aConst
.aBool
));
272 case CP_TAG_CONST_BYTE
:
274 buff
, static_cast< sal_uInt8
>(m_value
.aConst
.aByte
));
276 case CP_TAG_CONST_INT16
:
277 buff
+= writeINT16(buff
, m_value
.aConst
.aShort
);
279 case CP_TAG_CONST_UINT16
:
280 buff
+= writeINT16(buff
, m_value
.aConst
.aUShort
);
282 case CP_TAG_CONST_INT32
:
283 buff
+= writeINT32(buff
, m_value
.aConst
.aLong
);
285 case CP_TAG_CONST_UINT32
:
286 buff
+= writeUINT32(buff
, m_value
.aConst
.aULong
);
288 case CP_TAG_CONST_INT64
:
289 buff
+= writeUINT64(buff
, m_value
.aConst
.aHyper
);
291 case CP_TAG_CONST_UINT64
:
292 buff
+= writeUINT64(buff
, m_value
.aConst
.aUHyper
);
294 case CP_TAG_CONST_FLOAT
:
295 buff
+= writeFloat(buff
, m_value
.aConst
.aFloat
);
297 case CP_TAG_CONST_DOUBLE
:
298 buff
+= writeDouble(buff
, m_value
.aConst
.aDouble
);
300 case CP_TAG_CONST_STRING
:
301 buff
+= writeString(buff
, m_value
.aConst
.aString
);
303 case CP_TAG_UTF8_NAME
:
304 buff
+= writeUtf8(buff
, m_value
.aUtf8
);
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
);
317 return (buff
- buffer
);
321 /**************************************************************************
325 **************************************************************************/
336 RTFieldAccess m_access
;
337 RTValueType m_constValueType
;
338 RTConstValueUnion m_constValue
;
343 void setData(const OString
& name
,
344 const OString
& typeName
,
346 const OString
& fileName
,
347 RTFieldAccess access
,
348 RTValueType constValueType
,
349 RTConstValueUnion constValue
);
350 // throws std::bad_alloc
353 FieldEntry::FieldEntry()
354 : m_access(RTFieldAccess::INVALID
)
355 , m_constValueType(RT_TYPE_NONE
)
359 FieldEntry::~FieldEntry()
362 (m_constValueType
== RT_TYPE_STRING
) &&
363 m_constValue
.aString
&&
364 (m_constValue
.aString
!= NULL_WSTRING
)
367 delete[] m_constValue
.aString
;
371 void FieldEntry::setData(const OString
& name
,
372 const OString
& typeName
,
374 const OString
& fileName
,
375 RTFieldAccess access
,
376 RTValueType constValueType
,
377 RTConstValueUnion constValue
)
379 std::unique_ptr
<sal_Unicode
[]> newValue
;
380 if (constValueType
== RT_TYPE_STRING
&& constValue
.aString
!= nullptr) {
381 sal_Int32 n
= rtl_ustr_getLength(constValue
.aString
) + 1;
382 newValue
.reset(new sal_Unicode
[n
]);
383 memcpy(newValue
.get(), constValue
.aString
, n
* sizeof (sal_Unicode
));
387 m_typeName
= typeName
;
389 m_fileName
= fileName
;
392 (m_constValueType
== RT_TYPE_STRING
) &&
393 m_constValue
.aString
&&
394 (m_constValue
.aString
!= NULL_WSTRING
)
397 delete[] m_constValue
.aString
;
401 m_constValueType
= constValueType
;
403 if (m_constValueType
== RT_TYPE_STRING
)
405 if (constValue
.aString
== nullptr)
406 m_constValue
.aString
= NULL_WSTRING
;
409 m_constValue
.aString
= newValue
.release();
414 m_constValue
= constValue
;
418 /**************************************************************************
422 **************************************************************************/
434 void setData(const OString
& typeName
,
439 ParamEntry::ParamEntry()
440 : m_mode(RT_PARAM_INVALID
)
444 void ParamEntry::setData(const OString
& typeName
,
449 m_typeName
= typeName
;
453 /**************************************************************************
457 **************************************************************************/
465 RTReferenceType m_type
;
466 RTFieldAccess m_access
;
470 void setData(const OString
& name
,
471 RTReferenceType refType
,
473 RTFieldAccess access
);
476 ReferenceEntry::ReferenceEntry()
477 : m_type(RTReferenceType::INVALID
)
478 , m_access(RTFieldAccess::INVALID
)
482 void ReferenceEntry::setData(const OString
& name
,
483 RTReferenceType refType
,
485 RTFieldAccess access
)
493 /**************************************************************************
497 **************************************************************************/
504 OString m_returnTypeName
;
506 sal_uInt16 m_paramCount
;
507 std::unique_ptr
<ParamEntry
[]> m_params
;
508 sal_uInt16 m_excCount
;
509 std::unique_ptr
<OString
[]> m_excNames
;
514 void setData(const OString
& name
,
515 const OString
& returnTypeName
,
517 sal_uInt16 paramCount
,
519 const OString
& doku
);
521 void setExcName(sal_uInt16 excIndex
, const OString
& name
) const;
525 void reallocParams(sal_uInt16 size
);
526 void reallocExcs(sal_uInt16 size
);
529 MethodEntry::MethodEntry()
530 : m_mode(RTMethodMode::INVALID
)
536 void MethodEntry::setData(const OString
& name
,
537 const OString
& returnTypeName
,
539 sal_uInt16 paramCount
,
544 m_returnTypeName
= returnTypeName
;
549 reallocParams(paramCount
);
550 reallocExcs(excCount
);
553 void MethodEntry::setExcName(sal_uInt16 excIndex
, const OString
& name
) const
555 if (excIndex
< m_excCount
)
557 m_excNames
[excIndex
] = name
;
561 void MethodEntry::reallocParams(sal_uInt16 size
)
563 ParamEntry
* newParams
;
566 newParams
= new ParamEntry
[size
];
573 sal_uInt16 mn
= std::min(size
, m_paramCount
);
575 for (i
= 0; i
< mn
; i
++)
577 newParams
[i
].setData(m_params
[i
].m_typeName
, m_params
[i
].m_name
, m_params
[i
].m_mode
);
584 m_params
.reset( newParams
);
587 void MethodEntry::reallocExcs(sal_uInt16 size
)
589 OString
* newExcNames
;
592 newExcNames
= new OString
[size
];
594 newExcNames
= nullptr;
597 sal_uInt16 mn
= std::min(size
, m_excCount
);
599 for (i
= 0; i
< mn
; i
++)
601 newExcNames
[i
] = m_excNames
[i
];
605 m_excNames
.reset( newExcNames
);
609 /**************************************************************************
611 class TypeRegistryEntry
613 **************************************************************************/
620 sal_uInt32 m_refCount
;
621 typereg_Version m_version
;
622 RTTypeClass m_typeClass
;
624 sal_uInt16 m_nSuperTypes
;
625 std::unique_ptr
<OString
[]>
629 sal_uInt16 m_fieldCount
;
630 FieldEntry
* m_fields
;
631 sal_uInt16 m_methodCount
;
632 MethodEntry
* m_methods
;
633 sal_uInt16 m_referenceCount
;
634 ReferenceEntry
* m_references
;
636 std::unique_ptr
<sal_uInt8
[]> m_blop
;
637 sal_uInt32 m_blopSize
;
639 TypeWriter(typereg_Version version
,
640 OString
const & documentation
,
641 OString
const & fileName
,
642 RTTypeClass RTTypeClass
,
644 const OString
& typeName
,
645 sal_uInt16 superTypeCount
,
646 sal_uInt16 FieldCount
,
647 sal_uInt16 methodCount
,
648 sal_uInt16 referenceCount
);
652 void setSuperType(sal_uInt16 index
, OString
const & name
) const;
654 void createBlop(); // throws std::bad_alloc
657 TypeWriter::TypeWriter(typereg_Version version
,
658 OString
const & documentation
,
659 OString
const & fileName
,
660 RTTypeClass RTTypeClass
,
662 const OString
& typeName
,
663 sal_uInt16 superTypeCount
,
664 sal_uInt16 fieldCount
,
665 sal_uInt16 methodCount
,
666 sal_uInt16 referenceCount
)
670 static_cast< enum RTTypeClass
>(
671 RTTypeClass
| (published
? RT_TYPE_PUBLISHED
: 0)))
672 , m_typeName(typeName
)
673 , m_nSuperTypes(superTypeCount
)
674 , m_doku(documentation
)
675 , m_fileName(fileName
)
676 , m_fieldCount(fieldCount
)
678 , m_methodCount(methodCount
)
680 , m_referenceCount(referenceCount
)
681 , m_references(nullptr)
684 if (m_nSuperTypes
> 0)
686 m_superTypeNames
.reset( new OString
[m_nSuperTypes
] );
690 m_fields
= new FieldEntry
[fieldCount
];
693 m_methods
= new MethodEntry
[methodCount
];
695 if (m_referenceCount
)
696 m_references
= new ReferenceEntry
[referenceCount
];
699 TypeWriter::~TypeWriter()
707 if (m_referenceCount
)
708 delete[] m_references
;
711 void TypeWriter::setSuperType(sal_uInt16 index
, OString
const & name
) const
713 m_superTypeNames
[index
] = name
;
716 void TypeWriter::createBlop()
718 //TODO: Fix memory leaks that occur when std::bad_alloc is thrown
720 std::unique_ptr
<sal_uInt8
[]> pBlopFields
;
721 std::unique_ptr
<sal_uInt8
[]> pBlopMethods
;
722 std::unique_ptr
<sal_uInt8
[]> pBlopReferences
;
723 sal_uInt8
* pBuffer
= nullptr;
724 sal_uInt32 blopFieldsSize
= 0;
725 sal_uInt32 blopMethodsSize
= 0;
726 sal_uInt32 blopReferenceSize
= 0;
728 CPInfo
root(CP_TAG_INVALID
, nullptr);
729 sal_uInt16 cpIndexThisName
= 0;
730 std::unique_ptr
<sal_uInt16
[]> cpIndexSuperNames
;
731 sal_uInt16 cpIndexDoku
= 0;
732 sal_uInt16 cpIndexFileName
= 0;
733 CPInfo
* pInfo
= nullptr;
735 sal_uInt16 entrySize
= sizeof(sal_uInt16
);
736 sal_uInt32 blopHeaderEntrySize
= BLOP_OFFSET_N_ENTRIES
+ entrySize
+ (BLOP_HEADER_N_ENTRIES
* entrySize
);
737 sal_uInt32 blopFieldEntrySize
= BLOP_FIELD_N_ENTRIES
* entrySize
;
738 sal_uInt32 blopMethodEntrySize
= BLOP_METHOD_N_ENTRIES
* entrySize
;
739 sal_uInt32 blopParamEntrySize
= BLOP_PARAM_N_ENTRIES
* entrySize
;
740 sal_uInt32 blopReferenceEntrySize
= BLOP_REFERENCE_N_ENTRIES
* entrySize
;
742 sal_uInt32 blopSize
= blopHeaderEntrySize
;
744 // create CP entry for this name
745 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, &root
);
746 pInfo
->m_value
.aUtf8
= m_typeName
.getStr();
747 cpIndexThisName
= pInfo
->m_index
;
750 blopSize
+= entrySize
;
752 // create CP entry for super names
755 blopSize
+= m_nSuperTypes
* entrySize
;
757 cpIndexSuperNames
.reset(new sal_uInt16
[m_nSuperTypes
]);
759 for (sal_uInt32 i
=0; i
< m_nSuperTypes
; i
++)
761 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
762 pInfo
->m_value
.aUtf8
= m_superTypeNames
[i
].getStr();
763 cpIndexSuperNames
[i
] = pInfo
->m_index
;
767 // create CP entry for doku
768 if (!m_doku
.isEmpty())
770 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
771 pInfo
->m_value
.aUtf8
= m_doku
.getStr();
772 cpIndexDoku
= pInfo
->m_index
;
775 // create CP entry for idl source filename
776 if (!m_fileName
.isEmpty())
778 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
779 pInfo
->m_value
.aUtf8
= m_fileName
.getStr();
780 cpIndexFileName
= pInfo
->m_index
;
784 blopSize
+= sizeof(sal_uInt16
); // fieldCount + nFieldEntries
788 sal_uInt16 cpIndexName
= 0;
789 sal_uInt16 cpIndexTypeName
= 0;
790 sal_uInt16 cpIndexValue
= 0;
791 sal_uInt16 cpIndexDoku2
= 0;
792 sal_uInt16 cpIndexFileName2
= 0;
794 // nFieldEntries + n fields
795 blopFieldsSize
= sizeof(sal_uInt16
) + (m_fieldCount
* blopFieldEntrySize
);
797 blopSize
+= blopFieldsSize
;
799 pBlopFields
.reset(new sal_uInt8
[blopFieldsSize
]);
800 pBuffer
= pBlopFields
.get();
802 pBuffer
+= writeUINT16(pBuffer
, BLOP_FIELD_N_ENTRIES
);
804 for (sal_uInt16 i
= 0; i
< m_fieldCount
; i
++)
810 cpIndexFileName2
= 0;
812 pBuffer
+= writeUINT16(pBuffer
, static_cast<sal_uInt16
>(m_fields
[i
].m_access
));
814 if (!m_fields
[i
].m_name
.isEmpty())
816 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
817 pInfo
->m_value
.aUtf8
= m_fields
[i
].m_name
.getStr();
818 cpIndexName
= pInfo
->m_index
;
820 pBuffer
+= writeUINT16(pBuffer
, cpIndexName
);
822 if (!m_fields
[i
].m_typeName
.isEmpty())
824 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
825 pInfo
->m_value
.aUtf8
= m_fields
[i
].m_typeName
.getStr();
826 cpIndexTypeName
= pInfo
->m_index
;
828 pBuffer
+= writeUINT16(pBuffer
, cpIndexTypeName
);
830 if (m_fields
[i
].m_constValueType
!= RT_TYPE_NONE
)
832 pInfo
= new CPInfo(static_cast<CPInfoTag
>(m_fields
[i
].m_constValueType
), pInfo
);
833 pInfo
->m_value
.aConst
= m_fields
[i
].m_constValue
;
834 cpIndexValue
= pInfo
->m_index
;
836 pBuffer
+= writeUINT16(pBuffer
, cpIndexValue
);
838 if (!m_fields
[i
].m_doku
.isEmpty())
840 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
841 pInfo
->m_value
.aUtf8
= m_fields
[i
].m_doku
.getStr();
842 cpIndexDoku2
= pInfo
->m_index
;
844 pBuffer
+= writeUINT16(pBuffer
, cpIndexDoku2
);
846 if (!m_fields
[i
].m_fileName
.isEmpty())
848 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
849 pInfo
->m_value
.aUtf8
= m_fields
[i
].m_fileName
.getStr();
850 cpIndexFileName2
= pInfo
->m_index
;
852 pBuffer
+= writeUINT16(pBuffer
, cpIndexFileName2
);
857 blopSize
+= sizeof(sal_uInt16
); // methodCount
861 std::unique_ptr
<sal_uInt16
[]> pMethodEntrySize( new sal_uInt16
[m_methodCount
] );
862 sal_uInt16 cpIndexName
= 0;
863 sal_uInt16 cpIndexReturn
= 0;
864 sal_uInt16 cpIndexDoku2
= 0;
866 // nMethodEntries + nParamEntries
867 blopMethodsSize
= (2 * sizeof(sal_uInt16
));
869 for (sal_uInt16 i
= 0; i
< m_methodCount
; i
++)
871 pMethodEntrySize
[i
] = static_cast<sal_uInt16
>( blopMethodEntrySize
+ // header
872 sizeof(sal_uInt16
) + // parameterCount
873 (m_methods
[i
].m_paramCount
* blopParamEntrySize
) + // exceptions
874 sizeof(sal_uInt16
) + // exceptionCount
875 (m_methods
[i
].m_excCount
* sizeof(sal_uInt16
)) ); // exceptions
877 blopMethodsSize
+= pMethodEntrySize
[i
];
880 pBlopMethods
.reset(new sal_uInt8
[blopMethodsSize
]);
882 blopSize
+= blopMethodsSize
;
884 pBuffer
= pBlopMethods
.get();
886 pBuffer
+= writeUINT16(pBuffer
, BLOP_METHOD_N_ENTRIES
);
887 pBuffer
+= writeUINT16(pBuffer
, BLOP_PARAM_N_ENTRIES
);
889 for (sal_uInt16 i
= 0; i
< m_methodCount
; i
++)
894 pBuffer
+= writeUINT16(pBuffer
, pMethodEntrySize
[i
]);
895 pBuffer
+= writeUINT16(
897 sal::static_int_cast
< sal_uInt16
>(m_methods
[i
].m_mode
));
899 if (!m_methods
[i
].m_name
.isEmpty())
901 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
902 pInfo
->m_value
.aUtf8
= m_methods
[i
].m_name
.getStr();
903 cpIndexName
= pInfo
->m_index
;
905 pBuffer
+= writeUINT16(pBuffer
, cpIndexName
);
908 if (!m_methods
[i
].m_returnTypeName
.isEmpty())
910 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
911 pInfo
->m_value
.aUtf8
= m_methods
[i
].m_returnTypeName
.getStr();
912 cpIndexReturn
= pInfo
->m_index
;
914 pBuffer
+= writeUINT16(pBuffer
, cpIndexReturn
);
916 if (!m_methods
[i
].m_doku
.isEmpty())
918 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
919 pInfo
->m_value
.aUtf8
= m_methods
[i
].m_doku
.getStr();
920 cpIndexDoku2
= pInfo
->m_index
;
922 pBuffer
+= writeUINT16(pBuffer
, cpIndexDoku2
);
926 pBuffer
+= writeUINT16(pBuffer
, m_methods
[i
].m_paramCount
);
928 for (j
= 0; j
< m_methods
[i
].m_paramCount
; j
++)
930 if (!m_methods
[i
].m_params
[j
].m_typeName
.isEmpty())
932 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
933 pInfo
->m_value
.aUtf8
= m_methods
[i
].m_params
[j
].m_typeName
.getStr();
934 cpIndexName
= pInfo
->m_index
;
936 pBuffer
+= writeUINT16(pBuffer
, cpIndexName
);
939 pBuffer
+= writeUINT16(
941 sal::static_int_cast
< sal_uInt16
>(
942 m_methods
[i
].m_params
[j
].m_mode
));
944 if (!m_methods
[i
].m_params
[j
].m_name
.isEmpty())
946 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
947 pInfo
->m_value
.aUtf8
= m_methods
[i
].m_params
[j
].m_name
.getStr();
948 cpIndexName
= pInfo
->m_index
;
950 pBuffer
+= writeUINT16(pBuffer
, cpIndexName
);
954 pBuffer
+= writeUINT16(pBuffer
, m_methods
[i
].m_excCount
);
956 for (j
= 0; j
< m_methods
[i
].m_excCount
; j
++)
958 if (!m_methods
[i
].m_excNames
[j
].isEmpty())
960 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
961 pInfo
->m_value
.aUtf8
= m_methods
[i
].m_excNames
[j
].getStr();
962 cpIndexName
= pInfo
->m_index
;
964 pBuffer
+= writeUINT16(pBuffer
, cpIndexName
);
971 blopSize
+= entrySize
; // referenceCount
973 if (m_referenceCount
)
975 sal_uInt16 cpIndexName
= 0;
976 sal_uInt16 cpIndexDoku2
= 0;
978 // nReferenceEntries + n references
979 blopReferenceSize
= entrySize
+ (m_referenceCount
* blopReferenceEntrySize
);
981 blopSize
+= blopReferenceSize
;
983 pBlopReferences
.reset(new sal_uInt8
[blopReferenceSize
]);
984 pBuffer
= pBlopReferences
.get();
986 pBuffer
+= writeUINT16(pBuffer
, BLOP_REFERENCE_N_ENTRIES
);
988 for (sal_uInt16 i
= 0; i
< m_referenceCount
; i
++)
990 pBuffer
+= writeUINT16(
992 sal::static_int_cast
< sal_uInt16
>(m_references
[i
].m_type
));
997 if (!m_references
[i
].m_name
.isEmpty())
999 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
1000 pInfo
->m_value
.aUtf8
= m_references
[i
].m_name
.getStr();
1001 cpIndexName
= pInfo
->m_index
;
1003 pBuffer
+= writeUINT16(pBuffer
, cpIndexName
);
1005 if (!m_references
[i
].m_doku
.isEmpty())
1007 pInfo
= new CPInfo(CP_TAG_UTF8_NAME
, pInfo
);
1008 pInfo
->m_value
.aUtf8
= m_references
[i
].m_doku
.getStr();
1009 cpIndexDoku2
= pInfo
->m_index
;
1011 pBuffer
+= writeUINT16(pBuffer
, cpIndexDoku2
);
1013 pBuffer
+= writeUINT16(pBuffer
, static_cast<sal_uInt16
>(m_references
[i
].m_access
));
1018 // get CP infos blop-length
1019 pInfo
= root
.m_next
;
1020 sal_uInt32 cpBlopSize
= 0;
1021 sal_uInt16 cpCount
= 0;
1025 cpBlopSize
+= pInfo
->getBlopSize();
1027 pInfo
= pInfo
->m_next
;
1030 blopSize
+= cpBlopSize
;
1031 blopSize
+= sizeof(sal_uInt16
); // constantPoolCount
1033 // write all in flat buffer
1035 sal_uInt8
* blop
= new sal_uInt8
[blopSize
];
1039 // Assumes two's complement arithmetic with modulo-semantics:
1040 pBuffer
+= writeUINT32(pBuffer
, magic
+ m_version
);
1041 pBuffer
+= writeUINT32(pBuffer
, blopSize
);
1042 pBuffer
+= writeUINT16(pBuffer
, minorVersion
);
1043 pBuffer
+= writeUINT16(pBuffer
, majorVersion
);
1044 pBuffer
+= writeUINT16(pBuffer
, BLOP_HEADER_N_ENTRIES
);
1046 pBuffer
+= writeUINT16(pBuffer
, sal_uInt16(RT_UNO_IDL
));
1047 pBuffer
+= writeUINT16(pBuffer
, static_cast<sal_uInt16
>(m_typeClass
));
1048 pBuffer
+= writeUINT16(pBuffer
, cpIndexThisName
);
1049 pBuffer
+= writeUINT16(pBuffer
, 0); // cpIndexUik
1050 pBuffer
+= writeUINT16(pBuffer
, cpIndexDoku
);
1051 pBuffer
+= writeUINT16(pBuffer
, cpIndexFileName
);
1054 pBuffer
+= writeUINT16(pBuffer
, m_nSuperTypes
);
1057 for (sal_uInt32 i
=0; i
< m_nSuperTypes
; i
++)
1059 pBuffer
+= writeUINT16(pBuffer
, cpIndexSuperNames
[i
]);
1061 cpIndexSuperNames
.reset();
1064 pBuffer
+= writeUINT16(pBuffer
, cpCount
);
1066 // write and delete CP infos
1067 pInfo
= root
.m_next
;
1071 CPInfo
* pNextInfo
= pInfo
->m_next
;
1073 pBuffer
+= pInfo
->toBlop(pBuffer
);
1079 auto writeList
= [&pBuffer
](
1080 sal_uInt16 count
, sal_uInt8
* data
, sal_uInt32 size
)
1082 pBuffer
+= writeUINT16(pBuffer
, count
);
1084 memcpy(pBuffer
, data
, size
);
1090 writeList(m_fieldCount
, pBlopFields
.get(), blopFieldsSize
);
1093 writeList(m_methodCount
, pBlopMethods
.get(), blopMethodsSize
);
1096 writeList(m_referenceCount
, pBlopReferences
.get(), blopReferenceSize
);
1098 m_blop
.reset( blop
);
1099 m_blopSize
= blopSize
;
1102 } // unnamed namespace
1104 /**************************************************************************
1108 **************************************************************************/
1112 static void TYPEREG_CALLTYPE
release(TypeWriterImpl hEntry
)
1114 TypeWriter
* pEntry
= static_cast<TypeWriter
*>(hEntry
);
1116 if (pEntry
!= nullptr)
1118 if (--pEntry
->m_refCount
== 0)
1123 sal_Bool TYPEREG_CALLTYPE
typereg_writer_setFieldData(
1124 void * handle
, sal_uInt16 index
, rtl_uString
const * documentation
,
1125 rtl_uString
const * fileName
, RTFieldAccess flags
, rtl_uString
const * name
,
1126 rtl_uString
const * typeName
, RTValueType valueType
,
1127 RTConstValueUnion valueValue
)
1128 SAL_THROW_EXTERN_C()
1131 static_cast< TypeWriter
* >(handle
)->m_fields
[index
].setData(
1132 toByteString(name
), toByteString(typeName
),
1133 toByteString(documentation
), toByteString(fileName
), flags
,
1134 valueType
, valueValue
);
1135 } catch (std::bad_alloc
&) {
1141 static void TYPEREG_CALLTYPE
setFieldData(TypeWriterImpl hEntry
,
1143 rtl_uString
const * name
,
1144 rtl_uString
const * typeName
,
1145 rtl_uString
const * doku
,
1146 rtl_uString
const * fileName
,
1147 RTFieldAccess access
,
1148 RTValueType valueType
,
1149 RTConstValueUnion constValue
)
1151 typereg_writer_setFieldData(
1152 hEntry
, index
, doku
, fileName
, access
, name
, typeName
, valueType
,
1156 sal_Bool TYPEREG_CALLTYPE
typereg_writer_setMethodData(
1157 void * handle
, sal_uInt16 index
, rtl_uString
const * documentation
,
1158 RTMethodMode flags
, rtl_uString
const * name
,
1159 rtl_uString
const * returnTypeName
, sal_uInt16 parameterCount
,
1160 sal_uInt16 exceptionCount
)
1161 SAL_THROW_EXTERN_C()
1164 static_cast< TypeWriter
* >(handle
)->m_methods
[index
].setData(
1165 toByteString(name
), toByteString(returnTypeName
), flags
,
1166 parameterCount
, exceptionCount
, toByteString(documentation
));
1167 } catch (std::bad_alloc
&) {
1173 sal_Bool TYPEREG_CALLTYPE
typereg_writer_setMethodParameterData(
1174 void const * handle
, sal_uInt16 methodIndex
, sal_uInt16 parameterIndex
,
1175 RTParamMode flags
, rtl_uString
const * name
, rtl_uString
const * typeName
)
1176 SAL_THROW_EXTERN_C()
1179 static_cast< TypeWriter
const * >(handle
)->
1180 m_methods
[methodIndex
].m_params
[parameterIndex
].setData(
1181 toByteString(typeName
), toByteString(name
), flags
);
1182 } catch (std::bad_alloc
&) {
1188 sal_Bool TYPEREG_CALLTYPE
typereg_writer_setMethodExceptionTypeName(
1189 void const * handle
, sal_uInt16 methodIndex
, sal_uInt16 exceptionIndex
,
1190 rtl_uString
const * typeName
)
1191 SAL_THROW_EXTERN_C()
1194 static_cast< TypeWriter
const * >(handle
)->m_methods
[methodIndex
].setExcName(
1195 exceptionIndex
, toByteString(typeName
));
1196 } catch (std::bad_alloc
&) {
1202 void const * TYPEREG_CALLTYPE
typereg_writer_getBlob(void * handle
, sal_uInt32
* size
)
1203 SAL_THROW_EXTERN_C()
1205 TypeWriter
* writer
= static_cast< TypeWriter
* >(handle
);
1206 if (!writer
->m_blop
) {
1208 writer
->createBlop();
1209 } catch (std::bad_alloc
&) {
1213 *size
= writer
->m_blopSize
;
1214 return writer
->m_blop
.get();
1217 static const sal_uInt8
* TYPEREG_CALLTYPE
getBlop(TypeWriterImpl hEntry
)
1220 return static_cast< sal_uInt8
const * >(
1221 typereg_writer_getBlob(hEntry
, &size
));
1224 static sal_uInt32 TYPEREG_CALLTYPE
getBlopSize(TypeWriterImpl hEntry
)
1227 typereg_writer_getBlob(hEntry
, &size
);
1231 sal_Bool TYPEREG_CALLTYPE
typereg_writer_setReferenceData(
1232 void * handle
, sal_uInt16 index
, rtl_uString
const * documentation
,
1233 RTReferenceType sort
, RTFieldAccess flags
, rtl_uString
const * typeName
)
1234 SAL_THROW_EXTERN_C()
1237 static_cast< TypeWriter
* >(handle
)->m_references
[index
].setData(
1238 toByteString(typeName
), sort
, toByteString(documentation
), flags
);
1239 } catch (std::bad_alloc
&) {
1245 void * TYPEREG_CALLTYPE
typereg_writer_create(
1246 typereg_Version version
, rtl_uString
const * documentation
,
1247 rtl_uString
const * fileName
, RTTypeClass typeClass
, sal_Bool published
,
1248 rtl_uString
const * typeName
, sal_uInt16 superTypeCount
,
1249 sal_uInt16 fieldCount
, sal_uInt16 methodCount
, sal_uInt16 referenceCount
)
1250 SAL_THROW_EXTERN_C()
1253 return new TypeWriter(
1254 version
, toByteString(documentation
), toByteString(fileName
),
1255 typeClass
, published
, toByteString(typeName
), superTypeCount
,
1256 fieldCount
, methodCount
, referenceCount
);
1257 } catch (std::bad_alloc
&) {
1262 void TYPEREG_CALLTYPE
typereg_writer_destroy(void * handle
) SAL_THROW_EXTERN_C() {
1263 delete static_cast< TypeWriter
* >(handle
);
1266 sal_Bool TYPEREG_CALLTYPE
typereg_writer_setSuperTypeName(
1267 void const * handle
, sal_uInt16 index
, rtl_uString
const * typeName
)
1268 SAL_THROW_EXTERN_C()
1271 static_cast< TypeWriter
const * >(handle
)->setSuperType(
1272 index
, toByteString(typeName
));
1273 } catch (std::bad_alloc
&) {
1279 static TypeWriterImpl TYPEREG_CALLTYPE
createEntry(
1280 RTTypeClass typeClass
, rtl_uString
const * typeName
, rtl_uString
const * superTypeName
,
1281 sal_uInt16 fieldCount
)
1284 sal_uInt16 superTypeCount
= rtl_uString_getLength(superTypeName
) == 0
1286 TypeWriterImpl t
= typereg_writer_create(
1287 TYPEREG_VERSION_0
, empty
.pData
, empty
.pData
, typeClass
, false, typeName
,
1288 superTypeCount
, fieldCount
, 0/*methodCount*/, 0/*referenceCount*/);
1289 if (superTypeCount
> 0) {
1290 typereg_writer_setSuperTypeName(t
, 0, superTypeName
);
1297 RegistryTypeWriter::RegistryTypeWriter(RTTypeClass RTTypeClass
,
1298 const OUString
& typeName
,
1299 const OUString
& superTypeName
,
1300 sal_uInt16 fieldCount
)
1303 m_hImpl
= createEntry(RTTypeClass
,
1305 superTypeName
.pData
,
1309 RegistryTypeWriter::~RegistryTypeWriter()
1314 void RegistryTypeWriter::setFieldData( sal_uInt16 index
,
1315 const OUString
& name
,
1316 const OUString
& typeName
,
1317 const OUString
& doku
,
1318 const OUString
& fileName
,
1319 RTFieldAccess access
,
1320 const RTConstValue
& constValue
)
1322 ::setFieldData(m_hImpl
, index
, name
.pData
, typeName
.pData
, doku
.pData
, fileName
.pData
, access
, constValue
.m_type
, constValue
.m_value
);
1325 const sal_uInt8
* RegistryTypeWriter::getBlop()
1327 return ::getBlop(m_hImpl
);
1330 sal_uInt32
RegistryTypeWriter::getBlopSize()
1332 return ::getBlopSize(m_hImpl
);
1335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */