Coverage Report

Created: 2025-08-29 06:48

/src/json-glib/json-glib/json-value.c
Line
Count
Source (jump to first uncovered line)
1
/* json-value.c - JSON value container
2
 * 
3
 * This file is part of JSON-GLib
4
 * Copyright (C) 2012  Emmanuele Bassi <ebassi@gnome.org>
5
 * Copyright (C) 2015 Collabora Ltd.
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 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
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 * Author:
21
 *   Emmanuele Bassi  <ebassi@linux.intel.com>
22
 *   Philip Withnall  <philip.withnall@collabora.co.uk>
23
 */
24
25
#include "config.h"
26
27
#include <glib.h>
28
29
#include "json-types-private.h"
30
31
const gchar *
32
json_value_type_get_name (JsonValueType value_type)
33
0
{
34
0
  switch (value_type)
35
0
    {
36
0
    case JSON_VALUE_INVALID:
37
0
      return "Unset";
38
39
0
    case JSON_VALUE_INT:
40
0
      return "Integer";
41
42
0
    case JSON_VALUE_DOUBLE:
43
0
      return "Floating Point";
44
45
0
    case JSON_VALUE_BOOLEAN:
46
0
      return "Boolean";
47
48
0
    case JSON_VALUE_STRING:
49
0
      return "String";
50
51
0
    case JSON_VALUE_NULL:
52
0
      return "Null";
53
0
    }
54
55
0
  return "Undefined";
56
0
}
57
58
GType
59
json_value_type (const JsonValue *value)
60
0
{
61
0
  switch (value->type)
62
0
    {
63
0
    case JSON_VALUE_INVALID:
64
0
      return G_TYPE_INVALID;
65
66
0
    case JSON_VALUE_INT:
67
0
      return G_TYPE_INT64;
68
69
0
    case JSON_VALUE_DOUBLE:
70
0
      return G_TYPE_DOUBLE;
71
72
0
    case JSON_VALUE_BOOLEAN:
73
0
      return G_TYPE_BOOLEAN;
74
75
0
    case JSON_VALUE_STRING:
76
0
      return G_TYPE_STRING;
77
78
0
    case JSON_VALUE_NULL:
79
0
      return G_TYPE_INVALID;
80
0
    }
81
82
0
  return G_TYPE_INVALID;
83
0
}
84
85
JsonValue *
86
json_value_alloc (void)
87
0
{
88
0
  JsonValue *res = g_slice_new0 (JsonValue);
89
90
0
  res->ref_count = 1;
91
92
0
  return res;
93
0
}
94
95
JsonValue *
96
json_value_init (JsonValue     *value,
97
                 JsonValueType  value_type)
98
0
{
99
0
  g_return_val_if_fail (value != NULL, NULL);
100
101
0
  if (value->type != JSON_VALUE_INVALID)
102
0
    json_value_unset (value);
103
104
0
  value->type = value_type;
105
106
0
  return value;
107
0
}
108
109
JsonValue *
110
json_value_ref (JsonValue *value)
111
0
{
112
0
  g_return_val_if_fail (value != NULL, NULL);
113
114
0
  value->ref_count++;
115
116
0
  return value;
117
0
}
118
119
void
120
json_value_unref (JsonValue *value)
121
0
{
122
0
  g_return_if_fail (value != NULL);
123
124
0
  if (--value->ref_count == 0)
125
0
    json_value_free (value);
126
0
}
127
128
void
129
json_value_unset (JsonValue *value)
130
0
{
131
0
  g_return_if_fail (value != NULL);
132
133
0
  switch (value->type)
134
0
    {
135
0
    case JSON_VALUE_INVALID:
136
0
      break;
137
138
0
    case JSON_VALUE_INT:
139
0
      value->data.v_int = 0;
140
0
      break;
141
142
0
    case JSON_VALUE_DOUBLE:
143
0
      value->data.v_double = 0.0;
144
0
      break;
145
146
0
    case JSON_VALUE_BOOLEAN:
147
0
      value->data.v_bool = FALSE;
148
0
      break;
149
150
0
    case JSON_VALUE_STRING:
151
0
      g_free (value->data.v_str);
152
0
      value->data.v_str = NULL;
153
0
      break;
154
155
0
    case JSON_VALUE_NULL:
156
0
      break;
157
0
    }
158
0
}
159
160
void
161
json_value_free (JsonValue *value)
162
0
{
163
0
  if (G_LIKELY (value != NULL))
164
0
    {
165
0
      json_value_unset (value);
166
0
      g_slice_free (JsonValue, value);
167
0
    }
168
0
}
169
170
/*< private >
171
 * json_value_seal:
172
 * @value: a JSON scalar value
173
 *
174
 * Seals the value, making it immutable to further changes.
175
 *
176
 * If the value is already immutable, this is a no-op.
177
 */
178
void
179
json_value_seal (JsonValue *value)
180
0
{
181
0
  g_return_if_fail (JSON_VALUE_IS_VALID (value));
182
0
  g_return_if_fail (value->ref_count > 0);
183
184
0
  value->immutable = TRUE;
185
0
}
186
187
guint
188
json_value_hash (gconstpointer key)
189
0
{
190
0
  JsonValue *value;
191
0
  guint value_hash;
192
0
  guint type_hash;
193
194
0
  value = (JsonValue *) key;
195
196
  /* Hash the type and value separately.
197
   * Use the top 3 bits to store the type. */
198
0
  type_hash = value->type << (sizeof (guint) * 8 - 3);
199
200
0
  switch (value->type)
201
0
    {
202
0
    case JSON_VALUE_NULL:
203
0
      value_hash = 0;
204
0
      break;
205
0
    case JSON_VALUE_BOOLEAN:
206
0
      value_hash = json_value_get_boolean (value) ? 1 : 0;
207
0
      break;
208
0
    case JSON_VALUE_STRING:
209
0
      value_hash = json_string_hash (json_value_get_string (value));
210
0
      break;
211
0
    case JSON_VALUE_INT: {
212
0
      gint64 v = json_value_get_int (value);
213
0
      value_hash = g_int64_hash (&v);
214
0
      break;
215
0
    }
216
0
    case JSON_VALUE_DOUBLE: {
217
0
      gdouble v = json_value_get_double (value);
218
0
      value_hash = g_double_hash (&v);
219
0
      break;
220
0
    }
221
0
    case JSON_VALUE_INVALID:
222
0
    default:
223
0
      g_assert_not_reached ();
224
0
    }
225
226
  /* Mask out the top 3 bits of the @value_hash. */
227
0
  value_hash &= ~(7 << (sizeof (guint) * 8 - 3));
228
229
0
  return (type_hash | value_hash);
230
0
}
231
232
#define _JSON_VALUE_DEFINE_SET(Type,EType,CType,VField) \
233
void \
234
0
json_value_set_##Type (JsonValue *value, CType VField) \
235
0
{ \
236
0
  g_return_if_fail (JSON_VALUE_IS_VALID (value)); \
237
0
  g_return_if_fail (JSON_VALUE_HOLDS (value, JSON_VALUE_##EType)); \
238
0
  g_return_if_fail (!value->immutable); \
239
0
\
240
0
  value->data.VField = VField; \
241
0
\
242
0
}
Unexecuted instantiation: json_value_set_int
Unexecuted instantiation: json_value_set_double
Unexecuted instantiation: json_value_set_boolean
243
244
#define _JSON_VALUE_DEFINE_GET(Type,EType,CType,VField) \
245
CType \
246
0
json_value_get_##Type (const JsonValue *value) \
247
0
{ \
248
0
  g_return_val_if_fail (JSON_VALUE_IS_VALID (value), 0); \
249
0
  g_return_val_if_fail (JSON_VALUE_HOLDS (value, JSON_VALUE_##EType), 0); \
250
0
\
251
0
  return value->data.VField; \
252
0
}
Unexecuted instantiation: json_value_get_int
Unexecuted instantiation: json_value_get_double
Unexecuted instantiation: json_value_get_boolean
Unexecuted instantiation: json_value_get_string
253
254
#define _JSON_VALUE_DEFINE_SET_GET(Type,EType,CType,VField) \
255
_JSON_VALUE_DEFINE_SET(Type,EType,CType,VField) \
256
_JSON_VALUE_DEFINE_GET(Type,EType,CType,VField)
257
258
_JSON_VALUE_DEFINE_SET_GET(int, INT, gint64, v_int)
259
260
_JSON_VALUE_DEFINE_SET_GET(double, DOUBLE, gdouble, v_double)
261
262
_JSON_VALUE_DEFINE_SET_GET(boolean, BOOLEAN, gboolean, v_bool)
263
264
void
265
json_value_set_string (JsonValue *value,
266
                       const gchar *v_str)
267
0
{
268
0
  g_return_if_fail (JSON_VALUE_IS_VALID (value));
269
0
  g_return_if_fail (JSON_VALUE_HOLDS_STRING (value));
270
0
  g_return_if_fail (!value->immutable);
271
272
0
  g_free (value->data.v_str);
273
0
  value->data.v_str = g_strdup (v_str);
274
0
}
275
276
_JSON_VALUE_DEFINE_GET(string, STRING, const gchar *, v_str)
277
278
#undef _JSON_VALUE_DEFINE_SET_GET
279
#undef _JSON_VALUE_DEFINE_GET
280
#undef _JSON_VALUE_DEFINE_SET