home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
-
- // wfList.cpp
- // A doubly linked list manager
- //
- // Created by dp Suresh <dp@netscape.com>
-
- #ifdef TEST
- #include <stream.h>
- #endif /* TEST */
-
-
- #include <string.h> // for NULL
-
- #include "wfList.h"
-
-
- //-------------//
- // Constructor //
- //-------------//
-
- wfList::wfList(WF_FREE_FUNC freeFunc)
- : head(NULL), tail(NULL), freeItemFunc(freeFunc)
- {
- }
-
-
- //------------//
- // Destructor //
- //------------//
-
- wfList::~wfList()
- {
- removeAll();
- }
-
-
- //----------------------------------//
- // Implementation of public methods //
- //----------------------------------//
-
-
- wfList::ERROR_CODE
- wfList::add(void *item)
- {
- struct wfListElement *ele = new (struct wfListElement);
-
- if (!ele) return (NO_MEMORY);
-
- ele->item = item;
- ele->next = NULL;
- ele->prev = NULL;
-
- ERROR_CODE ret = listAdd(ele);
- if (ret != SUCCESS)
- {
- delete ele;
- }
-
- return (ret);
- }
-
- wfList::ERROR_CODE
- wfList::remove (void *item)
- {
- struct wfListElement *ele = find(item);
- if (ele == NULL)
- {
- return (NOT_FOUND);
- }
-
- ERROR_CODE ret = listRemove(ele);
- if (ret == SUCCESS)
- {
- listDeleteItem(ele->item);
- delete ele;
- }
- return (ret);
- }
-
- wfList::ERROR_CODE
- wfList::removeAll (void)
- {
- ERROR_CODE ret = SUCCESS;
- while (head && ret == SUCCESS)
- {
- wfListElement *ele = head;
- ERROR_CODE ret = listRemove(ele);
- if (ret != SUCCESS)
- {
- break;
- }
- listDeleteItem(ele->item);
- delete ele;
- }
- return (ret);
- }
-
- wfList::ERROR_CODE
- wfList::isEmpty()
- {
- return ((head == NULL) ? WF_TRUE : WF_FALSE);
- }
-
- wfList::ERROR_CODE
- wfList::isExist(void *item)
- {
- wfListElement *tmp = find(item);
- return((tmp != NULL) ? WF_TRUE : WF_FALSE);
- }
-
- wfList::ERROR_CODE
- wfList::iterate(IteratorFunction fn)
- {
- struct wfListElement *tmp = head;
- if (!fn) return(GENERIC_ERROR);
- if (!tmp) return(GENERIC_ERROR);
-
- while (tmp)
- {
- void *item = tmp->item;
- struct wfListElement *next = tmp->next;
-
- ERROR_CODE ret = (*fn)(item);
- switch (ret) {
- case GENERIC_ERROR:
- return (ret);
- case SUCCESS:
- default:
- break;
- }
-
- tmp = next;
- }
- return (SUCCESS);
- }
-
- int
- wfList::count(void)
- {
- wfListElement *tmp = head;
- int n = 0;
- for (; tmp; tmp = tmp->next)
- {
- n++;
- }
- return (n);
- }
-
- //-----------------------------------//
- // Implementation of Private methods //
- //-----------------------------------//
-
- wfList::ERROR_CODE
- wfList::listAdd(struct wfListElement *ele)
- {
- if (isEmpty() == WF_TRUE)
- {
- // Empty list
- head = tail = ele;
- }
- else
- {
- // Add at the tail
- tail->next = ele;
- ele->prev = tail;
- tail = ele;
- }
- return (SUCCESS);
- }
-
-
- wfList::ERROR_CODE
- wfList::listRemove (struct wfListElement *ele)
- {
- if (ele->prev)
- {
- // Not the first element
- ele->prev->next = ele->next;
- }
- else
- {
- // First element
- head = ele->next;
- }
-
- if (ele->next)
- {
- // Not the last element
- ele->next->prev = ele->prev;
- }
- else
- {
- // Last element
- tail = ele->prev;
- }
- return (SUCCESS);
- }
-
- void
- wfList::listDeleteItem(void *item)
- {
- if (freeItemFunc != NULL)
- {
- (*freeItemFunc)(this, item);
- }
- return;
- }
-
-
- struct wfListElement *
- wfList::find(void *item)
- {
- wfListElement *tmp = head;
- while (tmp && tmp->item != item) tmp = tmp->next;
- return (tmp);
- }
-
-
- #ifdef TEST
- wfList::ERROR_CODE
- print(void *item)
- {
- cout << "--> " << (int)item << " ";
- return (wfList::SUCCESS);
- }
-
- main()
- {
- wfList l;
-
- cout << "isEmpty() : " << l.isEmpty() << "\n";
- cout << "isExist(5): " << l.isExist((void *)5) << "\n";
- cout << "remove(5) : " << l.remove((void *)5) << "\n";
- cout << "count() : " << l.count() << "\n";
- l.iterate(print); cout << "\n";
-
- cout << "add(5) : " << l.add((void *)5) << "\n";
- cout << "add(6) : " << l.add((void *)6) << "\n";
- cout << "add(7) : " << l.add((void *)7) << "\n";
- cout << "add(8) : " << l.add((void *)8) << "\n";
- cout << "add(9) : " << l.add((void *)9) << "\n";
- cout << "isEmpty() : " << l.isEmpty() << "\n";
- cout << "count() : " << l.count() << "\n";
-
- l.iterate(print); cout << "\n";
-
- cout << "isExist(5): " << l.isExist((void *)5) << "\n";
- cout << "isExist(8): " << l.isExist((void *)8) << "\n";
- cout << "isExist(0xCAFE): " << l.isExist((void *)0xCAFE) << "\n";
- cout << "isExist(9): " << l.isExist((void *)9) << "\n";
-
- cout << "remove(5) : " << l.remove((void *)5) << "\n";
- l.iterate(print); cout << "\n";
- cout << "remove(8) : " << l.remove((void *)8) << "\n";
- l.iterate(print); cout << "\n";
- cout << "remove(0xCAFE) : " << l.remove((void *)0xCAFE) << "\n";
- l.iterate(print); cout << "\n";
- cout << "remove(9) : " << l.remove((void *)9) << "\n";
- cout << "count() : " << l.count() << "\n";
- l.iterate(print); cout << "\n";
-
- return(0);
- }
-
- #if 0
- // The above test should yeild this result
- isEmpty() : 1
- isExist(5): 0
- remove(5) : 4
-
- add(5) : 2
- add(6) : 2
- add(7) : 2
- add(8) : 2
- add(9) : 2
- isEmpty() : 0
- --> 5 --> 6 --> 7 --> 8 --> 9
- isExist(5): 1
- isExist(8): 1
- isExist(0xCAFE): 0
- isExist(9): 1
- remove(5) : 2
- --> 6 --> 7 --> 8 --> 9
- remove(8) : 2
- --> 6 --> 7 --> 9
- remove(0xCAFE) : 4
- --> 6 --> 7 --> 9
- remove(9) : 2
- --> 6 --> 7
- wfList::delete (deleting 6...)
- wfList::delete (deleting 7...)
- #endif /* 0 */
- #endif /* TEST */
-
-