Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
index.c
Go to the documentation of this file.
1 /*
2  * index.c
3  * Copyright 2009-2011 John Lindgren
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions, and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions, and the following disclaimer in the documentation
13  * provided with the distribution.
14  *
15  * This software is provided "as is" and without any warranty, express or
16  * implied. In no event shall the authors be liable for any damages arising from
17  * the use of this software.
18  */
19 
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include <glib.h>
24 
25 #include "config.h"
26 #include "index.h"
27 
28 struct _Index {
29  void * * data;
30  int count, size;
31 };
32 
33 typedef struct {
34  int (* compare) (const void * a, const void * b);
36 
37 typedef struct {
38  int (* compare) (const void * a, const void * b, void * data);
39  void * data;
41 
42 EXPORT Index * index_new (void)
43 {
44  Index * index = g_slice_new (Index);
45 
46  index->data = NULL;
47  index->count = 0;
48  index->size = 0;
49 
50  return index;
51 }
52 
53 EXPORT void index_free (Index * index)
54 {
55  g_free (index->data);
56  g_slice_free (Index, index);
57 }
58 
59 EXPORT int index_count (Index * index)
60 {
61  return index->count;
62 }
63 
64 EXPORT void index_allocate (Index * index, int size)
65 {
66  if (size <= index->size)
67  return;
68 
69  if (! index->size)
70  index->size = 64;
71 
72  while (size > index->size)
73  index->size <<= 1;
74 
75  index->data = g_realloc (index->data, sizeof (void *) * index->size);
76 }
77 
78 EXPORT void index_set (Index * index, int at, void * value)
79 {
80  index->data[at] = value;
81 }
82 
83 EXPORT void * index_get (Index * index, int at)
84 {
85  return index->data[at];
86 }
87 
88 static void make_room (Index * index, int at, int count)
89 {
90  index_allocate (index, index->count + count);
91 
92  if (at < index->count)
93  memmove (index->data + at + count, index->data + at, sizeof (void *) *
94  (index->count - at));
95 
96  index->count += count;
97 }
98 
99 EXPORT void index_insert (Index * index, int at, void * value)
100 {
101  make_room (index, at, 1);
102  index->data[at] = value;
103 }
104 
105 EXPORT void index_append (Index * index, void * value)
106 {
107  index_insert (index, index->count, value);
108 }
109 
110 EXPORT void index_copy_set (Index * source, int from, Index * target,
111  int to, int count)
112 {
113  memcpy (target->data + to, source->data + from, sizeof (void *) * count);
114 }
115 
116 EXPORT void index_copy_insert (Index * source, int from, Index * target,
117  int to, int count)
118 {
119  make_room (target, to, count);
120  memcpy (target->data + to, source->data + from, sizeof (void *) * count);
121 }
122 
123 EXPORT void index_copy_append (Index * source, int from, Index * target,
124  int count)
125 {
126  index_copy_insert (source, from, target, target->count, count);
127 }
128 
129 EXPORT void index_merge_insert (Index * first, int at, Index * second)
130 {
131  index_copy_insert (second, 0, first, at, second->count);
132 }
133 
134 EXPORT void index_merge_append (Index * first, Index * second)
135 {
136  index_copy_insert (second, 0, first, first->count, second->count);
137 }
138 
139 EXPORT void index_move (Index * index, int from, int to, int count)
140 {
141  memmove (index->data + to, index->data + from, sizeof (void *) * count);
142 }
143 
144 EXPORT void index_delete (Index * index, int at, int count)
145 {
146  index->count -= count;
147  memmove (index->data + at, index->data + at + count, sizeof (void *) *
148  (index->count - at));
149 }
150 
151 static int index_compare (const void * ap, const void * bp, void * _wrapper)
152 {
153  CompareWrapper * wrapper = _wrapper;
154  return wrapper->compare (* (const void * *) ap, * (const void * *) bp);
155 }
156 
157 EXPORT void index_sort (Index * index, int (* compare) (const void *, const void *))
158 {
159  CompareWrapper wrapper = {compare};
160  g_qsort_with_data (index->data, index->count, sizeof (void *),
161  index_compare, & wrapper);
162 }
163 
164 static int index_compare2 (const void * ap, const void * bp, void * _wrapper)
165 {
166  CompareWrapper2 * wrapper = _wrapper;
167  return wrapper->compare (* (const void * *) ap, * (const void * *) bp, wrapper->data);
168 }
169 
170 EXPORT void index_sort_with_data (Index * index, int (* compare)
171  (const void * a, const void * b, void * data), void * data)
172 {
173  CompareWrapper2 wrapper = {compare, data};
174  g_qsort_with_data (index->data, index->count, sizeof (void *),
175  index_compare2, & wrapper);
176 }