spec: Remove kdbus-extension packages for _with_da_profile
[platform/upstream/glib.git] / gio / gsettings-mapping.c
1 /*
2  * Copyright © 2010 Novell, Inc.
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  *
19  * Author: Vincent Untz <vuntz@gnome.org>
20  */
21
22 #include "config.h"
23
24 #include "gsettings-mapping.h"
25
26 static GVariant *
27 g_settings_set_mapping_int (const GValue       *value,
28                             const GVariantType *expected_type)
29 {
30   GVariant *variant = NULL;
31   gint64 l;
32
33   if (G_VALUE_HOLDS_INT (value))
34     l = g_value_get_int (value);
35   else if (G_VALUE_HOLDS_INT64 (value))
36     l = g_value_get_int64 (value);
37   else
38     return NULL;
39
40   if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
41     {
42       if (G_MININT16 <= l && l <= G_MAXINT16)
43         variant = g_variant_new_int16 ((gint16) l);
44     }
45   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
46     {
47       if (0 <= l && l <= G_MAXUINT16)
48         variant = g_variant_new_uint16 ((guint16) l);
49     }
50   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
51     {
52       if (G_MININT32 <= l && l <= G_MAXINT32)
53         variant = g_variant_new_int32 ((gint) l);
54     }
55   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
56     {
57       if (0 <= l && l <= G_MAXUINT32)
58         variant = g_variant_new_uint32 ((guint) l);
59     }
60   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
61     {
62       if (G_MININT64 <= l && l <= G_MAXINT64)
63         variant = g_variant_new_int64 ((gint64) l);
64     }
65   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
66     {
67       if (0 <= l && (guint64) l <= G_MAXUINT64)
68         variant = g_variant_new_uint64 ((guint64) l);
69     }
70   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
71     {
72       if (0 <= l && l <= G_MAXUINT32)
73         variant = g_variant_new_handle ((guint) l);
74     }
75   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
76     variant = g_variant_new_double ((gdouble) l);
77
78   return variant;
79 }
80
81 static GVariant *
82 g_settings_set_mapping_float (const GValue       *value,
83                               const GVariantType *expected_type)
84 {
85   GVariant *variant = NULL;
86   gdouble d;
87   gint64 l;
88
89   if (G_VALUE_HOLDS_DOUBLE (value))
90     d = g_value_get_double (value);
91   else
92     return NULL;
93
94   l = (gint64) d;
95   if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
96     {
97       if (G_MININT16 <= l && l <= G_MAXINT16)
98         variant = g_variant_new_int16 ((gint16) l);
99     }
100   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
101     {
102       if (0 <= l && l <= G_MAXUINT16)
103         variant = g_variant_new_uint16 ((guint16) l);
104     }
105   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
106     {
107       if (G_MININT32 <= l && l <= G_MAXINT32)
108         variant = g_variant_new_int32 ((gint) l);
109     }
110   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
111     {
112       if (0 <= l && l <= G_MAXUINT32)
113         variant = g_variant_new_uint32 ((guint) l);
114     }
115   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
116     {
117       if (G_MININT64 <= l && l <= G_MAXINT64)
118         variant = g_variant_new_int64 ((gint64) l);
119     }
120   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
121     {
122       if (0 <= l && (guint64) l <= G_MAXUINT64)
123         variant = g_variant_new_uint64 ((guint64) l);
124     }
125   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
126     {
127       if (0 <= l && l <= G_MAXUINT32)
128         variant = g_variant_new_handle ((guint) l);
129     }
130   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
131     variant = g_variant_new_double ((gdouble) d);
132
133   return variant;
134 }
135 static GVariant *
136 g_settings_set_mapping_unsigned_int (const GValue       *value,
137                                      const GVariantType *expected_type)
138 {
139   GVariant *variant = NULL;
140   guint64 u;
141
142   if (G_VALUE_HOLDS_UINT (value))
143     u = g_value_get_uint (value);
144   else if (G_VALUE_HOLDS_UINT64 (value))
145     u = g_value_get_uint64 (value);
146   else
147     return NULL;
148
149   if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
150     {
151       if (u <= G_MAXINT16)
152         variant = g_variant_new_int16 ((gint16) u);
153     }
154   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
155     {
156       if (u <= G_MAXUINT16)
157         variant = g_variant_new_uint16 ((guint16) u);
158     }
159   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
160     {
161       if (u <= G_MAXINT32)
162         variant = g_variant_new_int32 ((gint) u);
163     }
164   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
165     {
166       if (u <= G_MAXUINT32)
167         variant = g_variant_new_uint32 ((guint) u);
168     }
169   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
170     {
171       if (u <= G_MAXINT64)
172         variant = g_variant_new_int64 ((gint64) u);
173     }
174   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
175     {
176       if (u <= G_MAXUINT64)
177         variant = g_variant_new_uint64 ((guint64) u);
178     }
179   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
180     {
181       if (u <= G_MAXUINT32)
182         variant = g_variant_new_handle ((guint) u);
183     }
184   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
185     variant = g_variant_new_double ((gdouble) u);
186
187   return variant;
188 }
189
190 static gboolean
191 g_settings_get_mapping_int (GValue   *value,
192                             GVariant *variant)
193 {
194   const GVariantType *type;
195   gint64 l;
196
197   type = g_variant_get_type (variant);
198
199   if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
200     l = g_variant_get_int16 (variant);
201   else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
202     l = g_variant_get_int32 (variant);
203   else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
204     l = g_variant_get_int64 (variant);
205   else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
206     l = g_variant_get_handle (variant);
207   else
208     return FALSE;
209
210   if (G_VALUE_HOLDS_INT (value))
211     {
212       g_value_set_int (value, l);
213       return (G_MININT32 <= l && l <= G_MAXINT32);
214     }
215   else if (G_VALUE_HOLDS_UINT (value))
216     {
217       g_value_set_uint (value, l);
218       return (0 <= l && l <= G_MAXUINT32);
219     }
220   else if (G_VALUE_HOLDS_INT64 (value))
221     {
222       g_value_set_int64 (value, l);
223       return (G_MININT64 <= l && l <= G_MAXINT64);
224     }
225   else if (G_VALUE_HOLDS_UINT64 (value))
226     {
227       g_value_set_uint64 (value, l);
228       return (0 <= l && (guint64) l <= G_MAXUINT64);
229     }
230   else if (G_VALUE_HOLDS_DOUBLE (value))
231     {
232       g_value_set_double (value, l);
233       return TRUE;
234     }
235
236   return FALSE;
237 }
238
239 static gboolean
240 g_settings_get_mapping_float (GValue   *value,
241                               GVariant *variant)
242 {
243   const GVariantType *type;
244   gdouble d;
245   gint64 l;
246
247   type = g_variant_get_type (variant);
248
249   if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
250     d = g_variant_get_double (variant);
251   else
252     return FALSE;
253
254   l = (gint64)d;
255   if (G_VALUE_HOLDS_INT (value))
256     {
257       g_value_set_int (value, l);
258       return (G_MININT32 <= l && l <= G_MAXINT32);
259     }
260   else if (G_VALUE_HOLDS_UINT (value))
261     {
262       g_value_set_uint (value, l);
263       return (0 <= l && l <= G_MAXUINT32);
264     }
265   else if (G_VALUE_HOLDS_INT64 (value))
266     {
267       g_value_set_int64 (value, l);
268       return (G_MININT64 <= l && l <= G_MAXINT64);
269     }
270   else if (G_VALUE_HOLDS_UINT64 (value))
271     {
272       g_value_set_uint64 (value, l);
273       return (0 <= l && (guint64) l <= G_MAXUINT64);
274     }
275   else if (G_VALUE_HOLDS_DOUBLE (value))
276     {
277       g_value_set_double (value, d);
278       return TRUE;
279     }
280
281   return FALSE;
282 }
283 static gboolean
284 g_settings_get_mapping_unsigned_int (GValue   *value,
285                                      GVariant *variant)
286 {
287   const GVariantType *type;
288   guint64 u;
289
290   type = g_variant_get_type (variant);
291
292   if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
293     u = g_variant_get_uint16 (variant);
294   else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
295     u = g_variant_get_uint32 (variant);
296   else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
297     u = g_variant_get_uint64 (variant);
298   else
299     return FALSE;
300
301   if (G_VALUE_HOLDS_INT (value))
302     {
303       g_value_set_int (value, u);
304       return (u <= G_MAXINT32);
305     }
306   else if (G_VALUE_HOLDS_UINT (value))
307     {
308       g_value_set_uint (value, u);
309       return (u <= G_MAXUINT32);
310     }
311   else if (G_VALUE_HOLDS_INT64 (value))
312     {
313       g_value_set_int64 (value, u);
314       return (u <= G_MAXINT64);
315     }
316   else if (G_VALUE_HOLDS_UINT64 (value))
317     {
318       g_value_set_uint64 (value, u);
319       return (u <= G_MAXUINT64);
320     }
321   else if (G_VALUE_HOLDS_DOUBLE (value))
322     {
323       g_value_set_double (value, u);
324       return TRUE;
325     }
326
327   return FALSE;
328 }
329
330 GVariant *
331 g_settings_set_mapping (const GValue       *value,
332                         const GVariantType *expected_type,
333                         gpointer            user_data)
334 {
335   gchar *type_string;
336
337   if (G_VALUE_HOLDS_BOOLEAN (value))
338     {
339       if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BOOLEAN))
340         return g_variant_new_boolean (g_value_get_boolean (value));
341     }
342
343   else if (G_VALUE_HOLDS_CHAR (value)  ||
344            G_VALUE_HOLDS_UCHAR (value))
345     {
346       if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE))
347         {
348           if (G_VALUE_HOLDS_CHAR (value))
349             return g_variant_new_byte (g_value_get_schar (value));
350           else
351             return g_variant_new_byte (g_value_get_uchar (value));
352         }
353     }
354
355   else if (G_VALUE_HOLDS_INT (value)   ||
356            G_VALUE_HOLDS_INT64 (value))
357     return g_settings_set_mapping_int (value, expected_type);
358
359   else if (G_VALUE_HOLDS_DOUBLE (value))
360     return g_settings_set_mapping_float (value, expected_type);
361
362   else if (G_VALUE_HOLDS_UINT (value)  ||
363            G_VALUE_HOLDS_UINT64 (value))
364     return g_settings_set_mapping_unsigned_int (value, expected_type);
365
366   else if (G_VALUE_HOLDS_STRING (value))
367     {
368       if (g_value_get_string (value) == NULL)
369         return NULL;
370       else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING))
371         return g_variant_new_string (g_value_get_string (value));
372       else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTESTRING))
373         return g_variant_new_bytestring (g_value_get_string (value));
374       else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
375         return g_variant_new_object_path (g_value_get_string (value));
376       else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_SIGNATURE))
377         return g_variant_new_signature (g_value_get_string (value));
378     }
379
380   else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
381     {
382       if (g_value_get_boxed (value) == NULL)
383         return NULL;
384       return g_variant_new_strv ((const gchar **) g_value_get_boxed (value),
385                                  -1);
386     }
387
388   else if (G_VALUE_HOLDS_ENUM (value))
389     {
390       GEnumValue *enumval;
391       GEnumClass *eclass;
392
393       /* GParamSpecEnum holds a ref on the class so we just peek... */
394       eclass = g_type_class_peek (G_VALUE_TYPE (value));
395       enumval = g_enum_get_value (eclass, g_value_get_enum (value));
396
397       if (enumval)
398         return g_variant_new_string (enumval->value_nick);
399       else
400         return NULL;
401     }
402
403   else if (G_VALUE_HOLDS_FLAGS (value))
404     {
405       GVariantBuilder builder;
406       GFlagsValue *flagsval;
407       GFlagsClass *fclass;
408       guint flags;
409
410       fclass = g_type_class_peek (G_VALUE_TYPE (value));
411       flags = g_value_get_flags (value);
412
413       g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
414       while (flags)
415         {
416           flagsval = g_flags_get_first_value (fclass, flags);
417
418           if (flagsval == NULL)
419             {
420               g_variant_builder_clear (&builder);
421               return NULL;
422             }
423
424           g_variant_builder_add (&builder, "s", flagsval->value_nick);
425           flags &= ~flagsval->value;
426         }
427
428       return g_variant_builder_end (&builder);
429     }
430
431   type_string = g_variant_type_dup_string (expected_type);
432   g_critical ("No GSettings bind handler for type \"%s\".", type_string);
433   g_free (type_string);
434
435   return NULL;
436 }
437
438 gboolean
439 g_settings_get_mapping (GValue   *value,
440                         GVariant *variant,
441                         gpointer  user_data)
442 {
443   if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
444     {
445       if (!G_VALUE_HOLDS_BOOLEAN (value))
446         return FALSE;
447       g_value_set_boolean (value, g_variant_get_boolean (variant));
448       return TRUE;
449     }
450
451   else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTE))
452     {
453       if (G_VALUE_HOLDS_UCHAR (value))
454         g_value_set_uchar (value, g_variant_get_byte (variant));
455       else if (G_VALUE_HOLDS_CHAR (value))
456         g_value_set_schar (value, (gint8)g_variant_get_byte (variant));
457       else
458         return FALSE;
459       return TRUE;
460     }
461
462   else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT16)  ||
463            g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32)  ||
464            g_variant_is_of_type (variant, G_VARIANT_TYPE_INT64)  ||
465            g_variant_is_of_type (variant, G_VARIANT_TYPE_HANDLE))
466     return g_settings_get_mapping_int (value, variant);
467
468   else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE))
469     return g_settings_get_mapping_float (value, variant);
470
471   else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT16) ||
472            g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32) ||
473            g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT64))
474     return g_settings_get_mapping_unsigned_int (value, variant);
475
476   else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)      ||
477            g_variant_is_of_type (variant, G_VARIANT_TYPE_OBJECT_PATH) ||
478            g_variant_is_of_type (variant, G_VARIANT_TYPE_SIGNATURE))
479     {
480       if (G_VALUE_HOLDS_STRING (value))
481         {
482           g_value_set_string (value, g_variant_get_string (variant, NULL));
483           return TRUE;
484         }
485
486       else if (G_VALUE_HOLDS_ENUM (value))
487         {
488           GEnumClass *eclass;
489           GEnumValue *evalue;
490           const gchar *nick;
491
492           /* GParamSpecEnum holds a ref on the class so we just peek... */
493           eclass = g_type_class_peek (G_VALUE_TYPE (value));
494           nick = g_variant_get_string (variant, NULL);
495           evalue = g_enum_get_value_by_nick (eclass, nick);
496
497           if (evalue)
498             {
499              g_value_set_enum (value, evalue->value);
500              return TRUE;
501             }
502
503           g_warning ("Unable to look up enum nick ‘%s’ via GType", nick);
504           return FALSE;
505         }
506     }
507   else if (g_variant_is_of_type (variant, G_VARIANT_TYPE ("as")))
508     {
509       if (G_VALUE_HOLDS (value, G_TYPE_STRV))
510         {
511           g_value_take_boxed (value, g_variant_dup_strv (variant, NULL));
512           return TRUE;
513         }
514
515       else if (G_VALUE_HOLDS_FLAGS (value))
516         {
517           GFlagsClass *fclass;
518           GFlagsValue *fvalue;
519           const gchar *nick;
520           GVariantIter iter;
521           guint flags = 0;
522
523           fclass = g_type_class_peek (G_VALUE_TYPE (value));
524
525           g_variant_iter_init (&iter, variant);
526           while (g_variant_iter_next (&iter, "&s", &nick))
527             {
528               fvalue = g_flags_get_value_by_nick (fclass, nick);
529
530               if (fvalue)
531                 flags |= fvalue->value;
532
533               else
534                 {
535                   g_warning ("Unable to lookup flags nick '%s' via GType",
536                              nick);
537                   return FALSE;
538                 }
539             }
540
541           g_value_set_flags (value, flags);
542           return TRUE;
543         }
544     }
545   else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTESTRING))
546     {
547       g_value_set_string (value, g_variant_get_bytestring (variant));
548       return TRUE;
549     }
550
551   g_critical ("No GSettings bind handler for type \"%s\".",
552               g_variant_get_type_string (variant));
553
554   return FALSE;
555 }
556
557 gboolean
558 g_settings_mapping_is_compatible (GType               gvalue_type,
559                                   const GVariantType *variant_type)
560 {
561   gboolean ok = FALSE;
562
563   if (gvalue_type == G_TYPE_BOOLEAN)
564     ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BOOLEAN);
565   else if (gvalue_type == G_TYPE_CHAR  ||
566            gvalue_type == G_TYPE_UCHAR)
567     ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BYTE);
568   else if (gvalue_type == G_TYPE_INT    ||
569            gvalue_type == G_TYPE_UINT   ||
570            gvalue_type == G_TYPE_INT64  ||
571            gvalue_type == G_TYPE_UINT64 ||
572            gvalue_type == G_TYPE_DOUBLE)
573     ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT16)  ||
574           g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT16) ||
575           g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT32)  ||
576           g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT32) ||
577           g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT64)  ||
578           g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT64) ||
579           g_variant_type_equal (variant_type, G_VARIANT_TYPE_HANDLE) ||
580           g_variant_type_equal (variant_type, G_VARIANT_TYPE_DOUBLE));
581   else if (gvalue_type == G_TYPE_STRING)
582     ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING)      ||
583           g_variant_type_equal (variant_type, G_VARIANT_TYPE ("ay")) ||
584           g_variant_type_equal (variant_type, G_VARIANT_TYPE_OBJECT_PATH) ||
585           g_variant_type_equal (variant_type, G_VARIANT_TYPE_SIGNATURE));
586   else if (gvalue_type == G_TYPE_STRV)
587     ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE ("as"));
588   else if (G_TYPE_IS_ENUM (gvalue_type))
589     ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING);
590   else if (G_TYPE_IS_FLAGS (gvalue_type))
591     ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE ("as"));
592
593   return ok;
594 }