/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_codemaker.hxx" #include "rtl/alloc.h" #include "codemaker/typemanager.hxx" #include "registry/reader.hxx" #include "registry/version.h" using namespace rtl; TypeManager::TypeManager() { m_pImpl = new TypeManagerImpl(); acquire(); } TypeManager::~TypeManager() { release(); } sal_Int32 TypeManager::acquire() { return osl_incrementInterlockedCount(&m_pImpl->m_refCount); } sal_Int32 TypeManager::release() { sal_Int32 refCount = 0; if (0 == (refCount = osl_decrementInterlockedCount(&m_pImpl->m_refCount)) ) { delete m_pImpl; } return refCount;; } sal_Bool TypeManager::isBaseType(const ::rtl::OString& name) { if ( name.equals(OString("short")) ) return sal_True; if ( name.equals(OString("unsigned short")) ) return sal_True; if ( name.equals(OString("long")) ) return sal_True; if ( name.equals(OString("unsigned long")) ) return sal_True; if ( name.equals(OString("hyper")) ) return sal_True; if ( name.equals(OString("unsigned hyper")) ) return sal_True; if ( name.equals(OString("string")) ) return sal_True; if ( name.equals(OString("boolean")) ) return sal_True; if ( name.equals(OString("char")) ) return sal_True; if ( name.equals(OString("byte")) ) return sal_True; if ( name.equals(OString("any")) ) return sal_True; if ( name.equals(OString("type")) ) return sal_True; if ( name.equals(OString("float")) ) return sal_True; if ( name.equals(OString("double")) ) return sal_True; if ( name.equals(OString("void")) ) return sal_True; return sal_False; } RegistryTypeManager::RegistryTypeManager() { m_pImpl = new RegistryTypeManagerImpl(); acquire(); } RegistryTypeManager::~RegistryTypeManager() { release(); } void RegistryTypeManager::acquire() { TypeManager::acquire(); } void RegistryTypeManager::release() { if (0 == TypeManager::release()) { freeRegistries(); delete m_pImpl; } } sal_Bool RegistryTypeManager::init( const StringVector& regFiles, StringVector const & extraFiles ) { if (regFiles.empty()) return sal_False; StringVector::const_iterator iter = regFiles.begin(); Registry tmpReg; while (iter != regFiles.end()) { if (!tmpReg.open( convertToFileUrl(*iter), REG_READONLY)) m_pImpl->m_registries.push_back(new Registry(tmpReg)); else { freeRegistries(); return sal_False; } ++iter; } iter = extraFiles.begin(); while (iter != extraFiles.end()) { if (!tmpReg.open( convertToFileUrl(*iter), REG_READONLY)) m_pImpl->m_extra_registries.push_back(new Registry(tmpReg)); else { freeRegistries(); return sal_False; } ++iter; } return sal_True; } ::rtl::OString RegistryTypeManager::getTypeName(RegistryKey& rTypeKey) const { OString typeName = OUStringToOString(rTypeKey.getName(), RTL_TEXTENCODING_UTF8); if (m_pImpl->m_base.getLength() > 1) typeName = typeName.copy(typeName.indexOf('/', 1) + 1); else typeName = typeName.copy(1); return typeName; } typereg::Reader RegistryTypeManager::getTypeReader( const OString& name, sal_Bool * pIsExtraType ) const { typereg::Reader reader; RegistryKey key(searchTypeKey(name, pIsExtraType)); if (key.isValid()) { RegValueType valueType; sal_uInt32 valueSize; if (!key.getValueInfo(OUString(), &valueType, &valueSize)) { sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); if (!key.getValue(OUString(), pBuffer)) { reader = typereg::Reader( pBuffer, valueSize, true, TYPEREG_VERSION_1); } rtl_freeMemory(pBuffer); } } return reader; } typereg::Reader RegistryTypeManager::getTypeReader(RegistryKey& rTypeKey) const { typereg::Reader reader; if (rTypeKey.isValid()) { RegValueType valueType; sal_uInt32 valueSize; if (!rTypeKey.getValueInfo(OUString(), &valueType, &valueSize)) { sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); if (!rTypeKey.getValue(OUString(), pBuffer)) { reader = typereg::Reader( pBuffer, valueSize, true, TYPEREG_VERSION_1); } rtl_freeMemory(pBuffer); } } return reader; } RTTypeClass RegistryTypeManager::getTypeClass(const OString& name) const { if (m_pImpl->m_t2TypeClass.count(name) > 0) { return m_pImpl->m_t2TypeClass[name]; } else { RegistryKey key(searchTypeKey(name)); if (key.isValid()) { RegValueType valueType; sal_uInt32 valueSize; if (!key.getValueInfo(OUString(), &valueType, &valueSize)) { sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); if (!key.getValue(OUString(), pBuffer)) { typereg::Reader reader( pBuffer, valueSize, false, TYPEREG_VERSION_1); RTTypeClass ret = reader.getTypeClass(); rtl_freeMemory(pBuffer); m_pImpl->m_t2TypeClass[name] = ret; return ret; } rtl_freeMemory(pBuffer); } } } return RT_TYPE_INVALID; } RTTypeClass RegistryTypeManager::getTypeClass(RegistryKey& rTypeKey) const { OString name = getTypeName(rTypeKey); if (m_pImpl->m_t2TypeClass.count(name) > 0) { return m_pImpl->m_t2TypeClass[name]; } else { if (rTypeKey.isValid()) { RegValueType valueType; sal_uInt32 valueSize; if (!rTypeKey.getValueInfo(OUString(), &valueType, &valueSize)) { sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); if (!rTypeKey.getValue(OUString(), pBuffer)) { typereg::Reader reader( pBuffer, valueSize, false, TYPEREG_VERSION_1); RTTypeClass ret = reader.getTypeClass(); rtl_freeMemory(pBuffer); m_pImpl->m_t2TypeClass[name] = ret; return ret; } rtl_freeMemory(pBuffer); } } } return RT_TYPE_INVALID; } void RegistryTypeManager::setBase(const OString& base) { if (base.lastIndexOf('/') == (base.getLength() - 1)) m_pImpl->m_base += base.copy(0, base.lastIndexOf('/') - 1); else m_pImpl->m_base += base; } void RegistryTypeManager::freeRegistries() { RegistryList::const_iterator iter = m_pImpl->m_registries.begin(); while (iter != m_pImpl->m_registries.end()) { delete *iter; ++iter; } iter = m_pImpl->m_extra_registries.begin(); while (iter != m_pImpl->m_extra_registries.end()) { delete *iter; ++iter; } } RegistryKey RegistryTypeManager::searchTypeKey(const OString& name_, sal_Bool * pIsExtraType ) const { OUString name( OStringToOUString(m_pImpl->m_base + "/" + name_, RTL_TEXTENCODING_UTF8) ); RegistryKey key, rootKey; RegistryList::const_iterator iter = m_pImpl->m_registries.begin(); while (iter != m_pImpl->m_registries.end()) { if (!(*iter)->openRootKey(rootKey)) { if (!rootKey.openKey(name, key)) { if (pIsExtraType) *pIsExtraType = sal_False; return key; } } ++iter; } iter = m_pImpl->m_extra_registries.begin(); while (iter != m_pImpl->m_extra_registries.end()) { if (!(*iter)->openRootKey(rootKey)) { if (!rootKey.openKey(name, key)) { if (pIsExtraType) *pIsExtraType = sal_True; break; } } ++iter; } return key; } RegistryKeyList RegistryTypeManager::getTypeKeys(const ::rtl::OString& name_) const { RegistryKeyList keyList= RegistryKeyList(); OString tmpName; if ( name_.equals("/") || name_.equals(m_pImpl->m_base) ) { tmpName = m_pImpl->m_base; } else { if ( m_pImpl->m_base.equals("/") ) tmpName = name_; else tmpName = m_pImpl->m_base + "/" + name_; } OUString name( OStringToOUString(tmpName, RTL_TEXTENCODING_UTF8) ); RegistryKey key, rootKey; RegistryList::const_iterator iter = m_pImpl->m_registries.begin(); while (iter != m_pImpl->m_registries.end()) { if (!(*iter)->openRootKey(rootKey)) { if (!rootKey.openKey(name, key)) { keyList.push_back(KeyPair(key, sal_False)); } } ++iter; } iter = m_pImpl->m_extra_registries.begin(); while (iter != m_pImpl->m_extra_registries.end()) { if (!(*iter)->openRootKey(rootKey)) { if (!rootKey.openKey(name, key)) { keyList.push_back(KeyPair(key, sal_True)); } } ++iter; } return keyList; }