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_malloc (sizeof (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_free (index);
00054 }
00055
00056 gint index_count (struct index * index)
00057 {
00058 return index->count;
00059 }
00060
00061 void index_set (struct index * index, gint at, void * value)
00062 {
00063 index->data[at] = value;
00064 }
00065
00066 void * index_get (struct index * index, gint at)
00067 {
00068 return index->data[at];
00069 }
00070
00071 static void resize_to (struct index * index, gint size)
00072 {
00073 if (size < 100)
00074 size = (size + 9) / 10 * 10;
00075 else if (size < 1000)
00076 size = (size + 99) / 100 * 100;
00077 else
00078 size = (size + 999) / 1000 * 1000;
00079
00080 if (index->size < size)
00081 {
00082 index->data = g_realloc (index->data, sizeof (void *) * size);
00083 index->size = size;
00084 }
00085 }
00086
00087 static void make_room (struct index * index, gint at, gint count)
00088 {
00089 resize_to (index, index->count + count);
00090 memmove (index->data + at + count, index->data + at, sizeof (void *) *
00091 (index->count - at));
00092 index->count += count;
00093 }
00094
00095 void index_insert (struct index * index, gint at, void * value)
00096 {
00097 make_room (index, at, 1);
00098 index->data[at] = value;
00099 }
00100
00101 void index_append (struct index * index, void * value)
00102 {
00103 index_insert (index, index->count, value);
00104 }
00105
00106 void index_copy_set (struct index * source, gint from, struct index * target,
00107 gint to, gint count)
00108 {
00109 memcpy (target->data + to, source->data + from, sizeof (void *) * count);
00110 }
00111
00112 void index_copy_insert (struct index * source, gint from, struct index * target,
00113 gint to, gint count)
00114 {
00115 make_room (target, to, count);
00116 memcpy (target->data + to, source->data + from, sizeof (void *) * count);
00117 }
00118
00119 void index_copy_append (struct index * source, gint from, struct index * target,
00120 gint count)
00121 {
00122 index_copy_insert (source, from, target, target->count, count);
00123 }
00124
00125 void index_merge_insert (struct index * first, gint at, struct index * second)
00126 {
00127 index_copy_insert (second, 0, first, at, second->count);
00128 }
00129
00130 void index_merge_append (struct index * first, struct index * second)
00131 {
00132 index_copy_insert (second, 0, first, first->count, second->count);
00133 }
00134
00135 void index_move (struct index * index, gint from, gint to, gint count)
00136 {
00137 memmove (index->data + to, index->data + from, sizeof (void *) * count);
00138 }
00139
00140 void index_delete (struct index * index, gint at, gint count)
00141 {
00142 index->count -= count;
00143 memmove (index->data + at, index->data + at + count, sizeof (void *) *
00144 (index->count - at));
00145 }
00146
00147 static gint index_compare (const void * a, const void * b, void * _compare)
00148 {
00149 gint (* compare) (const void *, const void *) = _compare;
00150
00151 return compare (* (const void * *) a, * (const void * *) b);
00152 }
00153
00154 void index_sort (struct index * index, gint (* compare) (const void *, const
00155 void *))
00156 {
00157 g_qsort_with_data (index->data, index->count, sizeof (void *),
00158 index_compare, compare);
00159 }
00160
00161 static gint index_compare_with_data (const void * a, const void * b, void *
00162 _index)
00163 {
00164 struct index * index = _index;
00165
00166 return index->compare (* (const void * *) a, * (const void * *) b,
00167 index->compare_data);
00168 }
00169
00170 void index_sort_with_data (struct index * index, gint (* compare)
00171 (const void * a, const void * b, void * data), void * data)
00172 {
00173 index->compare = compare;
00174 index->compare_data = data;
00175 g_qsort_with_data (index->data, index->count, sizeof (void *),
00176 index_compare_with_data, index);
00177 index->compare = NULL;
00178 index->compare_data = NULL;
00179 }