diff options
Diffstat (limited to 'registry/source')
-rw-r--r-- | registry/source/keyimpl.cxx | 1081 | ||||
-rw-r--r-- | registry/source/keyimpl.hxx | 153 | ||||
-rw-r--r-- | registry/source/makefile.mk | 53 | ||||
-rw-r--r-- | registry/source/reflcnst.hxx | 297 | ||||
-rw-r--r-- | registry/source/reflread.cxx | 1773 | ||||
-rw-r--r-- | registry/source/reflwrit.cxx | 1490 | ||||
-rw-r--r-- | registry/source/regimpl.cxx | 1767 | ||||
-rw-r--r-- | registry/source/regimpl.hxx | 183 | ||||
-rw-r--r-- | registry/source/registry.cxx | 630 | ||||
-rw-r--r-- | registry/source/regkey.cxx | 1025 | ||||
-rw-r--r-- | registry/source/regkey.hxx | 83 |
11 files changed, 8535 insertions, 0 deletions
diff --git a/registry/source/keyimpl.cxx b/registry/source/keyimpl.cxx new file mode 100644 index 000000000000..4603ce41d163 --- /dev/null +++ b/registry/source/keyimpl.cxx @@ -0,0 +1,1081 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "keyimpl.hxx" + +#include "reflcnst.hxx" +#include "rtl/alloc.h" +#include "rtl/memory.h" +#include "rtl/ustrbuf.hxx" + +using rtl::OUString; +using rtl::OUStringBuffer; +using namespace store; + +namespace { static char const VALUE_PREFIX[] = "$VL_"; } + +//********************************************************************* +// ORegKey() +// +ORegKey::ORegKey(const OUString& keyName, ORegistry* pReg) + : m_refCount(1) + , m_name(keyName) + , m_bDeleted(0) + , m_bModified(0) + , m_pRegistry(pReg) +{ +} + +//********************************************************************* +// ~ORegKey() +// +ORegKey::~ORegKey() +{ + OSL_POSTCOND(m_refCount == 0, "registry::ORegKey::dtor(): refcount not zero."); +} + +//********************************************************************* +// acquireKey +// +RegError ORegKey::acquireKey(RegKeyHandle hKey) +{ + return m_pRegistry->acquireKey(hKey); +} + +//********************************************************************* +// releaseKey +// +RegError ORegKey::releaseKey(RegKeyHandle hKey) +{ + return m_pRegistry->releaseKey(hKey); +} + +//********************************************************************* +// createKey +// +RegError ORegKey::createKey(const OUString& keyName, RegKeyHandle* phNewKey) +{ + return m_pRegistry->createKey(this, keyName, phNewKey); +} + + +//********************************************************************* +// openKey +// +RegError ORegKey::openKey(const OUString& keyName, RegKeyHandle* phOpenKey) +{ + return m_pRegistry->openKey(this, keyName, phOpenKey); +} + + +//********************************************************************* +// openSubKeys +// +RegError ORegKey::openSubKeys(const OUString& keyName, RegKeyHandle** phOpenSubKeys, sal_uInt32* pnSubKeys) +{ + RegError _ret = REG_NO_ERROR; + + *phOpenSubKeys = 0; + *pnSubKeys = 0; + + ORegKey* pKey = this; + if ( keyName.getLength() ) + { + _ret = openKey(keyName, (RegKeyHandle*)&pKey); + if (_ret != REG_NO_ERROR) + return _ret; + } + + sal_uInt32 nSubKeys = pKey->countSubKeys(); + *pnSubKeys = nSubKeys; + + ORegKey** pSubKeys; + pSubKeys = (ORegKey**)rtl_allocateZeroMemory(nSubKeys * sizeof(ORegKey*)); + + OStoreDirectory::iterator iter; + OStoreDirectory rStoreDir(pKey->getStoreDir()); + storeError _err = rStoreDir.first(iter); + + nSubKeys = 0; + while ( _err == store_E_None ) + { + if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR ) + { + OUString const sSubKeyName = iter.m_pszName; + + ORegKey* pOpenSubKey = 0; + _ret = pKey->openKey(sSubKeyName, (RegKeyHandle*)&pOpenSubKey); + if (_ret != REG_NO_ERROR) + { + *phOpenSubKeys = NULL; + *pnSubKeys = 0; + rtl_freeMemory(pSubKeys); // @@@ leaking 'pSubKeys[0...nSubkeys-1]' + return _ret; // @@@ leaking 'pKey' + } + + pSubKeys[nSubKeys] = pOpenSubKey; + + nSubKeys++; + } + + _err = rStoreDir.next(iter); + } + + *phOpenSubKeys = (RegKeyHandle*)pSubKeys; + if (keyName.getLength()) + { + (void) releaseKey(pKey); + } + return REG_NO_ERROR; +} + + +//********************************************************************* +// getKeyNames +// +RegError ORegKey::getKeyNames(const OUString& keyName, + rtl_uString*** pSubKeyNames, + sal_uInt32* pnSubKeys) +{ + RegError _ret = REG_NO_ERROR; + + *pSubKeyNames = 0; + *pnSubKeys = 0; + + ORegKey* pKey = this; + if (keyName.getLength()) + { + _ret = openKey(keyName, (RegKeyHandle*)&pKey); + if (_ret != REG_NO_ERROR) + return _ret; + } + + sal_uInt32 nSubKeys = pKey->countSubKeys(); + *pnSubKeys = nSubKeys; + + rtl_uString** pSubKeys = 0; + pSubKeys = (rtl_uString**)rtl_allocateZeroMemory(nSubKeys * sizeof(rtl_uString*)); + + OStoreDirectory::iterator iter; + OStoreDirectory rStoreDir(pKey->getStoreDir()); + storeError _err = rStoreDir.first(iter); + + nSubKeys = 0; + + while ( _err == store_E_None ) + { + if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR) + { + OUString const sSubKeyName = iter.m_pszName; + + OUString sFullKeyName(pKey->getName()); + if (sFullKeyName.getLength() > 1) + sFullKeyName += m_pRegistry->ROOT; + sFullKeyName += sSubKeyName; + + rtl_uString_newFromString(&pSubKeys[nSubKeys], sFullKeyName.pData); + + nSubKeys++; + } + + _err = rStoreDir.next(iter); + } + + *pSubKeyNames = pSubKeys; + if (keyName.getLength()) + { + releaseKey(pKey); + } + return REG_NO_ERROR; +} + + +//********************************************************************* +// closeKey +// +RegError ORegKey::closeKey(RegKeyHandle hKey) +{ + return (m_pRegistry->closeKey(hKey)); +} + + +//********************************************************************* +// deleteKey +// +RegError ORegKey::deleteKey(const OUString& keyName) +{ + return (m_pRegistry->deleteKey(this, keyName)); +} + + +//********************************************************************* +// getValueType +// +RegError ORegKey::getValueInfo(const OUString& valueName, RegValueType* pValueType, sal_uInt32* pValueSize) const +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + storeAccessMode accessMode = VALUE_MODE_OPEN; + + if (m_pRegistry->isReadOnly()) + { + accessMode = VALUE_MODE_OPENREAD; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if ( rValue.create(m_pRegistry->getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) + { + *pValueType = RG_VALUETYPE_NOT_DEFINED; + *pValueSize = 0; + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 readBytes; + if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != VALUE_HEADERSIZE) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt32 size; + sal_uInt8 type = *((sal_uInt8*)pBuffer); + readUINT32(pBuffer+VALUE_TYPEOFFSET, size); + + *pValueType = (RegValueType)type; +// if (*pValueType == RG_VALUETYPE_UNICODE) +// { +// *pValueSize = (size / 2) * sizeof(sal_Unicode); +// } else +// { + if (*pValueType > 4) + { + rtl_freeMemory(pBuffer); + pBuffer = (sal_uInt8*)rtl_allocateMemory(4); + rValue.readAt(VALUE_HEADEROFFSET, pBuffer, 4, readBytes); + + readUINT32(pBuffer, size); + } + + *pValueSize = size; +// } + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + + +//********************************************************************* +// setValue +// +RegError ORegKey::setValue(const OUString& valueName, RegValueType vType, RegValue value, sal_uInt32 vSize) +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + + if (m_pRegistry->isReadOnly()) + { + return REG_REGISTRY_READONLY; + } + + if (vType > 4) + { + return REG_INVALID_VALUE; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT , sImplValueName, VALUE_MODE_CREATE) ) + { + return REG_SET_VALUE_FAILED; + } + + sal_uInt32 size = vSize; + + sal_uInt8 type = (sal_uInt8)vType; + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size); + rtl_copyMemory(pBuffer, &type, 1); + + writeUINT32(pBuffer+VALUE_TYPEOFFSET, size); + + switch (vType) + { + case RG_VALUETYPE_NOT_DEFINED: + rtl_copyMemory(pBuffer+VALUE_HEADEROFFSET, value, size); + break; + case RG_VALUETYPE_LONG: + writeINT32(pBuffer+VALUE_HEADEROFFSET, *((sal_Int32*)value)); + break; + case RG_VALUETYPE_STRING: + writeUtf8(pBuffer+VALUE_HEADEROFFSET, (const sal_Char*)value); + break; + case RG_VALUETYPE_UNICODE: + writeString(pBuffer+VALUE_HEADEROFFSET, (const sal_Unicode*)value); + break; + case RG_VALUETYPE_BINARY: + rtl_copyMemory(pBuffer+VALUE_HEADEROFFSET, value, size); + break; + default: + OSL_ASSERT(false); + break; + } + + sal_uInt32 writenBytes; + if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + if (writenBytes != (VALUE_HEADERSIZE+size)) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + setModified(); + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// setLongListValue +// +RegError ORegKey::setLongListValue(const OUString& valueName, sal_Int32* pValueList, sal_uInt32 len) +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + + if (m_pRegistry->isReadOnly()) + { + return REG_REGISTRY_READONLY; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, VALUE_MODE_CREATE) ) + { + return REG_SET_VALUE_FAILED; + } + + sal_uInt32 size = 4; // 4 Bytes (sal_uInt32) fuer die Laenge + + size += len * 4; + + sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_LONGLIST; + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size); + rtl_copyMemory(pBuffer, &type, 1); + + writeUINT32(pBuffer+VALUE_TYPEOFFSET, size); + writeUINT32(pBuffer+VALUE_HEADEROFFSET, len); + + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays + + for (sal_uInt32 i=0; i < len; i++) + { + writeINT32(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]); + offset += 4; + } + + sal_uInt32 writenBytes; + if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + if (writenBytes != (VALUE_HEADEROFFSET+size)) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + setModified(); + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// setStringListValue +// +RegError ORegKey::setStringListValue(const OUString& valueName, sal_Char** pValueList, sal_uInt32 len) +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + + if (m_pRegistry->isReadOnly()) + { + return REG_REGISTRY_READONLY; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, VALUE_MODE_CREATE) ) + { + return REG_SET_VALUE_FAILED; + } + + sal_uInt32 size = 4; // 4 Bytes (sal_uInt32) fuer die Laenge + + sal_uInt32 i; + for (i=0; i < len; i++) + { + size += 4 + strlen(pValueList[i]) + 1; + } + + sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_STRINGLIST; + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size); + rtl_copyMemory(pBuffer, &type, 1); + + writeUINT32(pBuffer+VALUE_TYPEOFFSET, size); + writeUINT32(pBuffer+VALUE_HEADEROFFSET, len); + + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; + sal_uInt32 sLen = 0; + + for (i=0; i < len; i++) + { + sLen = strlen(pValueList[i]) + 1; + writeUINT32(pBuffer+VALUE_HEADEROFFSET+offset, sLen); + + offset += 4; + writeUtf8(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]); + offset += sLen; + } + + sal_uInt32 writenBytes; + if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + if (writenBytes != (VALUE_HEADERSIZE+size)) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + setModified(); + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// setUnicodeListValue +// +RegError ORegKey::setUnicodeListValue(const OUString& valueName, sal_Unicode** pValueList, sal_uInt32 len) +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + + if (m_pRegistry->isReadOnly()) + { + return REG_REGISTRY_READONLY; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, VALUE_MODE_CREATE) ) + { + return REG_SET_VALUE_FAILED; + } + + sal_uInt32 size = 4; // 4 Bytes (sal_uInt32) fuer die Laenge + + sal_uInt32 i; + for (i=0; i < len; i++) + { + size += 4 + ((rtl_ustr_getLength(pValueList[i]) +1) * 2); + } + + sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_UNICODELIST; + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size); + rtl_copyMemory(pBuffer, &type, 1); + + writeUINT32(pBuffer+VALUE_TYPEOFFSET, size); + writeUINT32(pBuffer+VALUE_HEADEROFFSET, len); + + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; + sal_uInt32 sLen = 0; + + for (i=0; i < len; i++) + { + sLen = (rtl_ustr_getLength(pValueList[i]) + 1) * 2; + writeUINT32(pBuffer+VALUE_HEADEROFFSET+offset, sLen); + + offset += 4; + writeString(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]); + offset += sLen; + } + + sal_uInt32 writenBytes; + if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + if (writenBytes != (VALUE_HEADERSIZE+size)) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + setModified(); + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// getValue +// +RegError ORegKey::getValue(const OUString& valueName, RegValue value) const +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + RegValueType valueType; + sal_uInt32 valueSize; + storeAccessMode accessMode = VALUE_MODE_OPEN; + + if (m_pRegistry->isReadOnly()) + { + accessMode = VALUE_MODE_OPENREAD; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) + { + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 readBytes; + if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != VALUE_HEADERSIZE) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + + rtl_freeMemory(pBuffer); + + if (valueType > 4) + { + return REG_INVALID_VALUE; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + + if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != valueSize) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + switch (valueType) + { + case RG_VALUETYPE_NOT_DEFINED: + rtl_copyMemory(value, pBuffer, valueSize); + break; + case RG_VALUETYPE_LONG: + readINT32(pBuffer, *((sal_Int32*)value)); + break; + case RG_VALUETYPE_STRING: + readUtf8(pBuffer, (sal_Char*)value, valueSize); + break; + case RG_VALUETYPE_UNICODE: + readString(pBuffer, (sal_Unicode*)value, valueSize); + break; + case RG_VALUETYPE_BINARY: + rtl_copyMemory(value, pBuffer, valueSize); + break; + case RG_VALUETYPE_LONGLIST: + case RG_VALUETYPE_STRINGLIST: + case RG_VALUETYPE_UNICODELIST: + rtl_copyMemory(value, pBuffer, valueSize); + break; + } + + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// getLongListValue +// +RegError ORegKey::getLongListValue(const OUString& valueName, sal_Int32** pValueList, sal_uInt32* pLen) const +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + RegValueType valueType; + sal_uInt32 valueSize; + storeAccessMode accessMode = VALUE_MODE_OPEN; + + if (m_pRegistry->isReadOnly()) + { + accessMode = VALUE_MODE_OPENREAD; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) + { + pValueList = NULL; + *pLen = 0; + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 readBytes; + if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != VALUE_HEADERSIZE) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + + if (valueType != RG_VALUETYPE_LONGLIST) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + + rtl_freeMemory(pBuffer); + + pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + + if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) ) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != valueSize) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt32 len = 0; + readUINT32(pBuffer, len); + + *pLen = len; + sal_Int32* pVList = (sal_Int32*)rtl_allocateZeroMemory(len * sizeof(sal_Int32)); + + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; + + for (sal_uInt32 i=0; i < len; i++) + { + readINT32(pBuffer+offset, pVList[i]); + offset += 4; + } + + *pValueList = pVList; + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// getStringListValue +// +RegError ORegKey::getStringListValue(const OUString& valueName, sal_Char*** pValueList, sal_uInt32* pLen) const +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + RegValueType valueType; + sal_uInt32 valueSize; + storeAccessMode accessMode = VALUE_MODE_OPEN; + + if (m_pRegistry->isReadOnly()) + { + accessMode = VALUE_MODE_OPENREAD; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) + { + pValueList = NULL; + *pLen = 0; + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 readBytes; + if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != VALUE_HEADERSIZE) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + + if (valueType != RG_VALUETYPE_STRINGLIST) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + + rtl_freeMemory(pBuffer); + + pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + + if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) ) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != valueSize) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt32 len = 0; + readUINT32(pBuffer, len); + + *pLen = len; + sal_Char** pVList = (sal_Char**)rtl_allocateZeroMemory(len * sizeof(sal_Char*)); + + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; + sal_uInt32 sLen = 0; + + sal_Char *pValue; + for (sal_uInt32 i=0; i < len; i++) + { + readUINT32(pBuffer+offset, sLen); + + offset += 4; + + pValue = (sal_Char*)rtl_allocateMemory(sLen); + readUtf8(pBuffer+offset, pValue, sLen); + pVList[i] = pValue; + + offset += sLen; + } + + *pValueList = pVList; + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// getUnicodeListValue +// +RegError ORegKey::getUnicodeListValue(const OUString& valueName, sal_Unicode*** pValueList, sal_uInt32* pLen) const +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + RegValueType valueType; + sal_uInt32 valueSize; + storeAccessMode accessMode = VALUE_MODE_OPEN; + + if (m_pRegistry->isReadOnly()) + { + accessMode = VALUE_MODE_OPENREAD; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) + { + pValueList = NULL; + *pLen = 0; + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 readBytes; + if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != VALUE_HEADERSIZE) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + + if (valueType != RG_VALUETYPE_UNICODELIST) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + + rtl_freeMemory(pBuffer); + + pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + + if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) ) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != valueSize) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt32 len = 0; + readUINT32(pBuffer, len); + + *pLen = len; + sal_Unicode** pVList = (sal_Unicode**)rtl_allocateZeroMemory(len * sizeof(sal_Unicode*)); + + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; + sal_uInt32 sLen = 0; + + sal_Unicode *pValue; + for (sal_uInt32 i=0; i < len; i++) + { + readUINT32(pBuffer+offset, sLen); + + offset += 4; + + pValue = (sal_Unicode*)rtl_allocateMemory((sLen / 2) * sizeof(sal_Unicode)); + readString(pBuffer+offset, pValue, sLen); + pVList[i] = pValue; + + offset += sLen; + } + + *pValueList = pVList; + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// getKeyType() +// +RegError ORegKey::getKeyType(const OUString& name, RegKeyType* pKeyType) const +{ + *pKeyType = RG_KEYTYPE; + + REG_GUARD(m_pRegistry->m_mutex); + + if ( name.getLength() ) + { + ORegKey* pThis = const_cast< ORegKey* >(this); + + RegKeyHandle hKey = 0; + RegError _ret = pThis->openKey(name, &hKey); + if (_ret != REG_NO_ERROR) + return _ret; + (void) pThis->releaseKey(hKey); + } + + return REG_NO_ERROR; +} + +RegError ORegKey::getResolvedKeyName(const OUString& keyName, + OUString& resolvedName) +{ + if (keyName.getLength() == 0) + return REG_INVALID_KEYNAME; + + resolvedName = getFullPath(keyName); + return REG_NO_ERROR; +} + +//********************************************************************* +// countSubKeys() +// +sal_uInt32 ORegKey::countSubKeys() +{ + REG_GUARD(m_pRegistry->m_mutex); + + OStoreDirectory::iterator iter; + OStoreDirectory rStoreDir = getStoreDir(); + storeError _err = rStoreDir.first(iter); + sal_uInt32 count = 0; + + while ( _err == store_E_None ) + { + if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR ) + { + count++; + } + + _err = rStoreDir.next(iter); + } + + return count; +} + +OStoreDirectory ORegKey::getStoreDir() +{ + OStoreDirectory rStoreDir; + OUString fullPath; + OUString relativName; + storeAccessMode accessMode = KEY_MODE_OPEN; + + if ( m_name.equals(m_pRegistry->ROOT) ) + { + fullPath = OUString(); + relativName = OUString(); + } else + { + fullPath = m_name.copy(0, m_name.lastIndexOf('/') + 1); + relativName = m_name.copy(m_name.lastIndexOf('/') + 1); + } + + if (m_pRegistry->isReadOnly()) + { + accessMode = KEY_MODE_OPENREAD; + } + + rStoreDir.create(getStoreFile(), fullPath, relativName, accessMode); + + return rStoreDir; +} + +OUString ORegKey::getFullPath(OUString const & path) const { + OSL_ASSERT(m_name.getLength() != 0 && path.getLength() != 0); + OUStringBuffer b(m_name); + if (b.charAt(b.getLength() - 1) == '/') { + if (path[0] == '/') { + b.append(path.getStr() + 1, path.getLength() - 1); + } else { + b.append(path); + } + } else { + if (path[0] != '/') { + b.append(sal_Unicode('/')); + } + b.append(path); + } + return b.makeStringAndClear(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/registry/source/keyimpl.hxx b/registry/source/keyimpl.hxx new file mode 100644 index 000000000000..a384d2024953 --- /dev/null +++ b/registry/source/keyimpl.hxx @@ -0,0 +1,153 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _KEYIMPL_HXX_ +#define _KEYIMPL_HXX_ + +#include <registry/registry.h> +#include "regimpl.hxx" +#include <rtl/ustring.hxx> + +class ORegKey +{ +public: + + ORegKey(const rtl::OUString& keyName, ORegistry* pReg); + ~ORegKey(); + + sal_uInt32 acquire() + { return ++m_refCount; } + + sal_uInt32 release() + { return --m_refCount; } + + RegError acquireKey(RegKeyHandle hKey); + RegError releaseKey(RegKeyHandle hKey); + + RegError createKey(const rtl::OUString& keyName, RegKeyHandle* phNewKey); + + RegError openKey(const rtl::OUString& keyName, RegKeyHandle* phOpenKey); + + RegError openSubKeys(const rtl::OUString& keyName, + RegKeyHandle** phOpenSubKeys, + sal_uInt32* pnSubKeys); + + RegError getKeyNames(const rtl::OUString& keyName, + rtl_uString*** pSubKeyNames, + sal_uInt32* pnSubKeys); + + RegError closeKey(RegKeyHandle hKey); + + RegError deleteKey(const rtl::OUString& keyName); + + RegError getValueInfo(const rtl::OUString& valueName, + RegValueType* pValueTye, + sal_uInt32* pValueSize) const; + + RegError setValue(const rtl::OUString& valueName, + RegValueType vType, + RegValue value, + sal_uInt32 vSize); + + RegError setLongListValue(const rtl::OUString& valueName, + sal_Int32* pValueList, + sal_uInt32 len); + + RegError setStringListValue(const rtl::OUString& valueName, + sal_Char** pValueList, + sal_uInt32 len); + + RegError setUnicodeListValue(const rtl::OUString& valueName, + sal_Unicode** pValueList, + sal_uInt32 len); + + RegError getValue(const rtl::OUString& valueName, RegValue value) const; + + RegError getLongListValue(const rtl::OUString& valueName, + sal_Int32** pValueList, + sal_uInt32* pLen) const; + + RegError getStringListValue(const rtl::OUString& valueName, + sal_Char*** pValueList, + sal_uInt32* pLen) const; + + RegError getUnicodeListValue(const rtl::OUString& valueName, + sal_Unicode*** pValueList, + sal_uInt32* pLen) const; + + RegError getKeyType(const rtl::OUString& name, + RegKeyType* pKeyType) const; + + RegError getResolvedKeyName(const rtl::OUString& keyName, + rtl::OUString& resolvedName); + + bool isDeleted() const + { return m_bDeleted != 0; } + + void setDeleted (sal_Bool bKeyDeleted) + { m_bDeleted = bKeyDeleted ? 1 : 0; } + + bool isModified() const + { return m_bModified != 0; } + + void setModified (bool bModified = true) + { m_bModified = bModified ? 1 : 0; } + + sal_Bool isReadOnly() const + { return m_pRegistry->isReadOnly(); } + + sal_uInt32 countSubKeys(); + + ORegistry* getRegistry() const + { return m_pRegistry; } + + const store::OStoreFile& getStoreFile() const + { return m_pRegistry->getStoreFile(); } + + store::OStoreDirectory getStoreDir(); + + const rtl::OUString& getName() const + { return m_name; } + + sal_uInt32 getRefCount() const + { return m_refCount; } + + rtl::OUString getFullPath(rtl::OUString const & path) const; + +private: + sal_uInt32 m_refCount; + rtl::OUString m_name; + int m_bDeleted:1; + int m_bModified:1; + ORegistry* m_pRegistry; +}; + +#endif + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/registry/source/makefile.mk b/registry/source/makefile.mk new file mode 100644 index 000000000000..9b9cb5ca4fee --- /dev/null +++ b/registry/source/makefile.mk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +PRJ=.. + +PRJNAME=registry +TARGET=regcpp + +ENABLE_EXCEPTIONS := TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : ..$/version.mk + +# ------------------------------------------------------------------ + +SLOFILES= \ + $(SLO)$/regimpl.obj \ + $(SLO)$/regkey.obj \ + $(SLO)$/registry.obj \ + $(SLO)$/keyimpl.obj \ + $(SLO)$/reflread.obj \ + $(SLO)$/reflwrit.obj + +# ------------------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/registry/source/reflcnst.hxx b/registry/source/reflcnst.hxx new file mode 100644 index 000000000000..8d682d9a966b --- /dev/null +++ b/registry/source/reflcnst.hxx @@ -0,0 +1,297 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _REFLCNST_HXX_ +#define _REFLCNST_HXX_ + +#include <registry/refltype.hxx> +#include <sal/macros.h> + +#include <string.h> + +#define REGTYPE_IEEE_NATIVE 1 + +extern const sal_uInt32 magic; +extern const sal_uInt16 minorVersion; +extern const sal_uInt16 majorVersion; + +#define OFFSET_MAGIC 0 +#define OFFSET_SIZE (OFFSET_MAGIC + sizeof(magic)) +#define OFFSET_MINOR_VERSION (OFFSET_SIZE + sizeof(sal_uInt32)) +#define OFFSET_MAJOR_VERSION (OFFSET_MINOR_VERSION + sizeof(minorVersion)) +#define OFFSET_N_ENTRIES (OFFSET_MAJOR_VERSION + sizeof(sal_uInt16)) +#define OFFSET_TYPE_SOURCE (OFFSET_N_ENTRIES + sizeof(sal_uInt16)) +#define OFFSET_TYPE_CLASS (OFFSET_TYPE_SOURCE + sizeof(sal_uInt16)) +#define OFFSET_THIS_TYPE (OFFSET_TYPE_CLASS + sizeof(sal_uInt16)) +#define OFFSET_UIK (OFFSET_THIS_TYPE + sizeof(sal_uInt16)) +#define OFFSET_DOKU (OFFSET_UIK + sizeof(sal_uInt16)) +#define OFFSET_FILENAME (OFFSET_DOKU + sizeof(sal_uInt16)) + +#define OFFSET_N_SUPERTYPES (OFFSET_FILENAME + sizeof(sal_uInt16)) +#define OFFSET_SUPERTYPES (OFFSET_N_SUPERTYPES + sizeof(sal_uInt16)) + +#define OFFSET_CP_SIZE (OFFSET_SUPERTYPES + sizeof(sal_uInt16)) +#define OFFSET_CP (OFFSET_CP_SIZE + sizeof(sal_uInt16)) + +#define CP_OFFSET_ENTRY_SIZE 0 +#define CP_OFFSET_ENTRY_TAG (CP_OFFSET_ENTRY_SIZE + sizeof(sal_uInt32)) +#define CP_OFFSET_ENTRY_DATA (CP_OFFSET_ENTRY_TAG + sizeof(sal_uInt16)) +#define CP_OFFSET_ENTRY_UIK1 CP_OFFSET_ENTRY_DATA +#define CP_OFFSET_ENTRY_UIK2 (CP_OFFSET_ENTRY_UIK1 + sizeof(sal_uInt32)) +#define CP_OFFSET_ENTRY_UIK3 (CP_OFFSET_ENTRY_UIK2 + sizeof(sal_uInt16)) +#define CP_OFFSET_ENTRY_UIK4 (CP_OFFSET_ENTRY_UIK3 + sizeof(sal_uInt16)) +#define CP_OFFSET_ENTRY_UIK5 (CP_OFFSET_ENTRY_UIK4 + sizeof(sal_uInt32)) + +#define FIELD_OFFSET_ACCESS 0 +#define FIELD_OFFSET_NAME (FIELD_OFFSET_ACCESS + sizeof(sal_uInt16)) +#define FIELD_OFFSET_TYPE (FIELD_OFFSET_NAME + sizeof(sal_uInt16)) +#define FIELD_OFFSET_VALUE (FIELD_OFFSET_TYPE + sizeof(sal_uInt16)) +#define FIELD_OFFSET_DOKU (FIELD_OFFSET_VALUE + sizeof(sal_uInt16)) +#define FIELD_OFFSET_FILENAME (FIELD_OFFSET_DOKU + sizeof(sal_uInt16)) +//#define FIELD_ENTRY_SIZE (FIELD_OFFSET_FILENAME + sizeof(sal_uInt16)) + +#define PARAM_OFFSET_TYPE 0 +#define PARAM_OFFSET_MODE (PARAM_OFFSET_TYPE + sizeof(sal_uInt16)) +#define PARAM_OFFSET_NAME (PARAM_OFFSET_MODE + sizeof(sal_uInt16)) +//#define PARAM_ENTRY_SIZE (PARAM_OFFSET_NAME + sizeof(sal_uInt16)) + +#define METHOD_OFFSET_SIZE 0 +#define METHOD_OFFSET_MODE (METHOD_OFFSET_SIZE + sizeof(sal_uInt16)) +#define METHOD_OFFSET_NAME (METHOD_OFFSET_MODE + sizeof(sal_uInt16)) +#define METHOD_OFFSET_RETURN (METHOD_OFFSET_NAME + sizeof(sal_uInt16)) +#define METHOD_OFFSET_DOKU (METHOD_OFFSET_RETURN + sizeof(sal_uInt16)) +#define METHOD_OFFSET_PARAM_COUNT (METHOD_OFFSET_DOKU + sizeof(sal_uInt16)) +//#define METHOD_OFFSET_PARAM(i) (METHOD_OFFSET_PARAM_COUNT + sizeof(sal_uInt16) + (i * PARAM_ENTRY_SIZE)) + +#define REFERENCE_OFFSET_TYPE 0 +#define REFERENCE_OFFSET_NAME (REFERENCE_OFFSET_TYPE + sizeof(sal_uInt16)) +#define REFERENCE_OFFSET_DOKU (REFERENCE_OFFSET_NAME + sizeof(sal_uInt16)) +#define REFERENCE_OFFSET_ACCESS (REFERENCE_OFFSET_DOKU + sizeof(sal_uInt16)) +//#define REFERENCE_ENTRY_SIZE (REFERENCE_OFFSET_ACCESS + sizeof(sal_uInt16)) + +enum CPInfoTag +{ + CP_TAG_INVALID = RT_TYPE_NONE, + CP_TAG_CONST_BOOL = RT_TYPE_BOOL, + CP_TAG_CONST_BYTE = RT_TYPE_BYTE, + CP_TAG_CONST_INT16 = RT_TYPE_INT16, + CP_TAG_CONST_UINT16 = RT_TYPE_UINT16, + CP_TAG_CONST_INT32 = RT_TYPE_INT32, + CP_TAG_CONST_UINT32 = RT_TYPE_UINT32, + CP_TAG_CONST_INT64 = RT_TYPE_INT64, + CP_TAG_CONST_UINT64 = RT_TYPE_UINT64, + CP_TAG_CONST_FLOAT = RT_TYPE_FLOAT, + CP_TAG_CONST_DOUBLE = RT_TYPE_DOUBLE, + CP_TAG_CONST_STRING = RT_TYPE_STRING, + CP_TAG_UTF8_NAME, + CP_TAG_UIK +}; + +inline sal_uInt32 writeBYTE(sal_uInt8* buffer, sal_uInt8 v) +{ + buffer[0] = v; + + return sizeof(sal_uInt8); +} + +inline sal_uInt16 readBYTE(const sal_uInt8* buffer, sal_uInt8& v) +{ + v = buffer[0]; + + return sizeof(sal_uInt8); +} + +inline sal_uInt32 writeINT16(sal_uInt8* buffer, sal_Int16 v) +{ + buffer[0] = (sal_uInt8)((v >> 8) & 0xFF); + buffer[1] = (sal_uInt8)((v >> 0) & 0xFF); + + return sizeof(sal_Int16); +} + +inline sal_uInt32 readINT16(const sal_uInt8* buffer, sal_Int16& v) +{ + v = ((buffer[0] << 8) | (buffer[1] << 0)); + + return sizeof(sal_Int16); +} + +inline sal_uInt32 writeUINT16(sal_uInt8* buffer, sal_uInt16 v) +{ + buffer[0] = (sal_uInt8)((v >> 8) & 0xFF); + buffer[1] = (sal_uInt8)((v >> 0) & 0xFF); + + return sizeof(sal_uInt16); +} + +inline sal_uInt32 readUINT16(const sal_uInt8* buffer, sal_uInt16& v) +{ + v = ((buffer[0] << 8) | (buffer[1] << 0)); + + return sizeof(sal_uInt16); +} + +inline sal_uInt32 writeINT32(sal_uInt8* buffer, sal_Int32 v) +{ + buffer[0] = (sal_uInt8)((v >> 24) & 0xFF); + buffer[1] = (sal_uInt8)((v >> 16) & 0xFF); + buffer[2] = (sal_uInt8)((v >> 8) & 0xFF); + buffer[3] = (sal_uInt8)((v >> 0) & 0xFF); + + return sizeof(sal_Int32); +} + +inline sal_uInt32 readINT32(const sal_uInt8* buffer, sal_Int32& v) +{ + v = ( + (buffer[0] << 24) | + (buffer[1] << 16) | + (buffer[2] << 8) | + (buffer[3] << 0) + ); + + return sizeof(sal_Int32); +} + +inline sal_uInt32 writeUINT32(sal_uInt8* buffer, sal_uInt32 v) +{ + buffer[0] = (sal_uInt8)((v >> 24) & 0xFF); + buffer[1] = (sal_uInt8)((v >> 16) & 0xFF); + buffer[2] = (sal_uInt8)((v >> 8) & 0xFF); + buffer[3] = (sal_uInt8)((v >> 0) & 0xFF); + + return sizeof(sal_uInt32); +} + +inline sal_uInt32 readUINT32(const sal_uInt8* buffer, sal_uInt32& v) +{ + v = ( + (buffer[0] << 24) | + (buffer[1] << 16) | + (buffer[2] << 8) | + (buffer[3] << 0) + ); + + return sizeof(sal_uInt32); +} + +inline sal_uInt32 writeINT64(sal_uInt8* buffer, sal_Int64 v) +{ + buffer[0] = (sal_uInt8)((v >> 56) & 0xFF); + buffer[1] = (sal_uInt8)((v >> 48) & 0xFF); + buffer[2] = (sal_uInt8)((v >> 40) & 0xFF); + buffer[3] = (sal_uInt8)((v >> 32) & 0xFF); + buffer[4] = (sal_uInt8)((v >> 24) & 0xFF); + buffer[5] = (sal_uInt8)((v >> 16) & 0xFF); + buffer[6] = (sal_uInt8)((v >> 8) & 0xFF); + buffer[7] = (sal_uInt8)((v >> 0) & 0xFF); + + return sizeof(sal_Int64); +} + +inline sal_uInt32 readINT64(const sal_uInt8* buffer, sal_Int64& v) +{ + v = ( + ((sal_Int64)buffer[0] << 56) | + ((sal_Int64)buffer[1] << 48) | + ((sal_Int64)buffer[2] << 40) | + ((sal_Int64)buffer[3] << 32) | + ((sal_Int64)buffer[4] << 24) | + ((sal_Int64)buffer[5] << 16) | + ((sal_Int64)buffer[6] << 8) | + ((sal_Int64)buffer[7] << 0) + ); + + return sizeof(sal_Int64); +} + +inline sal_uInt32 writeUINT64(sal_uInt8* buffer, sal_uInt64 v) +{ + buffer[0] = (sal_uInt8)((v >> 56) & 0xFF); + buffer[1] = (sal_uInt8)((v >> 48) & 0xFF); + buffer[2] = (sal_uInt8)((v >> 40) & 0xFF); + buffer[3] = (sal_uInt8)((v >> 32) & 0xFF); + buffer[4] = (sal_uInt8)((v >> 24) & 0xFF); + buffer[5] = (sal_uInt8)((v >> 16) & 0xFF); + buffer[6] = (sal_uInt8)((v >> 8) & 0xFF); + buffer[7] = (sal_uInt8)((v >> 0) & 0xFF); + + return sizeof(sal_uInt64); +} + +inline sal_uInt32 readUINT64(const sal_uInt8* buffer, sal_uInt64& v) +{ + v = ( + ((sal_uInt64)buffer[0] << 56) | + ((sal_uInt64)buffer[1] << 48) | + ((sal_uInt64)buffer[2] << 40) | + ((sal_uInt64)buffer[3] << 32) | + ((sal_uInt64)buffer[4] << 24) | + ((sal_uInt64)buffer[5] << 16) | + ((sal_uInt64)buffer[6] << 8) | + ((sal_uInt64)buffer[7] << 0) + ); + + return sizeof(sal_uInt64); +} + +inline sal_uInt32 writeUtf8(sal_uInt8* buffer, const sal_Char* v) +{ + sal_uInt32 size = strlen(v) + 1; + + memcpy(buffer, v, size); + + return (size); +} + +inline sal_uInt32 readUtf8(const sal_uInt8* buffer, sal_Char* v, sal_uInt32 maxSize) +{ + sal_uInt32 size = SAL_MIN(strlen((const sal_Char*) buffer) + 1, maxSize); + + memcpy(v, buffer, size); + + if (size == maxSize) v[size - 1] = '\0'; + + return (size); +} + + +sal_uInt32 writeFloat(sal_uInt8* buffer, float v); +sal_uInt32 writeDouble(sal_uInt8* buffer, double v); +sal_uInt32 writeString(sal_uInt8* buffer, const sal_Unicode* v); +sal_uInt32 readString(const sal_uInt8* buffer, sal_Unicode* v, sal_uInt32 maxSize); + +sal_uInt32 UINT16StringLen(const sal_uInt8* wstring); + +#endif + + + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/registry/source/reflread.cxx b/registry/source/reflread.cxx new file mode 100644 index 000000000000..ad5821d587f9 --- /dev/null +++ b/registry/source/reflread.cxx @@ -0,0 +1,1773 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 <memory> +#include <new> + +#include <string.h> +#include <sal/types.h> +#include <osl/endian.h> +#include <registry/reflread.hxx> + +#include "registry/reader.h" +#include "registry/version.h" + +#include "reflcnst.hxx" + +#include <cstddef> + +static sal_Char NULL_STRING[1] = { 0 }; +static sal_Unicode NULL_WSTRING[1] = { 0 }; + +const sal_uInt32 magic = 0x12345678; +const sal_uInt16 minorVersion = 0x0000; +const sal_uInt16 majorVersion = 0x0001; + +/************************************************************************** + + class BlopObject + + holds any data in a flat memory buffer + +**************************************************************************/ + +class BlopObject +{ +public: + const sal_uInt8* m_pBuffer; + sal_uInt32 m_bufferLen; + sal_Bool m_isCopied; + + BlopObject(const sal_uInt8* buffer, sal_uInt32 len, sal_Bool copyBuffer); + // throws std::bad_alloc + + ~BlopObject(); + + inline sal_uInt8 readBYTE(sal_uInt32 index) const + { + return m_pBuffer[index]; + } + + inline sal_Int16 readINT16(sal_uInt32 index) const + { + return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0)); + } + + inline sal_uInt16 readUINT16(sal_uInt32 index) const + { + return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0)); + } + + inline sal_Int32 readINT32(sal_uInt32 index) const + { + return ( + (m_pBuffer[index] << 24) | + (m_pBuffer[index+1] << 16) | + (m_pBuffer[index+2] << 8) | + (m_pBuffer[index+3] << 0) + ); + } + + inline sal_uInt32 readUINT32(sal_uInt32 index) const + { + return ( + (m_pBuffer[index] << 24) | + (m_pBuffer[index+1] << 16) | + (m_pBuffer[index+2] << 8) | + (m_pBuffer[index+3] << 0) + ); + } + + inline sal_Int64 readINT64(sal_uInt32 index) const + { + return ( + ((sal_Int64)m_pBuffer[index] << 56) | + ((sal_Int64)m_pBuffer[index+1] << 48) | + ((sal_Int64)m_pBuffer[index+2] << 40) | + ((sal_Int64)m_pBuffer[index+3] << 32) | + ((sal_Int64)m_pBuffer[index+4] << 24) | + ((sal_Int64)m_pBuffer[index+5] << 16) | + ((sal_Int64)m_pBuffer[index+6] << 8) | + ((sal_Int64)m_pBuffer[index+7] << 0) + ); + } + + inline sal_uInt64 readUINT64(sal_uInt32 index) const + { + return ( + ((sal_uInt64)m_pBuffer[index] << 56) | + ((sal_uInt64)m_pBuffer[index+1] << 48) | + ((sal_uInt64)m_pBuffer[index+2] << 40) | + ((sal_uInt64)m_pBuffer[index+3] << 32) | + ((sal_uInt64)m_pBuffer[index+4] << 24) | + ((sal_uInt64)m_pBuffer[index+5] << 16) | + ((sal_uInt64)m_pBuffer[index+6] << 8) | + ((sal_uInt64)m_pBuffer[index+7] << 0) + ); + } +}; + +BlopObject::BlopObject(const sal_uInt8* buffer, sal_uInt32 len, sal_Bool copyBuffer) + : m_bufferLen(len) + , m_isCopied(copyBuffer) +{ + if (m_isCopied) + { + m_pBuffer = 0; + sal_uInt8* newBuffer = new sal_uInt8[len]; + memcpy(newBuffer, buffer, len); + m_pBuffer = newBuffer; + } + else + { + m_pBuffer = buffer; + } +} + +BlopObject::~BlopObject() +{ + if (m_isCopied) + { + delete[] const_cast<sal_uInt8*>(m_pBuffer); + } +} + +/************************************************************************** + + class StringCache + +**************************************************************************/ + +class StringCache +{ +public: + sal_Unicode** m_stringTable; + sal_uInt16 m_numOfStrings; + sal_uInt16 m_stringsCopied; + + StringCache(sal_uInt16 size); // throws std::bad_alloc + ~StringCache(); + + const sal_Unicode* getString(sal_uInt16 index); + sal_uInt16 createString(const sal_uInt8* buffer); // throws std::bad_alloc +}; + +StringCache::StringCache(sal_uInt16 size) + : m_stringTable(NULL) + , m_numOfStrings(size) + , m_stringsCopied(0) +{ + m_stringTable = new sal_Unicode*[m_numOfStrings]; + + for (sal_uInt16 i = 0; i < m_numOfStrings; i++) + { + m_stringTable[i] = NULL; + } +} + +StringCache::~StringCache() +{ + if (m_stringTable) + { + for (sal_uInt16 i = 0; i < m_stringsCopied; i++) + { + delete[] m_stringTable[i]; + } + + delete[] m_stringTable; + } +} + +const sal_Unicode* StringCache::getString(sal_uInt16 index) +{ + if ((index > 0) && (index <= m_stringsCopied)) + return m_stringTable[index - 1]; + else + return NULL; +} + +sal_uInt16 StringCache::createString(const sal_uInt8* buffer) +{ + if (m_stringsCopied < m_numOfStrings) + { + sal_uInt32 len = UINT16StringLen(buffer); + + m_stringTable[m_stringsCopied] = new sal_Unicode[len + 1]; + + readString(buffer, m_stringTable[m_stringsCopied], (len + 1) * sizeof(sal_Unicode)); + + return ++m_stringsCopied; + } + else + return 0; +} + +/************************************************************************** + + class ConstantPool + +**************************************************************************/ + +class ConstantPool : public BlopObject +{ +public: + + sal_uInt16 m_numOfEntries; + sal_Int32* m_pIndex; // index values may be < 0 for cached string constants + + StringCache* m_pStringCache; + + ConstantPool(const sal_uInt8* buffer, sal_uInt16 numEntries) + : BlopObject(buffer, 0, sal_False) + , m_numOfEntries(numEntries) + , m_pIndex(NULL) + , m_pStringCache(NULL) + { + } + + ~ConstantPool(); + + sal_uInt32 parseIndex(); // throws std::bad_alloc + + CPInfoTag readTag(sal_uInt16 index); + + const sal_Char* readUTF8NameConstant(sal_uInt16 index); + sal_Bool readBOOLConstant(sal_uInt16 index); + sal_uInt8 readBYTEConstant(sal_uInt16 index); + sal_Int16 readINT16Constant(sal_uInt16 index); + sal_uInt16 readUINT16Constant(sal_uInt16 index); + sal_Int32 readINT32Constant(sal_uInt16 index); + sal_uInt32 readUINT32Constant(sal_uInt16 index); + sal_Int64 readINT64Constant(sal_uInt16 index); + sal_uInt64 readUINT64Constant(sal_uInt16 index); + float readFloatConstant(sal_uInt16 index); + double readDoubleConstant(sal_uInt16 index); + const sal_Unicode* readStringConstant(sal_uInt16 index); + // throws std::bad_alloc + void readUIK(sal_uInt16 index, RTUik* uik); +}; + +ConstantPool::~ConstantPool() +{ + delete[] m_pIndex; + delete m_pStringCache; +} + +sal_uInt32 ConstantPool::parseIndex() +{ + if (m_pIndex) + { + delete[] m_pIndex; + m_pIndex = NULL; + } + + if (m_pStringCache) + { + delete m_pStringCache; + m_pStringCache = NULL; + } + + sal_uInt32 offset = 0; + sal_uInt16 numOfStrings = 0; + + if (m_numOfEntries) + { + m_pIndex = new sal_Int32[m_numOfEntries]; + + for (int i = 0; i < m_numOfEntries; i++) + { + m_pIndex[i] = offset; + + offset += readUINT32(offset); + + if ( ((CPInfoTag) readUINT16(m_pIndex[i] + CP_OFFSET_ENTRY_TAG)) == + CP_TAG_CONST_STRING ) + { + numOfStrings++; + } + + } + } + + if (numOfStrings) + { + m_pStringCache = new StringCache(numOfStrings); + } + + m_bufferLen = offset; + + return offset; +} + +CPInfoTag ConstantPool::readTag(sal_uInt16 index) +{ + CPInfoTag tag = CP_TAG_INVALID; + + if (m_pIndex && (index > 0) && (index <= m_numOfEntries)) + { + tag = (CPInfoTag) readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG); + } + + return tag; +} + +const sal_Char* ConstantPool::readUTF8NameConstant(sal_uInt16 index) +{ + const sal_Char* aName = NULL_STRING; + + if (m_pIndex && (index > 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_UTF8_NAME) + { + aName = (const sal_Char*) (m_pBuffer + m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aName; +} + +sal_Bool ConstantPool::readBOOLConstant(sal_uInt16 index) +{ + sal_Bool aBool = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_BOOL) + { + aBool = (sal_Bool) readBYTE(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aBool; +} + +sal_uInt8 ConstantPool::readBYTEConstant(sal_uInt16 index) +{ + sal_uInt8 aByte = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_BYTE) + { + aByte = readBYTE(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aByte; +} + +sal_Int16 ConstantPool::readINT16Constant(sal_uInt16 index) +{ + sal_Int16 aINT16 = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT16) + { + aINT16 = readINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aINT16; +} + +sal_uInt16 ConstantPool::readUINT16Constant(sal_uInt16 index) +{ + sal_uInt16 asal_uInt16 = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT16) + { + asal_uInt16 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return asal_uInt16; +} + +sal_Int32 ConstantPool::readINT32Constant(sal_uInt16 index) +{ + sal_Int32 aINT32 = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT32) + { + aINT32 = readINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aINT32; +} + +sal_uInt32 ConstantPool::readUINT32Constant(sal_uInt16 index) +{ + sal_uInt32 aUINT32 = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT32) + { + aUINT32 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aUINT32; +} + +sal_Int64 ConstantPool::readINT64Constant(sal_uInt16 index) +{ + sal_Int64 aINT64 = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT64) + { + aINT64 = readINT64(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aINT64; +} + +sal_uInt64 ConstantPool::readUINT64Constant(sal_uInt16 index) +{ + sal_uInt64 aUINT64 = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT64) + { + aUINT64 = readUINT64(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aUINT64; +} + +float ConstantPool::readFloatConstant(sal_uInt16 index) +{ + union + { + float v; + sal_uInt32 b; + } x = { 0.0f }; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_FLOAT) + { +#ifdef REGTYPE_IEEE_NATIVE + x.b = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); +#else +# error no IEEE +#endif + } + } + + return x.v; +} + +double ConstantPool::readDoubleConstant(sal_uInt16 index) +{ + union + { + double v; + struct + { + sal_uInt32 b1; + sal_uInt32 b2; + } b; + } x = { 0.0 }; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_DOUBLE) + { + +#ifdef REGTYPE_IEEE_NATIVE +# ifdef OSL_BIGENDIAN + x.b.b1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + x.b.b2 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA + sizeof(sal_uInt32)); +# else + x.b.b1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA + sizeof(sal_uInt32)); + x.b.b2 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); +# endif +#else +# error no IEEE +#endif + } + } + + return x.v; +} + +const sal_Unicode* ConstantPool::readStringConstant(sal_uInt16 index) +{ + const sal_Unicode* aString = NULL_WSTRING; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries) && m_pStringCache) + { + if (m_pIndex[index - 1] >= 0) + { + // create cached string now + + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_STRING) + { + m_pIndex[index - 1] = -1 * m_pStringCache->createString(m_pBuffer + m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + aString = m_pStringCache->getString((sal_uInt16) (m_pIndex[index - 1] * -1)); + } + + return aString; +} + +void ConstantPool::readUIK(sal_uInt16 index, RTUik* uik) +{ + if (index == 0) + { + uik->m_Data1 = 0; + uik->m_Data2 = 0; + uik->m_Data3 = 0; + uik->m_Data4 = 0; + uik->m_Data5 = 0; + } + else if (m_pIndex && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_UIK) + { + uik->m_Data1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK1); + uik->m_Data2 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK2); + uik->m_Data3 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK3); + uik->m_Data4 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK4); + uik->m_Data5 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK5); + } + } +} + +/************************************************************************** + + class FieldList + +**************************************************************************/ + +class FieldList : public BlopObject +{ +public: + + sal_uInt16 m_numOfEntries; + sal_uInt16 m_numOfFieldEntries; + sal_uInt16 m_FIELD_ENTRY_SIZE; + ConstantPool* m_pCP; + + FieldList(const sal_uInt8* buffer, sal_uInt16 numEntries, ConstantPool* pCP) + : BlopObject(buffer, 0, sal_False) + , m_numOfEntries(numEntries) + , m_pCP(pCP) + { + if ( m_numOfEntries > 0 ) + { + m_numOfFieldEntries = readUINT16(0); + m_FIELD_ENTRY_SIZE = m_numOfFieldEntries * sizeof(sal_uInt16); + } else + { + m_numOfFieldEntries = 0; + m_FIELD_ENTRY_SIZE = 0; + } + } + + sal_uInt32 parseIndex(); + + const sal_Char* getFieldName(sal_uInt16 index); + const sal_Char* getFieldType(sal_uInt16 index); + RTFieldAccess getFieldAccess(sal_uInt16 index); + RTValueType getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value); + // throws std::bad_alloc + const sal_Char* getFieldDoku(sal_uInt16 index); + const sal_Char* getFieldFileName(sal_uInt16 index); +}; + +sal_uInt32 FieldList::parseIndex() +{ + return ((m_numOfEntries ? sizeof(sal_uInt16) : 0) + (m_numOfEntries * m_FIELD_ENTRY_SIZE)); +} + +const sal_Char* FieldList::getFieldName(sal_uInt16 index) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_NAME)); + } + + return aName; +} + +const sal_Char* FieldList::getFieldType(sal_uInt16 index) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_TYPE)); + } + + return aName; +} + +RTFieldAccess FieldList::getFieldAccess(sal_uInt16 index) +{ + RTFieldAccess aAccess = RT_ACCESS_INVALID; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_ACCESS); + } + + return aAccess; +} + +RTValueType FieldList::getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value) +{ + RTValueType ret = RT_TYPE_NONE; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + sal_uInt16 cpIndex = readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_VALUE); + + switch (m_pCP->readTag(cpIndex)) + { + case CP_TAG_CONST_BOOL: + value->aBool = m_pCP->readBOOLConstant(cpIndex); + ret = RT_TYPE_BOOL; + break; + case CP_TAG_CONST_BYTE: + value->aByte = m_pCP->readBYTEConstant(cpIndex); + ret = RT_TYPE_BYTE; + break; + case CP_TAG_CONST_INT16: + value->aShort = m_pCP->readINT16Constant(cpIndex); + ret = RT_TYPE_INT16; + break; + case CP_TAG_CONST_UINT16: + value->aUShort = m_pCP->readUINT16Constant(cpIndex); + ret = RT_TYPE_UINT16; + break; + case CP_TAG_CONST_INT32: + value->aLong = m_pCP->readINT32Constant(cpIndex); + ret = RT_TYPE_INT32; + break; + case CP_TAG_CONST_UINT32: + value->aULong = m_pCP->readUINT32Constant(cpIndex); + ret = RT_TYPE_UINT32; + break; + case CP_TAG_CONST_INT64: + value->aHyper = m_pCP->readINT64Constant(cpIndex); + ret = RT_TYPE_INT64; + break; + case CP_TAG_CONST_UINT64: + value->aUHyper = m_pCP->readUINT64Constant(cpIndex); + ret = RT_TYPE_UINT64; + break; + case CP_TAG_CONST_FLOAT: + value->aFloat = m_pCP->readFloatConstant(cpIndex); + ret = RT_TYPE_FLOAT; + break; + case CP_TAG_CONST_DOUBLE: + value->aDouble = m_pCP->readDoubleConstant(cpIndex); + ret = RT_TYPE_DOUBLE; + break; + case CP_TAG_CONST_STRING: + value->aString = m_pCP->readStringConstant(cpIndex); + ret = RT_TYPE_STRING; + break; + default: + break; + } + } + + return ret; +} + +const sal_Char* FieldList::getFieldDoku(sal_uInt16 index) +{ + const sal_Char* aDoku = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_DOKU)); + } + + return aDoku; +} + +const sal_Char* FieldList::getFieldFileName(sal_uInt16 index) +{ + const sal_Char* aFileName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aFileName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_FILENAME)); + } + + return aFileName; +} + +/************************************************************************** + + class ReferenceList + +**************************************************************************/ + +class ReferenceList : public BlopObject +{ +public: + + sal_uInt16 m_numOfEntries; + sal_uInt16 m_numOfReferenceEntries; + sal_uInt16 m_REFERENCE_ENTRY_SIZE; + ConstantPool* m_pCP; + + ReferenceList(const sal_uInt8* buffer, sal_uInt16 numEntries, ConstantPool* pCP) + : BlopObject(buffer, 0, sal_False) + , m_numOfEntries(numEntries) + , m_pCP(pCP) + { + if ( m_numOfEntries > 0 ) + { + m_numOfReferenceEntries = readUINT16(0); + m_REFERENCE_ENTRY_SIZE = m_numOfReferenceEntries * sizeof(sal_uInt16); + } else + { + m_numOfReferenceEntries = 0; + m_REFERENCE_ENTRY_SIZE = 0; + } + } + + sal_uInt32 parseIndex(); + + const sal_Char* getReferenceName(sal_uInt16 index); + RTReferenceType getReferenceType(sal_uInt16 index); + const sal_Char* getReferenceDoku(sal_uInt16 index); + RTFieldAccess getReferenceAccess(sal_uInt16 index); +}; + +sal_uInt32 ReferenceList::parseIndex() +{ + return ((m_numOfEntries ? sizeof(sal_uInt16) : 0) + (m_numOfEntries * m_REFERENCE_ENTRY_SIZE)); +} + +const sal_Char* ReferenceList::getReferenceName(sal_uInt16 index) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_NAME)); + } + + return aName; +} + +RTReferenceType ReferenceList::getReferenceType(sal_uInt16 index) +{ + RTReferenceType refType = RT_REF_INVALID; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + refType = (RTReferenceType) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_TYPE); + } + + return refType; +} + +const sal_Char* ReferenceList::getReferenceDoku(sal_uInt16 index) +{ + const sal_Char* aDoku = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_DOKU)); + } + + return aDoku; +} + +RTFieldAccess ReferenceList::getReferenceAccess(sal_uInt16 index) +{ + RTFieldAccess aAccess = RT_ACCESS_INVALID; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_ACCESS); + } + + return aAccess; +} + +/************************************************************************** + + class MethodList + +**************************************************************************/ + +class MethodList : public BlopObject +{ +public: + + sal_uInt16 m_numOfEntries; + sal_uInt16 m_numOfMethodEntries; + sal_uInt16 m_numOfParamEntries; + sal_uInt16 m_PARAM_ENTRY_SIZE; + sal_uInt32* m_pIndex; + ConstantPool* m_pCP; + + MethodList(const sal_uInt8* buffer, sal_uInt16 numEntries, ConstantPool* pCP) + : BlopObject(buffer, 0, sal_False) + , m_numOfEntries(numEntries) + , m_pIndex(NULL) + , m_pCP(pCP) + { + if ( m_numOfEntries > 0 ) + { + m_numOfMethodEntries = readUINT16(0); + m_numOfParamEntries = readUINT16(sizeof(sal_uInt16)); + m_PARAM_ENTRY_SIZE = m_numOfParamEntries * sizeof(sal_uInt16); + } else + { + m_numOfMethodEntries = 0; + m_numOfParamEntries = 0; + m_PARAM_ENTRY_SIZE = 0; + } + } + + ~MethodList(); + + sal_uInt32 parseIndex(); // throws std::bad_alloc + + const sal_Char* getMethodName(sal_uInt16 index); + sal_uInt16 getMethodParamCount(sal_uInt16 index); + const sal_Char* getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex); + const sal_Char* getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex); + RTParamMode getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex); + sal_uInt16 getMethodExcCount(sal_uInt16 index); + const sal_Char* getMethodExcType(sal_uInt16 index, sal_uInt16 excIndex); + const sal_Char* getMethodReturnType(sal_uInt16 index); + RTMethodMode getMethodMode(sal_uInt16 index); + const sal_Char* getMethodDoku(sal_uInt16 index); + +private: + sal_uInt16 calcMethodParamIndex( const sal_uInt16 index ); +}; + +MethodList::~MethodList() +{ + if (m_pIndex) delete[] m_pIndex; +} + +sal_uInt16 MethodList::calcMethodParamIndex( const sal_uInt16 index ) +{ + return (METHOD_OFFSET_PARAM_COUNT + sizeof(sal_uInt16) + (index * m_PARAM_ENTRY_SIZE)); +} + +sal_uInt32 MethodList::parseIndex() +{ + if (m_pIndex) + { + delete[] m_pIndex; + m_pIndex = NULL; + } + + sal_uInt32 offset = 0; + + if (m_numOfEntries) + { + offset = 2 * sizeof(sal_uInt16); + m_pIndex = new sal_uInt32[m_numOfEntries]; + + for (int i = 0; i < m_numOfEntries; i++) + { + m_pIndex[i] = offset; + + offset += readUINT16(offset); + } + } + + return offset; +} + +const sal_Char* MethodList::getMethodName(sal_uInt16 index) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_NAME)); + } + + return aName; +} + +sal_uInt16 MethodList::getMethodParamCount(sal_uInt16 index) +{ + sal_uInt16 aCount = 0; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aCount = readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT); + } + + return aCount; +} + +const sal_Char* MethodList::getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && + (index <= m_numOfEntries) && + (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT))) + { + aName = m_pCP->readUTF8NameConstant( + readUINT16( + m_pIndex[index] + + calcMethodParamIndex(paramIndex) + + PARAM_OFFSET_TYPE)); + } + + return aName; +} + +const sal_Char* MethodList::getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && + (index <= m_numOfEntries) && + (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT))) + { + aName = m_pCP->readUTF8NameConstant( + readUINT16( + m_pIndex[index] + + calcMethodParamIndex(paramIndex) + + PARAM_OFFSET_NAME)); + } + + return aName; +} + +RTParamMode MethodList::getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex) +{ + RTParamMode aMode = RT_PARAM_INVALID; + + if ((m_numOfEntries > 0) && + (index <= m_numOfEntries) && + (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT))) + { + aMode = (RTParamMode) readUINT16( + m_pIndex[index] + + calcMethodParamIndex(paramIndex) + + PARAM_OFFSET_MODE); + } + + return aMode; +} + +sal_uInt16 MethodList::getMethodExcCount(sal_uInt16 index) +{ + sal_uInt16 aCount = 0; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aCount = readUINT16(m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT))); + } + + return aCount; +} + +const sal_Char* MethodList::getMethodExcType(sal_uInt16 index, sal_uInt16 excIndex) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + sal_uInt32 excOffset = m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)); + + if (excIndex <= readUINT16(excOffset)) + { + aName = m_pCP->readUTF8NameConstant( + readUINT16( + excOffset + + sizeof(sal_uInt16) + + (excIndex * sizeof(sal_uInt16)))); + } + } + + return aName; +} + +const sal_Char* MethodList::getMethodReturnType(sal_uInt16 index) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_RETURN)); + } + + return aName; +} + +RTMethodMode MethodList::getMethodMode(sal_uInt16 index) +{ + RTMethodMode aMode = RT_MODE_INVALID; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aMode = (RTMethodMode) readUINT16(m_pIndex[index] + METHOD_OFFSET_MODE); + } + + return aMode; +} + +const sal_Char* MethodList::getMethodDoku(sal_uInt16 index) +{ + const sal_Char* aDoku = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aDoku = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_DOKU)); + } + + return aDoku; +} + +/************************************************************************** + + class TypeRegistryEntry + +**************************************************************************/ + +class TypeRegistryEntry: public BlopObject { +public: + ConstantPool* m_pCP; + FieldList* m_pFields; + MethodList* m_pMethods; + ReferenceList* m_pReferences; + sal_uInt32 m_refCount; + sal_uInt16 m_nSuperTypes; + sal_uInt16 m_offset_SUPERTYPES; + + TypeRegistryEntry( + const sal_uInt8* buffer, sal_uInt32 len, sal_Bool copyBuffer); + // throws std::bad_alloc + + ~TypeRegistryEntry(); + + typereg_Version getVersion() const; +}; + +TypeRegistryEntry::TypeRegistryEntry( + const sal_uInt8* buffer, sal_uInt32 len, sal_Bool copyBuffer): + BlopObject(buffer, len, copyBuffer), m_pCP(NULL), m_pFields(NULL), + m_pMethods(NULL), m_pReferences(NULL), m_refCount(1), m_nSuperTypes(0), + m_offset_SUPERTYPES(0) +{ + std::size_t const entrySize = sizeof(sal_uInt16); + sal_uInt16 nHeaderEntries = readUINT16(OFFSET_N_ENTRIES); + sal_uInt16 offset_N_SUPERTYPES = OFFSET_N_ENTRIES + entrySize + (nHeaderEntries * entrySize); + m_offset_SUPERTYPES = offset_N_SUPERTYPES + entrySize; + m_nSuperTypes = readUINT16(offset_N_SUPERTYPES); + + sal_uInt16 offset_CP_SIZE = m_offset_SUPERTYPES + (m_nSuperTypes * entrySize); + sal_uInt16 offset_CP = offset_CP_SIZE + entrySize; + + m_pCP = new ConstantPool(m_pBuffer + offset_CP, readUINT16(offset_CP_SIZE)); + + sal_uInt32 offset = offset_CP + m_pCP->parseIndex(); + + m_pFields = new FieldList( + m_pBuffer + offset + entrySize, readUINT16(offset), m_pCP); + + offset += sizeof(sal_uInt16) + m_pFields->parseIndex(); + + m_pMethods = new MethodList( + m_pBuffer + offset + entrySize, readUINT16(offset), m_pCP); + + offset += sizeof(sal_uInt16) + m_pMethods->parseIndex(); + + m_pReferences = new ReferenceList( + m_pBuffer + offset + entrySize, readUINT16(offset), m_pCP); + + m_pReferences->parseIndex(); +} + +TypeRegistryEntry::~TypeRegistryEntry() +{ + delete m_pCP; + delete m_pFields; + delete m_pMethods; + delete m_pReferences; +} + +typereg_Version TypeRegistryEntry::getVersion() const { + // Assumes two's complement arithmetic with modulo-semantics: + return static_cast< typereg_Version >(readUINT32(OFFSET_MAGIC) - magic); +} + +/************************************************************************** + + C-API + +**************************************************************************/ + +extern "C" { + +sal_Bool typereg_reader_create( + void const * buffer, sal_uInt32 length, sal_Bool copy, + typereg_Version maxVersion, void ** result) + SAL_THROW_EXTERN_C() +{ + if (length < OFFSET_CP || length > SAL_MAX_UINT32) { + *result = 0; + return true; + } + std::auto_ptr< TypeRegistryEntry > entry; + try { + entry.reset( + new TypeRegistryEntry( + static_cast< sal_uInt8 const * >(buffer), + static_cast< sal_uInt32 >(length), copy)); + } catch (std::bad_alloc &) { + return false; + } + if (entry->readUINT32(OFFSET_SIZE) != length) { + *result = 0; + return true; + } + typereg_Version version = entry->getVersion(); + if (version < TYPEREG_VERSION_0 || version > maxVersion) { + *result = 0; + return true; + } + *result = entry.release(); + return true; +} + +static TypeReaderImpl TYPEREG_CALLTYPE createEntry(const sal_uInt8* buffer, sal_uInt32 len, sal_Bool copyBuffer) +{ + void * handle; + typereg_reader_create(buffer, len, copyBuffer, TYPEREG_VERSION_0, &handle); + return handle; +} + +void typereg_reader_acquire(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry != NULL) + pEntry->m_refCount++; +} + +void typereg_reader_release(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry != NULL) + { + if (--pEntry->m_refCount == 0) + delete pEntry; + } +} + +typereg_Version typereg_reader_getVersion(void * handle) SAL_THROW_EXTERN_C() { + return handle == 0 + ? TYPEREG_VERSION_0 + : static_cast< TypeRegistryEntry * >(handle)->getVersion(); +} + +static sal_uInt16 TYPEREG_CALLTYPE getMinorVersion(TypeReaderImpl hEntry) +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->readUINT16(OFFSET_MINOR_VERSION); +} + +static sal_uInt16 TYPEREG_CALLTYPE getMajorVersion(TypeReaderImpl hEntry) +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->readUINT16(OFFSET_MAJOR_VERSION); +} + +RTTypeClass typereg_reader_getTypeClass(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return RT_TYPE_INVALID; + + return (RTTypeClass) + (pEntry->readUINT16(OFFSET_TYPE_CLASS) & ~RT_TYPE_PUBLISHED); +} + +sal_Bool typereg_reader_isPublished(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry * entry = static_cast< TypeRegistryEntry * >(hEntry); + return entry != 0 + && (entry->readUINT16(OFFSET_TYPE_CLASS) & RT_TYPE_PUBLISHED) != 0; +} + +void typereg_reader_getTypeName(void * hEntry, rtl_uString** pTypeName) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pTypeName); + return; + } + + const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_THIS_TYPE)); + rtl_string2UString( + pTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + + +static void TYPEREG_CALLTYPE getSuperTypeName(TypeReaderImpl hEntry, rtl_uString** pSuperTypeName) +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pSuperTypeName); + return; + } + + if (pEntry->m_nSuperTypes == 0) + { + rtl_uString_new(pSuperTypeName); + return; + } + + const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES )); //+ (index * sizeof(sal_uInt16)))); + rtl_string2UString( + pSuperTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +static void TYPEREG_CALLTYPE getUik(TypeReaderImpl hEntry, RTUik* uik) +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry != NULL) + { + pEntry->m_pCP->readUIK(pEntry->readUINT16(OFFSET_UIK), uik); + } +} + +void typereg_reader_getDocumentation(void * hEntry, rtl_uString** pDoku) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pDoku); + return; + } + + const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_DOKU)); + rtl_string2UString( + pDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +void typereg_reader_getFileName(void * hEntry, rtl_uString** pFileName) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pFileName); + return; + } + + const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_FILENAME)); + rtl_string2UString( + pFileName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + + +sal_uInt16 typereg_reader_getFieldCount(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->m_pFields->m_numOfEntries; +} + +static sal_uInt32 TYPEREG_CALLTYPE getFieldCount(TypeReaderImpl hEntry) +{ + return typereg_reader_getFieldCount(hEntry); +} + +void typereg_reader_getFieldName(void * hEntry, rtl_uString** pFieldName, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pFieldName); + return; + } + const sal_Char* pTmp = pEntry->m_pFields->getFieldName(index); + rtl_string2UString( + pFieldName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +void typereg_reader_getFieldTypeName(void * hEntry, rtl_uString** pFieldType, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pFieldType); + return; + } + + const sal_Char* pTmp = pEntry->m_pFields->getFieldType(index); + rtl_string2UString( + pFieldType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +RTFieldAccess typereg_reader_getFieldFlags(void * hEntry, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return RT_ACCESS_INVALID; + + return pEntry->m_pFields->getFieldAccess(index); +} + +sal_Bool typereg_reader_getFieldValue( + void * hEntry, sal_uInt16 index, RTValueType * type, + RTConstValueUnion * value) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) { + *type = RT_TYPE_NONE; + return true; + } + + try { + *type = pEntry->m_pFields->getFieldConstValue(index, value); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static RTValueType TYPEREG_CALLTYPE getFieldConstValue(TypeReaderImpl hEntry, sal_uInt16 index, RTConstValueUnion* value) +{ + RTValueType t = RT_TYPE_NONE; + typereg_reader_getFieldValue(hEntry, index, &t, value); + return t; +} + +void typereg_reader_getFieldDocumentation(void * hEntry, rtl_uString** pDoku, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pDoku); + return; + } + + const sal_Char* pTmp = pEntry->m_pFields->getFieldDoku(index); + rtl_string2UString( + pDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +void typereg_reader_getFieldFileName(void * hEntry, rtl_uString** pFieldFileName, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pFieldFileName); + return; + } + + const sal_Char* pTmp = pEntry->m_pFields->getFieldFileName(index); + rtl_string2UString( + pFieldFileName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + + +sal_uInt16 typereg_reader_getMethodCount(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->m_pMethods->m_numOfEntries; +} + +static sal_uInt32 TYPEREG_CALLTYPE getMethodCount(TypeReaderImpl hEntry) +{ + return typereg_reader_getMethodCount(hEntry); +} + +void typereg_reader_getMethodName(void * hEntry, rtl_uString** pMethodName, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pMethodName); + return; + } + + const sal_Char* pTmp = pEntry->m_pMethods->getMethodName(index); + rtl_string2UString( + pMethodName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +sal_uInt16 typereg_reader_getMethodParameterCount( + void * hEntry, sal_uInt16 index) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->m_pMethods->getMethodParamCount(index); +} + +static sal_uInt32 TYPEREG_CALLTYPE getMethodParamCount(TypeReaderImpl hEntry, sal_uInt16 index) +{ + return typereg_reader_getMethodParameterCount(hEntry, index); +} + +void typereg_reader_getMethodParameterTypeName(void * hEntry, rtl_uString** pMethodParamType, sal_uInt16 index, sal_uInt16 paramIndex) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pMethodParamType); + return; + } + + const sal_Char* pTmp = pEntry->m_pMethods->getMethodParamType(index, paramIndex); + rtl_string2UString( + pMethodParamType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +void typereg_reader_getMethodParameterName(void * hEntry, rtl_uString** pMethodParamName, sal_uInt16 index, sal_uInt16 paramIndex) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pMethodParamName); + return; + } + + const sal_Char* pTmp = pEntry->m_pMethods->getMethodParamName(index, paramIndex); + rtl_string2UString( + pMethodParamName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +RTParamMode typereg_reader_getMethodParameterFlags(void * hEntry, sal_uInt16 index, sal_uInt16 paramIndex) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return RT_PARAM_INVALID; + + return pEntry->m_pMethods->getMethodParamMode(index, paramIndex); +} + +sal_uInt16 typereg_reader_getMethodExceptionCount( + void * hEntry, sal_uInt16 index) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->m_pMethods->getMethodExcCount(index); +} + +static sal_uInt32 TYPEREG_CALLTYPE getMethodExcCount(TypeReaderImpl hEntry, sal_uInt16 index) +{ + return typereg_reader_getMethodExceptionCount(hEntry, index); +} + +void typereg_reader_getMethodExceptionTypeName(void * hEntry, rtl_uString** pMethodExcpType, sal_uInt16 index, sal_uInt16 excIndex) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pMethodExcpType); + return; + } + + const sal_Char* pTmp = pEntry->m_pMethods->getMethodExcType(index, excIndex); + rtl_string2UString( + pMethodExcpType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +void typereg_reader_getMethodReturnTypeName(void * hEntry, rtl_uString** pMethodReturnType, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pMethodReturnType); + return; + } + + const sal_Char* pTmp = pEntry->m_pMethods->getMethodReturnType(index); + rtl_string2UString( + pMethodReturnType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +RTMethodMode typereg_reader_getMethodFlags(void * hEntry, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return RT_MODE_INVALID; + + return pEntry->m_pMethods->getMethodMode(index); +} + +void typereg_reader_getMethodDocumentation(void * hEntry, rtl_uString** pMethodDoku, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pMethodDoku); + return; + } + + const sal_Char* pTmp = pEntry->m_pMethods->getMethodDoku(index); + rtl_string2UString( + pMethodDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +sal_uInt16 typereg_reader_getReferenceCount(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->m_pReferences->m_numOfEntries; +} + +static sal_uInt32 TYPEREG_CALLTYPE getReferenceCount(TypeReaderImpl hEntry) +{ + return typereg_reader_getReferenceCount(hEntry); +} + +void typereg_reader_getReferenceTypeName(void * hEntry, rtl_uString** pReferenceName, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pReferenceName); + return; + } + + const sal_Char* pTmp = pEntry->m_pReferences->getReferenceName(index); + rtl_string2UString( + pReferenceName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +RTReferenceType typereg_reader_getReferenceSort(void * hEntry, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return RT_REF_INVALID; + + return pEntry->m_pReferences->getReferenceType(index); +} + +void typereg_reader_getReferenceDocumentation(void * hEntry, rtl_uString** pReferenceDoku, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pReferenceDoku); + return; + } + + const sal_Char* pTmp = pEntry->m_pReferences->getReferenceDoku(index); + rtl_string2UString( + pReferenceDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +RTFieldAccess typereg_reader_getReferenceFlags(void * hEntry, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return RT_ACCESS_INVALID; + + return pEntry->m_pReferences->getReferenceAccess(index); +} + +sal_uInt16 typereg_reader_getSuperTypeCount(void * hEntry) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->m_nSuperTypes; +} + +void typereg_reader_getSuperTypeName( + void * hEntry, rtl_uString ** pSuperTypeName, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pSuperTypeName); + return; + } + + OSL_ASSERT(index < pEntry->m_nSuperTypes); + const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES + (index * sizeof(sal_uInt16)))); + rtl_string2UString( + pSuperTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +RegistryTypeReader_Api* TYPEREG_CALLTYPE initRegistryTypeReader_Api(void) +{ + static RegistryTypeReader_Api aApi= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + if (!aApi.acquire) + { + aApi.createEntry = &createEntry; + aApi.acquire = &typereg_reader_acquire; + aApi.release = &typereg_reader_release; + aApi.getMinorVersion = &getMinorVersion; + aApi.getMajorVersion = &getMajorVersion; + aApi.getTypeClass = &typereg_reader_getTypeClass; + aApi.getTypeName = &typereg_reader_getTypeName; + aApi.getSuperTypeName = &getSuperTypeName; + aApi.getUik = &getUik; + aApi.getDoku = &typereg_reader_getDocumentation; + aApi.getFileName = &typereg_reader_getFileName; + aApi.getFieldCount = &getFieldCount; + aApi.getFieldName = &typereg_reader_getFieldName; + aApi.getFieldType = &typereg_reader_getFieldTypeName; + aApi.getFieldAccess = &typereg_reader_getFieldFlags; + aApi.getFieldConstValue = &getFieldConstValue; + aApi.getFieldDoku = &typereg_reader_getFieldDocumentation; + aApi.getFieldFileName = &typereg_reader_getFieldFileName; + aApi.getMethodCount = &getMethodCount; + aApi.getMethodName = &typereg_reader_getMethodName; + aApi.getMethodParamCount = &getMethodParamCount; + aApi.getMethodParamType = &typereg_reader_getMethodParameterTypeName; + aApi.getMethodParamName = &typereg_reader_getMethodParameterName; + aApi.getMethodParamMode = &typereg_reader_getMethodParameterFlags; + aApi.getMethodExcCount = &getMethodExcCount; + aApi.getMethodExcType = &typereg_reader_getMethodExceptionTypeName; + aApi.getMethodReturnType = &typereg_reader_getMethodReturnTypeName; + aApi.getMethodMode = &typereg_reader_getMethodFlags; + aApi.getMethodDoku = &typereg_reader_getMethodDocumentation; + aApi.getReferenceCount = &getReferenceCount; + aApi.getReferenceName = &typereg_reader_getReferenceTypeName; + aApi.getReferenceType = &typereg_reader_getReferenceSort; + aApi.getReferenceDoku = &typereg_reader_getReferenceDocumentation; + aApi.getReferenceAccess = &typereg_reader_getReferenceFlags; + + return (&aApi); + } + else + { + return (&aApi); + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/registry/source/reflwrit.cxx b/registry/source/reflwrit.cxx new file mode 100644 index 000000000000..69cffead8372 --- /dev/null +++ b/registry/source/reflwrit.cxx @@ -0,0 +1,1490 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 ::rtl::OString; + + +namespace { + +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 }; + +#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); + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/registry/source/regimpl.cxx b/registry/source/regimpl.cxx new file mode 100644 index 000000000000..0bd28d0a2fb8 --- /dev/null +++ b/registry/source/regimpl.cxx @@ -0,0 +1,1767 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "regimpl.hxx" + +#include <memory> +#include <string.h> +#include <stdio.h> + +#if defined(UNX) +#include <unistd.h> +#endif +#ifdef __MINGW32__ +#include <unistd.h> +#endif + +#include <registry/reflread.hxx> + +#include <registry/reflwrit.hxx> + +#include "registry/reader.hxx" +#include "registry/refltype.hxx" +#include "registry/types.h" +#include "registry/version.h" + +#include "reflcnst.hxx" +#include "keyimpl.hxx" + +#include <osl/thread.h> +#include <rtl/alloc.h> +#include <rtl/memory.h> +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <osl/file.hxx> + +using namespace osl; +using namespace store; + +using ::rtl::OUString; +using ::rtl::OUStringToOString; +using ::rtl::OUStringBuffer; +using ::rtl::OString; + +namespace { + +void printString(rtl::OUString const & s) { + printf("\""); + for (sal_Int32 i = 0; i < s.getLength(); ++i) { + sal_Unicode c = s[i]; + if (c == '"' || c == '\\') { + printf("\\%c", static_cast< char >(c)); + } else if (s[i] >= ' ' && s[i] <= '~') { + printf("%c", static_cast< char >(c)); + } else { + printf("\\u%04X", static_cast< unsigned int >(c)); + } + } + printf("\""); +} + +void printFieldOrReferenceFlag( + RTFieldAccess * flags, RTFieldAccess flag, char const * name, bool * first) +{ + if ((*flags & flag) != 0) { + if (!*first) { + printf("|"); + } + *first = false; + printf("%s", name); + *flags &= ~flag; + } +} + +void printFieldOrReferenceFlags(RTFieldAccess flags) { + if (flags == 0) { + printf("none"); + } else { + bool first = true; + printFieldOrReferenceFlag( + &flags, RT_ACCESS_READONLY, "readonly", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_OPTIONAL, "optional", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_MAYBEVOID, "maybevoid", &first); + printFieldOrReferenceFlag(&flags, RT_ACCESS_BOUND, "bound", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_CONSTRAINED, "constrained", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_TRANSIENT, "transient", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_MAYBEAMBIGUOUS, "maybeambiguous", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_MAYBEDEFAULT, "maybedefault", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_REMOVEABLE, "removeable", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_ATTRIBUTE, "attribute", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_PROPERTY, "property", &first); + printFieldOrReferenceFlag(&flags, RT_ACCESS_CONST, "const", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_READWRITE, "readwrite", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_PARAMETERIZED_TYPE, "parameterized type", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_PUBLISHED, "published", &first); + if (flags != 0) { + if (!first) { + printf("|"); + } + printf("<invalid (0x%04X)>", static_cast< unsigned int >(flags)); + } + } +} + +void dumpType(typereg::Reader const & reader, rtl::OString const & indent) { + if (reader.isValid()) { + printf("version: %ld\n", static_cast< long >(reader.getVersion())); + printf("%sdocumentation: ", indent.getStr()); + printString(reader.getDocumentation()); + printf("\n"); + printf("%sfile name: ", indent.getStr()); + printString(reader.getFileName()); + printf("\n"); + printf("%stype class: ", indent.getStr()); + if (reader.isPublished()) { + printf("published "); + } + switch (reader.getTypeClass()) { + case RT_TYPE_INTERFACE: + printf("interface"); + break; + + case RT_TYPE_MODULE: + printf("module"); + break; + + case RT_TYPE_STRUCT: + printf("struct"); + break; + + case RT_TYPE_ENUM: + printf("enum"); + break; + + case RT_TYPE_EXCEPTION: + printf("exception"); + break; + + case RT_TYPE_TYPEDEF: + printf("typedef"); + break; + + case RT_TYPE_SERVICE: + printf("service"); + break; + + case RT_TYPE_SINGLETON: + printf("singleton"); + break; + + case RT_TYPE_CONSTANTS: + printf("constants"); + break; + + default: + printf( + "<invalid (%ld)>", static_cast< long >(reader.getTypeClass())); + break; + } + printf("\n"); + printf("%stype name: ", indent.getStr()); + printString(reader.getTypeName()); + printf("\n"); + printf( + "%ssuper type count: %u\n", indent.getStr(), + static_cast< unsigned int >(reader.getSuperTypeCount())); + {for (sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i) { + printf( + "%ssuper type name %u: ", indent.getStr(), + static_cast< unsigned int >(i)); + printString(reader.getSuperTypeName(i)); + printf("\n"); + }} + printf( + "%sfield count: %u\n", indent.getStr(), + static_cast< unsigned int >(reader.getFieldCount())); + {for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) { + printf( + "%sfield %u:\n", indent.getStr(), + static_cast< unsigned int >(i)); + printf("%s documentation: ", indent.getStr()); + printString(reader.getFieldDocumentation(i)); + printf("\n"); + printf("%s file name: ", indent.getStr()); + printString(reader.getFieldFileName(i)); + printf("\n"); + printf("%s flags: ", indent.getStr()); + printFieldOrReferenceFlags(reader.getFieldFlags(i)); + printf("\n"); + printf("%s name: ", indent.getStr()); + printString(reader.getFieldName(i)); + printf("\n"); + printf("%s type name: ", indent.getStr()); + printString(reader.getFieldTypeName(i)); + printf("\n"); + printf("%s value: ", indent.getStr()); + RTConstValue value(reader.getFieldValue(i)); + switch (value.m_type) { + case RT_TYPE_NONE: + printf("none"); + break; + + case RT_TYPE_BOOL: + printf("boolean %s", value.m_value.aBool ? "true" : "false"); + break; + + case RT_TYPE_BYTE: + printf( + "byte 0x%02X", + static_cast< unsigned int >(value.m_value.aByte)); + break; + + case RT_TYPE_INT16: + printf("short %d", static_cast< int >(value.m_value.aShort)); + break; + + case RT_TYPE_UINT16: + printf( + "unsigned short %u", + static_cast< unsigned int >(value.m_value.aUShort)); + break; + + case RT_TYPE_INT32: + printf("long %ld", static_cast< long >(value.m_value.aLong)); + break; + + case RT_TYPE_UINT32: + printf( + "unsigned long %lu", + static_cast< unsigned long >(value.m_value.aULong)); + break; + + case RT_TYPE_INT64: + // TODO: no portable way to print hyper values + printf("hyper"); + break; + + case RT_TYPE_UINT64: + // TODO: no portable way to print unsigned hyper values + printf("unsigned hyper"); + break; + + case RT_TYPE_FLOAT: + // TODO: no portable way to print float values + printf("float"); + break; + + case RT_TYPE_DOUBLE: + // TODO: no portable way to print double values + printf("double"); + break; + + case RT_TYPE_STRING: + printf("string "); + printString(value.m_value.aString); + break; + + default: + printf("<invalid (%ld)>", static_cast< long >(value.m_type)); + break; + } + printf("\n"); + }} + printf( + "%smethod count: %u\n", indent.getStr(), + static_cast< unsigned int >(reader.getMethodCount())); + {for (sal_uInt16 i = 0; i < reader.getMethodCount(); ++i) { + printf( + "%smethod %u:\n", indent.getStr(), + static_cast< unsigned int >(i)); + printf("%s documentation: ", indent.getStr()); + printString(reader.getMethodDocumentation(i)); + printf("\n"); + printf("%s flags: ", indent.getStr()); + switch (reader.getMethodFlags(i)) { + case RT_MODE_ONEWAY: + printf("oneway"); + break; + + case RT_MODE_TWOWAY: + printf("synchronous"); + break; + + case RT_MODE_ATTRIBUTE_GET: + printf("attribute get"); + break; + + case RT_MODE_ATTRIBUTE_SET: + printf("attribute set"); + break; + + default: + printf( + "<invalid (%ld)>", + static_cast< long >(reader.getMethodFlags(i))); + break; + } + printf("\n"); + printf("%s name: ", indent.getStr()); + printString(reader.getMethodName(i)); + printf("\n"); + printf("%s return type name: ", indent.getStr()); + printString(reader.getMethodReturnTypeName(i)); + printf("\n"); + printf( + "%s parameter count: %u\n", indent.getStr(), + static_cast< unsigned int >(reader.getMethodParameterCount(i))); + for (sal_uInt16 j = 0; j < reader.getMethodParameterCount(i); ++j) + { + printf( + "%s parameter %u:\n", indent.getStr(), + static_cast< unsigned int >(j)); + printf("%s flags: ", indent.getStr()); + RTParamMode flags = reader.getMethodParameterFlags(i, j); + bool rest = (flags & RT_PARAM_REST) != 0; + switch (flags & ~RT_PARAM_REST) { + case RT_PARAM_IN: + printf("in"); + break; + + case RT_PARAM_OUT: + printf("out"); + break; + + case RT_PARAM_INOUT: + printf("inout"); + break; + + default: + printf("<invalid (%ld)>", static_cast< long >(flags)); + rest = false; + break; + } + if (rest) { + printf("|rest"); + } + printf("\n"); + printf("%s name: ", indent.getStr()); + printString(reader.getMethodParameterName(i, j)); + printf("\n"); + printf("%s type name: ", indent.getStr()); + printString(reader.getMethodParameterTypeName(i, j)); + printf("\n"); + } + printf( + "%s exception count: %u\n", indent.getStr(), + static_cast< unsigned int >(reader.getMethodExceptionCount(i))); + for (sal_uInt16 j = 0; j < reader.getMethodExceptionCount(i); ++j) + { + printf( + "%s exception type name %u: ", indent.getStr(), + static_cast< unsigned int >(j)); + printString(reader.getMethodExceptionTypeName(i, j)); + printf("\n"); + } + }} + printf( + "%sreference count: %u\n", indent.getStr(), + static_cast< unsigned int >(reader.getReferenceCount())); + {for (sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i) { + printf( + "%sreference %u:\n", indent.getStr(), + static_cast< unsigned int >(i)); + printf("%s documentation: ", indent.getStr()); + printString(reader.getReferenceDocumentation(i)); + printf("\n"); + printf("%s flags: ", indent.getStr()); + printFieldOrReferenceFlags(reader.getReferenceFlags(i)); + printf("\n"); + printf("%s sort: ", indent.getStr()); + switch (reader.getReferenceSort(i)) { + case RT_REF_SUPPORTS: + printf("supports"); + break; + + case RT_REF_EXPORTS: + printf("exports"); + break; + + case RT_REF_TYPE_PARAMETER: + printf("type parameter"); + break; + + default: + printf( + "<invalid (%ld)>", + static_cast< long >(reader.getReferenceSort(i))); + break; + } + printf("\n"); + printf("%s type name: ", indent.getStr()); + printString(reader.getReferenceTypeName(i)); + printf("\n"); + }} + } else { + printf("<invalid>\n"); + } +} + +} + +//********************************************************************* +// ORegistry() +// +ORegistry::ORegistry() + : m_refCount(1) + , m_readOnly(sal_False) + , m_isOpen(sal_False) + , ROOT( RTL_CONSTASCII_USTRINGPARAM("/") ) +{ +} + +//********************************************************************* +// ~ORegistry() +// +ORegistry::~ORegistry() +{ + ORegKey* pRootKey = m_openKeyTable[ROOT]; + if (pRootKey != 0) + (void) releaseKey(pRootKey); + + if (m_file.isValid()) + m_file.close(); +} + + +//********************************************************************* +// initRegistry +// +RegError ORegistry::initRegistry(const OUString& regName, RegAccessMode accessMode) +{ + RegError eRet = REG_INVALID_REGISTRY; + OStoreFile rRegFile; + storeAccessMode sAccessMode = REG_MODE_OPEN; + storeError errCode; + + if (accessMode & REG_CREATE) + { + sAccessMode = REG_MODE_CREATE; + } + else if (accessMode & REG_READONLY) + { + sAccessMode = REG_MODE_OPENREAD; + m_readOnly = sal_True; + } + + if (0 == regName.getLength() && + store_AccessCreate == sAccessMode) + { + errCode = rRegFile.createInMemory(); + } + else + { + errCode = rRegFile.create(regName, sAccessMode, REG_PAGESIZE); + } + + if (errCode) + { + switch (errCode) + { + case store_E_NotExists: + eRet = REG_REGISTRY_NOT_EXISTS; + break; + case store_E_LockingViolation: + eRet = REG_CANNOT_OPEN_FOR_READWRITE; + break; + default: + eRet = REG_INVALID_REGISTRY; + break; + } + } + else + { + OStoreDirectory rStoreDir; + storeError _err = rStoreDir.create(rRegFile, OUString(), OUString(), sAccessMode); + + if ( _err == store_E_None ) + { + m_file = rRegFile; + m_name = regName; + m_isOpen = sal_True; + + m_openKeyTable[ROOT] = new ORegKey(ROOT, this); + eRet = REG_NO_ERROR; + } + else + eRet = REG_INVALID_REGISTRY; + } + + return eRet; +} + + +//********************************************************************* +// closeRegistry +// +RegError ORegistry::closeRegistry() +{ + REG_GUARD(m_mutex); + + if (m_file.isValid()) + { + (void) releaseKey(m_openKeyTable[ROOT]); + m_file.close(); + m_isOpen = sal_False; + return REG_NO_ERROR; + } else + { + return REG_REGISTRY_NOT_EXISTS; + } +} + + +//********************************************************************* +// destroyRegistry +// +RegError ORegistry::destroyRegistry(const OUString& regName) +{ + REG_GUARD(m_mutex); + + if (regName.getLength()) + { + ORegistry* pReg = new ORegistry(); + + if (!pReg->initRegistry(regName, REG_READWRITE)) + { + delete pReg; + + OUString systemName; + if ( FileBase::getSystemPathFromFileURL(regName, systemName) != FileBase::E_None ) + systemName = regName; + + OString name( OUStringToOString(systemName, osl_getThreadTextEncoding()) ); + if (unlink(name) != 0) + { + return REG_DESTROY_REGISTRY_FAILED; + } + } else + { + return REG_DESTROY_REGISTRY_FAILED; + } + } else + { + if (m_refCount != 1 || isReadOnly()) + { + return REG_DESTROY_REGISTRY_FAILED; + } + + if (m_file.isValid()) + { + releaseKey(m_openKeyTable[ROOT]); + m_file.close(); + m_isOpen = sal_False; + + if (m_name.getLength()) + { + OUString systemName; + if ( FileBase::getSystemPathFromFileURL(m_name, systemName) != FileBase::E_None ) + systemName = m_name; + + OString name( OUStringToOString(systemName, osl_getThreadTextEncoding()) ); + if (unlink(name.getStr()) != 0) + { + return REG_DESTROY_REGISTRY_FAILED; + } + } + } else + { + return REG_REGISTRY_NOT_EXISTS; + } + } + + return REG_NO_ERROR; +} + +//********************************************************************* +// acquireKey +// +RegError ORegistry::acquireKey (RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + REG_GUARD(m_mutex); + pKey->acquire(); + + return REG_NO_ERROR; +} + +//********************************************************************* +// releaseKey +// +RegError ORegistry::releaseKey (RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + REG_GUARD(m_mutex); + if (pKey->release() == 0) + { + m_openKeyTable.erase(pKey->getName()); + delete pKey; + } + return REG_NO_ERROR; +} + +//********************************************************************* +// createKey +// +RegError ORegistry::createKey(RegKeyHandle hKey, const OUString& keyName, + RegKeyHandle* phNewKey) +{ + ORegKey* pKey; + + *phNewKey = NULL; + + if ( !keyName.getLength() ) + return REG_INVALID_KEYNAME; + + REG_GUARD(m_mutex); + + if (hKey) + pKey = (ORegKey*)hKey; + else + pKey = m_openKeyTable[ROOT]; + + OUString sFullKeyName = pKey->getFullPath(keyName); + + if (m_openKeyTable.count(sFullKeyName) > 0) + { + *phNewKey = m_openKeyTable[sFullKeyName]; + ((ORegKey*)*phNewKey)->acquire(); + ((ORegKey*)*phNewKey)->setDeleted(sal_False); + return REG_NO_ERROR; + } + + OStoreDirectory rStoreDir; + OUStringBuffer sFullPath(sFullKeyName.getLength()); + OUString token; + + sFullPath.append((sal_Unicode)'/'); + + sal_Int32 nIndex = 0; + do + { + token = sFullKeyName.getToken( 0, '/', nIndex ); + if (token.getLength()) + { + if (rStoreDir.create(pKey->getStoreFile(), sFullPath.getStr(), token, KEY_MODE_CREATE)) + { + return REG_CREATE_KEY_FAILED; + } + + sFullPath.append(token); + sFullPath.append((sal_Unicode)'/'); + } + } while( nIndex != -1 ); + + + pKey = new ORegKey(sFullKeyName, this); + *phNewKey = pKey; + m_openKeyTable[sFullKeyName] = pKey; + + return REG_NO_ERROR; +} + + +//********************************************************************* +// openKey +// +RegError ORegistry::openKey(RegKeyHandle hKey, const OUString& keyName, + RegKeyHandle* phOpenKey) +{ + ORegKey* pKey; + + *phOpenKey = NULL; + + if ( !keyName.getLength() ) + { + return REG_INVALID_KEYNAME; + } + + REG_GUARD(m_mutex); + + if (hKey) + pKey = (ORegKey*)hKey; + else + pKey = m_openKeyTable[ROOT]; + + OUString path(pKey->getFullPath(keyName)); + KeyMap::iterator i(m_openKeyTable.find(path)); + if (i == m_openKeyTable.end()) { + sal_Int32 n = path.lastIndexOf('/') + 1; + switch (OStoreDirectory().create( + pKey->getStoreFile(), path.copy(0, n), path.copy(n), + isReadOnly() ? KEY_MODE_OPENREAD : KEY_MODE_OPEN)) + { + case store_E_NotExists: + return REG_KEY_NOT_EXISTS; + case store_E_WrongFormat: + return REG_INVALID_KEY; + default: + break; + } + + std::auto_ptr< ORegKey > p(new ORegKey(path, this)); + i = m_openKeyTable.insert(std::make_pair(path, p.get())).first; + p.release(); + } else { + i->second->acquire(); + } + *phOpenKey = i->second; + return REG_NO_ERROR; +} + + +//********************************************************************* +// closeKey +// +RegError ORegistry::closeKey(RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + + REG_GUARD(m_mutex); + + OUString const aKeyName (pKey->getName()); + if (!(m_openKeyTable.count(aKeyName) > 0)) + return REG_KEY_NOT_OPEN; + + if (pKey->isModified()) + { + ORegKey * pRootKey = getRootKey(); + if (pKey != pRootKey) + { + // propagate "modified" state to RootKey. + pRootKey->setModified(); + } + else + { + // closing modified RootKey, flush registry file. + OSL_TRACE("registry::ORegistry::closeKey(): flushing modified RootKey"); + (void) m_file.flush(); + } + pKey->setModified(false); + (void) releaseKey(pRootKey); + } + + return releaseKey(pKey); +} + +//********************************************************************* +// deleteKey +// +RegError ORegistry::deleteKey(RegKeyHandle hKey, const OUString& keyName) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if ( !keyName.getLength() ) + return REG_INVALID_KEYNAME; + + REG_GUARD(m_mutex); + + if (!pKey) + pKey = m_openKeyTable[ROOT]; + + OUString sFullKeyName(pKey->getFullPath(keyName)); + return eraseKey(m_openKeyTable[ROOT], sFullKeyName); +} + +RegError ORegistry::eraseKey(ORegKey* pKey, const OUString& keyName) +{ + RegError _ret = REG_NO_ERROR; + + if ( !keyName.getLength() ) + { + return REG_INVALID_KEYNAME; + } + + OUString sFullKeyName(pKey->getName()); + OUString sFullPath(sFullKeyName); + OUString sRelativKey; + sal_Int32 lastIndex = keyName.lastIndexOf('/'); + + if ( lastIndex >= 0 ) + { + sRelativKey += keyName.copy(lastIndex + 1); + + if (sFullKeyName.getLength() > 1) + sFullKeyName += keyName; + else + sFullKeyName += (keyName+1); + + sFullPath = sFullKeyName.copy(0, keyName.lastIndexOf('/') + 1); + } else + { + if (sFullKeyName.getLength() > 1) + sFullKeyName += ROOT; + + sRelativKey += keyName; + sFullKeyName += keyName; + + if (sFullPath.getLength() > 1) + sFullPath += ROOT; + } + + ORegKey* pOldKey = 0; + _ret = pKey->openKey(keyName, (RegKeyHandle*)&pOldKey); + if (_ret != REG_NO_ERROR) + return _ret; + + _ret = deleteSubkeysAndValues(pOldKey); + if (_ret != REG_NO_ERROR) + { + pKey->closeKey(pOldKey); + return _ret; + } + + OUString tmpName(sRelativKey); + tmpName += ROOT; + + OStoreFile sFile(pKey->getStoreFile()); + if ( sFile.isValid() && sFile.remove(sFullPath, tmpName) ) + { + return REG_DELETE_KEY_FAILED; + } + pOldKey->setModified(); + + // set flag deleted !!! + pOldKey->setDeleted(sal_True); + + return pKey->closeKey(pOldKey); +} + +//********************************************************************* +// deleteSubKeysAndValues +// +RegError ORegistry::deleteSubkeysAndValues(ORegKey* pKey) +{ + OStoreDirectory::iterator iter; + RegError _ret = REG_NO_ERROR; + OStoreDirectory rStoreDir(pKey->getStoreDir()); + storeError _err = rStoreDir.first(iter); + + while ( _err == store_E_None ) + { + OUString const keyName = iter.m_pszName; + + if (iter.m_nAttrib & STORE_ATTRIB_ISDIR) + { + _ret = eraseKey(pKey, keyName); + if (_ret) + return _ret; + } + else + { + OUString sFullPath(pKey->getName()); + + if (sFullPath.getLength() > 1) + sFullPath += ROOT; + + if ( ((OStoreFile&)pKey->getStoreFile()).remove(sFullPath, keyName) ) + { + return REG_DELETE_VALUE_FAILED; + } + pKey->setModified(); + } + + _err = rStoreDir.next(iter); + } + + return REG_NO_ERROR; +} + + +//********************************************************************* +// loadKey +// +RegError ORegistry::loadKey(RegKeyHandle hKey, const OUString& regFileName, + sal_Bool bWarnings, sal_Bool bReport) +{ + RegError _ret = REG_NO_ERROR; + ORegKey* pKey = static_cast< ORegKey* >(hKey); + + std::auto_ptr< ORegistry > pReg (new ORegistry()); + _ret = pReg->initRegistry(regFileName, REG_READONLY); + if (_ret != REG_NO_ERROR) + return _ret; + ORegKey* pRootKey = pReg->getRootKey(); + + REG_GUARD(m_mutex); + + OStoreDirectory::iterator iter; + OStoreDirectory rStoreDir(pRootKey->getStoreDir()); + storeError _err = rStoreDir.first(iter); + + while ( _err == store_E_None ) + { + OUString const keyName = iter.m_pszName; + + if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR ) + { + _ret = loadAndSaveKeys(pKey, pRootKey, keyName, 0, bWarnings, bReport); + } + else + { + _ret = loadAndSaveValue(pKey, pRootKey, keyName, 0, bWarnings, bReport); + } + + if (_ret == REG_MERGE_ERROR) + break; + if (_ret == REG_MERGE_CONFLICT && bWarnings) + break; + + _err = rStoreDir.next(iter); + } + + rStoreDir = OStoreDirectory(); + (void) pReg->releaseKey(pRootKey); + return _ret; +} + + +//********************************************************************* +// saveKey +// +RegError ORegistry::saveKey(RegKeyHandle hKey, const OUString& regFileName, + sal_Bool bWarnings, sal_Bool bReport) +{ + RegError _ret = REG_NO_ERROR; + ORegKey* pKey = static_cast< ORegKey* >(hKey); + + std::auto_ptr< ORegistry > pReg (new ORegistry()); + _ret = pReg->initRegistry(regFileName, REG_CREATE); + if (_ret != REG_NO_ERROR) + return _ret; + ORegKey* pRootKey = pReg->getRootKey(); + + REG_GUARD(m_mutex); + + OStoreDirectory::iterator iter; + OStoreDirectory rStoreDir(pKey->getStoreDir()); + storeError _err = rStoreDir.first(iter); + + while ( _err == store_E_None ) + { + OUString const keyName = iter.m_pszName; + + if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR ) + { + _ret = loadAndSaveKeys(pRootKey, pKey, keyName, + pKey->getName().getLength(), + bWarnings, bReport); + } + else + { + _ret = loadAndSaveValue(pRootKey, pKey, keyName, + pKey->getName().getLength(), + bWarnings, bReport); + } + + if (_ret != REG_NO_ERROR) + break; + + _err = rStoreDir.next(iter); + } + + (void) pReg->releaseKey(pRootKey); + return _ret; +} + + +//********************************************************************* +// loadAndSaveValue() +// +RegError ORegistry::loadAndSaveValue(ORegKey* pTargetKey, + ORegKey* pSourceKey, + const OUString& valueName, + sal_uInt32 nCut, + sal_Bool bWarnings, + sal_Bool bReport) +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + RegValueType valueType; + sal_uInt32 valueSize; + sal_uInt32 nSize; + storeAccessMode sourceAccess = VALUE_MODE_OPEN; + OUString sTargetPath(pTargetKey->getName()); + OUString sSourcePath(pSourceKey->getName()); + + if (pSourceKey->isReadOnly()) + { + sourceAccess = VALUE_MODE_OPENREAD; + } + + if (nCut) + { + sTargetPath = sSourcePath.copy(nCut); + } else + { + if (sTargetPath.getLength() > 1) + { + if (sSourcePath.getLength() > 1) + sTargetPath += sSourcePath; + } else + sTargetPath = sSourcePath; + } + + if (sTargetPath.getLength() > 1) sTargetPath += ROOT; + if (sSourcePath.getLength() > 1) sSourcePath += ROOT; + + if (rValue.create(pSourceKey->getStoreFile(), sSourcePath, valueName, sourceAccess)) + { + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 rwBytes; + if (rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (rwBytes != VALUE_HEADERSIZE) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + RegError _ret = REG_NO_ERROR; + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + rtl_freeMemory(pBuffer); + + nSize = VALUE_HEADERSIZE + valueSize; + pBuffer = (sal_uInt8*)rtl_allocateMemory(nSize); + + if (rValue.readAt(0, pBuffer, nSize, rwBytes)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (rwBytes != nSize) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + OStoreFile rTargetFile(pTargetKey->getStoreFile()); + + if (!rValue.create(rTargetFile, sTargetPath, valueName, VALUE_MODE_OPEN)) + { + if (valueType == RG_VALUETYPE_BINARY) + { + _ret = checkBlop( + rValue, sTargetPath, valueSize, pBuffer+VALUE_HEADEROFFSET, + bReport); + if (_ret) + { + if (_ret == REG_MERGE_ERROR || + (_ret == REG_MERGE_CONFLICT && bWarnings)) + { + rtl_freeMemory(pBuffer); + return _ret; + } + } else + { + rtl_freeMemory(pBuffer); + return _ret; + } + } + } + + // write + if (rValue.create(rTargetFile, sTargetPath, valueName, VALUE_MODE_CREATE)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (rValue.writeAt(0, pBuffer, nSize, rwBytes)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + if (rwBytes != nSize) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + pTargetKey->setModified(); + + rtl_freeMemory(pBuffer); + return _ret; +} + + +//********************************************************************* +// checkblop() +// +RegError ORegistry::checkBlop(OStoreStream& rValue, + const OUString& sTargetPath, + sal_uInt32 srcValueSize, + sal_uInt8* pSrcBuffer, + sal_Bool bReport) +{ + RegistryTypeReader reader(pSrcBuffer, srcValueSize, sal_False); + + if (reader.getTypeClass() == RT_TYPE_INVALID) + { + return REG_INVALID_VALUE; + } + + sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + RegValueType valueType; + sal_uInt32 valueSize; + sal_uInt32 rwBytes; + OString targetPath( OUStringToOString(sTargetPath, RTL_TEXTENCODING_UTF8) ); + + if (!rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes) && + (rwBytes == VALUE_HEADERSIZE)) + { + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + rtl_freeMemory(pBuffer); + + if (valueType == RG_VALUETYPE_BINARY) + { + pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + if (!rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, rwBytes) && + (rwBytes == valueSize)) + { + RegistryTypeReader reader2(pBuffer, valueSize, sal_False); + + if ((reader.getTypeClass() != reader2.getTypeClass()) + || reader2.getTypeClass() == RT_TYPE_INVALID) + { + rtl_freeMemory(pBuffer); + + if (bReport) + { + fprintf(stdout, "ERROR: values of blop from key \"%s\" has different types.\n", + targetPath.getStr()); + } + return REG_MERGE_ERROR; + } + + if (reader.getTypeClass() == RT_TYPE_MODULE) + { + if (reader.getFieldCount() > 0 && + reader2.getFieldCount() > 0) + { + mergeModuleValue(rValue, reader, reader2); + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; + } else + if (reader2.getFieldCount() > 0) + { + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; + } else + { + rtl_freeMemory(pBuffer); + return REG_MERGE_CONFLICT; + } + } else + { + rtl_freeMemory(pBuffer); + + if (bReport) + { + fprintf(stdout, "WARNING: value of key \"%s\" already exists.\n", + targetPath.getStr()); + } + return REG_MERGE_CONFLICT; + } + } else + { + rtl_freeMemory(pBuffer); + if (bReport) + { + fprintf(stdout, "ERROR: values of key \"%s\" contains bad data.\n", + targetPath.getStr()); + } + return REG_MERGE_ERROR; + } + } else + { + rtl_freeMemory(pBuffer); + if (bReport) + { + fprintf(stdout, "ERROR: values of key \"%s\" has different types.\n", + targetPath.getStr()); + } + return REG_MERGE_ERROR; + } + } else + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } +} + +static sal_uInt32 checkTypeReaders(RegistryTypeReader& reader1, + RegistryTypeReader& reader2, + std::set< OUString >& nameSet) +{ + sal_uInt32 count=0; + sal_uInt16 i; + for (i=0 ; i < reader1.getFieldCount(); i++) + { + nameSet.insert(reader1.getFieldName(i)); + count++; + } + for (i=0 ; i < reader2.getFieldCount(); i++) + { + if (nameSet.find(reader2.getFieldName(i)) == nameSet.end()) + { + nameSet.insert(reader2.getFieldName(i)); + count++; + } + } + return count; +} + +//********************************************************************* +// mergeModuleValue() +// +RegError ORegistry::mergeModuleValue(OStoreStream& rTargetValue, + RegistryTypeReader& reader, + RegistryTypeReader& reader2) +{ + sal_uInt16 index = 0; + + std::set< OUString > nameSet; + sal_uInt32 count = checkTypeReaders(reader, reader2, nameSet); + + if (count != reader.getFieldCount()) + { + RegistryTypeWriter writer(reader.getTypeClass(), + reader.getTypeName(), + reader.getSuperTypeName(), + (sal_uInt16)count, + 0, + 0); + + sal_uInt16 i; + for (i=0 ; i < reader.getFieldCount(); i++) + { + writer.setFieldData(index, + reader.getFieldName(i), + reader.getFieldType(i), + reader.getFieldDoku(i), + reader.getFieldFileName(i), + reader.getFieldAccess(i), + reader.getFieldConstValue(i)); + index++; + } + for (i=0 ; i < reader2.getFieldCount(); i++) + { + if (nameSet.find(reader2.getFieldName(i)) == nameSet.end()) + { + writer.setFieldData(index, + reader2.getFieldName(i), + reader2.getFieldType(i), + reader2.getFieldDoku(i), + reader2.getFieldFileName(i), + reader2.getFieldAccess(i), + reader2.getFieldConstValue(i)); + index++; + } + } + + const sal_uInt8* pBlop = writer.getBlop(); + sal_uInt32 aBlopSize = writer.getBlopSize(); + + sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_BINARY; + sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + aBlopSize); + + rtl_copyMemory(pBuffer, &type, 1); + writeUINT32(pBuffer+VALUE_TYPEOFFSET, aBlopSize); + rtl_copyMemory(pBuffer+VALUE_HEADEROFFSET, pBlop, aBlopSize); + + sal_uInt32 rwBytes; + if (rTargetValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+aBlopSize, rwBytes)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + if (rwBytes != VALUE_HEADERSIZE+aBlopSize) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + rtl_freeMemory(pBuffer); + } + return REG_NO_ERROR; +} + +//********************************************************************* +// loadAndSaveKeys() +// +RegError ORegistry::loadAndSaveKeys(ORegKey* pTargetKey, + ORegKey* pSourceKey, + const OUString& keyName, + sal_uInt32 nCut, + sal_Bool bWarnings, + sal_Bool bReport) +{ + RegError _ret = REG_NO_ERROR; + OUString sRelPath(pSourceKey->getName().copy(nCut)); + OUString sFullPath; + + if(pTargetKey->getName().getLength() > 1) + sFullPath += pTargetKey->getName(); + sFullPath += sRelPath; + if (sRelPath.getLength() > 1 || sFullPath.getLength() == 0) + sFullPath += ROOT; + + OUString sFullKeyName = sFullPath; + sFullKeyName += keyName; + + OStoreDirectory rStoreDir; + if (rStoreDir.create(pTargetKey->getStoreFile(), sFullPath, keyName, KEY_MODE_CREATE)) + { + return REG_CREATE_KEY_FAILED; + } + + if (m_openKeyTable.count(sFullKeyName) > 0) + { + m_openKeyTable[sFullKeyName]->setDeleted(sal_False); + } + + ORegKey* pTmpKey = 0; + _ret = pSourceKey->openKey(keyName, (RegKeyHandle*)&pTmpKey); + if (_ret != REG_NO_ERROR) + return _ret; + + OStoreDirectory::iterator iter; + OStoreDirectory rTmpStoreDir(pTmpKey->getStoreDir()); + storeError _err = rTmpStoreDir.first(iter); + + while ( _err == store_E_None) + { + OUString const sName = iter.m_pszName; + + if (iter.m_nAttrib & STORE_ATTRIB_ISDIR) + { + _ret = loadAndSaveKeys(pTargetKey, pTmpKey, + sName, nCut, bWarnings, bReport); + } else + { + _ret = loadAndSaveValue(pTargetKey, pTmpKey, + sName, nCut, bWarnings, bReport); + } + + if (_ret == REG_MERGE_ERROR) + break; + if (_ret == REG_MERGE_CONFLICT && bWarnings) + break; + + _err = rTmpStoreDir.next(iter); + } + + pSourceKey->releaseKey(pTmpKey); + return _ret; +} + + +//********************************************************************* +// getRootKey() +// +ORegKey* ORegistry::getRootKey() +{ + m_openKeyTable[ROOT]->acquire(); + return m_openKeyTable[ROOT]; +} + + +//********************************************************************* +// dumpRegistry() +// +RegError ORegistry::dumpRegistry(RegKeyHandle hKey) const +{ + ORegKey *pKey = (ORegKey*)hKey; + OUString sName; + RegError _ret = REG_NO_ERROR; + OStoreDirectory::iterator iter; + OStoreDirectory rStoreDir(pKey->getStoreDir()); + storeError _err = rStoreDir.first(iter); + + OString regName( OUStringToOString( getName(), osl_getThreadTextEncoding() ) ); + OString keyName( OUStringToOString( pKey->getName(), RTL_TEXTENCODING_UTF8 ) ); + fprintf(stdout, "Registry \"%s\":\n\n%s\n", regName.getStr(), keyName.getStr()); + + while ( _err == store_E_None ) + { + sName = iter.m_pszName; + + if (iter.m_nAttrib & STORE_ATTRIB_ISDIR) + { + _ret = dumpKey(pKey->getName(), sName, 1); + } else + { + _ret = dumpValue(pKey->getName(), sName, 1); + } + + if (_ret) + { + return _ret; + } + + _err = rStoreDir.next(iter); + } + + return REG_NO_ERROR; +} + +//********************************************************************* +// dumpValue() +// +RegError ORegistry::dumpValue(const OUString& sPath, const OUString& sName, sal_Int16 nSpc) const +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + sal_uInt32 valueSize; + RegValueType valueType; + OUString sFullPath(sPath); + OString sIndent; + storeAccessMode accessMode = VALUE_MODE_OPEN; + + if (isReadOnly()) + { + accessMode = VALUE_MODE_OPENREAD; + } + + for (int i= 0; i < nSpc; i++) sIndent += " "; + + if (sFullPath.getLength() > 1) + { + sFullPath += ROOT; + } + if (rValue.create(m_file, sFullPath, sName, accessMode)) + { + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 rwBytes; + if (rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (rwBytes != (VALUE_HEADERSIZE)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + + pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + if (rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, rwBytes)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (rwBytes != valueSize) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + const sal_Char* indent = sIndent.getStr(); + switch (valueType) + { + case 0: + fprintf(stdout, "%sValue: Type = VALUETYPE_NOT_DEFINED\n", indent); + break; + case 1: + { + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_LONG\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf(stdout, "%s Data = ", indent); + + sal_Int32 value; + readINT32(pBuffer, value); + fprintf(stdout, "%ld\n", sal::static_int_cast< long >(value)); + } + break; + case 2: + { + sal_Char* value = (sal_Char*)rtl_allocateMemory(valueSize); + readUtf8(pBuffer, value, valueSize); + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_STRING\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf(stdout, "%s Data = \"%s\"\n", indent, value); + rtl_freeMemory(value); + } + break; + case 3: + { + sal_uInt32 size = (valueSize / 2) * sizeof(sal_Unicode); + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_UNICODE\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf(stdout, "%s Data = ", indent); + + sal_Unicode* value = new sal_Unicode[size]; + readString(pBuffer, value, size); + + OString uStr = OUStringToOString(value, RTL_TEXTENCODING_UTF8); + fprintf(stdout, "L\"%s\"\n", uStr.getStr()); + delete[] value; + } + break; + case 4: + { + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_BINARY\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf(stdout, "%s Data = ", indent); + dumpType( + typereg::Reader( + pBuffer, valueSize, false, TYPEREG_VERSION_1), + sIndent + " "); + } + break; + case 5: + { + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays + sal_uInt32 len = 0; + + readUINT32(pBuffer, len); + + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_LONGLIST\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf( + stdout, "%s Len = %lu\n", indent, + sal::static_int_cast< unsigned long >(len)); + fprintf(stdout, "%s Data = ", indent); + + sal_Int32 longValue; + for (sal_uInt32 i=0; i < len; i++) + { + readINT32(pBuffer+offset, longValue); + + if (offset > 4) + fprintf(stdout, "%s ", indent); + + fprintf( + stdout, "%lu = %ld\n", + sal::static_int_cast< unsigned long >(i), + sal::static_int_cast< long >(longValue)); + offset += 4; // 4 Bytes fuer sal_Int32 + } + } + break; + case 6: + { + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays + sal_uInt32 sLen = 0; + sal_uInt32 len = 0; + + readUINT32(pBuffer, len); + + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_STRINGLIST\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf( + stdout, "%s Len = %lu\n", indent, + sal::static_int_cast< unsigned long >(len)); + fprintf(stdout, "%s Data = ", indent); + + sal_Char *pValue; + for (sal_uInt32 i=0; i < len; i++) + { + readUINT32(pBuffer+offset, sLen); + + offset += 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes + + pValue = (sal_Char*)rtl_allocateMemory(sLen); + readUtf8(pBuffer+offset, pValue, sLen); + + if (offset > 8) + fprintf(stdout, "%s ", indent); + + fprintf( + stdout, "%lu = \"%s\"\n", + sal::static_int_cast< unsigned long >(i), pValue); + offset += sLen; + } + } + break; + case 7: + { + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays + sal_uInt32 sLen = 0; + sal_uInt32 len = 0; + + readUINT32(pBuffer, len); + + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_UNICODELIST\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf( + stdout, "%s Len = %lu\n", indent, + sal::static_int_cast< unsigned long >(len)); + fprintf(stdout, "%s Data = ", indent); + + sal_Unicode *pValue; + OString uStr; + for (sal_uInt32 i=0; i < len; i++) + { + readUINT32(pBuffer+offset, sLen); + + offset += 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes + + pValue = (sal_Unicode*)rtl_allocateMemory((sLen / 2) * sizeof(sal_Unicode)); + readString(pBuffer+offset, pValue, sLen); + + if (offset > 8) + fprintf(stdout, "%s ", indent); + + uStr = OUStringToOString(pValue, RTL_TEXTENCODING_UTF8); + fprintf( + stdout, "%lu = L\"%s\"\n", + sal::static_int_cast< unsigned long >(i), + uStr.getStr()); + + offset += sLen; + + rtl_freeMemory(pValue); + } + } + break; + } + + fprintf(stdout, "\n"); + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// dumpKey() +// +RegError ORegistry::dumpKey(const OUString& sPath, const OUString& sName, sal_Int16 nSpace) const +{ + OStoreDirectory rStoreDir; + OUString sFullPath(sPath); + OString sIndent; + storeAccessMode accessMode = KEY_MODE_OPEN; + RegError _ret = REG_NO_ERROR; + + if (isReadOnly()) + { + accessMode = KEY_MODE_OPENREAD; + } + + for (int i= 0; i < nSpace; i++) sIndent += " "; + + if (sFullPath.getLength() > 1) + sFullPath += ROOT; + + storeError _err = rStoreDir.create(m_file, sFullPath, sName, accessMode); + + if (_err == store_E_NotExists) + return REG_KEY_NOT_EXISTS; + else + if (_err == store_E_WrongFormat) + return REG_INVALID_KEY; + + fprintf(stdout, "%s/ %s\n", sIndent.getStr(), OUStringToOString(sName, RTL_TEXTENCODING_UTF8).getStr()); + + OUString sSubPath(sFullPath); + OUString sSubName; + sSubPath += sName; + + OStoreDirectory::iterator iter; + + _err = rStoreDir.first(iter); + + while ( _err == store_E_None) + { + sSubName = iter.m_pszName; + + if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR ) + { + _ret = dumpKey(sSubPath, sSubName, nSpace+2); + } else + { + _ret = dumpValue(sSubPath, sSubName, nSpace+2); + } + + if (_ret) + { + return _ret; + } + + _err = rStoreDir.next(iter); + } + + return REG_NO_ERROR; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/registry/source/regimpl.hxx b/registry/source/regimpl.hxx new file mode 100644 index 000000000000..80b6470704c5 --- /dev/null +++ b/registry/source/regimpl.hxx @@ -0,0 +1,183 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _REGIMPL_HXX_ +#define _REGIMPL_HXX_ + +#include <set> +#include <boost/unordered_map.hpp> + +#include <registry/registry.h> +#include <rtl/ustring.hxx> +#include <osl/mutex.hxx> +#include <store/store.hxx> + +#define REG_PAGESIZE 512 + +#define REG_MODE_CREATE store_AccessCreate +#define REG_MODE_OPEN store_AccessReadWrite +#define REG_MODE_OPENREAD store_AccessReadOnly + +#define KEY_MODE_CREATE store_AccessCreate +#define KEY_MODE_OPEN store_AccessReadWrite +#define KEY_MODE_OPENREAD store_AccessReadOnly + + +#define VALUE_MODE_CREATE store_AccessCreate +#define VALUE_MODE_OPEN store_AccessReadWrite +#define VALUE_MODE_OPENREAD store_AccessReadOnly + +// 5 Bytes = 1 (Byte fuer den Typ) + 4 (Bytes fuer die Groesse der Daten) +#define VALUE_HEADERSIZE 5 +#define VALUE_TYPEOFFSET 1 +#define VALUE_HEADEROFFSET 5 + +#define REG_CREATE 0x0004 // allow write accesses + +#define REG_GUARD(mutex) \ + osl::Guard< osl::Mutex > aGuard( mutex ); + +class ORegKey; +class RegistryTypeReader; + +class ORegistry +{ +public: + ORegistry(); + + sal_uInt32 acquire() + { return ++m_refCount; } + + sal_uInt32 release() + { return --m_refCount; } + + RegError initRegistry(const rtl::OUString& name, + RegAccessMode accessMode); + + RegError closeRegistry(); + + RegError destroyRegistry(const rtl::OUString& name); + + RegError acquireKey(RegKeyHandle hKey); + RegError releaseKey(RegKeyHandle hKey); + + RegError createKey(RegKeyHandle hKey, + const rtl::OUString& keyName, + RegKeyHandle* phNewKey); + + RegError openKey(RegKeyHandle hKey, + const rtl::OUString& keyName, + RegKeyHandle* phOpenKey); + + RegError closeKey(RegKeyHandle hKey); + + RegError deleteKey(RegKeyHandle hKey, const rtl::OUString& keyName); + + RegError loadKey(RegKeyHandle hKey, + const rtl::OUString& regFileName, + sal_Bool bWarings=sal_False, + sal_Bool bReport=sal_False); + + RegError saveKey(RegKeyHandle hKey, + const rtl::OUString& regFileName, + sal_Bool bWarings=sal_False, + sal_Bool bReport=sal_False); + + RegError dumpRegistry(RegKeyHandle hKey) const; + + ~ORegistry(); + + sal_Bool isReadOnly() const + { return m_readOnly; } + + sal_Bool isOpen() const + { return m_isOpen; } + + ORegKey* getRootKey(); + + const store::OStoreFile& getStoreFile() const + { return m_file; } + + const rtl::OUString& getName() const + { return m_name; } + + friend class ORegKey; + +private: + RegError eraseKey(ORegKey* pKey, const rtl::OUString& keyName); + + RegError deleteSubkeysAndValues(ORegKey* pKey); + + RegError loadAndSaveValue(ORegKey* pTargetKey, + ORegKey* pSourceKey, + const rtl::OUString& valueName, + sal_uInt32 nCut, + sal_Bool bWarnings=sal_False, + sal_Bool bReport=sal_False); + + RegError checkBlop(store::OStoreStream& rValue, + const rtl::OUString& sTargetPath, + sal_uInt32 srcValueSize, + sal_uInt8* pSrcBuffer, + sal_Bool bReport=sal_False); + + RegError mergeModuleValue(store::OStoreStream& rTargetValue, + RegistryTypeReader& reader, + RegistryTypeReader& reader2); + + RegError loadAndSaveKeys(ORegKey* pTargetKey, + ORegKey* pSourceKey, + const rtl::OUString& keyName, + sal_uInt32 nCut, + sal_Bool bWarnings=sal_False, + sal_Bool bReport=sal_False); + + RegError dumpValue(const rtl::OUString& sPath, + const rtl::OUString& sName, + sal_Int16 nSpace) const; + + RegError dumpKey(const rtl::OUString& sPath, + const rtl::OUString& sName, + sal_Int16 nSpace) const; + + typedef boost::unordered_map< rtl::OUString, ORegKey*, rtl::OUStringHash > KeyMap; + + sal_uInt32 m_refCount; + osl::Mutex m_mutex; + sal_Bool m_readOnly; + sal_Bool m_isOpen; + rtl::OUString m_name; + store::OStoreFile m_file; + KeyMap m_openKeyTable; + + const rtl::OUString ROOT; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/registry/source/registry.cxx b/registry/source/registry.cxx new file mode 100644 index 000000000000..d61fa32a4b5e --- /dev/null +++ b/registry/source/registry.cxx @@ -0,0 +1,630 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 <registry/registry.h> +#include <registry/registry.hxx> +#include <osl/process.h> + +#include "keyimpl.hxx" +#include "regimpl.hxx" +#include "regkey.hxx" + +#if defined(WIN32) || defined(WNT) +#include <io.h> +#endif + +#include <string.h> +#if defined(UNX) +#include <stdlib.h> +#include <unistd.h> +#endif + +extern "C" { + +//********************************************************************* +// acquire +// +static void REGISTRY_CALLTYPE acquire(RegHandle hReg) +{ + ORegistry* pReg = (ORegistry*) hReg; + + if (pReg != NULL) + pReg->acquire(); +} + + +//********************************************************************* +// release +// +static void REGISTRY_CALLTYPE release(RegHandle hReg) +{ + ORegistry* pReg = (ORegistry*) hReg; + + if (pReg) + { + if (pReg->release() == 0) + { + delete pReg; + hReg = NULL; + } + } +} + + +//********************************************************************* +// getName +// +static RegError REGISTRY_CALLTYPE getName(RegHandle hReg, rtl_uString** pName) +{ + ORegistry* pReg; + + if (hReg) + { + pReg = (ORegistry*)hReg; + if ( pReg->isOpen() ) + { + rtl_uString_assign(pName, pReg->getName().pData); + return REG_NO_ERROR; + } else + { + rtl_uString_new(pName); + return REG_REGISTRY_NOT_OPEN; + } + } + + rtl_uString_new(pName); + return REG_INVALID_REGISTRY; +} + + +//********************************************************************* +// isReadOnly +// +static sal_Bool REGISTRY_CALLTYPE isReadOnly(RegHandle hReg) +{ + if (hReg) + return ((ORegistry*)hReg)->isReadOnly(); + else + return sal_False; +} + + +//********************************************************************* +// createRegistry +// +static RegError REGISTRY_CALLTYPE createRegistry(rtl_uString* registryName, + RegHandle* phRegistry) +{ + RegError ret; + + ORegistry* pReg = new ORegistry(); + if ((ret = pReg->initRegistry(registryName, REG_CREATE))) + { + *phRegistry = NULL; + return ret; + } + + *phRegistry = pReg; + + return REG_NO_ERROR; +} + +//********************************************************************* +// openRootKey +// +static RegError REGISTRY_CALLTYPE openRootKey(RegHandle hReg, + RegKeyHandle* phRootKey) +{ + ORegistry* pReg; + + if (hReg) + { + pReg = (ORegistry*)hReg; + if (!pReg->isOpen()) + return REG_REGISTRY_NOT_OPEN; + } else + { + phRootKey = NULL; + return REG_INVALID_REGISTRY; + } + + *phRootKey = pReg->getRootKey(); + + return REG_NO_ERROR; +} + + +//********************************************************************* +// openRegistry +// +static RegError REGISTRY_CALLTYPE openRegistry(rtl_uString* registryName, + RegHandle* phRegistry, + RegAccessMode accessMode) +{ + RegError _ret; + + ORegistry* pReg = new ORegistry(); + if ((_ret = pReg->initRegistry(registryName, accessMode))) + { + *phRegistry = NULL; + delete pReg; + return _ret; + } + + + *phRegistry = pReg; + + return REG_NO_ERROR; +} + +//********************************************************************* +// closeRegistry +// +static RegError REGISTRY_CALLTYPE closeRegistry(RegHandle hReg) +{ + ORegistry *pReg; + + if (hReg) + { + pReg = (ORegistry*)hReg; + if (!pReg->isOpen()) + return REG_REGISTRY_NOT_OPEN; + + RegError ret = REG_NO_ERROR; + if (pReg->release() == 0) + { + delete(pReg); + hReg = NULL; + } + else + ret = pReg->closeRegistry(); + + return ret; + } else + { + return REG_INVALID_REGISTRY; + } +} + + +//********************************************************************* +// destroyRegistry +// +static RegError REGISTRY_CALLTYPE destroyRegistry(RegHandle hReg, + rtl_uString* registryName) +{ + ORegistry *pReg; + + if (hReg) + { + pReg = (ORegistry*)hReg; + if (!pReg->isOpen()) + return REG_INVALID_REGISTRY; + + RegError ret = pReg->destroyRegistry(registryName); + if (!ret) + { + if (!registryName->length) + { + delete(pReg); + hReg = NULL; + } + } + return ret; + } else + { + return REG_INVALID_REGISTRY; + } +} + + +//********************************************************************* +// loadRegKey +// +static RegError REGISTRY_CALLTYPE loadKey(RegHandle hReg, + RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName) +{ + + ORegistry* pReg = static_cast< ORegistry* >(hReg); + if (!pReg) + return REG_INVALID_REGISTRY; + + if (!pReg->isOpen()) + return REG_REGISTRY_NOT_OPEN; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->getRegistry() != pReg) + return REG_INVALID_KEY; + if (pKey->isDeleted()) + return REG_INVALID_KEY; + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + + ORegKey* pNewKey = 0; + RegError _ret = pKey->openKey(keyName, (RegKeyHandle*)&pNewKey); + if (_ret == REG_NO_ERROR) + { + pKey->releaseKey(pNewKey); + pKey->deleteKey(keyName); + } + + _ret = pKey->createKey(keyName, (RegKeyHandle*)&pNewKey); + if (_ret != REG_NO_ERROR) + return _ret; + + _ret = pReg->loadKey(pNewKey, regFileName); + if (_ret != REG_NO_ERROR) + { + pKey->releaseKey(pNewKey); + pKey->deleteKey(keyName); + return _ret; + } + + return pKey->closeKey(pNewKey); +} + +//********************************************************************* +// saveKey +// +static RegError REGISTRY_CALLTYPE saveKey(RegHandle hReg, + RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName) +{ + + ORegistry* pReg = static_cast< ORegistry* >(hReg); + if (!pReg) + return REG_INVALID_REGISTRY; + + if (!pReg->isOpen()) + return REG_REGISTRY_NOT_OPEN; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->getRegistry() != pReg) + return REG_INVALID_KEY; + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + ORegKey* pNewKey = 0; + RegError _ret = pKey->openKey(keyName, (RegKeyHandle*)&pNewKey); + if (_ret != REG_NO_ERROR) + return _ret; + + _ret = pReg->saveKey(pNewKey, regFileName); + if (_ret != REG_NO_ERROR) + { + (void) pKey->releaseKey(pNewKey); + return _ret; + } + + return pKey->releaseKey(pNewKey); +} + +//********************************************************************* +// mergeKey +// +static RegError REGISTRY_CALLTYPE mergeKey(RegHandle hReg, + RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName, + sal_Bool bWarnings, + sal_Bool bReport) +{ + ORegistry* pReg = static_cast< ORegistry* >(hReg); + if (!pReg) + return REG_INVALID_REGISTRY; + if (!pReg->isOpen()) + return REG_REGISTRY_NOT_OPEN; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + if (pKey->getRegistry() != pReg) + return REG_INVALID_KEY; + if (pKey->isDeleted()) + return REG_INVALID_KEY; + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + if (keyName->length) + { + ORegKey* pNewKey = 0; + RegError _ret = pKey->createKey(keyName, (RegKeyHandle*)&pNewKey); + if (_ret != REG_NO_ERROR) + return _ret; + + _ret = pReg->loadKey(pNewKey, regFileName, bWarnings, bReport); + if (_ret == REG_MERGE_ERROR || (_ret == REG_MERGE_CONFLICT && bWarnings)) + { + if (pNewKey != pKey) + (void) pKey->closeKey(pNewKey); + else + (void) pKey->releaseKey(pNewKey); + return _ret; + } + + return (pNewKey != pKey) ? pKey->closeKey(pNewKey) : pKey->releaseKey(pNewKey); + } + + return pReg->loadKey(pKey, regFileName, bWarnings, bReport); +} + +//********************************************************************* +// dumpRegistry +// +static RegError REGISTRY_CALLTYPE dumpRegistry(RegHandle hReg, + RegKeyHandle hKey) +{ + ORegistry* pReg = static_cast< ORegistry* >(hReg); + if (!pReg) + return REG_INVALID_REGISTRY; + if (!pReg->isOpen()) + return REG_REGISTRY_NOT_OPEN; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + if (pKey->getRegistry() != pReg) + return REG_INVALID_KEY; + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + return pReg->dumpRegistry(hKey); +} + +//********************************************************************* +// initRegistry_Api +// +Registry_Api* REGISTRY_CALLTYPE initRegistry_Api(void) +{ + static Registry_Api aApi= {&acquire, + &release, + &isReadOnly, + &openRootKey, + &getName, + &createRegistry, + &openRegistry, + &closeRegistry, + &destroyRegistry, + &loadKey, + &saveKey, + &mergeKey, + &dumpRegistry, + &acquireKey, + &releaseKey, + &isKeyReadOnly, + &getKeyName, + &createKey, + &openKey, + &openSubKeys, + &closeSubKeys, + &deleteKey, + &closeKey, + &setValue, + &setLongListValue, + &setStringListValue, + &setUnicodeListValue, + &getValueInfo, + &getValue, + &getLongListValue, + &getStringListValue, + &getUnicodeListValue, + &freeValueList, + &createLink, + &deleteLink, + &getKeyType, + &getLinkTarget, + &getResolvedKeyName, + &getKeyNames, + &freeKeyNames}; + + return (&aApi); +} + +} + +//********************************************************************* +// reg_loadRegKey +// +RegError REGISTRY_CALLTYPE reg_loadKey(RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName) +{ + ORegKey *pKey; + + if (hKey) + pKey = (ORegKey*)hKey; + else + return REG_INVALID_KEY; + + return loadKey(pKey->getRegistry(), hKey, keyName, regFileName); +} + +//********************************************************************* +// reg_saveKey +// +RegError REGISTRY_CALLTYPE reg_saveKey(RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName) +{ + ORegKey *pKey; + + if (hKey) + pKey = (ORegKey*)hKey; + else + return REG_INVALID_KEY; + + return saveKey(pKey->getRegistry(), hKey, keyName, regFileName); +} + +//********************************************************************* +// reg_mergeKey +// +RegError REGISTRY_CALLTYPE reg_mergeKey(RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName, + sal_Bool bWarnings, + sal_Bool bReport) +{ + ORegKey *pKey; + + if (hKey) + pKey = (ORegKey*)hKey; + else + return REG_INVALID_KEY; + + return mergeKey(pKey->getRegistry(), hKey, keyName, regFileName, bWarnings, bReport); +} + +//********************************************************************* +// reg_createRegistry +// +RegError REGISTRY_CALLTYPE reg_createRegistry(rtl_uString* registryName, + RegHandle* phRegistry) +{ + RegError ret; + + ORegistry* pReg = new ORegistry(); + if ((ret = pReg->initRegistry(registryName, REG_CREATE))) + { + *phRegistry = NULL; + return ret; + } + + *phRegistry = pReg; + + return REG_NO_ERROR; +} + +//********************************************************************* +// reg_openRootKey +// +RegError REGISTRY_CALLTYPE reg_openRootKey(RegHandle hRegistry, + RegKeyHandle* phRootKey) +{ + return openRootKey(hRegistry, phRootKey); +} + + +//********************************************************************* +// reg_getName +// +RegError REGISTRY_CALLTYPE reg_getName(RegHandle hRegistry, rtl_uString** pName) +{ + return getName(hRegistry, pName); +} + + +//********************************************************************* +// reg_isReadOnly +// +sal_Bool REGISTRY_CALLTYPE reg_isReadOnly(RegHandle hRegistry) +{ + return isReadOnly(hRegistry); +} + + +//********************************************************************* +// reg_openRegistry +// +RegError REGISTRY_CALLTYPE reg_openRegistry(rtl_uString* registryName, + RegHandle* phRegistry, + RegAccessMode accessMode) +{ + RegError _ret; + + ORegistry* pReg = new ORegistry(); + if ((_ret = pReg->initRegistry(registryName, accessMode))) + { + *phRegistry = NULL; + return _ret; + } + + *phRegistry = pReg; + + return REG_NO_ERROR; +} + +//********************************************************************* +// reg_closeRegistry +// +RegError REGISTRY_CALLTYPE reg_closeRegistry(RegHandle hRegistry) +{ + ORegistry* pReg; + + if (hRegistry) + { + pReg = (ORegistry*)hRegistry; + delete(pReg); + return REG_NO_ERROR; + } else + { + return REG_REGISTRY_NOT_OPEN; + } +} + + +//********************************************************************* +// reg_destroyRegistry +// +RegError REGISTRY_CALLTYPE reg_destroyRegistry(RegHandle hRegistry, + rtl_uString* registryName) +{ + return destroyRegistry(hRegistry, registryName); +} + + +//********************************************************************* +// reg_dumpRegistry +// +RegError REGISTRY_CALLTYPE reg_dumpRegistry(RegKeyHandle hKey) +{ + ORegKey *pKey; + + if (hKey) + pKey = (ORegKey*)hKey; + else + return REG_INVALID_KEY; + + return dumpRegistry(pKey->getRegistry(), hKey); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/registry/source/regkey.cxx b/registry/source/regkey.cxx new file mode 100644 index 000000000000..6ea83afe6a54 --- /dev/null +++ b/registry/source/regkey.cxx @@ -0,0 +1,1025 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "regkey.hxx" + +#include <registry/registry.hxx> +#include <rtl/alloc.h> +#include "regimpl.hxx" +#include "keyimpl.hxx" + +using rtl::OUString; + +//********************************************************************* +// acquireKey +// +void REGISTRY_CALLTYPE acquireKey(RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (pKey != 0) + { + ORegistry* pReg = pKey->getRegistry(); + (void) pReg->acquireKey(pKey); + } +} + + +//********************************************************************* +// releaseKey +// +void REGISTRY_CALLTYPE releaseKey(RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (pKey != 0) + { + ORegistry* pReg = pKey->getRegistry(); + (void) pReg->releaseKey(pKey); + } +} + + +//********************************************************************* +// isKeyReadOnly +// +sal_Bool REGISTRY_CALLTYPE isKeyReadOnly(RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + return (pKey != 0) ? pKey->isReadOnly() : sal_False; +} + + +//********************************************************************* +// getKeyName +// +RegError REGISTRY_CALLTYPE getKeyName(RegKeyHandle hKey, rtl_uString** pKeyName) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (pKey) + { + rtl_uString_assign( pKeyName, pKey->getName().pData ); + return REG_NO_ERROR; + } else + { + rtl_uString_new(pKeyName); + return REG_INVALID_KEY; + } +} + + +//********************************************************************* +// createKey +// +RegError REGISTRY_CALLTYPE createKey(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle* phNewKey) +{ + *phNewKey = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + return pKey->createKey(keyName, phNewKey); +} + +//********************************************************************* +// openKey +// +RegError REGISTRY_CALLTYPE openKey(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle* phOpenKey) +{ + *phOpenKey = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + return pKey->openKey(keyName, phOpenKey); +} + +//********************************************************************* +// openSubKeys +// +RegError REGISTRY_CALLTYPE openSubKeys(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle** pphSubKeys, + sal_uInt32* pnSubKeys) +{ + *pphSubKeys = NULL; + *pnSubKeys = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + return pKey->openSubKeys(keyName, pphSubKeys, pnSubKeys); +} + +//********************************************************************* +// closeSubKeys +// +RegError REGISTRY_CALLTYPE closeSubKeys(RegKeyHandle* phSubKeys, + sal_uInt32 nSubKeys) +{ + if (phSubKeys == 0 || nSubKeys == 0) + return REG_INVALID_KEY; + + ORegistry* pReg = ((ORegKey*)(phSubKeys[0]))->getRegistry(); + for (sal_uInt32 i = 0; i < nSubKeys; i++) + { + (void) pReg->closeKey(phSubKeys[i]); + } + rtl_freeMemory(phSubKeys); + + return REG_NO_ERROR; +} + +//********************************************************************* +// deleteKey +// +RegError REGISTRY_CALLTYPE deleteKey(RegKeyHandle hKey, + rtl_uString* keyName) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + return pKey->deleteKey(keyName); +} + +//********************************************************************* +// closeKey +// +RegError REGISTRY_CALLTYPE closeKey(RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + return pKey->closeKey(hKey); +} + +//********************************************************************* +// setValue +// +RegError REGISTRY_CALLTYPE setValue(RegKeyHandle hKey, + rtl_uString* keyName, + RegValueType valueType, + RegValue pData, + sal_uInt32 valueSize) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->setValue(valueName, valueType, pData, valueSize); + if (_ret1 != REG_NO_ERROR) + { + RegError _ret2 = pKey->closeKey(pSubKey); + if (_ret2) + return _ret2; + else + return _ret1; + } + + return pKey->closeKey(pSubKey); + } + + return pKey->setValue(valueName, valueType, pData, valueSize); +} + +//********************************************************************* +// setLongValueList +// +RegError REGISTRY_CALLTYPE setLongListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Int32* pValueList, + sal_uInt32 len) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->setLongListValue(valueName, pValueList, len); + if (_ret1 != REG_NO_ERROR) + { + RegError _ret2 = pKey->closeKey(pSubKey); + if (_ret2 != REG_NO_ERROR) + return _ret2; + else + return _ret1; + } + + return pKey->closeKey(pSubKey); + } + + return pKey->setLongListValue(valueName, pValueList, len); +} + +//********************************************************************* +// setStringValueList +// +RegError REGISTRY_CALLTYPE setStringListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Char** pValueList, + sal_uInt32 len) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->setStringListValue(valueName, pValueList, len); + if (_ret1 != REG_NO_ERROR) + { + RegError _ret2 = pKey->closeKey(pSubKey); + if (_ret2 != REG_NO_ERROR) + return _ret2; + else + return _ret1; + } + + return pKey->closeKey(pSubKey); + } + + return pKey->setStringListValue(valueName, pValueList, len); +} + +//********************************************************************* +// setUnicodeValueList +// +RegError REGISTRY_CALLTYPE setUnicodeListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Unicode** pValueList, + sal_uInt32 len) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->setUnicodeListValue(valueName, pValueList, len); + if (_ret1 != REG_NO_ERROR) + { + RegError _ret2 = pKey->closeKey(pSubKey); + if (_ret2 != REG_NO_ERROR) + return _ret2; + else + return _ret1; + } + + return pKey->closeKey(pSubKey); + } + + return pKey->setUnicodeListValue(valueName, pValueList, len); +} + +//********************************************************************* +// getValueInfo +// +RegError REGISTRY_CALLTYPE getValueInfo(RegKeyHandle hKey, + rtl_uString* keyName, + RegValueType* pValueType, + sal_uInt32* pValueSize) +{ + *pValueType = RG_VALUETYPE_NOT_DEFINED; + *pValueSize = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + RegValueType valueType; + sal_uInt32 valueSize; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret != REG_NO_ERROR) + return _ret; + + if (pSubKey->getValueInfo(valueName, &valueType, &valueSize) != REG_NO_ERROR) + { + (void) pKey->releaseKey(pSubKey); + return REG_INVALID_VALUE; + } + + *pValueType = valueType; + *pValueSize = valueSize; + + return pKey->releaseKey(pSubKey); + } + + + if (pKey->getValueInfo(valueName, &valueType, &valueSize) != REG_NO_ERROR) + { + return REG_INVALID_VALUE; + } + + *pValueType = valueType; + *pValueSize = valueSize; + + return REG_NO_ERROR; +} + +//********************************************************************* +// getValueInfo +// +RegError REGISTRY_CALLTYPE getValue(RegKeyHandle hKey, + rtl_uString* keyName, + RegValue pValue) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->getValue(valueName, pValue); + if (_ret1 != REG_NO_ERROR) + { + (void) pKey->releaseKey(pSubKey); + return _ret1; + } + + return pKey->releaseKey(pSubKey); + } + + return pKey->getValue(valueName, pValue); +} + +//********************************************************************* +// getLongValueList +// +RegError REGISTRY_CALLTYPE getLongListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Int32** pValueList, + sal_uInt32* pLen) +{ + OSL_PRECOND((pValueList != 0) && (pLen != 0), "registry::getLongListValue(): invalid parameter"); + *pValueList = 0, *pLen = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->getLongListValue(valueName, pValueList, pLen); + if (_ret1 != REG_NO_ERROR) + { + (void) pKey->releaseKey(pSubKey); + return _ret1; + } + + return pKey->releaseKey(pSubKey); + } + + return pKey->getLongListValue(valueName, pValueList, pLen); +} + +//********************************************************************* +// getStringValueList +// +RegError REGISTRY_CALLTYPE getStringListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Char*** pValueList, + sal_uInt32* pLen) +{ + OSL_PRECOND((pValueList != 0) && (pLen != 0), "registry::getStringListValue(): invalid parameter"); + *pValueList = 0, *pLen = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->getStringListValue(valueName, pValueList, pLen); + if (_ret1 != REG_NO_ERROR) + { + (void) pKey->releaseKey(pSubKey); + return _ret1; + } + + return pKey->releaseKey(pSubKey); + } + + return pKey->getStringListValue(valueName, pValueList, pLen); +} + +//********************************************************************* +// getUnicodeListValue +// +RegError REGISTRY_CALLTYPE getUnicodeListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Unicode*** pValueList, + sal_uInt32* pLen) +{ + OSL_PRECOND((pValueList != 0) && (pLen != 0), "registry::getUnicodeListValue(): invalid parameter"); + *pValueList = 0, *pLen = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->getUnicodeListValue(valueName, pValueList, pLen); + if (_ret1 != REG_NO_ERROR) + { + (void) pKey->releaseKey(pSubKey); + return _ret1; + } + + return pKey->releaseKey(pSubKey); + } + + return pKey->getUnicodeListValue(valueName, pValueList, pLen); +} + +//********************************************************************* +// freeValueList +// +RegError REGISTRY_CALLTYPE freeValueList(RegValueType valueType, + RegValue pValueList, + sal_uInt32 len) +{ + switch (valueType) + { + case 5: + { + rtl_freeMemory(pValueList); + } + break; + case 6: + { + sal_Char** pVList = (sal_Char**)pValueList; + for (sal_uInt32 i=0; i < len; i++) + { + rtl_freeMemory(pVList[i]); + } + + rtl_freeMemory(pVList); + } + break; + case 7: + { + sal_Unicode** pVList = (sal_Unicode**)pValueList; + for (sal_uInt32 i=0; i < len; i++) + { + rtl_freeMemory(pVList[i]); + } + + rtl_freeMemory(pVList); + } + break; + default: + return REG_INVALID_VALUE; + } + + pValueList = NULL; + return REG_NO_ERROR; +} + +//********************************************************************* +// createLink +// +RegError REGISTRY_CALLTYPE createLink(RegKeyHandle, rtl_uString*, rtl_uString*) +{ + return REG_INVALID_LINK; // links are no longer supported +} + +//********************************************************************* +// deleteLink +// +RegError REGISTRY_CALLTYPE deleteLink(RegKeyHandle, rtl_uString*) +{ + return REG_INVALID_LINK; // links are no longer supported +} + +//********************************************************************* +// getKeyType +// +RegError REGISTRY_CALLTYPE getKeyType(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyType* pKeyType) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + return pKey->getKeyType(keyName, pKeyType); +} + +//********************************************************************* +// getLinkTarget +// +RegError REGISTRY_CALLTYPE getLinkTarget( + RegKeyHandle, rtl_uString*, rtl_uString**) +{ + return REG_INVALID_LINK; // links are no longer supported +} + +//********************************************************************* +// getName +// +RegError REGISTRY_CALLTYPE getResolvedKeyName(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Bool, + rtl_uString** pResolvedName) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + OUString resolvedName; + RegError _ret = pKey->getResolvedKeyName(keyName, resolvedName); + if (_ret == REG_NO_ERROR) + rtl_uString_assign(pResolvedName, resolvedName.pData); + return _ret; +} + +//********************************************************************* +// getKeyNames +// +RegError REGISTRY_CALLTYPE getKeyNames(RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString*** pSubKeyNames, + sal_uInt32* pnSubKeys) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + return pKey->getKeyNames(keyName, pSubKeyNames, pnSubKeys); +} + +//********************************************************************* +// freeKeyNames +// +RegError REGISTRY_CALLTYPE freeKeyNames(rtl_uString** pKeyNames, + sal_uInt32 nKeys) +{ + for (sal_uInt32 i=0; i < nKeys; i++) + { + rtl_uString_release(pKeyNames[i]); + } + + rtl_freeMemory(pKeyNames); + + return REG_NO_ERROR; +} + +//********************************************************************* +// C API +// + +//********************************************************************* +// reg_createKey +// +RegError REGISTRY_CALLTYPE reg_createKey(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle* phNewKey) +{ + if (!hKey) + return REG_INVALID_KEY; + + return createKey(hKey, keyName, phNewKey); +} + +//********************************************************************* +// reg_openKey +// +RegError REGISTRY_CALLTYPE reg_openKey(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle* phOpenKey) +{ + if (!hKey) + return REG_INVALID_KEY; + + return openKey(hKey, keyName, phOpenKey); +} + +//********************************************************************* +// reg_openSubKeys +// +RegError REGISTRY_CALLTYPE reg_openSubKeys(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle** pphSubKeys, + sal_uInt32* pnSubKeys) +{ + if (!hKey) + return REG_INVALID_KEY; + + return openSubKeys(hKey, keyName, pphSubKeys, pnSubKeys); +} + +//********************************************************************* +// reg_closeSubKeys +// +RegError REGISTRY_CALLTYPE reg_closeSubKeys(RegKeyHandle* pphSubKeys, + sal_uInt32 nSubKeys) +{ + if (!pphSubKeys) + return REG_INVALID_KEY; + + return closeSubKeys(pphSubKeys, nSubKeys); +} + +//********************************************************************* +// reg_deleteKey +// +RegError REGISTRY_CALLTYPE reg_deleteKey(RegKeyHandle hKey, + rtl_uString* keyName) +{ + if (!hKey) + return REG_INVALID_KEY; + + return deleteKey(hKey, keyName); +} + +//********************************************************************* +// reg_closeKey +// +RegError REGISTRY_CALLTYPE reg_closeKey(RegKeyHandle hKey) +{ + if (!hKey) + return REG_INVALID_KEY; + + return closeKey(hKey); +} + + +//********************************************************************* +// reg_getKeyName +// +RegError REGISTRY_CALLTYPE reg_getKeyName(RegKeyHandle hKey, rtl_uString** pKeyName) +{ + if (hKey) + { + rtl_uString_assign( pKeyName, ((ORegKey*)hKey)->getName().pData ); + return REG_NO_ERROR; + } else + { + rtl_uString_new( pKeyName ); + return REG_INVALID_KEY; + } +} + +//********************************************************************* +// reg_setValue +// +RegError REGISTRY_CALLTYPE reg_setValue(RegKeyHandle hKey, + rtl_uString* keyName, + RegValueType valueType, + RegValue pData, + sal_uInt32 valueSize) +{ + if (!hKey) + return REG_INVALID_KEY; + + return setValue(hKey, keyName, valueType, pData, valueSize); +} + +//********************************************************************* +// reg_setLongListValue +// +RegError REGISTRY_CALLTYPE reg_setLongListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Int32* pValueList, + sal_uInt32 len) +{ + if (!hKey) + return REG_INVALID_KEY; + + return setLongListValue(hKey, keyName, pValueList, len); +} + +//********************************************************************* +// reg_setStringListValue +// +RegError REGISTRY_CALLTYPE reg_setStringListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Char** pValueList, + sal_uInt32 len) +{ + if (!hKey) + return REG_INVALID_KEY; + + return setStringListValue(hKey, keyName, pValueList, len); +} + +//********************************************************************* +// reg_setUnicodeListValue +// +RegError REGISTRY_CALLTYPE reg_setUnicodeListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Unicode** pValueList, + sal_uInt32 len) +{ + if (!hKey) + return REG_INVALID_KEY; + + return setUnicodeListValue(hKey, keyName, pValueList, len); +} + +//********************************************************************* +// reg_getValueInfo +// +RegError REGISTRY_CALLTYPE reg_getValueInfo(RegKeyHandle hKey, + rtl_uString* keyName, + RegValueType* pValueType, + sal_uInt32* pValueSize) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getValueInfo(hKey, keyName, pValueType, pValueSize); +} + +//********************************************************************* +// reg_getValueInfo +// +RegError REGISTRY_CALLTYPE reg_getValue(RegKeyHandle hKey, + rtl_uString* keyName, + RegValue pData) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getValue(hKey, keyName, pData); +} + +//********************************************************************* +// reg_getLongListValue +// +RegError REGISTRY_CALLTYPE reg_getLongListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Int32** pValueList, + sal_uInt32* pLen) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getLongListValue(hKey, keyName, pValueList, pLen); +} + +//********************************************************************* +// reg_getStringListValue +// +RegError REGISTRY_CALLTYPE reg_getStringListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Char*** pValueList, + sal_uInt32* pLen) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getStringListValue(hKey, keyName, pValueList, pLen); +} + +//********************************************************************* +// reg_getUnicodeListValue +// +RegError REGISTRY_CALLTYPE reg_getUnicodeListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Unicode*** pValueList, + sal_uInt32* pLen) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getUnicodeListValue(hKey, keyName, pValueList, pLen); +} + +//********************************************************************* +// reg_freeValueList +// +RegError REGISTRY_CALLTYPE reg_freeValueList(RegValueType valueType, + RegValue pValueList, + sal_uInt32 len) +{ + if (pValueList) + return freeValueList(valueType, pValueList, len); + else + return REG_INVALID_VALUE; +} + +//********************************************************************* +// reg_createLink +// +RegError REGISTRY_CALLTYPE reg_createLink(RegKeyHandle hKey, + rtl_uString* linkName, + rtl_uString* linkTarget) +{ + if (!hKey) + return REG_INVALID_KEY; + + return createLink(hKey, linkName, linkTarget); +} + +//********************************************************************* +// reg_deleteLink +// +RegError REGISTRY_CALLTYPE reg_deleteLink(RegKeyHandle hKey, + rtl_uString* linkName) +{ + if (!hKey) + return REG_INVALID_KEY; + + return deleteLink(hKey, linkName); +} + +//********************************************************************* +// reg_getKeyType +// +RegError REGISTRY_CALLTYPE reg_getKeyType(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyType* pKeyType) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getKeyType(hKey, keyName, pKeyType); +} + +//********************************************************************* +// reg_getLinkTarget +// +RegError REGISTRY_CALLTYPE reg_getLinkTarget(RegKeyHandle hKey, + rtl_uString* linkName, + rtl_uString** pLinkTarget) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getLinkTarget(hKey, linkName, pLinkTarget); +} + +//********************************************************************* +// reg_getResolvedKeyName +// +RegError REGISTRY_CALLTYPE reg_getResolvedKeyName(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Bool firstLinkOnly, + rtl_uString** pResolvedName) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getResolvedKeyName(hKey, keyName, firstLinkOnly, pResolvedName); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/registry/source/regkey.hxx b/registry/source/regkey.hxx new file mode 100644 index 000000000000..0503c05772c9 --- /dev/null +++ b/registry/source/regkey.hxx @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_REGISTRY_SOURCE_REGKEY_HXX +#define INCLUDED_REGISTRY_SOURCE_REGKEY_HXX + +#include "sal/config.h" +#include "registry/regtype.h" +#include "rtl/ustring.h" +#include "sal/types.h" + +extern "C" { + +void REGISTRY_CALLTYPE acquireKey(RegKeyHandle); +void REGISTRY_CALLTYPE releaseKey(RegKeyHandle); +sal_Bool REGISTRY_CALLTYPE isKeyReadOnly(RegKeyHandle); +RegError REGISTRY_CALLTYPE getKeyName(RegKeyHandle, rtl_uString**); +RegError REGISTRY_CALLTYPE createKey(RegKeyHandle, rtl_uString*, RegKeyHandle*); +RegError REGISTRY_CALLTYPE openKey(RegKeyHandle, rtl_uString*, RegKeyHandle*); +RegError REGISTRY_CALLTYPE openSubKeys( + RegKeyHandle, rtl_uString*, RegKeyHandle**, sal_uInt32*); +RegError REGISTRY_CALLTYPE closeSubKeys(RegKeyHandle*, sal_uInt32); +RegError REGISTRY_CALLTYPE deleteKey(RegKeyHandle, rtl_uString*); +RegError REGISTRY_CALLTYPE closeKey(RegKeyHandle); +RegError REGISTRY_CALLTYPE setValue( + RegKeyHandle, rtl_uString*, RegValueType, RegValue, sal_uInt32); +RegError REGISTRY_CALLTYPE setLongListValue( + RegKeyHandle, rtl_uString*, sal_Int32*, sal_uInt32); +RegError REGISTRY_CALLTYPE setStringListValue( + RegKeyHandle, rtl_uString*, sal_Char**, sal_uInt32); +RegError REGISTRY_CALLTYPE setUnicodeListValue( + RegKeyHandle, rtl_uString*, sal_Unicode**, sal_uInt32); +RegError REGISTRY_CALLTYPE getValueInfo( + RegKeyHandle, rtl_uString*, RegValueType*, sal_uInt32*); +RegError REGISTRY_CALLTYPE getValue(RegKeyHandle, rtl_uString*, RegValue); +RegError REGISTRY_CALLTYPE getLongListValue( + RegKeyHandle, rtl_uString*, sal_Int32**, sal_uInt32*); +RegError REGISTRY_CALLTYPE getStringListValue( + RegKeyHandle, rtl_uString*, sal_Char***, sal_uInt32*); +RegError REGISTRY_CALLTYPE getUnicodeListValue( + RegKeyHandle, rtl_uString*, sal_Unicode***, sal_uInt32*); +RegError REGISTRY_CALLTYPE freeValueList(RegValueType, RegValue, sal_uInt32); +RegError REGISTRY_CALLTYPE createLink(RegKeyHandle, rtl_uString*, rtl_uString*); +RegError REGISTRY_CALLTYPE deleteLink(RegKeyHandle, rtl_uString*); +RegError REGISTRY_CALLTYPE getKeyType(RegKeyHandle, rtl_uString*, RegKeyType*); +RegError REGISTRY_CALLTYPE getLinkTarget( + RegKeyHandle, rtl_uString*, rtl_uString**); +RegError REGISTRY_CALLTYPE getResolvedKeyName( + RegKeyHandle, rtl_uString*, sal_Bool, rtl_uString**); +RegError REGISTRY_CALLTYPE getKeyNames( + RegKeyHandle, rtl_uString*, rtl_uString***, sal_uInt32*); +RegError REGISTRY_CALLTYPE freeKeyNames(rtl_uString**, sal_uInt32); + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |