Branch data Line data Source code
1 : : /* GLIB - Library of useful routines for C programming
2 : : * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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 Public
17 : : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 : : */
19 : :
20 : : /*
21 : : * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 : : * file for a list of people on the GLib Team. See the ChangeLog
23 : : * files for a list of changes. These files are distributed with
24 : : * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 : : */
26 : :
27 : : #define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_30
28 : :
29 : : #include <glib.h>
30 : : #include <glib-object.h>
31 : : #include "gobject/gvaluecollector.h"
32 : :
33 : : static void
34 : 1 : test_enum_transformation (void)
35 : : {
36 : : GType type;
37 : 1 : GValue orig = G_VALUE_INIT;
38 : 1 : GValue xform = G_VALUE_INIT;
39 : 1 : GEnumValue values[] = { {0,"0","0"}, {1,"1","1"}};
40 : :
41 : 1 : type = g_enum_register_static ("TestEnum", values);
42 : :
43 : 1 : g_value_init (&orig, type);
44 : 1 : g_value_set_enum (&orig, 1);
45 : :
46 : 1 : memset (&xform, 0, sizeof (GValue));
47 : 1 : g_value_init (&xform, G_TYPE_CHAR);
48 : 1 : g_value_transform (&orig, &xform);
49 : 1 : g_assert_cmpint (g_value_get_char (&xform), ==, 1);
50 : 1 : g_assert_cmpint (g_value_get_schar (&xform), ==, 1);
51 : :
52 : 1 : memset (&xform, 0, sizeof (GValue));
53 : 1 : g_value_init (&xform, G_TYPE_UCHAR);
54 : 1 : g_value_transform (&orig, &xform);
55 : 1 : g_assert_cmpint (g_value_get_uchar (&xform), ==, 1);
56 : :
57 : 1 : memset (&xform, 0, sizeof (GValue));
58 : 1 : g_value_init (&xform, G_TYPE_INT);
59 : 1 : g_value_transform (&orig, &xform);
60 : 1 : g_assert_cmpint (g_value_get_int (&xform), ==, 1);
61 : :
62 : 1 : memset (&xform, 0, sizeof (GValue));
63 : 1 : g_value_init (&xform, G_TYPE_UINT);
64 : 1 : g_value_transform (&orig, &xform);
65 : 1 : g_assert_cmpint (g_value_get_uint (&xform), ==, 1);
66 : :
67 : 1 : memset (&xform, 0, sizeof (GValue));
68 : 1 : g_value_init (&xform, G_TYPE_LONG);
69 : 1 : g_value_transform (&orig, &xform);
70 : 1 : g_assert_cmpint (g_value_get_long (&xform), ==, 1);
71 : :
72 : 1 : memset (&xform, 0, sizeof (GValue));
73 : 1 : g_value_init (&xform, G_TYPE_ULONG);
74 : 1 : g_value_transform (&orig, &xform);
75 : 1 : g_assert_cmpint (g_value_get_ulong (&xform), ==, 1);
76 : :
77 : 1 : memset (&xform, 0, sizeof (GValue));
78 : 1 : g_value_init (&xform, G_TYPE_INT64);
79 : 1 : g_value_transform (&orig, &xform);
80 : 1 : g_assert_cmpint (g_value_get_int64 (&xform), ==, 1);
81 : :
82 : 1 : memset (&xform, 0, sizeof (GValue));
83 : 1 : g_value_init (&xform, G_TYPE_UINT64);
84 : 1 : g_value_transform (&orig, &xform);
85 : 1 : g_assert_cmpint (g_value_get_uint64 (&xform), ==, 1);
86 : 1 : }
87 : :
88 : :
89 : : static void
90 : 1 : test_gtype_value (void)
91 : : {
92 : : GType type;
93 : 1 : GValue value = G_VALUE_INIT;
94 : 1 : GValue copy = G_VALUE_INIT;
95 : :
96 : 1 : g_value_init (&value, G_TYPE_GTYPE);
97 : :
98 : 1 : g_value_set_gtype (&value, G_TYPE_BOXED);
99 : 1 : type = g_value_get_gtype (&value);
100 : 1 : g_assert_true (type == G_TYPE_BOXED);
101 : :
102 : 1 : g_value_init (©, G_TYPE_GTYPE);
103 : 1 : g_value_copy (&value, ©);
104 : 1 : type = g_value_get_gtype (©);
105 : 1 : g_assert_true (type == G_TYPE_BOXED);
106 : 1 : }
107 : :
108 : : static gchar *
109 : 14 : collect (GValue *value, ...)
110 : : {
111 : : gchar *error;
112 : : va_list var_args;
113 : :
114 : 14 : error = NULL;
115 : :
116 : 14 : va_start (var_args, value);
117 : 28 : G_VALUE_COLLECT (value, var_args, 0, &error);
118 : 14 : va_end (var_args);
119 : :
120 : 14 : return error;
121 : : }
122 : :
123 : : static gchar *
124 : 13 : lcopy (GValue *value, ...)
125 : : {
126 : : gchar *error;
127 : : va_list var_args;
128 : :
129 : 13 : error = NULL;
130 : :
131 : 13 : va_start (var_args, value);
132 : 26 : G_VALUE_LCOPY (value, var_args, 0, &error);
133 : 13 : va_end (var_args);
134 : :
135 : 13 : return error;
136 : : }
137 : :
138 : : static void
139 : 1 : test_collection (void)
140 : : {
141 : 1 : GValue value = G_VALUE_INIT;
142 : : gchar *error;
143 : :
144 : 1 : g_value_init (&value, G_TYPE_CHAR);
145 : 1 : error = collect (&value, 'c');
146 : 1 : g_assert_null (error);
147 : 1 : g_assert_cmpint (g_value_get_char (&value), ==, 'c');
148 : :
149 : 1 : g_value_unset (&value);
150 : 1 : g_value_init (&value, G_TYPE_UCHAR);
151 : 1 : error = collect (&value, 129);
152 : 1 : g_assert_null (error);
153 : 1 : g_assert_cmpint (g_value_get_uchar (&value), ==, 129);
154 : :
155 : 1 : g_value_unset (&value);
156 : 1 : g_value_init (&value, G_TYPE_BOOLEAN);
157 : 1 : error = collect (&value, TRUE);
158 : 1 : g_assert_null (error);
159 : 1 : g_assert_cmpint (g_value_get_boolean (&value), ==, TRUE);
160 : :
161 : 1 : g_value_unset (&value);
162 : 1 : g_value_init (&value, G_TYPE_INT);
163 : 1 : error = collect (&value, G_MAXINT);
164 : 1 : g_assert_null (error);
165 : 1 : g_assert_cmpint (g_value_get_int (&value), ==, G_MAXINT);
166 : :
167 : 1 : g_value_unset (&value);
168 : 1 : g_value_init (&value, G_TYPE_UINT);
169 : 1 : error = collect (&value, G_MAXUINT);
170 : 1 : g_assert_null (error);
171 : 1 : g_assert_cmpuint (g_value_get_uint (&value), ==, G_MAXUINT);
172 : :
173 : 1 : g_value_unset (&value);
174 : 1 : g_value_init (&value, G_TYPE_LONG);
175 : 1 : error = collect (&value, G_MAXLONG);
176 : 1 : g_assert_null (error);
177 : 1 : g_assert_cmpint (g_value_get_long (&value), ==, G_MAXLONG);
178 : :
179 : 1 : g_value_unset (&value);
180 : 1 : g_value_init (&value, G_TYPE_ULONG);
181 : 1 : error = collect (&value, G_MAXULONG);
182 : 1 : g_assert_null (error);
183 : 1 : g_assert_cmpuint (g_value_get_ulong (&value), ==, G_MAXULONG);
184 : :
185 : 1 : g_value_unset (&value);
186 : 1 : g_value_init (&value, G_TYPE_INT64);
187 : 1 : error = collect (&value, G_MAXINT64);
188 : 1 : g_assert_null (error);
189 : 1 : g_assert_cmpint (g_value_get_int64 (&value), ==, G_MAXINT64);
190 : :
191 : 1 : g_value_unset (&value);
192 : 1 : g_value_init (&value, G_TYPE_UINT64);
193 : 1 : error = collect (&value, G_MAXUINT64);
194 : 1 : g_assert_null (error);
195 : 1 : g_assert_cmpuint (g_value_get_uint64 (&value), ==, G_MAXUINT64);
196 : :
197 : 1 : g_value_unset (&value);
198 : 1 : g_value_init (&value, G_TYPE_FLOAT);
199 : 1 : error = collect (&value, G_MAXFLOAT);
200 : 1 : g_assert_null (error);
201 : 1 : g_assert_cmpfloat (g_value_get_float (&value), ==, G_MAXFLOAT);
202 : :
203 : 1 : g_value_unset (&value);
204 : 1 : g_value_init (&value, G_TYPE_DOUBLE);
205 : 1 : error = collect (&value, G_MAXDOUBLE);
206 : 1 : g_assert_null (error);
207 : 1 : g_assert_cmpfloat (g_value_get_double (&value), ==, G_MAXDOUBLE);
208 : :
209 : 1 : g_value_unset (&value);
210 : 1 : g_value_init (&value, G_TYPE_STRING);
211 : 1 : error = collect (&value, "string ?");
212 : 1 : g_assert_null (error);
213 : 1 : g_assert_cmpstr (g_value_get_string (&value), ==, "string ?");
214 : :
215 : 1 : g_value_unset (&value);
216 : 1 : g_value_init (&value, G_TYPE_GTYPE);
217 : 1 : error = collect (&value, G_TYPE_BOXED);
218 : 1 : g_assert_null (error);
219 : 1 : g_assert_true (g_value_get_gtype (&value) == G_TYPE_BOXED);
220 : :
221 : 1 : g_value_unset (&value);
222 : 1 : g_value_init (&value, G_TYPE_VARIANT);
223 : 1 : error = collect (&value, g_variant_new_uint32 (42));
224 : 1 : g_assert_null (error);
225 : 1 : g_assert_true (g_variant_is_of_type (g_value_get_variant (&value),
226 : : G_VARIANT_TYPE ("u")));
227 : 1 : g_assert_cmpuint (g_variant_get_uint32 (g_value_get_variant (&value)), ==, 42);
228 : :
229 : 1 : g_value_unset (&value);
230 : 1 : }
231 : :
232 : : static void
233 : 1 : test_copying (void)
234 : : {
235 : 1 : GValue value = G_VALUE_INIT;
236 : : gchar *error;
237 : :
238 : : {
239 : 1 : gchar c = 0;
240 : :
241 : 1 : g_value_init (&value, G_TYPE_CHAR);
242 : 1 : g_value_set_char (&value, 'c');
243 : 1 : error = lcopy (&value, &c);
244 : 1 : g_assert_null (error);
245 : 1 : g_assert_cmpint (c, ==, 'c');
246 : : }
247 : :
248 : : {
249 : 1 : guchar c = 0;
250 : :
251 : 1 : g_value_unset (&value);
252 : 1 : g_value_init (&value, G_TYPE_UCHAR);
253 : 1 : g_value_set_uchar (&value, 129);
254 : 1 : error = lcopy (&value, &c);
255 : 1 : g_assert_null (error);
256 : 1 : g_assert_cmpint (c, ==, 129);
257 : : }
258 : :
259 : : {
260 : 1 : gint c = 0;
261 : :
262 : 1 : g_value_unset (&value);
263 : 1 : g_value_init (&value, G_TYPE_INT);
264 : 1 : g_value_set_int (&value, G_MAXINT);
265 : 1 : error = lcopy (&value, &c);
266 : 1 : g_assert_null (error);
267 : 1 : g_assert_cmpint (c, ==, G_MAXINT);
268 : : }
269 : :
270 : : {
271 : 1 : guint c = 0;
272 : :
273 : 1 : g_value_unset (&value);
274 : 1 : g_value_init (&value, G_TYPE_UINT);
275 : 1 : g_value_set_uint (&value, G_MAXUINT);
276 : 1 : error = lcopy (&value, &c);
277 : 1 : g_assert_null (error);
278 : 1 : g_assert_cmpuint (c, ==, G_MAXUINT);
279 : : }
280 : :
281 : : {
282 : 1 : glong c = 0;
283 : :
284 : 1 : g_value_unset (&value);
285 : 1 : g_value_init (&value, G_TYPE_LONG);
286 : 1 : g_value_set_long (&value, G_MAXLONG);
287 : 1 : error = lcopy (&value, &c);
288 : 1 : g_assert_null (error);
289 : 1 : g_assert (c == G_MAXLONG);
290 : : }
291 : :
292 : : {
293 : 1 : gulong c = 0;
294 : :
295 : 1 : g_value_unset (&value);
296 : 1 : g_value_init (&value, G_TYPE_ULONG);
297 : 1 : g_value_set_ulong (&value, G_MAXULONG);
298 : 1 : error = lcopy (&value, &c);
299 : 1 : g_assert_null (error);
300 : 1 : g_assert (c == G_MAXULONG);
301 : : }
302 : :
303 : : {
304 : 1 : gint64 c = 0;
305 : :
306 : 1 : g_value_unset (&value);
307 : 1 : g_value_init (&value, G_TYPE_INT64);
308 : 1 : g_value_set_int64 (&value, G_MAXINT64);
309 : 1 : error = lcopy (&value, &c);
310 : 1 : g_assert_null (error);
311 : 1 : g_assert (c == G_MAXINT64);
312 : : }
313 : :
314 : : {
315 : 1 : guint64 c = 0;
316 : :
317 : 1 : g_value_unset (&value);
318 : 1 : g_value_init (&value, G_TYPE_UINT64);
319 : 1 : g_value_set_uint64 (&value, G_MAXUINT64);
320 : 1 : error = lcopy (&value, &c);
321 : 1 : g_assert_null (error);
322 : 1 : g_assert (c == G_MAXUINT64);
323 : : }
324 : :
325 : : {
326 : 1 : gfloat c = 0;
327 : :
328 : 1 : g_value_unset (&value);
329 : 1 : g_value_init (&value, G_TYPE_FLOAT);
330 : 1 : g_value_set_float (&value, G_MAXFLOAT);
331 : 1 : error = lcopy (&value, &c);
332 : 1 : g_assert_null (error);
333 : 1 : g_assert (c == G_MAXFLOAT);
334 : : }
335 : :
336 : : {
337 : 1 : gdouble c = 0;
338 : :
339 : 1 : g_value_unset (&value);
340 : 1 : g_value_init (&value, G_TYPE_DOUBLE);
341 : 1 : g_value_set_double (&value, G_MAXDOUBLE);
342 : 1 : error = lcopy (&value, &c);
343 : 1 : g_assert_null (error);
344 : 1 : g_assert (c == G_MAXDOUBLE);
345 : : }
346 : :
347 : : {
348 : 1 : gchar *c = NULL;
349 : :
350 : 1 : g_value_unset (&value);
351 : 1 : g_value_init (&value, G_TYPE_STRING);
352 : 1 : g_value_set_string (&value, "string ?");
353 : 1 : error = lcopy (&value, &c);
354 : 1 : g_assert_null (error);
355 : 1 : g_assert_cmpstr (c, ==, "string ?");
356 : 1 : g_free (c);
357 : : }
358 : :
359 : : {
360 : 1 : GType c = G_TYPE_NONE;
361 : :
362 : 1 : g_value_unset (&value);
363 : 1 : g_value_init (&value, G_TYPE_GTYPE);
364 : 1 : g_value_set_gtype (&value, G_TYPE_BOXED);
365 : 1 : error = lcopy (&value, &c);
366 : 1 : g_assert_null (error);
367 : 1 : g_assert_true (c == G_TYPE_BOXED);
368 : : }
369 : :
370 : : {
371 : 1 : GVariant *c = NULL;
372 : :
373 : 1 : g_value_unset (&value);
374 : 1 : g_value_init (&value, G_TYPE_VARIANT);
375 : 1 : g_value_set_variant (&value, g_variant_new_uint32 (42));
376 : 1 : error = lcopy (&value, &c);
377 : 1 : g_assert_null (error);
378 : 1 : g_assert_nonnull (c);
379 : 1 : g_assert (g_variant_is_of_type (c, G_VARIANT_TYPE ("u")));
380 : 1 : g_assert_cmpuint (g_variant_get_uint32 (c), ==, 42);
381 : 1 : g_variant_unref (c);
382 : 1 : g_value_unset (&value);
383 : : }
384 : 1 : }
385 : :
386 : : static void
387 : 1 : test_value_basic (void)
388 : : {
389 : 1 : GValue value = G_VALUE_INIT;
390 : :
391 : 1 : g_assert_false (G_IS_VALUE (&value));
392 : 1 : g_assert_false (G_VALUE_HOLDS_INT (&value));
393 : 1 : g_value_unset (&value);
394 : 1 : g_assert_false (G_IS_VALUE (&value));
395 : 1 : g_assert_false (G_VALUE_HOLDS_INT (&value));
396 : :
397 : 1 : g_value_init (&value, G_TYPE_INT);
398 : 1 : g_assert_true (G_IS_VALUE (&value));
399 : 1 : g_assert_true (G_VALUE_HOLDS_INT (&value));
400 : 1 : g_assert_false (G_VALUE_HOLDS_UINT (&value));
401 : 1 : g_assert_cmpint (g_value_get_int (&value), ==, 0);
402 : :
403 : 1 : g_value_set_int (&value, 10);
404 : 1 : g_assert_cmpint (g_value_get_int (&value), ==, 10);
405 : :
406 : 1 : g_value_reset (&value);
407 : 1 : g_assert_true (G_IS_VALUE (&value));
408 : 1 : g_assert_true (G_VALUE_HOLDS_INT (&value));
409 : 1 : g_assert_cmpint (g_value_get_int (&value), ==, 0);
410 : :
411 : 1 : g_value_unset (&value);
412 : 1 : g_assert_false (G_IS_VALUE (&value));
413 : 1 : g_assert_false (G_VALUE_HOLDS_INT (&value));
414 : 1 : }
415 : :
416 : : static void
417 : 1 : test_value_string (void)
418 : : {
419 : 1 : const gchar *static1 = "static1";
420 : 1 : const gchar *static2 = "static2";
421 : : const gchar *storedstr;
422 : : const gchar *copystr;
423 : : gchar *str1, *str2, *stolen_str;
424 : 1 : GValue value = G_VALUE_INIT;
425 : 1 : GValue copy = G_VALUE_INIT;
426 : :
427 : 1 : g_test_summary ("Test that G_TYPE_STRING GValue copy properly");
428 : :
429 : : /*
430 : : * Regular strings (ownership not passed)
431 : : */
432 : :
433 : : /* Create a regular string gvalue and make sure it copies the provided string */
434 : 1 : g_value_init (&value, G_TYPE_STRING);
435 : 1 : g_assert_true (G_VALUE_HOLDS_STRING (&value));
436 : :
437 : : /* The string contents should be empty at this point */
438 : 1 : storedstr = g_value_get_string (&value);
439 : 1 : g_assert_true (storedstr == NULL);
440 : :
441 : 1 : g_value_set_string (&value, static1);
442 : : /* The contents should be a copy of the same string */
443 : 1 : storedstr = g_value_get_string (&value);
444 : 1 : g_assert_true (storedstr != static1);
445 : 1 : g_assert_cmpstr (storedstr, ==, static1);
446 : : /* Check g_value_dup_string() provides a copy */
447 : 1 : str1 = g_value_dup_string (&value);
448 : 1 : g_assert_true (storedstr != str1);
449 : 1 : g_assert_cmpstr (str1, ==, static1);
450 : 1 : g_free (str1);
451 : :
452 : : /* Copying a regular string gvalue should copy the contents */
453 : 1 : g_value_init (©, G_TYPE_STRING);
454 : 1 : g_value_copy (&value, ©);
455 : 1 : copystr = g_value_get_string (©);
456 : 1 : g_assert_true (copystr != storedstr);
457 : 1 : g_assert_cmpstr (copystr, ==, static1);
458 : 1 : g_value_unset (©);
459 : :
460 : : /* Setting a new string should change the contents */
461 : 1 : g_value_set_string (&value, static2);
462 : : /* The contents should be a copy of that *new* string */
463 : 1 : storedstr = g_value_get_string (&value);
464 : 1 : g_assert_true (storedstr != static2);
465 : 1 : g_assert_cmpstr (storedstr, ==, static2);
466 : :
467 : : /* Setting a static string over that should also change it (test for
468 : : * coverage and valgrind) */
469 : 1 : g_value_set_static_string (&value, static1);
470 : 1 : storedstr = g_value_get_string (&value);
471 : 1 : g_assert_true (storedstr != static2);
472 : 1 : g_assert_cmpstr (storedstr, ==, static1);
473 : :
474 : : /* Giving a string directly (ownership passed) should replace the content */
475 : 1 : str2 = g_strdup (static2);
476 : 1 : g_value_take_string (&value, str2);
477 : 1 : storedstr = g_value_get_string (&value);
478 : 1 : g_assert_true (storedstr != static2);
479 : 1 : g_assert_cmpstr (storedstr, ==, str2);
480 : :
481 : 1 : g_value_unset (&value);
482 : :
483 : : /*
484 : : * Regular strings (ownership passed)
485 : : */
486 : :
487 : 1 : g_value_init (&value, G_TYPE_STRING);
488 : 1 : g_assert_true (G_VALUE_HOLDS_STRING (&value));
489 : 1 : str1 = g_strdup (static1);
490 : 1 : g_value_take_string (&value, str1);
491 : : /* The contents should be the string we provided */
492 : 1 : storedstr = g_value_get_string (&value);
493 : 1 : g_assert_true (storedstr == str1);
494 : : /* But g_value_dup_string() should provide a copy */
495 : 1 : str2 = g_value_dup_string (&value);
496 : 1 : g_assert_true (storedstr != str2);
497 : 1 : g_assert_cmpstr (str2, ==, static1);
498 : 1 : g_free (str2);
499 : :
500 : : /* Copying a regular string gvalue (even with ownership passed) should copy
501 : : * the contents */
502 : 1 : g_value_init (©, G_TYPE_STRING);
503 : 1 : g_value_copy (&value, ©);
504 : 1 : copystr = g_value_get_string (©);
505 : 1 : g_assert_true (copystr != storedstr);
506 : 1 : g_assert_cmpstr (copystr, ==, static1);
507 : 1 : g_value_unset (©);
508 : :
509 : : /* Setting a new regular string should change the contents */
510 : 1 : g_value_set_string (&value, static2);
511 : : /* The contents should be a copy of that *new* string */
512 : 1 : storedstr = g_value_get_string (&value);
513 : 1 : g_assert_true (storedstr != static2);
514 : 1 : g_assert_cmpstr (storedstr, ==, static2);
515 : :
516 : : /* Now check stealing the ownership of the contents */
517 : 1 : stolen_str = g_value_steal_string (&value);
518 : 1 : g_assert_null (g_value_get_string (&value));
519 : 1 : g_value_unset (&value);
520 : 1 : g_assert_cmpstr (stolen_str, ==, static2);
521 : 1 : g_free (stolen_str);
522 : :
523 : : /*
524 : : * Static strings
525 : : */
526 : 1 : g_value_init (&value, G_TYPE_STRING);
527 : 1 : g_assert_true (G_VALUE_HOLDS_STRING (&value));
528 : 1 : g_value_set_static_string (&value, static1);
529 : : /* The contents should be the string we provided */
530 : 1 : storedstr = g_value_get_string (&value);
531 : 1 : g_assert_true (storedstr == static1);
532 : : /* But g_value_dup_string() should provide a copy */
533 : 1 : str2 = g_value_dup_string (&value);
534 : 1 : g_assert_true (storedstr != str2);
535 : 1 : g_assert_cmpstr (str2, ==, static1);
536 : 1 : g_free (str2);
537 : :
538 : : /* Copying a static string gvalue should *actually* copy the contents */
539 : 1 : g_value_init (©, G_TYPE_STRING);
540 : 1 : g_value_copy (&value, ©);
541 : 1 : copystr = g_value_get_string (©);
542 : 1 : g_assert_true (copystr != static1);
543 : 1 : g_value_unset (©);
544 : :
545 : : /* Setting a new string should change the contents */
546 : 1 : g_value_set_static_string (&value, static2);
547 : : /* The contents should be a copy of that *new* string */
548 : 1 : storedstr = g_value_get_string (&value);
549 : 1 : g_assert_true (storedstr != static1);
550 : 1 : g_assert_cmpstr (storedstr, ==, static2);
551 : :
552 : : /* Check if g_value_steal_string() can handle GValue
553 : : * with a static string */
554 : 1 : stolen_str = g_value_steal_string (&value);
555 : 1 : g_assert_true (stolen_str != static2);
556 : 1 : g_assert_cmpstr (stolen_str, ==, static2);
557 : 1 : g_assert_null (g_value_get_string (&value));
558 : 1 : g_free (stolen_str);
559 : :
560 : 1 : g_value_unset (&value);
561 : :
562 : : /*
563 : : * Interned/Canonical strings
564 : : */
565 : 1 : static1 = g_intern_static_string (static1);
566 : 1 : g_value_init (&value, G_TYPE_STRING);
567 : 1 : g_assert_true (G_VALUE_HOLDS_STRING (&value));
568 : 1 : g_value_set_interned_string (&value, static1);
569 : 1 : g_assert_true (G_VALUE_IS_INTERNED_STRING (&value));
570 : : /* The contents should be the string we provided */
571 : 1 : storedstr = g_value_get_string (&value);
572 : 1 : g_assert_true (storedstr == static1);
573 : : /* But g_value_dup_string() should provide a copy */
574 : 1 : str2 = g_value_dup_string (&value);
575 : 1 : g_assert_true (storedstr != str2);
576 : 1 : g_assert_cmpstr (str2, ==, static1);
577 : 1 : g_free (str2);
578 : :
579 : : /* Copying an interned string gvalue should *not* copy the contents
580 : : * and should still be an interned string */
581 : 1 : g_value_init (©, G_TYPE_STRING);
582 : 1 : g_value_copy (&value, ©);
583 : 1 : g_assert_true (G_VALUE_IS_INTERNED_STRING (©));
584 : 1 : copystr = g_value_get_string (©);
585 : 1 : g_assert_true (copystr == static1);
586 : 1 : g_value_unset (©);
587 : :
588 : : /* Setting a new interned string should change the contents */
589 : 1 : static2 = g_intern_static_string (static2);
590 : 1 : g_value_set_interned_string (&value, static2);
591 : 1 : g_assert_true (G_VALUE_IS_INTERNED_STRING (&value));
592 : : /* The contents should be the interned string */
593 : 1 : storedstr = g_value_get_string (&value);
594 : 1 : g_assert_cmpstr (storedstr, ==, static2);
595 : :
596 : : /* Setting a new regular string should change the contents */
597 : 1 : g_value_set_string (&value, static2);
598 : 1 : g_assert_false (G_VALUE_IS_INTERNED_STRING (&value));
599 : : /* The contents should be a copy of that *new* string */
600 : 1 : storedstr = g_value_get_string (&value);
601 : 1 : g_assert_true (storedstr != static2);
602 : 1 : g_assert_cmpstr (storedstr, ==, static2);
603 : :
604 : : /* Check if g_value_steal_string() can handle GValue
605 : : * with an interned string */
606 : 1 : stolen_str = g_value_steal_string (&value);
607 : 1 : g_assert_true (stolen_str != static2);
608 : 1 : g_assert_cmpstr (stolen_str, ==, static2);
609 : 1 : g_assert_null (g_value_get_string (&value));
610 : 1 : g_free (stolen_str);
611 : :
612 : 1 : g_value_unset (&value);
613 : 1 : }
614 : :
615 : : static gint
616 : 488 : cmpint (gconstpointer a, gconstpointer b)
617 : : {
618 : 488 : const GValue *aa = a;
619 : 488 : const GValue *bb = b;
620 : :
621 : 488 : return g_value_get_int (aa) - g_value_get_int (bb);
622 : : }
623 : :
624 : : static void
625 : 1 : test_valuearray_basic (void)
626 : : {
627 : : GValueArray *a;
628 : : GValueArray *a2;
629 : 1 : GValue v = G_VALUE_INIT;
630 : : GValue *p;
631 : : guint i;
632 : :
633 : 1 : a = g_value_array_new (20);
634 : :
635 : 1 : g_value_init (&v, G_TYPE_INT);
636 : 101 : for (i = 0; i < 100; i++)
637 : : {
638 : 100 : g_value_set_int (&v, i);
639 : 100 : g_value_array_append (a, &v);
640 : : }
641 : :
642 : 1 : g_assert_cmpint (a->n_values, ==, 100);
643 : 1 : p = g_value_array_get_nth (a, 5);
644 : 1 : g_assert_cmpint (g_value_get_int (p), ==, 5);
645 : :
646 : 17 : for (i = 20; i < 100; i+= 5)
647 : 16 : g_value_array_remove (a, 100 - i);
648 : :
649 : 51 : for (i = 100; i < 150; i++)
650 : : {
651 : 50 : g_value_set_int (&v, i);
652 : 50 : g_value_array_prepend (a, &v);
653 : : }
654 : :
655 : 1 : g_value_array_sort (a, cmpint);
656 : 134 : for (i = 0; i < a->n_values - 1; i++)
657 : 133 : g_assert_cmpint (g_value_get_int (&a->values[i]), <=, g_value_get_int (&a->values[i+1]));
658 : :
659 : 1 : a2 = g_value_array_copy (a);
660 : 135 : for (i = 0; i < a->n_values; i++)
661 : 134 : g_assert_cmpint (g_value_get_int (&a->values[i]), ==, g_value_get_int (&a2->values[i]));
662 : :
663 : 1 : g_value_array_free (a);
664 : 1 : g_value_array_free (a2);
665 : 1 : }
666 : :
667 : : static gint
668 : 356 : cmpint_with_data (gconstpointer a,
669 : : gconstpointer b,
670 : : gpointer user_data)
671 : : {
672 : 356 : const GValue *aa = a;
673 : 356 : const GValue *bb = b;
674 : :
675 : 356 : g_assert_cmpuint (GPOINTER_TO_UINT (user_data), ==, 123);
676 : :
677 : 356 : return g_value_get_int (aa) - g_value_get_int (bb);
678 : : }
679 : :
680 : : static void
681 : 1 : test_value_array_sort_with_data (void)
682 : : {
683 : : GValueArray *a, *a2;
684 : 1 : GValue v = G_VALUE_INIT;
685 : :
686 : 1 : a = g_value_array_new (20);
687 : :
688 : : /* Try sorting an empty array. */
689 : 1 : a2 = g_value_array_sort_with_data (a, cmpint_with_data, GUINT_TO_POINTER (456));
690 : 1 : g_assert_cmpuint (a->n_values, ==, 0);
691 : 1 : g_assert_true (a2 == a);
692 : :
693 : : /* Add some values and try sorting them. */
694 : 1 : g_value_init (&v, G_TYPE_INT);
695 : 101 : for (unsigned int i = 0; i < 100; i++)
696 : : {
697 : 100 : g_value_set_int (&v, 100 - i);
698 : 100 : g_value_array_append (a, &v);
699 : : }
700 : :
701 : 1 : g_assert_cmpint (a->n_values, ==, 100);
702 : :
703 : 1 : a2 = g_value_array_sort_with_data (a, cmpint_with_data, GUINT_TO_POINTER (123));
704 : :
705 : 100 : for (unsigned int i = 0; i < a->n_values - 1; i++)
706 : 99 : g_assert_cmpint (g_value_get_int (&a->values[i]), <=, g_value_get_int (&a->values[i+1]));
707 : :
708 : 1 : g_assert_true (a2 == a);
709 : :
710 : 1 : g_value_array_free (a);
711 : 1 : }
712 : :
713 : : /* We create some dummy objects with this relationship:
714 : : *
715 : : * GObject TestInterface
716 : : * / \ / /
717 : : * TestObjectA TestObjectB /
718 : : * / \ /
719 : : * TestObjectA1 TestObjectA2-------
720 : : *
721 : : * ie: TestObjectA1 and TestObjectA2 are subclasses of TestObjectA
722 : : * and TestObjectB is related to neither. TestObjectA2 and TestObjectB
723 : : * implement TestInterface
724 : : */
725 : :
726 : : typedef GTypeInterface TestInterfaceInterface;
727 : : static GType test_interface_get_type (void);
728 : 3 : G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_OBJECT)
729 : 1 : static void test_interface_default_init (TestInterfaceInterface *iface) { }
730 : :
731 : : static GType test_object_a_get_type (void);
732 : : typedef GObject TestObjectA; typedef GObjectClass TestObjectAClass;
733 : 5 : G_DEFINE_TYPE (TestObjectA, test_object_a, G_TYPE_OBJECT)
734 : 1 : static void test_object_a_class_init (TestObjectAClass *class) { }
735 : 3 : static void test_object_a_init (TestObjectA *a) { }
736 : :
737 : : static GType test_object_b_get_type (void);
738 : : typedef GObject TestObjectB; typedef GObjectClass TestObjectBClass;
739 : 1 : static void test_object_b_iface_init (TestInterfaceInterface *iface) { }
740 : 3 : G_DEFINE_TYPE_WITH_CODE (TestObjectB, test_object_b, G_TYPE_OBJECT,
741 : : G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_object_b_iface_init))
742 : 1 : static void test_object_b_class_init (TestObjectBClass *class) { }
743 : 1 : static void test_object_b_init (TestObjectB *b) { }
744 : :
745 : : static GType test_object_a1_get_type (void);
746 : : typedef GObject TestObjectA1; typedef GObjectClass TestObjectA1Class;
747 : 3 : G_DEFINE_TYPE (TestObjectA1, test_object_a1, test_object_a_get_type ())
748 : 1 : static void test_object_a1_class_init (TestObjectA1Class *class) { }
749 : 1 : static void test_object_a1_init (TestObjectA1 *c) { }
750 : :
751 : : static GType test_object_a2_get_type (void);
752 : : typedef GObject TestObjectA2; typedef GObjectClass TestObjectA2Class;
753 : 1 : static void test_object_a2_iface_init (TestInterfaceInterface *iface) { }
754 : 3 : G_DEFINE_TYPE_WITH_CODE (TestObjectA2, test_object_a2, test_object_a_get_type (),
755 : : G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_object_a2_iface_init))
756 : 1 : static void test_object_a2_class_init (TestObjectA2Class *class) { }
757 : 1 : static void test_object_a2_init (TestObjectA2 *b) { }
758 : :
759 : : static void
760 : 1 : test_value_transform_object (void)
761 : : {
762 : 1 : GValue src = G_VALUE_INIT;
763 : 1 : GValue dest = G_VALUE_INIT;
764 : : GObject *object;
765 : : guint i, s, d;
766 : 6 : GType types[] = {
767 : : G_TYPE_OBJECT,
768 : 1 : test_interface_get_type (),
769 : 1 : test_object_a_get_type (),
770 : 1 : test_object_b_get_type (),
771 : 1 : test_object_a1_get_type (),
772 : 1 : test_object_a2_get_type ()
773 : : };
774 : :
775 : 7 : for (i = 0; i < G_N_ELEMENTS (types); i++)
776 : : {
777 : 6 : if (!G_TYPE_IS_CLASSED (types[i]))
778 : 1 : continue;
779 : :
780 : 5 : object = g_object_new (types[i], NULL);
781 : :
782 : 35 : for (s = 0; s < G_N_ELEMENTS (types); s++)
783 : : {
784 : 30 : if (!G_TYPE_CHECK_INSTANCE_TYPE (object, types[s]))
785 : 17 : continue;
786 : :
787 : 13 : g_value_init (&src, types[s]);
788 : 13 : g_value_set_object (&src, object);
789 : 13 : g_value_set_object (&src, g_value_get_object (&src));
790 : :
791 : 91 : for (d = 0; d < G_N_ELEMENTS (types); d++)
792 : : {
793 : 78 : g_test_message ("Next: %s object in GValue of %s to GValue of %s", g_type_name (types[i]), g_type_name (types[s]), g_type_name (types[d]));
794 : 78 : g_assert_true (g_value_type_transformable (types[s], types[d]));
795 : 78 : g_value_init (&dest, types[d]);
796 : 78 : g_assert_true (g_value_transform (&src, &dest));
797 : 78 : g_assert_cmpint (g_value_get_object (&dest) != NULL, ==, G_TYPE_CHECK_INSTANCE_TYPE (object, types[d]));
798 : 78 : g_value_unset (&dest);
799 : : }
800 : 13 : g_value_unset (&src);
801 : : }
802 : :
803 : 5 : g_object_unref (object);
804 : : }
805 : 1 : }
806 : :
807 : : int
808 : 1 : main (int argc, char *argv[])
809 : : {
810 : 1 : g_test_init (&argc, &argv, NULL);
811 : :
812 : 1 : g_test_add_func ("/value/basic", test_value_basic);
813 : 1 : g_test_add_func ("/value/array/basic", test_valuearray_basic);
814 : 1 : g_test_add_func ("/value/array/sort-with-data", test_value_array_sort_with_data);
815 : 1 : g_test_add_func ("/value/collection", test_collection);
816 : 1 : g_test_add_func ("/value/copying", test_copying);
817 : 1 : g_test_add_func ("/value/enum-transformation", test_enum_transformation);
818 : 1 : g_test_add_func ("/value/gtype", test_gtype_value);
819 : 1 : g_test_add_func ("/value/string", test_value_string);
820 : 1 : g_test_add_func ("/value/transform-object", test_value_transform_object);
821 : :
822 : 1 : return g_test_run ();
823 : : }
|