summaryrefslogtreecommitdiff
path: root/mcast/netcv2dvbip/clist.c
diff options
context:
space:
mode:
Diffstat (limited to 'mcast/netcv2dvbip/clist.c')
-rw-r--r--mcast/netcv2dvbip/clist.c196
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]);
+ }
+}
+