os/ossrv/glib/gobject/gvaluearray.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* GObject - GLib Type, Object, Parameter and Signal Library
sl@0
     2
 * Copyright (C) 2001 Red Hat, Inc.
sl@0
     3
 * Portions copyright (c) 2006-2009 Nokia Corporation.  All rights reserved.
sl@0
     4
 *
sl@0
     5
 * This library is free software; you can redistribute it and/or
sl@0
     6
 * modify it under the terms of the GNU Lesser General Public
sl@0
     7
 * License as published by the Free Software Foundation; either
sl@0
     8
 * version 2 of the License, or (at your option) any later version.
sl@0
     9
 *
sl@0
    10
 * This library is distributed in the hope that it will be useful,
sl@0
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
sl@0
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
sl@0
    13
 * Lesser General Public License for more details.
sl@0
    14
 *
sl@0
    15
 * You should have received a copy of the GNU Lesser General
sl@0
    16
 * Public License along with this library; if not, write to the
sl@0
    17
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
sl@0
    18
 * Boston, MA 02111-1307, USA.
sl@0
    19
 */
sl@0
    20
sl@0
    21
/*
sl@0
    22
 * MT safe
sl@0
    23
 */
sl@0
    24
sl@0
    25
#include "config.h"
sl@0
    26
sl@0
    27
#include <string.h>
sl@0
    28
#include <stdlib.h>  /* qsort() */
sl@0
    29
sl@0
    30
#include "gvaluearray.h"
sl@0
    31
#include "gobjectalias.h"
sl@0
    32
sl@0
    33
sl@0
    34
/**
sl@0
    35
 * SECTION:value_arrays
sl@0
    36
 * @short_description: A container structure to maintain an array of
sl@0
    37
 *     generic values
sl@0
    38
 * @see_also: #GValue, #GParamSpecValueArray, g_param_spec_value_array()
sl@0
    39
 * @title: Value arrays
sl@0
    40
 *
sl@0
    41
 * The prime purpose of a #GValueArray is for it to be used as an
sl@0
    42
 * object property that holds an array of values. A #GValueArray wraps
sl@0
    43
 * an array of #GValue elements in order for it to be used as a boxed
sl@0
    44
 * type through %G_TYPE_VALUE_ARRAY.
sl@0
    45
 */
sl@0
    46
sl@0
    47
sl@0
    48
#ifdef	DISABLE_MEM_POOLS
sl@0
    49
#  define	GROUP_N_VALUES	(1)	/* power of 2 !! */
sl@0
    50
#else
sl@0
    51
#  define	GROUP_N_VALUES	(8)	/* power of 2 !! */
sl@0
    52
#endif
sl@0
    53
sl@0
    54
sl@0
    55
/* --- functions --- */
sl@0
    56
/**
sl@0
    57
 * g_value_array_get_nth:
sl@0
    58
 * @value_array: #GValueArray to get a value from
sl@0
    59
 * @index_: index of the value of interest
sl@0
    60
 *
sl@0
    61
 * Return a pointer to the value at @index_ containd in @value_array.
sl@0
    62
 *
sl@0
    63
 * Returns: pointer to a value at @index_ in @value_array
sl@0
    64
 */
sl@0
    65
EXPORT_C GValue*
sl@0
    66
g_value_array_get_nth (GValueArray *value_array,
sl@0
    67
		       guint        index)
sl@0
    68
{
sl@0
    69
  g_return_val_if_fail (value_array != NULL, NULL);
sl@0
    70
  g_return_val_if_fail (index < value_array->n_values, NULL);
sl@0
    71
sl@0
    72
  return value_array->values + index;
sl@0
    73
}
sl@0
    74
sl@0
    75
static inline void
sl@0
    76
value_array_grow (GValueArray *value_array,
sl@0
    77
		  guint        n_values,
sl@0
    78
		  gboolean     zero_init)
sl@0
    79
{
sl@0
    80
  g_return_if_fail (n_values >= value_array->n_values);
sl@0
    81
sl@0
    82
  value_array->n_values = n_values;
sl@0
    83
  if (value_array->n_values > value_array->n_prealloced)
sl@0
    84
    {
sl@0
    85
      guint i = value_array->n_prealloced;
sl@0
    86
sl@0
    87
      value_array->n_prealloced = (value_array->n_values + GROUP_N_VALUES - 1) & ~(GROUP_N_VALUES - 1);
sl@0
    88
      value_array->values = g_renew (GValue, value_array->values, value_array->n_prealloced);
sl@0
    89
      if (!zero_init)
sl@0
    90
	i = value_array->n_values;
sl@0
    91
      memset (value_array->values + i, 0,
sl@0
    92
	      (value_array->n_prealloced - i) * sizeof (value_array->values[0]));
sl@0
    93
    }
sl@0
    94
}
sl@0
    95
sl@0
    96
static inline void
sl@0
    97
value_array_shrink (GValueArray *value_array)
sl@0
    98
{
sl@0
    99
#ifdef  DISABLE_MEM_POOLS
sl@0
   100
  if (value_array->n_prealloced >= value_array->n_values + GROUP_N_VALUES)
sl@0
   101
    {
sl@0
   102
      value_array->n_prealloced = (value_array->n_values + GROUP_N_VALUES - 1) & ~(GROUP_N_VALUES - 1);
sl@0
   103
      value_array->values = g_renew (GValue, value_array->values, value_array->n_prealloced);
sl@0
   104
    }
sl@0
   105
#endif
sl@0
   106
}
sl@0
   107
sl@0
   108
/**
sl@0
   109
 * g_value_array_new:
sl@0
   110
 * @n_prealloced: number of values to preallocate space for
sl@0
   111
 *
sl@0
   112
 * Allocate and initialize a new #GValueArray, optionally preserve space
sl@0
   113
 * for @n_prealloced elements. New arrays always contain 0 elements,
sl@0
   114
 * regardless of the value of @n_prealloced.
sl@0
   115
 *
sl@0
   116
 * Returns: a newly allocated #GValueArray with 0 values
sl@0
   117
 */
sl@0
   118
EXPORT_C GValueArray*
sl@0
   119
g_value_array_new (guint n_prealloced)
sl@0
   120
{
sl@0
   121
  GValueArray *value_array = g_slice_new (GValueArray);
sl@0
   122
sl@0
   123
  value_array->n_values = 0;
sl@0
   124
  value_array->n_prealloced = 0;
sl@0
   125
  value_array->values = NULL;
sl@0
   126
  value_array_grow (value_array, n_prealloced, TRUE);
sl@0
   127
  value_array->n_values = 0;
sl@0
   128
sl@0
   129
  return value_array;
sl@0
   130
}
sl@0
   131
sl@0
   132
/**
sl@0
   133
 * g_value_array_free:
sl@0
   134
 * @value_array: #GValueArray to free
sl@0
   135
 *
sl@0
   136
 * Free a #GValueArray including its contents.
sl@0
   137
 */
sl@0
   138
EXPORT_C void
sl@0
   139
g_value_array_free (GValueArray *value_array)
sl@0
   140
{
sl@0
   141
  guint i;
sl@0
   142
sl@0
   143
  g_return_if_fail (value_array != NULL);
sl@0
   144
sl@0
   145
  for (i = 0; i < value_array->n_values; i++)
sl@0
   146
    {
sl@0
   147
      GValue *value = value_array->values + i;
sl@0
   148
sl@0
   149
      if (G_VALUE_TYPE (value) != 0) /* we allow unset values in the array */
sl@0
   150
	g_value_unset (value);
sl@0
   151
    }
sl@0
   152
  g_free (value_array->values);
sl@0
   153
  g_slice_free (GValueArray, value_array);
sl@0
   154
}
sl@0
   155
sl@0
   156
/**
sl@0
   157
 * g_value_array_copy:
sl@0
   158
 * @value_array: #GValueArray to copy
sl@0
   159
 *
sl@0
   160
 * Construct an exact copy of a #GValueArray by duplicating all its
sl@0
   161
 * contents.
sl@0
   162
 *
sl@0
   163
 * Returns: Newly allocated copy of #GValueArray
sl@0
   164
 */
sl@0
   165
EXPORT_C GValueArray*
sl@0
   166
g_value_array_copy (const GValueArray *value_array)
sl@0
   167
{
sl@0
   168
  GValueArray *new_array;
sl@0
   169
  guint i;
sl@0
   170
sl@0
   171
  g_return_val_if_fail (value_array != NULL, NULL);
sl@0
   172
sl@0
   173
  new_array = g_slice_new (GValueArray);
sl@0
   174
  new_array->n_values = 0;
sl@0
   175
  new_array->values = NULL;
sl@0
   176
  new_array->n_prealloced = 0;
sl@0
   177
  value_array_grow (new_array, value_array->n_values, TRUE);
sl@0
   178
  for (i = 0; i < new_array->n_values; i++)
sl@0
   179
    if (G_VALUE_TYPE (value_array->values + i) != 0)
sl@0
   180
      {
sl@0
   181
	GValue *value = new_array->values + i;
sl@0
   182
	
sl@0
   183
	g_value_init (value, G_VALUE_TYPE (value_array->values + i));
sl@0
   184
	g_value_copy (value_array->values + i, value);
sl@0
   185
      }
sl@0
   186
  return new_array;
sl@0
   187
}
sl@0
   188
sl@0
   189
/**
sl@0
   190
 * g_value_array_prepend:
sl@0
   191
 * @value_array: #GValueArray to add an element to
sl@0
   192
 * @value: #GValue to copy into #GValueArray
sl@0
   193
 *
sl@0
   194
 * Insert a copy of @value as first element of @value_array.
sl@0
   195
 *
sl@0
   196
 * Returns: the #GValueArray passed in as @value_array
sl@0
   197
 */
sl@0
   198
EXPORT_C GValueArray*
sl@0
   199
g_value_array_prepend (GValueArray  *value_array,
sl@0
   200
		       const GValue *value)
sl@0
   201
{
sl@0
   202
  g_return_val_if_fail (value_array != NULL, NULL);
sl@0
   203
sl@0
   204
  return g_value_array_insert (value_array, 0, value);
sl@0
   205
}
sl@0
   206
sl@0
   207
/**
sl@0
   208
 * g_value_array_append:
sl@0
   209
 * @value_array: #GValueArray to add an element to
sl@0
   210
 * @value: #GValue to copy into #GValueArray
sl@0
   211
 *
sl@0
   212
 * Insert a copy of @value as last element of @value_array.
sl@0
   213
 *
sl@0
   214
 * Returns: the #GValueArray passed in as @value_array
sl@0
   215
 */
sl@0
   216
EXPORT_C GValueArray*
sl@0
   217
g_value_array_append (GValueArray  *value_array,
sl@0
   218
		      const GValue *value)
sl@0
   219
{
sl@0
   220
  g_return_val_if_fail (value_array != NULL, NULL);
sl@0
   221
sl@0
   222
  return g_value_array_insert (value_array, value_array->n_values, value);
sl@0
   223
}
sl@0
   224
sl@0
   225
/**
sl@0
   226
 * g_value_array_insert:
sl@0
   227
 * @value_array: #GValueArray to add an element to
sl@0
   228
 * @index_: insertion position, must be &lt;= value_array-&gt;n_values
sl@0
   229
 * @value: #GValue to copy into #GValueArray
sl@0
   230
 *
sl@0
   231
 * Insert a copy of @value at specified position into @value_array.
sl@0
   232
 *
sl@0
   233
 * Returns: the #GValueArray passed in as @value_array
sl@0
   234
 */
sl@0
   235
EXPORT_C GValueArray*
sl@0
   236
g_value_array_insert (GValueArray  *value_array,
sl@0
   237
		      guint         index,
sl@0
   238
		      const GValue *value)
sl@0
   239
{
sl@0
   240
  guint i;
sl@0
   241
sl@0
   242
  g_return_val_if_fail (value_array != NULL, NULL);
sl@0
   243
  g_return_val_if_fail (index <= value_array->n_values, value_array);
sl@0
   244
sl@0
   245
  /* we support NULL for "value" as a shortcut for an unset value */
sl@0
   246
sl@0
   247
  i = value_array->n_values;
sl@0
   248
  value_array_grow (value_array, value_array->n_values + 1, FALSE);
sl@0
   249
  if (index + 1 < value_array->n_values)
sl@0
   250
    g_memmove (value_array->values + index + 1, value_array->values + index,
sl@0
   251
	       (i - index) * sizeof (value_array->values[0]));
sl@0
   252
  memset (value_array->values + index, 0, sizeof (value_array->values[0]));
sl@0
   253
  if (value)
sl@0
   254
    {
sl@0
   255
      g_value_init (value_array->values + index, G_VALUE_TYPE (value));
sl@0
   256
      g_value_copy (value, value_array->values + index);
sl@0
   257
    }
sl@0
   258
  return value_array;
sl@0
   259
}
sl@0
   260
sl@0
   261
/**
sl@0
   262
 * g_value_array_remove:
sl@0
   263
 * @value_array: #GValueArray to remove an element from
sl@0
   264
 * @index_: position of value to remove, must be &lt; value_array->n_values
sl@0
   265
 *
sl@0
   266
 * Remove the value at position @index_ from @value_array.
sl@0
   267
 *
sl@0
   268
 * Returns: the #GValueArray passed in as @value_array
sl@0
   269
 */
sl@0
   270
EXPORT_C GValueArray*
sl@0
   271
g_value_array_remove (GValueArray *value_array,
sl@0
   272
		      guint        index)
sl@0
   273
{
sl@0
   274
  g_return_val_if_fail (value_array != NULL, NULL);
sl@0
   275
  g_return_val_if_fail (index < value_array->n_values, value_array);
sl@0
   276
sl@0
   277
  if (G_VALUE_TYPE (value_array->values + index) != 0)
sl@0
   278
    g_value_unset (value_array->values + index);
sl@0
   279
  value_array->n_values--;
sl@0
   280
  if (index < value_array->n_values)
sl@0
   281
    g_memmove (value_array->values + index, value_array->values + index + 1,
sl@0
   282
	       (value_array->n_values - index) * sizeof (value_array->values[0]));
sl@0
   283
  value_array_shrink (value_array);
sl@0
   284
  if (value_array->n_prealloced > value_array->n_values)
sl@0
   285
    memset (value_array->values + value_array->n_values, 0, sizeof (value_array->values[0]));
sl@0
   286
sl@0
   287
  return value_array;
sl@0
   288
}
sl@0
   289
sl@0
   290
/**
sl@0
   291
 * g_value_array_sort:
sl@0
   292
 * @value_array: #GValueArray to sort
sl@0
   293
 * @compare_func: function to compare elements
sl@0
   294
 *
sl@0
   295
 * Sort @value_array using @compare_func to compare the elements accoring to
sl@0
   296
 * the semantics of #GCompareFunc.
sl@0
   297
 *
sl@0
   298
 * The current implementation uses Quick-Sort as sorting algorithm.
sl@0
   299
 *
sl@0
   300
 * Returns: the #GValueArray passed in as @value_array
sl@0
   301
 */
sl@0
   302
EXPORT_C GValueArray*
sl@0
   303
g_value_array_sort (GValueArray *value_array,
sl@0
   304
		    GCompareFunc compare_func)
sl@0
   305
{
sl@0
   306
  g_return_val_if_fail (compare_func != NULL, NULL);
sl@0
   307
sl@0
   308
  if (value_array->n_values)
sl@0
   309
    qsort (value_array->values,
sl@0
   310
	   value_array->n_values,
sl@0
   311
	   sizeof (value_array->values[0]),
sl@0
   312
	   compare_func);
sl@0
   313
  return value_array;
sl@0
   314
}
sl@0
   315
sl@0
   316
/**
sl@0
   317
 * g_value_array_sort_with_data:
sl@0
   318
 * @value_array: #GValueArray to sort
sl@0
   319
 * @compare_func: function to compare elements
sl@0
   320
 * @user_data: extra data argument provided for @compare_func
sl@0
   321
 *
sl@0
   322
 * Sort @value_array using @compare_func to compare the elements accoring
sl@0
   323
 * to the semantics of #GCompareDataFunc.
sl@0
   324
 *
sl@0
   325
 * The current implementation uses Quick-Sort as sorting algorithm.
sl@0
   326
 *
sl@0
   327
 * Returns: the #GValueArray passed in as @value_array
sl@0
   328
 */
sl@0
   329
EXPORT_C GValueArray*
sl@0
   330
g_value_array_sort_with_data (GValueArray     *value_array,
sl@0
   331
			      GCompareDataFunc compare_func,
sl@0
   332
			      gpointer         user_data)
sl@0
   333
{
sl@0
   334
  g_return_val_if_fail (value_array != NULL, NULL);
sl@0
   335
  g_return_val_if_fail (compare_func != NULL, NULL);
sl@0
   336
sl@0
   337
  if (value_array->n_values)
sl@0
   338
    g_qsort_with_data (value_array->values,
sl@0
   339
		       value_array->n_values,
sl@0
   340
		       sizeof (value_array->values[0]),
sl@0
   341
		       compare_func, user_data);
sl@0
   342
  return value_array;
sl@0
   343
}
sl@0
   344
sl@0
   345
#define __G_VALUE_ARRAY_C__
sl@0
   346
#include "gobjectaliasdef.c"