gvaluecollector.h 10 KB

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