(root)/
glib-2.79.0/
gobject/
gvaluecollector.h
       1  /* GObject - GLib Type, Object, Parameter and Signal Library
       2   * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
       3   *
       4   * SPDX-License-Identifier: LGPL-2.1-or-later
       5   *
       6   * This library is free software; you can redistribute it and/or
       7   * modify it under the terms of the GNU Lesser General Public
       8   * License as published by the Free Software Foundation; either
       9   * version 2.1 of the License, or (at your option) any later version.
      10   *
      11   * This library is distributed in the hope that it will be useful,
      12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14   * Lesser General Public License for more details.
      15   *
      16   * You should have received a copy of the GNU Lesser General
      17   * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      18   *
      19   * gvaluecollector.h: GValue varargs stubs
      20   */
      21  
      22  #ifndef __G_VALUE_COLLECTOR_H__
      23  #define __G_VALUE_COLLECTOR_H__
      24  
      25  #include <glib-object.h>
      26  
      27  G_BEGIN_DECLS
      28  
      29  /* we may want to add aggregate types here some day, if requested
      30   * by users. the basic C types are covered already, everything
      31   * smaller than an int is promoted to an integer and floats are
      32   * always promoted to doubles for varargs call constructions.
      33   */
      34  enum	/*< skip >*/
      35  {
      36    G_VALUE_COLLECT_INT		= 'i',
      37    G_VALUE_COLLECT_LONG		= 'l',
      38    G_VALUE_COLLECT_INT64         = 'q',
      39    G_VALUE_COLLECT_DOUBLE	= 'd',
      40    G_VALUE_COLLECT_POINTER	= 'p'
      41  };
      42  
      43  
      44  /* vararg union holding actual values collected
      45   */
      46  /**
      47   * GTypeCValue:
      48   * @v_int: the field for holding integer values
      49   * @v_long: the field for holding long integer values
      50   * @v_int64: the field for holding 64 bit integer values
      51   * @v_double: the field for holding floating point values
      52   * @v_pointer: the field for holding pointers
      53   * 
      54   * A union holding one collected value.
      55   */
      56  union _GTypeCValue
      57  {
      58    gint     v_int;
      59    glong    v_long;
      60    gint64   v_int64;
      61    gdouble  v_double;
      62    gpointer v_pointer;
      63  };
      64  
      65  /**
      66   * G_VALUE_COLLECT_INIT:
      67   * @value: a #GValue return location. @value must contain only 0 bytes.
      68   * @_value_type: the #GType to use for @value.
      69   * @var_args: the va_list variable; it may be evaluated multiple times
      70   * @flags: flags which are passed on to the collect_value() function of
      71   *  the #GTypeValueTable of @value.
      72   * @__error: a #gchar** variable that will be modified to hold a g_new()
      73   *  allocated error messages if something fails
      74   * 
      75   * Collects a variable argument value from a `va_list`.
      76   *
      77   * We have to implement the varargs collection as a macro, because on some
      78   * systems `va_list` variables cannot be passed by reference.
      79   *
      80   * Since: 2.24
      81   */
      82  #define G_VALUE_COLLECT_INIT(value, _value_type, var_args, flags, __error) \
      83    G_STMT_START { \
      84      GTypeValueTable *g_vci_vtab; \
      85      G_VALUE_COLLECT_INIT2(value, g_vci_vtab, _value_type, var_args, flags, __error); \
      86  } G_STMT_END
      87  
      88  /**
      89   * G_VALUE_COLLECT_INIT2:
      90   * @value: a #GValue return location. @value must contain only 0 bytes.
      91   * @g_vci_vtab: a #GTypeValueTable pointer that will be set to the value table
      92   *   for @_value_type
      93   * @_value_type: the #GType to use for @value.
      94   * @var_args: the va_list variable; it may be evaluated multiple times
      95   * @flags: flags which are passed on to the collect_value() function of
      96   *  the #GTypeValueTable of @value.
      97   * @__error: a #gchar** variable that will be modified to hold a g_new()
      98   *  allocated error messages if something fails
      99   *
     100   * A variant of G_VALUE_COLLECT_INIT() that provides the #GTypeValueTable
     101   * to the caller.
     102   *
     103   * Since: 2.74
     104   */
     105  #define G_VALUE_COLLECT_INIT2(value, g_vci_vtab, _value_type, var_args, flags, __error)		\
     106  G_STMT_START {										\
     107    GValue *g_vci_val = (value);								\
     108    guint g_vci_flags = (flags);								\
     109    const gchar *g_vci_collect_format; \
     110    GTypeCValue g_vci_cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, };		\
     111    guint g_vci_n_values = 0;									\
     112    g_vci_vtab = g_type_value_table_peek (_value_type);			\
     113    g_vci_collect_format = g_vci_vtab->collect_format;					\
     114    g_vci_val->g_type = _value_type;		/* value_meminit() from gvalue.c */		\
     115    while (*g_vci_collect_format)								\
     116      {											\
     117        GTypeCValue *g_vci_cvalue = g_vci_cvalues + g_vci_n_values++;					\
     118                                                                                          \
     119        switch (*g_vci_collect_format++)							\
     120  	{										\
     121  	case G_VALUE_COLLECT_INT:							\
     122  	  g_vci_cvalue->v_int = va_arg ((var_args), gint);					\
     123  	  break;									\
     124  	case G_VALUE_COLLECT_LONG:							\
     125  	  g_vci_cvalue->v_long = va_arg ((var_args), glong);					\
     126  	  break;									\
     127  	case G_VALUE_COLLECT_INT64:							\
     128  	  g_vci_cvalue->v_int64 = va_arg ((var_args), gint64);				\
     129  	  break;									\
     130  	case G_VALUE_COLLECT_DOUBLE:							\
     131  	  g_vci_cvalue->v_double = va_arg ((var_args), gdouble);				\
     132  	  break;									\
     133  	case G_VALUE_COLLECT_POINTER:							\
     134  	  g_vci_cvalue->v_pointer = va_arg ((var_args), gpointer);				\
     135  	  break;									\
     136  	default:									\
     137  	  g_assert_not_reached ();							\
     138  	}										\
     139      }											\
     140    *(__error) = g_vci_vtab->collect_value (g_vci_val,						\
     141  				       g_vci_n_values,					\
     142  				       g_vci_cvalues,					\
     143  				       g_vci_flags);						\
     144  } G_STMT_END
     145  
     146  /**
     147   * G_VALUE_COLLECT:
     148   * @value: a #GValue return location. @value is supposed to be initialized
     149   *  according to the value type to be collected
     150   * @var_args: the va_list variable; it may be evaluated multiple times
     151   * @flags: flags which are passed on to the collect_value() function of
     152   *  the #GTypeValueTable of @value.
     153   * @__error: a #gchar** variable that will be modified to hold a g_new()
     154   *  allocated error messages if something fails
     155   *
     156   * Collects a variable argument value from a `va_list`.
     157   *
     158   * We have to implement the varargs collection as a macro, because on some systems
     159   * `va_list` variables cannot be passed by reference.
     160   *
     161   * Note: If you are creating the @value argument just before calling this macro,
     162   * you should use the G_VALUE_COLLECT_INIT() variant and pass the uninitialized
     163   * #GValue. That variant is faster than G_VALUE_COLLECT().
     164   */
     165  #define G_VALUE_COLLECT(value, var_args, flags, __error) G_STMT_START {			\
     166    GValue *g_vc_value = (value);								\
     167    GType g_vc_value_type = G_VALUE_TYPE (g_vc_value);						\
     168    GTypeValueTable *g_vc_vtable = g_type_value_table_peek (g_vc_value_type);			\
     169  											\
     170    if (g_vc_vtable->value_free)								\
     171      g_vc_vtable->value_free (g_vc_value);							\
     172    memset (g_vc_value->data, 0, sizeof (g_vc_value->data));					\
     173  											\
     174    G_VALUE_COLLECT_INIT(value, g_vc_value_type, var_args, flags, __error);			\
     175  } G_STMT_END
     176  
     177  /**
     178   * G_VALUE_COLLECT_SKIP:
     179   * @_value_type: the #GType of the value to skip
     180   * @var_args: the va_list variable; it may be evaluated multiple times
     181   *
     182   * Skip an argument of type @_value_type from @var_args.
     183   */
     184  #define G_VALUE_COLLECT_SKIP(_value_type, var_args)					\
     185  G_STMT_START {										\
     186    GTypeValueTable *g_vcs_vtable = g_type_value_table_peek (_value_type);			\
     187    const gchar *g_vcs_collect_format = g_vcs_vtable->collect_format;				\
     188                                                                                          \
     189    while (*g_vcs_collect_format)								\
     190      {											\
     191        switch (*g_vcs_collect_format++)							\
     192  	{										\
     193  	case G_VALUE_COLLECT_INT:							\
     194  	  va_arg ((var_args), gint);							\
     195  	  break;									\
     196  	case G_VALUE_COLLECT_LONG:							\
     197  	  va_arg ((var_args), glong);							\
     198  	  break;									\
     199  	case G_VALUE_COLLECT_INT64:							\
     200  	  va_arg ((var_args), gint64);							\
     201  	  break;									\
     202  	case G_VALUE_COLLECT_DOUBLE:							\
     203  	  va_arg ((var_args), gdouble);							\
     204  	  break;									\
     205  	case G_VALUE_COLLECT_POINTER:							\
     206  	  va_arg ((var_args), gpointer);						\
     207  	  break;									\
     208  	default:									\
     209  	  g_assert_not_reached ();							\
     210  	}										\
     211      }											\
     212  } G_STMT_END
     213  
     214  /**
     215   * G_VALUE_LCOPY:
     216   * @value: a #GValue to store into the @var_args; this must be initialized
     217   *  and set
     218   * @var_args: the va_list variable; it may be evaluated multiple times
     219   * @flags: flags which are passed on to the lcopy_value() function of
     220   *  the #GTypeValueTable of @value.
     221   * @__error: a #gchar** variable that will be modified to hold a g_new()
     222   *  allocated error message if something fails
     223   *
     224   * Stores a value’s value into one or more argument locations from a `va_list`.
     225   *
     226   * This is the inverse of G_VALUE_COLLECT().
     227   */
     228  #define G_VALUE_LCOPY(value, var_args, flags, __error)					\
     229  G_STMT_START {										\
     230    const GValue *g_vl_value = (value);							\
     231    guint g_vl_flags = (flags);								\
     232    GType g_vl_value_type = G_VALUE_TYPE (g_vl_value);						\
     233    GTypeValueTable *g_vl_vtable = g_type_value_table_peek (g_vl_value_type);			\
     234    const gchar *g_vl_lcopy_format = g_vl_vtable->lcopy_format;					\
     235    GTypeCValue g_vl_cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, };		\
     236    guint g_vl_n_values = 0;									\
     237                                                                                          \
     238    while (*g_vl_lcopy_format)								\
     239      {											\
     240        GTypeCValue *g_vl_cvalue = g_vl_cvalues + g_vl_n_values++;					\
     241                                                                                          \
     242        switch (*g_vl_lcopy_format++)								\
     243  	{										\
     244  	case G_VALUE_COLLECT_INT:							\
     245  	  g_vl_cvalue->v_int = va_arg ((var_args), gint);					\
     246  	  break;									\
     247  	case G_VALUE_COLLECT_LONG:							\
     248  	  g_vl_cvalue->v_long = va_arg ((var_args), glong);					\
     249  	  break;									\
     250  	case G_VALUE_COLLECT_INT64:							\
     251  	  g_vl_cvalue->v_int64 = va_arg ((var_args), gint64);				\
     252  	  break;									\
     253  	case G_VALUE_COLLECT_DOUBLE:							\
     254  	  g_vl_cvalue->v_double = va_arg ((var_args), gdouble);				\
     255  	  break;									\
     256  	case G_VALUE_COLLECT_POINTER:							\
     257  	  g_vl_cvalue->v_pointer = va_arg ((var_args), gpointer);				\
     258  	  break;									\
     259  	default:									\
     260  	  g_assert_not_reached ();							\
     261  	}										\
     262      }											\
     263    *(__error) = g_vl_vtable->lcopy_value (g_vl_value,						\
     264  				     g_vl_n_values,						\
     265  				     g_vl_cvalues,						\
     266  				     g_vl_flags);						\
     267  } G_STMT_END
     268  
     269  
     270  /**
     271   * G_VALUE_COLLECT_FORMAT_MAX_LENGTH:
     272   * 
     273   * The maximal number of #GTypeCValues which can be collected for a 
     274   * single #GValue.
     275   */
     276  #define	G_VALUE_COLLECT_FORMAT_MAX_LENGTH	(8)
     277  
     278  G_END_DECLS
     279  
     280  #endif /* __G_VALUE_COLLECTOR_H__ */