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_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 }