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