blob: ec2cfa8e68ed58034727b16de81efeb5341fd8ec [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_rsc.hxx"
/****************** I N C L U D E S **************************************/
// C and C++ Includes.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// Programmabh�ngige Includes.
#include <tools/link.hxx>
#include <rsctree.hxx>
/****************** C O D E **********************************************/
/****************** B i N o d e ******************************************/
/*************************************************************************
|*
|* BiNode::BiNode()
|*
|* Beschreibung NAME.DOC
|* Ersterstellung MM 07.02.91
|* Letzte Aenderung MM 07.02.91
|*
*************************************************************************/
BiNode::BiNode(){
pLeft = pRight = NULL;
}
/*************************************************************************
|*
|* BiNode::~BiNode()
|*
|* Beschreibung
|* Ersterstellung MM 07.02.91
|* Letzte Aenderung MM 07.02.91
|*
*************************************************************************/
BiNode::~BiNode(){
}
/*************************************************************************
|*
|* BiNode::EnumNodes()
|*
|* Beschreibung
|* Ersterstellung MM 07.02.91
|* Letzte Aenderung MM 07.02.91
|*
*************************************************************************/
void BiNode::EnumNodes( Link aLink ) const{
if( Left() )
Left()->EnumNodes( aLink );
aLink.Call( (BiNode *)this );
if( Right() )
Right()->EnumNodes( aLink );
}
/*************************************************************************
|*
|* BiNode::ChangeDLListBTree()
|*
|* Beschreibung
|* Ersterstellung MM 11.01.91
|* Letzte Aenderung MM 11.01.91
|*
*************************************************************************/
BiNode * BiNode::ChangeDLListBTree( BiNode * pList ){
BiNode * pRightNode;
BiNode * pMiddle;
BiNode * pTmp;
sal_uInt32 nEle, i;
if( pList ){
while( pList->Left() )
pList = pList->Left();
pTmp = pList;
for( nEle = 0; pTmp->Right(); nEle++ )
pTmp = pTmp->Right();
pMiddle = pList;
if( nEle / 2 )
for( i = 0; i < (nEle / 2); i++ )
pMiddle = pMiddle->Right();
else
pList = (BiNode *)0;
if( NULL != (pTmp = pMiddle->Left()) ) // rechten Zeiger auf Null
pTmp->pRight = (BiNode *)0;
// linken Zeiger auf Null
if( NULL != (pRightNode = pMiddle->Right()) )
pRightNode->pLeft = (BiNode *)0;
pMiddle->pLeft = ChangeDLListBTree( pList );
pMiddle->pRight = ChangeDLListBTree( pRightNode );
return( pMiddle );
}
return( pList );
}
/*************************************************************************
|*
|* BiNode::ChangeBTreeDLList()
|*
|* Beschreibung
|* Ersterstellung MM 11.01.91
|* Letzte Aenderung MM 11.01.91
|*
*************************************************************************/
BiNode * BiNode::ChangeBTreeDLList(){
BiNode * pList;
BiNode * pLL_RN; // linke Liste rechter Knoten
if( Right() ){
pList = Right()->ChangeBTreeDLList();
pRight = pList;
pList->pLeft = this;
}
pList = this;
if( Left() ){
pLL_RN = pList = Left()->ChangeBTreeDLList();
while( pLL_RN->Right() )
pLL_RN = pLL_RN->Right();
pLeft = pLL_RN;
pLL_RN->pRight = this;
}
return( pList );
}
/****************** N a m e N o d e **************************************/
/*************************************************************************
|*
|* NameNode::Remove()
|*
|* Beschreibung
|* Ersterstellung MM 10.07.91
|* Letzte Aenderung MM 10.07.91
|*
*************************************************************************/
NameNode * NameNode::Remove( NameNode * pRemove ){
NameNode * pRoot = this;
NameNode * pParent = SearchParent( pRemove );
if( pParent ){
if( pParent->Left()
&& (EQUAL == pRemove->Compare( pParent->Left() ) ) ){
pParent->pLeft = pRemove->Left();
if( pRemove->Right() )
pParent->Insert( pRemove->Right() );
}
else if( pParent->Right()
&& (EQUAL == pRemove->Compare( pParent->Right() ) ) ){
pParent->pRight = pRemove->Right();
if( pRemove->Left() )
pParent->Insert( pRemove->Left() );
}
}
else if( EQUAL == this->Compare( pRemove ) ){
if( Right() ){
pRoot = Right();
if( Left() )
Right()->Insert( Left() );
}
else{
pRoot = Left();
}
}
pRemove->pLeft = pRemove->pRight = NULL;
return pRoot;
}
/*************************************************************************
|*
|* NameNode::Compare
|*
|* Beschreibung
|* Ersterstellung MM 10.07.91
|* Letzte Aenderung MM 13.07.91
|*
*************************************************************************/
COMPARE NameNode::Compare( const NameNode * pCompare ) const{
if( (long)this < (long)pCompare )
return LESS;
else if( (long)this > (long)pCompare )
return GREATER;
else
return EQUAL;
}
COMPARE NameNode::Compare( const void * pCompare ) const{
if( (long)this < (long)pCompare )
return LESS;
else if( (long)this > (long)pCompare )
return GREATER;
else
return EQUAL;
}
/*************************************************************************
|*
|* NameNode::SearchParent
|*
|* Beschreibung
|* Ersterstellung MM 10.07.91
|* Letzte Aenderung MM 10.07.91
|*
*************************************************************************/
NameNode* NameNode::SearchParent( const NameNode * pSearch ) const{
// search for a parent node.
// return a pointer to the parent node if found.
// otherwise return 0.
int nCmp = Compare( pSearch );
if( nCmp == GREATER ){
if( Left() ){
if( ((NameNode *)Left())->Compare( pSearch ) == EQUAL )
return (NameNode *)this;
return ((NameNode *)Left())->SearchParent( pSearch );
};
}
else if( nCmp == LESS ){
if( Right() ){
if( ((NameNode *)Right())->Compare( pSearch ) == EQUAL )
return (NameNode *)this;
return ((NameNode *)Right())->SearchParent( pSearch );
}
};
return( (NameNode *)NULL );
}
/*************************************************************************
|*
|* NameNode::Search
|*
|* Beschreibung
|* Ersterstellung MM 21.03.90
|* Letzte Aenderung MM 27.06.90
|*
*************************************************************************/
NameNode* NameNode::Search( const NameNode * pSearch ) const{
// search for a node.
// return a pointer to the node if found.
// otherwise return 0.
int nCmp = Compare( pSearch );
if( nCmp == GREATER ){
if( Left() )
return ((NameNode *)Left())->Search( pSearch );
}
else if( nCmp == LESS ){
if( Right() )
return ((NameNode *)Right())->Search( pSearch );
}
else
return( (NameNode *)this );
return( NULL );
}
NameNode* NameNode::Search( const void * pSearch ) const{
// search for a node.
// return a pointer to the node if found.
// otherwise return 0.
int nCmp = Compare( pSearch );
if( nCmp == GREATER ){
if( Left() )
return ((NameNode *)Left())->Search( pSearch );
}
else if( nCmp == LESS ){
if( Right() )
return ((NameNode *)Right())->Search( pSearch );
}
else
return( (NameNode *)this );
return( NULL );
}
/*************************************************************************
|*
|* NameNode::Insert()
|*
|* Beschreibung NAME.DOC
|* Ersterstellung MM 11.01.91
|* Letzte Aenderung MM 11.01.91
|*
*************************************************************************/
sal_Bool NameNode::Insert( NameNode * pTN, sal_uInt32* pnDepth ){
// Ein Knoten wird in den Baum eingefuegt
// Gibt es einen Knoten mit dem gleichen Namen, dann return sal_False
// sonst return sal_True. Der Knoten wird auf jeden Fall eingefuegt.
sal_Bool bRet = sal_True;
int nCmp = Compare( pTN );
*pnDepth += 1;
if( nCmp == GREATER ){
if( Left() )
bRet = ((NameNode *)Left())->Insert( pTN, pnDepth );
else
pLeft = pTN;
}
else{
if( Right() )
bRet = ((NameNode *)Right())->Insert( pTN, pnDepth );
else
pRight = pTN;
if( nCmp == EQUAL )
bRet = sal_False;
};
return( bRet );
}
/*************************************************************************
|*
|* NameNode::Insert()
|*
|* Beschreibung NAME.DOC
|* Ersterstellung MM 21.03.90
|* Letzte Aenderung MM 11.01.91
|*
*************************************************************************/
sal_Bool NameNode::Insert( NameNode * pTN ){
// insert a node in the tree.
// if the node with the same name is in, return sal_False and no insert.
// if not return true.
sal_uInt32 nDepth = 0;
sal_Bool bRet;
bRet = Insert( pTN, &nDepth );
if( bRet ){
if( nDepth > 20 ){
if( Left() )
pLeft = ChangeDLListBTree( Left()->ChangeBTreeDLList() );
if( Right() )
pRight = ChangeDLListBTree( Right()->ChangeBTreeDLList() );
}
}
return( bRet );
}
/*************************************************************************
|*
|* NameNode::OrderTree()
|*
|* Beschreibung
|* Ersterstellung MM 23.09.91
|* Letzte Aenderung MM 23.09.91
|*
*************************************************************************/
void NameNode::OrderTree(){
NameNode * pTmpLeft = (NameNode *)Left();
NameNode * pTmpRight = (NameNode *)Right();
pLeft = NULL;
pRight = NULL;
SubOrderTree( pTmpLeft );
SubOrderTree( pTmpRight );
}
void NameNode::SubOrderTree( NameNode * pOrderNode ){
if( pOrderNode ){
NameNode * pTmpLeft = (NameNode *)pOrderNode->Left();
NameNode * pTmpRight = (NameNode *)pOrderNode->Right();
pOrderNode->pLeft = NULL;
pOrderNode->pRight = NULL;
Insert( pOrderNode );
SubOrderTree( pTmpLeft );
SubOrderTree( pTmpRight );
}
}
/*************************************************************************
|*
|* NameNode::IdOrderTree()
|*
|* Beschreibung
|* Ersterstellung MM 15.11.91
|* Letzte Aenderung MM 15.11.91
|*
*************************************************************************/
class OrderCtrl {
sal_Bool bOrder;
NameNode * pName;
DECL_LINK( CallBackFunc, NameNode * );
public:
OrderCtrl() { bOrder = sal_False; pName = NULL; }
sal_Bool IsOrder( const NameNode * pRoot )
{
bOrder = sal_True;
pName = NULL;
pRoot->EnumNodes( LINK( this, OrderCtrl, CallBackFunc ) );
return bOrder;
};
};
IMPL_LINK_INLINE_START( OrderCtrl, CallBackFunc, NameNode *, pNext )
{
if( pName && pName->Compare( pNext ) != LESS )
bOrder = sal_False;
pName = pNext;
return 0;
}
IMPL_LINK_INLINE_END( OrderCtrl, CallBackFunc, NameNode *, pNext )
sal_Bool NameNode::IsOrderTree() const{
OrderCtrl aOrder;
return aOrder.IsOrder( this );
}
/****************** I d N o d e ******************************************/
/*************************************************************************
|*
|* IdNode::Search()
|*
|* Beschreibung
|* Ersterstellung MM 06.11.91
|* Letzte Aenderung MM 06.11.91
|*
*************************************************************************/
IdNode * IdNode::Search( sal_uInt32 nTypeName ) const{
return( (IdNode *)NameNode::Search( (const void *)&nTypeName ) );
}
/*************************************************************************
|*
|* IdNode::Compare()
|*
|* Beschreibung
|* Ersterstellung MM 06.11.91
|* Letzte Aenderung MM 06.11.91
|*
*************************************************************************/
COMPARE IdNode::Compare( const NameNode * pSearch ) const
{
if( GetId() < (sal_uInt32)(((const IdNode *)pSearch)->GetId()) )
return LESS;
else if( GetId() > (sal_uInt32)(((const IdNode *)pSearch)->GetId()) )
return GREATER;
else
return EQUAL;
}
COMPARE IdNode::Compare( const void * pSearch ) const{
// pSearch ist ein Zeiger auf sal_uInt32
if( GetId() < *((const sal_uInt32 *)pSearch) )
return LESS;
else if( GetId() > *((const sal_uInt32 *)pSearch) )
return GREATER;
else
return EQUAL;
}
/*************************************************************************
|*
|* IdNode::GetId()
|*
|* Beschreibung
|* Ersterstellung MM 23.09.91
|* Letzte Aenderung MM 23.09.91
|*
*************************************************************************/
sal_uInt32 IdNode::GetId() const
{
return( 0xFFFFFFFF );
}
/*************************************************************************
|*
|* StringNode::Search()
|*
|* Beschreibung
|* Ersterstellung MM 06.11.91
|* Letzte Aenderung MM 06.11.91
|*
*************************************************************************/
StringNode * StringNode::Search( const char * pSearch ) const{
return (StringNode *)NameNode::Search( (const void *)pSearch );
}
/*************************************************************************
|*
|* StringNode::Compare()
|*
|* Beschreibung
|* Ersterstellung MM 06.11.91
|* Letzte Aenderung MM 06.11.91
|*
*************************************************************************/
COMPARE StringNode::Compare( const NameNode * pSearch ) const
{
int nCmp = strcmp( aName.GetBuffer(),
((const StringNode *)pSearch)->aName.GetBuffer() );
if( nCmp < 0 )
return LESS;
else if( nCmp > 0 )
return GREATER;
else
return EQUAL;
}
COMPARE StringNode::Compare( const void * pSearch ) const
{
// pSearch ist ein Zeiger auf const char *
int nCmp = strcmp( aName.GetBuffer(), (const char *)pSearch );
if( nCmp < 0 )
return LESS;
else if( nCmp > 0 )
return GREATER;
else
return EQUAL;
}