bump product version to 5.0.4.1
[LibreOffice.git] / rsc / source / res / rscmgr.cxx
blob1f8e941d079f3fe1a4b9c2680c11ba64e3ad50e0
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>
24 #include <ctype.h>
26 #include <rscmgr.hxx>
27 #include <rscdb.hxx>
29 RscMgr::RscMgr( Atom nId, sal_uInt32 nTypeId, RscTop * pSuperCl )
30 : RscClass( nId, nTypeId, pSuperCl )
34 sal_uInt32 RscMgr::Size()
36 return RscClass::Size() + ALIGNED_SIZE( sizeof( RscMgrInst ) );
39 RSCINST RscMgr::Create( RSCINST * pInst, const RSCINST & rDflt, bool bOwnClass )
41 RSCINST aInst;
42 RscMgrInst * pClassData;
44 if( !pInst )
46 aInst.pClass = this;
47 aInst.pData = static_cast<CLASS_DATA>(rtl_allocateMemory( Size() ));
49 else
50 aInst = *pInst;
52 if( !bOwnClass && rDflt.IsInst() )
53 bOwnClass = rDflt.pClass->InHierarchy( this );
55 RscClass::Create( &aInst, rDflt, bOwnClass );
57 pClassData = reinterpret_cast<RscMgrInst *>(aInst.pData + RscClass::Size() );
58 pClassData->Create();
60 if( bOwnClass )
62 RscMgrInst * pDfltData = reinterpret_cast<RscMgrInst *>(rDflt.pData + RscClass::Size());
63 *pClassData = *pDfltData;
66 return aInst;
69 void RscMgr::Destroy( const RSCINST & rInst )
71 RscMgrInst * pClassData;
73 RscClass::Destroy( rInst );
75 pClassData = reinterpret_cast<RscMgrInst *>(rInst.pData + RscClass::Size());
76 pClassData->Destroy();
79 void RscMgr::SetToDefault( const RSCINST & rInst )
81 RscMgrInst * pClassData;
83 pClassData = reinterpret_cast<RscMgrInst *>(rInst.pData + RscClass::Size());
84 pClassData->bDflt = true;
86 RscClass::SetToDefault( rInst );
89 bool RscMgr::IsDefault( const RSCINST & rInst )
91 RscMgrInst * pClassData;
93 pClassData = reinterpret_cast<RscMgrInst *>(rInst.pData + RscClass::Size());
94 if( !pClassData->bDflt )
95 return false;
97 return RscClass::IsDefault( rInst );
100 bool RscMgr::IsValueDefault( const RSCINST & rInst, CLASS_DATA pDef )
102 if( !RscClass::IsValueDefault( rInst, pDef ) )
103 return false;
105 if( pDef )
107 RscMgrInst * pClassData = reinterpret_cast<RscMgrInst *>(rInst.pData + RscClass::Size());
108 RscMgrInst * pDfltData = reinterpret_cast<RscMgrInst *>(pDef + RscClass::Size());
110 if( !pClassData->aRefId.IsId() && !pDfltData->aRefId.IsId() )
112 return true;
116 return false;
120 void RscMgr::WriteSrcHeader( const RSCINST & rInst, FILE * fOutput,
121 RscTypCont * pTC, sal_uInt32 nTab,
122 const RscId & rId, const char * pVarName )
124 RscMgrInst * pClassData;
125 sal_uInt32 i;
127 pClassData = reinterpret_cast<RscMgrInst *>(rInst.pData + RscClass::Size());
129 fprintf( fOutput, "%s %s",
130 pHS->getString( rInst.pClass->GetId() ).getStr(),
131 (rId.GetName()).getStr() );
133 if( pClassData->aRefId.IsId() )
134 fprintf( fOutput, ",%s", pClassData->aRefId.GetName().getStr() );
135 else
137 fprintf( fOutput, "\n" );
138 for( i = 0; i < nTab; i++ )
139 fputc( '\t', fOutput );
141 fprintf( fOutput, "{\n" );
143 rInst.pClass->WriteSrc( rInst, fOutput, pTC, nTab +1, pVarName );
145 RscClass::WriteSrc( rInst, fOutput, pTC, nTab +1, pVarName);
147 for( i = 0; i < nTab; i++ )
148 fputc( '\t', fOutput );
150 fprintf( fOutput, "}" );
154 void RscMgr::WriteSrc( const RSCINST &, FILE *, RscTypCont *, sal_uInt32,
155 const char * )
159 ERRTYPE RscMgr::WriteRcHeader( const RSCINST & rInst, RscWriteRc & rMem,
160 RscTypCont * pTC, const RscId &rId,
161 sal_uInt32 nDeep, bool bExtra )
163 RscMgrInst * pClassData;
164 ERRTYPE aError;
165 ObjNode * pObjNode = NULL;
167 pClassData = reinterpret_cast<RscMgrInst *>(rInst.pData + RscClass::Size());
169 if( pClassData->aRefId.IsId() )
171 //Erhoehen und abfragen um Endlosrekusion zu vermeiden
172 nDeep++;
173 if( nDeep > nRefDeep )
174 aError = ERR_REFTODEEP;
175 else
176 pObjNode = rInst.pClass->GetRefClass()->
177 GetObjNode( pClassData->aRefId );
179 if( !pObjNode && pTC )
181 OStringBuffer aMsg(pHS->getString(rInst.pClass->GetId()));
182 aMsg.append(' ').append(pClassData->aRefId.GetName());
183 aError = WRN_MGR_REFNOTFOUND;
184 pTC->pEH->Error(aError, rInst.pClass, rId, aMsg.getStr());
188 if( aError.IsOk() )
190 if( pObjNode )
192 RSCINST aRefI;
193 RscTop * pTmpRefClass = rInst.pClass->GetRefClass();
195 aRefI = RSCINST( rInst.pClass, pObjNode->GetRscObj() );
196 if( pTmpRefClass == rInst.pClass )
198 aError = aRefI.pClass->WriteRcHeader( aRefI, rMem, pTC,
199 rId, nDeep, bExtra );
201 else
203 RSCINST aRefInst = rInst.pClass->Create( NULL, aRefI );
204 aError = aRefI.pClass->WriteRcHeader( aRefInst, rMem, pTC,
205 rId, nDeep, bExtra );
206 pTmpRefClass->Destroy( aRefInst );
209 else
211 sal_uInt32 nOldSize;
212 sal_uInt32 nLocalSize;
214 nOldSize = rMem.IncSize( 16 /*sizeof( RSHEADER_TYPE )*/ );
216 aError = rInst.pClass->WriteRc( rInst, rMem, pTC, nDeep, bExtra );
217 if( aError.IsOk() )
218 aError = WriteInstRc( rInst, rMem, pTC, nDeep, bExtra );
219 nLocalSize = rMem.Size();
221 if( aError.IsOk() )
223 // RscClass wird uebersprungen
224 aError = RscTop::WriteRc( rInst, rMem, pTC, nDeep, bExtra );
228 // Definition der Struktur, aus denen die Resource aufgebaut ist
229 struct RSHEADER_TYPE{
230 RESOURCE_TYPE nRT; // Resource Typ
231 sal_uInt32 nRT; // Resource Typ
232 sal_uInt32 nGlobOff; // Globaler Offset
233 sal_uInt32 nLocalOff; // Lokaler Offset
236 sal_uInt32 nID = rId;
237 rMem.PutAt( nOldSize, nID );
238 rMem.PutAt( nOldSize +4, (sal_uInt32)rInst.pClass->GetTypId() );
239 rMem.PutAt( nOldSize +8, (sal_uInt32)(rMem.Size() - nOldSize) );
240 rMem.PutAt( nOldSize +12, (sal_uInt32)(nLocalSize - nOldSize) );
244 return aError;
247 ERRTYPE RscMgr::WriteRc( const RSCINST &, RscWriteRc &,
248 RscTypCont *, sal_uInt32, bool )
251 return ERR_OK;
254 bool RscMgr::IsConsistent( const RSCINST & rInst )
256 bool bRet;
257 RscMgrInst * pClassData;
259 bRet = RscClass::IsConsistent( rInst );
261 pClassData = reinterpret_cast<RscMgrInst *>(rInst.pData + RscClass::Size());
262 if( pClassData->aRefId.IsId() &&
263 ((pClassData->aRefId.GetNumber() < 1) ||
264 (pClassData->aRefId.GetNumber() > 0x7FFF) ||
265 IsToDeep( rInst ).IsError()) )
267 bRet = false;
270 return bRet;
273 ERRTYPE RscMgr::GetRef( const RSCINST & rInst, RscId * pRscId )
275 RscMgrInst * pClassData;
277 pClassData = reinterpret_cast<RscMgrInst *>(rInst.pData + RscClass::Size());
278 *pRscId = pClassData->aRefId;
279 return ERR_OK;
282 ERRTYPE RscMgr::IsToDeep( const RSCINST & rInst, sal_uInt32 nDeep )
284 RscMgrInst * pClassData;
285 RscId aOldId, aId;
286 ERRTYPE aError;
287 RSCINST aTmpI = rInst;
288 ObjNode * pObjNode;
290 pClassData = reinterpret_cast<RscMgrInst *>(rInst.pData + RscClass::Size());
292 while( aTmpI.IsInst() && (nDeep < nRefDeep) && aError.IsOk() )
294 // Referenz holen
295 aTmpI.pClass->GetRef( aTmpI, &aId );
296 // Referenziertes Objekt holen
297 pObjNode = aTmpI.pClass->GetObjNode( aId );
298 // Referenzierte Objekt gefunden ?
299 if( pObjNode )
301 aTmpI.pData = pObjNode->GetRscObj();
302 nDeep++;
304 else //aTmpI.IsInst() wird false, Schleife beenden
305 aTmpI.pData = NULL;
308 if( nDeep >= nRefDeep )
310 pClassData->aRefId = aOldId;
311 aError = ERR_REFTODEEP;
314 return aError;
317 ERRTYPE RscMgr::SetRef( const RSCINST & rInst, const RscId & rRefId )
319 RscMgrInst * pClassData;
320 RscId aOldId, aId;
321 ERRTYPE aError;
323 if( rRefId.IsId() &&
324 ((rRefId.GetNumber() < 1) ||
325 (rRefId.GetNumber() > 0x7FFF)) )
327 aError = ERR_IDRANGE;
329 else
331 pClassData = reinterpret_cast<RscMgrInst *>(rInst.pData + RscClass::Size());
332 aOldId = pClassData->aRefId;// Alten Wert merken
333 pClassData->aRefId = rRefId;// vorher eintragen,
334 // sonst Fehler bei rekursion
337 aError = IsToDeep( rInst );
338 if( aError.IsOk() )
339 pClassData->bDflt = false;
340 else
341 pClassData->aRefId = aOldId;
344 return aError;
347 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */