blob: 2d0f1d6d5550a25ee34b7a25df30eecc2257598c [file] [log] [blame]
/**************************************************************
*
* 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;
}