Update ooo320-m1
[ooovba.git] / tools / source / communi / geninfo.cxx
blob9c94e432948166d9516361133f9967012788838c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: geninfo.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_tools.hxx"
33 #include "tools/geninfo.hxx"
34 #include <stdio.h>
37 // class GenericInformation
40 /*****************************************************************************/
41 GenericInformation::GenericInformation( const ByteString &rKey,
42 const ByteString &rValue,
43 GenericInformationList *pParentList,
44 GenericInformationList *pSubInfos )
45 /*****************************************************************************/
46 : ByteString( rKey ),
47 sValue( rValue ),
48 pInfoList( pSubInfos ),
49 pParent( pParentList )
51 // if a ParentList exists, insert this object into it
52 if ( pParent )
53 pParent->InsertInfo( this );
54 // make myself owner of pInfoList
55 if ( pInfoList )
56 pInfoList->SetOwner( this );
59 /*****************************************************************************/
60 GenericInformation::GenericInformation( const GenericInformation& rInf,
61 BOOL bCopySubs)
62 /*****************************************************************************/
63 : ByteString( rInf ),
64 sValue( rInf.sValue ),
65 pInfoList( 0L ),
66 pParent(NULL)
68 if(bCopySubs && rInf.pInfoList)
69 pInfoList = new GenericInformationList(*rInf.pInfoList, this);
72 /*****************************************************************************/
73 GenericInformation::~GenericInformation()
74 /*****************************************************************************/
76 // remove pInfoList and all childs out of memory
77 delete pInfoList;
78 pInfoList = 0;
80 // remove this Info out of ParentList
81 if ( pParent )
82 pParent->RemoveInfo( this );
85 /*****************************************************************************/
86 BOOL GenericInformation::InsertSubInfo( GenericInformation *pInfo )
87 /*****************************************************************************/
89 return ( pInfoList && pInfoList->InsertInfo( pInfo ));
92 /*****************************************************************************/
93 BOOL GenericInformation::InsertSubInfo( const ByteString &rPathKey, const ByteString &rValue,
94 BOOL bSearchByPath, BOOL bNewPath )
95 /*****************************************************************************/
97 return (pInfoList && pInfoList->InsertInfo( rPathKey, rValue, bSearchByPath, bNewPath ));
100 /*****************************************************************************/
101 void GenericInformation::RemoveSubInfo( GenericInformation *pInfo,
102 BOOL bDelete )
103 /*****************************************************************************/
105 pInfoList->RemoveInfo( pInfo, bDelete );
108 /*****************************************************************************/
109 //void GenericInformation::RemoveSelf( BOOL bDelete )
110 /*****************************************************************************/
112 if ( pParent )
113 pParent->RemoveInfo( this, bDelete ); // loescht sich aus der Liste vom Parent und
114 // bei Bedarf auch mit obiger Methode alle Sublisten
116 // loescht sich bei Bedarf auch selbst
117 if ( bDelete )
118 delete this;
122 /*****************************************************************************/
123 GenericInformation *GenericInformation::GetSubInfo( ByteString &rKey,
124 BOOL bSearchByPath,
125 BOOL bCreatePath )
126 /*****************************************************************************/
128 if ( !pInfoList && bCreatePath )
129 pInfoList = new GenericInformationList( this );
130 if ( pInfoList )
131 return pInfoList->GetInfo( rKey, bSearchByPath, bCreatePath );
132 return NULL;
137 // class GenericInformationList
140 /*****************************************************************************/
141 GenericInformationList::GenericInformationList( GenericInformation *pParent )
142 /*****************************************************************************/
143 : pOwner( pParent )
147 /*****************************************************************************/
148 GenericInformationList::GenericInformationList(const GenericInformationList& rList,
149 GenericInformation *pParent)
150 /*****************************************************************************/
151 : GenericInformationList_Impl()
153 USHORT i;
154 GenericInformation* pTemp,*pWork;
156 pOwner = pParent;
158 for(i=0;i<rList.Count();i++)
160 pTemp = rList.GetObject(i);
161 pWork = new GenericInformation(*pTemp,TRUE);
163 Insert(pWork,LIST_APPEND);
167 /*****************************************************************************/
168 GenericInformationList::~GenericInformationList()
169 /*****************************************************************************/
171 // delete all Informations stored in this List
172 // ### GH: Hier werden dann wohl etwa die H�lfte der Eintr�ge gel�scht
173 /* for ( ULONG i = 0; i < Count(); i++ ) {
174 GetObject( i )->ListDeleted();
175 delete GetObject( i );
176 Remove( i );*/
177 // Neue Variante:
178 while ( Count() ) {
179 GetObject( 0 )->ListDeleted();
180 delete GetObject( 0 );
181 Remove( (ULONG)0 );
185 /*****************************************************************************/
186 GenericInformation *GenericInformationList::Search( ULONG &rPos, ByteString sKey,
187 ULONG nStart, ULONG nEnd )
188 /*****************************************************************************/
190 if ( Count() == 0 ) {
191 rPos = 0;
192 return NULL;
195 if ( nStart == nEnd ) {
196 rPos = nStart;
197 ByteString sCandidate = ByteString( *GetObject( nStart ));
198 if ( sCandidate.ToUpperAscii() == sKey.ToUpperAscii()) {
199 return GetObject( nStart ); // found !!!
201 else {
202 // requested key not found
203 return NULL;
207 // search binary in existing list
208 ULONG nActPos = nStart + (( nEnd - nStart ) / 2 );
209 rPos = nActPos;
210 ByteString sCandidate = ByteString( *GetObject( nActPos ));
212 if ( sCandidate.ToUpperAscii() == sKey.ToUpperAscii())
213 return GetObject( nActPos ); // found !!!
215 // split the list at ActPos
216 if ( sCandidate < sKey )
217 return Search( rPos, sKey, nActPos + 1, nEnd );
218 else
219 return Search( rPos, sKey, nStart, nActPos );
222 /*****************************************************************************/
223 GenericInformation *GenericInformationList::GetInfo( ByteString &rKey,
224 BOOL bSearchByPath,
225 BOOL bCreatePath )
226 /*****************************************************************************/
229 rKey.EraseLeadingChars( '/' );
230 rKey.EraseTrailingChars( '/' );
232 ByteString sKey;
233 if ( bSearchByPath )
234 sKey = rKey.GetToken( 0, '/' );
235 else
236 sKey = rKey;
238 ULONG nPos = 0;
239 GenericInformation *pReturnInfo = Search( nPos, sKey, 0, Count() - 1 );
240 /* wenn kein Searchpath gesetzt und kein Returninfo vorhanden,
241 * gib NULL zurueck
242 * wenn Searchpath gesetzt und returninfo vorhanden,
243 * suche weiter nach unten
244 * wenn searchpath gesetzt kein returninfo vorhanden und newpath gesetzt,
245 * mache neues Verzeichniss
247 USHORT nTokenCount = rKey.GetTokenCount('/');
248 // search for next key of path in next level of tree
249 if ( bSearchByPath && (nTokenCount > 1)) {
250 ByteString sPath = ByteString(rKey.Copy( sKey.Len() + 1 ));
251 if ( !pReturnInfo ) { // wenn kein Return, dann muss man es anlegen
252 if ( !bCreatePath ) // wenn aber kein Create, dann nicht anlegen
253 return NULL;
254 pReturnInfo = new GenericInformation( sKey, "", this, NULL);
255 pReturnInfo->SetSubList( new GenericInformationList( pReturnInfo ));
257 return pReturnInfo->GetSubInfo( sPath, TRUE, bCreatePath );
259 if ( !pReturnInfo && bCreatePath ) {
260 pReturnInfo = new GenericInformation ( sKey, "", this, NULL);
263 return pReturnInfo; // kann durchaus NULL sein.
266 /*****************************************************************************/
267 ULONG GenericInformationList::InsertSorted( GenericInformation *pInfo,
268 BOOL bOverwrite,
269 ULONG nStart, ULONG nEnd )
270 /*****************************************************************************/
272 if ( Count() == 0 ) {
273 // empty list, so insert at first pos
274 Insert( pInfo, LIST_APPEND );
275 return 0;
278 ByteString sKey( pInfo->GetBuffer());
279 sKey.ToUpperAscii();
281 // Check to sppeed up reading a (partially) sorted list
282 if ( nStart == 0 && Count()-1 == nEnd )
284 ByteString sCandidate( *GetObject( nEnd ));
285 if ( sCandidate.ToUpperAscii() < sKey )
287 Insert( pInfo, LIST_APPEND );
288 return nEnd+1;
292 // ### GH: dieser Block schein �berfl�ssig zu sein
293 if ( Count() == 1 ) {
294 ByteString sCandidate( *GetObject( 0 ));
295 if ( sCandidate.ToUpperAscii() == sKey ) {
296 // key allready exists in list
297 if ( bOverwrite )
298 Replace( pInfo, ULONG(0)); // ### Laut NF scheint hier ein Memory Leak zu sein
299 return 0;
301 else if ( sCandidate > sKey ) {
302 Insert( pInfo, ULONG(0));
303 return 0;
305 else {
306 Insert( pInfo, LIST_APPEND );
307 return 1;
310 // ### GH: /ENDE/ dieser Block schein �berfl�ssig zu sein
312 ULONG nActPos = nStart + (( nEnd - nStart ) / 2 );
313 ByteString sCandidate = ByteString( *GetObject( nActPos ));
315 if ( sCandidate.ToUpperAscii() == sKey ) {
316 // key allready exists in list
317 if ( bOverwrite )
318 Replace( pInfo, nActPos ); // ### Laut NF scheint hier ein Memory Leak zu sein
319 return nActPos;
322 if ( nStart == nEnd ) {
323 // now more ways to search for key -> insert here
324 if ( sCandidate > sKey ) {
325 Insert( pInfo, nStart );
326 return nStart;
328 else {
329 Insert( pInfo, nStart + 1 );
330 return ( nStart + 1 );
334 if ( nActPos == Count() - 1 ) {
335 // reached end of list -> insert here
336 Insert( pInfo, LIST_APPEND );
337 return ( nActPos + 1 );
340 ByteString sSecondCand = ByteString( *GetObject( nActPos + 1 ));
341 if (( sCandidate < sKey ) && ( sSecondCand.ToUpperAscii() > sKey )) {
342 // optimal position to insert object
343 Insert( pInfo, nActPos + 1 );
344 return ( nActPos + 1 );
347 if ( sCandidate < sKey )
348 return InsertSorted( pInfo, bOverwrite, nActPos + 1, nEnd );
349 else
350 return InsertSorted( pInfo, bOverwrite, nStart, nActPos );
353 /*****************************************************************************/
354 BOOL GenericInformationList::InsertInfo( GenericInformation *pInfo,
355 BOOL bOverwrite )
356 /*****************************************************************************/
358 if ( !pInfo->Len())
359 return FALSE;
361 InsertSorted( pInfo, bOverwrite, 0, Count() - 1 );
362 return TRUE;
366 /*****************************************************************************/
367 BOOL GenericInformationList::InsertInfo( const ByteString &rPathKey, const ByteString &rValue,
368 BOOL bSearchByPath, BOOL bNewPath )
369 /*****************************************************************************/
371 GenericInformation *pInfo;
372 ByteString sPathKey ( rPathKey );
373 sPathKey.EraseLeadingChars( '/' );
374 sPathKey.EraseTrailingChars( '/' );
376 pInfo = GetInfo( sPathKey, bSearchByPath, bNewPath );
378 if ( pInfo ) {
379 pInfo->SetValue( rValue );
380 return TRUE;
382 return FALSE;
385 /*****************************************************************************/
386 void GenericInformationList::RemoveInfo( GenericInformation *pInfo,
387 BOOL bDelete )
388 /*****************************************************************************/
390 Remove( pInfo );
391 if ( bDelete )
392 delete pInfo;
393 /* if ( Count() == 0 && pOwner ) // Leere Listen entfernen;
395 SetOwner( NULL );
396 delete this;
397 } Rausgepatched by GH */
400 GenericInformation* GenericInformationList::SetOwner( GenericInformation *pNewOwner )
402 GenericInformation *pOldOwner = pOwner;
403 if ( pOwner ) // bei parent austragen;
404 pOwner->SetSubList( NULL );
405 if ( pNewOwner )
406 pNewOwner->SetSubList( this );
407 pOwner = pNewOwner;
408 return pOldOwner;