/************************************************************** * * 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. * *************************************************************/ #include #include #include 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;; } RegistryTypeManager::RegistryTypeManager() { m_pImpl = new RegistryTypeManagerImpl(); acquire(); } RegistryTypeManager::~RegistryTypeManager() { release(); } void RegistryTypeManager::acquire() { TypeManager::acquire(); } void RegistryTypeManager::release() { if (0 == TypeManager::release()) { if (m_pImpl->m_pMergedRegistry) { if (m_pImpl->m_pMergedRegistry->isValid()) { m_pImpl->m_pMergedRegistry->destroy(OUString()); } delete m_pImpl->m_pMergedRegistry; } if (m_pImpl->m_registries.size() > 0) { freeRegistries(); } delete m_pImpl; } } sal_Bool RegistryTypeManager::init(sal_Bool bMerged, const StringVector& regFiles) { m_pImpl->m_isMerged = bMerged && (regFiles.size() > 1); 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++; } if (m_pImpl->m_isMerged) { Registry *pTmpReg = new Registry; OUString tmpName; osl::FileBase::createTempFile(0, 0, &tmpName); if (!pTmpReg->create(tmpName)) { RegistryKey rootKey; RegError ret = REG_NO_ERROR; OUString aRoot( RTL_CONSTASCII_USTRINGPARAM("/") ); iter = regFiles.begin(); pTmpReg->openRootKey(rootKey); while (iter != regFiles.end()) { if ( (ret = pTmpReg->mergeKey(rootKey, aRoot, convertToFileUrl( *iter ))) ) { if (ret != REG_MERGE_CONFLICT) { freeRegistries(); rootKey.closeKey(); pTmpReg->destroy( OUString() ); delete pTmpReg; return sal_False; } } iter++; } m_pImpl->m_pMergedRegistry = pTmpReg; freeRegistries(); } else { delete pTmpReg; freeRegistries(); return sal_False; } } return sal_True; } TypeReader RegistryTypeManager::getTypeReader(const OString& name) { TypeReader reader; 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)) { reader = TypeReader(pBuffer, valueSize, sal_True); } rtl_freeMemory(pBuffer); } } return reader; } RTTypeClass RegistryTypeManager::getTypeClass(const OString& name) { 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)) { TypeReader reader(pBuffer, valueSize, sal_False); 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) { m_pImpl->m_base = base; if (base.lastIndexOf('/') != (base.getLength() - 1)) { m_pImpl->m_base += "/"; } } void RegistryTypeManager::freeRegistries() { RegistryList::const_iterator iter = m_pImpl->m_registries.begin(); while (iter != m_pImpl->m_registries.end()) { delete *iter; iter++; } } RegistryKey RegistryTypeManager::searchTypeKey(const OString& name) { RegistryKey key, rootKey; if (m_pImpl->m_isMerged) { if (!m_pImpl->m_pMergedRegistry->openRootKey(rootKey)) { rootKey.openKey(OStringToOUString(m_pImpl->m_base + name, RTL_TEXTENCODING_UTF8), key); } } else { RegistryList::const_iterator iter = m_pImpl->m_registries.begin(); while (iter != m_pImpl->m_registries.end()) { if (!(*iter)->openRootKey(rootKey)) { if (!rootKey.openKey(OStringToOUString(m_pImpl->m_base + name, RTL_TEXTENCODING_UTF8), key)) break; } iter++; } } return key; }