1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: geninfo.cxx,v $
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"
37 // class GenericInformation
40 /*****************************************************************************/
41 GenericInformation::GenericInformation( const ByteString
&rKey
,
42 const ByteString
&rValue
,
43 GenericInformationList
*pParentList
,
44 GenericInformationList
*pSubInfos
)
45 /*****************************************************************************/
48 pInfoList( pSubInfos
),
49 pParent( pParentList
)
51 // if a ParentList exists, insert this object into it
53 pParent
->InsertInfo( this );
54 // make myself owner of pInfoList
56 pInfoList
->SetOwner( this );
59 /*****************************************************************************/
60 GenericInformation::GenericInformation( const GenericInformation
& rInf
,
62 /*****************************************************************************/
64 sValue( rInf
.sValue
),
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
80 // remove this Info out of ParentList
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
,
103 /*****************************************************************************/
105 pInfoList
->RemoveInfo( pInfo
, bDelete
);
108 /*****************************************************************************/
109 //void GenericInformation::RemoveSelf( BOOL bDelete )
110 /*****************************************************************************/
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
122 /*****************************************************************************/
123 GenericInformation
*GenericInformation::GetSubInfo( ByteString
&rKey
,
126 /*****************************************************************************/
128 if ( !pInfoList
&& bCreatePath
)
129 pInfoList
= new GenericInformationList( this );
131 return pInfoList
->GetInfo( rKey
, bSearchByPath
, bCreatePath
);
137 // class GenericInformationList
140 /*****************************************************************************/
141 GenericInformationList::GenericInformationList( GenericInformation
*pParent
)
142 /*****************************************************************************/
147 /*****************************************************************************/
148 GenericInformationList::GenericInformationList(const GenericInformationList
& rList
,
149 GenericInformation
*pParent
)
150 /*****************************************************************************/
151 : GenericInformationList_Impl()
154 GenericInformation
* pTemp
,*pWork
;
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 );
179 GetObject( 0 )->ListDeleted();
180 delete GetObject( 0 );
185 /*****************************************************************************/
186 GenericInformation
*GenericInformationList::Search( ULONG
&rPos
, ByteString sKey
,
187 ULONG nStart
, ULONG nEnd
)
188 /*****************************************************************************/
190 if ( Count() == 0 ) {
195 if ( nStart
== nEnd
) {
197 ByteString sCandidate
= ByteString( *GetObject( nStart
));
198 if ( sCandidate
.ToUpperAscii() == sKey
.ToUpperAscii()) {
199 return GetObject( nStart
); // found !!!
202 // requested key not found
207 // search binary in existing list
208 ULONG nActPos
= nStart
+ (( nEnd
- nStart
) / 2 );
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
);
219 return Search( rPos
, sKey
, nStart
, nActPos
);
222 /*****************************************************************************/
223 GenericInformation
*GenericInformationList::GetInfo( ByteString
&rKey
,
226 /*****************************************************************************/
229 rKey
.EraseLeadingChars( '/' );
230 rKey
.EraseTrailingChars( '/' );
234 sKey
= rKey
.GetToken( 0, '/' );
239 GenericInformation
*pReturnInfo
= Search( nPos
, sKey
, 0, Count() - 1 );
240 /* wenn kein Searchpath gesetzt und kein Returninfo vorhanden,
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
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
,
269 ULONG nStart
, ULONG nEnd
)
270 /*****************************************************************************/
272 if ( Count() == 0 ) {
273 // empty list, so insert at first pos
274 Insert( pInfo
, LIST_APPEND
);
278 ByteString
sKey( pInfo
->GetBuffer());
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
);
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
298 Replace( pInfo
, ULONG(0)); // ### Laut NF scheint hier ein Memory Leak zu sein
301 else if ( sCandidate
> sKey
) {
302 Insert( pInfo
, ULONG(0));
306 Insert( pInfo
, LIST_APPEND
);
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
318 Replace( pInfo
, nActPos
); // ### Laut NF scheint hier ein Memory Leak zu sein
322 if ( nStart
== nEnd
) {
323 // now more ways to search for key -> insert here
324 if ( sCandidate
> sKey
) {
325 Insert( pInfo
, nStart
);
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
);
350 return InsertSorted( pInfo
, bOverwrite
, nStart
, nActPos
);
353 /*****************************************************************************/
354 BOOL
GenericInformationList::InsertInfo( GenericInformation
*pInfo
,
356 /*****************************************************************************/
361 InsertSorted( pInfo
, bOverwrite
, 0, Count() - 1 );
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
);
379 pInfo
->SetValue( rValue
);
385 /*****************************************************************************/
386 void GenericInformationList::RemoveInfo( GenericInformation
*pInfo
,
388 /*****************************************************************************/
393 /* if ( Count() == 0 && pOwner ) // Leere Listen entfernen;
397 } Rausgepatched by GH */
400 GenericInformation
* GenericInformationList::SetOwner( GenericInformation
*pNewOwner
)
402 GenericInformation
*pOldOwner
= pOwner
;
403 if ( pOwner
) // bei parent austragen;
404 pOwner
->SetSubList( NULL
);
406 pNewOwner
->SetSubList( this );