diff options
Diffstat (limited to 'debian/htdig/htdig-3.2.0b6/htlib/List.cc')
-rw-r--r-- | debian/htdig/htdig-3.2.0b6/htlib/List.cc | 511 |
1 files changed, 511 insertions, 0 deletions
diff --git a/debian/htdig/htdig-3.2.0b6/htlib/List.cc b/debian/htdig/htdig-3.2.0b6/htlib/List.cc new file mode 100644 index 00000000..dd020aab --- /dev/null +++ b/debian/htdig/htdig-3.2.0b6/htlib/List.cc @@ -0,0 +1,511 @@ +// +// List.cc +// +// List: A List class which holds objects of type Object. +// +// Part of the ht://Dig package <http://www.htdig.org/> +// Copyright (c) 1999-2004 The ht://Dig Group +// For copyright details, see the file COPYING in your distribution +// or the GNU Library General Public License (LGPL) version 2 or later +// <http://www.gnu.org/copyleft/lgpl.html> +// +// $Id: List.cc,v 1.9 2004/05/28 13:15:21 lha Exp $ +// + +#ifdef HAVE_CONFIG_H +#include "htconfig.h" +#endif /* HAVE_CONFIG_H */ + +#include "List.h" + +class listnode +{ +public: + + listnode *next; + Object *object; +}; + + +//********************************************************************* +// List::List() +// Constructor +// +List::List() +{ + head = tail = 0; + number = 0; +} + + +//********************************************************************* +// List::~List() +// Destructor +// +List::~List() +{ + Destroy(); +} + + +//********************************************************************* +// void List::Release() +// Release all the objects from our list. +// +void List::Release() +{ + listnode *node; + while (head) + { + node = head; + head = head->next; + delete node; + } + head = tail = 0; + number = 0; + cursor.Clear(); +} + + +//********************************************************************* +// void List::Destroy() +// Delete all the objects from our list. +// +void List::Destroy() +{ + listnode *node; + while (head) + { + node = head; + head = head->next; + delete node->object; + delete node; + } + head = tail = 0; + number = 0; + cursor.Clear(); +} + + +//********************************************************************* +// void List::Add(Object *object) +// Add an object to the list. +// +void List::Add(Object *object) +{ + listnode *node = new listnode; + node->next = 0; + node->object = object; + if (tail) + { + tail->next = node; + tail = node; + } + else + { + head = tail = node; + } + + number++; +} + + +//********************************************************************* +// void List::Insert(Object *object, int position) +// Add an object to the list. +// +void List::Insert(Object *object, int position) +{ + listnode *node = new listnode; + node->next = 0; + node->object = object; + + listnode *ln = head; + listnode *prev = 0; + + for (int i = 0; i < position && ln; i++, ln = ln->next) + prev = ln; + if (!ln) + { + if (tail) + tail->next = node; + tail = node; + + // + // The list is empty. This is a simple case, then. + // + if (!head) + head = node; + } + else + { + if (ln == head) + { + node->next = head; + head = node; + } + else + { + node->next = ln; + prev->next = node; + } + } + + cursor.current_index = -1; + number++; +} + + +//********************************************************************* +// void List::Assign(Object *object, int position) +// Assign a new value to an index. +// +void List::Assign(Object *object, int position) +{ + // + // First make sure that there is something there! + // + while (number < position + 1) + { + Add(0); + } + + // + // Now find the listnode to put the new object in + // + listnode *temp = head; + + for (int i = 0; temp && i < position; i++) + { + temp = temp->next; + } + + cursor.current_index = -1; + delete temp->object; + temp->object = object; +} + + +//********************************************************************* +// int List::Remove(Object *object) +// Remove an object from the list. +// +int List::Remove(Object *object) +{ + listnode *node = head; + listnode *prev = 0; + while (node) + { + if (node->object == object) + { + // + // Found it! + // + // + // If we are in the middle of a Get_Next() sequence, we need to + // fix up any problems with the current node. + // + if (cursor.current == node) + { + cursor.current = node->next; + } + + if (head == tail) + { + head = tail = 0; + } + else if (head == node) + { + head = head->next; + } + else if (tail == node) + { + tail = prev; + tail->next = 0; + } + else + { + prev->next = node->next; + } + + delete node; + number--; + cursor.current_index = -1; + return 1; + } + prev = node; + node = node->next; + } + return 0; +} + +//********************************************************************* +// +int List::Remove(int position, int action /* = LIST_REMOVE_DESTROY */) +{ + Object *o = List::operator[](position); + if(action == LIST_REMOVE_DESTROY) delete o; + return List::Remove(o); +} + +//********************************************************************* +// Object *List::Get_Next() +// Return the next object in the list. +// +Object *List::Get_Next(ListCursor& cursor) const +{ + listnode *temp = cursor.current; + + if (cursor.current) + { + cursor.prev = cursor.current; + cursor.current = cursor.current->next; + if (cursor.current_index >= 0) + cursor.current_index++; + } + else + return 0; + return temp->object; +} + + +//********************************************************************* +// Object *List::Get_First() +// Return the first object in the list. +// +Object *List::Get_First() +{ + if (head) + return head->object; + else + return 0; +} + + +//********************************************************************* +// int List::Index(Object *obj) +// Return the index of an object in the list. +// +int List::Index(Object *obj) +{ + listnode *temp = head; + int index = 0; + + while (temp && temp->object != obj) + { + temp = temp->next; + index++; + } + if (index >= number) + return -1; + else + return index; +} + + +//********************************************************************* +// Object *List::Next(Object *prev) +// Return the next object in the list. Using this, the list will +// appear as a circular list. +// +Object *List::Next(Object *prev) +{ + listnode *node = head; + while (node) + { + if (node->object == prev) + { + node = node->next; + if (!node) + return head->object; + else + return node->object; + } + node = node->next; + } + + return 0; +} + + +//********************************************************************* +// Object *List::Previous(Object *next) +// Return the next object in the list. Using this, the list will +// appear as a circular list. +// +Object *List::Previous(Object *next) +{ + listnode *node = head; + listnode *prev = 0; + while (node) + { + if (node->object == next) + { + if (!prev) + return 0; + else + return prev->object; + } + prev = node; + node = node->next; + } + + return 0; +} + + +//********************************************************************* +// Return the nth object in the list. +// +const Object *List::Nth(ListCursor& cursor, int n) const +{ + if (n < 0 || n >= number) + return 0; + + listnode *temp = head; + + if (cursor.current_index == n) + return cursor.current->object; + + if (cursor.current && cursor.current_index >= 0 && n == cursor.current_index + 1) + { + cursor.prev = cursor.current; + cursor.current = cursor.current->next; + if (!cursor.current) + { + cursor.current_index = -1; + return 0; + } + cursor.current_index = n; + return cursor.current->object; + } + + for (int i = 0; temp && i < n; i++) + { + temp = temp->next; + } + + if (temp) + { + cursor.current_index = n; + cursor.current = temp; + return temp->object; + } + else + return 0; +} + + +//********************************************************************* +// Object *List::Last() +// Return the last object inserted. +// +Object *List::Last() +{ + if (tail) + { + return tail->object; + } + + return 0; +} + +//********************************************************************* +// +Object *List::Pop(int action /* = LIST_REMOVE_DESTROY */) +{ + Object *o = 0; + listnode *ln = head; + listnode *prev = 0; + + if (tail) { + if(action == LIST_REMOVE_DESTROY) { + delete tail->object; + } else { + o = tail->object; + } + if(head == tail) { + head = tail = 0; + } else { + + for (int i = 0; ln != tail; i++, ln = ln->next) + prev = ln; + tail = prev; + tail->next = 0; + } + } + + return o; +} + + +//********************************************************************* +// Object *List::Copy() const +// Return a deep copy of the list. +// +Object *List::Copy() const +{ + List *list = new List; + ListCursor cursor; + + Start_Get(cursor); + Object *obj; + while ((obj = Get_Next(cursor))) + { + list->Add(obj->Copy()); + } + return list; +} + + +//********************************************************************* +// List &List::operator=(List &list) +// Return a deep copy of the list. +// +List &List::operator=(List &list) +{ + Destroy(); + list.Start_Get(); + Object *obj; + while ((obj = list.Get_Next())) + { + Add(obj->Copy()); + } + return *this; +} + + +//********************************************************************* +// void AppendList(List &list) +// Move contents of other list to the end of this list, and empty the +// other list. +// +void List::AppendList(List &list) +{ + // Never mind an empty list or ourselves. + if (list.number == 0 || &list == this) + return; + + // Correct our pointers in head and tail. + if (tail) + { + // Link in other list. + tail->next = list.head; + + // Update members for added contents. + number += list.number; + tail = list.tail; + } + else + { + head = list.head; + tail = list.tail; + number = list.number; + } + + // Clear others members to be an empty list. + list.head = list.tail = 0; + list.cursor.current = 0; + list.cursor.current_index = -1; + list.number = 0; +} |