2001-10-19 16:09:42 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
*
|
1999-11-15 10:13:17 +03:00
|
|
|
* 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.
|
1999-08-28 12:19:56 +04:00
|
|
|
*
|
1999-11-15 10:13:17 +03:00
|
|
|
* 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.
|
2001-07-03 03:40:23 +04:00
|
|
|
*
|
1999-11-25 06:03:07 +03:00
|
|
|
* Bob Miller, kbob@oblix.com
|
|
|
|
* -- plugged core leak.
|
1999-08-28 12:19:56 +04:00
|
|
|
*
|
2001-07-03 03:40:23 +04:00
|
|
|
* Jonas Sicking, sicking@bigfoot.com
|
|
|
|
* -- Cleanup/bugfix/features in Iterator
|
|
|
|
* Added tx prefix to classnames
|
1999-08-28 12:19:56 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "List.h"
|
1999-11-15 10:13:17 +03:00
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
//----------------------------/
|
|
|
|
//- Implementation of txList -/
|
|
|
|
//----------------------------/
|
1999-08-28 12:19:56 +04:00
|
|
|
|
|
|
|
/**
|
2001-07-03 03:40:23 +04:00
|
|
|
* Default constructor for a txList;
|
1999-08-28 12:19:56 +04:00
|
|
|
**/
|
1999-11-15 10:13:17 +03:00
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
txList::txList() {
|
1999-08-28 12:19:56 +04:00
|
|
|
firstItem = 0;
|
|
|
|
lastItem = 0;
|
|
|
|
itemCount = 0;
|
2001-07-03 03:40:23 +04:00
|
|
|
} //-- txList;
|
1999-08-28 12:19:56 +04:00
|
|
|
|
|
|
|
/**
|
2001-07-03 03:40:23 +04:00
|
|
|
* txList destructor, cleans up ListItems, but will not delete the Object
|
1999-08-28 12:19:56 +04:00
|
|
|
* references
|
|
|
|
*/
|
2001-07-03 03:40:23 +04:00
|
|
|
txList::~txList() {
|
1999-08-28 12:19:56 +04:00
|
|
|
ListItem* item = firstItem;
|
|
|
|
while (item) {
|
|
|
|
ListItem* tItem = item;
|
|
|
|
item = item->nextItem;
|
|
|
|
delete tItem;
|
|
|
|
}
|
2001-07-03 03:40:23 +04:00
|
|
|
} //-- ~txList
|
1999-08-28 12:19:56 +04:00
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
void txList::insert(int index, void* objPtr) {
|
1999-08-28 12:19:56 +04:00
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
if (index >= itemCount) {
|
1999-08-28 12:19:56 +04:00
|
|
|
insertBefore(objPtr, 0);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
//-- add to middle of list
|
|
|
|
ListItem* nextItem = firstItem;
|
2001-07-03 03:40:23 +04:00
|
|
|
for (int i = 0; i < index; i++)
|
|
|
|
nextItem = nextItem->nextItem;
|
1999-08-28 12:19:56 +04:00
|
|
|
insertBefore(objPtr, nextItem);
|
|
|
|
}
|
|
|
|
} //-- insert
|
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
void txList::add(void* objPtr) {
|
|
|
|
insertBefore(objPtr, 0);
|
1999-08-28 12:19:56 +04:00
|
|
|
} //-- add
|
|
|
|
|
2000-05-29 11:14:03 +04:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
**/
|
2001-07-03 03:40:23 +04:00
|
|
|
void* txList::get(int index) {
|
2000-05-29 11:14:03 +04:00
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
if (index < 0 || index >= itemCount)
|
|
|
|
return 0;
|
2000-05-29 11:14:03 +04:00
|
|
|
|
|
|
|
int c = 0;
|
|
|
|
ListItem* item = firstItem;
|
2001-04-03 16:38:01 +04:00
|
|
|
while ((c != index) && item) {
|
2000-05-29 11:14:03 +04:00
|
|
|
item = item->nextItem;
|
|
|
|
++c;
|
|
|
|
}
|
|
|
|
|
2001-04-03 16:38:01 +04:00
|
|
|
if (item)
|
|
|
|
return item->objPtr;
|
|
|
|
return 0;
|
2000-05-29 11:14:03 +04:00
|
|
|
} //-- get(int)
|
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
txList::ListItem* txList::getFirstItem() {
|
1999-08-28 12:19:56 +04:00
|
|
|
return firstItem;
|
|
|
|
} //-- getFirstItem
|
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
txList::ListItem* txList::getLastItem() {
|
1999-08-28 12:19:56 +04:00
|
|
|
return lastItem;
|
|
|
|
} //-- getLastItem
|
|
|
|
|
|
|
|
/**
|
2001-07-03 03:40:23 +04:00
|
|
|
* Returns the number of items in this txList
|
1999-08-28 12:19:56 +04:00
|
|
|
**/
|
2001-06-26 18:10:28 +04:00
|
|
|
PRInt32 List::getLength() {
|
1999-08-28 12:19:56 +04:00
|
|
|
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
|
2001-07-03 03:40:23 +04:00
|
|
|
* beginning of the txList (ie, insert after nothing).
|
1999-08-28 12:19:56 +04:00
|
|
|
* This method assumes refItem is a member of this list, and since this
|
|
|
|
* is a private method, I feel that's a valid assumption
|
|
|
|
**/
|
2001-07-03 03:40:23 +04:00
|
|
|
void txList::insertAfter(void* objPtr, ListItem* refItem) {
|
1999-08-28 12:19:56 +04:00
|
|
|
//-- if refItem == null insert at front
|
2001-07-03 03:40:23 +04:00
|
|
|
if (!refItem)
|
|
|
|
insertBefore(objPtr, firstItem);
|
|
|
|
else
|
|
|
|
insertBefore(objPtr, refItem->nextItem);
|
1999-08-28 12:19:56 +04:00
|
|
|
} //-- 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
|
2001-07-03 03:40:23 +04:00
|
|
|
* end of the txList (ie, insert before nothing).
|
1999-08-28 12:19:56 +04:00
|
|
|
* This method assumes refItem is a member of this list, and since this
|
|
|
|
* is a private method, I feel that's a valid assumption
|
|
|
|
**/
|
2001-07-03 03:40:23 +04:00
|
|
|
void txList::insertBefore(void* objPtr, ListItem* refItem) {
|
1999-08-28 12:19:56 +04:00
|
|
|
|
|
|
|
ListItem* item = new ListItem;
|
2001-04-03 16:38:01 +04:00
|
|
|
if (!item)
|
|
|
|
return;
|
|
|
|
|
1999-08-28 12:19:56 +04:00
|
|
|
item->objPtr = objPtr;
|
|
|
|
item->nextItem = 0;
|
|
|
|
item->prevItem = 0;
|
|
|
|
|
|
|
|
//-- if refItem == null insert at end
|
|
|
|
if (!refItem) {
|
|
|
|
//-- add to back of list
|
2001-07-03 03:40:23 +04:00
|
|
|
if (lastItem) {
|
1999-08-28 12:19:56 +04:00
|
|
|
lastItem->nextItem = item;
|
|
|
|
item->prevItem = lastItem;
|
|
|
|
}
|
|
|
|
lastItem = item;
|
2001-07-03 03:40:23 +04:00
|
|
|
if (!firstItem)
|
|
|
|
firstItem = item;
|
1999-08-28 12:19:56 +04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
//-- insert before given item
|
|
|
|
item->nextItem = refItem;
|
|
|
|
item->prevItem = refItem->prevItem;
|
|
|
|
refItem->prevItem = item;
|
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
if (item->prevItem)
|
|
|
|
item->prevItem->nextItem = item;
|
|
|
|
else
|
|
|
|
firstItem = item;
|
1999-08-28 12:19:56 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// increase the item count
|
|
|
|
++itemCount;
|
|
|
|
} //-- insertBefore
|
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
void* txList::remove(void* objPtr) {
|
1999-08-28 12:19:56 +04:00
|
|
|
ListItem* item = firstItem;
|
|
|
|
while (item) {
|
|
|
|
if (item->objPtr == objPtr) {
|
|
|
|
remove(item);
|
|
|
|
delete item;
|
|
|
|
return objPtr;
|
|
|
|
}
|
|
|
|
item = item->nextItem;
|
|
|
|
}
|
|
|
|
// not in list
|
|
|
|
return 0;
|
|
|
|
} //-- remove
|
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
txList::ListItem* txList::remove(ListItem* item) {
|
1999-08-28 12:19:56 +04:00
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
if (!item)
|
|
|
|
return item;
|
1999-08-28 12:19:56 +04:00
|
|
|
|
|
|
|
//-- adjust the previous item's next pointer
|
|
|
|
if (item->prevItem) {
|
|
|
|
item->prevItem->nextItem = item->nextItem;
|
|
|
|
}
|
|
|
|
//-- adjust the next item's previous pointer
|
2001-07-03 03:40:23 +04:00
|
|
|
if (item->nextItem) {
|
1999-08-28 12:19:56 +04:00
|
|
|
item->nextItem->prevItem = item->prevItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-- adjust first and last items
|
2001-07-03 03:40:23 +04:00
|
|
|
if (item == firstItem)
|
|
|
|
firstItem = item->nextItem;
|
|
|
|
if (item == lastItem)
|
|
|
|
lastItem = item->prevItem;
|
1999-08-28 12:19:56 +04:00
|
|
|
|
|
|
|
//-- decrease Item count
|
|
|
|
--itemCount;
|
|
|
|
return item;
|
|
|
|
} //-- remove
|
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
//------------------------------------/
|
|
|
|
//- Implementation of txListIterator -/
|
|
|
|
//------------------------------------/
|
1999-08-28 12:19:56 +04:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2001-07-03 03:40:23 +04:00
|
|
|
* Creates a new txListIterator for the given txList
|
|
|
|
* @param list, the txList to create an Iterator for
|
1999-08-28 12:19:56 +04:00
|
|
|
**/
|
2001-07-03 03:40:23 +04:00
|
|
|
txListIterator::txListIterator(txList* list) {
|
1999-08-28 12:19:56 +04:00
|
|
|
this->list = list;
|
|
|
|
currentItem = 0;
|
2001-07-03 03:40:23 +04:00
|
|
|
atEndOfList = MB_FALSE;
|
|
|
|
} //-- txListIterator
|
1999-08-28 12:19:56 +04:00
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
txListIterator::~txListIterator() {
|
1999-08-28 12:19:56 +04:00
|
|
|
//-- overrides default destructor to do nothing
|
2001-07-03 03:40:23 +04:00
|
|
|
} //-- ~txListIterator
|
1999-08-28 12:19:56 +04:00
|
|
|
|
|
|
|
/**
|
2001-07-03 03:40:23 +04:00
|
|
|
* Adds the Object pointer to the txList pointed to by this txListIterator.
|
|
|
|
* The Object pointer is inserted as the next item in the txList
|
|
|
|
* based on the current position within the txList
|
1999-08-28 12:19:56 +04:00
|
|
|
* @param objPtr the Object pointer to add to the list
|
|
|
|
**/
|
2001-07-03 03:40:23 +04:00
|
|
|
void txListIterator::addAfter(void* objPtr) {
|
1999-08-28 12:19:56 +04:00
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
if (currentItem || !atEndOfList)
|
|
|
|
list->insertAfter(objPtr, currentItem);
|
|
|
|
else
|
|
|
|
list->insertBefore(objPtr, 0);
|
1999-08-28 12:19:56 +04:00
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
} //-- addAfter
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds the Object pointer to the txList pointed to by this txListIterator.
|
|
|
|
* The Object pointer is inserted as the previous item in the txList
|
|
|
|
* based on the current position within the txList
|
|
|
|
* @param objPtr the Object pointer to add to the list
|
|
|
|
**/
|
|
|
|
void txListIterator::addBefore(void* objPtr) {
|
|
|
|
|
|
|
|
if (currentItem || atEndOfList)
|
|
|
|
list->insertBefore(objPtr, currentItem);
|
|
|
|
else
|
|
|
|
list->insertAfter(objPtr, 0);
|
|
|
|
|
|
|
|
} //-- addBefore
|
1999-08-28 12:19:56 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
**/
|
2001-07-03 03:40:23 +04:00
|
|
|
MBool txListIterator::hasNext() {
|
1999-08-28 12:19:56 +04:00
|
|
|
MBool hasNext = MB_FALSE;
|
2001-07-03 03:40:23 +04:00
|
|
|
if (currentItem)
|
2001-08-14 11:58:24 +04:00
|
|
|
hasNext = (currentItem->nextItem != 0);
|
2001-07-03 03:40:23 +04:00
|
|
|
else if (!atEndOfList)
|
2001-08-14 11:58:24 +04:00
|
|
|
hasNext = (list->firstItem != 0);
|
2001-07-03 03:40:23 +04:00
|
|
|
|
1999-08-28 12:19:56 +04:00
|
|
|
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
|
|
|
|
**/
|
2001-07-03 03:40:23 +04:00
|
|
|
MBool txListIterator::hasPrevious() {
|
|
|
|
MBool hasPrevious = MB_FALSE;
|
|
|
|
if (currentItem)
|
2001-08-14 11:58:24 +04:00
|
|
|
hasPrevious = (currentItem->prevItem != 0);
|
2001-07-03 03:40:23 +04:00
|
|
|
else if (atEndOfList)
|
2001-08-14 11:58:24 +04:00
|
|
|
hasPrevious = (list->lastItem != 0);
|
2001-07-03 03:40:23 +04:00
|
|
|
|
|
|
|
return hasPrevious;
|
1999-08-28 12:19:56 +04:00
|
|
|
} //-- hasPrevious
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the next Object pointer in the list
|
|
|
|
**/
|
2001-07-03 03:40:23 +04:00
|
|
|
void* txListIterator::next() {
|
1999-08-28 12:19:56 +04:00
|
|
|
|
|
|
|
void* obj = 0;
|
2001-07-03 03:40:23 +04:00
|
|
|
if (currentItem)
|
|
|
|
currentItem = currentItem->nextItem;
|
|
|
|
else if (!atEndOfList)
|
|
|
|
currentItem = list->firstItem;
|
1999-08-28 12:19:56 +04:00
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
if (currentItem)
|
1999-08-28 12:19:56 +04:00
|
|
|
obj = currentItem->objPtr;
|
2001-07-03 03:40:23 +04:00
|
|
|
else
|
|
|
|
atEndOfList = MB_TRUE;
|
1999-08-28 12:19:56 +04:00
|
|
|
|
|
|
|
return obj;
|
|
|
|
} //-- next
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the previous Object in the list
|
|
|
|
**/
|
2001-07-03 03:40:23 +04:00
|
|
|
void* txListIterator::previous() {
|
1999-08-28 12:19:56 +04:00
|
|
|
|
|
|
|
void* obj = 0;
|
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
if (currentItem)
|
|
|
|
currentItem = currentItem->prevItem;
|
|
|
|
else if (atEndOfList)
|
|
|
|
currentItem = list->lastItem;
|
|
|
|
|
|
|
|
if (currentItem)
|
|
|
|
obj = currentItem->objPtr;
|
|
|
|
|
|
|
|
atEndOfList = MB_FALSE;
|
|
|
|
|
1999-08-28 12:19:56 +04:00
|
|
|
return obj;
|
|
|
|
} //-- previous
|
|
|
|
|
2001-07-03 03:40:23 +04:00
|
|
|
/**
|
|
|
|
* Returns the current Object
|
|
|
|
**/
|
|
|
|
void* txListIterator::current() {
|
|
|
|
|
|
|
|
if (currentItem)
|
|
|
|
return currentItem->objPtr;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
} //-- current
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Moves the specified number of steps
|
|
|
|
**/
|
|
|
|
void* txListIterator::advance(int i) {
|
|
|
|
|
|
|
|
void* obj = 0;
|
|
|
|
|
|
|
|
if (i > 0) {
|
2001-10-19 16:09:42 +04:00
|
|
|
if (!currentItem && !atEndOfList) {
|
|
|
|
currentItem = list->firstItem;
|
|
|
|
--i;
|
|
|
|
}
|
2001-07-03 03:40:23 +04:00
|
|
|
for (; currentItem && i > 0; i--)
|
|
|
|
currentItem = currentItem->nextItem;
|
|
|
|
|
|
|
|
atEndOfList = currentItem == 0;
|
|
|
|
}
|
2001-10-19 16:09:42 +04:00
|
|
|
else if (i < 0) {
|
|
|
|
if (!currentItem && atEndOfList) {
|
|
|
|
currentItem = list->lastItem;
|
|
|
|
++i;
|
|
|
|
}
|
2001-07-03 03:40:23 +04:00
|
|
|
for (; currentItem && i < 0; i++)
|
|
|
|
currentItem = currentItem->prevItem;
|
|
|
|
|
|
|
|
atEndOfList = MB_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (currentItem)
|
|
|
|
obj = currentItem->objPtr;
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
} //-- advance
|
|
|
|
|
1999-08-28 12:19:56 +04:00
|
|
|
/**
|
|
|
|
* Removes the Object last returned by the next() or previous() methods;
|
|
|
|
* @return the removed Object pointer
|
|
|
|
**/
|
2001-07-03 03:40:23 +04:00
|
|
|
void* txListIterator::remove() {
|
1999-08-28 12:19:56 +04:00
|
|
|
|
|
|
|
void* obj = 0;
|
|
|
|
if (currentItem) {
|
|
|
|
obj = currentItem->objPtr;
|
2001-07-03 03:40:23 +04:00
|
|
|
txList::ListItem* item = currentItem;
|
1999-08-28 12:19:56 +04:00
|
|
|
previous(); //-- make previous item the current item
|
|
|
|
list->remove(item);
|
1999-11-25 06:03:07 +03:00
|
|
|
delete item;
|
1999-08-28 12:19:56 +04:00
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
} //-- remove
|
|
|
|
|
|
|
|
/**
|
2001-07-03 03:40:23 +04:00
|
|
|
* Resets the current location within the txList to the beginning of the txList
|
1999-08-28 12:19:56 +04:00
|
|
|
**/
|
2001-07-03 03:40:23 +04:00
|
|
|
void txListIterator::reset() {
|
|
|
|
atEndOfList = MB_FALSE;
|
1999-08-28 12:19:56 +04:00
|
|
|
currentItem = 0;
|
|
|
|
} //-- reset
|
|
|
|
|
|
|
|
/**
|
2001-07-03 03:40:23 +04:00
|
|
|
* Move the iterator to right after the last element
|
1999-08-28 12:19:56 +04:00
|
|
|
**/
|
2001-07-03 03:40:23 +04:00
|
|
|
void txListIterator::resetToEnd() {
|
|
|
|
atEndOfList = MB_TRUE;
|
|
|
|
currentItem = 0;
|
|
|
|
} //-- moveToEnd
|