Audacious $Id:Doxyfile42802007-03-2104:39:00Znenolod$
|
00001 /* 00002 * index.c 00003 * Copyright 2009-2011 John Lindgren 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions, and the following disclaimer. 00010 * 00011 * 2. Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions, and the following disclaimer in the documentation 00013 * provided with the distribution. 00014 * 00015 * This software is provided "as is" and without any warranty, express or 00016 * implied. In no event shall the authors be liable for any damages arising from 00017 * the use of this software. 00018 */ 00019 00020 #include <stdlib.h> 00021 #include <string.h> 00022 00023 #include <glib.h> 00024 00025 #include "config.h" 00026 #include "index.h" 00027 00028 struct _Index { 00029 void * * data; 00030 int count, size; 00031 }; 00032 00033 typedef struct { 00034 int (* compare) (const void * a, const void * b); 00035 } CompareWrapper; 00036 00037 typedef struct { 00038 int (* compare) (const void * a, const void * b, void * data); 00039 void * data; 00040 } CompareWrapper2; 00041 00042 EXPORT Index * index_new (void) 00043 { 00044 Index * index = g_slice_new (Index); 00045 00046 index->data = NULL; 00047 index->count = 0; 00048 index->size = 0; 00049 00050 return index; 00051 } 00052 00053 EXPORT void index_free (Index * index) 00054 { 00055 g_free (index->data); 00056 g_slice_free (Index, index); 00057 } 00058 00059 EXPORT int index_count (Index * index) 00060 { 00061 return index->count; 00062 } 00063 00064 EXPORT void index_allocate (Index * index, int size) 00065 { 00066 if (size <= index->size) 00067 return; 00068 00069 if (! index->size) 00070 index->size = 64; 00071 00072 while (size > index->size) 00073 index->size <<= 1; 00074 00075 index->data = g_realloc (index->data, sizeof (void *) * index->size); 00076 } 00077 00078 EXPORT void index_set (Index * index, int at, void * value) 00079 { 00080 index->data[at] = value; 00081 } 00082 00083 EXPORT void * index_get (Index * index, int at) 00084 { 00085 return index->data[at]; 00086 } 00087 00088 static void make_room (Index * index, int at, int count) 00089 { 00090 index_allocate (index, index->count + count); 00091 00092 if (at < index->count) 00093 memmove (index->data + at + count, index->data + at, sizeof (void *) * 00094 (index->count - at)); 00095 00096 index->count += count; 00097 } 00098 00099 EXPORT void index_insert (Index * index, int at, void * value) 00100 { 00101 make_room (index, at, 1); 00102 index->data[at] = value; 00103 } 00104 00105 EXPORT void index_append (Index * index, void * value) 00106 { 00107 index_insert (index, index->count, value); 00108 } 00109 00110 EXPORT void index_copy_set (Index * source, int from, Index * target, 00111 int to, int count) 00112 { 00113 memcpy (target->data + to, source->data + from, sizeof (void *) * count); 00114 } 00115 00116 EXPORT void index_copy_insert (Index * source, int from, Index * target, 00117 int to, int count) 00118 { 00119 make_room (target, to, count); 00120 memcpy (target->data + to, source->data + from, sizeof (void *) * count); 00121 } 00122 00123 EXPORT void index_copy_append (Index * source, int from, Index * target, 00124 int count) 00125 { 00126 index_copy_insert (source, from, target, target->count, count); 00127 } 00128 00129 EXPORT void index_merge_insert (Index * first, int at, Index * second) 00130 { 00131 index_copy_insert (second, 0, first, at, second->count); 00132 } 00133 00134 EXPORT void index_merge_append (Index * first, Index * second) 00135 { 00136 index_copy_insert (second, 0, first, first->count, second->count); 00137 } 00138 00139 EXPORT void index_move (Index * index, int from, int to, int count) 00140 { 00141 memmove (index->data + to, index->data + from, sizeof (void *) * count); 00142 } 00143 00144 EXPORT void index_delete (Index * index, int at, int count) 00145 { 00146 index->count -= count; 00147 memmove (index->data + at, index->data + at + count, sizeof (void *) * 00148 (index->count - at)); 00149 } 00150 00151 static int index_compare (const void * ap, const void * bp, void * _wrapper) 00152 { 00153 CompareWrapper * wrapper = _wrapper; 00154 return wrapper->compare (* (const void * *) ap, * (const void * *) bp); 00155 } 00156 00157 EXPORT void index_sort (Index * index, int (* compare) (const void *, const void *)) 00158 { 00159 CompareWrapper wrapper = {compare}; 00160 g_qsort_with_data (index->data, index->count, sizeof (void *), 00161 index_compare, & wrapper); 00162 } 00163 00164 static int index_compare2 (const void * ap, const void * bp, void * _wrapper) 00165 { 00166 CompareWrapper2 * wrapper = _wrapper; 00167 return wrapper->compare (* (const void * *) ap, * (const void * *) bp, wrapper->data); 00168 } 00169 00170 EXPORT void index_sort_with_data (Index * index, int (* compare) 00171 (const void * a, const void * b, void * data), void * data) 00172 { 00173 CompareWrapper2 wrapper = {compare, data}; 00174 g_qsort_with_data (index->data, index->count, sizeof (void *), 00175 index_compare2, & wrapper); 00176 }