bump product version to 5.0.4.1
[LibreOffice.git] / rsc / source / res / rscarray.cxx
blob4db3fb2c8dbbb751b745e046e0a12b3279c98180
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
25 #include <rscconst.hxx>
26 #include <rscarray.hxx>
27 #include <rscdb.hxx>
29 RscInstNode::RscInstNode( sal_uInt32 nId )
31 nTypeId = nId;
34 RscInstNode::~RscInstNode()
36 if( aInst.IsInst() )
38 aInst.pClass->Destroy( aInst );
39 rtl_freeMemory( aInst.pData );
43 sal_uInt32 RscInstNode::GetId() const
45 return nTypeId;
48 RscArray::RscArray( Atom nId, sal_uInt32 nTypeId, RscTop * pSuper, RscEnum * pTypeCl )
49 : RscTop( nId, nTypeId, pSuper )
51 pTypeClass = pTypeCl;
52 nOffInstData = RscTop::Size();
53 nSize = nOffInstData + ALIGNED_SIZE( sizeof( RscArrayInst ) );
56 RscArray::~RscArray()
60 RSCCLASS_TYPE RscArray::GetClassType() const
62 return RSCCLASS_ENUMARRAY;
65 RscTop * RscArray::GetTypeClass() const
67 return pTypeClass;
70 static RscInstNode * Create( RscInstNode * pNode )
72 RscInstNode * pRetNode = NULL;
74 if( pNode )
76 pRetNode = new RscInstNode( pNode->GetId() );
77 pRetNode->aInst = pNode->aInst.pClass->Create( NULL, pNode->aInst );
78 RscInstNode * pTmpNode = Create(pNode->Left());
79 if (pTmpNode)
80 pRetNode->Insert( pTmpNode );
81 if( (pTmpNode = Create( pNode->Right() )) != NULL )
82 pRetNode->Insert( pTmpNode );
85 return pRetNode;
88 RSCINST RscArray::Create( RSCINST * pInst, const RSCINST & rDflt,
89 bool bOwnClass )
91 RSCINST aInst;
92 RscArrayInst * pClassData;
94 if( !pInst )
96 aInst.pClass = this;
97 aInst.pData = static_cast<CLASS_DATA>(rtl_allocateMemory( Size() ));
99 else
100 aInst = *pInst;
102 if( !bOwnClass && rDflt.IsInst() )
103 bOwnClass = rDflt.pClass->InHierarchy( this );
105 RscTop::Create( &aInst, rDflt, bOwnClass );
107 pClassData = reinterpret_cast<RscArrayInst *>(aInst.pData + nOffInstData);
108 pClassData->pNode = NULL;
109 if( bOwnClass )
111 RscArrayInst * pDfltClassData;
113 pDfltClassData = reinterpret_cast<RscArrayInst *>(rDflt.pData + nOffInstData);
115 pClassData->pNode = ::Create( pDfltClassData->pNode );
117 return aInst;
120 static void Destroy( RscInstNode * pNode )
122 if( pNode )
124 Destroy( pNode->Left() );
125 Destroy( pNode->Right() );
126 delete pNode;
130 void RscArray::Destroy( const RSCINST & rInst )
132 RscArrayInst * pClassData;
134 RscTop::Destroy( rInst );
136 pClassData = reinterpret_cast<RscArrayInst *>(rInst.pData + nOffInstData);
138 //Baum rekursiv loeschen
139 ::Destroy( pClassData->pNode );
142 ERRTYPE RscArray::GetValueEle( const RSCINST & rInst,
143 sal_Int32 lValue,
144 RscTop * pCreateClass,
145 RSCINST * pGetInst)
147 RscArrayInst * pClassData;
148 RscInstNode * pNode;
150 pClassData = reinterpret_cast<RscArrayInst *>(rInst.pData + nOffInstData);
152 ERRTYPE aError;
154 Atom nId;
155 if( !pTypeClass->GetValueConst( sal_uInt32(lValue), &nId ) )
156 { // nicht gefunden
157 return ERR_ARRAY_INVALIDINDEX;
160 if( pClassData->pNode )
161 pNode = pClassData->pNode->Search( sal_uInt32(lValue) );
162 else
163 pNode = NULL;
165 if( !pNode )
167 pNode = new RscInstNode( sal_uInt32(lValue) );
168 if( pCreateClass && GetSuperClass()->InHierarchy( pCreateClass ) )
169 pNode->aInst = pCreateClass->Create( NULL, rInst );
170 else
171 pNode->aInst = GetSuperClass()->Create( NULL, rInst );
173 pNode->aInst.pClass->SetToDefault( pNode->aInst );
174 if( pClassData->pNode )
175 pClassData->pNode->Insert( pNode );
176 else
177 pClassData->pNode = pNode;
180 *pGetInst = pNode->aInst;
181 return aError;
184 ERRTYPE RscArray::GetArrayEle( const RSCINST & rInst,
185 Atom nId,
186 RscTop * pCreateClass,
187 RSCINST * pGetInst)
189 sal_Int32 lValue;
190 if( !pTypeClass->GetConstValue( nId, &lValue ) )
191 { // nicht gefunden
192 return ERR_ARRAY_INVALIDINDEX;
195 return GetValueEle( rInst, lValue, pCreateClass, pGetInst );
198 static bool IsConsistent( RscInstNode * pNode )
200 bool bRet = true;
202 if( pNode )
204 bRet = pNode->aInst.pClass->IsConsistent( pNode->aInst );
205 if( !IsConsistent( pNode->Left() ) )
206 bRet = false;
207 if( !IsConsistent( pNode->Right() ) )
208 bRet = false;
210 return bRet;
213 bool RscArray::IsConsistent( const RSCINST & rInst )
215 RscArrayInst * pClassData;
216 bool bRet;
218 bRet = RscTop::IsConsistent( rInst );
220 pClassData = reinterpret_cast<RscArrayInst *>(rInst.pData + nOffInstData);
221 if( !::IsConsistent( pClassData->pNode ) )
222 bRet = false;
224 return bRet;
227 static void SetToDefault( RscInstNode * pNode )
229 if( pNode )
231 pNode->aInst.pClass->SetToDefault( pNode->aInst );
232 SetToDefault( pNode->Left() );
233 SetToDefault( pNode->Right() );
237 void RscArray::SetToDefault( const RSCINST & rInst )
239 RscArrayInst * pClassData;
241 pClassData = reinterpret_cast<RscArrayInst *>(rInst.pData + nOffInstData);
243 ::SetToDefault( pClassData->pNode );
245 RscTop::SetToDefault( rInst );
248 static bool IsDefault( RscInstNode * pNode )
250 bool bRet = true;
252 if( pNode )
254 bRet = pNode->aInst.pClass->IsDefault( pNode->aInst );
255 if( bRet )
256 bRet = IsDefault( pNode->Left() );
257 if( bRet )
258 bRet = IsDefault( pNode->Right() );
260 return bRet;
263 bool RscArray::IsDefault( const RSCINST & rInst )
265 RscArrayInst * pClassData;
267 pClassData = reinterpret_cast<RscArrayInst *>(rInst.pData + nOffInstData);
269 bool bRet = ::IsDefault( pClassData->pNode );
271 if( bRet )
272 bRet = RscTop::IsDefault( rInst );
273 return bRet;
276 static bool IsValueDefault( RscInstNode * pNode, CLASS_DATA pDef )
278 bool bRet = true;
280 if( pNode )
282 bRet = pNode->aInst.pClass->IsValueDefault( pNode->aInst, pDef );
283 if( bRet )
284 bRet = IsValueDefault( pNode->Left(), pDef );
285 if( bRet )
286 bRet = IsValueDefault( pNode->Right(), pDef );
288 return bRet;
291 bool RscArray::IsValueDefault( const RSCINST & rInst, CLASS_DATA pDef )
293 bool bRet = RscTop::IsValueDefault( rInst, pDef );
295 if( bRet )
297 RscArrayInst * pClassData = reinterpret_cast<RscArrayInst *>(rInst.pData + nOffInstData);
299 bRet = ::IsValueDefault( pClassData->pNode, pDef );
301 return bRet;
304 void RscArray::WriteSrcHeader( const RSCINST & rInst, FILE * fOutput,
305 RscTypCont * pTC, sal_uInt32 nTab,
306 const RscId & aId, const char * pVarName )
308 RscArrayInst * pClassData;
310 pClassData = reinterpret_cast<RscArrayInst *>(rInst.pData + nOffInstData);
312 if( pTC->IsSrsDefault() )
313 { // nur einen Wert schreiben
314 RscInstNode * pNode = NULL;
315 if( pClassData->pNode )
317 std::vector< sal_uInt32 >::const_iterator it;
318 for( it = pTC->GetFallbacks().begin(); !pNode && it != pTC->GetFallbacks().end(); ++it )
319 pNode = pClassData->pNode->Search( *it );
322 if( pNode )
324 if( pNode->aInst.pClass->IsDefault( pNode->aInst ) )
325 fprintf( fOutput, "Default" );
326 else
327 pNode->aInst.pClass->WriteSrcHeader(
328 pNode->aInst, fOutput,
329 pTC, nTab, aId, pVarName );
330 return;
334 if( IsDefault( rInst ) )
335 fprintf( fOutput, "Default" );
336 else
338 RSCINST aSuper( GetSuperClass(), rInst.pData );
339 aSuper.pClass->WriteSrcHeader( aSuper, fOutput, pTC,
340 nTab, aId, pVarName );
342 if( !pTC->IsSrsDefault() )
343 WriteSrc( rInst, fOutput, pTC, nTab, pVarName );
346 static void WriteSrc( RscInstNode * pNode, FILE * fOutput, RscTypCont * pTC,
347 sal_uInt32 nTab, const char * pVarName,
348 CLASS_DATA pDfltData, RscConst * pTypeClass )
350 if( pNode )
352 WriteSrc( pNode->Left(), fOutput, pTC, nTab, pVarName,
353 pDfltData, pTypeClass );
354 if( !pNode->aInst.pClass->IsValueDefault( pNode->aInst, pDfltData ) )
356 fprintf( fOutput, ";\n" );
357 for( sal_uInt32 n = 0; n < nTab; n++ )
358 fputc( '\t', fOutput );
360 Atom nIdxId;
361 pTypeClass->GetValueConst( pNode->GetId(), &nIdxId );
362 fprintf( fOutput, "%s[ %s ] = ", pVarName, pHS->getString( nIdxId ).getStr() );
363 pNode->aInst.pClass->WriteSrcHeader( pNode->aInst, fOutput, pTC,
364 nTab, RscId(), pVarName );
366 WriteSrc( pNode->Right(), fOutput, pTC, nTab, pVarName,
367 pDfltData, pTypeClass );
371 void RscArray::WriteSrcArray( const RSCINST & rInst, FILE * fOutput,
372 RscTypCont * pTC, sal_uInt32 nTab,
373 const char * pVarName )
375 RscArrayInst * pClassData;
377 pClassData = reinterpret_cast<RscArrayInst *>(rInst.pData + nOffInstData);
379 ::WriteSrc( pClassData->pNode, fOutput, pTC, nTab, pVarName,
380 rInst.pData, pTypeClass );
383 void RscArray::WriteSrc( const RSCINST & rInst, FILE * fOutput,
384 RscTypCont * pTC, sal_uInt32 nTab,
385 const char * pVarName )
387 WriteSrcArray( rInst, fOutput, pTC, nTab, pVarName );
390 ERRTYPE RscArray::WriteRc( const RSCINST & rInst, RscWriteRc & rMem,
391 RscTypCont * pTC, sal_uInt32 nDeep, bool bExtra )
393 ERRTYPE aError;
394 RscArrayInst * pClassData;
395 RscInstNode * pNode = NULL;
397 pClassData = reinterpret_cast<RscArrayInst *>(rInst.pData + nOffInstData);
399 if( pClassData->pNode )
401 #if OSL_DEBUG_LEVEL > 2
402 fprintf( stderr, "RscArray::WriteRc: Fallback " );
403 #endif
404 std::vector< sal_uInt32 >::const_iterator it;
405 for( it = pTC->GetFallbacks().begin(); !pNode && it != pTC->GetFallbacks().end(); ++it )
407 pNode = pClassData->pNode->Search( *it );
408 #if OSL_DEBUG_LEVEL > 2
409 fprintf( stderr, " 0x%hx", *it );
410 #endif
412 #if OSL_DEBUG_LEVEL > 2
413 fprintf( stderr, "\n" );
414 #endif
417 if( pNode )
418 aError = pNode->aInst.pClass->WriteRc( pNode->aInst, rMem, pTC,
419 nDeep, bExtra );
420 else
421 aError = RscTop::WriteRc( rInst, rMem, pTC, nDeep, bExtra );
423 return aError;
426 RscClassArray::RscClassArray( Atom nId, sal_uInt32 nTypeId, RscTop * pSuper,
427 RscEnum * pTypeCl )
428 : RscArray( nId, nTypeId, pSuper, pTypeCl )
432 RscClassArray::~RscClassArray()
436 void RscClassArray::WriteSrcHeader( const RSCINST & rInst, FILE * fOutput,
437 RscTypCont * pTC, sal_uInt32 nTab,
438 const RscId & aId, const char * pName )
440 RscArray::WriteSrcHeader( rInst, fOutput, pTC, nTab, aId, pName );
443 void RscClassArray::WriteSrc( const RSCINST & rInst, FILE * fOutput,
444 RscTypCont * pTC, sal_uInt32 nTab,
445 const char * pVarName )
447 RscArray::WriteSrc( rInst, fOutput, pTC, nTab, pVarName );
450 ERRTYPE RscClassArray::WriteRcHeader( const RSCINST & rInst, RscWriteRc & aMem,
451 RscTypCont * pTC, const RscId & aId,
452 sal_uInt32 nDeep, bool bExtra )
454 // Eigenen Typ schreiben
455 return GetSuperClass()->WriteRcHeader( rInst, aMem, pTC, aId,
456 nDeep, bExtra );
459 RscLangArray::RscLangArray( Atom nId, sal_uInt32 nTypeId, RscTop * pSuper,
460 RscEnum * pTypeCl )
461 : RscArray( nId, nTypeId, pSuper, pTypeCl )
465 RSCCLASS_TYPE RscLangArray::GetClassType() const
467 if( GetSuperClass() )
468 return GetSuperClass()->GetClassType();
469 else
470 return RscArray::GetClassType();
474 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */