/* * 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 #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]); } }