3 * Purple is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program 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
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
30 typedef struct _FbJsonValue FbJsonValue
;
40 struct _FbJsonValuesPrivate
53 G_DEFINE_TYPE(FbJsonValues
, fb_json_values
, G_TYPE_OBJECT
);
56 fb_json_values_dispose(GObject
*obj
)
59 FbJsonValuesPrivate
*priv
= FB_JSON_VALUES(obj
)->priv
;
61 while (!g_queue_is_empty(priv
->queue
)) {
62 value
= g_queue_pop_head(priv
->queue
);
64 if (G_IS_VALUE(&value
->value
)) {
65 g_value_unset(&value
->value
);
71 if (priv
->array
!= NULL
) {
72 json_array_unref(priv
->array
);
75 if (priv
->error
!= NULL
) {
76 g_error_free(priv
->error
);
79 g_queue_free(priv
->queue
);
83 fb_json_values_class_init(FbJsonValuesClass
*klass
)
85 GObjectClass
*gklass
= G_OBJECT_CLASS(klass
);
87 gklass
->dispose
= fb_json_values_dispose
;
88 g_type_class_add_private(klass
, sizeof (FbJsonValuesPrivate
));
92 fb_json_values_init(FbJsonValues
*values
)
94 FbJsonValuesPrivate
*priv
;
96 priv
= G_TYPE_INSTANCE_GET_PRIVATE(values
, FB_TYPE_JSON_VALUES
,
100 priv
->queue
= g_queue_new();
104 fb_json_error_quark(void)
108 if (G_UNLIKELY(q
== 0)) {
109 q
= g_quark_from_static_string("fb-json-error-quark");
116 fb_json_bldr_new(JsonNodeType type
)
120 bldr
= json_builder_new();
123 case JSON_NODE_ARRAY
:
124 fb_json_bldr_arr_begin(bldr
, NULL
);
127 case JSON_NODE_OBJECT
:
128 fb_json_bldr_obj_begin(bldr
, NULL
);
139 fb_json_bldr_close(JsonBuilder
*bldr
, JsonNodeType type
, gsize
*size
)
146 case JSON_NODE_ARRAY
:
147 fb_json_bldr_arr_end(bldr
);
150 case JSON_NODE_OBJECT
:
151 fb_json_bldr_obj_end(bldr
);
158 genr
= json_generator_new();
159 root
= json_builder_get_root(bldr
);
161 json_generator_set_root(genr
, root
);
162 ret
= json_generator_to_data(genr
, size
);
164 json_node_free(root
);
165 g_object_unref(genr
);
166 g_object_unref(bldr
);
172 fb_json_bldr_arr_begin(JsonBuilder
*bldr
, const gchar
*name
)
175 json_builder_set_member_name(bldr
, name
);
178 json_builder_begin_array(bldr
);
182 fb_json_bldr_arr_end(JsonBuilder
*bldr
)
184 json_builder_end_array(bldr
);
188 fb_json_bldr_obj_begin(JsonBuilder
*bldr
, const gchar
*name
)
191 json_builder_set_member_name(bldr
, name
);
194 json_builder_begin_object(bldr
);
198 fb_json_bldr_obj_end(JsonBuilder
*bldr
)
200 json_builder_end_object(bldr
);
204 fb_json_bldr_add_bool(JsonBuilder
*bldr
, const gchar
*name
, gboolean value
)
207 json_builder_set_member_name(bldr
, name
);
210 json_builder_add_boolean_value(bldr
, value
);
214 fb_json_bldr_add_dbl(JsonBuilder
*bldr
, const gchar
*name
, gdouble value
)
217 json_builder_set_member_name(bldr
, name
);
220 json_builder_add_double_value(bldr
, value
);
224 fb_json_bldr_add_int(JsonBuilder
*bldr
, const gchar
*name
, gint64 value
)
227 json_builder_set_member_name(bldr
, name
);
230 json_builder_add_int_value(bldr
, value
);
234 fb_json_bldr_add_str(JsonBuilder
*bldr
, const gchar
*name
, const gchar
*value
)
237 json_builder_set_member_name(bldr
, name
);
240 json_builder_add_string_value(bldr
, value
);
244 fb_json_bldr_add_strf(JsonBuilder
*bldr
, const gchar
*name
,
245 const gchar
*format
, ...)
250 va_start(ap
, format
);
251 value
= g_strdup_vprintf(format
, ap
);
254 fb_json_bldr_add_str(bldr
, name
, value
);
259 fb_json_node_new(const gchar
*data
, gssize size
, GError
**error
)
265 g_return_val_if_fail(data
!= NULL
, NULL
);
271 /* Ensure data is null terminated for json-glib < 1.0.2 */
272 slice
= g_strndup(data
, size
);
273 prsr
= json_parser_new();
275 if (!json_parser_load_from_data(prsr
, slice
, size
, error
)) {
276 g_object_unref(prsr
);
281 root
= json_parser_get_root(prsr
);
282 root
= json_node_copy(root
);
284 g_object_unref(prsr
);
290 fb_json_node_get(JsonNode
*root
, const gchar
*expr
, GError
**error
)
298 /* Special case for json-glib < 0.99.2 */
299 if (purple_strequal(expr
, "$")) {
300 return json_node_copy(root
);
303 node
= json_path_query(expr
, root
, &err
);
306 g_propagate_error(error
, err
);
307 json_node_free(node
);
311 rslt
= json_node_get_array(node
);
312 size
= json_array_get_length(rslt
);
315 g_set_error(error
, FB_JSON_ERROR
, FB_JSON_ERROR_NOMATCH
,
316 _("No matches for %s"), expr
);
317 json_node_free(node
);
322 g_set_error(error
, FB_JSON_ERROR
, FB_JSON_ERROR_AMBIGUOUS
,
323 _("Ambiguous matches for %s"), expr
);
324 json_node_free(node
);
328 if (json_array_get_null_element(rslt
, 0)) {
329 g_set_error(error
, FB_JSON_ERROR
, FB_JSON_ERROR_NULL
,
330 _("Null value for %s"), expr
);
331 json_node_free(node
);
335 ret
= json_array_dup_element(rslt
, 0);
336 json_node_free(node
);
341 fb_json_node_get_nth(JsonNode
*root
, guint n
)
347 obj
= json_node_get_object(root
);
348 vals
= json_object_get_values(obj
);
349 ret
= g_list_nth_data(vals
, n
);
356 fb_json_node_get_arr(JsonNode
*root
, const gchar
*expr
, GError
**error
)
361 rslt
= fb_json_node_get(root
, expr
, error
);
367 ret
= json_node_dup_array(rslt
);
368 json_node_free(rslt
);
373 fb_json_node_get_bool(JsonNode
*root
, const gchar
*expr
, GError
**error
)
378 rslt
= fb_json_node_get(root
, expr
, error
);
384 ret
= json_node_get_boolean(rslt
);
385 json_node_free(rslt
);
390 fb_json_node_get_dbl(JsonNode
*root
, const gchar
*expr
, GError
**error
)
395 rslt
= fb_json_node_get(root
, expr
, error
);
401 ret
= json_node_get_double(rslt
);
402 json_node_free(rslt
);
407 fb_json_node_get_int(JsonNode
*root
, const gchar
*expr
, GError
**error
)
412 rslt
= fb_json_node_get(root
, expr
, error
);
418 ret
= json_node_get_int(rslt
);
419 json_node_free(rslt
);
424 fb_json_node_get_str(JsonNode
*root
, const gchar
*expr
, GError
**error
)
429 rslt
= fb_json_node_get(root
, expr
, error
);
435 ret
= json_node_dup_string(rslt
);
436 json_node_free(rslt
);
441 fb_json_values_new(JsonNode
*root
)
443 FbJsonValues
*values
;
444 FbJsonValuesPrivate
*priv
;
446 g_return_val_if_fail(root
!= NULL
, NULL
);
448 values
= g_object_new(FB_TYPE_JSON_VALUES
, NULL
);
456 fb_json_values_add(FbJsonValues
*values
, FbJsonType type
, gboolean required
,
460 FbJsonValuesPrivate
*priv
;
462 g_return_if_fail(values
!= NULL
);
463 g_return_if_fail(expr
!= NULL
);
466 value
= g_new0(FbJsonValue
, 1);
469 value
->required
= required
;
471 g_queue_push_tail(priv
->queue
, value
);
475 fb_json_values_get_root(FbJsonValues
*values
)
477 FbJsonValuesPrivate
*priv
;
480 g_return_val_if_fail(values
!= NULL
, NULL
);
483 if (priv
->array
== NULL
) {
487 g_return_val_if_fail(priv
->index
> 0, NULL
);
488 index
= priv
->index
- 1;
490 if (json_array_get_length(priv
->array
) <= index
) {
494 return json_array_get_element(priv
->array
, index
);
498 fb_json_values_set_array(FbJsonValues
*values
, gboolean required
,
501 FbJsonValuesPrivate
*priv
;
503 g_return_if_fail(values
!= NULL
);
506 priv
->array
= fb_json_node_get_arr(priv
->root
, expr
, &priv
->error
);
507 priv
->isarray
= TRUE
;
509 if ((priv
->error
!= NULL
) && !required
) {
510 g_clear_error(&priv
->error
);
515 fb_json_values_update(FbJsonValues
*values
, GError
**error
)
518 FbJsonValuesPrivate
*priv
;
525 g_return_val_if_fail(values
!= NULL
, FALSE
);
528 if (G_UNLIKELY(priv
->error
!= NULL
)) {
529 g_propagate_error(error
, priv
->error
);
535 if ((priv
->array
== NULL
) ||
536 (json_array_get_length(priv
->array
) <= priv
->index
))
541 root
= json_array_get_element(priv
->array
, priv
->index
++);
546 g_return_val_if_fail(root
!= NULL
, FALSE
);
548 for (l
= priv
->queue
->head
; l
!= NULL
; l
= l
->next
) {
550 node
= fb_json_node_get(root
, value
->expr
, &err
);
552 if (G_IS_VALUE(&value
->value
)) {
553 g_value_unset(&value
->value
);
557 json_node_free(node
);
559 if (value
->required
) {
560 g_propagate_error(error
, err
);
568 type
= json_node_get_value_type(node
);
570 if (G_UNLIKELY(type
!= value
->type
)) {
571 g_set_error(error
, FB_JSON_ERROR
, FB_JSON_ERROR_TYPE
,
572 _("Expected a %s but got a %s for %s"),
573 g_type_name(value
->type
),
576 json_node_free(node
);
580 json_node_get_value(node
, &value
->value
);
581 json_node_free(node
);
584 priv
->next
= priv
->queue
->head
;
589 fb_json_values_next(FbJsonValues
*values
)
592 FbJsonValuesPrivate
*priv
;
594 g_return_val_if_fail(values
!= NULL
, NULL
);
597 g_return_val_if_fail(priv
->next
!= NULL
, NULL
);
598 value
= priv
->next
->data
;
599 priv
->next
= priv
->next
->next
;
601 if (!G_IS_VALUE(&value
->value
)) {
605 return &value
->value
;
609 fb_json_values_next_bool(FbJsonValues
*values
, gboolean defval
)
613 value
= fb_json_values_next(values
);
615 if (G_UNLIKELY(value
== NULL
)) {
619 return g_value_get_boolean(value
);
623 fb_json_values_next_dbl(FbJsonValues
*values
, gdouble defval
)
627 value
= fb_json_values_next(values
);
629 if (G_UNLIKELY(value
== NULL
)) {
633 return g_value_get_double(value
);
637 fb_json_values_next_int(FbJsonValues
*values
, gint64 defval
)
641 value
= fb_json_values_next(values
);
643 if (G_UNLIKELY(value
== NULL
)) {
647 return g_value_get_int64(value
);
651 fb_json_values_next_str(FbJsonValues
*values
, const gchar
*defval
)
655 value
= fb_json_values_next(values
);
657 if (G_UNLIKELY(value
== NULL
)) {
661 return g_value_get_string(value
);
665 fb_json_values_next_str_dup(FbJsonValues
*values
, const gchar
*defval
)
669 value
= fb_json_values_next(values
);
671 if (G_UNLIKELY(value
== NULL
)) {
672 return g_strdup(defval
);
675 return g_value_dup_string(value
);