Audacious
$Id:Doxyfile42802007-03-2104:39:00Znenolod$
|
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 }