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