bb45bdf359
Change-Id: I2dcde42e6068631a5a643961a764df86dc63dca2 Reviewed-on: https://gerrit.libreoffice.org/4690 Tested-by: LibreOffice gerrit bot <gerrit@libreoffice.org> Reviewed-by: Norbert Thiebaud <nthiebaud@gmail.com> Tested-by: Norbert Thiebaud <nthiebaud@gmail.com>
474 lines
13 KiB
C++
474 lines
13 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* 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 .
|
|
*/
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include <rscconst.hxx>
|
|
#include <rscarray.hxx>
|
|
#include <rscdb.hxx>
|
|
|
|
RscInstNode::RscInstNode( sal_uInt32 nId )
|
|
{
|
|
nTypeId = nId;
|
|
}
|
|
|
|
RscInstNode::~RscInstNode()
|
|
{
|
|
if( aInst.IsInst() )
|
|
{
|
|
aInst.pClass->Destroy( aInst );
|
|
rtl_freeMemory( aInst.pData );
|
|
}
|
|
}
|
|
|
|
sal_uInt32 RscInstNode::GetId() const
|
|
{
|
|
return nTypeId;
|
|
}
|
|
|
|
RscArray::RscArray( Atom nId, sal_uInt32 nTypeId, RscTop * pSuper, RscEnum * pTypeCl )
|
|
: RscTop( nId, nTypeId, pSuper )
|
|
{
|
|
pTypeClass = pTypeCl;
|
|
nOffInstData = RscTop::Size();
|
|
nSize = nOffInstData + ALIGNED_SIZE( sizeof( RscArrayInst ) );
|
|
}
|
|
|
|
RscArray::~RscArray()
|
|
{
|
|
}
|
|
|
|
RSCCLASS_TYPE RscArray::GetClassType() const
|
|
{
|
|
return RSCCLASS_ENUMARRAY;
|
|
}
|
|
|
|
RscTop * RscArray::GetTypeClass() const
|
|
{
|
|
return pTypeClass;
|
|
}
|
|
|
|
static RscInstNode * Create( RscInstNode * pNode )
|
|
{
|
|
RscInstNode * pRetNode = NULL;
|
|
|
|
if( pNode )
|
|
{
|
|
pRetNode = new RscInstNode( pNode->GetId() );
|
|
pRetNode->aInst = pNode->aInst.pClass->Create( NULL, pNode->aInst );
|
|
RscInstNode * pTmpNode = Create(pNode->Left());
|
|
if (pTmpNode)
|
|
pRetNode->Insert( pTmpNode );
|
|
if( (pTmpNode = Create( pNode->Right() )) != NULL )
|
|
pRetNode->Insert( pTmpNode );
|
|
}
|
|
|
|
return pRetNode;
|
|
}
|
|
|
|
RSCINST RscArray::Create( RSCINST * pInst, const RSCINST & rDflt,
|
|
bool bOwnClass )
|
|
{
|
|
RSCINST aInst;
|
|
RscArrayInst * pClassData;
|
|
|
|
if( !pInst )
|
|
{
|
|
aInst.pClass = this;
|
|
aInst.pData = (CLASS_DATA) rtl_allocateMemory( Size() );
|
|
}
|
|
else
|
|
aInst = *pInst;
|
|
|
|
if( !bOwnClass && rDflt.IsInst() )
|
|
bOwnClass = rDflt.pClass->InHierarchy( this );
|
|
|
|
RscTop::Create( &aInst, rDflt, bOwnClass );
|
|
|
|
pClassData = (RscArrayInst *)(aInst.pData + nOffInstData);
|
|
pClassData->pNode = NULL;
|
|
if( bOwnClass )
|
|
{
|
|
RscArrayInst * pDfltClassData;
|
|
|
|
pDfltClassData = (RscArrayInst *)(rDflt.pData + nOffInstData);
|
|
|
|
pClassData->pNode = ::Create( pDfltClassData->pNode );
|
|
}
|
|
return aInst;
|
|
}
|
|
|
|
static void Destroy( RscInstNode * pNode )
|
|
{
|
|
if( pNode )
|
|
{
|
|
Destroy( pNode->Left() );
|
|
Destroy( pNode->Right() );
|
|
delete pNode;
|
|
}
|
|
}
|
|
|
|
void RscArray::Destroy( const RSCINST & rInst )
|
|
{
|
|
RscArrayInst * pClassData;
|
|
|
|
RscTop::Destroy( rInst );
|
|
|
|
pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
|
|
|
|
//Baum rekursiv loeschen
|
|
::Destroy( pClassData->pNode );
|
|
}
|
|
|
|
ERRTYPE RscArray::GetValueEle( const RSCINST & rInst,
|
|
sal_Int32 lValue,
|
|
RscTop * pCreateClass,
|
|
RSCINST * pGetInst)
|
|
{
|
|
RscArrayInst * pClassData;
|
|
RscInstNode * pNode;
|
|
|
|
pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
|
|
|
|
ERRTYPE aError;
|
|
|
|
Atom nId;
|
|
if( !pTypeClass->GetValueConst( sal_uInt32(lValue), &nId ) )
|
|
{ // nicht gefunden
|
|
return ERR_ARRAY_INVALIDINDEX;
|
|
}
|
|
|
|
if( pClassData->pNode )
|
|
pNode = pClassData->pNode->Search( sal_uInt32(lValue) );
|
|
else
|
|
pNode = NULL;
|
|
|
|
if( !pNode )
|
|
{
|
|
pNode = new RscInstNode( sal_uInt32(lValue) );
|
|
if( pCreateClass && GetSuperClass()->InHierarchy( pCreateClass ) )
|
|
pNode->aInst = pCreateClass->Create( NULL, rInst );
|
|
else
|
|
pNode->aInst = GetSuperClass()->Create( NULL, rInst );
|
|
|
|
pNode->aInst.pClass->SetToDefault( pNode->aInst );
|
|
if( pClassData->pNode )
|
|
pClassData->pNode->Insert( pNode );
|
|
else
|
|
pClassData->pNode = pNode;
|
|
}
|
|
|
|
*pGetInst = pNode->aInst;
|
|
return aError;
|
|
}
|
|
|
|
ERRTYPE RscArray::GetArrayEle( const RSCINST & rInst,
|
|
Atom nId,
|
|
RscTop * pCreateClass,
|
|
RSCINST * pGetInst)
|
|
{
|
|
sal_Int32 lValue;
|
|
if( !pTypeClass->GetConstValue( nId, &lValue ) )
|
|
{ // nicht gefunden
|
|
return ERR_ARRAY_INVALIDINDEX;
|
|
}
|
|
|
|
return GetValueEle( rInst, lValue, pCreateClass, pGetInst );
|
|
}
|
|
|
|
static bool IsConsistent( RscInstNode * pNode )
|
|
{
|
|
bool bRet = true;
|
|
|
|
if( pNode )
|
|
{
|
|
bRet = pNode->aInst.pClass->IsConsistent( pNode->aInst );
|
|
if( !IsConsistent( pNode->Left() ) )
|
|
bRet = false;
|
|
if( !IsConsistent( pNode->Right() ) )
|
|
bRet = false;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
bool RscArray::IsConsistent( const RSCINST & rInst )
|
|
{
|
|
RscArrayInst * pClassData;
|
|
bool bRet;
|
|
|
|
bRet = RscTop::IsConsistent( rInst );
|
|
|
|
pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
|
|
if( !::IsConsistent( pClassData->pNode ) )
|
|
bRet = false;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
static void SetToDefault( RscInstNode * pNode )
|
|
{
|
|
if( pNode )
|
|
{
|
|
pNode->aInst.pClass->SetToDefault( pNode->aInst );
|
|
SetToDefault( pNode->Left() );
|
|
SetToDefault( pNode->Right() );
|
|
}
|
|
}
|
|
|
|
void RscArray::SetToDefault( const RSCINST & rInst )
|
|
{
|
|
RscArrayInst * pClassData;
|
|
|
|
pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
|
|
|
|
::SetToDefault( pClassData->pNode );
|
|
|
|
RscTop::SetToDefault( rInst );
|
|
}
|
|
|
|
static bool IsDefault( RscInstNode * pNode )
|
|
{
|
|
bool bRet = true;
|
|
|
|
if( pNode )
|
|
{
|
|
bRet = pNode->aInst.pClass->IsDefault( pNode->aInst );
|
|
if( bRet )
|
|
bRet = IsDefault( pNode->Left() );
|
|
if( bRet )
|
|
bRet = IsDefault( pNode->Right() );
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
bool RscArray::IsDefault( const RSCINST & rInst )
|
|
{
|
|
RscArrayInst * pClassData;
|
|
|
|
pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
|
|
|
|
bool bRet = ::IsDefault( pClassData->pNode );
|
|
|
|
if( bRet )
|
|
bRet = RscTop::IsDefault( rInst );
|
|
return bRet;
|
|
}
|
|
|
|
static bool IsValueDefault( RscInstNode * pNode, CLASS_DATA pDef )
|
|
{
|
|
bool bRet = true;
|
|
|
|
if( pNode )
|
|
{
|
|
bRet = pNode->aInst.pClass->IsValueDefault( pNode->aInst, pDef );
|
|
if( bRet )
|
|
bRet = IsValueDefault( pNode->Left(), pDef );
|
|
if( bRet )
|
|
bRet = IsValueDefault( pNode->Right(), pDef );
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
bool RscArray::IsValueDefault( const RSCINST & rInst, CLASS_DATA pDef )
|
|
{
|
|
bool bRet = RscTop::IsValueDefault( rInst, pDef );
|
|
|
|
if( bRet )
|
|
{
|
|
RscArrayInst * pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
|
|
|
|
bRet = ::IsValueDefault( pClassData->pNode, pDef );
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
void RscArray::WriteSrcHeader( const RSCINST & rInst, FILE * fOutput,
|
|
RscTypCont * pTC, sal_uInt32 nTab,
|
|
const RscId & aId, const char * pVarName )
|
|
{
|
|
RscArrayInst * pClassData;
|
|
|
|
pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
|
|
|
|
if( pTC->IsSrsDefault() )
|
|
{ // nur einen Wert schreiben
|
|
RscInstNode * pNode = NULL;
|
|
if( pClassData->pNode )
|
|
{
|
|
std::vector< sal_uInt32 >::const_iterator it;
|
|
for( it = pTC->GetFallbacks().begin(); !pNode && it != pTC->GetFallbacks().end(); ++it )
|
|
pNode = pClassData->pNode->Search( *it );
|
|
}
|
|
|
|
if( pNode )
|
|
{
|
|
if( pNode->aInst.pClass->IsDefault( pNode->aInst ) )
|
|
fprintf( fOutput, "Default" );
|
|
else
|
|
pNode->aInst.pClass->WriteSrcHeader(
|
|
pNode->aInst, fOutput,
|
|
pTC, nTab, aId, pVarName );
|
|
return;
|
|
}
|
|
}
|
|
|
|
if( IsDefault( rInst ) )
|
|
fprintf( fOutput, "Default" );
|
|
else
|
|
{
|
|
RSCINST aSuper( GetSuperClass(), rInst.pData );
|
|
aSuper.pClass->WriteSrcHeader( aSuper, fOutput, pTC,
|
|
nTab, aId, pVarName );
|
|
}
|
|
if( !pTC->IsSrsDefault() )
|
|
WriteSrc( rInst, fOutput, pTC, nTab, pVarName );
|
|
}
|
|
|
|
static void WriteSrc( RscInstNode * pNode, FILE * fOutput, RscTypCont * pTC,
|
|
sal_uInt32 nTab, const char * pVarName,
|
|
CLASS_DATA pDfltData, RscConst * pTypeClass )
|
|
{
|
|
if( pNode )
|
|
{
|
|
WriteSrc( pNode->Left(), fOutput, pTC, nTab, pVarName,
|
|
pDfltData, pTypeClass );
|
|
if( !pNode->aInst.pClass->IsValueDefault( pNode->aInst, pDfltData ) )
|
|
{
|
|
fprintf( fOutput, ";\n" );
|
|
for( sal_uInt32 n = 0; n < nTab; n++ )
|
|
fputc( '\t', fOutput );
|
|
|
|
Atom nIdxId;
|
|
pTypeClass->GetValueConst( pNode->GetId(), &nIdxId );
|
|
fprintf( fOutput, "%s[ %s ] = ", pVarName, pHS->getString( nIdxId ).getStr() );
|
|
pNode->aInst.pClass->WriteSrcHeader( pNode->aInst, fOutput, pTC,
|
|
nTab, RscId(), pVarName );
|
|
}
|
|
WriteSrc( pNode->Right(), fOutput, pTC, nTab, pVarName,
|
|
pDfltData, pTypeClass );
|
|
}
|
|
}
|
|
|
|
void RscArray::WriteSrcArray( const RSCINST & rInst, FILE * fOutput,
|
|
RscTypCont * pTC, sal_uInt32 nTab,
|
|
const char * pVarName )
|
|
{
|
|
RscArrayInst * pClassData;
|
|
|
|
pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
|
|
|
|
::WriteSrc( pClassData->pNode, fOutput, pTC, nTab, pVarName,
|
|
rInst.pData, pTypeClass );
|
|
};
|
|
|
|
void RscArray::WriteSrc( const RSCINST & rInst, FILE * fOutput,
|
|
RscTypCont * pTC, sal_uInt32 nTab,
|
|
const char * pVarName )
|
|
{
|
|
WriteSrcArray( rInst, fOutput, pTC, nTab, pVarName );
|
|
}
|
|
|
|
ERRTYPE RscArray::WriteRc( const RSCINST & rInst, RscWriteRc & rMem,
|
|
RscTypCont * pTC, sal_uInt32 nDeep, bool bExtra )
|
|
{
|
|
ERRTYPE aError;
|
|
RscArrayInst * pClassData;
|
|
RscInstNode * pNode = NULL;
|
|
|
|
pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
|
|
|
|
if( pClassData->pNode )
|
|
{
|
|
#if OSL_DEBUG_LEVEL > 2
|
|
fprintf( stderr, "RscArray::WriteRc: Fallback " );
|
|
#endif
|
|
std::vector< sal_uInt32 >::const_iterator it;
|
|
for( it = pTC->GetFallbacks().begin(); !pNode && it != pTC->GetFallbacks().end(); ++it )
|
|
{
|
|
pNode = pClassData->pNode->Search( *it );
|
|
#if OSL_DEBUG_LEVEL > 2
|
|
fprintf( stderr, " 0x%hx", *it );
|
|
#endif
|
|
}
|
|
#if OSL_DEBUG_LEVEL > 2
|
|
fprintf( stderr, "\n" );
|
|
#endif
|
|
}
|
|
|
|
if( pNode )
|
|
aError = pNode->aInst.pClass->WriteRc( pNode->aInst, rMem, pTC,
|
|
nDeep, bExtra );
|
|
else
|
|
aError = RscTop::WriteRc( rInst, rMem, pTC, nDeep, bExtra );
|
|
|
|
return aError;
|
|
}
|
|
|
|
RscClassArray::RscClassArray( Atom nId, sal_uInt32 nTypeId, RscTop * pSuper,
|
|
RscEnum * pTypeCl )
|
|
: RscArray( nId, nTypeId, pSuper, pTypeCl )
|
|
{
|
|
}
|
|
|
|
RscClassArray::~RscClassArray()
|
|
{
|
|
}
|
|
|
|
void RscClassArray::WriteSrcHeader( const RSCINST & rInst, FILE * fOutput,
|
|
RscTypCont * pTC, sal_uInt32 nTab,
|
|
const RscId & aId, const char * pName )
|
|
{
|
|
RscArray::WriteSrcHeader( rInst, fOutput, pTC, nTab, aId, pName );
|
|
}
|
|
|
|
void RscClassArray::WriteSrc( const RSCINST & rInst, FILE * fOutput,
|
|
RscTypCont * pTC, sal_uInt32 nTab,
|
|
const char * pVarName )
|
|
{
|
|
RscArray::WriteSrc( rInst, fOutput, pTC, nTab, pVarName );
|
|
}
|
|
|
|
ERRTYPE RscClassArray::WriteRcHeader( const RSCINST & rInst, RscWriteRc & aMem,
|
|
RscTypCont * pTC, const RscId & aId,
|
|
sal_uInt32 nDeep, bool bExtra )
|
|
{
|
|
// Eigenen Typ schreiben
|
|
return GetSuperClass()->WriteRcHeader( rInst, aMem, pTC, aId,
|
|
nDeep, bExtra );
|
|
}
|
|
|
|
RscLangArray::RscLangArray( Atom nId, sal_uInt32 nTypeId, RscTop * pSuper,
|
|
RscEnum * pTypeCl )
|
|
: RscArray( nId, nTypeId, pSuper, pTypeCl )
|
|
{
|
|
}
|
|
|
|
RSCCLASS_TYPE RscLangArray::GetClassType() const
|
|
{
|
|
if( GetSuperClass() )
|
|
return GetSuperClass()->GetClassType();
|
|
else
|
|
return RscArray::GetClassType();
|
|
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|