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