Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
index.c
Go to the documentation of this file.
00001 /*
00002  * index.c
00003  * Copyright 2009-2010 John Lindgren
00004  *
00005  * This file is part of Audacious.
00006  *
00007  * Audacious is free software: you can redistribute it and/or modify it under
00008  * the terms of the GNU General Public License as published by the Free Software
00009  * Foundation, version 2 or version 3 of the License.
00010  *
00011  * Audacious is distributed in the hope that it will be useful, but WITHOUT ANY
00012  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00013  * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License along with
00016  * Audacious. If not, see <http://www.gnu.org/licenses/>.
00017  *
00018  * The Audacious team does not consider modular code linking to Audacious or
00019  * using our public API to be a derived work.
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 }