xref: /AOO41X/main/tools/source/communi/geninfo.cxx (revision 89b56da77b74925c286b3e777681ba8dda16bf41)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_tools.hxx"
26 #include "tools/geninfo.hxx"
27 #include <stdio.h>
28 
29 //
30 // class GenericInformation
31 //
32 
33 /*****************************************************************************/
GenericInformation(const ByteString & rKey,const ByteString & rValue,GenericInformationList * pParentList,GenericInformationList * pSubInfos)34 GenericInformation::GenericInformation( const ByteString &rKey,
35                         const ByteString &rValue,
36                         GenericInformationList *pParentList,
37                         GenericInformationList *pSubInfos )
38 /*****************************************************************************/
39                 : ByteString( rKey ),
40                 sValue( rValue ),
41                 pInfoList( pSubInfos ),
42                 pParent( pParentList )
43 {
44     // if a ParentList exists, insert this object into it
45     if ( pParent )
46         pParent->InsertInfo( this );
47     // make myself owner of pInfoList
48     if ( pInfoList )
49         pInfoList->SetOwner( this );
50 }
51 
52 /*****************************************************************************/
GenericInformation(const GenericInformation & rInf,sal_Bool bCopySubs)53 GenericInformation::GenericInformation( const GenericInformation& rInf,
54                                         sal_Bool bCopySubs)
55 /*****************************************************************************/
56                 : ByteString( rInf ),
57                 sValue( rInf.sValue ),
58                 pInfoList( 0L ),
59                 pParent(NULL)
60 {
61     if(bCopySubs && rInf.pInfoList)
62         pInfoList = new GenericInformationList(*rInf.pInfoList, this);
63 }
64 
65 /*****************************************************************************/
~GenericInformation()66 GenericInformation::~GenericInformation()
67 /*****************************************************************************/
68 {
69     // remove pInfoList and all childs out of memory
70     delete pInfoList;
71     pInfoList = 0;
72 
73     // remove this Info out of ParentList
74     if ( pParent )
75         pParent->RemoveInfo( this );
76 }
77 
78 /*****************************************************************************/
InsertSubInfo(GenericInformation * pInfo)79 sal_Bool GenericInformation::InsertSubInfo( GenericInformation *pInfo )
80 /*****************************************************************************/
81 {
82     return ( pInfoList && pInfoList->InsertInfo( pInfo ));
83 }
84 
85 /*****************************************************************************/
InsertSubInfo(const ByteString & rPathKey,const ByteString & rValue,sal_Bool bSearchByPath,sal_Bool bNewPath)86 sal_Bool GenericInformation::InsertSubInfo( const ByteString &rPathKey, const ByteString &rValue,
87                     sal_Bool bSearchByPath, sal_Bool bNewPath )
88 /*****************************************************************************/
89 {
90   return (pInfoList && pInfoList->InsertInfo( rPathKey, rValue, bSearchByPath, bNewPath ));
91 }
92 
93 /*****************************************************************************/
RemoveSubInfo(GenericInformation * pInfo,sal_Bool bDelete)94 void GenericInformation::RemoveSubInfo( GenericInformation *pInfo,
95                             sal_Bool bDelete )
96 /*****************************************************************************/
97 {
98     pInfoList->RemoveInfo( pInfo, bDelete );
99 }
100 
101 /*****************************************************************************/
102 //void GenericInformation::RemoveSelf( sal_Bool bDelete )
103 /*****************************************************************************/
104 /*{
105   if ( pParent )
106     pParent->RemoveInfo( this, bDelete ); // loescht sich aus der Liste vom Parent und
107   // bei Bedarf auch mit obiger Methode alle Sublisten
108 
109   // loescht sich bei Bedarf auch selbst
110     if ( bDelete )
111     delete this;
112 }
113 */
114 
115 /*****************************************************************************/
GetSubInfo(ByteString & rKey,sal_Bool bSearchByPath,sal_Bool bCreatePath)116 GenericInformation *GenericInformation::GetSubInfo( ByteString &rKey,
117                         sal_Bool bSearchByPath,
118                             sal_Bool bCreatePath )
119 /*****************************************************************************/
120 {
121   if ( !pInfoList && bCreatePath )
122     pInfoList = new GenericInformationList( this );
123   if ( pInfoList )
124     return pInfoList->GetInfo( rKey, bSearchByPath, bCreatePath );
125   return NULL;
126 }
127 
128 
129 //
130 // class GenericInformationList
131 //
132 
133 /*****************************************************************************/
GenericInformationList(GenericInformation * pParent)134 GenericInformationList::GenericInformationList( GenericInformation *pParent )
135 /*****************************************************************************/
136                 : pOwner( pParent )
137 {
138 }
139 
140 /*****************************************************************************/
GenericInformationList(const GenericInformationList & rList,GenericInformation * pParent)141 GenericInformationList::GenericInformationList(const GenericInformationList& rList,
142                             GenericInformation *pParent)
143 /*****************************************************************************/
144     : GenericInformationList_Impl()
145 {
146     sal_uInt16 i;
147     GenericInformation* pTemp,*pWork;
148 
149     pOwner = pParent;
150 
151     for(i=0;i<rList.Count();i++)
152     {
153         pTemp = rList.GetObject(i);
154         pWork = new GenericInformation(*pTemp,sal_True);
155 
156         Insert(pWork,LIST_APPEND);
157     }
158 }
159 
160 /*****************************************************************************/
~GenericInformationList()161 GenericInformationList::~GenericInformationList()
162 /*****************************************************************************/
163 {
164     // delete all Informations stored in this List
165     // ### GH: Hier werden dann wohl etwa die H�lfte der Eintr�ge gel�scht
166 /*  for ( sal_uIntPtr i = 0; i < Count(); i++ ) {
167         GetObject( i )->ListDeleted();
168         delete GetObject( i );
169         Remove( i );*/
170     // Neue Variante:
171     while ( Count() ) {
172         GetObject( 0 )->ListDeleted();
173         delete GetObject( 0 );
174         Remove( (sal_uIntPtr)0 );
175     }
176 }
177 
178 /*****************************************************************************/
Search(sal_uIntPtr & rPos,ByteString sKey,sal_uIntPtr nStart,sal_uIntPtr nEnd)179 GenericInformation *GenericInformationList::Search( sal_uIntPtr &rPos, ByteString sKey,
180                                                    sal_uIntPtr nStart, sal_uIntPtr nEnd )
181 /*****************************************************************************/
182 {
183     if ( Count() == 0 ) {
184         rPos = 0;
185         return NULL;
186     }
187 
188     if ( nStart == nEnd ) {
189         rPos = nStart;
190         ByteString sCandidate = ByteString( *GetObject( nStart ));
191         if ( sCandidate.ToUpperAscii() == sKey.ToUpperAscii()) {
192             return GetObject( nStart ); // found !!!
193         }
194         else {
195             // requested key not found
196             return NULL;
197         }
198     }
199 
200     // search binary in existing list
201     sal_uIntPtr nActPos = nStart + (( nEnd - nStart ) / 2 );
202     rPos = nActPos;
203     ByteString sCandidate = ByteString( *GetObject( nActPos ));
204 
205     if ( sCandidate.ToUpperAscii()  == sKey.ToUpperAscii())
206         return GetObject( nActPos ); // found !!!
207 
208     // split the list at ActPos
209     if ( sCandidate < sKey )
210         return Search( rPos, sKey, nActPos + 1, nEnd );
211     else
212         return Search( rPos, sKey, nStart, nActPos );
213 }
214 
215 /*****************************************************************************/
GetInfo(ByteString & rKey,sal_Bool bSearchByPath,sal_Bool bCreatePath)216 GenericInformation *GenericInformationList::GetInfo( ByteString &rKey,
217                              sal_Bool bSearchByPath,
218                              sal_Bool bCreatePath )
219 /*****************************************************************************/
220 {
221 
222     rKey.EraseLeadingChars( '/' );
223     rKey.EraseTrailingChars( '/' );
224 
225     ByteString sKey;
226     if ( bSearchByPath )
227         sKey = rKey.GetToken( 0, '/' );
228     else
229         sKey = rKey;
230 
231     sal_uIntPtr nPos = 0;
232     GenericInformation *pReturnInfo = Search( nPos, sKey, 0, Count() - 1 );
233     /* wenn kein Searchpath gesetzt und kein Returninfo vorhanden,
234      *   gib NULL zurueck
235      * wenn Searchpath gesetzt und returninfo vorhanden,
236      *   suche weiter nach unten
237      * wenn searchpath gesetzt kein returninfo vorhanden und newpath gesetzt,
238      *   mache neues Verzeichniss
239      */
240     sal_uInt16 nTokenCount = rKey.GetTokenCount('/');
241     // search for next key of path in next level of tree
242     if ( bSearchByPath && (nTokenCount > 1)) {
243       ByteString sPath = ByteString(rKey.Copy( sKey.Len() + 1 ));
244       if ( !pReturnInfo ) { // wenn kein Return, dann muss man es anlegen
245         if ( !bCreatePath ) // wenn aber kein Create, dann nicht anlegen
246           return NULL;
247         pReturnInfo = new GenericInformation( sKey, "", this, NULL);
248         pReturnInfo->SetSubList( new GenericInformationList( pReturnInfo ));
249       }
250       return pReturnInfo->GetSubInfo( sPath, sal_True, bCreatePath );
251     }
252     if ( !pReturnInfo && bCreatePath ) {
253       pReturnInfo = new GenericInformation ( sKey, "", this, NULL);
254     }
255 
256     return pReturnInfo; // kann durchaus NULL sein.
257 }
258 
259 /*****************************************************************************/
InsertSorted(GenericInformation * pInfo,sal_Bool bOverwrite,sal_uIntPtr nStart,sal_uIntPtr nEnd)260 sal_uIntPtr GenericInformationList::InsertSorted( GenericInformation *pInfo,
261                                         sal_Bool bOverwrite,
262                                         sal_uIntPtr nStart, sal_uIntPtr nEnd )
263 /*****************************************************************************/
264 {
265     if ( Count() == 0 ) {
266         // empty list, so insert at first pos
267         Insert( pInfo, LIST_APPEND );
268         return 0;
269     }
270 
271     ByteString sKey( pInfo->GetBuffer());
272     sKey.ToUpperAscii();
273 
274     // Check to sppeed up reading a (partially) sorted list
275     if ( nStart == 0 && Count()-1 == nEnd )
276     {
277         ByteString sCandidate( *GetObject( nEnd ));
278         if ( sCandidate.ToUpperAscii() < sKey )
279         {
280             Insert( pInfo, LIST_APPEND );
281             return nEnd+1;
282         }
283     }
284 
285 // ### GH: dieser Block schein �berfl�ssig zu sein
286     if ( Count() == 1 ) {
287         ByteString sCandidate( *GetObject( 0 ));
288         if ( sCandidate.ToUpperAscii() == sKey ) {
289             // key allready exists in list
290             if ( bOverwrite )
291                 Replace( pInfo, sal_uIntPtr(0));    // ### Laut NF scheint hier ein Memory Leak zu sein
292             return 0;
293         }
294         else if ( sCandidate > sKey ) {
295             Insert( pInfo, sal_uIntPtr(0));
296             return 0;
297         }
298         else {
299             Insert( pInfo, LIST_APPEND );
300             return 1;
301         }
302     }
303 // ### GH: /ENDE/ dieser Block schein �berfl�ssig zu sein
304 
305     sal_uIntPtr nActPos = nStart + (( nEnd - nStart ) / 2 );
306     ByteString sCandidate = ByteString( *GetObject( nActPos ));
307 
308     if ( sCandidate.ToUpperAscii() == sKey ) {
309         // key allready exists in list
310         if ( bOverwrite )
311             Replace( pInfo, nActPos );  // ### Laut NF scheint hier ein Memory Leak zu sein
312         return nActPos;
313     }
314 
315     if ( nStart == nEnd ) {
316         // now more ways to search for key -> insert here
317         if ( sCandidate > sKey ) {
318             Insert( pInfo, nStart );
319             return nStart;
320         }
321         else {
322             Insert( pInfo, nStart + 1 );
323             return ( nStart + 1 );
324         }
325     }
326 
327     if ( nActPos == Count() - 1 ) {
328         // reached end of list -> insert here
329         Insert( pInfo, LIST_APPEND );
330         return ( nActPos + 1 );
331     }
332 
333     ByteString sSecondCand = ByteString( *GetObject( nActPos + 1 ));
334     if (( sCandidate < sKey ) && ( sSecondCand.ToUpperAscii() > sKey )) {
335         // optimal position to insert object
336         Insert( pInfo, nActPos + 1 );
337         return ( nActPos + 1 );
338     }
339 
340     if ( sCandidate < sKey )
341         return InsertSorted( pInfo, bOverwrite, nActPos + 1, nEnd );
342     else
343         return InsertSorted( pInfo, bOverwrite, nStart, nActPos );
344 }
345 
346 /*****************************************************************************/
InsertInfo(GenericInformation * pInfo,sal_Bool bOverwrite)347 sal_Bool GenericInformationList::InsertInfo( GenericInformation *pInfo,
348                                 sal_Bool bOverwrite )
349 /*****************************************************************************/
350 {
351     if ( !pInfo->Len())
352         return sal_False;
353 
354     InsertSorted( pInfo, bOverwrite, 0, Count() - 1 );
355     return sal_True;
356 }
357 
358 
359 /*****************************************************************************/
InsertInfo(const ByteString & rPathKey,const ByteString & rValue,sal_Bool bSearchByPath,sal_Bool bNewPath)360 sal_Bool GenericInformationList::InsertInfo( const ByteString &rPathKey, const ByteString &rValue,
361                      sal_Bool bSearchByPath, sal_Bool bNewPath )
362 /*****************************************************************************/
363 {
364   GenericInformation *pInfo;
365   ByteString sPathKey ( rPathKey );
366   sPathKey.EraseLeadingChars( '/' );
367   sPathKey.EraseTrailingChars( '/' );
368 
369   pInfo = GetInfo( sPathKey, bSearchByPath, bNewPath );
370 
371   if ( pInfo ) {
372     pInfo->SetValue( rValue );
373     return sal_True;
374   }
375   return sal_False;
376 }
377 
378 /*****************************************************************************/
RemoveInfo(GenericInformation * pInfo,sal_Bool bDelete)379 void GenericInformationList::RemoveInfo( GenericInformation *pInfo,
380                                 sal_Bool bDelete )
381 /*****************************************************************************/
382 {
383     Remove( pInfo );
384     if ( bDelete )
385         delete pInfo;
386 /*  if ( Count() == 0 && pOwner )   // Leere Listen entfernen;
387     {
388         SetOwner( NULL );
389         delete this;
390     } Rausgepatched by GH */
391 }
392 
SetOwner(GenericInformation * pNewOwner)393 GenericInformation* GenericInformationList::SetOwner( GenericInformation *pNewOwner )
394 {
395     GenericInformation *pOldOwner = pOwner;
396     if ( pOwner )   // bei parent austragen;
397         pOwner->SetSubList( NULL );
398     if ( pNewOwner )
399         pNewOwner->SetSubList( this );
400     pOwner = pNewOwner;
401     return pOldOwner;
402 }
403 
404 
405