diff options
Diffstat (limited to 'mcast/netcv2dvbip/clist.c')
-rw-r--r-- | mcast/netcv2dvbip/clist.c | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/mcast/netcv2dvbip/clist.c b/mcast/netcv2dvbip/clist.c new file mode 100644 index 0000000..1916e08 --- /dev/null +++ b/mcast/netcv2dvbip/clist.c @@ -0,0 +1,196 @@ +/* + * tools.c: Various tools + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: tools.c 2.3 2009/05/31 11:43:24 kls Exp $ + */ + +#include <stdlib.h> + +#include "clist.h" + + +// --- cListObject ----------------------------------------------------------- + +cListObject::cListObject(void) +{ + prev = next = NULL; +} + +cListObject::~cListObject() +{ +} + +void cListObject::Append(cListObject *Object) +{ + next = Object; + Object->prev = this; +} + +void cListObject::Insert(cListObject *Object) +{ + prev = Object; + Object->next = this; +} + +void cListObject::Unlink(void) +{ + if (next) + next->prev = prev; + if (prev) + prev->next = next; + next = prev = NULL; +} + +int cListObject::Index(void) const +{ + cListObject *p = prev; + int i = 0; + + while (p) { + i++; + p = p->prev; + } + return i; +} + +// --- cListBase ------------------------------------------------------------- + +cListBase::cListBase(void) +{ + objects = lastObject = NULL; + count = 0; +} + +cListBase::~cListBase() +{ + Clear(); +} + +void cListBase::Add(cListObject *Object, cListObject *After) +{ + if (After && After != lastObject) { + After->Next()->Insert(Object); + After->Append(Object); + } + else { + if (lastObject) + lastObject->Append(Object); + else + objects = Object; + lastObject = Object; + } + count++; +} + +void cListBase::Ins(cListObject *Object, cListObject *Before) +{ + if (Before && Before != objects) { + Before->Prev()->Append(Object); + Before->Insert(Object); + } + else { + if (objects) + objects->Insert(Object); + else + lastObject = Object; + objects = Object; + } + count++; +} + +void cListBase::Del(cListObject *Object, bool DeleteObject) +{ + if (Object == objects) + objects = Object->Next(); + if (Object == lastObject) + lastObject = Object->Prev(); + Object->Unlink(); + if (DeleteObject) + delete Object; + count--; +} + +void cListBase::Move(int From, int To) +{ + Move(Get(From), Get(To)); +} + +void cListBase::Move(cListObject *From, cListObject *To) +{ + if (From && To) { + if (From->Index() < To->Index()) + To = To->Next(); + if (From == objects) + objects = From->Next(); + if (From == lastObject) + lastObject = From->Prev(); + From->Unlink(); + if (To) { + if (To->Prev()) + To->Prev()->Append(From); + From->Append(To); + } + else { + lastObject->Append(From); + lastObject = From; + } + if (!From->Prev()) + objects = From; + } +} + +void cListBase::Clear(void) +{ + while (objects) { + cListObject *object = objects->Next(); + delete objects; + objects = object; + } + objects = lastObject = NULL; + count = 0; +} + +cListObject *cListBase::Get(int Index) const +{ + if (Index < 0) + return NULL; + cListObject *object = objects; + while (object && Index-- > 0) + object = object->Next(); + return object; +} + +static int CompareListObjects(const void *a, const void *b) +{ + const cListObject *la = *(const cListObject **)a; + const cListObject *lb = *(const cListObject **)b; + return la->Compare(*lb); +} + +void cListBase::Sort(void) +{ + int n = Count(); +#ifndef WIN32 + cListObject *a[n]; +#else + cListObject **a; + a = new cListObject*[n]; +#endif + cListObject *object = objects; + int i = 0; + while (object && i < n) { + a[i++] = object; + object = object->Next(); + } + qsort(a, n, sizeof(cListObject *), CompareListObjects); + objects = lastObject = NULL; + for (i = 0; i < n; i++) { + a[i]->Unlink(); + count--; + Add(a[i]); + } +} + |