1 /* GStreamer
2  * Copyright (C) <2004> David Schleef <david at schleef dot org>
3  * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
4  *
5  * gstvalue.c: Unit tests for GstValue
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #define GLIB_DISABLE_DEPRECATION_WARNINGS
27 #include <gst/check/gstcheck.h>
28 
29 
GST_START_TEST(test_deserialize_buffer)30 GST_START_TEST (test_deserialize_buffer)
31 {
32   GValue value = { 0 };
33   GstBuffer *buf;
34   guint8 data[8];
35   guint64 val;
36 
37   g_value_init (&value, GST_TYPE_BUFFER);
38   fail_unless (gst_value_deserialize (&value, "1234567890abcdef"));
39   /* does not increase the refcount */
40   buf = GST_BUFFER (g_value_get_boxed (&value));
41   ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
42 
43   /* does not increase the refcount */
44   buf = gst_value_get_buffer (&value);
45   ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
46 
47   gst_buffer_extract (buf, 0, data, 8);
48   val = GST_READ_UINT64_BE (data);
49   fail_unless_equals_uint64 (val, G_GUINT64_CONSTANT (0x1234567890abcdef));
50 
51   /* cleanup */
52   g_value_unset (&value);
53 }
54 
55 GST_END_TEST;
56 
57 /* create and serialize a buffer */
GST_START_TEST(test_serialize_buffer)58 GST_START_TEST (test_serialize_buffer)
59 {
60   GValue value = { 0 };
61   GstBuffer *buf;
62   gchar *serialized;
63   const guint8 buf_data[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef };
64   gint len;
65 
66   len = sizeof (buf_data);
67   buf = gst_buffer_new_and_alloc (len);
68 
69   gst_buffer_fill (buf, 0, (gchar *) buf_data, len);
70 
71   ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
72 
73   /* and assign buffer to mini object */
74   g_value_init (&value, GST_TYPE_BUFFER);
75   gst_value_take_buffer (&value, buf);
76   ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
77 
78   /* now serialize it */
79   serialized = gst_value_serialize (&value);
80   GST_DEBUG ("serialized buffer to %s", serialized);
81   fail_unless (serialized != NULL);
82   fail_unless_equals_string (serialized, "1234567890abcdef");
83 
84   /* refcount should not change */
85   ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
86 
87   /* cleanup */
88   g_free (serialized);
89   g_value_unset (&value);
90 
91   /* take NULL buffer */
92   g_value_init (&value, GST_TYPE_BUFFER);
93   GST_DEBUG ("setting NULL buffer");
94   gst_value_take_buffer (&value, NULL);
95 
96   /* now serialize it */
97   GST_DEBUG ("serializing NULL buffer");
98   serialized = gst_value_serialize (&value);
99   /* should return NULL */
100   fail_unless (serialized == NULL);
101 
102   g_free (serialized);
103   g_value_unset (&value);
104 }
105 
106 GST_END_TEST;
107 
GST_START_TEST(test_deserialize_gint64)108 GST_START_TEST (test_deserialize_gint64)
109 {
110   GValue value = { 0 };
111   const char *strings[] = {
112     "12345678901",
113     "-12345678901",
114     "1152921504606846976",
115     "-1152921504606846976",
116   };
117   gint64 results[] = {
118     12345678901LL,
119     -12345678901LL,
120     1152921504606846976LL,
121     -1152921504606846976LL,
122   };
123   int i;
124 
125   g_value_init (&value, G_TYPE_INT64);
126 
127   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
128     fail_unless (gst_value_deserialize (&value, strings[i]),
129         "could not deserialize %s (%d)", strings[i], i);
130     fail_unless (g_value_get_int64 (&value) == results[i],
131         "resulting value is %" G_GINT64_FORMAT ", not %" G_GINT64_FORMAT
132         ", for string %s (%d)", g_value_get_int64 (&value),
133         results[i], strings[i], i);
134   }
135 }
136 
137 GST_END_TEST;
138 
GST_START_TEST(test_deserialize_guint64)139 GST_START_TEST (test_deserialize_guint64)
140 {
141   GValue value = { 0 };
142   const char *strings[] = {
143     "0xffffffffffffffff",
144     "9223372036854775810",
145     "-9223372036854775810",
146     "-1",
147     "1",
148     "-0",
149   };
150   guint64 results[] = {
151     0xffffffffffffffffULL,
152     9223372036854775810ULL,
153     9223372036854775806ULL,
154     (guint64) - 1,
155     1,
156     0,
157   };
158   int i;
159 
160   g_value_init (&value, G_TYPE_UINT64);
161 
162   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
163     fail_unless (gst_value_deserialize (&value, strings[i]),
164         "could not deserialize %s (%d)", strings[i], i);
165     fail_unless (g_value_get_uint64 (&value) == results[i],
166         "resulting value is %" G_GUINT64_FORMAT ", not %" G_GUINT64_FORMAT
167         ", for string %s (%d)", g_value_get_uint64 (&value),
168         results[i], strings[i], i);
169   }
170 }
171 
172 GST_END_TEST;
173 
GST_START_TEST(test_deserialize_guchar)174 GST_START_TEST (test_deserialize_guchar)
175 {
176   GValue value = { 0 };
177   const char *strings[] = {
178     "0xff",
179     "255",
180     "-1",
181     "1",
182     "-0",
183   };
184   guchar results[] = {
185     0xff,
186     255,
187     (guchar) - 1,
188     1,
189     0,
190   };
191   int i;
192 
193   g_value_init (&value, G_TYPE_UCHAR);
194 
195   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
196     fail_unless (gst_value_deserialize (&value, strings[i]),
197         "could not deserialize %s (%d)", strings[i], i);
198     fail_unless (g_value_get_uchar (&value) == results[i],
199         "resulting value is %u not %u, for string %s (%d)",
200         g_value_get_uchar (&value), results[i], strings[i], i);
201   }
202 
203   /* test serialisation as well while we're at it */
204   {
205     gchar *str;
206     GValue value = { 0 };
207     g_value_init (&value, G_TYPE_UCHAR);
208 
209     g_value_set_uchar (&value, 255);
210     str = gst_value_serialize (&value);
211 
212     fail_unless_equals_string (str, "255");
213     g_free (str);
214   }
215 }
216 
217 GST_END_TEST;
218 
GST_START_TEST(test_deserialize_gstfraction)219 GST_START_TEST (test_deserialize_gstfraction)
220 {
221   GValue value = { 0 };
222   const char *strings[] = {
223     "4/5",
224     "-8/9"
225   };
226   gint64 result_numers[] = {
227     4,
228     -8
229   };
230   gint64 result_denoms[] = {
231     5,
232     9
233   };
234 
235   int i;
236 
237   g_value_init (&value, GST_TYPE_FRACTION);
238   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
239     fail_unless (gst_value_deserialize (&value, strings[i]),
240         "could not deserialize %s (%d)", strings[i], i);
241     fail_unless (gst_value_get_fraction_numerator (&value) == result_numers[i],
242         "resulting numerator value is %d, not %d"
243         ", for string %s (%d)", gst_value_get_fraction_numerator (&value),
244         result_numers[i], strings[i], i);
245     fail_unless (gst_value_get_fraction_denominator (&value) ==
246         result_denoms[i], "resulting denominator value is %d, not %d"
247         ", for string %s (%d)", gst_value_get_fraction_denominator (&value),
248         result_denoms[i], strings[i], i);
249   }
250 }
251 
252 GST_END_TEST;
253 
GST_START_TEST(test_deserialize_gint)254 GST_START_TEST (test_deserialize_gint)
255 {
256   GValue value = { 0 };
257   const char *strings[] = {
258     "123456",
259     "-123456",
260     "0xFFFF",
261     "0x0000FFFF",
262     /* a positive long long, serializing to highest possible positive sint */
263     "0x7FFFFFFF",
264     /* a positive long long, serializing to lowest possible negative sint */
265     "0x80000000",
266     /* a negative long long, serializing to lowest possible negative sint */
267     "0xFFFFFFFF80000000",
268     "0xFF000000",
269     /* a positive long long serializing to -1 */
270     "0xFFFFFFFF",
271     "0xFFFFFFFF",
272     /* a negative long long serializing to -1 */
273     "0xFFFFFFFFFFFFFFFF",
274     "0xFFFFFFFFFFFFFFFF",
275     "0xEFFFFFFF",
276   };
277   /* some casts need to be explicit because of unsigned -> signed */
278   gint results[] = {
279     123456,
280     -123456,
281     0xFFFF,
282     0xFFFF,
283     0x7FFFFFFF,
284     (gint) 0x80000000,
285     (gint) 0x80000000,
286     (gint) 0xFF000000,
287     -1,
288     (gint) 0xFFFFFFFF,
289     -1,
290     (gint) 0xFFFFFFFFFFFFFFFFLL,
291     (gint) 0xEFFFFFFF,
292   };
293   int i;
294 
295   g_value_init (&value, G_TYPE_INT);
296 
297   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
298     fail_unless (gst_value_deserialize (&value, strings[i]),
299         "could not deserialize %s (%d)", strings[i], i);
300     fail_unless (g_value_get_int (&value) == results[i],
301         "resulting value is %d, not %d, for string %s (%d)",
302         g_value_get_int (&value), results[i], strings[i], i);
303   }
304 }
305 
306 GST_END_TEST;
307 
GST_START_TEST(test_deserialize_gint_failures)308 GST_START_TEST (test_deserialize_gint_failures)
309 {
310   GValue value = { 0 };
311   const char *strings[] = {
312     "-",                        /* not a complete number */
313     "- TEST",                   /* not a complete number */
314     "0x0000000100000000",       /* lowest long long that cannot fit in 32 bits */
315     "0xF000000000000000",
316     "0xFFFFFFF000000000",
317     "0xFFFFFFFF00000000",
318     "0x10000000000000000",      /* first number too long to fit into a long long */
319     /* invent a new processor first before trying to make this one pass */
320     "0x10000000000000000000000000000000000000000000",
321   };
322   int i;
323 
324   g_value_init (&value, G_TYPE_INT);
325 
326   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
327     fail_if (gst_value_deserialize (&value, strings[i]),
328         "deserialized %s (%d), while it should have failed", strings[i], i);
329   }
330 }
331 
332 GST_END_TEST;
333 
GST_START_TEST(test_deserialize_guint)334 GST_START_TEST (test_deserialize_guint)
335 {
336   GValue value = { 0 };
337   const char *strings[] = {
338     "123456",
339     "-123456",
340     "0xFFFF",
341     "0x0000FFFF",
342     /* a positive long long, serializing to highest possible positive sint */
343     "0x7FFFFFFF",
344     /* a positive long long, serializing to lowest possible negative sint */
345     "0x80000000",
346     "2147483648",
347     /* a negative long long, serializing to lowest possible negative sint */
348     "0xFFFFFFFF80000000",
349     /* a value typically used for rgb masks */
350     "0xFF000000",
351     /* a positive long long serializing to highest possible positive uint */
352     "0xFFFFFFFF",
353     "0xFFFFFFFF",
354     /* a negative long long serializing to highest possible positive uint */
355     "0xFFFFFFFFFFFFFFFF",
356     "0xEFFFFFFF",
357   };
358   guint results[] = {
359     123456,
360     (guint) - 123456,
361     0xFFFF,
362     0xFFFF,
363     0x7FFFFFFF,
364     0x80000000,
365     (guint) 2147483648LL,
366     0x80000000,
367     0xFF000000,
368     0xFFFFFFFF,
369     G_MAXUINT,
370     (guint) 0xFFFFFFFFFFFFFFFFLL,
371     0xEFFFFFFF,
372   };
373   int i;
374 
375   g_value_init (&value, G_TYPE_UINT);
376 
377   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
378     fail_unless (gst_value_deserialize (&value, strings[i]),
379         "could not deserialize %s (%d)", strings[i], i);
380     fail_unless (g_value_get_uint (&value) == results[i],
381         "resulting value is %d, not %d, for string %s (%d)",
382         g_value_get_uint (&value), results[i], strings[i], i);
383   }
384 }
385 
386 GST_END_TEST;
387 
GST_START_TEST(test_deserialize_guint_failures)388 GST_START_TEST (test_deserialize_guint_failures)
389 {
390   GValue value = { 0 };
391   const char *strings[] = {
392     "-",                        /* not a complete number */
393     "- TEST",                   /* not a complete number */
394 #if 0
395 /* FIXME: these values should not be deserializable, since they overflow
396  * the target format */
397     "0x0000000100000000",       /* lowest long long that cannot fit in 32 bits */
398     "0xF000000000000000",
399     "0xFFFFFFF000000000",
400     "0xFFFFFFFF00000000",
401     "0x10000000000000000",      /* first number too long to fit into a long long */
402     /* invent a new processor first before trying to make this one pass */
403     "0x10000000000000000000000000000000000000000000",
404 #endif
405   };
406   int i;
407 
408   g_value_init (&value, G_TYPE_UINT);
409 
410   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
411     fail_if (gst_value_deserialize (&value, strings[i]),
412         "deserialized %s (%d), while it should have failed", strings[i], i);
413   }
414 }
415 
416 GST_END_TEST;
417 
GST_START_TEST(test_serialize_flags)418 GST_START_TEST (test_serialize_flags)
419 {
420   GValue value = { 0 };
421   gchar *string;
422   GstSeekFlags flags[] = {
423     0,
424     GST_SEEK_FLAG_NONE,
425     GST_SEEK_FLAG_FLUSH,
426     GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
427   };
428   const char *results[] = {
429     "GST_SEEK_FLAG_NONE",
430     "GST_SEEK_FLAG_NONE",
431     "GST_SEEK_FLAG_FLUSH",
432     "GST_SEEK_FLAG_FLUSH+GST_SEEK_FLAG_ACCURATE",
433   };
434   int i;
435 
436   g_value_init (&value, GST_TYPE_SEEK_FLAGS);
437 
438   for (i = 0; i < G_N_ELEMENTS (flags); ++i) {
439     g_value_set_flags (&value, flags[i]);
440     string = gst_value_serialize (&value);
441     fail_if (string == NULL, "could not serialize flags %d", i);
442     fail_unless (strcmp (string, results[i]) == 0,
443         "resulting value is %s, not %s, for flags #%d", string, results[i], i);
444     g_free (string);
445   }
446 }
447 
448 GST_END_TEST;
449 
450 
GST_START_TEST(test_deserialize_flags)451 GST_START_TEST (test_deserialize_flags)
452 {
453   GValue value = { 0 };
454   const char *strings[] = {
455     "",
456     "0",
457     "GST_SEEK_FLAG_NONE",
458     "GST_SEEK_FLAG_FLUSH",
459     "0xf",
460     "15",
461     "GST_SEEK_FLAG_FLUSH+GST_SEEK_FLAG_ACCURATE",
462   };
463   GstSeekFlags results[] = {
464     GST_SEEK_FLAG_NONE,
465     GST_SEEK_FLAG_NONE,
466     GST_SEEK_FLAG_NONE,
467     GST_SEEK_FLAG_FLUSH,
468     0xf,
469     15,
470     GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
471   };
472   int i;
473 
474   g_value_init (&value, GST_TYPE_SEEK_FLAGS);
475 
476   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
477     fail_unless (gst_value_deserialize (&value, strings[i]),
478         "could not deserialize %s (%d)", strings[i], i);
479     fail_unless (g_value_get_flags (&value) == results[i],
480         "resulting value is %d, not %d, for string %s (%d)",
481         g_value_get_flags (&value), results[i], strings[i], i);
482   }
483 
484   fail_if (gst_value_deserialize (&value, "foo"),
485       "flag deserializing for bogus value should have failed!");
486   fail_if (gst_value_deserialize (&value, "GST_SEEK_FLAG_FLUSH+foo"),
487       "flag deserializing for bogus value should have failed!");
488   fail_if (gst_value_deserialize (&value,
489           "GST_SEEK_FLAG_FLUSH+foo+GST_SEEK_FLAG_ACCURATE"),
490       "flag deserializing for bogus value should have failed!");
491 }
492 
493 GST_END_TEST;
494 
GST_START_TEST(test_deserialize_gtype)495 GST_START_TEST (test_deserialize_gtype)
496 {
497   GValue value = { 0 };
498   const char *strings[] = {
499     "gchararray",
500     "gint",
501   };
502   GType results[] = {
503     G_TYPE_STRING,
504     G_TYPE_INT,
505   };
506   int i;
507 
508   g_value_init (&value, G_TYPE_GTYPE);
509 
510   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
511     fail_unless (gst_value_deserialize (&value, strings[i]),
512         "could not deserialize %s (%d)", strings[i], i);
513     fail_unless (g_value_get_gtype (&value) == results[i],
514         "resulting value is %" G_GSIZE_FORMAT ", not %" G_GSIZE_FORMAT
515         ", for string %s (%d)",
516         g_value_get_gtype (&value), results[i], strings[i], i);
517   }
518 }
519 
520 GST_END_TEST;
521 
GST_START_TEST(test_deserialize_gtype_failures)522 GST_START_TEST (test_deserialize_gtype_failures)
523 {
524   GValue value = { 0 };
525   const char *strings[] = {
526     "-",                        /* not a gtype */
527   };
528   int i;
529 
530   g_value_init (&value, G_TYPE_GTYPE);
531 
532   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
533     fail_if (gst_value_deserialize (&value, strings[i]),
534         "deserialized %s (%d), while it should have failed", strings[i], i);
535   }
536 }
537 
538 GST_END_TEST;
539 
GST_START_TEST(test_deserialize_bitmask)540 GST_START_TEST (test_deserialize_bitmask)
541 {
542   GValue value = { 0 };
543   const char *strings[] = {
544     "0xffffffffffffffff",
545     "0x1234567890ABCDEF",
546   };
547   guint64 results[] = {
548     0xffffffffffffffffULL,
549     0x1234567890ABCDEFULL,
550   };
551   int i;
552 
553   g_value_init (&value, GST_TYPE_BITMASK);
554 
555   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
556     fail_unless (gst_value_deserialize (&value, strings[i]),
557         "could not deserialize %s (%d)", strings[i], i);
558     fail_unless (gst_value_get_bitmask (&value) == results[i],
559         "resulting value is 0x%016" G_GINT64_MODIFIER "x, not 0x%016"
560         G_GINT64_MODIFIER "x, for string %s (%d)",
561         gst_value_get_bitmask (&value), results[i], strings[i], i);
562   }
563 }
564 
565 GST_END_TEST;
566 
567 static void
check_flagset_mask_serialisation(GValue * value,guint test_flags,guint test_mask)568 check_flagset_mask_serialisation (GValue * value, guint test_flags,
569     guint test_mask)
570 {
571   gchar *string;
572   gst_value_set_flagset (value, test_flags, test_mask);
573 
574   /* Normalise our test flags against the mask now for easier testing,
575    * as that's what we expect to get back from the flagset after it
576    * normalises internally */
577   test_flags &= test_mask;
578 
579   /* Check the values got stored correctly */
580   fail_unless (gst_value_get_flagset_flags (value) == test_flags,
581       "resulting flags value is 0x%u, not 0x%x",
582       gst_value_get_flagset_flags (value), test_flags);
583   fail_unless (gst_value_get_flagset_mask (value) == test_mask,
584       "resulting mask is 0x%u, not 0x%x",
585       gst_value_get_flagset_mask (value), test_mask);
586 
587   string = gst_value_serialize (value);
588   fail_if (string == NULL, "could not serialize flagset");
589 
590   GST_DEBUG ("Serialized flagset to: %s", string);
591 
592   fail_unless (gst_value_deserialize (value, string),
593       "could not deserialize %s", string);
594 
595   fail_unless (gst_value_get_flagset_flags (value) == test_flags,
596       "resulting flags value is 0x%u, not 0x%x, for string %s",
597       gst_value_get_flagset_flags (value), test_flags, string);
598 
599   fail_unless (gst_value_get_flagset_mask (value) == test_mask,
600       "resulting mask is 0x%u, not 0x%x, for string %s",
601       gst_value_get_flagset_mask (value), test_mask, string);
602 
603   g_free (string);
604 }
605 
GST_START_TEST(test_flagset)606 GST_START_TEST (test_flagset)
607 {
608   GValue value = G_VALUE_INIT;
609   GValue value2 = G_VALUE_INIT;
610   GValue dest = G_VALUE_INIT;
611   gchar *string;
612   GType test_flagset_type;
613   guint test_flags, test_mask;
614 
615   /* Test serialisation of abstract type */
616   g_value_init (&value, GST_TYPE_FLAG_SET);
617 
618   test_flags = 0xf1f1;
619   test_mask = 0xffff;
620 
621   gst_value_set_flagset (&value, test_flags, test_mask);
622   string = gst_value_serialize (&value);
623   fail_if (string == NULL, "could not serialize flagset");
624 
625   fail_unless (gst_value_deserialize (&value, string),
626       "could not deserialize %s", string);
627 
628   fail_unless (gst_value_get_flagset_flags (&value) == test_flags,
629       "resulting value is 0x%u, not 0x%x, for string %s",
630       gst_value_get_flagset_flags (&value), test_flags, string);
631 
632   fail_unless (gst_value_get_flagset_mask (&value) == test_mask,
633       "resulting value is 0x%u, not 0x%x, for string %s",
634       gst_value_get_flagset_mask (&value), test_mask, string);
635 
636   g_free (string);
637   g_value_unset (&value);
638 
639   /* Check we can't wrap a random non-flags type */
640   ASSERT_CRITICAL (gst_flagset_register (GST_TYPE_OBJECT));
641 
642   test_flagset_type = gst_flagset_register (GST_TYPE_SEEK_FLAGS);
643 
644   fail_unless (g_type_is_a (test_flagset_type, GST_TYPE_FLAG_SET));
645 
646   g_value_init (&value, test_flagset_type);
647 
648   test_flags =
649       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_TRICKMODE |
650       GST_SEEK_FLAG_TRICKMODE_KEY_UNITS;
651   test_mask =
652       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_TRICKMODE |
653       GST_SEEK_FLAG_TRICKMODE_NO_AUDIO;
654 
655   check_flagset_mask_serialisation (&value, test_flags, test_mask);
656   /* Check serialisation works with the generic 'exact' flag */
657   check_flagset_mask_serialisation (&value, test_flags,
658       GST_FLAG_SET_MASK_EXACT);
659 
660   /* Check deserialisation of flagset in 'flags' form, without
661    * the hex strings at the start */
662   test_flags = GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_TRICKMODE;
663   test_mask = GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_TRICKMODE |
664       GST_SEEK_FLAG_TRICKMODE_NO_AUDIO;
665   string = g_strdup ("+flush+trickmode/trickmode-no-audio");
666 
667   fail_unless (gst_value_deserialize (&value, string),
668       "could not deserialize %s", string);
669 
670   GST_DEBUG ("Deserialized %s to 0x%x:0x%x", string,
671       gst_value_get_flagset_flags (&value),
672       gst_value_get_flagset_mask (&value));
673 
674   fail_unless (gst_value_get_flagset_flags (&value) == test_flags,
675       "resulting flags value is 0x%u, not 0x%x, for string %s",
676       gst_value_get_flagset_flags (&value), (test_flags & test_mask), string);
677 
678   fail_unless (gst_value_get_flagset_mask (&value) == test_mask,
679       "resulting mask is 0x%u, not 0x%x, for string %s",
680       gst_value_get_flagset_mask (&value), test_mask, string);
681 
682   g_free (string);
683   g_value_unset (&value);
684 
685   /* Test that fixating don't-care fields works, using our
686    * sub-type flagset for good measure  */
687   g_value_init (&value, test_flagset_type);
688   gst_value_set_flagset (&value, test_flags, test_mask);
689 
690   fail_unless (gst_value_fixate (&dest, &value));
691   fail_unless (gst_value_get_flagset_flags (&dest) == test_flags);
692   fail_unless (gst_value_get_flagset_mask (&dest) == GST_FLAG_SET_MASK_EXACT);
693 
694   g_value_unset (&value);
695 
696   /* Intersection tests */
697   g_value_init (&value, GST_TYPE_FLAG_SET);
698   g_value_init (&value2, test_flagset_type);
699 
700   /* We want Accurate, but not Snap-Before */
701   gst_value_set_flagset (&value, GST_SEEK_FLAG_ACCURATE,
702       GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_SNAP_BEFORE);
703 
704   /* This only cares that things are flushing */
705   gst_value_set_flagset (&value2, GST_SEEK_FLAG_FLUSH, GST_SEEK_FLAG_FLUSH);
706 
707   test_flags = GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH;
708   test_mask =
709       GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SNAP_BEFORE;
710 
711   /* GstFlagSet should always intersect with itself */
712   g_value_unset (&dest);
713   fail_unless (gst_value_can_intersect (&value, &value));
714   fail_unless (gst_value_intersect (&dest, &value, &value));
715 
716   /* GstFlagSet subtype should intersect with itself */
717   g_value_unset (&dest);
718   fail_unless (gst_value_can_intersect (&value2, &value2));
719   fail_unless (gst_value_intersect (&dest, &value2, &value2));
720 
721   /* Check we can intersect custom flagset subtype with flagset */
722   g_value_unset (&dest);
723   fail_unless (gst_value_can_intersect (&value2, &value));
724   fail_unless (gst_value_intersect (&dest, &value2, &value));
725 
726   /* and in the other order */
727   g_value_unset (&dest);
728   fail_unless (gst_value_can_intersect (&value, &value2));
729   fail_unless (gst_value_intersect (&dest, &value, &value2));
730 
731   fail_unless (gst_value_get_flagset_flags (&dest) == test_flags,
732       "resulting flags value is 0x%u, not 0x%x",
733       gst_value_get_flagset_flags (&dest), test_flags);
734 
735   fail_unless (gst_value_get_flagset_mask (&dest) == test_mask,
736       "resulting mask is 0x%u, not 0x%x",
737       gst_value_get_flagset_mask (&dest), test_mask);
738 
739   gst_value_set_flagset (&value,
740       GST_SEEK_FLAG_ACCURATE, GST_SEEK_FLAG_ACCURATE);
741   gst_value_set_flagset (&value2, GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH,
742       GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_SNAP_BEFORE | GST_SEEK_FLAG_FLUSH);
743   /* Check that accurate alone is a subset of accurate+!snap_before+flush,
744    * but not vice-versa */
745   fail_unless (gst_value_is_subset (&value, &value2));
746   fail_if (gst_value_is_subset (&value2, &value));
747 
748   g_value_unset (&dest);
749   g_value_unset (&value);
750   g_value_unset (&value2);
751 }
752 
753 GST_END_TEST;
754 
755 
GST_START_TEST(test_string)756 GST_START_TEST (test_string)
757 {
758   const gchar *try[] = {
759     "Dude",
760     "Hi, I'm a string",
761     "tüüüt!",
762     "\"\""                      /* Empty string */
763   };
764   gchar *tmp;
765   GValue v = { 0, };
766   guint i;
767 
768   g_value_init (&v, G_TYPE_STRING);
769   for (i = 0; i < G_N_ELEMENTS (try); i++) {
770     g_value_set_string (&v, try[i]);
771     tmp = gst_value_serialize (&v);
772     fail_if (tmp == NULL, "couldn't serialize: %s\n", try[i]);
773     fail_unless (gst_value_deserialize (&v, tmp),
774         "couldn't deserialize: %s\n", tmp);
775     g_free (tmp);
776 
777     fail_unless (g_str_equal (g_value_get_string (&v), try[i]),
778         "\nserialized  : %s\ndeserialized: %s", try[i],
779         g_value_get_string (&v));
780   }
781   /* NULL strings should not be serializable */
782   g_value_set_string (&v, NULL);
783   fail_unless (gst_value_serialize (&v) == NULL);
784   g_value_unset (&v);
785 }
786 
787 GST_END_TEST;
788 
GST_START_TEST(test_deserialize_string)789 GST_START_TEST (test_deserialize_string)
790 {
791   struct
792   {
793     const gchar *from;
794     const gchar *to;
795   } tests[] = {
796     {
797     "\"foo\"", "foo"}, {
798     "\"foo\\%\"", "foo%"}, {
799     "\"0123456789_-+/:.\"", "0123456789_-+/:."}, {
800     "\"Hello\\ World\"", "Hello World"}, {
801     "\"Hello\\ World", "\"Hello\\ World"}, {
802     "\"\\", "\"\\"}, {
803     "\"\\0", "\"\\0"}, {
804     "", ""},                    /* empty strings */
805     {
806     "\"\"", ""},                /* quoted empty string -> empty string */
807         /* Expected FAILURES: */
808     {
809     "\"\\0\"", NULL},           /* unfinished escaped character */
810     {
811     "\"", NULL},                /* solitary quote */
812     {
813     "\" \"", NULL},             /* spaces must be escaped */
814 #if 0
815         /* FIXME 0.9: this test should fail, but it doesn't */
816     {
817     "tüüt", NULL}             /* string with special chars must be escaped */
818 #endif
819   };
820   guint i;
821   GValue v = { 0, };
822 
823   g_value_init (&v, G_TYPE_STRING);
824   for (i = 0; i < G_N_ELEMENTS (tests); i++) {
825     if (gst_value_deserialize (&v, tests[i].from)) {
826       fail_if (tests[i].to == NULL,
827           "I got %s instead of a failure", g_value_get_string (&v));
828       fail_unless (g_str_equal (g_value_get_string (&v), tests[i].to),
829           "\nwanted: %s\ngot    : %s", tests[i].to, g_value_get_string (&v));
830     } else {
831       fail_if (tests[i].to != NULL, "failed, but wanted: %s", tests[i].to);
832     }
833   }
834   g_value_unset (&v);
835 }
836 
837 GST_END_TEST;
838 
GST_START_TEST(test_value_compare)839 GST_START_TEST (test_value_compare)
840 {
841   GValue value1 = { 0 };
842   GValue value2 = { 0 };
843   GValue tmp = { 0 };
844   GstAllocationParams alloc_params = { 0 };
845 
846   g_value_init (&value1, G_TYPE_INT);
847   g_value_set_int (&value1, 10);
848   g_value_init (&value2, G_TYPE_INT);
849   g_value_set_int (&value2, 20);
850   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
851   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
852   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
853   g_value_unset (&value1);
854   g_value_unset (&value2);
855 
856   g_value_init (&value1, G_TYPE_DOUBLE);
857   g_value_set_double (&value1, 10);
858   g_value_init (&value2, G_TYPE_DOUBLE);
859   g_value_set_double (&value2, 20);
860   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
861   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
862   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
863   g_value_unset (&value1);
864   g_value_unset (&value2);
865 
866   g_value_init (&value1, G_TYPE_STRING);
867   g_value_set_string (&value1, "a");
868   g_value_init (&value2, G_TYPE_STRING);
869   g_value_set_string (&value2, "b");
870   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
871   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
872   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
873   /* Test some NULL string comparisons */
874   g_value_set_string (&value2, NULL);
875   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_UNORDERED);
876   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_UNORDERED);
877   fail_unless (gst_value_compare (&value2, &value2) == GST_VALUE_EQUAL);
878 
879   g_value_unset (&value1);
880   g_value_unset (&value2);
881 
882   /* comparing 2/3 with 3/4 */
883   g_value_init (&value1, GST_TYPE_FRACTION);
884   gst_value_set_fraction (&value1, 2, 3);
885   g_value_init (&value2, GST_TYPE_FRACTION);
886   gst_value_set_fraction (&value2, 3, 4);
887   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
888   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
889   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
890   g_value_unset (&value1);
891   g_value_unset (&value2);
892 
893   /* comparing -4/5 with 2/-3 */
894   g_value_init (&value1, GST_TYPE_FRACTION);
895   gst_value_set_fraction (&value1, -4, 5);
896   g_value_init (&value2, GST_TYPE_FRACTION);
897   gst_value_set_fraction (&value2, 2, -3);
898   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
899   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
900   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
901   g_value_unset (&value1);
902   g_value_unset (&value2);
903 
904   /* comparing 10/100 with 200/2000 */
905   g_value_init (&value1, GST_TYPE_FRACTION);
906   gst_value_set_fraction (&value1, 10, 100);
907   g_value_init (&value2, GST_TYPE_FRACTION);
908   gst_value_set_fraction (&value2, 200, 2000);
909   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL);
910   g_value_unset (&value1);
911   g_value_unset (&value2);
912 
913   /* comparing -4/5 with 2/-3 */
914   g_value_init (&value1, GST_TYPE_FRACTION);
915   gst_value_set_fraction (&value1, -4, 5);
916   g_value_init (&value2, GST_TYPE_FRACTION);
917   gst_value_set_fraction (&value2, 2, -3);
918   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
919   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
920   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
921   g_value_unset (&value1);
922   g_value_unset (&value2);
923 
924   /* Check that lists are equal regardless of order */
925   g_value_init (&value1, GST_TYPE_LIST);
926   g_value_init (&tmp, G_TYPE_INT);
927   g_value_set_int (&tmp, 1);
928   gst_value_list_append_value (&value1, &tmp);
929   g_value_set_int (&tmp, 2);
930   gst_value_list_append_value (&value1, &tmp);
931   g_value_set_int (&tmp, 3);
932   gst_value_list_append_value (&value1, &tmp);
933   g_value_set_int (&tmp, 4);
934   gst_value_list_append_value (&value1, &tmp);
935 
936   g_value_init (&value2, GST_TYPE_LIST);
937   g_value_set_int (&tmp, 4);
938   gst_value_list_append_value (&value2, &tmp);
939   g_value_set_int (&tmp, 3);
940   gst_value_list_append_value (&value2, &tmp);
941   g_value_set_int (&tmp, 2);
942   gst_value_list_append_value (&value2, &tmp);
943   g_value_set_int (&tmp, 1);
944   gst_value_list_append_value (&value2, &tmp);
945 
946   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
947       "value lists with different order were not equal when they should be");
948   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL,
949       "value lists with same order were not equal when they should be");
950   fail_unless (gst_value_compare (&value2, &value2) == GST_VALUE_EQUAL,
951       "value lists with same order were not equal when they should be");
952 
953   /* Carry over the lists to this next check: */
954   /* Lists with different sizes are unequal */
955   g_value_set_int (&tmp, 1);
956   gst_value_list_append_value (&value2, &tmp);
957 
958   fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
959       "Value lists with different size were equal when they shouldn't be");
960 
961   /* Carry over the lists to this next check: */
962   /* Lists with same size but list1 contains one more element not in list2 */
963   g_value_set_int (&tmp, 5);
964   gst_value_list_append_value (&value1, &tmp);
965 
966   fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
967       "Value lists with different elements were equal when they shouldn't be");
968   fail_if (gst_value_compare (&value2, &value1) == GST_VALUE_EQUAL,
969       "Value lists with different elements were equal when they shouldn't be");
970 
971   g_value_unset (&value1);
972   g_value_unset (&value2);
973   g_value_unset (&tmp);
974 
975   /* Arrays are only equal when in the same order */
976   g_value_init (&value1, GST_TYPE_ARRAY);
977   g_value_init (&tmp, G_TYPE_INT);
978   g_value_set_int (&tmp, 1);
979   gst_value_array_append_value (&value1, &tmp);
980   g_value_set_int (&tmp, 2);
981   gst_value_array_append_value (&value1, &tmp);
982   g_value_set_int (&tmp, 3);
983   gst_value_array_append_value (&value1, &tmp);
984   g_value_set_int (&tmp, 4);
985   gst_value_array_append_value (&value1, &tmp);
986 
987   g_value_init (&value2, GST_TYPE_ARRAY);
988   g_value_set_int (&tmp, 4);
989   gst_value_array_append_value (&value2, &tmp);
990   g_value_set_int (&tmp, 3);
991   gst_value_array_append_value (&value2, &tmp);
992   g_value_set_int (&tmp, 2);
993   gst_value_array_append_value (&value2, &tmp);
994   g_value_set_int (&tmp, 1);
995   gst_value_array_append_value (&value2, &tmp);
996 
997   fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
998       "Value arrays with different order were equal when they shouldn't be");
999   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL,
1000       "Identical value arrays were not equal when they should be");
1001   fail_unless (gst_value_compare (&value2, &value2) == GST_VALUE_EQUAL,
1002       "Identical value arrays were not equal when they should be");
1003 
1004   /* Carry over the arrays to this next check: */
1005   /* Arrays with different sizes are unequal */
1006   g_value_unset (&value2);
1007   g_value_init (&value2, GST_TYPE_ARRAY);
1008   g_value_copy (&value1, &value2);
1009 
1010   g_value_set_int (&tmp, 1);
1011   gst_value_array_append_value (&value2, &tmp);
1012 
1013   fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
1014       "Value arrays with different size were equal when they shouldn't be");
1015   /* order should not matter */
1016   fail_if (gst_value_compare (&value2, &value1) == GST_VALUE_EQUAL,
1017       "Value arrays with different size were equal when they shouldn't be");
1018 
1019   g_value_unset (&value1);
1020   g_value_unset (&value2);
1021   g_value_unset (&tmp);
1022 
1023   g_value_init (&value1, GST_TYPE_BITMASK);
1024   gst_value_set_bitmask (&value1, 0x123);
1025   g_value_init (&value2, GST_TYPE_BITMASK);
1026   gst_value_set_bitmask (&value2, 0x321);
1027   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_UNORDERED);
1028   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_UNORDERED);
1029   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
1030   g_value_unset (&value1);
1031   g_value_unset (&value2);
1032 
1033   /* Check that we can compare objects */
1034   g_value_init (&value1, GST_TYPE_BIN);
1035   g_value_take_object (&value1, gst_bin_new (NULL));
1036   g_value_init (&value2, GST_TYPE_BIN);
1037   g_value_take_object (&value2, gst_bin_new (NULL));
1038   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_UNORDERED);
1039   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
1040   g_value_unset (&value1);
1041   g_value_unset (&value2);
1042 
1043   /* Check that we can compare allocation params */
1044   g_value_init (&value1, GST_TYPE_ALLOCATION_PARAMS);
1045   g_value_set_boxed (&value1, &alloc_params);
1046   g_value_init (&value2, GST_TYPE_ALLOCATION_PARAMS);
1047   alloc_params.align = 1;
1048   g_value_set_boxed (&value2, &alloc_params);
1049   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_UNORDERED);
1050   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
1051   g_value_unset (&value1);
1052   g_value_unset (&value2);
1053 
1054   /* Check that we can compare structure */
1055   {
1056     GstStructure *s = gst_structure_new_empty ("test");
1057 
1058     g_value_init (&value1, GST_TYPE_STRUCTURE);
1059     g_value_init (&value2, GST_TYPE_STRUCTURE);
1060     fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL);
1061 
1062     gst_value_set_structure (&value1, s);
1063     fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_UNORDERED);
1064     gst_value_set_structure (&value2, s);
1065     fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL);
1066     g_value_unset (&value1);
1067     g_value_unset (&value2);
1068     gst_structure_free (s);
1069   }
1070 }
1071 
1072 GST_END_TEST;
1073 
GST_START_TEST(test_value_intersect)1074 GST_START_TEST (test_value_intersect)
1075 {
1076   GValue dest = { 0 };
1077   GValue src1 = { 0 };
1078   GValue src2 = { 0 };
1079   GValue item = { 0 };
1080   gboolean ret;
1081 
1082   g_value_init (&src1, G_TYPE_INT);
1083   g_value_set_int (&src1, 10);
1084   g_value_init (&src2, G_TYPE_INT);
1085   g_value_set_int (&src2, 20);
1086   ret = gst_value_intersect (&dest, &src1, &src2);
1087   fail_unless (ret == FALSE);
1088   g_value_unset (&src1);
1089   g_value_unset (&src2);
1090 
1091   g_value_init (&src1, G_TYPE_STRING);
1092   g_value_set_static_string (&src1, "YUY2");
1093   g_value_init (&src2, GST_TYPE_LIST);
1094   g_value_init (&item, G_TYPE_STRING);
1095   g_value_set_static_string (&item, "YUY2");
1096   gst_value_list_append_value (&src2, &item);
1097   g_value_set_static_string (&item, "I420");
1098   gst_value_list_append_value (&src2, &item);
1099   g_value_set_static_string (&item, "ABCD");
1100   gst_value_list_append_value (&src2, &item);
1101 
1102   fail_unless (gst_value_intersect (&dest, &src1, &src2));
1103   fail_unless (G_VALUE_HOLDS_STRING (&dest));
1104   fail_unless (g_str_equal (g_value_get_string (&dest), "YUY2"));
1105 
1106   g_value_unset (&src1);
1107   g_value_unset (&src2);
1108   g_value_unset (&dest);
1109 }
1110 
1111 GST_END_TEST;
1112 
1113 
GST_START_TEST(test_value_subtract_int)1114 GST_START_TEST (test_value_subtract_int)
1115 {
1116   GValue dest = { 0 };
1117   GValue src1 = { 0 };
1118   GValue src2 = { 0 };
1119   const GValue *tmp;
1120   gboolean ret;
1121 
1122   /*  int <-> int
1123    */
1124   g_value_init (&src1, G_TYPE_INT);
1125   g_value_set_int (&src1, 10);
1126   g_value_init (&src2, G_TYPE_INT);
1127   g_value_set_int (&src2, 20);
1128   /* subtract as in sets, result is 10 */
1129   ret = gst_value_subtract (&dest, &src1, &src2);
1130   fail_unless (ret == TRUE);
1131   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1132   g_value_unset (&dest);
1133 
1134   /* same values, yields empty set */
1135   ret = gst_value_subtract (&dest, &src1, &src1);
1136   fail_unless (ret == FALSE);
1137   g_value_unset (&src1);
1138   g_value_unset (&src2);
1139 
1140   /*  int <-> int_range
1141    */
1142 
1143   /* would yield an empty set */
1144   g_value_init (&src1, G_TYPE_INT);
1145   g_value_set_int (&src1, 10);
1146   g_value_init (&src2, GST_TYPE_INT_RANGE);
1147   gst_value_set_int_range (&src2, 0, 20);
1148   ret = gst_value_subtract (&dest, &src1, &src2);
1149   fail_unless (ret == FALSE);
1150 
1151   /* and the other way around, should create a list of two ranges. */
1152   ret = gst_value_subtract (&dest, &src2, &src1);
1153   fail_unless (ret == TRUE);
1154   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1155   tmp = gst_value_list_get_value (&dest, 0);
1156   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
1157   fail_unless (gst_value_get_int_range_min (tmp) == 0);
1158   fail_unless (gst_value_get_int_range_max (tmp) == 9);
1159   tmp = gst_value_list_get_value (&dest, 1);
1160   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
1161   fail_unless (gst_value_get_int_range_min (tmp) == 11);
1162   fail_unless (gst_value_get_int_range_max (tmp) == 20);
1163   g_value_unset (&dest);
1164   g_value_unset (&src1);
1165   g_value_unset (&src2);
1166 
1167   /* border case 1, empty set */
1168   g_value_init (&src1, G_TYPE_INT);
1169   g_value_set_int (&src1, 10);
1170   g_value_init (&src2, GST_TYPE_INT_RANGE);
1171   gst_value_set_int_range (&src2, 10, 20);
1172   ret = gst_value_subtract (&dest, &src1, &src2);
1173   fail_unless (ret == FALSE);
1174 
1175   /* and the other way around, should create a new range. */
1176   ret = gst_value_subtract (&dest, &src2, &src1);
1177   fail_unless (ret == TRUE);
1178   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1179   fail_unless (gst_value_get_int_range_min (&dest) == 11);
1180   fail_unless (gst_value_get_int_range_max (&dest) == 20);
1181   g_value_unset (&dest);
1182   g_value_unset (&src1);
1183   g_value_unset (&src2);
1184 
1185   /* border case 2, empty set */
1186   g_value_init (&src1, G_TYPE_INT);
1187   g_value_set_int (&src1, 20);
1188   g_value_init (&src2, GST_TYPE_INT_RANGE);
1189   gst_value_set_int_range (&src2, 10, 20);
1190   ret = gst_value_subtract (&dest, &src1, &src2);
1191   fail_unless (ret == FALSE);
1192 
1193   /* and the other way around, should create a new range. */
1194   ret = gst_value_subtract (&dest, &src2, &src1);
1195   fail_unless (ret == TRUE);
1196   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1197   fail_unless (gst_value_get_int_range_min (&dest) == 10);
1198   fail_unless (gst_value_get_int_range_max (&dest) == 19);
1199   g_value_unset (&dest);
1200   g_value_unset (&src1);
1201   g_value_unset (&src2);
1202 
1203   /* case 3, valid set */
1204   g_value_init (&src1, G_TYPE_INT);
1205   g_value_set_int (&src1, 0);
1206   g_value_init (&src2, GST_TYPE_INT_RANGE);
1207   gst_value_set_int_range (&src2, 10, 20);
1208   ret = gst_value_subtract (&dest, &src1, &src2);
1209   fail_unless (ret == TRUE);
1210   fail_unless (G_VALUE_HOLDS_INT (&dest) == TRUE);
1211   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1212   g_value_unset (&dest);
1213 
1214   /* and the other way around, should keep the range. */
1215   ret = gst_value_subtract (&dest, &src2, &src1);
1216   fail_unless (ret == TRUE);
1217   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1218   fail_unless (gst_value_get_int_range_min (&dest) == 10);
1219   fail_unless (gst_value_get_int_range_max (&dest) == 20);
1220   g_value_unset (&dest);
1221   g_value_unset (&src1);
1222   g_value_unset (&src2);
1223 
1224   /*  int_range <-> int_range
1225    */
1226 
1227   /* same range, empty set */
1228   g_value_init (&src1, GST_TYPE_INT_RANGE);
1229   gst_value_set_int_range (&src1, 10, 20);
1230   g_value_init (&src2, GST_TYPE_INT_RANGE);
1231   gst_value_set_int_range (&src2, 10, 20);
1232   ret = gst_value_subtract (&dest, &src1, &src2);
1233   fail_unless (ret == FALSE);
1234   ret = gst_value_subtract (&dest, &src2, &src1);
1235   fail_unless (ret == FALSE);
1236   g_value_unset (&src1);
1237   g_value_unset (&src2);
1238 
1239   /* non overlapping ranges */
1240   g_value_init (&src1, GST_TYPE_INT_RANGE);
1241   gst_value_set_int_range (&src1, 10, 20);
1242   g_value_init (&src2, GST_TYPE_INT_RANGE);
1243   gst_value_set_int_range (&src2, 30, 40);
1244   ret = gst_value_subtract (&dest, &src1, &src2);
1245   fail_unless (ret == TRUE);
1246   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1247   fail_unless (gst_value_get_int_range_min (&dest) == 10);
1248   fail_unless (gst_value_get_int_range_max (&dest) == 20);
1249   g_value_unset (&dest);
1250   /* the other way */
1251   ret = gst_value_subtract (&dest, &src2, &src1);
1252   fail_unless (ret == TRUE);
1253   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1254   fail_unless (gst_value_get_int_range_min (&dest) == 30);
1255   fail_unless (gst_value_get_int_range_max (&dest) == 40);
1256   g_value_unset (&dest);
1257   g_value_unset (&src1);
1258   g_value_unset (&src2);
1259 
1260   /* completely overlapping ranges */
1261   g_value_init (&src1, GST_TYPE_INT_RANGE);
1262   gst_value_set_int_range (&src1, 10, 20);
1263   g_value_init (&src2, GST_TYPE_INT_RANGE);
1264   gst_value_set_int_range (&src2, 10, 30);
1265   ret = gst_value_subtract (&dest, &src1, &src2);
1266   fail_unless (ret == FALSE);
1267   /* the other way */
1268   ret = gst_value_subtract (&dest, &src2, &src1);
1269   fail_unless (ret == TRUE);
1270   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1271   fail_unless (gst_value_get_int_range_min (&dest) == 21);
1272   fail_unless (gst_value_get_int_range_max (&dest) == 30);
1273   g_value_unset (&dest);
1274   g_value_unset (&src1);
1275   g_value_unset (&src2);
1276 
1277   /* partially overlapping ranges */
1278   g_value_init (&src1, GST_TYPE_INT_RANGE);
1279   gst_value_set_int_range (&src1, 10, 20);
1280   g_value_init (&src2, GST_TYPE_INT_RANGE);
1281   gst_value_set_int_range (&src2, 15, 30);
1282   ret = gst_value_subtract (&dest, &src1, &src2);
1283   fail_unless (ret == TRUE);
1284   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1285   fail_unless (gst_value_get_int_range_min (&dest) == 10);
1286   fail_unless (gst_value_get_int_range_max (&dest) == 14);
1287   g_value_unset (&dest);
1288   /* the other way */
1289   ret = gst_value_subtract (&dest, &src2, &src1);
1290   fail_unless (ret == TRUE);
1291   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1292   fail_unless (gst_value_get_int_range_min (&dest) == 21);
1293   fail_unless (gst_value_get_int_range_max (&dest) == 30);
1294   g_value_unset (&dest);
1295   g_value_unset (&src1);
1296   g_value_unset (&src2);
1297 
1298   /* create a hole { int_range, int_range } */
1299   g_value_init (&src1, GST_TYPE_INT_RANGE);
1300   gst_value_set_int_range (&src1, 10, 30);
1301   g_value_init (&src2, GST_TYPE_INT_RANGE);
1302   gst_value_set_int_range (&src2, 15, 20);
1303   ret = gst_value_subtract (&dest, &src1, &src2);
1304   fail_unless (ret == TRUE);
1305   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1306   tmp = gst_value_list_get_value (&dest, 0);
1307   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
1308   fail_unless (gst_value_get_int_range_min (tmp) == 10);
1309   fail_unless (gst_value_get_int_range_max (tmp) == 14);
1310   tmp = gst_value_list_get_value (&dest, 1);
1311   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
1312   fail_unless (gst_value_get_int_range_min (tmp) == 21);
1313   fail_unless (gst_value_get_int_range_max (tmp) == 30);
1314   g_value_unset (&dest);
1315   /* the other way */
1316   ret = gst_value_subtract (&dest, &src2, &src1);
1317   fail_unless (ret == FALSE);
1318   g_value_unset (&src1);
1319   g_value_unset (&src2);
1320 
1321   /* create a hole, { int, int } */
1322   g_value_init (&src1, GST_TYPE_INT_RANGE);
1323   gst_value_set_int_range (&src1, 10, 30);
1324   g_value_init (&src2, GST_TYPE_INT_RANGE);
1325   gst_value_set_int_range (&src2, 11, 29);
1326   ret = gst_value_subtract (&dest, &src1, &src2);
1327   fail_unless (ret == TRUE);
1328   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1329   tmp = gst_value_list_get_value (&dest, 0);
1330   fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
1331   fail_unless (g_value_get_int (tmp) == 10);
1332   tmp = gst_value_list_get_value (&dest, 1);
1333   fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
1334   fail_unless (g_value_get_int (tmp) == 30);
1335   g_value_unset (&dest);
1336   /* the other way */
1337   ret = gst_value_subtract (&dest, &src2, &src1);
1338   fail_unless (ret == FALSE);
1339   g_value_unset (&src1);
1340   g_value_unset (&src2);
1341 
1342   /* create a hole, { int, int_range } */
1343   g_value_init (&src1, GST_TYPE_INT_RANGE);
1344   gst_value_set_int_range (&src1, 10, 30);
1345   g_value_init (&src2, GST_TYPE_INT_RANGE);
1346   gst_value_set_int_range (&src2, 11, 28);
1347   ret = gst_value_subtract (&dest, &src1, &src2);
1348   fail_unless (ret == TRUE);
1349   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1350   tmp = gst_value_list_get_value (&dest, 0);
1351   fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
1352   fail_unless (g_value_get_int (tmp) == 10);
1353   tmp = gst_value_list_get_value (&dest, 1);
1354   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
1355   fail_unless (gst_value_get_int_range_min (tmp) == 29);
1356   fail_unless (gst_value_get_int_range_max (tmp) == 30);
1357   g_value_unset (&dest);
1358   /* the other way */
1359   ret = gst_value_subtract (&dest, &src2, &src1);
1360   fail_unless (ret == FALSE);
1361   g_value_unset (&src1);
1362   g_value_unset (&src2);
1363 
1364   /* create a hole, { int_range, int } */
1365   g_value_init (&src1, GST_TYPE_INT_RANGE);
1366   gst_value_set_int_range (&src1, 10, 30);
1367   g_value_init (&src2, GST_TYPE_INT_RANGE);
1368   gst_value_set_int_range (&src2, 12, 29);
1369   ret = gst_value_subtract (&dest, &src1, &src2);
1370   fail_unless (ret == TRUE);
1371   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1372   tmp = gst_value_list_get_value (&dest, 0);
1373   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
1374   fail_unless (gst_value_get_int_range_min (tmp) == 10);
1375   fail_unless (gst_value_get_int_range_max (tmp) == 11);
1376   tmp = gst_value_list_get_value (&dest, 1);
1377   fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
1378   fail_unless (g_value_get_int (tmp) == 30);
1379   g_value_unset (&dest);
1380   /* the other way */
1381   ret = gst_value_subtract (&dest, &src2, &src1);
1382   fail_unless (ret == FALSE);
1383   g_value_unset (&src1);
1384   g_value_unset (&src2);
1385 }
1386 
1387 GST_END_TEST;
1388 
GST_START_TEST(test_value_subtract_int64)1389 GST_START_TEST (test_value_subtract_int64)
1390 {
1391   GValue dest = { 0 };
1392   GValue src1 = { 0 };
1393   GValue src2 = { 0 };
1394   const GValue *tmp;
1395   gboolean ret;
1396 
1397   /*  int64 <-> int64
1398    */
1399   g_value_init (&src1, G_TYPE_INT64);
1400   g_value_set_int64 (&src1, 10);
1401   g_value_init (&src2, G_TYPE_INT64);
1402   g_value_set_int64 (&src2, 20);
1403   /* subtract as in sets, result is 10 */
1404   ret = gst_value_subtract (&dest, &src1, &src2);
1405   fail_unless (ret == TRUE);
1406   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1407   g_value_unset (&dest);
1408 
1409   /* same values, yields empty set */
1410   ret = gst_value_subtract (&dest, &src1, &src1);
1411   fail_unless (ret == FALSE);
1412   g_value_unset (&src1);
1413   g_value_unset (&src2);
1414 
1415   /*  int64 <-> int64_range
1416    */
1417 
1418   /* would yield an empty set */
1419   g_value_init (&src1, G_TYPE_INT64);
1420   g_value_set_int64 (&src1, 10);
1421   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1422   gst_value_set_int64_range (&src2, 0, 20);
1423   ret = gst_value_subtract (&dest, &src1, &src2);
1424   fail_unless (ret == FALSE);
1425 
1426   /* and the other way around, should create a list of two ranges. */
1427   ret = gst_value_subtract (&dest, &src2, &src1);
1428   fail_unless (ret == TRUE);
1429   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1430   tmp = gst_value_list_get_value (&dest, 0);
1431   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
1432   fail_unless (gst_value_get_int64_range_min (tmp) == 0);
1433   fail_unless (gst_value_get_int64_range_max (tmp) == 9);
1434   tmp = gst_value_list_get_value (&dest, 1);
1435   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
1436   fail_unless (gst_value_get_int64_range_min (tmp) == 11);
1437   fail_unless (gst_value_get_int64_range_max (tmp) == 20);
1438   g_value_unset (&dest);
1439   g_value_unset (&src1);
1440   g_value_unset (&src2);
1441 
1442   /* border case 1, empty set */
1443   g_value_init (&src1, G_TYPE_INT64);
1444   g_value_set_int64 (&src1, 10);
1445   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1446   gst_value_set_int64_range (&src2, 10, 20);
1447   ret = gst_value_subtract (&dest, &src1, &src2);
1448   fail_unless (ret == FALSE);
1449 
1450   /* and the other way around, should create a new range. */
1451   ret = gst_value_subtract (&dest, &src2, &src1);
1452   fail_unless (ret == TRUE);
1453   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1454   fail_unless (gst_value_get_int64_range_min (&dest) == 11);
1455   fail_unless (gst_value_get_int64_range_max (&dest) == 20);
1456   g_value_unset (&dest);
1457   g_value_unset (&src1);
1458   g_value_unset (&src2);
1459 
1460   /* border case 2, empty set */
1461   g_value_init (&src1, G_TYPE_INT64);
1462   g_value_set_int64 (&src1, 20);
1463   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1464   gst_value_set_int64_range (&src2, 10, 20);
1465   ret = gst_value_subtract (&dest, &src1, &src2);
1466   fail_unless (ret == FALSE);
1467 
1468   /* and the other way around, should create a new range. */
1469   ret = gst_value_subtract (&dest, &src2, &src1);
1470   fail_unless (ret == TRUE);
1471   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1472   fail_unless (gst_value_get_int64_range_min (&dest) == 10);
1473   fail_unless (gst_value_get_int64_range_max (&dest) == 19);
1474   g_value_unset (&dest);
1475   g_value_unset (&src1);
1476   g_value_unset (&src2);
1477 
1478   /* case 3, valid set */
1479   g_value_init (&src1, G_TYPE_INT64);
1480   g_value_set_int64 (&src1, 0);
1481   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1482   gst_value_set_int64_range (&src2, 10, 20);
1483   ret = gst_value_subtract (&dest, &src1, &src2);
1484   fail_unless (ret == TRUE);
1485   fail_unless (G_VALUE_HOLDS_INT64 (&dest) == TRUE);
1486   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1487   g_value_unset (&dest);
1488 
1489   /* and the other way around, should keep the range. */
1490   ret = gst_value_subtract (&dest, &src2, &src1);
1491   fail_unless (ret == TRUE);
1492   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1493   fail_unless (gst_value_get_int64_range_min (&dest) == 10);
1494   fail_unless (gst_value_get_int64_range_max (&dest) == 20);
1495   g_value_unset (&dest);
1496   g_value_unset (&src1);
1497   g_value_unset (&src2);
1498 
1499   /*  int64_range <-> int64_range
1500    */
1501 
1502   /* same range, empty set */
1503   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1504   gst_value_set_int64_range (&src1, 10, 20);
1505   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1506   gst_value_set_int64_range (&src2, 10, 20);
1507   ret = gst_value_subtract (&dest, &src1, &src2);
1508   fail_unless (ret == FALSE);
1509   ret = gst_value_subtract (&dest, &src2, &src1);
1510   fail_unless (ret == FALSE);
1511   g_value_unset (&src1);
1512   g_value_unset (&src2);
1513 
1514   /* non overlapping ranges */
1515   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1516   gst_value_set_int64_range (&src1, 10, 20);
1517   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1518   gst_value_set_int64_range (&src2, 30, 40);
1519   ret = gst_value_subtract (&dest, &src1, &src2);
1520   fail_unless (ret == TRUE);
1521   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1522   fail_unless (gst_value_get_int64_range_min (&dest) == 10);
1523   fail_unless (gst_value_get_int64_range_max (&dest) == 20);
1524   g_value_unset (&dest);
1525   /* the other way */
1526   ret = gst_value_subtract (&dest, &src2, &src1);
1527   fail_unless (ret == TRUE);
1528   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1529   fail_unless (gst_value_get_int64_range_min (&dest) == 30);
1530   fail_unless (gst_value_get_int64_range_max (&dest) == 40);
1531   g_value_unset (&dest);
1532   g_value_unset (&src1);
1533   g_value_unset (&src2);
1534 
1535   /* completely overlapping ranges */
1536   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1537   gst_value_set_int64_range (&src1, 10, 20);
1538   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1539   gst_value_set_int64_range (&src2, 10, 30);
1540   ret = gst_value_subtract (&dest, &src1, &src2);
1541   fail_unless (ret == FALSE);
1542   /* the other way */
1543   ret = gst_value_subtract (&dest, &src2, &src1);
1544   fail_unless (ret == TRUE);
1545   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1546   fail_unless (gst_value_get_int64_range_min (&dest) == 21);
1547   fail_unless (gst_value_get_int64_range_max (&dest) == 30);
1548   g_value_unset (&dest);
1549   g_value_unset (&src1);
1550   g_value_unset (&src2);
1551 
1552   /* partially overlapping ranges */
1553   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1554   gst_value_set_int64_range (&src1, 10, 20);
1555   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1556   gst_value_set_int64_range (&src2, 15, 30);
1557   ret = gst_value_subtract (&dest, &src1, &src2);
1558   fail_unless (ret == TRUE);
1559   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1560   fail_unless (gst_value_get_int64_range_min (&dest) == 10);
1561   fail_unless (gst_value_get_int64_range_max (&dest) == 14);
1562   g_value_unset (&dest);
1563   /* the other way */
1564   ret = gst_value_subtract (&dest, &src2, &src1);
1565   fail_unless (ret == TRUE);
1566   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1567   fail_unless (gst_value_get_int64_range_min (&dest) == 21);
1568   fail_unless (gst_value_get_int64_range_max (&dest) == 30);
1569   g_value_unset (&dest);
1570   g_value_unset (&src1);
1571   g_value_unset (&src2);
1572 
1573   /* create a hole { int64_range, int64_range } */
1574   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1575   gst_value_set_int64_range (&src1, 10, 30);
1576   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1577   gst_value_set_int64_range (&src2, 15, 20);
1578   ret = gst_value_subtract (&dest, &src1, &src2);
1579   fail_unless (ret == TRUE);
1580   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1581   tmp = gst_value_list_get_value (&dest, 0);
1582   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
1583   fail_unless (gst_value_get_int64_range_min (tmp) == 10);
1584   fail_unless (gst_value_get_int64_range_max (tmp) == 14);
1585   tmp = gst_value_list_get_value (&dest, 1);
1586   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
1587   fail_unless (gst_value_get_int64_range_min (tmp) == 21);
1588   fail_unless (gst_value_get_int64_range_max (tmp) == 30);
1589   g_value_unset (&dest);
1590   /* the other way */
1591   ret = gst_value_subtract (&dest, &src2, &src1);
1592   fail_unless (ret == FALSE);
1593   g_value_unset (&src1);
1594   g_value_unset (&src2);
1595 
1596   /* create a hole, { int64, int64 } */
1597   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1598   gst_value_set_int64_range (&src1, 10, 30);
1599   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1600   gst_value_set_int64_range (&src2, 11, 29);
1601   ret = gst_value_subtract (&dest, &src1, &src2);
1602   fail_unless (ret == TRUE);
1603   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1604   tmp = gst_value_list_get_value (&dest, 0);
1605   fail_unless (G_VALUE_HOLDS_INT64 (tmp) == TRUE);
1606   fail_unless (g_value_get_int64 (tmp) == 10);
1607   tmp = gst_value_list_get_value (&dest, 1);
1608   fail_unless (G_VALUE_HOLDS_INT64 (tmp) == TRUE);
1609   fail_unless (g_value_get_int64 (tmp) == 30);
1610   g_value_unset (&dest);
1611   /* the other way */
1612   ret = gst_value_subtract (&dest, &src2, &src1);
1613   fail_unless (ret == FALSE);
1614   g_value_unset (&src1);
1615   g_value_unset (&src2);
1616 
1617   /* create a hole, { int64, int64_range } */
1618   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1619   gst_value_set_int64_range (&src1, 10, 30);
1620   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1621   gst_value_set_int64_range (&src2, 11, 28);
1622   ret = gst_value_subtract (&dest, &src1, &src2);
1623   fail_unless (ret == TRUE);
1624   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1625   tmp = gst_value_list_get_value (&dest, 0);
1626   fail_unless (G_VALUE_HOLDS_INT64 (tmp) == TRUE);
1627   fail_unless (g_value_get_int64 (tmp) == 10);
1628   tmp = gst_value_list_get_value (&dest, 1);
1629   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
1630   fail_unless (gst_value_get_int64_range_min (tmp) == 29);
1631   fail_unless (gst_value_get_int64_range_max (tmp) == 30);
1632   g_value_unset (&dest);
1633   /* the other way */
1634   ret = gst_value_subtract (&dest, &src2, &src1);
1635   fail_unless (ret == FALSE);
1636   g_value_unset (&src1);
1637   g_value_unset (&src2);
1638 
1639   /* create a hole, { int64_range, int64 } */
1640   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1641   gst_value_set_int64_range (&src1, 10, 30);
1642   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1643   gst_value_set_int64_range (&src2, 12, 29);
1644   ret = gst_value_subtract (&dest, &src1, &src2);
1645   fail_unless (ret == TRUE);
1646   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1647   tmp = gst_value_list_get_value (&dest, 0);
1648   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
1649   fail_unless (gst_value_get_int64_range_min (tmp) == 10);
1650   fail_unless (gst_value_get_int64_range_max (tmp) == 11);
1651   tmp = gst_value_list_get_value (&dest, 1);
1652   fail_unless (G_VALUE_HOLDS_INT64 (tmp) == TRUE);
1653   fail_unless (g_value_get_int64 (tmp) == 30);
1654   g_value_unset (&dest);
1655   /* the other way */
1656   ret = gst_value_subtract (&dest, &src2, &src1);
1657   fail_unless (ret == FALSE);
1658   g_value_unset (&src1);
1659   g_value_unset (&src2);
1660 }
1661 
1662 GST_END_TEST;
1663 
GST_START_TEST(test_value_subtract_double)1664 GST_START_TEST (test_value_subtract_double)
1665 {
1666   GValue dest = { 0 };
1667   GValue src1 = { 0 };
1668   GValue src2 = { 0 };
1669   const GValue *tmp;
1670   gboolean ret;
1671 
1672   /*  double <-> double
1673    */
1674   g_value_init (&src1, G_TYPE_DOUBLE);
1675   g_value_set_double (&src1, 10.0);
1676   g_value_init (&src2, G_TYPE_DOUBLE);
1677   g_value_set_double (&src2, 20.0);
1678   /* subtract as in sets, result is 10 */
1679   ret = gst_value_subtract (&dest, &src1, &src2);
1680   fail_unless (ret == TRUE);
1681   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1682   g_value_unset (&dest);
1683 
1684   /* same values, yields empty set */
1685   ret = gst_value_subtract (&dest, &src1, &src1);
1686   fail_unless (ret == FALSE);
1687   g_value_unset (&src1);
1688   g_value_unset (&src2);
1689 
1690   /*  double <-> double_range
1691    */
1692 
1693   /* would yield an empty set */
1694   g_value_init (&src1, G_TYPE_DOUBLE);
1695   g_value_set_double (&src1, 10.0);
1696   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1697   gst_value_set_double_range (&src2, 0.0, 20.0);
1698   ret = gst_value_subtract (&dest, &src1, &src2);
1699   fail_unless (ret == FALSE);
1700 
1701   /* and the other way around, we cannot create open ranges
1702    * so the result is the range again */
1703   ret = gst_value_subtract (&dest, &src2, &src1);
1704   fail_unless (ret == TRUE);
1705   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1706   fail_unless (gst_value_get_double_range_min (&dest) == 0.0);
1707   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
1708   g_value_unset (&dest);
1709   g_value_unset (&src1);
1710   g_value_unset (&src2);
1711 
1712   /* border case 1, empty set */
1713   g_value_init (&src1, G_TYPE_DOUBLE);
1714   g_value_set_double (&src1, 10.0);
1715   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1716   gst_value_set_double_range (&src2, 10.0, 20.0);
1717   ret = gst_value_subtract (&dest, &src1, &src2);
1718   fail_unless (ret == FALSE);
1719 
1720   /* and the other way around, should keep same range as
1721    * we don't have open ranges. */
1722   ret = gst_value_subtract (&dest, &src2, &src1);
1723   fail_unless (ret == TRUE);
1724   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1725   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
1726   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
1727   g_value_unset (&dest);
1728   g_value_unset (&src1);
1729   g_value_unset (&src2);
1730 
1731   /* border case 2, empty set */
1732   g_value_init (&src1, G_TYPE_DOUBLE);
1733   g_value_set_double (&src1, 20.0);
1734   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1735   gst_value_set_double_range (&src2, 10.0, 20.0);
1736   ret = gst_value_subtract (&dest, &src1, &src2);
1737   fail_unless (ret == FALSE);
1738 
1739   /* and the other way around, should keep same range as
1740    * we don't have open ranges. */
1741   ret = gst_value_subtract (&dest, &src2, &src1);
1742   fail_unless (ret == TRUE);
1743   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1744   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
1745   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
1746   g_value_unset (&dest);
1747   g_value_unset (&src1);
1748   g_value_unset (&src2);
1749 
1750   /* case 3, valid set */
1751   g_value_init (&src1, G_TYPE_DOUBLE);
1752   g_value_set_double (&src1, 0.0);
1753   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1754   gst_value_set_double_range (&src2, 10.0, 20.0);
1755   ret = gst_value_subtract (&dest, &src1, &src2);
1756   fail_unless (ret == TRUE);
1757   fail_unless (G_VALUE_HOLDS_DOUBLE (&dest) == TRUE);
1758   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1759   g_value_unset (&dest);
1760 
1761   /* and the other way around, should keep the range. */
1762   ret = gst_value_subtract (&dest, &src2, &src1);
1763   fail_unless (ret == TRUE);
1764   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1765   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
1766   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
1767   g_value_unset (&dest);
1768   g_value_unset (&src1);
1769   g_value_unset (&src2);
1770 
1771   /*  double_range <-> double_range
1772    */
1773 
1774   /* Check equality */
1775   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1776   gst_value_set_double_range (&src1, 10.0, 20.0);
1777   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1778   gst_value_set_double_range (&src2, 10.0, 15.0);
1779   /* They are not equal (higher bound is different */
1780   fail_if (gst_value_compare (&src1, &src2) == GST_VALUE_EQUAL);
1781   g_value_unset (&src1);
1782   /* They are not equal (lower bound is different */
1783   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1784   gst_value_set_double_range (&src1, 5.0, 15.0);
1785   fail_if (gst_value_compare (&src1, &src2) == GST_VALUE_EQUAL);
1786   g_value_unset (&src1);
1787   /* And finally check equality */
1788   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1789   gst_value_set_double_range (&src1, 10.0, 15.0);
1790   fail_unless (gst_value_compare (&src1, &src2) == GST_VALUE_EQUAL);
1791   g_value_unset (&src1);
1792   g_value_unset (&src2);
1793 
1794   /* same range, empty set */
1795   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1796   gst_value_set_double_range (&src1, 10.0, 20.0);
1797   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1798   gst_value_set_double_range (&src2, 10.0, 20.0);
1799   ret = gst_value_subtract (&dest, &src1, &src2);
1800   fail_unless (ret == FALSE);
1801   ret = gst_value_subtract (&dest, &src2, &src1);
1802   fail_unless (ret == FALSE);
1803   g_value_unset (&src1);
1804   g_value_unset (&src2);
1805 
1806   /* non overlapping ranges */
1807   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1808   gst_value_set_double_range (&src1, 10.0, 20.0);
1809   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1810   gst_value_set_double_range (&src2, 30.0, 40.0);
1811   ret = gst_value_subtract (&dest, &src1, &src2);
1812   fail_unless (ret == TRUE);
1813   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1814   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
1815   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
1816   g_value_unset (&dest);
1817   /* the other way */
1818   ret = gst_value_subtract (&dest, &src2, &src1);
1819   fail_unless (ret == TRUE);
1820   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1821   fail_unless (gst_value_get_double_range_min (&dest) == 30.0);
1822   fail_unless (gst_value_get_double_range_max (&dest) == 40.0);
1823   g_value_unset (&dest);
1824   g_value_unset (&src1);
1825   g_value_unset (&src2);
1826 
1827   /* completely overlapping ranges */
1828   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1829   gst_value_set_double_range (&src1, 10.0, 20.0);
1830   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1831   gst_value_set_double_range (&src2, 10.0, 30.0);
1832   ret = gst_value_subtract (&dest, &src1, &src2);
1833   fail_unless (ret == FALSE);
1834   /* the other way */
1835   ret = gst_value_subtract (&dest, &src2, &src1);
1836   fail_unless (ret == TRUE);
1837   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1838   fail_unless (gst_value_get_double_range_min (&dest) == 20.0);
1839   fail_unless (gst_value_get_double_range_max (&dest) == 30.0);
1840   g_value_unset (&dest);
1841   g_value_unset (&src1);
1842   g_value_unset (&src2);
1843 
1844   /* partially overlapping ranges */
1845   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1846   gst_value_set_double_range (&src1, 10.0, 20.0);
1847   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1848   gst_value_set_double_range (&src2, 15.0, 30.0);
1849   ret = gst_value_subtract (&dest, &src1, &src2);
1850   fail_unless (ret == TRUE);
1851   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1852   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
1853   fail_unless (gst_value_get_double_range_max (&dest) == 15.0);
1854   g_value_unset (&dest);
1855   /* the other way */
1856   ret = gst_value_subtract (&dest, &src2, &src1);
1857   fail_unless (ret == TRUE);
1858   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1859   fail_unless (gst_value_get_double_range_min (&dest) == 20.0);
1860   fail_unless (gst_value_get_double_range_max (&dest) == 30.0);
1861   g_value_unset (&dest);
1862   g_value_unset (&src1);
1863   g_value_unset (&src2);
1864 
1865   /* create a hole { double_range, double_range } */
1866   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1867   gst_value_set_double_range (&src1, 10.0, 30.0);
1868   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1869   gst_value_set_double_range (&src2, 15.0, 20.0);
1870   ret = gst_value_subtract (&dest, &src1, &src2);
1871   fail_unless (ret == TRUE);
1872   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1873   tmp = gst_value_list_get_value (&dest, 0);
1874   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (tmp) == TRUE);
1875   fail_unless (gst_value_get_double_range_min (tmp) == 10.0);
1876   fail_unless (gst_value_get_double_range_max (tmp) == 15.0);
1877   tmp = gst_value_list_get_value (&dest, 1);
1878   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (tmp) == TRUE);
1879   fail_unless (gst_value_get_double_range_min (tmp) == 20.0);
1880   fail_unless (gst_value_get_double_range_max (tmp) == 30.0);
1881   g_value_unset (&dest);
1882   /* the other way */
1883   ret = gst_value_subtract (&dest, &src2, &src1);
1884   fail_unless (ret == FALSE);
1885   g_value_unset (&src1);
1886   g_value_unset (&src2);
1887 }
1888 
1889 GST_END_TEST;
1890 
1891 /* Test arithmetic subtraction of fractions */
GST_START_TEST(test_value_subtract_fraction)1892 GST_START_TEST (test_value_subtract_fraction)
1893 {
1894   GValue result = { 0 };
1895   GValue src1 = { 0 };
1896   GValue src2 = { 0 };
1897 
1898   /* Subtract 1/4 from 1/2 */
1899   g_value_init (&src1, GST_TYPE_FRACTION);
1900   g_value_init (&src2, GST_TYPE_FRACTION);
1901   g_value_init (&result, GST_TYPE_FRACTION);
1902   gst_value_set_fraction (&src1, 1, 2);
1903   gst_value_set_fraction (&src2, 1, 4);
1904   fail_unless (gst_value_fraction_subtract (&result, &src1, &src2) == TRUE);
1905   fail_unless (gst_value_get_fraction_numerator (&result) == 1);
1906   fail_unless (gst_value_get_fraction_denominator (&result) == 4);
1907 
1908   g_value_unset (&src1);
1909   g_value_unset (&src2);
1910   g_value_unset (&result);
1911 
1912   /* Subtract 1/12 from 7/8 */
1913   g_value_init (&src1, GST_TYPE_FRACTION);
1914   g_value_init (&src2, GST_TYPE_FRACTION);
1915   g_value_init (&result, GST_TYPE_FRACTION);
1916   gst_value_set_fraction (&src1, 7, 8);
1917   gst_value_set_fraction (&src2, 1, 12);
1918   fail_unless (gst_value_fraction_subtract (&result, &src1, &src2) == TRUE);
1919   fail_unless (gst_value_get_fraction_numerator (&result) == 19);
1920   fail_unless (gst_value_get_fraction_denominator (&result) == 24);
1921 
1922   g_value_unset (&src1);
1923   g_value_unset (&src2);
1924   g_value_unset (&result);
1925 
1926   /* Subtract 12/13 from 4/3 */
1927   g_value_init (&src1, GST_TYPE_FRACTION);
1928   g_value_init (&src2, GST_TYPE_FRACTION);
1929   g_value_init (&result, GST_TYPE_FRACTION);
1930   gst_value_set_fraction (&src1, 4, 3);
1931   gst_value_set_fraction (&src2, 12, 13);
1932   fail_unless (gst_value_fraction_subtract (&result, &src1, &src2) == TRUE);
1933   fail_unless (gst_value_get_fraction_numerator (&result) == 16);
1934   fail_unless (gst_value_get_fraction_denominator (&result) == 39);
1935 
1936   g_value_unset (&src1);
1937   g_value_unset (&src2);
1938   g_value_unset (&result);
1939 
1940   /* Subtract 1/12 from 7/8 */
1941 }
1942 
1943 GST_END_TEST;
1944 
1945 /* Test set subtraction operations on fraction ranges */
GST_START_TEST(test_value_subtract_fraction_range)1946 GST_START_TEST (test_value_subtract_fraction_range)
1947 {
1948   GValue dest = { 0 };
1949   GValue src1 = { 0 };
1950   GValue src2 = { 0 };
1951   GValue cmp = { 0 };
1952   const GValue *tmp;
1953   gboolean ret;
1954 
1955   /* Value for tests */
1956   g_value_init (&cmp, GST_TYPE_FRACTION);
1957 
1958   /*  fraction <-> fraction
1959    */
1960   g_value_init (&src1, GST_TYPE_FRACTION);
1961   gst_value_set_fraction (&src1, 10, 1);
1962   g_value_init (&src2, GST_TYPE_FRACTION);
1963   gst_value_set_fraction (&src2, 20, 1);
1964   gst_value_set_fraction (&src1, 10, 1);
1965 
1966   /* subtract as in sets, result is 10 */
1967   ret = gst_value_subtract (&dest, &src1, &src2);
1968   fail_unless (ret == TRUE);
1969   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1970   g_value_unset (&dest);
1971 
1972   /* same values, yields empty set */
1973   ret = gst_value_subtract (&dest, &src1, &src1);
1974   fail_unless (ret == FALSE);
1975   g_value_unset (&src1);
1976   g_value_unset (&src2);
1977 
1978   /*  fraction <-> fraction_range
1979    */
1980 
1981   /* would yield an empty set */
1982   g_value_init (&src1, GST_TYPE_FRACTION);
1983   gst_value_set_fraction (&src1, 10, 1);
1984   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
1985   gst_value_set_fraction_range_full (&src2, 0, 1, 20, 1);
1986   ret = gst_value_subtract (&dest, &src1, &src2);
1987   fail_unless (ret == FALSE);
1988 
1989   /* and the other way around, we cannot create open ranges
1990    * so the result is the range again */
1991   ret = gst_value_subtract (&dest, &src2, &src1);
1992   fail_unless (ret == TRUE);
1993   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
1994   gst_value_set_fraction (&cmp, 0, 1);
1995   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
1996           &cmp) == GST_VALUE_EQUAL);
1997   gst_value_set_fraction (&cmp, 20, 1);
1998   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
1999           &cmp) == GST_VALUE_EQUAL);
2000   g_value_unset (&dest);
2001   g_value_unset (&src1);
2002   g_value_unset (&src2);
2003 
2004   /* border case 1, empty set */
2005   g_value_init (&src1, GST_TYPE_FRACTION);
2006   gst_value_set_fraction (&src1, 10, 1);
2007   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2008   gst_value_set_fraction_range_full (&src2, 10, 1, 20, 1);
2009   ret = gst_value_subtract (&dest, &src1, &src2);
2010   fail_unless (ret == FALSE);
2011 
2012   /* and the other way around, should keep same range as
2013    * we don't have open ranges. */
2014   ret = gst_value_subtract (&dest, &src2, &src1);
2015   fail_unless (ret == TRUE);
2016   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2017   gst_value_set_fraction (&cmp, 10, 1);
2018   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
2019           &cmp) == GST_VALUE_EQUAL);
2020   gst_value_set_fraction (&cmp, 20, 1);
2021   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
2022           &cmp) == GST_VALUE_EQUAL);
2023   g_value_unset (&dest);
2024   g_value_unset (&src1);
2025   g_value_unset (&src2);
2026 
2027   /* case 2, valid set */
2028   g_value_init (&src1, GST_TYPE_FRACTION);
2029   gst_value_set_fraction (&src1, 0, 1);
2030   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2031   gst_value_set_fraction_range_full (&src2, 10, 1, 20, 1);
2032   ret = gst_value_subtract (&dest, &src1, &src2);
2033   fail_unless (ret == TRUE);
2034   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION);
2035   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
2036   g_value_unset (&dest);
2037 
2038   /* and the other way around, should keep the range. */
2039   ret = gst_value_subtract (&dest, &src2, &src1);
2040   fail_unless (ret == TRUE);
2041   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2042   fail_unless (gst_value_compare (&dest, &src2) == GST_VALUE_EQUAL);
2043   g_value_unset (&dest);
2044   g_value_unset (&src1);
2045   g_value_unset (&src2);
2046 
2047   /*  fraction_range <-> fraction_range
2048    */
2049 
2050   /* same range, empty set */
2051   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
2052   gst_value_set_fraction_range_full (&src1, 10, 2, 20, 2);
2053   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2054   gst_value_set_fraction_range_full (&src2, 10, 2, 20, 2);
2055   ret = gst_value_subtract (&dest, &src1, &src2);
2056   fail_unless (ret == FALSE);
2057   ret = gst_value_subtract (&dest, &src2, &src1);
2058   fail_unless (ret == FALSE);
2059   g_value_unset (&src1);
2060   g_value_unset (&src2);
2061 
2062   /* non overlapping ranges */
2063   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
2064   gst_value_set_fraction_range_full (&src1, 10, 2, 10, 1);
2065   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2066   gst_value_set_fraction_range_full (&src2, 30, 2, 40, 2);
2067   ret = gst_value_subtract (&dest, &src1, &src2);
2068   fail_unless (ret == TRUE);
2069   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2070   gst_value_set_fraction (&cmp, 5, 1);
2071   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
2072           &cmp) == GST_VALUE_EQUAL);
2073   gst_value_set_fraction (&cmp, 10, 1);
2074   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
2075           &cmp) == GST_VALUE_EQUAL);
2076 
2077   g_value_unset (&dest);
2078   /* the other way */
2079   ret = gst_value_subtract (&dest, &src2, &src1);
2080   fail_unless (ret == TRUE);
2081   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2082   gst_value_set_fraction (&cmp, 15, 1);
2083   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
2084           &cmp) == GST_VALUE_EQUAL);
2085   gst_value_set_fraction (&cmp, 20, 1);
2086   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
2087           &cmp) == GST_VALUE_EQUAL);
2088   g_value_unset (&dest);
2089   g_value_unset (&src1);
2090   g_value_unset (&src2);
2091 
2092   /* completely overlapping ranges */
2093   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
2094   gst_value_set_fraction_range_full (&src1, 10, 1, 20, 1);
2095   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2096   gst_value_set_fraction_range_full (&src2, 10, 1, 30, 1);
2097   ret = gst_value_subtract (&dest, &src1, &src2);
2098   fail_unless (ret == FALSE);
2099   /* the other way */
2100   ret = gst_value_subtract (&dest, &src2, &src1);
2101   fail_unless (ret == TRUE);
2102   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2103   gst_value_set_fraction (&cmp, 20, 1);
2104   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
2105           &cmp) == GST_VALUE_EQUAL);
2106   gst_value_set_fraction (&cmp, 30, 1);
2107   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
2108           &cmp) == GST_VALUE_EQUAL);
2109   g_value_unset (&dest);
2110   g_value_unset (&src1);
2111   g_value_unset (&src2);
2112 
2113   /* partially overlapping ranges */
2114   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
2115   gst_value_set_fraction_range_full (&src1, 10, 1, 20, 1);
2116   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2117   gst_value_set_fraction_range_full (&src2, 15, 1, 30, 1);
2118   ret = gst_value_subtract (&dest, &src1, &src2);
2119   fail_unless (ret == TRUE);
2120   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2121   gst_value_set_fraction (&cmp, 10, 1);
2122   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
2123           &cmp) == GST_VALUE_EQUAL);
2124   gst_value_set_fraction (&cmp, 15, 1);
2125   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
2126           &cmp) == GST_VALUE_EQUAL);
2127   g_value_unset (&dest);
2128 
2129   /* the other way */
2130   ret = gst_value_subtract (&dest, &src2, &src1);
2131   fail_unless (ret == TRUE);
2132   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2133   gst_value_set_fraction (&cmp, 20, 1);
2134   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
2135           &cmp) == GST_VALUE_EQUAL);
2136   gst_value_set_fraction (&cmp, 30, 1);
2137   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
2138           &cmp) == GST_VALUE_EQUAL);
2139   g_value_unset (&dest);
2140   g_value_unset (&src1);
2141   g_value_unset (&src2);
2142 
2143   /* create a hole { double_range, double_range } */
2144   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
2145   gst_value_set_fraction_range_full (&src1, 10, 1, 30, 1);
2146   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2147   gst_value_set_fraction_range_full (&src2, 15, 1, 20, 1);
2148   ret = gst_value_subtract (&dest, &src1, &src2);
2149   fail_unless (ret == TRUE);
2150   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
2151   /* 1st list entry */
2152   tmp = gst_value_list_get_value (&dest, 0);
2153   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (tmp) == TRUE);
2154   gst_value_set_fraction (&cmp, 10, 1);
2155   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (tmp),
2156           &cmp) == GST_VALUE_EQUAL);
2157   gst_value_set_fraction (&cmp, 15, 1);
2158   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (tmp),
2159           &cmp) == GST_VALUE_EQUAL);
2160   /* 2nd list entry */
2161   tmp = gst_value_list_get_value (&dest, 1);
2162   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (tmp) == TRUE);
2163   gst_value_set_fraction (&cmp, 20, 1);
2164   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (tmp),
2165           &cmp) == GST_VALUE_EQUAL);
2166   gst_value_set_fraction (&cmp, 30, 1);
2167   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (tmp),
2168           &cmp) == GST_VALUE_EQUAL);
2169   g_value_unset (&dest);
2170   /* the other way */
2171   ret = gst_value_subtract (&dest, &src2, &src1);
2172   fail_unless (ret == FALSE);
2173   g_value_unset (&src1);
2174   g_value_unset (&src2);
2175 
2176   g_value_unset (&cmp);
2177 }
2178 
2179 GST_END_TEST;
2180 
2181 /* Test set subtraction operations on fraction lists */
GST_START_TEST(test_value_subtract_fraction_list)2182 GST_START_TEST (test_value_subtract_fraction_list)
2183 {
2184   GValue list1 = { 0 };
2185   GValue list2 = { 0 };
2186   GValue val1 = { 0 };
2187   GValue val2 = { 0 };
2188   GValue tmp = { 0 };
2189   gboolean ret;
2190 
2191   g_value_init (&list1, GST_TYPE_LIST);
2192   g_value_init (&val1, GST_TYPE_FRACTION);
2193   gst_value_set_fraction (&val1, 15, 2);
2194   gst_value_list_append_value (&list1, &val1);
2195   g_value_init (&tmp, GST_TYPE_FRACTION);
2196   gst_value_set_fraction (&tmp, 5, 1);
2197   gst_value_list_append_value (&list1, &tmp);
2198   g_value_unset (&tmp);
2199 
2200   g_value_init (&list2, GST_TYPE_LIST);
2201   g_value_init (&val2, GST_TYPE_FRACTION);
2202   gst_value_set_fraction (&val2, 15, 1);
2203   gst_value_list_append_value (&list2, &val2);
2204   g_value_init (&tmp, GST_TYPE_FRACTION);
2205   gst_value_set_fraction (&tmp, 5, 1);
2206   gst_value_list_append_value (&list2, &tmp);
2207   g_value_unset (&tmp);
2208 
2209   /* should subtract all common elements */
2210   ret = gst_value_subtract (&tmp, &list1, &list2);
2211   fail_unless (ret == TRUE);
2212   fail_unless (gst_value_compare (&tmp, &val1) == GST_VALUE_EQUAL);
2213   g_value_unset (&val1);
2214   g_value_unset (&tmp);
2215 
2216   ret = gst_value_subtract (&tmp, &list2, &list1);
2217   fail_unless (ret == TRUE);
2218   fail_unless (gst_value_compare (&tmp, &val2) == GST_VALUE_EQUAL);
2219   g_value_unset (&val2);
2220   g_value_unset (&tmp);
2221 
2222   g_value_unset (&list1);
2223   g_value_unset (&list2);
2224 }
2225 
2226 GST_END_TEST;
2227 
GST_START_TEST(test_date)2228 GST_START_TEST (test_date)
2229 {
2230   GstStructure *s;
2231   GDate *date, *date2;
2232   gchar *str;
2233 
2234   date = g_date_new_dmy (22, 9, 2005);
2235 
2236   s = gst_structure_new ("media/x-type", "SOME_DATE_TAG", G_TYPE_DATE,
2237       date, NULL);
2238 
2239   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TAG", G_TYPE_DATE));
2240   fail_unless (gst_structure_get_date (s, "SOME_DATE_TAG", &date2));
2241   fail_unless (date2 != NULL);
2242   fail_unless (g_date_valid (date2));
2243   fail_unless (g_date_compare (date, date2) == 0);
2244 
2245   g_date_free (date);
2246   g_date_free (date2);
2247   date = NULL;
2248   date2 = NULL;
2249 
2250   str = gst_structure_to_string (s);
2251   gst_structure_free (s);
2252   s = NULL;
2253 
2254   fail_unless (g_str_equal (str,
2255           "media/x-type, SOME_DATE_TAG=(date)2005-09-22;"));
2256 
2257   s = gst_structure_from_string (str, NULL);
2258   g_free (str);
2259   str = NULL;
2260 
2261   fail_unless (s != NULL);
2262   fail_unless (gst_structure_has_name (s, "media/x-type"));
2263   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TAG", G_TYPE_DATE));
2264   fail_unless (gst_structure_get_date (s, "SOME_DATE_TAG", &date));
2265   fail_unless (date != NULL);
2266   fail_unless (g_date_valid (date));
2267   fail_unless (g_date_get_day (date) == 22);
2268   fail_unless (g_date_get_month (date) == 9);
2269   fail_unless (g_date_get_year (date) == 2005);
2270   g_date_free (date);
2271   date = NULL;
2272 
2273   str = gst_structure_to_string (s);
2274   gst_structure_free (s);
2275   s = NULL;
2276 
2277   fail_unless (g_str_equal (str,
2278           "media/x-type, SOME_DATE_TAG=(date)2005-09-22;"));
2279   g_free (str);
2280   str = NULL;
2281 }
2282 
2283 GST_END_TEST;
2284 
2285 static gboolean
date_time_equal(GstDateTime * a,GstDateTime * b)2286 date_time_equal (GstDateTime * a, GstDateTime * b)
2287 {
2288   if (gst_date_time_get_year (a) != gst_date_time_get_year (b) ||
2289       gst_date_time_get_month (a) != gst_date_time_get_month (b) ||
2290       gst_date_time_get_day (a) != gst_date_time_get_day (b))
2291     return FALSE;
2292 
2293   if (gst_date_time_get_hour (a) != gst_date_time_get_hour (b) ||
2294       gst_date_time_get_minute (a) != gst_date_time_get_minute (b) ||
2295       gst_date_time_get_second (a) != gst_date_time_get_second (b) ||
2296       gst_date_time_get_microsecond (a) != gst_date_time_get_microsecond (b))
2297     return FALSE;
2298 
2299   if (gst_date_time_get_time_zone_offset (a) !=
2300       gst_date_time_get_time_zone_offset (b))
2301     return FALSE;
2302 
2303   return TRUE;
2304 }
2305 
GST_START_TEST(test_date_time)2306 GST_START_TEST (test_date_time)
2307 {
2308   GstStructure *s;
2309   GstDateTime *datetime, *datetime2;
2310   GValue val = { 0, };
2311   gchar *str;
2312 
2313   /* utc timezone */
2314   datetime = gst_date_time_new (0, 2010, 6, 23, 7, 40, 10);
2315 
2316   s = gst_structure_new ("media/x-type", "SOME_DATE_TIME_TAG",
2317       GST_TYPE_DATE_TIME, datetime, NULL);
2318 
2319   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
2320           GST_TYPE_DATE_TIME));
2321   fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
2322           &datetime2));
2323   fail_unless (datetime2 != NULL);
2324   fail_unless (date_time_equal (datetime, datetime2));
2325 
2326   gst_date_time_unref (datetime);
2327   gst_date_time_unref (datetime2);
2328   datetime = NULL;
2329   datetime2 = NULL;
2330 
2331   str = gst_structure_to_string (s);
2332   gst_structure_free (s);
2333   s = NULL;
2334 
2335   fail_unless_equals_string (str,
2336       "media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10Z;");
2337 
2338   s = gst_structure_from_string (str, NULL);
2339   g_free (str);
2340   str = NULL;
2341 
2342   fail_unless (s != NULL);
2343   fail_unless (gst_structure_has_name (s, "media/x-type"));
2344   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
2345           GST_TYPE_DATE_TIME));
2346   fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
2347           &datetime));
2348   fail_unless (datetime != NULL);
2349   fail_unless (gst_date_time_get_year (datetime) == 2010);
2350   fail_unless (gst_date_time_get_month (datetime) == 6);
2351   fail_unless (gst_date_time_get_day (datetime) == 23);
2352   fail_unless (gst_date_time_get_hour (datetime) == 7);
2353   fail_unless (gst_date_time_get_minute (datetime) == 40);
2354   fail_unless (gst_date_time_get_second (datetime) == 10);
2355   fail_unless (gst_date_time_get_microsecond (datetime) == 0);
2356   fail_unless (gst_date_time_get_time_zone_offset (datetime) == 0);
2357   gst_date_time_unref (datetime);
2358   datetime = NULL;
2359 
2360   str = gst_structure_to_string (s);
2361   gst_structure_free (s);
2362   s = NULL;
2363 
2364   fail_unless_equals_string (str,
2365       "media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10Z;");
2366   g_free (str);
2367   str = NULL;
2368 
2369   /* with timezone */
2370   datetime = gst_date_time_new (-3.0, 2010, 6, 23, 7, 40, 10.000001);
2371 
2372   s = gst_structure_new ("media/x-type", "SOME_DATE_TIME_TAG",
2373       GST_TYPE_DATE_TIME, datetime, NULL);
2374 
2375   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
2376           GST_TYPE_DATE_TIME));
2377   fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
2378           &datetime2));
2379   fail_unless (datetime2 != NULL);
2380   fail_unless (date_time_equal (datetime, datetime2));
2381 
2382   gst_date_time_unref (datetime);
2383   gst_date_time_unref (datetime2);
2384   datetime = NULL;
2385   datetime2 = NULL;
2386 
2387   str = gst_structure_to_string (s);
2388   gst_structure_free (s);
2389   s = NULL;
2390 
2391   fail_unless_equals_string (str,
2392       "media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10.000001-0300;");
2393 
2394   s = gst_structure_from_string (str, NULL);
2395   g_free (str);
2396   str = NULL;
2397 
2398   fail_unless (s != NULL);
2399   fail_unless (gst_structure_has_name (s, "media/x-type"));
2400   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
2401           GST_TYPE_DATE_TIME));
2402   fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
2403           &datetime));
2404   fail_unless (datetime != NULL);
2405   fail_unless (gst_date_time_get_year (datetime) == 2010);
2406   fail_unless (gst_date_time_get_month (datetime) == 6);
2407   fail_unless (gst_date_time_get_day (datetime) == 23);
2408   fail_unless (gst_date_time_get_hour (datetime) == 7);
2409   fail_unless (gst_date_time_get_minute (datetime) == 40);
2410   fail_unless (gst_date_time_get_second (datetime) == 10);
2411   fail_unless (gst_date_time_get_microsecond (datetime) == 1);
2412   fail_unless (gst_date_time_get_time_zone_offset (datetime) == -3);
2413   gst_date_time_unref (datetime);
2414   datetime = NULL;
2415 
2416   str = gst_structure_to_string (s);
2417   gst_structure_free (s);
2418   s = NULL;
2419   fail_unless_equals_string (str,
2420       "media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10.000001-0300;");
2421 
2422   g_free (str);
2423   str = NULL;
2424 
2425   /* with positive timezone */
2426   datetime = gst_date_time_new (2.0, 2010, 6, 23, 7, 40, 10.000001);
2427 
2428   s = gst_structure_new ("media/x-type", "SOME_DATE_TIME_TAG",
2429       GST_TYPE_DATE_TIME, datetime, NULL);
2430 
2431   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
2432           GST_TYPE_DATE_TIME));
2433   fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
2434           &datetime2));
2435   fail_unless (datetime2 != NULL);
2436   fail_unless (date_time_equal (datetime, datetime2));
2437 
2438   gst_date_time_unref (datetime);
2439   gst_date_time_unref (datetime2);
2440   datetime = NULL;
2441   datetime2 = NULL;
2442 
2443   str = gst_structure_to_string (s);
2444   gst_structure_free (s);
2445   s = NULL;
2446 
2447   fail_unless_equals_string (str,
2448       "media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10.000001+0200;");
2449 
2450   s = gst_structure_from_string (str, NULL);
2451   g_free (str);
2452   str = NULL;
2453 
2454   fail_unless (s != NULL);
2455   fail_unless (gst_structure_has_name (s, "media/x-type"));
2456   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
2457           GST_TYPE_DATE_TIME));
2458   fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
2459           &datetime));
2460   fail_unless (datetime != NULL);
2461   fail_unless (gst_date_time_get_year (datetime) == 2010);
2462   fail_unless (gst_date_time_get_month (datetime) == 6);
2463   fail_unless (gst_date_time_get_day (datetime) == 23);
2464   fail_unless (gst_date_time_get_hour (datetime) == 7);
2465   fail_unless (gst_date_time_get_minute (datetime) == 40);
2466   fail_unless (gst_date_time_get_second (datetime) == 10);
2467   fail_unless (gst_date_time_get_microsecond (datetime) == 1);
2468   fail_unless (gst_date_time_get_time_zone_offset (datetime) == 2);
2469   gst_date_time_unref (datetime);
2470   datetime = NULL;
2471 
2472   str = gst_structure_to_string (s);
2473   gst_structure_free (s);
2474   s = NULL;
2475   fail_unless_equals_string (str,
2476       "media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10.000001+0200;");
2477 
2478   g_free (str);
2479   str = NULL;
2480 
2481   /* test partial dates */
2482   datetime = gst_date_time_new (0.0, 2010, -1, -1, -1, -1, -1.0);
2483   g_value_init (&val, GST_TYPE_DATE_TIME);
2484   g_value_take_boxed (&val, datetime);
2485   str = gst_value_serialize (&val);
2486   g_value_reset (&val);
2487   fail_unless_equals_string (str, "2010");
2488   fail_unless (gst_value_deserialize (&val, str));
2489   datetime = g_value_get_boxed (&val);
2490   fail_if (!gst_date_time_has_year (datetime));
2491   fail_if (gst_date_time_has_month (datetime));
2492   fail_if (gst_date_time_has_day (datetime));
2493   fail_if (gst_date_time_has_time (datetime));
2494   g_value_unset (&val);
2495   g_free (str);
2496 
2497   datetime = gst_date_time_new (0.0, 2010, 9, -1, -1, -1, -1.0);
2498   g_value_init (&val, GST_TYPE_DATE_TIME);
2499   g_value_take_boxed (&val, datetime);
2500   str = gst_value_serialize (&val);
2501   g_value_reset (&val);
2502   fail_unless_equals_string (str, "2010-09");
2503   fail_unless (gst_value_deserialize (&val, str));
2504   datetime = g_value_get_boxed (&val);
2505   fail_if (!gst_date_time_has_year (datetime));
2506   fail_if (!gst_date_time_has_month (datetime));
2507   fail_if (gst_date_time_has_day (datetime));
2508   fail_if (gst_date_time_has_time (datetime));
2509   g_value_unset (&val);
2510   g_free (str);
2511 
2512   datetime = gst_date_time_new (0.0, 1983, 11, 30, -1, -1, -1.0);
2513   g_value_init (&val, GST_TYPE_DATE_TIME);
2514   g_value_take_boxed (&val, datetime);
2515   str = gst_value_serialize (&val);
2516   g_value_reset (&val);
2517   fail_unless_equals_string (str, "1983-11-30");
2518   fail_unless (gst_value_deserialize (&val, str));
2519   datetime = g_value_get_boxed (&val);
2520   fail_if (!gst_date_time_has_year (datetime));
2521   fail_if (!gst_date_time_has_month (datetime));
2522   fail_if (!gst_date_time_has_day (datetime));
2523   fail_if (gst_date_time_has_time (datetime));
2524   g_value_unset (&val);
2525   g_free (str);
2526 
2527   datetime = gst_date_time_new (0.0, 1983, 11, 30, 3, 52, -1.0);
2528   g_value_init (&val, GST_TYPE_DATE_TIME);
2529   g_value_take_boxed (&val, datetime);
2530   str = gst_value_serialize (&val);
2531   g_value_reset (&val);
2532   fail_unless_equals_string (str, "1983-11-30T03:52Z");
2533   fail_unless (gst_value_deserialize (&val, str));
2534   datetime = g_value_get_boxed (&val);
2535   fail_if (!gst_date_time_has_year (datetime));
2536   fail_if (!gst_date_time_has_month (datetime));
2537   fail_if (!gst_date_time_has_day (datetime));
2538   fail_if (!gst_date_time_has_time (datetime));
2539   fail_if (gst_date_time_has_second (datetime));
2540   fail_unless_equals_float (gst_date_time_get_time_zone_offset (datetime), 0.0);
2541   g_value_unset (&val);
2542   g_free (str);
2543 
2544   datetime = gst_date_time_new (-4.5, 1983, 11, 30, 3, 52, -1.0);
2545   g_value_init (&val, GST_TYPE_DATE_TIME);
2546   g_value_take_boxed (&val, datetime);
2547   str = gst_value_serialize (&val);
2548   g_value_reset (&val);
2549   fail_unless_equals_string (str, "1983-11-30T03:52-0430");
2550   fail_unless (gst_value_deserialize (&val, str));
2551   datetime = g_value_get_boxed (&val);
2552   fail_if (!gst_date_time_has_year (datetime));
2553   fail_if (!gst_date_time_has_month (datetime));
2554   fail_if (!gst_date_time_has_day (datetime));
2555   fail_if (!gst_date_time_has_time (datetime));
2556   fail_if (gst_date_time_has_second (datetime));
2557   fail_unless_equals_float (gst_date_time_get_time_zone_offset (datetime),
2558       -4.5);
2559   g_value_unset (&val);
2560   g_free (str);
2561 
2562   datetime = gst_date_time_new (4.5, 1983, 11, 30, 14, 52, 9);
2563   g_value_init (&val, GST_TYPE_DATE_TIME);
2564   g_value_take_boxed (&val, datetime);
2565   str = gst_value_serialize (&val);
2566   g_value_reset (&val);
2567   fail_unless_equals_string (str, "1983-11-30T14:52:09+0430");
2568   fail_unless (gst_value_deserialize (&val, str));
2569   datetime = g_value_get_boxed (&val);
2570   fail_if (!gst_date_time_has_year (datetime));
2571   fail_if (!gst_date_time_has_month (datetime));
2572   fail_if (!gst_date_time_has_day (datetime));
2573   fail_if (!gst_date_time_has_time (datetime));
2574   fail_if (!gst_date_time_has_second (datetime));
2575   fail_unless_equals_float (gst_date_time_get_time_zone_offset (datetime), 4.5);
2576   g_value_unset (&val);
2577   g_free (str);
2578 
2579   datetime = gst_date_time_new (-4.5, 1983, 11, 30, 14, 52, 9.702);
2580   g_value_init (&val, GST_TYPE_DATE_TIME);
2581   g_value_take_boxed (&val, datetime);
2582   str = gst_value_serialize (&val);
2583   g_value_reset (&val);
2584   fail_unless_equals_string (str, "1983-11-30T14:52:09.702-0430");
2585   fail_unless (gst_value_deserialize (&val, str));
2586   datetime = g_value_get_boxed (&val);
2587   fail_if (!gst_date_time_has_year (datetime));
2588   fail_if (!gst_date_time_has_month (datetime));
2589   fail_if (!gst_date_time_has_day (datetime));
2590   fail_if (!gst_date_time_has_time (datetime));
2591   fail_if (!gst_date_time_has_second (datetime));
2592   fail_unless_equals_float (gst_date_time_get_time_zone_offset (datetime),
2593       -4.5);
2594   g_value_unset (&val);
2595   g_free (str);
2596 }
2597 
2598 GST_END_TEST;
2599 
GST_START_TEST(test_fraction_range)2600 GST_START_TEST (test_fraction_range)
2601 {
2602   GValue range = { 0, };
2603   GValue start = { 0, };
2604   GValue end = { 0, };
2605   GValue src = { 0, };
2606   GValue dest = { 0, };
2607   GValue range2 = { 0, };
2608 
2609   g_value_init (&range, GST_TYPE_FRACTION_RANGE);
2610   g_value_init (&range2, GST_TYPE_FRACTION_RANGE);
2611   g_value_init (&start, GST_TYPE_FRACTION);
2612   g_value_init (&end, GST_TYPE_FRACTION);
2613   g_value_init (&src, GST_TYPE_FRACTION);
2614 
2615   gst_value_set_fraction (&src, 1, 2);
2616 
2617   /* Check that a intersection of fraction & range = fraction */
2618   gst_value_set_fraction (&start, 1, 4);
2619   gst_value_set_fraction (&end, 2, 3);
2620   gst_value_set_fraction_range (&range, &start, &end);
2621 
2622   fail_unless (gst_value_intersect (&dest, &src, &range) == TRUE);
2623   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION);
2624   fail_unless (gst_value_compare (&dest, &src) == GST_VALUE_EQUAL);
2625 
2626   /* Check that a intersection selects the overlapping range */
2627   gst_value_set_fraction (&start, 1, 3);
2628   gst_value_set_fraction (&end, 2, 3);
2629   gst_value_set_fraction_range (&range2, &start, &end);
2630   g_value_unset (&dest);
2631   fail_unless (gst_value_intersect (&dest, &range, &range2) == TRUE);
2632   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2633 
2634   gst_value_set_fraction_range (&range2, &start, &end);
2635   fail_unless (gst_value_compare (&dest, &range2) == GST_VALUE_EQUAL);
2636 
2637   /* Check that non intersection ranges don't intersect */
2638   gst_value_set_fraction (&start, 4, 2);
2639   gst_value_set_fraction (&end, 5, 2);
2640   gst_value_set_fraction_range (&range2, &start, &end);
2641   g_value_unset (&dest);
2642   fail_unless (gst_value_intersect (&dest, &range, &range2) == FALSE);
2643 
2644   g_value_unset (&start);
2645   g_value_unset (&end);
2646   g_value_unset (&range);
2647   g_value_unset (&range2);
2648   g_value_unset (&src);
2649 }
2650 
2651 GST_END_TEST;
2652 
GST_START_TEST(test_serialize_deserialize_format_enum)2653 GST_START_TEST (test_serialize_deserialize_format_enum)
2654 {
2655   GstStructure *s, *s2;
2656   GstFormat foobar_fmt;
2657   gchar *str, *str2, *end = NULL;
2658 
2659   /* make sure custom formats are serialised properly as well */
2660   foobar_fmt = gst_format_register ("foobar", "GST_FORMAT_FOOBAR");
2661   fail_unless (foobar_fmt != GST_FORMAT_UNDEFINED);
2662 
2663   s = gst_structure_new ("foo/bar", "format1", GST_TYPE_FORMAT,
2664       GST_FORMAT_BYTES, "format2", GST_TYPE_FORMAT, GST_FORMAT_TIME,
2665       "format3", GST_TYPE_FORMAT, GST_FORMAT_DEFAULT, "format4",
2666       GST_TYPE_FORMAT, foobar_fmt, NULL);
2667 
2668   str = gst_structure_to_string (s);
2669   GST_LOG ("Got structure string '%s'", GST_STR_NULL (str));
2670   fail_unless (str != NULL);
2671   fail_unless (strstr (str, "TIME") != NULL);
2672   fail_unless (strstr (str, "BYTE") != NULL);
2673   fail_unless (strstr (str, "DEFAULT") != NULL);
2674   fail_unless (strstr (str, "FOOBAR") != NULL);
2675 
2676   s2 = gst_structure_from_string (str, &end);
2677   fail_unless (s2 != NULL);
2678 
2679   str2 = gst_structure_to_string (s2);
2680   fail_unless (str2 != NULL);
2681 
2682   fail_unless (g_str_equal (str, str2));
2683 
2684   g_free (str);
2685   g_free (str2);
2686   gst_structure_free (s);
2687   gst_structure_free (s2);
2688 }
2689 
2690 GST_END_TEST;
2691 
GST_START_TEST(test_serialize_deserialize_value_array)2692 GST_START_TEST (test_serialize_deserialize_value_array)
2693 {
2694   GValue v = G_VALUE_INIT, v2 = G_VALUE_INIT, v3 = G_VALUE_INIT;
2695   gchar *str = NULL;
2696 
2697   g_value_init (&v, GST_TYPE_ARRAY);
2698   g_value_init (&v2, GST_TYPE_ARRAY);
2699   g_value_init (&v3, G_TYPE_DOUBLE);
2700   g_value_set_double (&v3, 1);
2701   gst_value_array_append_value (&v2, &v3);
2702   g_value_unset (&v3);
2703   g_value_init (&v3, G_TYPE_DOUBLE);
2704   g_value_set_double (&v3, 0);
2705   gst_value_array_append_value (&v2, &v3);
2706   g_value_unset (&v3);
2707   gst_value_array_append_value (&v, &v2);
2708   g_value_unset (&v2);
2709 
2710   str = gst_value_serialize (&v);
2711 
2712   g_value_init (&v2, GST_TYPE_ARRAY);
2713   fail_unless (gst_value_deserialize (&v2, str));
2714   fail_unless (gst_value_compare (&v, &v2) == 0);
2715 
2716   g_value_unset (&v2);
2717   g_value_unset (&v);
2718   g_free (str);
2719 }
2720 
2721 GST_END_TEST;
2722 
GST_START_TEST(test_serialize_deserialize_caps)2723 GST_START_TEST (test_serialize_deserialize_caps)
2724 {
2725   GValue value = { 0 }
2726   , value2 = {
2727   0};
2728   GstCaps *caps, *caps2;
2729   GstCaps *incaps;
2730   gchar *serialized;
2731 
2732   incaps = gst_caps_new_simple ("caps/internal",
2733       "in-field", G_TYPE_INT, 20, "in-field2",
2734       G_TYPE_STRING, "some in ternal field", NULL);
2735   caps = gst_caps_new_simple ("test/caps",
2736       "foo", G_TYPE_INT, 10, "bar", G_TYPE_STRING, "test",
2737       "int-caps", GST_TYPE_CAPS, incaps, NULL);
2738   fail_if (GST_CAPS_REFCOUNT_VALUE (caps) != 1);
2739   gst_caps_unref (incaps);
2740 
2741   /* and assign caps to gvalue */
2742   g_value_init (&value, GST_TYPE_CAPS);
2743   g_value_take_boxed (&value, caps);
2744   fail_if (GST_CAPS_REFCOUNT_VALUE (caps) != 1);
2745 
2746   /* now serialize it */
2747   serialized = gst_value_serialize (&value);
2748   GST_DEBUG ("serialized caps to %s", serialized);
2749   fail_unless (serialized != NULL);
2750 
2751   /* refcount should not change */
2752   fail_if (GST_CAPS_REFCOUNT_VALUE (caps) != 1);
2753 
2754   /* now deserialize again */
2755   g_value_init (&value2, GST_TYPE_CAPS);
2756   gst_value_deserialize (&value2, serialized);
2757 
2758   caps2 = g_value_get_boxed (&value2);
2759   fail_if (GST_CAPS_REFCOUNT_VALUE (caps2) != 1);
2760 
2761   /* they should be equal */
2762   fail_unless (gst_caps_is_equal (caps, caps2));
2763 
2764   /* cleanup */
2765   g_value_unset (&value);
2766   g_value_unset (&value2);
2767   g_free (serialized);
2768 }
2769 
2770 GST_END_TEST;
2771 
GST_START_TEST(test_int_range)2772 GST_START_TEST (test_int_range)
2773 {
2774   GValue range = { 0, };
2775   GValue start = { 0, };
2776   GValue end = { 0, };
2777   GValue src = { 0, };
2778   GValue dest = { 0, };
2779   GValue range2 = { 0, };
2780 
2781   g_value_init (&range, GST_TYPE_INT_RANGE);
2782   g_value_init (&range2, GST_TYPE_INT_RANGE);
2783   g_value_init (&start, G_TYPE_INT);
2784   g_value_init (&end, G_TYPE_INT);
2785   g_value_init (&src, G_TYPE_INT);
2786 
2787   g_value_set_int (&src, 2);
2788 
2789   /* Check that a intersection of int & range = int */
2790   gst_value_set_int_range (&range, 1, 5);
2791 
2792   fail_unless (gst_value_intersect (&dest, &src, &range) == TRUE);
2793   fail_unless (G_VALUE_TYPE (&dest) == G_TYPE_INT);
2794   fail_unless (gst_value_compare (&dest, &src) == GST_VALUE_EQUAL);
2795 
2796   /* Check that a intersection selects the overlapping range */
2797   gst_value_set_int_range (&range2, 2, 3);
2798   g_value_unset (&dest);
2799   fail_unless (gst_value_intersect (&dest, &range, &range2) == TRUE);
2800   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
2801 
2802   fail_unless (gst_value_compare (&dest, &range2) == GST_VALUE_EQUAL);
2803 
2804   /* Check that non intersection ranges don't intersect */
2805   gst_value_set_int_range (&range2, 6, 7);
2806   g_value_unset (&dest);
2807   fail_unless (gst_value_intersect (&dest, &range, &range2) == FALSE);
2808 
2809   gst_value_set_int_range (&range, -7, -6);
2810   fail_unless_equals_int (gst_value_get_int_range_min (&range), -7);
2811   fail_unless_equals_int (gst_value_get_int_range_max (&range), -6);
2812   gst_value_set_int_range (&range, -7, 7);
2813   fail_unless_equals_int (gst_value_get_int_range_min (&range), -7);
2814   fail_unless_equals_int (gst_value_get_int_range_max (&range), 7);
2815 
2816   g_value_unset (&start);
2817   g_value_unset (&end);
2818   g_value_unset (&range);
2819   g_value_unset (&range2);
2820   g_value_unset (&src);
2821 }
2822 
2823 GST_END_TEST;
2824 
GST_START_TEST(test_int64_range)2825 GST_START_TEST (test_int64_range)
2826 {
2827   GValue range = { 0, };
2828   GValue start = { 0, };
2829   GValue end = { 0, };
2830   GValue src = { 0, };
2831   GValue dest = { 0, };
2832   GValue range2 = { 0, };
2833 
2834   g_value_init (&range, GST_TYPE_INT64_RANGE);
2835   g_value_init (&range2, GST_TYPE_INT64_RANGE);
2836   g_value_init (&start, G_TYPE_INT64);
2837   g_value_init (&end, G_TYPE_INT64);
2838   g_value_init (&src, G_TYPE_INT64);
2839 
2840   g_value_set_int64 (&src, 2);
2841 
2842   /* Check that a intersection of int64 & range = int64 */
2843   gst_value_set_int64_range (&range, 1, 5);
2844 
2845   fail_unless (gst_value_intersect (&dest, &src, &range) == TRUE);
2846   fail_unless (G_VALUE_TYPE (&dest) == G_TYPE_INT64);
2847   fail_unless (gst_value_compare (&dest, &src) == GST_VALUE_EQUAL);
2848 
2849   /* Check that a intersection selects the overlapping range */
2850   gst_value_set_int64_range (&range2, 2, 3);
2851   g_value_unset (&dest);
2852   fail_unless (gst_value_intersect (&dest, &range, &range2) == TRUE);
2853   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
2854 
2855   fail_unless (gst_value_compare (&dest, &range2) == GST_VALUE_EQUAL);
2856 
2857   /* Check that non intersection ranges don't intersect */
2858   gst_value_set_int64_range (&range2, 6, 7);
2859   g_value_unset (&dest);
2860   fail_unless (gst_value_intersect (&dest, &range, &range2) == FALSE);
2861 
2862   g_value_unset (&start);
2863   g_value_unset (&end);
2864   g_value_unset (&range);
2865   g_value_unset (&range2);
2866   g_value_unset (&src);
2867 }
2868 
2869 GST_END_TEST;
2870 
GST_START_TEST(test_serialize_int64_range)2871 GST_START_TEST (test_serialize_int64_range)
2872 {
2873   int i = 0;
2874 
2875   gint64 int64_ranges[] = {
2876     0, 5,
2877     0, G_MAXINT,
2878     5, G_MAXINT32,
2879     5, G_MAXINT64,
2880   };
2881   gint int64_ranges_size = sizeof (int64_ranges) / sizeof (int64_ranges[0]) / 2;
2882 
2883   gchar *int64_range_strings[] = {
2884     g_strdup ("[ 0, 5 ]"),
2885     g_strdup_printf ("[ 0, %" G_GINT64_FORMAT " ]", (gint64) G_MAXINT),
2886     g_strdup_printf ("[ 5, %" G_GINT64_FORMAT " ]", (gint64) G_MAXINT32),
2887     g_strdup_printf ("[ 5, %" G_GINT64_FORMAT " ]", G_MAXINT64),
2888   };
2889   gint int64_range_strings_size =
2890       sizeof (int64_range_strings) / sizeof (int64_range_strings[0]);
2891 
2892   fail_unless (int64_ranges_size == int64_range_strings_size);
2893 
2894   while (i + 1 < (int64_ranges_size * 2)) {
2895     if ((i + 1) % 2) {
2896       gchar *str;
2897       gchar *str2;
2898       GValue value = { 0 };
2899       const GValue *deserialized_value;
2900       int idx = i / 2;
2901       GstStructure *s;
2902 
2903       g_value_init (&value, GST_TYPE_INT64_RANGE);
2904 
2905       /* check serialization */
2906       gst_value_set_int64_range (&value, int64_ranges[i], int64_ranges[i + 1]);
2907       str = gst_value_serialize (&value);
2908       fail_unless (strcmp (str, int64_range_strings[idx]) == 0);
2909       g_free (int64_range_strings[idx]);
2910       g_value_unset (&value);
2911 
2912       /* now deserialize again to an int64 range */
2913       s = gst_structure_new ("foo/bar", "range", GST_TYPE_INT64_RANGE,
2914           int64_ranges[i], int64_ranges[i + 1], NULL);
2915       deserialized_value = gst_structure_get_value (s, "range");
2916       fail_unless (GST_VALUE_HOLDS_INT64_RANGE (deserialized_value) == TRUE);
2917       str2 = gst_value_serialize (deserialized_value);
2918 
2919       fail_unless (gst_value_get_int64_range_min (deserialized_value) ==
2920           int64_ranges[i]);
2921       fail_unless (gst_value_get_int64_range_max (deserialized_value) ==
2922           int64_ranges[i + 1]);
2923 
2924       gst_structure_free (s);
2925       g_free (str);
2926       g_free (str2);
2927     }
2928     i++;
2929   }
2930 }
2931 
2932 GST_END_TEST;
2933 
GST_START_TEST(test_deserialize_int_range)2934 GST_START_TEST (test_deserialize_int_range)
2935 {
2936   GstStructure *s;
2937   gchar *str, *str2;
2938   gchar *end = NULL;
2939   const GValue *deserialized_value;
2940 
2941   /* check a valid int_range deserialization */
2942   str = g_strdup_printf ("foo/bar, range=[ 1, %d ];", G_MAXINT);
2943   s = gst_structure_from_string (str, &end);
2944   fail_unless (*end == '\0');
2945   deserialized_value = gst_structure_get_value (s, "range");
2946   fail_unless (GST_VALUE_HOLDS_INT_RANGE (deserialized_value) == TRUE);
2947   fail_unless (gst_value_get_int_range_min (deserialized_value) == 1);
2948   fail_unless (gst_value_get_int_range_max (deserialized_value) == G_MAXINT);
2949   gst_structure_free (s);
2950   end = NULL;
2951   g_free (str);
2952 
2953   /* check invalid int_range deserialization */
2954   str =
2955       g_strdup_printf ("foo/bar, range=[ 1, %" G_GINT64_FORMAT " ];",
2956       (gint64) G_MAXINT + 1);
2957   s = NULL;
2958   ASSERT_CRITICAL (s = gst_structure_from_string (str, &end));
2959   g_free (str);
2960   if (s)
2961     gst_structure_free (s);
2962   str =
2963       g_strdup_printf ("foo/bar, range=[ %" G_GINT64_FORMAT ", %"
2964       G_GINT64_FORMAT " ];", (gint64) G_MAXINT, (gint64) G_MAXINT + 1);
2965   ASSERT_CRITICAL (s = gst_structure_from_string (str, NULL));
2966   end = NULL;
2967   g_free (str);
2968   if (s)
2969     gst_structure_free (s);
2970 
2971   /* check a valid int64_range deserialization. Those ranges need to
2972    * be explicit about their storage type. */
2973   str = g_strdup_printf ("foo/bar, range=(gint64)[ 1, %d ];", G_MAXINT);
2974   s = gst_structure_from_string (str, &end);
2975   fail_unless (*end == '\0');
2976   deserialized_value = gst_structure_get_value (s, "range");
2977   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (deserialized_value) == TRUE);
2978   fail_unless (gst_value_get_int64_range_min (deserialized_value) == 1);
2979   fail_unless (gst_value_get_int64_range_max (deserialized_value) == G_MAXINT);
2980   str2 = gst_structure_to_string (s);
2981   fail_unless (strcmp (str, str2) == 0);
2982   gst_structure_free (s);
2983   end = NULL;
2984   g_free (str);
2985   g_free (str2);
2986 
2987   /* check invalid int64_range (starting with a gint) deserialization */
2988   str =
2989       g_strdup_printf ("foo/bar, range=(gint64)[ 1, %" G_GUINT64_FORMAT " ];",
2990       (guint64) G_MAXINT64 + 1);
2991   s = NULL;
2992   ASSERT_CRITICAL (s = gst_structure_from_string (str, &end));
2993   if (s) {
2994     fail_unless (*end == '\0');
2995     gst_structure_free (s);
2996     end = NULL;
2997   }
2998   g_free (str);
2999 
3000   /* check invalid int64_range deserialization into a int64_range */
3001   str =
3002       g_strdup_printf ("foo/bar, range=(gint64)[ %" G_GINT64_FORMAT ", %"
3003       G_GUINT64_FORMAT " ];", (gint64) G_MAXINT, (guint64) G_MAXINT64 + 1);
3004   ASSERT_CRITICAL (s = gst_structure_from_string (str, NULL));
3005   g_free (str);
3006   if (s)
3007     gst_structure_free (s);
3008 
3009   /* check invalid int64_range deserialization into a int_range */
3010   str =
3011       g_strdup_printf ("foo/bar, range=[ %" G_GINT64_FORMAT ", %"
3012       G_GUINT64_FORMAT " ];", (gint64) G_MAXINT, (guint64) G_MAXINT64 + 1);
3013   s = gst_structure_from_string (str, &end);
3014   fail_unless (s == NULL);
3015   fail_unless (end == NULL);
3016   g_free (str);
3017 }
3018 
3019 GST_END_TEST;
3020 
GST_START_TEST(test_stepped_range_collection)3021 GST_START_TEST (test_stepped_range_collection)
3022 {
3023   GstStructure *s;
3024   const GValue *v;
3025 
3026   s = gst_structure_new ("foo/bar", "range", GST_TYPE_INT_RANGE, 8, 12, NULL);
3027   fail_unless (s != NULL);
3028   v = gst_structure_get_value (s, "range");
3029   fail_unless (v != NULL);
3030   fail_unless (gst_value_get_int_range_min (v) == 8);
3031   fail_unless (gst_value_get_int_range_max (v) == 12);
3032   fail_unless (gst_value_get_int_range_step (v) == 1);
3033   gst_structure_free (s);
3034 
3035   s = gst_structure_new ("foo/bar", "range", GST_TYPE_INT64_RANGE, (gint64) 8,
3036       (gint64) 12, NULL);
3037   fail_unless (s != NULL);
3038   v = gst_structure_get_value (s, "range");
3039   fail_unless (v != NULL);
3040   fail_unless (gst_value_get_int64_range_min (v) == 8);
3041   fail_unless (gst_value_get_int64_range_max (v) == 12);
3042   fail_unless (gst_value_get_int64_range_step (v) == 1);
3043   gst_structure_free (s);
3044 }
3045 
3046 GST_END_TEST;
3047 
GST_START_TEST(test_stepped_int_range_parsing)3048 GST_START_TEST (test_stepped_int_range_parsing)
3049 {
3050   gchar *str;
3051   guint n;
3052   gchar *end = NULL;
3053   GstStructure *s;
3054 
3055   static const gchar *good_ranges[] = {
3056     "[0, 1, 1]",
3057     "[-2, 2, 2]",
3058     "[16, 4096, 16]",
3059   };
3060 
3061   static const gchar *bad_ranges[] = {
3062     "[0, 1, -1]",
3063     "[1, 2, 2]",
3064     "[2, 3, 2]",
3065     "[0, 0, 0]",
3066   };
3067 
3068   /* check we can parse good ranges */
3069   for (n = 0; n < G_N_ELEMENTS (good_ranges); ++n) {
3070     str = g_strdup_printf ("foo/bar, range=%s", good_ranges[n]);
3071     s = gst_structure_from_string (str, &end);
3072     fail_unless (s != NULL);
3073     fail_unless (*end == '\0');
3074     gst_structure_free (s);
3075     s = NULL;
3076     g_free (str);
3077   }
3078 
3079   /* check we cannot parse bad ranges */
3080   for (n = 0; n < G_N_ELEMENTS (bad_ranges); ++n) {
3081     str = g_strdup_printf ("foo/bar, range=%s", bad_ranges[n]);
3082     ASSERT_CRITICAL (s = gst_structure_from_string (str, &end));
3083     if (s)
3084       gst_structure_free (s);
3085     g_free (str);
3086   }
3087 }
3088 
3089 GST_END_TEST;
3090 
GST_START_TEST(test_stepped_int_range_ops)3091 GST_START_TEST (test_stepped_int_range_ops)
3092 {
3093   gchar *str1, *str2, *str3;
3094   guint n;
3095   GstStructure *s1, *s2, *s3;
3096   const GValue *v1, *v2, *v3;
3097 
3098   static const struct
3099   {
3100     const gchar *set1;
3101     const gchar *op;
3102     const gchar *set2;
3103     const gchar *result;
3104   } ranges[] = {
3105     {
3106     "[16, 4096, 16]", "inter", "[100, 200, 10]", "160"}, {
3107     "[16, 4096, 16]", "inter", "[100, 200, 100]", NULL}, {
3108     "[16, 4096, 16]", "inter", "[0, 512, 256]", "[256, 512, 256]"}, {
3109     "[16, 32, 16]", "union", "[32, 96, 16]", "[16, 96, 16]"}, {
3110     "[16, 32, 16]", "union", "[48, 96, 16]", "[16, 96, 16]"}, {
3111     "[112, 192, 16]", "union", "[48, 96, 16]", "[48, 192, 16]"}, {
3112     "[16, 32, 16]", "union", "[64, 96, 16]", NULL}, {
3113     "[112, 192, 16]", "union", "[48, 96, 8]", NULL}, {
3114     "[10, 20, 5]", "union", "10", "[10, 20, 5]"}, {
3115     "[10, 20, 5]", "union", "20", "[10, 20, 5]"}, {
3116     "[10, 20, 5]", "union", "15", "[10, 20, 5]"}, {
3117     "[10, 20, 5]", "union", "5", "[5, 20, 5]"}, {
3118     "[10, 20, 5]", "union", "12", NULL}, {
3119     "[10, 20, 5]", "union", "30", NULL}, {
3120   "[10, 20, 5]", "union", "25", "[10, 25, 5]"},};
3121 
3122   for (n = 0; n < G_N_ELEMENTS (ranges); ++n) {
3123     gchar *end = NULL;
3124     GValue dest = { 0 };
3125     gboolean ret;
3126 
3127     str1 = g_strdup_printf ("foo/bar, range=%s", ranges[n].set1);
3128     s1 = gst_structure_from_string (str1, &end);
3129     fail_unless (s1 != NULL);
3130     fail_unless (*end == '\0');
3131     v1 = gst_structure_get_value (s1, "range");
3132     fail_unless (v1 != NULL);
3133 
3134     str2 = g_strdup_printf ("foo/bar, range=%s", ranges[n].set2);
3135     s2 = gst_structure_from_string (str2, &end);
3136     fail_unless (s2 != NULL);
3137     fail_unless (*end == '\0');
3138     v2 = gst_structure_get_value (s2, "range");
3139     fail_unless (v2 != NULL);
3140 
3141     if (!strcmp (ranges[n].op, "inter")) {
3142       ret = gst_value_intersect (&dest, v1, v2);
3143     } else if (!strcmp (ranges[n].op, "union")) {
3144       ret = gst_value_union (&dest, v1, v2);
3145     } else {
3146       fail_unless (FALSE);
3147       ret = FALSE;
3148     }
3149 
3150     if (ranges[n].result) {
3151       fail_unless (ret);
3152     } else {
3153       fail_unless (!ret);
3154     }
3155 
3156     if (ret) {
3157       str3 = g_strdup_printf ("foo/bar, range=%s", ranges[n].result);
3158       s3 = gst_structure_from_string (str3, &end);
3159       fail_unless (s3 != NULL);
3160       fail_unless (*end == '\0');
3161       v3 = gst_structure_get_value (s3, "range");
3162       fail_unless (v3 != NULL);
3163 
3164       if (gst_value_compare (&dest, v3) != GST_VALUE_EQUAL) {
3165         GST_ERROR ("%s %s %s yielded %s, expected %s", str1, ranges[n].op, str2,
3166             gst_value_serialize (&dest), gst_value_serialize (v3));
3167         fail_unless (FALSE);
3168       }
3169 
3170       gst_structure_free (s3);
3171       g_free (str3);
3172 
3173       g_value_unset (&dest);
3174     }
3175 
3176     gst_structure_free (s2);
3177     g_free (str2);
3178     gst_structure_free (s1);
3179     g_free (str1);
3180   }
3181 }
3182 
3183 GST_END_TEST;
3184 
GST_START_TEST(test_structure_basic)3185 GST_START_TEST (test_structure_basic)
3186 {
3187   GstStructure *s1, *s2;
3188   GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT;
3189 
3190   /* sanity test */
3191   s1 = gst_structure_from_string ("foo,bar=1", NULL);
3192   g_value_init (&v1, GST_TYPE_STRUCTURE);
3193   gst_value_set_structure (&v1, s1);
3194   fail_unless (gst_structure_is_equal (s1, gst_value_get_structure (&v1)));
3195 
3196   s2 = gst_structure_copy (s1);
3197   g_value_init (&v2, GST_TYPE_STRUCTURE);
3198   gst_value_set_structure (&v2, s2);
3199 
3200   /* can do everything but subtract */
3201   fail_unless (gst_value_can_compare (&v1, &v2));
3202   fail_unless (gst_value_can_intersect (&v1, &v2));
3203   fail_unless (!gst_value_can_subtract (&v1, &v2));
3204   fail_unless (gst_value_can_union (&v1, &v2));
3205 
3206   gst_structure_free (s1);
3207   gst_structure_free (s2);
3208   g_value_unset (&v1);
3209   g_value_unset (&v2);
3210 }
3211 
3212 GST_END_TEST;
3213 
GST_START_TEST(test_structure_single_ops)3214 GST_START_TEST (test_structure_single_ops)
3215 {
3216   static const struct
3217   {
3218     const gchar *str1;
3219     gboolean is_fixed;
3220     gboolean can_fixate;
3221   } single_struct[] = {
3222     {
3223     "foo,bar=(int)1", TRUE, TRUE}, {
3224   "foo,bar=(int)[1,2]", FALSE, TRUE},};
3225   gint i;
3226 
3227   for (i = 0; i < G_N_ELEMENTS (single_struct); i++) {
3228     GstStructure *s1 = gst_structure_from_string (single_struct[i].str1, NULL);
3229     GValue v1 = G_VALUE_INIT;
3230     GValue v2 = G_VALUE_INIT;
3231 
3232     fail_unless (s1 != NULL);
3233 
3234     GST_DEBUG ("checking structure %" GST_PTR_FORMAT, s1);
3235 
3236     g_value_init (&v1, GST_TYPE_STRUCTURE);
3237     gst_value_set_structure (&v1, s1);
3238 
3239     fail_unless (gst_value_is_fixed (&v1) == single_struct[i].is_fixed);
3240     fail_unless (gst_value_fixate (&v2, &v1) == single_struct[i].can_fixate);
3241     if (single_struct[i].can_fixate)
3242       g_value_unset (&v2);
3243 
3244     g_value_unset (&v1);
3245     gst_structure_free (s1);
3246   }
3247 }
3248 
3249 GST_END_TEST;
3250 
GST_START_TEST(test_structure_ops)3251 GST_START_TEST (test_structure_ops)
3252 {
3253   struct
3254   {
3255     const gchar *str1;
3256     const gchar *str2;
3257     const gchar *op;
3258     gint ret;
3259     GType str_type;
3260     const gchar *str_result;
3261   } comparisons[] = {
3262     /* *INDENT-OFF* */
3263     {"foo,bar=(int)1", "foo,bar=(int)1", "compare", GST_VALUE_EQUAL, 0, NULL},
3264     {"foo,bar=(int)1", "foo,bar=(int)1", "is_subset", TRUE, 0, NULL},
3265     {"foo,bar=(int)1", "foo,bar=(int)1", "intersect", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)1"},
3266     {"foo,bar=(int)1", "foo,bar=(int)1", "union", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)1"},
3267     {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "compare", GST_VALUE_UNORDERED, 0, NULL},
3268     {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "is_subset", FALSE, 0, NULL},
3269     {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "intersect", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)1"},
3270     {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "union", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)[1,2]"},
3271     {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "compare", GST_VALUE_UNORDERED, 0, NULL},
3272     {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "is_subset", TRUE, 0, NULL},
3273     {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "intersect", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)1"},
3274     {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "union", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)[1,2]"},
3275     {"foo,bar=(int)1", "foo,bar=(int)2", "compare", GST_VALUE_UNORDERED, 0, NULL},
3276     {"foo,bar=(int)1", "foo,bar=(int)2", "is_subset", FALSE, 0, NULL},
3277     {"foo,bar=(int)1", "foo,bar=(int)2", "intersect", FALSE, 0, NULL},
3278     {"foo,bar=(int)1", "foo,bar=(int)2", "union", TRUE, GST_TYPE_STRUCTURE, "foo,bar=(int)[1,2]"},
3279     {"foo,bar=(int)1", "baz,bar=(int)1", "compare", GST_VALUE_UNORDERED, 0, NULL},
3280     {"foo,bar=(int)1", "baz,bar=(int)1", "is_subset", FALSE, 0, NULL},
3281     {"foo,bar=(int)1", "baz,bar=(int)1", "intersect", FALSE, 0, NULL},
3282 #if 0
3283     /* deserializing lists is not implemented (but this should still work!) */
3284     {"foo,bar=(int)1", "baz,bar=(int)1", "union", TRUE, G_TYPE_LIST, "{foo,bar=(int)1;, baz,bar=(int)1;}"},
3285 #endif
3286     /* *INDENT-ON* */
3287   };
3288   gint i;
3289 
3290   for (i = 0; i < G_N_ELEMENTS (comparisons); i++) {
3291     GstStructure *s1 = gst_structure_from_string (comparisons[i].str1, NULL);
3292     GstStructure *s2 = gst_structure_from_string (comparisons[i].str2, NULL);
3293     GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT, v3 = G_VALUE_INIT;
3294 
3295     fail_unless (s1 != NULL);
3296     fail_unless (s2 != NULL);
3297 
3298     GST_DEBUG ("checking %s with structure1 %" GST_PTR_FORMAT " structure2 %"
3299         GST_PTR_FORMAT " is %d, %s", comparisons[i].op, s1, s2,
3300         comparisons[i].ret, comparisons[i].str_result);
3301 
3302     g_value_init (&v1, GST_TYPE_STRUCTURE);
3303     gst_value_set_structure (&v1, s1);
3304     g_value_init (&v2, GST_TYPE_STRUCTURE);
3305     gst_value_set_structure (&v2, s2);
3306 
3307     if (g_strcmp0 (comparisons[i].op, "compare") == 0) {
3308       fail_unless (gst_value_compare (&v1, &v2) == comparisons[i].ret);
3309     } else if (g_strcmp0 (comparisons[i].op, "is_subset") == 0) {
3310       fail_unless (gst_value_is_subset (&v1, &v2) == comparisons[i].ret);
3311     } else {
3312       if (g_strcmp0 (comparisons[i].op, "intersect") == 0) {
3313         fail_unless (gst_value_intersect (&v3, &v1, &v2) == comparisons[i].ret);
3314       } else if (g_strcmp0 (comparisons[i].op, "union") == 0) {
3315         fail_unless (gst_value_union (&v3, &v1, &v2) == comparisons[i].ret);
3316       }
3317       if (comparisons[i].ret) {
3318         GValue result = G_VALUE_INIT;
3319         gchar *str;
3320 
3321         str = gst_value_serialize (&v3);
3322         GST_LOG ("result %s", str);
3323         g_free (str);
3324 
3325         g_value_init (&result, comparisons[i].str_type);
3326         fail_unless (gst_value_deserialize (&result,
3327                 comparisons[i].str_result));
3328         fail_unless (gst_value_compare (&result, &v3) == GST_VALUE_EQUAL);
3329         g_value_unset (&v3);
3330         g_value_unset (&result);
3331       }
3332     }
3333 
3334     gst_structure_free (s1);
3335     gst_structure_free (s2);
3336     g_value_unset (&v1);
3337     g_value_unset (&v2);
3338   }
3339 }
3340 
3341 GST_END_TEST;
3342 
3343 static void
setup_test_value_array(GValue * value)3344 setup_test_value_array (GValue * value)
3345 {
3346   GValueArray *array;
3347   GValue v = G_VALUE_INIT;
3348 
3349   g_value_init (&v, G_TYPE_INT);
3350   g_value_init (value, G_TYPE_VALUE_ARRAY);
3351 
3352   array = g_value_array_new (3);
3353   g_value_set_int (&v, 1);
3354   g_value_array_append (array, &v);
3355   g_value_set_int (&v, 2);
3356   g_value_array_append (array, &v);
3357   g_value_set_int (&v, 3);
3358   g_value_array_append (array, &v);
3359 
3360   g_value_take_boxed (value, array);
3361 }
3362 
3363 static void
test_revert_array_transform(GValue * v1,GValue * v2)3364 test_revert_array_transform (GValue * v1, GValue * v2)
3365 {
3366   GValueArray *array;
3367 
3368   g_value_reset (v1);
3369 
3370   fail_unless (g_value_transform (v2, v1));
3371   array = g_value_get_boxed (v1);
3372   fail_unless (array->n_values == 3);
3373   fail_unless (g_value_get_int (g_value_array_get_nth (array, 0)) == 1);
3374   fail_unless (g_value_get_int (g_value_array_get_nth (array, 1)) == 2);
3375   fail_unless (g_value_get_int (g_value_array_get_nth (array, 2)) == 3);
3376 }
3377 
GST_START_TEST(test_transform_array)3378 GST_START_TEST (test_transform_array)
3379 {
3380   GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT;
3381 
3382   setup_test_value_array (&v1);
3383 
3384   g_value_init (&v2, GST_TYPE_ARRAY);
3385 
3386   fail_unless (g_value_transform (&v1, &v2));
3387   fail_unless (gst_value_array_get_size (&v2) == 3);
3388   fail_unless (g_value_get_int (gst_value_array_get_value (&v2, 0)) == 1);
3389   fail_unless (g_value_get_int (gst_value_array_get_value (&v2, 1)) == 2);
3390   fail_unless (g_value_get_int (gst_value_array_get_value (&v2, 2)) == 3);
3391 
3392   test_revert_array_transform (&v1, &v2);
3393 
3394   g_value_unset (&v1);
3395   g_value_unset (&v2);
3396 }
3397 
3398 GST_END_TEST;
3399 
GST_START_TEST(test_transform_list)3400 GST_START_TEST (test_transform_list)
3401 {
3402   GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT;
3403 
3404   setup_test_value_array (&v1);
3405 
3406   g_value_init (&v2, GST_TYPE_LIST);
3407 
3408   fail_unless (g_value_transform (&v1, &v2));
3409   fail_unless (gst_value_list_get_size (&v2) == 3);
3410   fail_unless (g_value_get_int (gst_value_list_get_value (&v2, 0)) == 1);
3411   fail_unless (g_value_get_int (gst_value_list_get_value (&v2, 1)) == 2);
3412   fail_unless (g_value_get_int (gst_value_list_get_value (&v2, 2)) == 3);
3413 
3414   test_revert_array_transform (&v1, &v2);
3415 
3416   g_value_unset (&v1);
3417   g_value_unset (&v2);
3418 }
3419 
3420 GST_END_TEST;
3421 
GST_START_TEST(test_serialize_null_aray)3422 GST_START_TEST (test_serialize_null_aray)
3423 {
3424   gchar *serialized;
3425   GValue v = G_VALUE_INIT;
3426 
3427   g_value_init (&v, G_TYPE_VALUE_ARRAY);
3428 
3429   g_value_set_boxed (&v, NULL);
3430   serialized = gst_value_serialize (&v);
3431   fail_unless_equals_string (serialized, "<  >");
3432   g_value_unset (&v);
3433   g_free (serialized);
3434 }
3435 
3436 GST_END_TEST;
3437 
3438 static Suite *
gst_value_suite(void)3439 gst_value_suite (void)
3440 {
3441   Suite *s = suite_create ("GstValue");
3442   TCase *tc_chain = tcase_create ("general");
3443 
3444   suite_add_tcase (s, tc_chain);
3445   tcase_add_test (tc_chain, test_deserialize_buffer);
3446   tcase_add_test (tc_chain, test_serialize_buffer);
3447   tcase_add_test (tc_chain, test_deserialize_gint);
3448   tcase_add_test (tc_chain, test_deserialize_gint_failures);
3449   tcase_add_test (tc_chain, test_deserialize_guint);
3450   tcase_add_test (tc_chain, test_deserialize_guint_failures);
3451   tcase_add_test (tc_chain, test_deserialize_gint64);
3452   tcase_add_test (tc_chain, test_deserialize_guint64);
3453   tcase_add_test (tc_chain, test_deserialize_guchar);
3454   tcase_add_test (tc_chain, test_deserialize_gstfraction);
3455   tcase_add_test (tc_chain, test_deserialize_gtype);
3456   tcase_add_test (tc_chain, test_deserialize_gtype_failures);
3457   tcase_add_test (tc_chain, test_deserialize_bitmask);
3458   tcase_add_test (tc_chain, test_serialize_flags);
3459   tcase_add_test (tc_chain, test_deserialize_flags);
3460   tcase_add_test (tc_chain, test_serialize_deserialize_format_enum);
3461   tcase_add_test (tc_chain, test_serialize_deserialize_value_array);
3462   tcase_add_test (tc_chain, test_string);
3463   tcase_add_test (tc_chain, test_deserialize_string);
3464   tcase_add_test (tc_chain, test_value_compare);
3465   tcase_add_test (tc_chain, test_value_intersect);
3466   tcase_add_test (tc_chain, test_value_subtract_int);
3467   tcase_add_test (tc_chain, test_value_subtract_int64);
3468   tcase_add_test (tc_chain, test_value_subtract_double);
3469   tcase_add_test (tc_chain, test_value_subtract_fraction);
3470   tcase_add_test (tc_chain, test_value_subtract_fraction_range);
3471   tcase_add_test (tc_chain, test_value_subtract_fraction_list);
3472   tcase_add_test (tc_chain, test_date);
3473   tcase_add_test (tc_chain, test_date_time);
3474   tcase_add_test (tc_chain, test_fraction_range);
3475   tcase_add_test (tc_chain, test_serialize_deserialize_caps);
3476   tcase_add_test (tc_chain, test_int_range);
3477   tcase_add_test (tc_chain, test_int64_range);
3478   tcase_add_test (tc_chain, test_serialize_int64_range);
3479   tcase_add_test (tc_chain, test_deserialize_int_range);
3480   tcase_add_test (tc_chain, test_stepped_range_collection);
3481   tcase_add_test (tc_chain, test_stepped_int_range_parsing);
3482   tcase_add_test (tc_chain, test_stepped_int_range_ops);
3483   tcase_add_test (tc_chain, test_flagset);
3484   tcase_add_test (tc_chain, test_structure_basic);
3485   tcase_add_test (tc_chain, test_structure_single_ops);
3486   tcase_add_test (tc_chain, test_structure_ops);
3487   tcase_add_test (tc_chain, test_transform_array);
3488   tcase_add_test (tc_chain, test_transform_list);
3489   tcase_add_test (tc_chain, test_serialize_null_aray);
3490 
3491   return s;
3492 }
3493 
3494 GST_CHECK_MAIN (gst_value);
3495