зеркало из https://github.com/mozilla/pjs.git
357 строки
9.0 KiB
C++
357 строки
9.0 KiB
C++
/*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (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.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is TransforMiiX XSLT processor.
|
|
*
|
|
* The Initial Developer of the Original Code is The MITRE Corporation.
|
|
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
|
*
|
|
* Portions created by Keith Visco as a Non MITRE employee,
|
|
* (C) 1999 Keith Visco. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Keith Visco, kvisco@ziplink.net
|
|
* -- original author.
|
|
* Bob Miller, kbob@oblix.com
|
|
* -- plugged core leak.
|
|
*
|
|
* $Id: List.cpp,v 1.5 2001-01-12 20:06:08 axel%pike.org Exp $
|
|
*/
|
|
|
|
#include "List.h"
|
|
#ifndef MOZ_XSL
|
|
#include <iostream.h>
|
|
#endif
|
|
|
|
//--------------------------/
|
|
//- Implementation of List -/
|
|
//--------------------------/
|
|
|
|
/**
|
|
* Default constructor for a List;
|
|
* @author <a href="mailto:kvisco@ziplink.net">Keith Visco</a>
|
|
* @version $Revision: 1.5 $ $Date: 2001-01-12 20:06:08 $
|
|
**/
|
|
|
|
List::List() {
|
|
firstItem = 0;
|
|
lastItem = 0;
|
|
itemCount = 0;
|
|
} //-- List;
|
|
|
|
/**
|
|
* List destructor, cleans up List Items, but will not delete the Object
|
|
* references
|
|
*/
|
|
List::~List() {
|
|
ListItem* item = firstItem;
|
|
while (item) {
|
|
ListItem* tItem = item;
|
|
item = item->nextItem;
|
|
delete tItem;
|
|
}
|
|
} //-- ~List
|
|
|
|
void List::insert(int index, void* objPtr) {
|
|
|
|
if ( index >= itemCount ) {
|
|
insertBefore(objPtr, 0);
|
|
}
|
|
else {
|
|
//-- add to middle of list
|
|
ListItem* nextItem = firstItem;
|
|
for ( int i = 0; i < index; i++ ) nextItem = nextItem->nextItem;
|
|
insertBefore(objPtr, nextItem);
|
|
}
|
|
} //-- insert
|
|
|
|
void List::add(void* objPtr) {
|
|
insert(itemCount, objPtr);
|
|
} //-- add
|
|
|
|
/**
|
|
* Returns the object located at the given index. This may
|
|
* be slow or fast depending on the implementation.
|
|
* Note:
|
|
* Currently this list is implemented via a linked list, so
|
|
* this method will be slow (unless the list only has a couple
|
|
* members) as it will need traverse the links each time
|
|
* @return the object located at the given index
|
|
**/
|
|
void* List::get(int index) {
|
|
|
|
if ((index < 0) || (index >= itemCount)) return 0;
|
|
|
|
int c = 0;
|
|
ListItem* item = firstItem;
|
|
while (c != index) {
|
|
item = item->nextItem;
|
|
++c;
|
|
}
|
|
|
|
return item->objPtr;
|
|
} //-- get(int)
|
|
|
|
List::ListItem* List::getFirstItem() {
|
|
return firstItem;
|
|
} //-- getFirstItem
|
|
|
|
List::ListItem* List::getLastItem() {
|
|
return lastItem;
|
|
} //-- getLastItem
|
|
|
|
/**
|
|
* Returns the number of items in this List
|
|
**/
|
|
Int32 List::getLength() {
|
|
return itemCount;
|
|
} //-- getLength
|
|
|
|
|
|
/**
|
|
* Inserts the given Object pointer as the item just after refItem.
|
|
* If refItem is a null pointer the Object will be inserted at the
|
|
* beginning of the List (ie, insert after nothing).
|
|
* This method assumes refItem is a member of this list, and since this
|
|
* is a private method, I feel that's a valid assumption
|
|
**/
|
|
void List::insertAfter(void* objPtr, ListItem* refItem) {
|
|
//-- if refItem == null insert at front
|
|
if (!refItem) insertBefore(objPtr, firstItem);
|
|
else insertBefore(objPtr, refItem->nextItem);
|
|
} //-- insertAfter
|
|
|
|
/**
|
|
* Inserts the given Object pointer as the item just before refItem.
|
|
* If refItem is a null pointer the Object will be inserted at the
|
|
* end of the List (ie, insert before nothing).
|
|
* This method assumes refItem is a member of this list, and since this
|
|
* is a private method, I feel that's a valid assumption
|
|
**/
|
|
void List::insertBefore(void* objPtr, ListItem* refItem) {
|
|
|
|
ListItem* item = new ListItem;
|
|
item->objPtr = objPtr;
|
|
item->nextItem = 0;
|
|
item->prevItem = 0;
|
|
|
|
//-- if refItem == null insert at end
|
|
if (!refItem) {
|
|
//-- add to back of list
|
|
if ( lastItem ) {
|
|
lastItem->nextItem = item;
|
|
item->prevItem = lastItem;
|
|
}
|
|
lastItem = item;
|
|
if ( !firstItem ) firstItem = item;
|
|
}
|
|
else {
|
|
//-- insert before given item
|
|
item->nextItem = refItem;
|
|
item->prevItem = refItem->prevItem;
|
|
refItem->prevItem = item;
|
|
|
|
if (refItem == firstItem) firstItem = item;
|
|
if (itemCount == 0) lastItem = item; // <-should we ever see this?
|
|
}
|
|
|
|
// increase the item count
|
|
++itemCount;
|
|
} //-- insertBefore
|
|
|
|
/**
|
|
* Returns a ListIterator for this List
|
|
**/
|
|
ListIterator* List::iterator() {
|
|
return new ListIterator(this);
|
|
}
|
|
|
|
void* List::remove(void* objPtr) {
|
|
ListItem* item = firstItem;
|
|
while (item) {
|
|
if (item->objPtr == objPtr) {
|
|
remove(item);
|
|
delete item;
|
|
return objPtr;
|
|
}
|
|
item = item->nextItem;
|
|
}
|
|
// not in list
|
|
return 0;
|
|
} //-- remove
|
|
|
|
List::ListItem* List::remove(ListItem* item) {
|
|
|
|
if ( !item ) return item;
|
|
|
|
//-- adjust the previous item's next pointer
|
|
if (item->prevItem) {
|
|
item->prevItem->nextItem = item->nextItem;
|
|
}
|
|
//-- adjust the next item's previous pointer
|
|
if ( item->nextItem ) {
|
|
item->nextItem->prevItem = item->prevItem;
|
|
}
|
|
|
|
//-- adjust first and last items
|
|
if (item == firstItem) firstItem = item->nextItem;
|
|
if (item == lastItem) lastItem = item->prevItem;
|
|
|
|
//-- decrease Item count
|
|
--itemCount;
|
|
return item;
|
|
} //-- remove
|
|
|
|
//----------------------------------/
|
|
//- Implementation of ListIterator -/
|
|
//----------------------------------/
|
|
|
|
|
|
/**
|
|
* Creates a new ListIterator for the given List
|
|
* @param list, the List to create an Iterator for
|
|
**/
|
|
ListIterator::ListIterator(List* list) {
|
|
this->list = list;
|
|
currentItem = 0;
|
|
allowRemove = MB_FALSE;
|
|
moveForward = MB_TRUE;
|
|
done = MB_FALSE;
|
|
count = 0;
|
|
} //-- ListIterator
|
|
|
|
ListIterator::~ListIterator() {
|
|
//-- overrides default destructor to do nothing
|
|
} //-- ~ListIterator
|
|
|
|
/**
|
|
* Adds the Object pointer to the List pointed to by this ListIterator.
|
|
* The Object pointer is inserted as the next item in the List
|
|
* based on the current position within the List
|
|
* @param objPtr the Object pointer to add to the list
|
|
**/
|
|
void ListIterator::add(void* objPtr) {
|
|
|
|
list->insertAfter(objPtr,currentItem);
|
|
allowRemove = MB_FALSE;
|
|
|
|
} //-- add
|
|
|
|
/**
|
|
* Returns true if a sucessful call to the next() method can be made
|
|
* @return MB_TRUE if a sucessful call to the next() method can be made,
|
|
* otherwise MB_FALSE
|
|
**/
|
|
MBool ListIterator::hasNext() {
|
|
MBool hasNext = MB_FALSE;
|
|
if ( done ) return hasNext;
|
|
else if ( currentItem ) {
|
|
if (moveForward) hasNext = (MBool) currentItem->nextItem;
|
|
else hasNext = (MBool)currentItem->prevItem;
|
|
}
|
|
else {
|
|
if (moveForward) hasNext = (MBool) list->firstItem;
|
|
else hasNext = (MBool) list->lastItem;
|
|
}
|
|
return hasNext;
|
|
} //-- hasNext
|
|
|
|
/**
|
|
* Returns true if a sucessful call to the previous() method can be made
|
|
* @return MB_TRUE if a sucessful call to the previous() method can be made,
|
|
* otherwise MB_FALSE
|
|
**/
|
|
MBool ListIterator::hasPrevious() {
|
|
MBool hasPrevious = MB_FALSE;
|
|
if (currentItem) {
|
|
if (moveForward) hasPrevious = (MBool)(currentItem->prevItem);
|
|
else hasPrevious = (MBool) (currentItem->nextItem);
|
|
}
|
|
return hasPrevious;
|
|
} //-- hasPrevious
|
|
|
|
/**
|
|
* Returns the next Object pointer in the list
|
|
**/
|
|
void* ListIterator::next() {
|
|
|
|
void* obj = 0;
|
|
if ( done ) return obj;
|
|
|
|
if (currentItem) {
|
|
if ( moveForward ) currentItem = currentItem->nextItem;
|
|
else currentItem = currentItem->prevItem;
|
|
}
|
|
else {
|
|
if ( moveForward ) currentItem = list->firstItem;
|
|
else currentItem = list->lastItem;
|
|
}
|
|
|
|
if ( currentItem ) {
|
|
obj = currentItem->objPtr;
|
|
allowRemove = MB_TRUE;
|
|
}
|
|
else done = MB_TRUE;
|
|
|
|
return obj;
|
|
} //-- next
|
|
|
|
/**
|
|
* Returns the previous Object in the list
|
|
**/
|
|
void* ListIterator::previous() {
|
|
|
|
void* obj = 0;
|
|
|
|
if (currentItem) {
|
|
if ( moveForward ) currentItem = currentItem->prevItem;
|
|
else currentItem = currentItem->nextItem;
|
|
if ( currentItem ) obj = currentItem->objPtr;
|
|
}
|
|
return obj;
|
|
} //-- previous
|
|
|
|
/**
|
|
* Removes the Object last returned by the next() or previous() methods;
|
|
* @return the removed Object pointer
|
|
**/
|
|
void* ListIterator::remove() {
|
|
|
|
if (!allowRemove) return 0;
|
|
allowRemove = MB_FALSE;
|
|
|
|
void* obj = 0;
|
|
if (currentItem) {
|
|
obj = currentItem->objPtr;
|
|
List::ListItem* item = currentItem;
|
|
previous(); //-- make previous item the current item
|
|
list->remove(item);
|
|
delete item;
|
|
}
|
|
return obj;
|
|
} //-- remove
|
|
|
|
/**
|
|
* Resets the current location within the List to the beginning of the List
|
|
**/
|
|
void ListIterator::reset() {
|
|
done = MB_FALSE;
|
|
currentItem = 0;
|
|
} //-- reset
|
|
|
|
/**
|
|
* sets this iterator to operate in the reverse direction
|
|
**/
|
|
void ListIterator::reverse() {
|
|
moveForward = (MBool)(!moveForward);
|
|
} //-- reverse
|
|
|