//============================================================================= // // File : class_list.cpp // Creation date : Wed Sep 09 2000 21:07:55 by Szymon Stefanek // // This file is part of the KVirc irc client distribution // Copyright (C) 2000-2008 Szymon Stefanek (pragma at kvirc dot net) // // This program is FREE software. You can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your opinion) any later version. // // This program is distributed in the HOPE that it will be USEFUL, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, write to the Free Software Foundation, // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //============================================================================ #include "kvi_debug.h" #include "kvi_malloc.h" #include "kvi_locale.h" #include "class_list.h" #include /* @doc: list @keyterms: list object class, sorted list @title: list class @type: class @short: Abstracts a double linked list of strings @inherits: [class]object[/class] @description: This object class abstracts a double linked list of strings. You can insert/remove items by zero based position, at the end (tail) or at the beginning (head). The list incorporates an efficient iteration method by using the [classfnc:list]$moveFirst[/classfnc](),[classfnc:list]$moveLast[/classfnc](), [classfnc:list]$moveNext[/classfnc](),[classfnc:list]$movePrev[/classfnc](), [classfnc:list]$current[/classfnc]() and [classfnc:list]$eof[/classfnc]() functions. @functions: !fn: $count() Returns the number of items in the list !fn: $isEmpty() Returns $true if the list is empty, $false otherwise. !fn: $clear() Removes all the items from the list.This is the same as [classfnc:list]$removeAll[/classfnc](). !fn: $removeAll() Removes all the items from the list. This is the same as [classfnc:list]$clear[/classfnc](). !fn: $append() Inserts the at the end (tail) of the list. !fn: $prepend() Inserts the at the beginning (head) of the list. !fn: $insert(,) Inserts the at zero-based position in the list. If is greater or equal to [classfnc:list]$count[/classfnc]() then the item is simply appended to the end of the list. !fn: $add(,) This is exactly the same as [classfnc:list]$insert[/classfnc](). !fn: $item() Returns the item at zero-based . If is greater or equal to [classfnc:list]$count[/classfnc]() (beyond the end of the list) then [fnc]$nothing[/fnc] is returned. !fn: $remove() Removes the item at zero-based . Returns $true if the item was succesfully removed and $false otherwise (i.e. pointed beyond the end of the list). !fn: $removeFirst() Removes the first item from the list. Returns $true if the item was succesfully removed (the list was not empty) and $false otherwise. !fn: $removeLast() Removes the last item from the list. Returns $true if the item was succesfully removed (the list was not empty) and $false otherwise. !fn: $removeCurrent() Removes the current item from the list. Returns $true if the item was succesfully removed or $false otherwise. Invalidates any iteration operation. !fn: $moveFirst() Moves the iterator to the first item in the list and returns $true if the move was succesfull (i.e., the list is not empty) and $false otherwise. !fn: $moveLast() Moves the iterator to the last item in the list and returns $true if the move was succesfull (i.e., the list is not empty) and $false otherwise. !fn: $movePrev() Moves the iterator to the previous item and returns $true if the move was succesfull (i.e., there IS a previous item) and $false otherwise. !fn: $moveNext() Moves the iterator to the next item and returns $true if the move was succesfull (i.e., there IS a next item) and $false otherwise. !fn: $eof() Returns $true if the iterator points to a valid item in the list (and thus [classfnc:list]$current[/classfnc]() would return a valid value) and $false otherwise. !fn: $current() Returns the item pointed by the current iterator or [fnc]$nothing[/fnc] is the iterator is not valid (points beyond the end of the list). */ KVSO_BEGIN_REGISTERCLASS(KviKvsObject_list,"list","object") KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,count) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,isEmpty) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,clear) KVSO_REGISTER_HANDLER(KviKvsObject_list,"removeAll",clear) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,append) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,prepend) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,insert) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,insert) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,at) KVSO_REGISTER_HANDLER(KviKvsObject_list,"item",at) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,remove) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,removeFirst) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,removeLast) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,removeCurrent) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,moveFirst) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,moveNext) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,movePrev) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,moveLast) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,sort) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,eof) KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_list,current) KVSO_END_REGISTERCLASS(KviKvsObject_list) KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_list,KviKvsObject) m_pDataList = new KviPointerList; m_pDataList->setAutoDelete(true); KVSO_END_CONSTRUCTOR(KviKvsObject_list) KVSO_BEGIN_DESTRUCTOR(KviKvsObject_list) delete m_pDataList; m_pDataList = 0; KVSO_END_CONSTRUCTOR(KviKvsObject_list) KVSO_CLASS_FUNCTION(list,current) { CHECK_INTERNAL_POINTER(m_pDataList) if(!m_pDataList->count()) { c->returnValue()->setNothing(); return true; } KviKvsVariant * v = m_pDataList->safeCurrent(); if(v)c->returnValue()->copyFrom(*v); else c->returnValue()->setNothing(); return true; } KVSO_CLASS_FUNCTION(list,eof) { CHECK_INTERNAL_POINTER(m_pDataList) c->returnValue()->setBoolean(m_pDataList->current() != 0); return true; } KVSO_CLASS_FUNCTION(list,moveLast) { CHECK_INTERNAL_POINTER(m_pDataList) c->returnValue()->setBoolean(m_pDataList->last() != 0); return true; } KVSO_CLASS_FUNCTION(list,movePrev) { CHECK_INTERNAL_POINTER(m_pDataList) c->returnValue()->setBoolean(m_pDataList->prev() != 0); return true; } KVSO_CLASS_FUNCTION(list,moveNext) { CHECK_INTERNAL_POINTER(m_pDataList) c->returnValue()->setBoolean(m_pDataList->next() != 0); return true; } KVSO_CLASS_FUNCTION(list,moveFirst) { CHECK_INTERNAL_POINTER(m_pDataList) c->returnValue()->setBoolean(m_pDataList->first() != 0); return true; } KVSO_CLASS_FUNCTION(list,removeLast) { CHECK_INTERNAL_POINTER(m_pDataList) c->returnValue()->setBoolean(m_pDataList->removeLast()); return true; } KVSO_CLASS_FUNCTION(list,removeCurrent) { CHECK_INTERNAL_POINTER(m_pDataList) if(m_pDataList->current()) { m_pDataList->removeCurrent(); c->returnValue()->setBoolean(true); } else { c->returnValue()->setBoolean(false); } return true; } KVSO_CLASS_FUNCTION(list,removeFirst) { CHECK_INTERNAL_POINTER(m_pDataList) c->returnValue()->setBoolean(m_pDataList->removeFirst()); return true; } KVSO_CLASS_FUNCTION(list,remove) { CHECK_INTERNAL_POINTER(m_pDataList) kvs_uint_t uIndex; KVSO_PARAMETERS_BEGIN(c) KVSO_PARAMETER("index",KVS_PT_UINT,0,uIndex) KVSO_PARAMETERS_END(c) c->returnValue()->setBoolean(m_pDataList->remove(uIndex)); return true; } KVSO_CLASS_FUNCTION(list,at) { CHECK_INTERNAL_POINTER(m_pDataList) kvs_uint_t uIndex; KVSO_PARAMETERS_BEGIN(c) KVSO_PARAMETER("index",KVS_PT_UINT,0,uIndex) KVSO_PARAMETERS_END(c) KviKvsVariant * v = m_pDataList->at(uIndex); if(v)c->returnValue()->copyFrom(*v); else c->returnValue()->setNothing(); return true; } KVSO_CLASS_FUNCTION(list,insert) { CHECK_INTERNAL_POINTER(m_pDataList) kvs_uint_t uIndex; KviKvsVariant * pVar; KVSO_PARAMETERS_BEGIN(c) KVSO_PARAMETER("index",KVS_PT_UINT,0,uIndex) KVSO_PARAMETER("item",KVS_PT_VARIANT,0,pVar) KVSO_PARAMETERS_END(c) m_pDataList->insert(uIndex,new KviKvsVariant(*pVar)); return true; } KVSO_CLASS_FUNCTION(list,prepend) { CHECK_INTERNAL_POINTER(m_pDataList) KviKvsVariant * pVar; KVSO_PARAMETERS_BEGIN(c) KVSO_PARAMETER("item",KVS_PT_VARIANT,0,pVar) KVSO_PARAMETERS_END(c) m_pDataList->prepend(new KviKvsVariant(*pVar)); return true; } KVSO_CLASS_FUNCTION(list,append) { CHECK_INTERNAL_POINTER(m_pDataList) KviKvsVariant * pVar; KVSO_PARAMETERS_BEGIN(c) KVSO_PARAMETER("item",KVS_PT_VARIANT,0,pVar) KVSO_PARAMETERS_END(c) m_pDataList->append(new KviKvsVariant(*pVar)); if (m_pDataList->count()==1) m_pDataList->first(); return true; } KVSO_CLASS_FUNCTION(list,clear) { CHECK_INTERNAL_POINTER(m_pDataList) m_pDataList->clear(); return true; } inline int kvi_compare(const KviKvsVariant * p1,const KviKvsVariant * p2) { return p1->compare(p2); } KVSO_CLASS_FUNCTION(list,sort) { CHECK_INTERNAL_POINTER(m_pDataList) m_pDataList->sort(); return true; } KVSO_CLASS_FUNCTION(list,isEmpty) { CHECK_INTERNAL_POINTER(m_pDataList) c->returnValue()->setBoolean(m_pDataList->isEmpty()); return true; } KVSO_CLASS_FUNCTION(list,count) { CHECK_INTERNAL_POINTER(m_pDataList) c->returnValue()->setInteger(m_pDataList->count()); return true; }