00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <string.h>
00032 #include "glib.h"
00033
00034
00035 #define MIN_ARRAY_SIZE 16
00036
00037
00038 typedef struct _GRealArray GRealArray;
00039
00040 struct _GRealArray
00041 {
00042 guint8 *data;
00043 guint len;
00044 guint alloc;
00045 guint elt_size;
00046 guint zero_terminated : 1;
00047 guint clear : 1;
00048 };
00049
00050
00051 static gint g_nearest_pow (gint num);
00052 static void g_array_maybe_expand (GRealArray *array,
00053 gint len);
00054
00055 static GMemChunk *array_mem_chunk = NULL;
00056 G_LOCK_DEFINE_STATIC (array_mem_chunk);
00057
00058 GArray*
00059 g_array_new (gboolean zero_terminated,
00060 gboolean clear,
00061 guint elt_size)
00062 {
00063 GRealArray *array;
00064
00065 G_LOCK (array_mem_chunk);
00066 if (!array_mem_chunk)
00067 array_mem_chunk = g_mem_chunk_new ("array mem chunk",
00068 sizeof (GRealArray),
00069 1024, G_ALLOC_AND_FREE);
00070
00071 array = g_chunk_new (GRealArray, array_mem_chunk);
00072 G_UNLOCK (array_mem_chunk);
00073
00074 array->data = NULL;
00075 array->len = 0;
00076 array->alloc = 0;
00077 array->zero_terminated = (zero_terminated ? 1 : 0);
00078 array->clear = (clear ? 1 : 0);
00079 array->elt_size = elt_size;
00080
00081 return (GArray*) array;
00082 }
00083
00084 void
00085 g_array_free (GArray *array,
00086 gboolean free_segment)
00087 {
00088 if (free_segment)
00089 g_free (array->data);
00090
00091 G_LOCK (array_mem_chunk);
00092 g_mem_chunk_free (array_mem_chunk, array);
00093 G_UNLOCK (array_mem_chunk);
00094 }
00095
00096 GArray*
00097 g_array_append_vals (GArray *farray,
00098 gconstpointer data,
00099 guint len)
00100 {
00101 GRealArray *array = (GRealArray*) farray;
00102
00103 g_array_maybe_expand (array, len);
00104
00105 memcpy (array->data + array->elt_size * array->len, data, array->elt_size * len);
00106
00107 array->len += len;
00108
00109 return farray;
00110 }
00111
00112 GArray*
00113 g_array_prepend_vals (GArray *farray,
00114 gconstpointer data,
00115 guint len)
00116 {
00117 GRealArray *array = (GRealArray*) farray;
00118
00119 g_array_maybe_expand (array, len);
00120
00121 g_memmove (array->data + array->elt_size * len, array->data, array->elt_size * array->len);
00122
00123 memcpy (array->data, data, len * array->elt_size);
00124
00125 array->len += len;
00126
00127 return farray;
00128 }
00129
00130 GArray*
00131 g_array_insert_vals (GArray *farray,
00132 guint index,
00133 gconstpointer data,
00134 guint len)
00135 {
00136 GRealArray *array = (GRealArray*) farray;
00137
00138 g_array_maybe_expand (array, len);
00139
00140 g_memmove (array->data + array->elt_size * (len + index),
00141 array->data + array->elt_size * index,
00142 array->elt_size * (array->len - index));
00143
00144 memcpy (array->data + array->elt_size * index, data, len * array->elt_size);
00145
00146 array->len += len;
00147
00148 return farray;
00149 }
00150
00151 GArray*
00152 g_array_set_size (GArray *farray,
00153 guint length)
00154 {
00155 GRealArray *array = (GRealArray*) farray;
00156
00157 if (array->len < length)
00158 g_array_maybe_expand (array, length - array->len);
00159
00160 array->len = length;
00161
00162 return farray;
00163 }
00164
00165 GArray*
00166 g_array_remove_index (GArray* farray,
00167 guint index)
00168 {
00169 GRealArray* array = (GRealArray*) farray;
00170
00171 g_return_val_if_fail (array, NULL);
00172
00173 g_return_val_if_fail (index < array->len, NULL);
00174
00175 if (index != array->len - 1)
00176 g_memmove (array->data + array->elt_size * index,
00177 array->data + array->elt_size * (index + 1),
00178 array->elt_size * (array->len - index - 1));
00179
00180 if (array->zero_terminated)
00181 memset (array->data + array->elt_size * (array->len - 1), 0,
00182 array->elt_size);
00183
00184 array->len -= 1;
00185
00186 return farray;
00187 }
00188
00189 GArray*
00190 g_array_remove_index_fast (GArray* farray,
00191 guint index)
00192 {
00193 GRealArray* array = (GRealArray*) farray;
00194
00195 g_return_val_if_fail (array, NULL);
00196
00197 g_return_val_if_fail (index < array->len, NULL);
00198
00199 if (index != array->len - 1)
00200 g_memmove (array->data + array->elt_size * index,
00201 array->data + array->elt_size * (array->len - 1),
00202 array->elt_size);
00203
00204 if (array->zero_terminated)
00205 memset (array->data + array->elt_size * (array->len - 1), 0,
00206 array->elt_size);
00207
00208 array->len -= 1;
00209
00210 return farray;
00211 }
00212
00213 static gint
00214 g_nearest_pow (gint num)
00215 {
00216 gint n = 1;
00217
00218 while (n < num)
00219 n <<= 1;
00220
00221 return n;
00222 }
00223
00224 static void
00225 g_array_maybe_expand (GRealArray *array,
00226 gint len)
00227 {
00228 guint want_alloc = (array->len + len + array->zero_terminated) * array->elt_size;
00229
00230 if (want_alloc > array->alloc)
00231 {
00232 guint old_alloc = array->alloc;
00233
00234 array->alloc = g_nearest_pow (want_alloc);
00235 array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
00236
00237 array->data = g_realloc (array->data, array->alloc);
00238
00239 if (array->clear || array->zero_terminated)
00240 memset (array->data + old_alloc, 0, array->alloc - old_alloc);
00241 }
00242 }
00243
00244
00245
00246
00247 typedef struct _GRealPtrArray GRealPtrArray;
00248
00249 struct _GRealPtrArray
00250 {
00251 gpointer *pdata;
00252 guint len;
00253 guint alloc;
00254 };
00255
00256 static void g_ptr_array_maybe_expand (GRealPtrArray *array,
00257 gint len);
00258
00259 static GMemChunk *ptr_array_mem_chunk = NULL;
00260 G_LOCK_DEFINE_STATIC (ptr_array_mem_chunk);
00261
00262
00263 GPtrArray*
00264 g_ptr_array_new (void)
00265 {
00266 GRealPtrArray *array;
00267
00268 G_LOCK (ptr_array_mem_chunk);
00269 if (!ptr_array_mem_chunk)
00270 ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
00271 sizeof (GRealPtrArray),
00272 1024, G_ALLOC_AND_FREE);
00273
00274 array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
00275 G_UNLOCK (ptr_array_mem_chunk);
00276
00277 array->pdata = NULL;
00278 array->len = 0;
00279 array->alloc = 0;
00280
00281 return (GPtrArray*) array;
00282 }
00283
00284 void
00285 g_ptr_array_free (GPtrArray *array,
00286 gboolean free_segment)
00287 {
00288 g_return_if_fail (array);
00289
00290 if (free_segment)
00291 g_free (array->pdata);
00292
00293 G_LOCK (ptr_array_mem_chunk);
00294 g_mem_chunk_free (ptr_array_mem_chunk, array);
00295 G_UNLOCK (ptr_array_mem_chunk);
00296 }
00297
00298 static void
00299 g_ptr_array_maybe_expand (GRealPtrArray *array,
00300 gint len)
00301 {
00302 guint old_alloc;
00303
00304 if ((array->len + len) > array->alloc)
00305 {
00306 old_alloc = array->alloc;
00307
00308 array->alloc = g_nearest_pow (array->len + len);
00309 array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
00310 if (array->pdata)
00311 array->pdata = g_realloc (array->pdata, sizeof(gpointer) * array->alloc);
00312 else
00313 array->pdata = g_new0 (gpointer, array->alloc);
00314
00315 memset (array->pdata + old_alloc, 0,
00316 sizeof (gpointer) * (array->alloc - old_alloc));
00317 }
00318 }
00319
00320 void
00321 g_ptr_array_set_size (GPtrArray *farray,
00322 gint length)
00323 {
00324 GRealPtrArray* array = (GRealPtrArray*) farray;
00325
00326 g_return_if_fail (array);
00327
00328 if (length > array->len)
00329 g_ptr_array_maybe_expand (array, (length - array->len));
00330
00331 array->len = length;
00332 }
00333
00334 gpointer
00335 g_ptr_array_remove_index (GPtrArray* farray,
00336 guint index)
00337 {
00338 GRealPtrArray* array = (GRealPtrArray*) farray;
00339 gpointer result;
00340
00341 g_return_val_if_fail (array, NULL);
00342
00343 g_return_val_if_fail (index < array->len, NULL);
00344
00345 result = array->pdata[index];
00346
00347 if (index != array->len - 1)
00348 g_memmove (array->pdata + index, array->pdata + index + 1,
00349 sizeof (gpointer) * (array->len - index - 1));
00350
00351 array->pdata[array->len - 1] = NULL;
00352
00353 array->len -= 1;
00354
00355 return result;
00356 }
00357
00358 gpointer
00359 g_ptr_array_remove_index_fast (GPtrArray* farray,
00360 guint index)
00361 {
00362 GRealPtrArray* array = (GRealPtrArray*) farray;
00363 gpointer result;
00364
00365 g_return_val_if_fail (array, NULL);
00366
00367 g_return_val_if_fail (index < array->len, NULL);
00368
00369 result = array->pdata[index];
00370
00371 if (index != array->len - 1)
00372 array->pdata[index] = array->pdata[array->len - 1];
00373
00374 array->pdata[array->len - 1] = NULL;
00375
00376 array->len -= 1;
00377
00378 return result;
00379 }
00380
00381 gboolean
00382 g_ptr_array_remove (GPtrArray* farray,
00383 gpointer data)
00384 {
00385 GRealPtrArray* array = (GRealPtrArray*) farray;
00386 int i;
00387
00388 g_return_val_if_fail (array, FALSE);
00389
00390 for (i = 0; i < array->len; i += 1)
00391 {
00392 if (array->pdata[i] == data)
00393 {
00394 g_ptr_array_remove_index (farray, i);
00395 return TRUE;
00396 }
00397 }
00398
00399 return FALSE;
00400 }
00401
00402 gboolean
00403 g_ptr_array_remove_fast (GPtrArray* farray,
00404 gpointer data)
00405 {
00406 GRealPtrArray* array = (GRealPtrArray*) farray;
00407 int i;
00408
00409 g_return_val_if_fail (array, FALSE);
00410
00411 for (i = 0; i < array->len; i += 1)
00412 {
00413 if (array->pdata[i] == data)
00414 {
00415 g_ptr_array_remove_index_fast (farray, i);
00416 return TRUE;
00417 }
00418 }
00419
00420 return FALSE;
00421 }
00422
00423 void
00424 g_ptr_array_add (GPtrArray* farray,
00425 gpointer data)
00426 {
00427 GRealPtrArray* array = (GRealPtrArray*) farray;
00428
00429 g_return_if_fail (array);
00430
00431 g_ptr_array_maybe_expand (array, 1);
00432
00433 array->pdata[array->len++] = data;
00434 }
00435
00436
00437
00438
00439 GByteArray* g_byte_array_new (void)
00440 {
00441 return (GByteArray*) g_array_new (FALSE, FALSE, 1);
00442 }
00443
00444 void g_byte_array_free (GByteArray *array,
00445 gboolean free_segment)
00446 {
00447 g_array_free ((GArray*) array, free_segment);
00448 }
00449
00450 GByteArray* g_byte_array_append (GByteArray *array,
00451 const guint8 *data,
00452 guint len)
00453 {
00454 g_array_append_vals ((GArray*) array, (guint8*)data, len);
00455
00456 return array;
00457 }
00458
00459 GByteArray* g_byte_array_prepend (GByteArray *array,
00460 const guint8 *data,
00461 guint len)
00462 {
00463 g_array_prepend_vals ((GArray*) array, (guint8*)data, len);
00464
00465 return array;
00466 }
00467
00468 GByteArray* g_byte_array_set_size (GByteArray *array,
00469 guint length)
00470 {
00471 g_array_set_size ((GArray*) array, length);
00472
00473 return array;
00474 }
00475
00476 GByteArray* g_byte_array_remove_index (GByteArray *array,
00477 guint index)
00478 {
00479 g_array_remove_index((GArray*) array, index);
00480
00481 return array;
00482 }
00483
00484 GByteArray* g_byte_array_remove_index_fast (GByteArray *array,
00485 guint index)
00486 {
00487 g_array_remove_index_fast((GArray*) array, index);
00488
00489 return array;
00490 }