Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
index.c
Go to the documentation of this file.
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 }