1 /* json-generator.c - JSON tree builder
3 * This file is part of JSON-GLib
4 * Copyright (C) 2010 Luca Bruno <lethalman88@gmail.com>
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.
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.
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/>.
20 * Luca Bruno <lethalman88@gmail.com>
24 * SECTION:json-builder
26 * @short_description: Generates JSON trees
27 * @See_Also: JsonGenerator
29 * #JsonBuilder provides an object for generating a JSON tree.
30 * You can generate only one tree with one #JsonBuilder instance.
32 * The root of the JSON tree can be either a #JsonObject or a #JsonArray.
33 * Thus the first call must necessarily be either
34 * json_builder_begin_object() or json_builder_begin_array().
36 * For convenience to language bindings, #JsonBuilder returns itself from
37 * most of functions, making it easy to chain function calls.
47 #include "json-types-private.h"
49 #include "json-builder.h"
51 #define JSON_BUILDER_GET_PRIVATE(obj) \
52 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), JSON_TYPE_BUILDER, JsonBuilderPrivate))
54 struct _JsonBuilderPrivate
62 JSON_BUILDER_MODE_OBJECT,
63 JSON_BUILDER_MODE_ARRAY,
64 JSON_BUILDER_MODE_MEMBER
80 json_builder_state_free (JsonBuilderState *state)
86 case JSON_BUILDER_MODE_OBJECT:
87 case JSON_BUILDER_MODE_MEMBER:
88 json_object_unref (state->data.object);
89 g_free (state->member_name);
90 state->data.object = NULL;
91 state->member_name = NULL;
93 case JSON_BUILDER_MODE_ARRAY:
94 json_array_unref (state->data.array);
95 state->data.array = NULL;
98 g_assert_not_reached ();
101 g_slice_free (JsonBuilderState, state);
105 G_DEFINE_TYPE (JsonBuilder, json_builder, G_TYPE_OBJECT);
108 json_builder_free_all_state (JsonBuilder *builder)
110 JsonBuilderState *state;
112 while (!g_queue_is_empty (builder->priv->stack))
114 state = g_queue_pop_head (builder->priv->stack);
115 json_builder_state_free (state);
118 if (builder->priv->root)
120 json_node_free (builder->priv->root);
121 builder->priv->root = NULL;
126 json_builder_finalize (GObject *gobject)
128 JsonBuilderPrivate *priv = JSON_BUILDER_GET_PRIVATE (gobject);
130 json_builder_free_all_state (JSON_BUILDER (gobject));
132 g_queue_free (priv->stack);
135 G_OBJECT_CLASS (json_builder_parent_class)->finalize (gobject);
139 json_builder_class_init (JsonBuilderClass *klass)
141 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
143 g_type_class_add_private (klass, sizeof (JsonBuilderPrivate));
145 gobject_class->finalize = json_builder_finalize;
149 json_builder_init (JsonBuilder *builder)
151 JsonBuilderPrivate *priv;
153 builder->priv = priv = JSON_BUILDER_GET_PRIVATE (builder);
155 priv->stack = g_queue_new ();
159 static inline JsonBuilderMode
160 json_builder_current_mode (JsonBuilder *builder)
162 JsonBuilderState *state = g_queue_peek_head (builder->priv->stack);
166 static inline gboolean
167 json_builder_is_valid_add_mode (JsonBuilder *builder)
169 JsonBuilderMode mode = json_builder_current_mode (builder);
170 return mode == JSON_BUILDER_MODE_MEMBER || mode == JSON_BUILDER_MODE_ARRAY;
176 * Creates a new #JsonBuilder. You can use this object to generate a
177 * JSON tree and obtain the root #JsonNode<!-- -->s.
179 * Return value: the newly created #JsonBuilder instance
182 json_builder_new (void)
184 return g_object_new (JSON_TYPE_BUILDER, NULL);
188 * json_builder_get_root:
189 * @builder: a #JsonBuilder
191 * Returns the root of the current constructed tree, if the build is complete
192 * (ie: all opened objects, object members and arrays are being closed).
194 * Return value: (transfer full): the #JsonNode, or %NULL if the build is not complete.
195 * Free the returned value with json_node_free().
198 json_builder_get_root (JsonBuilder *builder)
200 JsonNode *root = NULL;
202 g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
204 if (builder->priv->root)
205 root = json_node_copy (builder->priv->root);
211 * json_builder_reset:
212 * @builder: a #JsonBuilder
214 * Resets the state of the @builder back to its initial state.
217 json_builder_reset (JsonBuilder *builder)
219 g_return_if_fail (JSON_IS_BUILDER (builder));
221 json_builder_free_all_state (builder);
225 * json_builder_begin_object:
226 * @builder: a #JsonBuilder
228 * Opens a subobject inside the given @builder. When done adding members to
229 * the subobject, json_builder_end_object() must be called.
231 * Can be called for first or only if the call is associated to an object member
232 * or an array element.
234 * Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
237 json_builder_begin_object (JsonBuilder *builder)
240 JsonBuilderState *state;
241 JsonBuilderState *cur_state;
243 g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
244 g_return_val_if_fail (builder->priv->root == NULL, NULL);
245 g_return_val_if_fail (g_queue_is_empty (builder->priv->stack) || json_builder_is_valid_add_mode (builder), NULL);
247 object = json_object_new ();
248 cur_state = g_queue_peek_head (builder->priv->stack);
251 switch (cur_state->mode)
253 case JSON_BUILDER_MODE_ARRAY:
254 json_array_add_object_element (cur_state->data.array, json_object_ref (object));
257 case JSON_BUILDER_MODE_MEMBER:
258 json_object_set_object_member (cur_state->data.object, cur_state->member_name, json_object_ref (object));
259 g_free (cur_state->member_name);
260 cur_state->member_name = NULL;
261 cur_state->mode = JSON_BUILDER_MODE_OBJECT;
265 g_assert_not_reached ();
269 state = g_slice_new (JsonBuilderState);
270 state->data.object = object;
271 state->member_name = NULL;
272 state->mode = JSON_BUILDER_MODE_OBJECT;
273 g_queue_push_head (builder->priv->stack, state);
279 * json_builder_end_object:
280 * @builder: a #JsonBuilder
282 * Closes the subobject inside the given @builder that was opened by the most
283 * recent call to json_builder_begin_object().
285 * Cannot be called after json_builder_set_member_name().
287 * Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
290 json_builder_end_object (JsonBuilder *builder)
292 JsonBuilderState *state;
294 g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
295 g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
296 g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_OBJECT, NULL);
298 state = g_queue_pop_head (builder->priv->stack);
300 if (g_queue_is_empty (builder->priv->stack))
302 builder->priv->root = json_node_new (JSON_NODE_OBJECT);
303 json_node_take_object (builder->priv->root, json_object_ref (state->data.object));
306 json_builder_state_free (state);
312 * json_builder_begin_array:
313 * @builder: a #JsonBuilder
315 * Opens a subarray inside the given @builder. When done adding members to
316 * the subarray, json_builder_end_array() must be called.
318 * Can be called for first or only if the call is associated to an object member
319 * or an array element.
321 * Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
324 json_builder_begin_array (JsonBuilder *builder)
327 JsonBuilderState *state;
328 JsonBuilderState *cur_state;
330 g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
331 g_return_val_if_fail (builder->priv->root == NULL, NULL);
332 g_return_val_if_fail (g_queue_is_empty (builder->priv->stack) || json_builder_is_valid_add_mode (builder), NULL);
334 array = json_array_new ();
335 cur_state = g_queue_peek_head (builder->priv->stack);
338 switch (cur_state->mode)
340 case JSON_BUILDER_MODE_ARRAY:
341 json_array_add_array_element (cur_state->data.array, json_array_ref (array));
344 case JSON_BUILDER_MODE_MEMBER:
345 json_object_set_array_member (cur_state->data.object, cur_state->member_name, json_array_ref (array));
346 g_free (cur_state->member_name);
347 cur_state->member_name = NULL;
348 cur_state->mode = JSON_BUILDER_MODE_OBJECT;
352 g_assert_not_reached ();
356 state = g_slice_new (JsonBuilderState);
357 state->data.array = array;
358 state->mode = JSON_BUILDER_MODE_ARRAY;
359 g_queue_push_head (builder->priv->stack, state);
365 * json_builder_end_array:
366 * @builder: a #JsonBuilder
368 * Closes the subarray inside the given @builder that was opened by the most
369 * recent call to json_builder_begin_array().
371 * Cannot be called after json_builder_set_member_name().
373 * Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
376 json_builder_end_array (JsonBuilder *builder)
378 JsonBuilderState *state;
380 g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
381 g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
382 g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_ARRAY, NULL);
384 state = g_queue_pop_head (builder->priv->stack);
386 if (g_queue_is_empty (builder->priv->stack))
388 builder->priv->root = json_node_new (JSON_NODE_ARRAY);
389 json_node_take_array (builder->priv->root, json_array_ref (state->data.array));
392 json_builder_state_free (state);
398 * json_builder_set_member_name:
399 * @builder: a #JsonBuilder
400 * @member_name: the name of the member
402 * Set the name of the next member in an object. The next call must add a value,
403 * open an object or an array.
405 * Can be called only if the call is associated to an object.
407 * Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
410 json_builder_set_member_name (JsonBuilder *builder, const gchar *member_name)
412 JsonBuilderState *state;
414 g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
415 g_return_val_if_fail (member_name != NULL, NULL);
416 g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
417 g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_OBJECT, NULL);
419 state = g_queue_peek_head (builder->priv->stack);
420 state->member_name = g_strdup (member_name);
421 state->mode = JSON_BUILDER_MODE_MEMBER;
427 * json_builder_add_value:
428 * @builder: a #JsonBuilder
429 * @node: the value of the member or element
431 * If called after json_builder_set_member_name(), sets @node as member of the
432 * most recent opened object, otherwise @node is added as element of the most
433 * recent opened array.
435 * Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
438 json_builder_add_value (JsonBuilder *builder, JsonNode *node)
440 JsonBuilderState *state;
442 g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
443 g_return_val_if_fail (node != NULL, NULL);
444 g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
445 g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
447 state = g_queue_peek_head (builder->priv->stack);
450 case JSON_BUILDER_MODE_MEMBER:
451 json_object_set_member (state->data.object, state->member_name, node);
452 g_free (state->member_name);
453 state->member_name = NULL;
454 state->mode = JSON_BUILDER_MODE_OBJECT;
457 case JSON_BUILDER_MODE_ARRAY:
458 json_array_add_element (state->data.array, node);
462 g_assert_not_reached ();
469 * json_builder_add_int_value:
470 * @builder: a #JsonBuilder
471 * @value: the value of the member or element
473 * If called after json_builder_set_member_name(), sets @value as member of the
474 * most recent opened object, otherwise @value is added as element of the most
475 * recent opened array.
477 * See also: json_builder_add_value()
479 * Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
482 json_builder_add_int_value (JsonBuilder *builder, gint64 value)
484 JsonBuilderState *state;
486 g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
487 g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
488 g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
490 state = g_queue_peek_head (builder->priv->stack);
493 case JSON_BUILDER_MODE_MEMBER:
494 json_object_set_int_member (state->data.object, state->member_name, value);
495 g_free (state->member_name);
496 state->member_name = NULL;
497 state->mode = JSON_BUILDER_MODE_OBJECT;
500 case JSON_BUILDER_MODE_ARRAY:
501 json_array_add_int_element (state->data.array, value);
505 g_assert_not_reached ();
512 * json_builder_add_double_value:
513 * @builder: a #JsonBuilder
514 * @value: the value of the member or element
516 * If called after json_builder_set_member_name(), sets @value as member of the
517 * most recent opened object, otherwise @value is added as element of the most
518 * recent opened array.
520 * See also: json_builder_add_value()
522 * Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
525 json_builder_add_double_value (JsonBuilder *builder, gdouble value)
527 JsonBuilderState *state;
529 g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
530 g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
531 g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
533 state = g_queue_peek_head (builder->priv->stack);
537 case JSON_BUILDER_MODE_MEMBER:
538 json_object_set_double_member (state->data.object, state->member_name, value);
539 g_free (state->member_name);
540 state->member_name = NULL;
541 state->mode = JSON_BUILDER_MODE_OBJECT;
544 case JSON_BUILDER_MODE_ARRAY:
545 json_array_add_double_element (state->data.array, value);
549 g_assert_not_reached ();
556 * json_builder_add_boolean_value:
557 * @builder: a #JsonBuilder
558 * @value: the value of the member or element
560 * If called after json_builder_set_member_name(), sets @value as member of the
561 * most recent opened object, otherwise @value is added as element of the most
562 * recent opened array.
564 * See also: json_builder_add_value()
566 * Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
569 json_builder_add_boolean_value (JsonBuilder *builder, gboolean value)
571 JsonBuilderState *state;
573 g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
574 g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
575 g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
577 state = g_queue_peek_head (builder->priv->stack);
581 case JSON_BUILDER_MODE_MEMBER:
582 json_object_set_boolean_member (state->data.object, state->member_name, value);
583 g_free (state->member_name);
584 state->member_name = NULL;
585 state->mode = JSON_BUILDER_MODE_OBJECT;
588 case JSON_BUILDER_MODE_ARRAY:
589 json_array_add_boolean_element (state->data.array, value);
593 g_assert_not_reached ();
600 * json_builder_add_string_value:
601 * @builder: a #JsonBuilder
602 * @value: the value of the member or element
604 * If called after json_builder_set_member_name(), sets @value as member of the
605 * most recent opened object, otherwise @value is added as element of the most
606 * recent opened array.
608 * See also: json_builder_add_value()
610 * Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
613 json_builder_add_string_value (JsonBuilder *builder, const gchar *value)
615 JsonBuilderState *state;
617 g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
618 g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
619 g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
621 state = g_queue_peek_head (builder->priv->stack);
625 case JSON_BUILDER_MODE_MEMBER:
626 json_object_set_string_member (state->data.object, state->member_name, value);
627 g_free (state->member_name);
628 state->member_name = NULL;
629 state->mode = JSON_BUILDER_MODE_OBJECT;
632 case JSON_BUILDER_MODE_ARRAY:
633 json_array_add_string_element (state->data.array, value);
637 g_assert_not_reached ();
644 * json_builder_add_null_value:
645 * @builder: a #JsonBuilder
647 * If called after json_builder_set_member_name(), sets null as member of the
648 * most recent opened object, otherwise null is added as element of the most
649 * recent opened array.
651 * See also: json_builder_add_value()
653 * Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
656 json_builder_add_null_value (JsonBuilder *builder)
658 JsonBuilderState *state;
660 g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
661 g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
662 g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
664 state = g_queue_peek_head (builder->priv->stack);
668 case JSON_BUILDER_MODE_MEMBER:
669 json_object_set_null_member (state->data.object, state->member_name);
670 g_free (state->member_name);
671 state->member_name = NULL;
672 state->mode = JSON_BUILDER_MODE_OBJECT;
675 case JSON_BUILDER_MODE_ARRAY:
676 json_array_add_null_element (state->data.array);
680 g_assert_not_reached ();