diff options
Diffstat (limited to 'registry/source/reflwrit.cxx')
-rw-r--r-- | registry/source/reflwrit.cxx | 1491 |
1 files changed, 1491 insertions, 0 deletions
diff --git a/registry/source/reflwrit.cxx b/registry/source/reflwrit.cxx new file mode 100644 index 000000000000..442951849b02 --- /dev/null +++ b/registry/source/reflwrit.cxx @@ -0,0 +1,1491 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_registry.hxx" + +#include <new> +#include <sal/types.h> +#include <sal/macros.h> +#include <osl/endian.h> +#include <rtl/alloc.h> +#include "rtl/string.hxx" +#include "rtl/ustring.hxx" + +#include "registry/reflwrit.hxx" +#include "registry/version.h" +#include "registry/writer.h" + +#include "reflcnst.hxx" + +using namespace rtl; + +namespace { + +// Throws std::bad_alloc: +inline rtl::OString toByteString(rtl_uString const * str) { + return rtl::OString( + str->buffer, str->length, RTL_TEXTENCODING_UTF8, + OUSTRING_TO_OSTRING_CVTFLAGS); +} + +} + +static sal_Unicode NULL_WSTRING[1] = { 0 }; + +#if defined ( GCC ) && ( defined ( SCO ) ) +ORealDynamicLoader* ODynamicLoader<RegistryTypeWriter_Api>::m_pLoader = NULL; +#endif + +#define BLOP_OFFSET_MAGIC 0 +#define BLOP_OFFSET_SIZE (BLOP_OFFSET_MAGIC + sizeof(sal_uInt32)) +#define BLOP_OFFSET_MINOR (BLOP_OFFSET_SIZE + sizeof(sal_uInt32)) +#define BLOP_OFFSET_MAJOR (BLOP_OFFSET_MINOR + sizeof(sal_uInt16)) +#define BLOP_OFFSET_N_ENTRIES (BLOP_OFFSET_MAJOR + sizeof(sal_uInt16)) +#define BLOP_OFFSET_TYPE_SOURCE (BLOP_OFFSET_N_ENTRIES + sizeof(sal_uInt16)) +#define BLOP_OFFSET_TYPE_CLASS (BLOP_OFFSET_TYPE_SOURCE + sizeof(sal_uInt16)) +#define BLOP_OFFSET_THIS (BLOP_OFFSET_TYPE_CLASS + sizeof(sal_uInt16)) +#define BLOP_OFFSET_UIK (BLOP_OFFSET_THIS + sizeof(sal_uInt16)) +#define BLOP_OFFSET_DOKU (BLOP_OFFSET_UIK + sizeof(sal_uInt16)) +#define BLOP_OFFSET_FILENAME (BLOP_OFFSET_DOKU + sizeof(sal_uInt16)) +#define BLOP_HEADER_N_ENTRIES 6 + +#define BLOP_OFFSET_N_SUPERTYPES 0 +#define BLOP_OFFSET_SUPERTYPES (BLOP_OFFSET_N_SUPERTYPES + sizeof(sal_uInt16)) + +#define BLOP_FIELD_ENTRY_ACCESS 0 +#define BLOP_FIELD_ENTRY_NAME (BLOP_FIELD_ENTRY_ACCESS + sizeof(sal_uInt16)) +#define BLOP_FIELD_ENTRY_TYPE (BLOP_FIELD_ENTRY_NAME + sizeof(sal_uInt16)) +#define BLOP_FIELD_ENTRY_VALUE (BLOP_FIELD_ENTRY_TYPE + sizeof(sal_uInt16)) +#define BLOP_FIELD_ENTRY_DOKU (BLOP_FIELD_ENTRY_VALUE + sizeof(sal_uInt16)) +#define BLOP_FIELD_ENTRY_FILENAME (BLOP_FIELD_ENTRY_DOKU + sizeof(sal_uInt16)) +#define BLOP_FIELD_N_ENTRIES 6 + +#define BLOP_METHOD_SIZE 0 +#define BLOP_METHOD_MODE (BLOP_METHOD_SIZE + sizeof(sal_uInt16)) +#define BLOP_METHOD_NAME (BLOP_METHOD_MODE + sizeof(sal_uInt16)) +#define BLOP_METHOD_RETURN (BLOP_METHOD_NAME + sizeof(sal_uInt16)) +#define BLOP_METHOD_DOKU (BLOP_METHOD_RETURN + sizeof(sal_uInt16)) +#define BLOP_METHOD_N_ENTRIES 5 + +#define BLOP_PARAM_TYPE 0 +#define BLOP_PARAM_MODE (BLOP_PARAM_TYPE + sizeof(sal_uInt16)) +#define BLOP_PARAM_NAME (BLOP_PARAM_MODE + sizeof(sal_uInt16)) +#define BLOP_PARAM_N_ENTRIES 3 + +#define BLOP_REFERENCE_TYPE 0 +#define BLOP_REFERENCE_NAME (BLOP_REFERENCE_TYPE + sizeof(sal_uInt16)) +#define BLOP_REFERENCE_DOKU (BLOP_REFERENCE_NAME + sizeof(sal_uInt16)) +#define BLOP_REFERENCE_ACCESS (BLOP_REFERENCE_DOKU + sizeof(sal_uInt16)) +#define BLOP_REFERENCE_N_ENTRIES 4 + +sal_uInt32 UINT16StringLen(const sal_uInt8* wstring) +{ + if (!wstring) return 0; + + const sal_uInt8* b = wstring; + + while (b[0] || b[1]) b += sizeof(sal_uInt16); + + return ((b - wstring) / sizeof(sal_uInt16)); +} + +sal_uInt32 writeString(sal_uInt8* buffer, const sal_Unicode* v) +{ + sal_uInt32 len = rtl_ustr_getLength(v) + 1; + sal_uInt32 i; + sal_uInt8* buff = buffer; + + for (i = 0; i < len; i++) + { + buff += writeUINT16(buff, (sal_uInt16) v[i]); + } + + return (buff - buffer); +} + +sal_uInt32 readString(const sal_uInt8* buffer, sal_Unicode* v, sal_uInt32 maxSize) +{ + sal_uInt32 len = SAL_MIN(UINT16StringLen(buffer) + 1, maxSize / 2); + sal_uInt32 i; + sal_uInt8* buff = (sal_uInt8*)buffer; + + for (i = 0; i < (len - 1); i++) + { + sal_uInt16 aChar; + + buff += readUINT16(buff, aChar); + + v[i] = (sal_Unicode) aChar; + } + + v[len - 1] = L'\0'; + + return (buff - ((sal_uInt8*)buffer)); +} + +sal_uInt32 writeFloat(sal_uInt8* buffer, float v) +{ + union + { + float v; + sal_uInt32 b; + } x; + + x.v = v; + +#ifdef REGTYPE_IEEE_NATIVE + writeUINT32(buffer, x.b); +#else +# error no IEEE +#endif + + return sizeof(sal_uInt32); +} + +sal_uInt32 writeDouble(sal_uInt8* buffer, double v) +{ + union + { + double v; + struct + { + sal_uInt32 b1; + sal_uInt32 b2; + } b; + } x; + + x.v = v; + +#ifdef REGTYPE_IEEE_NATIVE +# ifdef OSL_BIGENDIAN + writeUINT32(buffer, x.b.b1); + writeUINT32(buffer + sizeof(sal_uInt32), x.b.b2); +# else + writeUINT32(buffer, x.b.b2); + writeUINT32(buffer + sizeof(sal_uInt32), x.b.b1); +# endif +#else +# error no IEEE +#endif + + return (sizeof(sal_uInt32) + sizeof(sal_uInt32)); +} + +/************************************************************************** + + buffer write functions + +**************************************************************************/ + + +/************************************************************************** + + struct CPInfo + +**************************************************************************/ + +struct CPInfo +{ + CPInfoTag m_tag; + union + { + const sal_Char* aUtf8; + RTUik* aUik; + RTConstValueUnion aConst; + } m_value; + + sal_uInt16 m_index; + struct CPInfo* m_next; + + CPInfo(CPInfoTag tag, struct CPInfo* prev); + + sal_uInt32 getBlopSize(); + + sal_uInt32 toBlop(sal_uInt8* buffer); +}; + +CPInfo::CPInfo(CPInfoTag tag, struct CPInfo* prev) + : m_tag(tag) + , m_index(0) + , m_next(NULL) +{ + if (prev) + { + m_index = prev->m_index + 1; + prev->m_next = this; + } +} + +sal_uInt32 CPInfo::getBlopSize() +{ + sal_uInt32 size = sizeof(sal_uInt32) /* size */ + sizeof(sal_uInt16) /* tag */; + + switch (m_tag) + { + case CP_TAG_CONST_BOOL: + size += sizeof(sal_uInt8); + break; + case CP_TAG_CONST_BYTE: + size += sizeof(sal_uInt8); + break; + case CP_TAG_CONST_INT16: + size += sizeof(sal_Int16); + break; + case CP_TAG_CONST_UINT16: + size += sizeof(sal_uInt16); + break; + case CP_TAG_CONST_INT32: + size += sizeof(sal_Int32); + break; + case CP_TAG_CONST_UINT32: + size += sizeof(sal_uInt32); + break; + case CP_TAG_CONST_INT64: + size += sizeof(sal_Int64); + break; + case CP_TAG_CONST_UINT64: + size += sizeof(sal_uInt64); + break; + case CP_TAG_CONST_FLOAT: + size += sizeof(sal_uInt32); + break; + case CP_TAG_CONST_DOUBLE: + size += sizeof(sal_uInt32) + sizeof(sal_uInt32); + break; + case CP_TAG_CONST_STRING: + size += (rtl_ustr_getLength(m_value.aConst.aString) + 1) * sizeof(sal_uInt16); + break; + case CP_TAG_UTF8_NAME: + size += strlen(m_value.aUtf8) + 1; + break; + case CP_TAG_UIK: + size += sizeof(sal_uInt32) + sizeof(sal_uInt16) + sizeof(sal_uInt16) + sizeof(sal_uInt32) + sizeof(sal_uInt32); + break; + default: + break; + } + + return size; +} + + +sal_uInt32 CPInfo::toBlop(sal_uInt8* buffer) +{ + sal_uInt8* buff = buffer; + + buff += writeUINT32(buff, getBlopSize()); + buff += writeUINT16(buff, (sal_uInt16) m_tag); + + switch (m_tag) + { + case CP_TAG_CONST_BOOL: + buff += writeBYTE(buff, (sal_uInt8) m_value.aConst.aBool); + break; + case CP_TAG_CONST_BYTE: + buff += writeBYTE(buff, m_value.aConst.aByte); + break; + case CP_TAG_CONST_INT16: + buff += writeINT16(buff, m_value.aConst.aShort); + break; + case CP_TAG_CONST_UINT16: + buff += writeINT16(buff, m_value.aConst.aUShort); + break; + case CP_TAG_CONST_INT32: + buff += writeINT32(buff, m_value.aConst.aLong); + break; + case CP_TAG_CONST_UINT32: + buff += writeUINT32(buff, m_value.aConst.aULong); + break; + case CP_TAG_CONST_INT64: + buff += writeUINT64(buff, m_value.aConst.aHyper); + break; + case CP_TAG_CONST_UINT64: + buff += writeUINT64(buff, m_value.aConst.aUHyper); + break; + case CP_TAG_CONST_FLOAT: + buff += writeFloat(buff, m_value.aConst.aFloat); + break; + case CP_TAG_CONST_DOUBLE: + buff += writeDouble(buff, m_value.aConst.aDouble); + break; + case CP_TAG_CONST_STRING: + buff += writeString(buff, m_value.aConst.aString); + break; + case CP_TAG_UTF8_NAME: + buff += writeUtf8(buff, m_value.aUtf8); + break; + case CP_TAG_UIK: + buff += writeUINT32(buff, m_value.aUik->m_Data1); + buff += writeUINT16(buff, m_value.aUik->m_Data2); + buff += writeUINT16(buff, m_value.aUik->m_Data3); + buff += writeUINT32(buff, m_value.aUik->m_Data4); + buff += writeUINT32(buff, m_value.aUik->m_Data5); + break; + default: + break; + } + + return (buff - buffer); +} + + +/************************************************************************** + + class FieldEntry + +**************************************************************************/ + +class FieldEntry +{ + +public: + + OString m_name; + OString m_typeName; + OString m_doku; + OString m_fileName; + RTFieldAccess m_access; + RTValueType m_constValueType; + RTConstValueUnion m_constValue; + + FieldEntry(); + ~FieldEntry(); + + void setData(const OString& name, + const OString& typeName, + const OString& doku, + const OString& fileName, + RTFieldAccess access, + RTValueType constValueType, + RTConstValueUnion constValue); + // throws std::bad_alloc +}; + +FieldEntry::FieldEntry() + : m_access(RT_ACCESS_INVALID) + , m_constValueType(RT_TYPE_NONE) +{ +} + +FieldEntry::~FieldEntry() +{ + if ( + (m_constValueType == RT_TYPE_STRING) && + m_constValue.aString && + (m_constValue.aString != NULL_WSTRING) + ) + { + delete[] (sal_Unicode*)m_constValue.aString; + } +} + +void FieldEntry::setData(const OString& name, + const OString& typeName, + const OString& doku, + const OString& fileName, + RTFieldAccess access, + RTValueType constValueType, + RTConstValueUnion constValue) +{ + sal_Unicode * newValue = 0; + if (constValueType == RT_TYPE_STRING && constValue.aString != 0) { + sal_Int32 n = rtl_ustr_getLength(constValue.aString) + 1; + newValue = new sal_Unicode[n]; + rtl_copyMemory(newValue, constValue.aString, n * sizeof (sal_Unicode)); + } + + m_name = name; + m_typeName = typeName; + m_doku = doku; + m_fileName = fileName; + + if ( + (m_constValueType == RT_TYPE_STRING) && + m_constValue.aString && + (m_constValue.aString != NULL_WSTRING) + ) + { + delete[] (sal_Unicode*)m_constValue.aString; + } + + m_access = access; + m_constValueType = constValueType; + + if (m_constValueType == RT_TYPE_STRING) + { + if (constValue.aString == NULL) + m_constValue.aString = NULL_WSTRING; + else + { + m_constValue.aString = newValue; + } + } + else + { + m_constValue = constValue; + } +} + +/************************************************************************** + + class ParamEntry + +**************************************************************************/ + +class ParamEntry +{ +public: + + OString m_typeName; + OString m_name; + RTParamMode m_mode; + + ParamEntry(); + ~ParamEntry(); + + void setData(const OString& typeName, + const OString& name, + RTParamMode mode); +}; + +ParamEntry::ParamEntry() + : m_mode(RT_PARAM_INVALID) +{ +} + +ParamEntry::~ParamEntry() +{ +} + +void ParamEntry::setData(const OString& typeName, + const OString& name, + RTParamMode mode) +{ + m_name = name; + m_typeName = typeName; + m_mode = mode; +} + +/************************************************************************** + + class ReferenceEntry + +**************************************************************************/ + +class ReferenceEntry +{ +public: + + OString m_name; + OString m_doku; + RTReferenceType m_type; + RTFieldAccess m_access; + + ReferenceEntry(); + ~ReferenceEntry(); + + void setData(const OString& name, + RTReferenceType refType, + const OString& doku, + RTFieldAccess access); +}; + +ReferenceEntry::ReferenceEntry() + : m_type(RT_REF_INVALID) + , m_access(RT_ACCESS_INVALID) +{ +} + +ReferenceEntry::~ReferenceEntry() +{ +} + +void ReferenceEntry::setData(const OString& name, + RTReferenceType refType, + const OString& doku, + RTFieldAccess access) +{ + m_name = name; + m_doku = doku; + m_type = refType; + m_access = access; +} + +/************************************************************************** + + class MethodEntry + +**************************************************************************/ + +class MethodEntry +{ +public: + + OString m_name; + OString m_returnTypeName; + RTMethodMode m_mode; + sal_uInt16 m_paramCount; + ParamEntry* m_params; + sal_uInt16 m_excCount; + OString* m_excNames; + OString m_doku; + + MethodEntry(); + ~MethodEntry(); + + void setData(const OString& name, + const OString& returnTypeName, + RTMethodMode mode, + sal_uInt16 paramCount, + sal_uInt16 excCount, + const OString& doku); + + void setExcName(sal_uInt16 excIndex, const OString& name); + +protected: + + void reallocParams(sal_uInt16 size); + void reallocExcs(sal_uInt16 size); +}; + +MethodEntry::MethodEntry() + : m_mode(RT_MODE_INVALID) + , m_paramCount(0) + , m_params(NULL) + , m_excCount(0) + , m_excNames(NULL) +{ +} + +MethodEntry::~MethodEntry() +{ + if (m_params) + delete[] m_params; + + if (m_excNames) + delete[] m_excNames; +} + +void MethodEntry::setData(const OString& name, + const OString& returnTypeName, + RTMethodMode mode, + sal_uInt16 paramCount, + sal_uInt16 excCount, + const OString& doku) +{ + m_name = name; + m_returnTypeName = returnTypeName; + m_doku = doku; + + m_mode = mode; + + reallocParams(paramCount); + reallocExcs(excCount); +} + +void MethodEntry::setExcName(sal_uInt16 excIndex, const OString& name) +{ + if (excIndex < m_excCount) + { + m_excNames[excIndex] = name; + } +} + +void MethodEntry::reallocParams(sal_uInt16 size) +{ + ParamEntry* newParams; + + if (size) + newParams = new ParamEntry[size]; + else + newParams = NULL; + + if (m_paramCount) + { + sal_uInt16 i; + + for (i = 0; i < SAL_MIN(size, m_paramCount); i++) + { + newParams[i].setData(m_params[i].m_typeName, m_params[i].m_name, m_params[i].m_mode); + } + + delete[] m_params; + } + + m_paramCount = size; + m_params = newParams; +} + +void MethodEntry::reallocExcs(sal_uInt16 size) +{ + OString* newExcNames; + + if (size) + newExcNames = new OString[size]; + else + newExcNames = NULL; + + sal_uInt16 i; + + for (i = 0; i < SAL_MIN(size, m_excCount); i++) + { + newExcNames[i] = m_excNames[i]; + } + + delete[] m_excNames; + + m_excCount = size; + m_excNames = newExcNames; +} + + +/************************************************************************** + + class TypeRegistryEntry + +**************************************************************************/ + +class TypeWriter +{ + +public: + + sal_uInt32 m_refCount; + typereg_Version m_version; + RTTypeClass m_typeClass; + OString m_typeName; + sal_uInt16 m_nSuperTypes; + OString* m_superTypeNames; + RTUik* m_pUik; + OString m_doku; + OString m_fileName; + sal_uInt16 m_fieldCount; + FieldEntry* m_fields; + sal_uInt16 m_methodCount; + MethodEntry* m_methods; + sal_uInt16 m_referenceCount; + ReferenceEntry* m_references; + + sal_uInt8* m_blop; + sal_uInt32 m_blopSize; + + TypeWriter(typereg_Version version, + rtl::OString const & documentation, + rtl::OString const & fileName, + RTTypeClass RTTypeClass, + bool published, + const OString& typeName, + sal_uInt16 superTypeCount, + sal_uInt16 FieldCount, + sal_uInt16 methodCount, + sal_uInt16 referenceCount); + + ~TypeWriter(); + + void setSuperType(sal_uInt16 index, OString const & name); + + void createBlop(); // throws std::bad_alloc +}; + +TypeWriter::TypeWriter(typereg_Version version, + rtl::OString const & documentation, + rtl::OString const & fileName, + RTTypeClass RTTypeClass, + bool published, + const OString& typeName, + sal_uInt16 superTypeCount, + sal_uInt16 fieldCount, + sal_uInt16 methodCount, + sal_uInt16 referenceCount) + : m_refCount(1) + , m_version(version) + , m_typeClass( + static_cast< enum RTTypeClass >( + RTTypeClass | (published ? RT_TYPE_PUBLISHED : 0))) + , m_typeName(typeName) + , m_nSuperTypes(superTypeCount) + , m_pUik(NULL) + , m_doku(documentation) + , m_fileName(fileName) + , m_fieldCount(fieldCount) + , m_methodCount(methodCount) + , m_referenceCount(referenceCount) + , m_blop(NULL) + , m_blopSize(0) +{ + if (m_nSuperTypes > 0) + { + m_superTypeNames = new OString[m_nSuperTypes]; + } else + { + m_superTypeNames = NULL; + } + + if (m_fieldCount) + m_fields = new FieldEntry[fieldCount]; + + if (m_methodCount) + m_methods = new MethodEntry[methodCount]; + + if (m_referenceCount) + m_references = new ReferenceEntry[referenceCount]; +} + +TypeWriter::~TypeWriter() +{ + if (m_superTypeNames) + delete[] m_superTypeNames; + + if (m_blop) + delete[] m_blop; + + if (m_fieldCount) + delete[] m_fields; + + if (m_methodCount) + delete[] m_methods; + + if (m_referenceCount) + delete[] m_references; + + if (m_pUik) + delete m_pUik; +} + +void TypeWriter::setSuperType(sal_uInt16 index, OString const & name) +{ + m_superTypeNames[index] = name; +} + +void TypeWriter::createBlop() +{ + //TODO: Fix memory leaks that occur when std::bad_alloc is thrown + + sal_uInt8* pBlopFields = NULL; + sal_uInt8* pBlopMethods = NULL; + sal_uInt8* pBlopReferences = NULL; + sal_uInt8* pBuffer = NULL; + sal_uInt32 blopFieldsSize = 0; + sal_uInt32 blopMethodsSize = 0; + sal_uInt32 blopReferenceSize = 0; + + CPInfo root(CP_TAG_INVALID, NULL); + sal_uInt16 cpIndexThisName = 0; + sal_uInt16* cpIndexSuperNames = NULL; + sal_uInt16 cpIndexUik = 0; + sal_uInt16 cpIndexDoku = 0; + sal_uInt16 cpIndexFileName = 0; + CPInfo* pInfo = NULL; + + sal_uInt16 entrySize = sizeof(sal_uInt16); + sal_uInt32 blopHeaderEntrySize = BLOP_OFFSET_N_ENTRIES + entrySize + (BLOP_HEADER_N_ENTRIES * entrySize); + sal_uInt32 blopFieldEntrySize = BLOP_FIELD_N_ENTRIES * entrySize; + sal_uInt32 blopMethodEntrySize = BLOP_METHOD_N_ENTRIES * entrySize; + sal_uInt32 blopParamEntrySize = BLOP_PARAM_N_ENTRIES * entrySize; + sal_uInt32 blopReferenceEntrySize = BLOP_REFERENCE_N_ENTRIES * entrySize; + + sal_uInt32 blopSize = blopHeaderEntrySize; + + // create CP entry for this name + pInfo = new CPInfo(CP_TAG_UTF8_NAME, &root); + pInfo->m_value.aUtf8 = m_typeName.getStr(); + cpIndexThisName = pInfo->m_index; + + // nSuperTypes + blopSize += entrySize; + + // create CP entry for super names + if (m_nSuperTypes) + { + blopSize += m_nSuperTypes * entrySize; + + cpIndexSuperNames = new sal_uInt16[m_nSuperTypes]; + + for (sal_uInt32 i=0; i < m_nSuperTypes; i++) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_superTypeNames[i].getStr(); + cpIndexSuperNames[i] = pInfo->m_index; + } + } + + // create CP entry for uik + if (m_pUik != NULL) + { + pInfo = new CPInfo(CP_TAG_UIK, pInfo); + pInfo->m_value.aUik = m_pUik; + cpIndexUik = pInfo->m_index; + } + + // create CP entry for doku + if (m_doku.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_doku.getStr(); + cpIndexDoku = pInfo->m_index; + } + + // create CP entry for idl source filename + if (m_fileName.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_fileName.getStr(); + cpIndexFileName = pInfo->m_index; + } + + // fields blop + blopSize += sizeof(sal_uInt16); // fieldCount + nFieldEntries + + if (m_fieldCount) + { + sal_uInt16 cpIndexName = 0; + sal_uInt16 cpIndexTypeName = 0; + sal_uInt16 cpIndexValue = 0; + sal_uInt16 cpIndexDoku2 = 0; + sal_uInt16 cpIndexFileName2 = 0; + + // nFieldEntries + n fields + blopFieldsSize = sizeof(sal_uInt16) + (m_fieldCount * blopFieldEntrySize); + + blopSize += blopFieldsSize; + + pBlopFields = new sal_uInt8[blopFieldsSize]; + pBuffer = pBlopFields; + + pBuffer += writeUINT16(pBuffer, BLOP_FIELD_N_ENTRIES); + + for (sal_uInt16 i = 0; i < m_fieldCount; i++) + { + cpIndexName = 0; + cpIndexTypeName = 0; + cpIndexValue = 0; + cpIndexDoku2 = 0; + cpIndexFileName2 = 0; + + pBuffer += writeUINT16(pBuffer, m_fields[i].m_access); + + if (m_fields[i].m_name.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_fields[i].m_name.getStr(); + cpIndexName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexName); + + if (m_fields[i].m_typeName.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_fields[i].m_typeName.getStr(); + cpIndexTypeName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexTypeName); + + if (m_fields[i].m_constValueType != RT_TYPE_NONE) + { + pInfo = new CPInfo((CPInfoTag)m_fields[i].m_constValueType, pInfo); + pInfo->m_value.aConst = m_fields[i].m_constValue; + cpIndexValue = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexValue); + + if (m_fields[i].m_doku.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_fields[i].m_doku.getStr(); + cpIndexDoku2 = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexDoku2); + + if (m_fields[i].m_fileName.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_fields[i].m_fileName.getStr(); + cpIndexFileName2 = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexFileName2); + } + } + + // methods blop + blopSize += sizeof(sal_uInt16); // methodCount + + if (m_methodCount) + { + sal_uInt16* pMethodEntrySize = new sal_uInt16[m_methodCount]; + sal_uInt16 cpIndexName = 0; + sal_uInt16 cpIndexReturn = 0; + sal_uInt16 cpIndexDoku2 = 0; + + // nMethodEntries + nParamEntries + blopMethodsSize = (2 * sizeof(sal_uInt16)); + + for (sal_uInt16 i = 0; i < m_methodCount; i++) + { + pMethodEntrySize[i] = (sal_uInt16) + ( blopMethodEntrySize + // header + sizeof(sal_uInt16) + // parameterCount + (m_methods[i].m_paramCount * blopParamEntrySize) + // exceptions + sizeof(sal_uInt16) + // exceptionCount + (m_methods[i].m_excCount * sizeof(sal_uInt16)) ); // exceptions + + blopMethodsSize += pMethodEntrySize[i]; + } + + pBlopMethods = new sal_uInt8[blopMethodsSize]; + + blopSize += blopMethodsSize; + + pBuffer = pBlopMethods; + + pBuffer += writeUINT16(pBuffer, BLOP_METHOD_N_ENTRIES); + pBuffer += writeUINT16(pBuffer, BLOP_PARAM_N_ENTRIES ); + + for (sal_uInt16 i = 0; i < m_methodCount; i++) + { + cpIndexReturn = 0; + cpIndexDoku2 = 0; + + pBuffer += writeUINT16(pBuffer, pMethodEntrySize[i]); + pBuffer += writeUINT16( + pBuffer, + sal::static_int_cast< sal_uInt16 >(m_methods[i].m_mode)); + + if (m_methods[i].m_name.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_methods[i].m_name.getStr(); + cpIndexName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexName); + cpIndexName = 0; + + if (m_methods[i].m_returnTypeName.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_methods[i].m_returnTypeName.getStr(); + cpIndexReturn = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexReturn); + + if (m_methods[i].m_doku.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_methods[i].m_doku.getStr(); + cpIndexDoku2 = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexDoku2); + + sal_uInt16 j; + + pBuffer += writeUINT16(pBuffer, m_methods[i].m_paramCount); + + for (j = 0; j < m_methods[i].m_paramCount; j++) + { + if (m_methods[i].m_params[j].m_typeName.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_methods[i].m_params[j].m_typeName.getStr(); + cpIndexName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexName); + cpIndexName = 0; + + pBuffer += writeUINT16( + pBuffer, + sal::static_int_cast< sal_uInt16 >( + m_methods[i].m_params[j].m_mode)); + + if (m_methods[i].m_params[j].m_name.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_methods[i].m_params[j].m_name.getStr(); + cpIndexName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexName); + cpIndexName = 0; + } + + pBuffer += writeUINT16(pBuffer, m_methods[i].m_excCount); + + for (j = 0; j < m_methods[i].m_excCount; j++) + { + if (m_methods[i].m_excNames[j].getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_methods[i].m_excNames[j].getStr(); + cpIndexName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexName); + cpIndexName = 0; + } + } + + delete[] pMethodEntrySize; + } + + // reference blop + blopSize += entrySize; // referenceCount + + if (m_referenceCount) + { + sal_uInt16 cpIndexName = 0; + sal_uInt16 cpIndexDoku2 = 0; + + // nReferenceEntries + n references + blopReferenceSize = entrySize + (m_referenceCount * blopReferenceEntrySize); + + blopSize += blopReferenceSize; + + pBlopReferences = new sal_uInt8[blopReferenceSize]; + pBuffer = pBlopReferences; + + pBuffer += writeUINT16(pBuffer, BLOP_REFERENCE_N_ENTRIES); + + for (sal_uInt16 i = 0; i < m_referenceCount; i++) + { + pBuffer += writeUINT16( + pBuffer, + sal::static_int_cast< sal_uInt16 >(m_references[i].m_type)); + + cpIndexName = 0; + cpIndexDoku2 = 0; + + if (m_references[i].m_name.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_references[i].m_name.getStr(); + cpIndexName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexName); + + if (m_references[i].m_doku.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_references[i].m_doku.getStr(); + cpIndexDoku2 = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexDoku2); + + pBuffer += writeUINT16(pBuffer, m_references[i].m_access); + } + } + + + // get CP infos blop-length + pInfo = root.m_next; + sal_uInt32 cpBlopSize = 0; + sal_uInt16 cpCount = 0; + + while (pInfo) + { + cpBlopSize += pInfo->getBlopSize(); + cpCount++; + pInfo = pInfo->m_next; + } + + blopSize += cpBlopSize; + blopSize += sizeof(sal_uInt16); // constantPoolCount + + // write all in flat buffer + + sal_uInt8 * blop = new sal_uInt8[blopSize]; + + pBuffer = blop; + + // Assumes two's complement arithmetic with modulo-semantics: + pBuffer += writeUINT32(pBuffer, magic + m_version); + pBuffer += writeUINT32(pBuffer, blopSize); + pBuffer += writeUINT16(pBuffer, minorVersion); + pBuffer += writeUINT16(pBuffer, majorVersion); + pBuffer += writeUINT16(pBuffer, BLOP_HEADER_N_ENTRIES); + + pBuffer += writeUINT16(pBuffer, (sal_uInt16)RT_UNO_IDL); + pBuffer += writeUINT16(pBuffer, (sal_uInt16)m_typeClass); + pBuffer += writeUINT16(pBuffer, cpIndexThisName); + pBuffer += writeUINT16(pBuffer, cpIndexUik); + pBuffer += writeUINT16(pBuffer, cpIndexDoku); + pBuffer += writeUINT16(pBuffer, cpIndexFileName); + + // write supertypes + pBuffer += writeUINT16(pBuffer, m_nSuperTypes); + if (m_nSuperTypes) + { + for (sal_uInt32 i=0; i < m_nSuperTypes; i++) + { + pBuffer += writeUINT16(pBuffer, cpIndexSuperNames[i]); + } + delete[] cpIndexSuperNames; + } + + pBuffer += writeUINT16(pBuffer, cpCount); + + // write and delete CP infos + pInfo = root.m_next; + + while (pInfo) + { + CPInfo* pNextInfo = pInfo->m_next; + + pBuffer += pInfo->toBlop(pBuffer); + delete pInfo; + + pInfo = pNextInfo; + } + + // write fields + pBuffer += writeUINT16(pBuffer, m_fieldCount); + if (blopFieldsSize) + { + memcpy(pBuffer, pBlopFields, blopFieldsSize); + pBuffer += blopFieldsSize; + } + + // write methods + pBuffer += writeUINT16(pBuffer, m_methodCount); + if (blopMethodsSize) + { + memcpy(pBuffer, pBlopMethods, blopMethodsSize); + pBuffer += blopMethodsSize; + } + + // write references + pBuffer += writeUINT16(pBuffer, m_referenceCount); + if (blopReferenceSize) + { + memcpy(pBuffer, pBlopReferences, blopReferenceSize); + pBuffer += blopReferenceSize; + } + + delete[] pBlopFields; + delete[] pBlopMethods; + delete[] pBlopReferences; + + delete[] m_blop; + m_blop = blop; + m_blopSize = blopSize; +} + + +/************************************************************************** + + C-API + +**************************************************************************/ + +extern "C" { + +static void TYPEREG_CALLTYPE acquire(TypeWriterImpl hEntry) +{ + TypeWriter* pEntry = (TypeWriter*) hEntry; + + if (pEntry != NULL) + pEntry->m_refCount++; +} + +static void TYPEREG_CALLTYPE release(TypeWriterImpl hEntry) +{ + TypeWriter* pEntry = (TypeWriter*) hEntry; + + if (pEntry != NULL) + { + if (--pEntry->m_refCount == 0) + delete pEntry; + } +} + +static void TYPEREG_CALLTYPE setUik(TypeWriterImpl hEntry, const RTUik* uik) +{ + TypeWriter* pEntry = (TypeWriter*) hEntry; + + if (pEntry != NULL) + { + if (pEntry->m_pUik) + { + pEntry->m_pUik->m_Data1 = uik->m_Data1; + pEntry->m_pUik->m_Data2 = uik->m_Data2; + pEntry->m_pUik->m_Data3 = uik->m_Data3; + pEntry->m_pUik->m_Data4 = uik->m_Data4; + pEntry->m_pUik->m_Data5 = uik->m_Data5; + } + else + pEntry->m_pUik = new RTUik(*uik); + } +} + +static void TYPEREG_CALLTYPE setDoku(TypeWriterImpl hEntry, rtl_uString* doku) +{ + static_cast< TypeWriter * >(hEntry)->m_doku = toByteString(doku); +} + +static void TYPEREG_CALLTYPE setFileName(TypeWriterImpl hEntry, rtl_uString* fileName) +{ + static_cast< TypeWriter * >(hEntry)->m_fileName = toByteString(fileName); +} + +sal_Bool typereg_writer_setFieldData( + void * handle, sal_uInt16 index, rtl_uString const * documentation, + rtl_uString const * fileName, RTFieldAccess flags, rtl_uString const * name, + rtl_uString const * typeName, RTValueType valueType, + RTConstValueUnion valueValue) + SAL_THROW_EXTERN_C() +{ + try { + static_cast< TypeWriter * >(handle)->m_fields[index].setData( + toByteString(name), toByteString(typeName), + toByteString(documentation), toByteString(fileName), flags, + valueType, valueValue); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static void TYPEREG_CALLTYPE setFieldData(TypeWriterImpl hEntry, + sal_uInt16 index, + rtl_uString* name, + rtl_uString* typeName, + rtl_uString* doku, + rtl_uString* fileName, + RTFieldAccess access, + RTValueType valueType, + RTConstValueUnion constValue) +{ + typereg_writer_setFieldData( + hEntry, index, doku, fileName, access, name, typeName, valueType, + constValue); +} + +sal_Bool typereg_writer_setMethodData( + void * handle, sal_uInt16 index, rtl_uString const * documentation, + RTMethodMode flags, rtl_uString const * name, + rtl_uString const * returnTypeName, sal_uInt16 parameterCount, + sal_uInt16 exceptionCount) + SAL_THROW_EXTERN_C() +{ + try { + static_cast< TypeWriter * >(handle)->m_methods[index].setData( + toByteString(name), toByteString(returnTypeName), flags, + parameterCount, exceptionCount, toByteString(documentation)); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static void TYPEREG_CALLTYPE setMethodData(TypeWriterImpl hEntry, + sal_uInt16 index, + rtl_uString* name, + rtl_uString* returnTypeName, + RTMethodMode mode, + sal_uInt16 paramCount, + sal_uInt16 excCount, + rtl_uString* doku) +{ + typereg_writer_setMethodData( + hEntry, index, doku, mode, name, returnTypeName, paramCount, excCount); +} + +sal_Bool typereg_writer_setMethodParameterData( + void * handle, sal_uInt16 methodIndex, sal_uInt16 parameterIndex, + RTParamMode flags, rtl_uString const * name, rtl_uString const * typeName) + SAL_THROW_EXTERN_C() +{ + try { + static_cast< TypeWriter * >(handle)-> + m_methods[methodIndex].m_params[parameterIndex].setData( + toByteString(typeName), toByteString(name), flags); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static void TYPEREG_CALLTYPE setParamData(TypeWriterImpl hEntry, + sal_uInt16 index, + sal_uInt16 paramIndex, + rtl_uString* type, + rtl_uString* name, + RTParamMode mode) +{ + typereg_writer_setMethodParameterData( + hEntry, index, paramIndex, mode, name, type); +} + +sal_Bool typereg_writer_setMethodExceptionTypeName( + void * handle, sal_uInt16 methodIndex, sal_uInt16 exceptionIndex, + rtl_uString const * typeName) + SAL_THROW_EXTERN_C() +{ + try { + static_cast< TypeWriter * >(handle)->m_methods[methodIndex].setExcName( + exceptionIndex, toByteString(typeName)); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static void TYPEREG_CALLTYPE setExcData(TypeWriterImpl hEntry, + sal_uInt16 index, + sal_uInt16 excIndex, + rtl_uString* type) +{ + typereg_writer_setMethodExceptionTypeName(hEntry, index, excIndex, type); +} + +void const * typereg_writer_getBlob(void * handle, sal_uInt32 * size) + SAL_THROW_EXTERN_C() +{ + TypeWriter * writer = static_cast< TypeWriter * >(handle); + if (writer->m_blop == 0) { + try { + writer->createBlop(); + } catch (std::bad_alloc &) { + return 0; + } + } + *size = writer->m_blopSize; + return writer->m_blop; +} + +static const sal_uInt8* TYPEREG_CALLTYPE getBlop(TypeWriterImpl hEntry) +{ + sal_uInt32 size; + return static_cast< sal_uInt8 const * >( + typereg_writer_getBlob(hEntry, &size)); +} + +static sal_uInt32 TYPEREG_CALLTYPE getBlopSize(TypeWriterImpl hEntry) +{ + sal_uInt32 size; + typereg_writer_getBlob(hEntry, &size); + return size; +} + +sal_Bool typereg_writer_setReferenceData( + void * handle, sal_uInt16 index, rtl_uString const * documentation, + RTReferenceType sort, RTFieldAccess flags, rtl_uString const * typeName) + SAL_THROW_EXTERN_C() +{ + try { + static_cast< TypeWriter * >(handle)->m_references[index].setData( + toByteString(typeName), sort, toByteString(documentation), flags); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static void TYPEREG_CALLTYPE setReferenceData(TypeWriterImpl hEntry, + sal_uInt16 index, + rtl_uString* name, + RTReferenceType refType, + rtl_uString* doku, + RTFieldAccess access) +{ + typereg_writer_setReferenceData(hEntry, index, doku, refType, access, name); +} + +void * typereg_writer_create( + typereg_Version version, rtl_uString const * documentation, + rtl_uString const * fileName, RTTypeClass typeClass, sal_Bool published, + rtl_uString const * typeName, sal_uInt16 superTypeCount, + sal_uInt16 fieldCount, sal_uInt16 methodCount, sal_uInt16 referenceCount) + SAL_THROW_EXTERN_C() +{ + try { + return new TypeWriter( + version, toByteString(documentation), toByteString(fileName), + typeClass, published, toByteString(typeName), superTypeCount, + fieldCount, methodCount, referenceCount); + } catch (std::bad_alloc &) { + return 0; + } +} + +void typereg_writer_destroy(void * handle) SAL_THROW_EXTERN_C() { + delete static_cast< TypeWriter * >(handle); +} + +sal_Bool typereg_writer_setSuperTypeName( + void * handle, sal_uInt16 index, rtl_uString const * typeName) + SAL_THROW_EXTERN_C() +{ + try { + static_cast< TypeWriter * >(handle)->setSuperType( + index, toByteString(typeName)); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static TypeWriterImpl TYPEREG_CALLTYPE createEntry( + RTTypeClass typeClass, rtl_uString * typeName, rtl_uString * superTypeName, + sal_uInt16 fieldCount, sal_uInt16 methodCount, sal_uInt16 referenceCount) +{ + rtl::OUString empty; + sal_uInt16 superTypeCount = rtl_uString_getLength(superTypeName) == 0 + ? 0 : 1; + TypeWriterImpl t = typereg_writer_create( + TYPEREG_VERSION_0, empty.pData, empty.pData, typeClass, false, typeName, + superTypeCount, fieldCount, methodCount, referenceCount); + if (superTypeCount > 0) { + typereg_writer_setSuperTypeName(t, 0, superTypeName); + } + return t; +} + +RegistryTypeWriter_Api* TYPEREG_CALLTYPE initRegistryTypeWriter_Api(void) +{ + static RegistryTypeWriter_Api aApi= {0,0,0,0,0,0,0,0,0,0,0,0,0}; + if (!aApi.acquire) + { + aApi.createEntry = &createEntry; + aApi.acquire = &acquire; + aApi.release = &release; + aApi.setUik = &setUik; + aApi.setDoku = &setDoku; + aApi.setFileName = &setFileName; + aApi.setFieldData = &setFieldData; + aApi.setMethodData = &setMethodData; + aApi.setParamData = &setParamData; + aApi.setExcData = &setExcData; + aApi.getBlop = &getBlop; + aApi.getBlopSize = &getBlopSize; + aApi.setReferenceData = &setReferenceData; + + return (&aApi); + } + else + { + return (&aApi); + } +} + +} |