update credits
[LibreOffice.git] / rsc / source / res / rscarray.cxx
blobf10b9c0bf018fe3040a78eec14d642e814efc01c
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 sal_Bool bOwnClass )
91 RSCINST aInst;
92 RscArrayInst * pClassData;
94 if( !pInst )
96 aInst.pClass = this;
97 aInst.pData = (CLASS_DATA) rtl_allocateMemory( Size() );
99 else
100 aInst = *pInst;
101 if( !bOwnClass && rDflt.IsInst() )
102 bOwnClass = rDflt.pClass->InHierarchy( this );
104 RscTop::Create( &aInst, rDflt, bOwnClass );
106 pClassData = (RscArrayInst *)(aInst.pData + nOffInstData);
107 pClassData->pNode = NULL;
108 if( bOwnClass )
110 RscArrayInst * pDfltClassData;
112 pDfltClassData = (RscArrayInst *)(rDflt.pData + nOffInstData);
114 pClassData->pNode = ::Create( pDfltClassData->pNode );
116 return( aInst );
119 static void Destroy( RscInstNode * pNode )
121 if( pNode )
123 Destroy( pNode->Left() );
124 Destroy( pNode->Right() );
125 delete pNode;
129 void RscArray::Destroy( const RSCINST & rInst )
131 RscArrayInst * pClassData;
133 RscTop::Destroy( rInst );
135 pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
137 //Baum rekursiv loeschen
138 ::Destroy( pClassData->pNode );
141 ERRTYPE RscArray::GetValueEle
143 const RSCINST & rInst,
144 sal_Int32 lValue,
145 RscTop * pCreateClass,
146 RSCINST * pGetInst
149 RscArrayInst * pClassData;
150 RscInstNode * pNode;
152 pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
154 ERRTYPE aError;
156 Atom nId;
157 if( !pTypeClass->GetValueConst( sal_uInt32(lValue), &nId ) )
158 { // nicht gefunden
159 return ERR_ARRAY_INVALIDINDEX;
162 if( pClassData->pNode )
163 pNode = pClassData->pNode->Search( sal_uInt32(lValue) );
164 else
165 pNode = NULL;
167 if( !pNode )
169 pNode = new RscInstNode( sal_uInt32(lValue) );
170 if( pCreateClass && GetSuperClass()->InHierarchy( pCreateClass ) )
171 pNode->aInst = pCreateClass->Create( NULL, rInst );
172 else
173 pNode->aInst = GetSuperClass()->Create( NULL, rInst );
174 pNode->aInst.pClass->SetToDefault( pNode->aInst );
175 if( pClassData->pNode )
176 pClassData->pNode->Insert( pNode );
177 else
178 pClassData->pNode = pNode;
181 *pGetInst = pNode->aInst;
182 return aError;
185 ERRTYPE RscArray::GetArrayEle
187 const RSCINST & rInst,
188 Atom nId,
189 RscTop * pCreateClass,
190 RSCINST * pGetInst
193 sal_Int32 lValue;
194 if( !pTypeClass->GetConstValue( nId, &lValue ) )
195 { // nicht gefunden
196 return ERR_ARRAY_INVALIDINDEX;
199 return GetValueEle( rInst, lValue, pCreateClass, pGetInst );
202 static sal_Bool IsConsistent( RscInstNode * pNode )
204 sal_Bool bRet = sal_True;
206 if( pNode )
208 bRet = pNode->aInst.pClass->IsConsistent( pNode->aInst );
209 if( !IsConsistent( pNode->Left() ) )
210 bRet = sal_False;
211 if( !IsConsistent( pNode->Right() ) )
212 bRet = sal_False;
214 return bRet;
217 sal_Bool RscArray::IsConsistent( const RSCINST & rInst )
219 RscArrayInst * pClassData;
220 sal_Bool bRet;
222 bRet = RscTop::IsConsistent( rInst );
224 pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
225 if( !::IsConsistent( pClassData->pNode ) )
226 bRet = sal_False;
228 return( bRet );
231 static void SetToDefault( RscInstNode * pNode )
233 if( pNode )
235 pNode->aInst.pClass->SetToDefault( pNode->aInst );
236 SetToDefault( pNode->Left() );
237 SetToDefault( pNode->Right() );
241 void RscArray::SetToDefault( const RSCINST & rInst )
243 RscArrayInst * pClassData;
245 pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
247 ::SetToDefault( pClassData->pNode );
249 RscTop::SetToDefault( rInst );
252 static sal_Bool IsDefault( RscInstNode * pNode )
254 sal_Bool bRet = sal_True;
256 if( pNode )
258 bRet = pNode->aInst.pClass->IsDefault( pNode->aInst );
259 if( bRet )
260 bRet = IsDefault( pNode->Left() );
261 if( bRet )
262 bRet = IsDefault( pNode->Right() );
264 return bRet;
267 sal_Bool RscArray::IsDefault( const RSCINST & rInst )
269 RscArrayInst * pClassData;
271 pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
273 sal_Bool bRet = ::IsDefault( pClassData->pNode );
275 if( bRet )
276 bRet = RscTop::IsDefault( rInst );
277 return bRet;
280 static sal_Bool IsValueDefault( RscInstNode * pNode, CLASS_DATA pDef )
282 sal_Bool bRet = sal_True;
284 if( pNode )
286 bRet = pNode->aInst.pClass->IsValueDefault( pNode->aInst, pDef );
287 if( bRet )
288 bRet = IsValueDefault( pNode->Left(), pDef );
289 if( bRet )
290 bRet = IsValueDefault( pNode->Right(), pDef );
292 return bRet;
295 sal_Bool RscArray::IsValueDefault( const RSCINST & rInst, CLASS_DATA pDef )
297 sal_Bool bRet = RscTop::IsValueDefault( rInst, pDef );
299 if( bRet )
301 RscArrayInst * pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
303 bRet = ::IsValueDefault( pClassData->pNode, pDef );
305 return bRet;
308 void RscArray::WriteSrcHeader( const RSCINST & rInst, FILE * fOutput,
309 RscTypCont * pTC, sal_uInt32 nTab,
310 const RscId & aId, const char * pVarName )
312 RscArrayInst * pClassData;
314 pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
316 if( pTC->IsSrsDefault() )
317 { // nur einen Wert schreiben
318 RscInstNode * pNode = NULL;
319 if( pClassData->pNode )
321 std::vector< sal_uInt32 >::const_iterator it;
322 for( it = pTC->GetFallbacks().begin(); !pNode && it != pTC->GetFallbacks().end(); ++it )
323 pNode = pClassData->pNode->Search( *it );
326 if( pNode )
328 if( pNode->aInst.pClass->IsDefault( pNode->aInst ) )
329 fprintf( fOutput, "Default" );
330 else
331 pNode->aInst.pClass->WriteSrcHeader(
332 pNode->aInst, fOutput,
333 pTC, nTab, aId, pVarName );
334 return;
338 if( IsDefault( rInst ) )
339 fprintf( fOutput, "Default" );
340 else
342 RSCINST aSuper( GetSuperClass(), rInst.pData );
343 aSuper.pClass->WriteSrcHeader( aSuper, fOutput, pTC,
344 nTab, aId, pVarName );
346 if( !pTC->IsSrsDefault() )
347 WriteSrc( rInst, fOutput, pTC, nTab, pVarName );
350 static void WriteSrc( RscInstNode * pNode, FILE * fOutput, RscTypCont * pTC,
351 sal_uInt32 nTab, const char * pVarName,
352 CLASS_DATA pDfltData, RscConst * pTypeClass )
354 if( pNode )
356 WriteSrc( pNode->Left(), fOutput, pTC, nTab, pVarName,
357 pDfltData, pTypeClass );
358 if( !pNode->aInst.pClass->IsValueDefault( pNode->aInst, pDfltData ) )
360 fprintf( fOutput, ";\n" );
361 for( sal_uInt32 n = 0; n < nTab; n++ )
362 fputc( '\t', fOutput );
364 Atom nIdxId;
365 pTypeClass->GetValueConst( pNode->GetId(), &nIdxId );
366 fprintf( fOutput, "%s[ %s ] = ", pVarName, pHS->getString( nIdxId ).getStr() );
367 pNode->aInst.pClass->WriteSrcHeader( pNode->aInst, fOutput, pTC,
368 nTab, RscId(), pVarName );
370 WriteSrc( pNode->Right(), fOutput, pTC, nTab, pVarName,
371 pDfltData, pTypeClass );
375 void RscArray::WriteSrcArray( const RSCINST & rInst, FILE * fOutput,
376 RscTypCont * pTC, sal_uInt32 nTab,
377 const char * pVarName )
379 RscArrayInst * pClassData;
381 pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
383 ::WriteSrc( pClassData->pNode, fOutput, pTC, nTab, pVarName,
384 rInst.pData, pTypeClass );
387 void RscArray::WriteSrc( const RSCINST & rInst, FILE * fOutput,
388 RscTypCont * pTC, sal_uInt32 nTab,
389 const char * pVarName )
391 WriteSrcArray( rInst, fOutput, pTC, nTab, pVarName );
394 ERRTYPE RscArray::WriteRc( const RSCINST & rInst, RscWriteRc & rMem,
395 RscTypCont * pTC, sal_uInt32 nDeep, sal_Bool bExtra )
397 ERRTYPE aError;
398 RscArrayInst * pClassData;
399 RscInstNode * pNode = NULL;
401 pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
403 if( pClassData->pNode )
405 #if OSL_DEBUG_LEVEL > 2
406 fprintf( stderr, "RscArray::WriteRc: Fallback " );
407 #endif
408 std::vector< sal_uInt32 >::const_iterator it;
409 for( it = pTC->GetFallbacks().begin(); !pNode && it != pTC->GetFallbacks().end(); ++it )
411 pNode = pClassData->pNode->Search( *it );
412 #if OSL_DEBUG_LEVEL > 2
413 fprintf( stderr, " 0x%hx", *it );
414 #endif
416 #if OSL_DEBUG_LEVEL > 2
417 fprintf( stderr, "\n" );
418 #endif
421 if( pNode )
422 aError = pNode->aInst.pClass->WriteRc( pNode->aInst, rMem, pTC,
423 nDeep, bExtra );
424 else
425 aError = RscTop::WriteRc( rInst, rMem, pTC, nDeep, bExtra );
427 return aError;
430 RscClassArray::RscClassArray( Atom nId, sal_uInt32 nTypeId, RscTop * pSuper,
431 RscEnum * pTypeCl )
432 : RscArray( nId, nTypeId, pSuper, pTypeCl )
436 RscClassArray::~RscClassArray()
440 void RscClassArray::WriteSrcHeader( const RSCINST & rInst, FILE * fOutput,
441 RscTypCont * pTC, sal_uInt32 nTab,
442 const RscId & aId, const char * pName )
444 RscArray::WriteSrcHeader( rInst, fOutput, pTC, nTab, aId, pName );
447 void RscClassArray::WriteSrc( const RSCINST & rInst, FILE * fOutput,
448 RscTypCont * pTC, sal_uInt32 nTab,
449 const char * pVarName )
451 RscArray::WriteSrc( rInst, fOutput, pTC, nTab, pVarName );
454 ERRTYPE RscClassArray::WriteRcHeader( const RSCINST & rInst, RscWriteRc & aMem,
455 RscTypCont * pTC, const RscId & aId,
456 sal_uInt32 nDeep, sal_Bool bExtra )
458 // Eigenen Typ schreiben
459 return GetSuperClass()->WriteRcHeader( rInst, aMem, pTC, aId,
460 nDeep, bExtra );
463 RscLangArray::RscLangArray( Atom nId, sal_uInt32 nTypeId, RscTop * pSuper,
464 RscEnum * pTypeCl )
465 : RscArray( nId, nTypeId, pSuper, pTypeCl )
469 RSCCLASS_TYPE RscLangArray::GetClassType() const
471 if( GetSuperClass() )
472 return GetSuperClass()->GetClassType();
473 else
474 return RscArray::GetClassType();
478 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */