00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <stdlib.h>
00021 #include <string.h>
00022
00023 #include <glib.h>
00024
00025 #include "index.h"
00026
00027 struct _Index {
00028 void * * data;
00029 int count, size;
00030 };
00031
00032 typedef struct {
00033 int (* compare) (const void * a, const void * b);
00034 } CompareWrapper;
00035
00036 typedef struct {
00037 int (* compare) (const void * a, const void * b, void * data);
00038 void * data;
00039 } CompareWrapper2;
00040
00041 Index * index_new (void)
00042 {
00043 Index * index = g_slice_new (Index);
00044
00045 index->data = NULL;
00046 index->count = 0;
00047 index->size = 0;
00048
00049 return index;
00050 }
00051
00052 void index_free (Index * index)
00053 {
00054 g_free (index->data);
00055 g_slice_free (Index, index);
00056 }
00057
00058 int index_count (Index * index)
00059 {
00060 return index->count;
00061 }
00062
00063 void index_allocate (Index * index, int size)
00064 {
00065 if (size <= index->size)
00066 return;
00067
00068 if (! index->size)
00069 index->size = 64;
00070
00071 while (size > index->size)
00072 index->size <<= 1;
00073
00074 index->data = g_realloc (index->data, sizeof (void *) * index->size);
00075 }
00076
00077 void index_set (Index * index, int at, void * value)
00078 {
00079 index->data[at] = value;
00080 }
00081
00082 void * index_get (Index * index, int at)
00083 {
00084 return index->data[at];
00085 }
00086
00087 static void make_room (Index * index, int at, int count)
00088 {
00089 index_allocate (index, index->count + count);
00090
00091 if (at < index->count)
00092 memmove (index->data + at + count, index->data + at, sizeof (void *) *
00093 (index->count - at));
00094
00095 index->count += count;
00096 }
00097
00098 void index_insert (Index * index, int at, void * value)
00099 {
00100 make_room (index, at, 1);
00101 index->data[at] = value;
00102 }
00103
00104 void index_append (Index * index, void * value)
00105 {
00106 index_insert (index, index->count, value);
00107 }
00108
00109 void index_copy_set (Index * source, int from, Index * target,
00110 int to, int count)
00111 {
00112 memcpy (target->data + to, source->data + from, sizeof (void *) * count);
00113 }
00114
00115 void index_copy_insert (Index * source, int from, Index * target,
00116 int to, int count)
00117 {
00118 make_room (target, to, count);
00119 memcpy (target->data + to, source->data + from, sizeof (void *) * count);
00120 }
00121
00122 void index_copy_append (Index * source, int from, Index * target,
00123 int count)
00124 {
00125 index_copy_insert (source, from, target, target->count, count);
00126 }
00127
00128 void index_merge_insert (Index * first, int at, Index * second)
00129 {
00130 index_copy_insert (second, 0, first, at, second->count);
00131 }
00132
00133 void index_merge_append (Index * first, Index * second)
00134 {
00135 index_copy_insert (second, 0, first, first->count, second->count);
00136 }
00137
00138 void index_move (Index * index, int from, int to, int count)
00139 {
00140 memmove (index->data + to, index->data + from, sizeof (void *) * count);
00141 }
00142
00143 void index_delete (Index * index, int at, int count)
00144 {
00145 index->count -= count;
00146 memmove (index->data + at, index->data + at + count, sizeof (void *) *
00147 (index->count - at));
00148 }
00149
00150 static int index_compare (const void * ap, const void * bp, void * _wrapper)
00151 {
00152 CompareWrapper * wrapper = _wrapper;
00153 return wrapper->compare (* (const void * *) ap, * (const void * *) bp);
00154 }
00155
00156 void index_sort (Index * index, int (* compare) (const void *, const void *))
00157 {
00158 CompareWrapper wrapper = {compare};
00159 g_qsort_with_data (index->data, index->count, sizeof (void *),
00160 index_compare, & wrapper);
00161 }
00162
00163 static int index_compare2 (const void * ap, const void * bp, void * _wrapper)
00164 {
00165 CompareWrapper2 * wrapper = _wrapper;
00166 return wrapper->compare (* (const void * *) ap, * (const void * *) bp, wrapper->data);
00167 }
00168
00169 void index_sort_with_data (Index * index, int (* compare)
00170 (const void * a, const void * b, void * data), void * data)
00171 {
00172 CompareWrapper2 wrapper = {compare, data};
00173 g_qsort_with_data (index->data, index->count, sizeof (void *),
00174 index_compare2, & wrapper);
00175 }