Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include <stdlib.h>
22 : #include <stdio.h>
23 : #include <string.h>
24 :
25 : #include <rscconst.hxx>
26 : #include <rscarray.hxx>
27 : #include <rscdb.hxx>
28 :
29 0 : RscInstNode::RscInstNode( sal_uInt32 nId )
30 : {
31 0 : nTypeId = nId;
32 0 : }
33 :
34 0 : RscInstNode::~RscInstNode()
35 : {
36 0 : if( aInst.IsInst() )
37 : {
38 0 : aInst.pClass->Destroy( aInst );
39 0 : rtl_freeMemory( aInst.pData );
40 : }
41 0 : }
42 :
43 0 : sal_uInt32 RscInstNode::GetId() const
44 : {
45 0 : return nTypeId;
46 : }
47 :
48 0 : RscArray::RscArray( Atom nId, sal_uInt32 nTypeId, RscTop * pSuper, RscEnum * pTypeCl )
49 0 : : RscTop( nId, nTypeId, pSuper )
50 : {
51 0 : pTypeClass = pTypeCl;
52 0 : nOffInstData = RscTop::Size();
53 0 : nSize = nOffInstData + ALIGNED_SIZE( sizeof( RscArrayInst ) );
54 0 : }
55 :
56 0 : RscArray::~RscArray()
57 : {
58 0 : }
59 :
60 0 : RSCCLASS_TYPE RscArray::GetClassType() const
61 : {
62 0 : return RSCCLASS_ENUMARRAY;
63 : }
64 :
65 0 : RscTop * RscArray::GetTypeClass() const
66 : {
67 0 : return pTypeClass;
68 : }
69 :
70 0 : static RscInstNode * Create( RscInstNode * pNode )
71 : {
72 0 : RscInstNode * pRetNode = NULL;
73 :
74 0 : if( pNode )
75 : {
76 0 : pRetNode = new RscInstNode( pNode->GetId() );
77 0 : pRetNode->aInst = pNode->aInst.pClass->Create( NULL, pNode->aInst );
78 0 : RscInstNode * pTmpNode = Create(pNode->Left());
79 0 : if (pTmpNode)
80 0 : pRetNode->Insert( pTmpNode );
81 0 : if( (pTmpNode = Create( pNode->Right() )) != NULL )
82 0 : pRetNode->Insert( pTmpNode );
83 : }
84 :
85 0 : return pRetNode;
86 : }
87 :
88 0 : RSCINST RscArray::Create( RSCINST * pInst, const RSCINST & rDflt,
89 : bool bOwnClass )
90 : {
91 0 : RSCINST aInst;
92 : RscArrayInst * pClassData;
93 :
94 0 : if( !pInst )
95 : {
96 0 : aInst.pClass = this;
97 0 : aInst.pData = (CLASS_DATA) rtl_allocateMemory( Size() );
98 : }
99 : else
100 0 : aInst = *pInst;
101 :
102 0 : if( !bOwnClass && rDflt.IsInst() )
103 0 : bOwnClass = rDflt.pClass->InHierarchy( this );
104 :
105 0 : RscTop::Create( &aInst, rDflt, bOwnClass );
106 :
107 0 : pClassData = (RscArrayInst *)(aInst.pData + nOffInstData);
108 0 : pClassData->pNode = NULL;
109 0 : if( bOwnClass )
110 : {
111 : RscArrayInst * pDfltClassData;
112 :
113 0 : pDfltClassData = (RscArrayInst *)(rDflt.pData + nOffInstData);
114 :
115 0 : pClassData->pNode = ::Create( pDfltClassData->pNode );
116 : }
117 0 : return aInst;
118 : }
119 :
120 0 : static void Destroy( RscInstNode * pNode )
121 : {
122 0 : if( pNode )
123 : {
124 0 : Destroy( pNode->Left() );
125 0 : Destroy( pNode->Right() );
126 0 : delete pNode;
127 : }
128 0 : }
129 :
130 0 : void RscArray::Destroy( const RSCINST & rInst )
131 : {
132 : RscArrayInst * pClassData;
133 :
134 0 : RscTop::Destroy( rInst );
135 :
136 0 : pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
137 :
138 : //Baum rekursiv loeschen
139 0 : ::Destroy( pClassData->pNode );
140 0 : }
141 :
142 0 : ERRTYPE RscArray::GetValueEle( const RSCINST & rInst,
143 : sal_Int32 lValue,
144 : RscTop * pCreateClass,
145 : RSCINST * pGetInst)
146 : {
147 : RscArrayInst * pClassData;
148 : RscInstNode * pNode;
149 :
150 0 : pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
151 :
152 0 : ERRTYPE aError;
153 :
154 : Atom nId;
155 0 : if( !pTypeClass->GetValueConst( sal_uInt32(lValue), &nId ) )
156 : { // nicht gefunden
157 0 : return ERR_ARRAY_INVALIDINDEX;
158 : }
159 :
160 0 : if( pClassData->pNode )
161 0 : pNode = pClassData->pNode->Search( sal_uInt32(lValue) );
162 : else
163 0 : pNode = NULL;
164 :
165 0 : if( !pNode )
166 : {
167 0 : pNode = new RscInstNode( sal_uInt32(lValue) );
168 0 : if( pCreateClass && GetSuperClass()->InHierarchy( pCreateClass ) )
169 0 : pNode->aInst = pCreateClass->Create( NULL, rInst );
170 : else
171 0 : pNode->aInst = GetSuperClass()->Create( NULL, rInst );
172 :
173 0 : pNode->aInst.pClass->SetToDefault( pNode->aInst );
174 0 : if( pClassData->pNode )
175 0 : pClassData->pNode->Insert( pNode );
176 : else
177 0 : pClassData->pNode = pNode;
178 : }
179 :
180 0 : *pGetInst = pNode->aInst;
181 0 : return aError;
182 : }
183 :
184 0 : ERRTYPE RscArray::GetArrayEle( const RSCINST & rInst,
185 : Atom nId,
186 : RscTop * pCreateClass,
187 : RSCINST * pGetInst)
188 : {
189 : sal_Int32 lValue;
190 0 : if( !pTypeClass->GetConstValue( nId, &lValue ) )
191 : { // nicht gefunden
192 0 : return ERR_ARRAY_INVALIDINDEX;
193 : }
194 :
195 0 : return GetValueEle( rInst, lValue, pCreateClass, pGetInst );
196 : }
197 :
198 0 : static bool IsConsistent( RscInstNode * pNode )
199 : {
200 0 : bool bRet = true;
201 :
202 0 : if( pNode )
203 : {
204 0 : bRet = pNode->aInst.pClass->IsConsistent( pNode->aInst );
205 0 : if( !IsConsistent( pNode->Left() ) )
206 0 : bRet = false;
207 0 : if( !IsConsistent( pNode->Right() ) )
208 0 : bRet = false;
209 : }
210 0 : return bRet;
211 : }
212 :
213 0 : bool RscArray::IsConsistent( const RSCINST & rInst )
214 : {
215 : RscArrayInst * pClassData;
216 : bool bRet;
217 :
218 0 : bRet = RscTop::IsConsistent( rInst );
219 :
220 0 : pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
221 0 : if( !::IsConsistent( pClassData->pNode ) )
222 0 : bRet = false;
223 :
224 0 : return bRet;
225 : }
226 :
227 0 : static void SetToDefault( RscInstNode * pNode )
228 : {
229 0 : if( pNode )
230 : {
231 0 : pNode->aInst.pClass->SetToDefault( pNode->aInst );
232 0 : SetToDefault( pNode->Left() );
233 0 : SetToDefault( pNode->Right() );
234 : }
235 0 : }
236 :
237 0 : void RscArray::SetToDefault( const RSCINST & rInst )
238 : {
239 : RscArrayInst * pClassData;
240 :
241 0 : pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
242 :
243 0 : ::SetToDefault( pClassData->pNode );
244 :
245 0 : RscTop::SetToDefault( rInst );
246 0 : }
247 :
248 0 : static bool IsDefault( RscInstNode * pNode )
249 : {
250 0 : bool bRet = true;
251 :
252 0 : if( pNode )
253 : {
254 0 : bRet = pNode->aInst.pClass->IsDefault( pNode->aInst );
255 0 : if( bRet )
256 0 : bRet = IsDefault( pNode->Left() );
257 0 : if( bRet )
258 0 : bRet = IsDefault( pNode->Right() );
259 : }
260 0 : return bRet;
261 : }
262 :
263 0 : bool RscArray::IsDefault( const RSCINST & rInst )
264 : {
265 : RscArrayInst * pClassData;
266 :
267 0 : pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
268 :
269 0 : bool bRet = ::IsDefault( pClassData->pNode );
270 :
271 0 : if( bRet )
272 0 : bRet = RscTop::IsDefault( rInst );
273 0 : return bRet;
274 : }
275 :
276 0 : static bool IsValueDefault( RscInstNode * pNode, CLASS_DATA pDef )
277 : {
278 0 : bool bRet = true;
279 :
280 0 : if( pNode )
281 : {
282 0 : bRet = pNode->aInst.pClass->IsValueDefault( pNode->aInst, pDef );
283 0 : if( bRet )
284 0 : bRet = IsValueDefault( pNode->Left(), pDef );
285 0 : if( bRet )
286 0 : bRet = IsValueDefault( pNode->Right(), pDef );
287 : }
288 0 : return bRet;
289 : }
290 :
291 0 : bool RscArray::IsValueDefault( const RSCINST & rInst, CLASS_DATA pDef )
292 : {
293 0 : bool bRet = RscTop::IsValueDefault( rInst, pDef );
294 :
295 0 : if( bRet )
296 : {
297 0 : RscArrayInst * pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
298 :
299 0 : bRet = ::IsValueDefault( pClassData->pNode, pDef );
300 : }
301 0 : return bRet;
302 : }
303 :
304 0 : void RscArray::WriteSrcHeader( const RSCINST & rInst, FILE * fOutput,
305 : RscTypCont * pTC, sal_uInt32 nTab,
306 : const RscId & aId, const char * pVarName )
307 : {
308 : RscArrayInst * pClassData;
309 :
310 0 : pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
311 :
312 0 : if( pTC->IsSrsDefault() )
313 : { // nur einen Wert schreiben
314 0 : RscInstNode * pNode = NULL;
315 0 : if( pClassData->pNode )
316 : {
317 0 : std::vector< sal_uInt32 >::const_iterator it;
318 0 : for( it = pTC->GetFallbacks().begin(); !pNode && it != pTC->GetFallbacks().end(); ++it )
319 0 : pNode = pClassData->pNode->Search( *it );
320 : }
321 :
322 0 : if( pNode )
323 : {
324 0 : if( pNode->aInst.pClass->IsDefault( pNode->aInst ) )
325 0 : fprintf( fOutput, "Default" );
326 : else
327 : pNode->aInst.pClass->WriteSrcHeader(
328 : pNode->aInst, fOutput,
329 0 : pTC, nTab, aId, pVarName );
330 0 : return;
331 : }
332 : }
333 :
334 0 : if( IsDefault( rInst ) )
335 0 : fprintf( fOutput, "Default" );
336 : else
337 : {
338 0 : RSCINST aSuper( GetSuperClass(), rInst.pData );
339 : aSuper.pClass->WriteSrcHeader( aSuper, fOutput, pTC,
340 0 : nTab, aId, pVarName );
341 : }
342 0 : if( !pTC->IsSrsDefault() )
343 0 : WriteSrc( rInst, fOutput, pTC, nTab, pVarName );
344 : }
345 :
346 0 : static void WriteSrc( RscInstNode * pNode, FILE * fOutput, RscTypCont * pTC,
347 : sal_uInt32 nTab, const char * pVarName,
348 : CLASS_DATA pDfltData, RscConst * pTypeClass )
349 : {
350 0 : if( pNode )
351 : {
352 : WriteSrc( pNode->Left(), fOutput, pTC, nTab, pVarName,
353 0 : pDfltData, pTypeClass );
354 0 : if( !pNode->aInst.pClass->IsValueDefault( pNode->aInst, pDfltData ) )
355 : {
356 0 : fprintf( fOutput, ";\n" );
357 0 : for( sal_uInt32 n = 0; n < nTab; n++ )
358 0 : fputc( '\t', fOutput );
359 :
360 : Atom nIdxId;
361 0 : pTypeClass->GetValueConst( pNode->GetId(), &nIdxId );
362 0 : fprintf( fOutput, "%s[ %s ] = ", pVarName, pHS->getString( nIdxId ).getStr() );
363 : pNode->aInst.pClass->WriteSrcHeader( pNode->aInst, fOutput, pTC,
364 0 : nTab, RscId(), pVarName );
365 : }
366 : WriteSrc( pNode->Right(), fOutput, pTC, nTab, pVarName,
367 0 : pDfltData, pTypeClass );
368 : }
369 0 : }
370 :
371 0 : void RscArray::WriteSrcArray( const RSCINST & rInst, FILE * fOutput,
372 : RscTypCont * pTC, sal_uInt32 nTab,
373 : const char * pVarName )
374 : {
375 : RscArrayInst * pClassData;
376 :
377 0 : pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
378 :
379 : ::WriteSrc( pClassData->pNode, fOutput, pTC, nTab, pVarName,
380 0 : rInst.pData, pTypeClass );
381 0 : };
382 :
383 0 : void RscArray::WriteSrc( const RSCINST & rInst, FILE * fOutput,
384 : RscTypCont * pTC, sal_uInt32 nTab,
385 : const char * pVarName )
386 : {
387 0 : WriteSrcArray( rInst, fOutput, pTC, nTab, pVarName );
388 0 : }
389 :
390 0 : ERRTYPE RscArray::WriteRc( const RSCINST & rInst, RscWriteRc & rMem,
391 : RscTypCont * pTC, sal_uInt32 nDeep, bool bExtra )
392 : {
393 0 : ERRTYPE aError;
394 : RscArrayInst * pClassData;
395 0 : RscInstNode * pNode = NULL;
396 :
397 0 : pClassData = (RscArrayInst *)(rInst.pData + nOffInstData);
398 :
399 0 : if( pClassData->pNode )
400 : {
401 : #if OSL_DEBUG_LEVEL > 2
402 : fprintf( stderr, "RscArray::WriteRc: Fallback " );
403 : #endif
404 0 : std::vector< sal_uInt32 >::const_iterator it;
405 0 : for( it = pTC->GetFallbacks().begin(); !pNode && it != pTC->GetFallbacks().end(); ++it )
406 : {
407 0 : pNode = pClassData->pNode->Search( *it );
408 : #if OSL_DEBUG_LEVEL > 2
409 : fprintf( stderr, " 0x%hx", *it );
410 : #endif
411 : }
412 : #if OSL_DEBUG_LEVEL > 2
413 : fprintf( stderr, "\n" );
414 : #endif
415 : }
416 :
417 0 : if( pNode )
418 0 : aError = pNode->aInst.pClass->WriteRc( pNode->aInst, rMem, pTC,
419 0 : nDeep, bExtra );
420 : else
421 0 : aError = RscTop::WriteRc( rInst, rMem, pTC, nDeep, bExtra );
422 :
423 0 : return aError;
424 : }
425 :
426 0 : RscClassArray::RscClassArray( Atom nId, sal_uInt32 nTypeId, RscTop * pSuper,
427 : RscEnum * pTypeCl )
428 0 : : RscArray( nId, nTypeId, pSuper, pTypeCl )
429 : {
430 0 : }
431 :
432 0 : RscClassArray::~RscClassArray()
433 : {
434 0 : }
435 :
436 0 : void RscClassArray::WriteSrcHeader( const RSCINST & rInst, FILE * fOutput,
437 : RscTypCont * pTC, sal_uInt32 nTab,
438 : const RscId & aId, const char * pName )
439 : {
440 0 : RscArray::WriteSrcHeader( rInst, fOutput, pTC, nTab, aId, pName );
441 0 : }
442 :
443 0 : void RscClassArray::WriteSrc( const RSCINST & rInst, FILE * fOutput,
444 : RscTypCont * pTC, sal_uInt32 nTab,
445 : const char * pVarName )
446 : {
447 0 : RscArray::WriteSrc( rInst, fOutput, pTC, nTab, pVarName );
448 0 : }
449 :
450 0 : ERRTYPE RscClassArray::WriteRcHeader( const RSCINST & rInst, RscWriteRc & aMem,
451 : RscTypCont * pTC, const RscId & aId,
452 : sal_uInt32 nDeep, bool bExtra )
453 : {
454 : // Eigenen Typ schreiben
455 0 : return GetSuperClass()->WriteRcHeader( rInst, aMem, pTC, aId,
456 0 : nDeep, bExtra );
457 : }
458 :
459 0 : RscLangArray::RscLangArray( Atom nId, sal_uInt32 nTypeId, RscTop * pSuper,
460 : RscEnum * pTypeCl )
461 0 : : RscArray( nId, nTypeId, pSuper, pTypeCl )
462 : {
463 0 : }
464 :
465 0 : RSCCLASS_TYPE RscLangArray::GetClassType() const
466 : {
467 0 : if( GetSuperClass() )
468 0 : return GetSuperClass()->GetClassType();
469 : else
470 0 : return RscArray::GetClassType();
471 :
472 : }
473 :
474 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|