Back to index

lightning-sunbird  0.9+nobinonly
txList.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is TransforMiiX XSLT processor code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * The MITRE Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Keith Visco <kvisco@ziplink.net> (Original Author)
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "txList.h"
00040 
00041   //----------------------------/
00042  //- Implementation of txList -/
00043 //----------------------------/
00044 
00049 txList::txList() {
00050    firstItem  = 0;
00051    lastItem   = 0;
00052    itemCount  = 0;
00053 } //-- txList;
00054 
00059 txList::~txList() {
00060     clear();
00061 } //-- ~txList
00062 
00063 nsresult txList::insert(int index, void* objPtr)
00064 {
00065     if (index >= itemCount) {
00066         return insertBefore(objPtr, 0);
00067     }
00068     // add inside the list
00069     ListItem* nextItem = firstItem;
00070     for (int i = 0; i < index; i++)
00071         nextItem = nextItem->nextItem;
00072     return insertBefore(objPtr, nextItem);
00073 } //-- insert
00074 
00075 nsresult txList::add(void* objPtr)
00076 {
00077     return insertBefore(objPtr, 0);
00078 } //-- add
00079 
00089 void* txList::get(int index) {
00090 
00091     if (index < 0 || index >= itemCount)
00092         return 0;
00093 
00094     int c = 0;
00095     ListItem* item = firstItem;
00096     while ((c != index) && item) {
00097         item = item->nextItem;
00098         ++c;
00099     }
00100 
00101     if (item)
00102         return item->objPtr;
00103     return 0;
00104 } //-- get(int)
00105 
00106 txList::ListItem* txList::getFirstItem() {
00107     return firstItem;
00108 } //-- getFirstItem
00109 
00110 txList::ListItem* txList::getLastItem() {
00111     return lastItem;
00112 } //-- getLastItem
00113 
00117 PRInt32 List::getLength() {
00118    return itemCount;
00119 } //-- getLength
00120 
00121 
00129 nsresult txList::insertAfter(void* objPtr, ListItem* refItem)
00130 {
00131     //-- if refItem == null insert at front
00132     if (!refItem)
00133         return insertBefore(objPtr, firstItem);
00134     return insertBefore(objPtr, refItem->nextItem);
00135 } //-- insertAfter
00136 
00144 nsresult txList::insertBefore(void* objPtr, ListItem* refItem)
00145 {
00146     ListItem* item = new ListItem;
00147     NS_ENSURE_TRUE(item, NS_ERROR_OUT_OF_MEMORY);
00148 
00149     item->objPtr = objPtr;
00150     item->nextItem = 0;
00151     item->prevItem = 0;
00152 
00153     //-- if refItem == null insert at end
00154     if (!refItem) {
00155         //-- add to back of list
00156         if (lastItem) {
00157             lastItem->nextItem = item;
00158             item->prevItem = lastItem;
00159         }
00160         lastItem = item;
00161         if (!firstItem)
00162             firstItem = item;
00163     }
00164     else {
00165         //-- insert before given item
00166         item->nextItem = refItem;
00167         item->prevItem = refItem->prevItem;
00168         refItem->prevItem = item;
00169 
00170         if (item->prevItem)
00171             item->prevItem->nextItem = item;
00172         else
00173             firstItem = item;
00174     }
00175 
00176     // increase the item count
00177     ++itemCount;
00178     
00179     return NS_OK;
00180 } //-- insertBefore
00181 
00182 void* txList::remove(void* objPtr) {
00183    ListItem* item = firstItem;
00184    while (item) {
00185       if (item->objPtr == objPtr) {
00186          remove(item);
00187          delete item;
00188          return objPtr;
00189       }
00190       item = item->nextItem;
00191    }
00192    // not in list
00193    return 0;
00194 } //-- remove
00195 
00196 txList::ListItem* txList::remove(ListItem* item) {
00197 
00198     if (!item)
00199         return item;
00200 
00201     //-- adjust the previous item's next pointer
00202     if (item->prevItem) {
00203         item->prevItem->nextItem = item->nextItem;
00204     }
00205     //-- adjust the next item's previous pointer
00206     if (item->nextItem) {
00207         item->nextItem->prevItem = item->prevItem;
00208     }
00209 
00210     //-- adjust first and last items
00211     if (item == firstItem)
00212         firstItem = item->nextItem;
00213     if (item == lastItem)
00214         lastItem = item->prevItem;
00215 
00216     //-- decrease Item count
00217     --itemCount;
00218     return item;
00219 } //-- remove
00220 
00221 void txList::clear()
00222 {
00223     ListItem* item = firstItem;
00224     while (item) {
00225         ListItem* tItem = item;
00226         item = item->nextItem;
00227         delete tItem;
00228     }
00229     firstItem  = 0;
00230     lastItem   = 0;
00231     itemCount  = 0;
00232 }
00233 
00234   //------------------------------------/
00235  //- Implementation of txListIterator -/
00236 //------------------------------------/
00237 
00238 
00243 txListIterator::txListIterator(txList* list) {
00244    this->list   = list;
00245    currentItem  = 0;
00246    atEndOfList  = MB_FALSE;
00247 } //-- txListIterator
00248 
00249 txListIterator::~txListIterator() {
00250   //-- overrides default destructor to do nothing
00251 } //-- ~txListIterator
00252 
00259 nsresult txListIterator::addAfter(void* objPtr)
00260 {
00261     if (currentItem || !atEndOfList)
00262         return list->insertAfter(objPtr, currentItem);
00263     return list->insertBefore(objPtr, 0);
00264 
00265 } //-- addAfter
00266 
00273 nsresult txListIterator::addBefore(void* objPtr)
00274 {
00275     if (currentItem || atEndOfList)
00276         return list->insertBefore(objPtr, currentItem);
00277     return list->insertAfter(objPtr, 0);
00278 
00279 } //-- addBefore
00280 
00286 MBool txListIterator::hasNext() {
00287     MBool hasNext = MB_FALSE;
00288     if (currentItem)
00289         hasNext = (currentItem->nextItem != 0);
00290     else if (!atEndOfList)
00291         hasNext = (list->firstItem != 0);
00292 
00293     return hasNext;
00294 } //-- hasNext
00295 
00301 MBool txListIterator::hasPrevious() {
00302     MBool hasPrevious = MB_FALSE;
00303     if (currentItem)
00304         hasPrevious = (currentItem->prevItem != 0);
00305     else if (atEndOfList)
00306         hasPrevious = (list->lastItem != 0);
00307 
00308     return hasPrevious;
00309 } //-- hasPrevious
00310 
00314 void* txListIterator::next() {
00315 
00316     void* obj = 0;
00317     if (currentItem)
00318         currentItem = currentItem->nextItem;
00319     else if (!atEndOfList)
00320         currentItem = list->firstItem;
00321 
00322     if (currentItem)
00323         obj = currentItem->objPtr;
00324     else
00325         atEndOfList = MB_TRUE;
00326 
00327     return obj;
00328 } //-- next
00329 
00333 void* txListIterator::previous() {
00334 
00335     void* obj = 0;
00336 
00337     if (currentItem)
00338         currentItem = currentItem->prevItem;
00339     else if (atEndOfList)
00340         currentItem = list->lastItem;
00341     
00342     if (currentItem)
00343         obj = currentItem->objPtr;
00344 
00345     atEndOfList = MB_FALSE;
00346 
00347     return obj;
00348 } //-- previous
00349 
00353 void* txListIterator::current() {
00354 
00355     if (currentItem)
00356         return currentItem->objPtr;
00357 
00358     return 0;
00359 } //-- current
00360 
00364 void* txListIterator::advance(int i) {
00365 
00366     void* obj = 0;
00367 
00368     if (i > 0) {
00369         if (!currentItem && !atEndOfList) {
00370             currentItem = list->firstItem;
00371             --i;
00372         }
00373         for (; currentItem && i > 0; i--)
00374             currentItem = currentItem->nextItem;
00375         
00376         atEndOfList = currentItem == 0;
00377     }
00378     else if (i < 0) {
00379         if (!currentItem && atEndOfList) {
00380             currentItem = list->lastItem;
00381             ++i;
00382         }
00383         for (; currentItem && i < 0; i++)
00384             currentItem = currentItem->prevItem;
00385 
00386         atEndOfList = MB_FALSE;
00387     }
00388 
00389     if (currentItem)
00390         obj = currentItem->objPtr;
00391 
00392     return obj;
00393 } //-- advance
00394 
00399 void* txListIterator::remove() {
00400 
00401     void* obj = 0;
00402     if (currentItem) {
00403         obj = currentItem->objPtr;
00404         txList::ListItem* item = currentItem;
00405         previous(); //-- make previous item the current item
00406         list->remove(item);
00407         delete item;
00408     }
00409     return obj;
00410 } //-- remove
00411 
00415 void txListIterator::reset() {
00416    atEndOfList = MB_FALSE;
00417    currentItem = 0;
00418 } //-- reset
00419 
00423 void txListIterator::resetToEnd() {
00424    atEndOfList = MB_TRUE;
00425    currentItem = 0;
00426 } //-- moveToEnd