| /************************************************************** |
| * |
| * 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 <rtl/alloc.h> |
| #include <osl/file.hxx> |
| #include <codemaker/typemanager.hxx> |
| |
| 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; |
| } |
| |