CWS-TOOLING: integrate CWS os146
[LibreOffice.git] / rsc / source / tools / rsctree.cxx
blobe719cc39548e4d909c0cf905e2df6a470fff031c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_rsc.hxx"
30 /****************** I N C L U D E S **************************************/
32 // C and C++ Includes.
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
37 // Programmabh�ngige Includes.
38 #include <tools/link.hxx>
39 #include <rsctree.hxx>
41 /****************** C O D E **********************************************/
43 /****************** B i N o d e ******************************************/
44 /*************************************************************************
46 |* BiNode::BiNode()
48 |* Beschreibung NAME.DOC
49 |* Ersterstellung MM 07.02.91
50 |* Letzte Aenderung MM 07.02.91
52 *************************************************************************/
53 BiNode::BiNode(){
54 pLeft = pRight = NULL;
57 /*************************************************************************
59 |* BiNode::~BiNode()
61 |* Beschreibung
62 |* Ersterstellung MM 07.02.91
63 |* Letzte Aenderung MM 07.02.91
65 *************************************************************************/
66 BiNode::~BiNode(){
69 /*************************************************************************
71 |* BiNode::EnumNodes()
73 |* Beschreibung
74 |* Ersterstellung MM 07.02.91
75 |* Letzte Aenderung MM 07.02.91
77 *************************************************************************/
78 void BiNode::EnumNodes( Link aLink ) const{
79 if( Left() )
80 Left()->EnumNodes( aLink );
81 aLink.Call( (BiNode *)this );
82 if( Right() )
83 Right()->EnumNodes( aLink );
86 /*************************************************************************
88 |* BiNode::ChangeDLListBTree()
90 |* Beschreibung
91 |* Ersterstellung MM 11.01.91
92 |* Letzte Aenderung MM 11.01.91
94 *************************************************************************/
95 BiNode * BiNode::ChangeDLListBTree( BiNode * pList ){
96 BiNode * pRightNode;
97 BiNode * pMiddle;
98 BiNode * pTmp;
99 sal_uInt32 nEle, i;
101 if( pList ){
102 while( pList->Left() )
103 pList = pList->Left();
104 pTmp = pList;
105 for( nEle = 0; pTmp->Right(); nEle++ )
106 pTmp = pTmp->Right();
107 pMiddle = pList;
108 if( nEle / 2 )
109 for( i = 0; i < (nEle / 2); i++ )
110 pMiddle = pMiddle->Right();
111 else
112 pList = (BiNode *)0;
114 if( NULL != (pTmp = pMiddle->Left()) ) // rechten Zeiger auf Null
115 pTmp->pRight = (BiNode *)0;
117 // linken Zeiger auf Null
118 if( NULL != (pRightNode = pMiddle->Right()) )
119 pRightNode->pLeft = (BiNode *)0;
121 pMiddle->pLeft = ChangeDLListBTree( pList );
122 pMiddle->pRight = ChangeDLListBTree( pRightNode );
124 return( pMiddle );
126 return( pList );
129 /*************************************************************************
131 |* BiNode::ChangeBTreeDLList()
133 |* Beschreibung
134 |* Ersterstellung MM 11.01.91
135 |* Letzte Aenderung MM 11.01.91
137 *************************************************************************/
138 BiNode * BiNode::ChangeBTreeDLList(){
139 BiNode * pList;
140 BiNode * pLL_RN; // linke Liste rechter Knoten
142 if( Right() ){
143 pList = Right()->ChangeBTreeDLList();
144 pRight = pList;
145 pList->pLeft = this;
147 pList = this;
148 if( Left() ){
149 pLL_RN = pList = Left()->ChangeBTreeDLList();
150 while( pLL_RN->Right() )
151 pLL_RN = pLL_RN->Right();
152 pLeft = pLL_RN;
153 pLL_RN->pRight = this;
155 return( pList );
158 /****************** N a m e N o d e **************************************/
159 /*************************************************************************
161 |* NameNode::Remove()
163 |* Beschreibung
164 |* Ersterstellung MM 10.07.91
165 |* Letzte Aenderung MM 10.07.91
167 *************************************************************************/
168 NameNode * NameNode::Remove( NameNode * pRemove ){
169 NameNode * pRoot = this;
170 NameNode * pParent = SearchParent( pRemove );
172 if( pParent ){
173 if( pParent->Left()
174 && (EQUAL == pRemove->Compare( pParent->Left() ) ) ){
175 pParent->pLeft = pRemove->Left();
176 if( pRemove->Right() )
177 pParent->Insert( pRemove->Right() );
179 else if( pParent->Right()
180 && (EQUAL == pRemove->Compare( pParent->Right() ) ) ){
181 pParent->pRight = pRemove->Right();
182 if( pRemove->Left() )
183 pParent->Insert( pRemove->Left() );
186 else if( EQUAL == this->Compare( pRemove ) ){
187 if( Right() ){
188 pRoot = Right();
189 if( Left() )
190 Right()->Insert( Left() );
192 else{
193 pRoot = Left();
196 pRemove->pLeft = pRemove->pRight = NULL;
198 return pRoot;
202 /*************************************************************************
204 |* NameNode::Compare
206 |* Beschreibung
207 |* Ersterstellung MM 10.07.91
208 |* Letzte Aenderung MM 13.07.91
210 *************************************************************************/
211 COMPARE NameNode::Compare( const NameNode * pCompare ) const{
212 if( (long)this < (long)pCompare )
213 return LESS;
214 else if( (long)this > (long)pCompare )
215 return GREATER;
216 else
217 return EQUAL;
220 COMPARE NameNode::Compare( const void * pCompare ) const{
221 if( (long)this < (long)pCompare )
222 return LESS;
223 else if( (long)this > (long)pCompare )
224 return GREATER;
225 else
226 return EQUAL;
229 /*************************************************************************
231 |* NameNode::SearchParent
233 |* Beschreibung
234 |* Ersterstellung MM 10.07.91
235 |* Letzte Aenderung MM 10.07.91
237 *************************************************************************/
238 NameNode* NameNode::SearchParent( const NameNode * pSearch ) const{
239 // search for a parent node.
240 // return a pointer to the parent node if found.
241 // otherwise return 0.
242 int nCmp = Compare( pSearch );
244 if( nCmp == GREATER ){
245 if( Left() ){
246 if( ((NameNode *)Left())->Compare( pSearch ) == EQUAL )
247 return (NameNode *)this;
248 return ((NameNode *)Left())->SearchParent( pSearch );
251 else if( nCmp == LESS ){
252 if( Right() ){
253 if( ((NameNode *)Right())->Compare( pSearch ) == EQUAL )
254 return (NameNode *)this;
255 return ((NameNode *)Right())->SearchParent( pSearch );
258 return( (NameNode *)NULL );
261 /*************************************************************************
263 |* NameNode::Search
265 |* Beschreibung
266 |* Ersterstellung MM 21.03.90
267 |* Letzte Aenderung MM 27.06.90
269 *************************************************************************/
270 NameNode* NameNode::Search( const NameNode * pSearch ) const{
271 // search for a node.
272 // return a pointer to the node if found.
273 // otherwise return 0.
274 int nCmp = Compare( pSearch );
276 if( nCmp == GREATER ){
277 if( Left() )
278 return ((NameNode *)Left())->Search( pSearch );
280 else if( nCmp == LESS ){
281 if( Right() )
282 return ((NameNode *)Right())->Search( pSearch );
284 else
285 return( (NameNode *)this );
287 return( NULL );
290 NameNode* NameNode::Search( const void * pSearch ) const{
291 // search for a node.
292 // return a pointer to the node if found.
293 // otherwise return 0.
294 int nCmp = Compare( pSearch );
296 if( nCmp == GREATER ){
297 if( Left() )
298 return ((NameNode *)Left())->Search( pSearch );
300 else if( nCmp == LESS ){
301 if( Right() )
302 return ((NameNode *)Right())->Search( pSearch );
304 else
305 return( (NameNode *)this );
307 return( NULL );
310 /*************************************************************************
312 |* NameNode::Insert()
314 |* Beschreibung NAME.DOC
315 |* Ersterstellung MM 11.01.91
316 |* Letzte Aenderung MM 11.01.91
318 *************************************************************************/
319 sal_Bool NameNode::Insert( NameNode * pTN, sal_uInt32* pnDepth ){
320 // Ein Knoten wird in den Baum eingefuegt
321 // Gibt es einen Knoten mit dem gleichen Namen, dann return sal_False
322 // sonst return sal_True. Der Knoten wird auf jeden Fall eingefuegt.
324 sal_Bool bRet = sal_True;
325 int nCmp = Compare( pTN );
327 *pnDepth += 1;
328 if( nCmp == GREATER ){
329 if( Left() )
330 bRet = ((NameNode *)Left())->Insert( pTN, pnDepth );
331 else
332 pLeft = pTN;
334 else{
335 if( Right() )
336 bRet = ((NameNode *)Right())->Insert( pTN, pnDepth );
337 else
338 pRight = pTN;
339 if( nCmp == EQUAL )
340 bRet = sal_False;
342 return( bRet );
345 /*************************************************************************
347 |* NameNode::Insert()
349 |* Beschreibung NAME.DOC
350 |* Ersterstellung MM 21.03.90
351 |* Letzte Aenderung MM 11.01.91
353 *************************************************************************/
354 sal_Bool NameNode::Insert( NameNode * pTN ){
355 // insert a node in the tree.
356 // if the node with the same name is in, return sal_False and no insert.
357 // if not return true.
358 sal_uInt32 nDepth = 0;
359 sal_Bool bRet;
361 bRet = Insert( pTN, &nDepth );
362 if( bRet ){
363 if( nDepth > 20 ){
364 if( Left() )
365 pLeft = ChangeDLListBTree( Left()->ChangeBTreeDLList() );
366 if( Right() )
367 pRight = ChangeDLListBTree( Right()->ChangeBTreeDLList() );
371 return( bRet );
374 /*************************************************************************
376 |* NameNode::OrderTree()
378 |* Beschreibung
379 |* Ersterstellung MM 23.09.91
380 |* Letzte Aenderung MM 23.09.91
382 *************************************************************************/
383 void NameNode::OrderTree(){
384 NameNode * pTmpLeft = (NameNode *)Left();
385 NameNode * pTmpRight = (NameNode *)Right();
387 pLeft = NULL;
388 pRight = NULL;
389 SubOrderTree( pTmpLeft );
390 SubOrderTree( pTmpRight );
393 void NameNode::SubOrderTree( NameNode * pOrderNode ){
394 if( pOrderNode ){
395 NameNode * pTmpLeft = (NameNode *)pOrderNode->Left();
396 NameNode * pTmpRight = (NameNode *)pOrderNode->Right();
397 pOrderNode->pLeft = NULL;
398 pOrderNode->pRight = NULL;
399 Insert( pOrderNode );
400 SubOrderTree( pTmpLeft );
401 SubOrderTree( pTmpRight );
405 /*************************************************************************
407 |* NameNode::IdOrderTree()
409 |* Beschreibung
410 |* Ersterstellung MM 15.11.91
411 |* Letzte Aenderung MM 15.11.91
413 *************************************************************************/
414 class OrderCtrl {
415 sal_Bool bOrder;
416 NameNode * pName;
417 DECL_LINK( CallBackFunc, NameNode * );
418 public:
419 OrderCtrl() { bOrder = sal_False; pName = NULL; }
420 sal_Bool IsOrder( const NameNode * pRoot )
422 bOrder = sal_True;
423 pName = NULL;
424 pRoot->EnumNodes( LINK( this, OrderCtrl, CallBackFunc ) );
425 return bOrder;
428 IMPL_LINK_INLINE_START( OrderCtrl, CallBackFunc, NameNode *, pNext )
430 if( pName && pName->Compare( pNext ) != LESS )
431 bOrder = sal_False;
432 pName = pNext;
433 return 0;
435 IMPL_LINK_INLINE_END( OrderCtrl, CallBackFunc, NameNode *, pNext )
437 sal_Bool NameNode::IsOrderTree() const{
438 OrderCtrl aOrder;
440 return aOrder.IsOrder( this );
443 /****************** I d N o d e ******************************************/
444 /*************************************************************************
446 |* IdNode::Search()
448 |* Beschreibung
449 |* Ersterstellung MM 06.11.91
450 |* Letzte Aenderung MM 06.11.91
452 *************************************************************************/
453 IdNode * IdNode::Search( sal_uInt32 nTypeName ) const{
454 return( (IdNode *)NameNode::Search( (const void *)&nTypeName ) );
457 /*************************************************************************
459 |* IdNode::Compare()
461 |* Beschreibung
462 |* Ersterstellung MM 06.11.91
463 |* Letzte Aenderung MM 06.11.91
465 *************************************************************************/
466 COMPARE IdNode::Compare( const NameNode * pSearch ) const
468 if( GetId() < (sal_uInt32)(((const IdNode *)pSearch)->GetId()) )
469 return LESS;
470 else if( GetId() > (sal_uInt32)(((const IdNode *)pSearch)->GetId()) )
471 return GREATER;
472 else
473 return EQUAL;
476 COMPARE IdNode::Compare( const void * pSearch ) const{
477 // pSearch ist ein Zeiger auf sal_uInt32
479 if( GetId() < *((const sal_uInt32 *)pSearch) )
480 return LESS;
481 else if( GetId() > *((const sal_uInt32 *)pSearch) )
482 return GREATER;
483 else
484 return EQUAL;
487 /*************************************************************************
489 |* IdNode::GetId()
491 |* Beschreibung
492 |* Ersterstellung MM 23.09.91
493 |* Letzte Aenderung MM 23.09.91
495 *************************************************************************/
496 sal_uInt32 IdNode::GetId() const
498 return( 0xFFFFFFFF );
501 /*************************************************************************
503 |* StringNode::Search()
505 |* Beschreibung
506 |* Ersterstellung MM 06.11.91
507 |* Letzte Aenderung MM 06.11.91
509 *************************************************************************/
510 StringNode * StringNode::Search( const char * pSearch ) const{
511 return (StringNode *)NameNode::Search( (const void *)pSearch );
514 /*************************************************************************
516 |* StringNode::Compare()
518 |* Beschreibung
519 |* Ersterstellung MM 06.11.91
520 |* Letzte Aenderung MM 06.11.91
522 *************************************************************************/
523 COMPARE StringNode::Compare( const NameNode * pSearch ) const
525 int nCmp = strcmp( aName.GetBuffer(),
526 ((const StringNode *)pSearch)->aName.GetBuffer() );
527 if( nCmp < 0 )
528 return LESS;
529 else if( nCmp > 0 )
530 return GREATER;
531 else
532 return EQUAL;
535 COMPARE StringNode::Compare( const void * pSearch ) const
537 // pSearch ist ein Zeiger auf const char *
538 int nCmp = strcmp( aName.GetBuffer(), (const char *)pSearch );
540 if( nCmp < 0 )
541 return LESS;
542 else if( nCmp > 0 )
543 return GREATER;
544 else
545 return EQUAL;