blob: 09490dfb5a727241d9c157a403ee7779db1576b4 [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.
*
*************************************************************/
// 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;
}