source: trunk/third/glib2/gobject/gvaluearray.c @ 18159

Revision 18159, 6.4 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18158, which included commits to RCS files with non-trunk default branches.
Line 
1/* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 2001 Red Hat, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20/*
21 * MT safe
22 */
23
24#include <config.h>
25
26#include        "gvaluearray.h"
27#include        <string.h>
28#include        <stdlib.h>      /* qsort() */
29
30#ifdef  DISABLE_MEM_POOLS
31#  define       GROUP_N_VALUES  (1)     /* power of 2 !! */
32#else
33#  define       GROUP_N_VALUES  (8)     /* power of 2 !! */
34#endif
35
36
37/* --- functions --- */
38GValue*
39g_value_array_get_nth (GValueArray *value_array,
40                       guint        index)
41{
42  g_return_val_if_fail (value_array != NULL, NULL);
43  g_return_val_if_fail (index < value_array->n_values, NULL);
44
45  return value_array->values + index;
46}
47
48static inline void
49value_array_grow (GValueArray *value_array,
50                  guint        n_values,
51                  gboolean     zero_init)
52{
53  g_return_if_fail (n_values >= value_array->n_values);
54
55  value_array->n_values = n_values;
56  if (value_array->n_values > value_array->n_prealloced)
57    {
58      guint i = value_array->n_prealloced;
59
60      value_array->n_prealloced = (value_array->n_values + GROUP_N_VALUES - 1) & ~(GROUP_N_VALUES - 1);
61      value_array->values = g_renew (GValue, value_array->values, value_array->n_prealloced);
62      if (!zero_init)
63        i = value_array->n_values;
64      memset (value_array->values + i, 0,
65              (value_array->n_prealloced - i) * sizeof (value_array->values[0]));
66    }
67}
68
69static inline void
70value_array_shrink (GValueArray *value_array)
71{
72#ifdef  DISABLE_MEM_POOLS
73  if (value_array->n_prealloced >= value_array->n_values + GROUP_N_VALUES)
74    {
75      value_array->n_prealloced = (value_array->n_values + GROUP_N_VALUES - 1) & ~(GROUP_N_VALUES - 1);
76      value_array->values = g_renew (GValue, value_array->values, value_array->n_prealloced);
77    }
78#endif
79}
80
81GValueArray*
82g_value_array_new (guint n_prealloced)
83{
84  GValueArray *value_array = g_new (GValueArray, 1);
85
86  value_array->n_values = 0;
87  value_array->n_prealloced = 0;
88  value_array->values = NULL;
89  value_array_grow (value_array, n_prealloced, TRUE);
90  value_array->n_values = 0;
91
92  return value_array;
93}
94
95void
96g_value_array_free (GValueArray *value_array)
97{
98  guint i;
99
100  g_return_if_fail (value_array != NULL);
101
102  for (i = 0; i < value_array->n_values; i++)
103    {
104      GValue *value = value_array->values + i;
105
106      if (G_VALUE_TYPE (value) != 0) /* we allow unset values in the array */
107        g_value_unset (value);
108    }
109  g_free (value_array->values);
110  g_free (value_array);
111}
112
113GValueArray*
114g_value_array_copy (const GValueArray *value_array)
115{
116  GValueArray *new_array;
117  guint i;
118
119  g_return_val_if_fail (value_array != NULL, NULL);
120
121  new_array = g_new (GValueArray, 1);
122  new_array->n_values = 0;
123  new_array->values = NULL;
124  new_array->n_prealloced = 0;
125  value_array_grow (new_array, value_array->n_values, TRUE);
126  for (i = 0; i < new_array->n_values; i++)
127    if (G_VALUE_TYPE (value_array->values + i) != 0)
128      {
129        GValue *value = new_array->values + i;
130       
131        g_value_init (value, G_VALUE_TYPE (value_array->values + i));
132        g_value_copy (value_array->values + i, value);
133      }
134  return new_array;
135}
136
137GValueArray*
138g_value_array_prepend (GValueArray  *value_array,
139                       const GValue *value)
140{
141  g_return_val_if_fail (value_array != NULL, NULL);
142
143  return g_value_array_insert (value_array, 0, value);
144}
145
146GValueArray*
147g_value_array_append (GValueArray  *value_array,
148                      const GValue *value)
149{
150  g_return_val_if_fail (value_array != NULL, NULL);
151
152  return g_value_array_insert (value_array, value_array->n_values, value);
153}
154
155GValueArray*
156g_value_array_insert (GValueArray  *value_array,
157                      guint         index,
158                      const GValue *value)
159{
160  guint i;
161
162  g_return_val_if_fail (value_array != NULL, NULL);
163  g_return_val_if_fail (index <= value_array->n_values, value_array);
164
165  /* we support NULL for "value" as a shortcut for an unset value */
166
167  i = value_array->n_values;
168  value_array_grow (value_array, value_array->n_values + 1, FALSE);
169  if (index + 1 < value_array->n_values)
170    g_memmove (value_array->values + index + 1, value_array->values + index,
171               (i - index) * sizeof (value_array->values[0]));
172  memset (value_array->values + index, 0, sizeof (value_array->values[0]));
173  if (value)
174    {
175      g_value_init (value_array->values + index, G_VALUE_TYPE (value));
176      g_value_copy (value, value_array->values + index);
177    }
178  return value_array;
179}
180
181GValueArray*
182g_value_array_remove (GValueArray *value_array,
183                      guint        index)
184{
185  g_return_val_if_fail (value_array != NULL, NULL);
186  g_return_val_if_fail (index < value_array->n_values, value_array);
187
188  if (G_VALUE_TYPE (value_array->values + index) != 0)
189    g_value_unset (value_array->values + index);
190  value_array->n_values--;
191  if (index < value_array->n_values)
192    g_memmove (value_array->values + index, value_array->values + index + 1,
193               (value_array->n_values - index) * sizeof (value_array->values[0]));
194  value_array_shrink (value_array);
195  if (value_array->n_prealloced > value_array->n_values)
196    memset (value_array->values + value_array->n_values, 0, sizeof (value_array->values[0]));
197
198  return value_array;
199}
200
201GValueArray*
202g_value_array_sort (GValueArray *value_array,
203                    GCompareFunc compare_func)
204{
205  g_return_val_if_fail (compare_func != NULL, NULL);
206
207  if (value_array->n_values)
208    qsort (value_array->values,
209           value_array->n_values,
210           sizeof (value_array->values[0]),
211           compare_func);
212  return value_array;
213}
214
215GValueArray*
216g_value_array_sort_with_data (GValueArray     *value_array,
217                              GCompareDataFunc compare_func,
218                              gpointer         user_data)
219{
220  g_return_val_if_fail (value_array != NULL, NULL);
221  g_return_val_if_fail (compare_func != NULL, NULL);
222
223  if (value_array->n_values)
224    g_qsort_with_data (value_array->values,
225                       value_array->n_values,
226                       sizeof (value_array->values[0]),
227                       compare_func, user_data);
228  return value_array;
229}
Note: See TracBrowser for help on using the repository browser.