reactos/rosapps/devutils/vmingw/CList.cpp
2003-01-07 17:59:20 +00:00

329 lines
7.3 KiB
C++

/********************************************************************
* Class: CList.cpp. This is part of WinUI.
*
* Purpose: A simple way to create doubly linked lists.
*
* Authors: Originally coded by Claude Catonio.
*
* License: Original code was public domain.
* Present revised CList classes are covered by GNU General Public License.
*
* Revisions:
* Manu B. 10/05/01 Terms was translated to English.
* Manu B. 10/16/01 Add CList::Destroy(CNode *node) method.
* Manu B. 11/12/01 Add InsertBefore/InsertAfter methods.
* Manu B. 11/17/01 First() & Last() now returns an integer value.
* Manu B. 11/19/01 CNode::Destroy() returns next node by default.
* Manu B. 12/28/01 Simplify CList, add InsertSorted().
* Manu B. 03/13/02 Suppress CNode methods, next and prev are public.
* Manu B. 03/28/02 Add Compare().
*
********************************************************************/
#include "CList.h"
/********************************************************************
* Class: CList.
*
* Purpose: List management.
*
* Revisions:
*
********************************************************************/
CList::~CList(){
//MessageBox (0, "CList", "destructor", MB_OK);
while (first != NULL){
current = first;
first = first->next;
delete current;
}
current = last = first;
count = 0;
}
/********************************************************************
* Browse the list.
********************************************************************/
CNode * CList::First(){
current = first;
return current;
}
CNode * CList::Last(){
current = last;
return current;
}
CNode * CList::Prev(){
// Empty list ?
if (first != NULL){
if(current->prev == NULL){
// No previous node.
return NULL;
}else{
// A previous one.
current = current->prev;
return current;
}
}
return NULL;
}
CNode * CList::Next(){
// Empty list ?
if (first != NULL){
if(current->next == NULL){
// No next node.
return NULL;
}else{
// A next one.
current = current->next;
return current;
}
}
return NULL;
}
/********************************************************************
* Insert nodes.
********************************************************************/
void CList::InsertFirst(CNode *node){
if(first == NULL){
// Empty list.
first = last = node;
}else{
// Set node pointers.
node->prev = NULL;
node->next = first;
// Insert in the list.
first->prev = node;
first = node;
}
// Set current node, increment the node counter.
current = node;
count++;
}
void CList::InsertLast(CNode *node){
if(first == NULL){
// Empty list.
first = last = node;
}else{
// Set node pointers.
node->prev = last;
node->next = NULL;
// Insert in the list.
last->next = node;
last = node;
}
// Set current node, increment the node counter.
current = node;
count++;
}
void CList::InsertBefore(CNode *node){
if(first == NULL){
// Empty list.
first = last = node;
}else{
if (current == first)
first = node;
// Set node pointers.
node->prev = current->prev;
node->next = current;
// Insert in the list.
if (node->prev)
node->prev->next = node;
current->prev = node;
}
// Set current node, increment the node counter.
current = node;
count++;
}
void CList::InsertAfter(CNode *node){
if(first == NULL){
// Empty list.
first = last = node;
}else{
if (current == last)
last = node;
// Set node pointers.
node->prev = current;
node->next = current->next;
// Insert in the list.
if (node->next)
node->next->prev = node;
current->next = node;
}
// Set current node, increment the node counter.
current = node;
count++;
}
bool CList::InsertSorted(CNode * newNode){
// Get the current node.
CNode * currentNode = GetCurrent();
int cmpResult;
if(!currentNode){
// The list is empty, InsertFirst() and return.
InsertFirst(newNode);
return true;
}
// Compare new node and current node data to know if we must parse Up
// or Down from current node.
cmpResult = Compare(newNode, currentNode);
// Search Up -----------------------------------------------------------------
if (cmpResult == -1){
// Parse the list while there's a previous node.
while (Prev()){
currentNode = GetCurrent();
cmpResult = Compare(newNode, currentNode);
if (cmpResult == 1){
// Correct position found.
InsertAfter(newNode);
return true;
}else if (cmpResult == 0){
// Don't add a file twice.
return false;
}
}
// There's no previous node, so insert first.
InsertFirst(newNode);
return true;
}
// Search Down --------------------------------------------------------------
else if (cmpResult == 1){
// Parse the list while there's a next node.
while (Next()){
currentNode = GetCurrent();
cmpResult = Compare(newNode, currentNode);
if (cmpResult == -1){
// Correct position found.
InsertBefore(newNode);
return true;
}else if (cmpResult == 0){
// Don't add a file twice.
return false;
}
}
// There's no next node, so insert last.
InsertLast(newNode);
return true;
}
// Don't add a file twice (cmpResult == 0) -------------------------------------
return false;
}
int CList::InsertSorted_New(CNode * newNode){
int cmpResult;
/* Get the current node */
CNode * currentNode = GetCurrent();
if(!currentNode)
return EMPTY_LIST;
/* Parse up or down ? */
cmpResult = Compare(newNode, currentNode);
/* -Up- */
if (cmpResult == -1){
// Parse the list while there's a previous node.
while (Prev()){
currentNode = GetCurrent();
cmpResult = Compare(newNode, currentNode);
if (cmpResult == 1){
// Correct position found.
return INSERT_AFTER;
}else if (cmpResult == 0){
// Don't add a file twice.
return FILE_FOUND;
}
}
// There's no previous node, so insert first.
return INSERT_FIRST;
/* -Down- */
}else if (cmpResult == 1){
// Parse the list while there's a next node.
while (Next()){
currentNode = GetCurrent();
cmpResult = Compare(newNode, currentNode);
if (cmpResult == -1){
// Correct position found.
return INSERT_BEFORE;
}else if (cmpResult == 0){
// Don't add a file twice.
return FILE_FOUND;
}
}
// There's no next node, so insert last.
return INSERT_LAST;
}
// Don't add a file twice (cmpResult == 0) -------------------------------------
return FILE_FOUND;
}
/********************************************************************
* Destroy nodes.
********************************************************************/
void CList::DestroyCurrent(){
// CNode * node = current;
Destroy(current);
}
void CList::Destroy(CNode * node){
// Empty list ?
if (current != NULL){
// Detach node from the list.
if (node->next != NULL)
node->next->prev = node->prev;
if (node->prev != NULL)
node->prev->next = node->next;
// Set current node.
if(node->next != NULL)
current = node->next;
else
current = node->prev;
if (current == NULL){
// Now, the list is empty.
first = last = NULL;
}else if (first == node){
// Detached node was first.
first = current;
}else if (last == node){
// Detached node was last.
last = current;
}
delete node;
count--;
}
}
void CList::DestroyList(){
while (first != NULL){
current = first;
first = first->next;
delete current;
}
current = last = first;
count = 0;
}
int CList::Length(){
return count;
}