Initial Import
[profile/ivi/json-glib.git] / json-glib / json-reader.c
1 /* json-reader.h - JSON cursor parser
2  * 
3  * This file is part of JSON-GLib
4  * Copyright (C) 2010  Intel Corp.
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:
20  *   Emmanuele Bassi  <ebassi@linux.intel.com>
21  */
22
23 /**
24  * SECTION:json-reader
25  * @Title: JsonReader
26  * @short_description: A cursor-based parser
27  *
28  * #JsonReader provides a simple, cursor-based API for parsing a JSON DOM. It
29  * is similar, in spirit, to the XML Reader API.
30  *
31  * In case of error, #JsonReader will be set in an error state; all subsequent
32  * calls will simply be ignored until a function that resets the error state is
33  * called, e.g.:
34  *
35  * |[
36  * /&ast; ask for the 7th element; if the element does not exist, the
37  *  &ast; reader will be put in an error state
38  *  &ast;/
39  * json_reader_read_element (reader, 6);
40  *
41  * /&ast; in case of error, this will return NULL, otherwise it will
42  *  &ast; return the value of the element
43  *  &ast;/
44  * str = json_reader_get_string_value (value);
45  *
46  * /&ast; this function resets the error state if any was set &ast;/
47  * json_reader_end_element (reader);
48  * ]|
49  *
50  * If you want to detect the error state as soon as possible, you can use
51  * json_reader_get_error():
52  *
53  * |[
54  * /&ast; like the example above, but in this case we print out the
55  *  &ast; error immediately
56  *  &ast;/
57  * if (!json_reader_read_element (reader, 6))
58  *   {
59  *     const GError *error = json_reader_get_error (reader);
60  *     g_print ("Unable to read the element: %s", error->message);
61  *   }
62  * ]|
63  *
64  * #JsonReader is available since JSON-GLib 0.12.
65  */
66
67 #ifdef HAVE_CONFIG_H
68 #include "config.h"
69 #endif
70
71 #include <string.h>
72
73 #include <glib/gi18n-lib.h>
74
75 #include "json-reader.h"
76
77 #include "json-types-private.h"
78
79 #include "json-debug.h"
80
81 #define json_reader_return_if_error_set(r)      G_STMT_START {  \
82         if (((JsonReader *) (r))->priv->error != NULL)          \
83           return;                               } G_STMT_END
84
85 #define json_reader_return_val_if_error_set(r,v) G_STMT_START {  \
86         if (((JsonReader *) (r))->priv->error != NULL)           \
87           return (v);                           } G_STMT_END
88
89 struct _JsonReaderPrivate
90 {
91   JsonNode *root;
92
93   JsonNode *current_node;
94   JsonNode *previous_node;
95
96   gchar *current_member;
97
98   GError *error;
99 };
100
101 enum
102 {
103   PROP_0,
104
105   PROP_ROOT,
106
107   PROP_LAST
108 };
109
110 static GParamSpec *reader_properties[PROP_LAST] = { NULL, };
111
112 G_DEFINE_TYPE (JsonReader, json_reader, G_TYPE_OBJECT);
113
114 static void
115 json_reader_finalize (GObject *gobject)
116 {
117   JsonReaderPrivate *priv = JSON_READER (gobject)->priv;
118
119   if (priv->root != NULL)
120     json_node_free (priv->root);
121
122   if (priv->error != NULL)
123     g_clear_error (&priv->error);
124
125   g_free (priv->current_member);
126
127   G_OBJECT_CLASS (json_reader_parent_class)->finalize (gobject);
128 }
129
130 static void
131 json_reader_set_property (GObject      *gobject,
132                           guint         prop_id,
133                           const GValue *value,
134                           GParamSpec   *pspec)
135 {
136   switch (prop_id)
137     {
138     case PROP_ROOT:
139       json_reader_set_root (JSON_READER (gobject), g_value_get_boxed (value));
140       break;
141
142     default:
143       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
144       break;
145     }
146 }
147
148 static void
149 json_reader_get_property (GObject    *gobject,
150                           guint       prop_id,
151                           GValue     *value,
152                           GParamSpec *pspec)
153 {
154   switch (prop_id)
155     {
156     case PROP_ROOT:
157       g_value_set_boxed (value, JSON_READER (gobject)->priv->root);
158       break;
159
160     default:
161       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
162       break;
163     }
164 }
165
166 static void
167 json_reader_class_init (JsonReaderClass *klass)
168 {
169   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
170
171   g_type_class_add_private (klass, sizeof (JsonReaderPrivate));
172
173   /**
174    * JsonReader:root:
175    *
176    * The root of the JSON tree that the #JsonReader should read.
177    *
178    * Since: 0.12
179    */
180   reader_properties[PROP_ROOT] =
181     g_param_spec_boxed ("root",
182                         "Root Node",
183                         "The root of the tree to read",
184                         JSON_TYPE_NODE,
185                         G_PARAM_READWRITE |
186                         G_PARAM_CONSTRUCT |
187                         G_PARAM_STATIC_STRINGS);
188
189   gobject_class->finalize = json_reader_finalize;
190   gobject_class->set_property = json_reader_set_property;
191   gobject_class->get_property = json_reader_get_property;
192   g_object_class_install_properties (gobject_class, PROP_LAST, reader_properties);
193 }
194
195 static void
196 json_reader_init (JsonReader *self)
197 {
198   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, JSON_TYPE_READER,
199                                             JsonReaderPrivate);
200 }
201
202 GQuark
203 json_reader_error_quark (void)
204 {
205   return g_quark_from_static_string ("json-reader-error");
206 }
207
208 /**
209  * json_reader_new:
210  * @node: (allow-none): a #JsonNode, or %NULL
211  *
212  * Creates a new #JsonReader. You can use this object to read the contents of
213  * the JSON tree starting from @node
214  *
215  * Return value: the newly created #JsonReader. Use g_object_unref() to
216  *   release the allocated resources when done
217  *
218  * Since: 0.12
219  */
220 JsonReader *
221 json_reader_new (JsonNode *node)
222 {
223   return g_object_new (JSON_TYPE_READER, "root", node, NULL);
224 }
225
226 /*
227  * json_reader_unset_error:
228  * @reader: a #JsonReader
229  *
230  * Unsets the error state of @reader, if set
231  */
232 static inline void
233 json_reader_unset_error (JsonReader *reader)
234 {
235   if (reader->priv->error != NULL)
236     g_clear_error (&(reader->priv->error));
237 }
238
239 /**
240  * json_reader_set_root:
241  * @reader: a #JsonReader
242  * @root: (allow-none): a #JsonNode
243  *
244  * Sets the root #JsonNode to be read by @reader. The @reader will take
245  * a copy of @root
246  *
247  * If another #JsonNode is currently set as root, it will be replaced.
248  *
249  * Since: 0.12
250  */
251 void
252 json_reader_set_root (JsonReader *reader,
253                       JsonNode   *root)
254 {
255   JsonReaderPrivate *priv;
256
257   g_return_if_fail (JSON_IS_READER (reader));
258
259   priv = reader->priv;
260
261   if (priv->root == root)
262     return;
263
264   if (priv->root != NULL)
265     {
266       json_node_free (priv->root);
267       priv->root = NULL;
268       priv->current_node = NULL;
269       priv->previous_node = NULL;
270     }
271
272   if (root != NULL)
273     {
274       priv->root = json_node_copy (root);
275       priv->current_node = priv->root;
276       priv->previous_node = NULL;
277     }
278
279   g_object_notify_by_pspec (G_OBJECT (reader), reader_properties[PROP_ROOT]);
280 }
281
282 /*
283  * json_reader_ser_error:
284  * @reader: a #JsonReader
285  * @error_code: the #JsonReaderError code for the error
286  * @error_fmt: format string
287  * @Varargs: list of arguments for the @error_fmt string
288  *
289  * Sets the error state of @reader using the given error code
290  * and string
291  *
292  * Return value: %FALSE, to be used to return immediately from
293  *   the caller function
294  */
295 static gboolean
296 json_reader_set_error (JsonReader      *reader,
297                        JsonReaderError  error_code,
298                        const gchar     *error_fmt,
299                        ...)
300 {
301   JsonReaderPrivate *priv = reader->priv;
302   va_list args;
303   gchar *error_msg;
304
305   if (priv->error != NULL)
306     g_clear_error (&priv->error);
307
308   va_start (args, error_fmt);
309   error_msg = g_strdup_vprintf (error_fmt, args);
310   va_end (args);
311
312   g_set_error_literal (&priv->error, JSON_READER_ERROR,
313                        error_code,
314                        error_msg);
315
316   g_free (error_msg);
317
318   return FALSE;
319 }
320
321 /**
322  * json_reader_get_error:
323  * @reader: a #JsonReader
324  *
325  * Retrieves the #GError currently set on @reader, if the #JsonReader
326  * is in error state
327  *
328  * Return value: (transfer none): the pointer to the error, or %NULL
329  *
330  * Since: 0.12
331  */
332 const GError *
333 json_reader_get_error (JsonReader *reader)
334 {
335   g_return_val_if_fail (JSON_IS_READER (reader), FALSE);
336
337   return reader->priv->error;
338 }
339
340 /**
341  * json_reader_is_array:
342  * @reader: a #JsonReader
343  *
344  * Checks whether the @reader is currently on an array
345  *
346  * Return value: %TRUE if the #JsonReader is on an array, and %FALSE
347  *   otherwise
348  *
349  * Since: 0.12
350  */
351 gboolean
352 json_reader_is_array (JsonReader *reader)
353 {
354   g_return_val_if_fail (JSON_IS_READER (reader), FALSE);
355   json_reader_return_val_if_error_set (reader, FALSE);
356
357   if (reader->priv->current_node == NULL)
358     return FALSE;
359
360   return JSON_NODE_HOLDS_ARRAY (reader->priv->current_node);
361 }
362
363 /**
364  * json_reader_is_object:
365  * @reader: a #JsonReader
366  *
367  * Checks whether the @reader is currently on an object
368  *
369  * Return value: %TRUE if the #JsonReader is on an object, and %FALSE
370  *   otherwise
371  *
372  * Since: 0.12
373  */
374 gboolean
375 json_reader_is_object (JsonReader *reader)
376 {
377   g_return_val_if_fail (JSON_IS_READER (reader), FALSE);
378   json_reader_return_val_if_error_set (reader, FALSE);
379
380   if (reader->priv->current_node == NULL)
381     return FALSE;
382
383   return JSON_NODE_HOLDS_OBJECT (reader->priv->current_node);
384 }
385
386 /**
387  * json_reader_is_value:
388  * @reader: a #JsonReader
389  *
390  * Checks whether the @reader is currently on a value
391  *
392  * Return value: %TRUE if the #JsonReader is on a value, and %FALSE
393  *   otherwise
394  *
395  * Since: 0.12
396  */
397 gboolean
398 json_reader_is_value (JsonReader *reader)
399 {
400   g_return_val_if_fail (JSON_IS_READER (reader), FALSE);
401   json_reader_return_val_if_error_set (reader, FALSE);
402
403   if (reader->priv->current_node == NULL)
404     return FALSE;
405
406   return JSON_NODE_HOLDS_VALUE (reader->priv->current_node);
407 }
408
409 /**
410  * json_reader_read_element:
411  * @reader: a #JsonReader
412  * @index_: the index of the element
413  *
414  * Advances the cursor of @reader to the element @index_ of the array
415  * or the object at the current position.
416  *
417  * You can use the json_reader_get_value* family of functions to retrieve
418  * the value of the element; for instance:
419  *
420  * |[
421  * json_reader_read_element (reader, 0);
422  * int_value = json_reader_get_int_value (reader);
423  * ]|
424  *
425  * After reading the value, json_reader_end_element() should be called to
426  * reposition the cursor inside the #JsonReader, e.g.:
427  *
428  * |[
429  * json_reader_read_element (reader, 1);
430  * str_value = json_reader_get_string_value (reader);
431  * json_reader_end_element (reader);
432  *
433  * json_reader_read_element (reader, 2);
434  * str_value = json_reader_get_string_value (reader);
435  * json_reader_end_element (reader);
436  * ]|
437  *
438  * If @reader is not currently on an array or an object, or if the @index_ is
439  * bigger than the size of the array or the object, the #JsonReader will be
440  * put in an error state until json_reader_end_element() is called.
441  *
442  * Return value: %TRUE on success, and %FALSE otherwise
443  *
444  * Since: 0.12
445  */
446 gboolean
447 json_reader_read_element (JsonReader *reader,
448                           guint       index_)
449 {
450   JsonReaderPrivate *priv;
451
452   g_return_val_if_fail (JSON_READER (reader), FALSE);
453   json_reader_return_val_if_error_set (reader, FALSE);
454
455   priv = reader->priv;
456
457   if (priv->current_node == NULL)
458     priv->current_node = priv->root;
459
460   if (!(JSON_NODE_HOLDS_ARRAY (priv->current_node) ||
461         JSON_NODE_HOLDS_OBJECT (priv->current_node)))
462     return json_reader_set_error (reader, JSON_READER_ERROR_NO_ARRAY,
463                                   _("The current node is of type '%s', but "
464                                     "an array or an object was expected."),
465                                   json_node_type_name (priv->current_node));
466
467   switch (json_node_get_node_type (priv->current_node))
468     {
469     case JSON_NODE_ARRAY:
470       {
471         JsonArray *array = json_node_get_array (priv->current_node);
472
473         if (index_ >= json_array_get_length (array))
474           return json_reader_set_error (reader, JSON_READER_ERROR_INVALID_INDEX,
475                                         _("The index '%d' is greater than the size "
476                                           "of the array at the current position."),
477                                         index_);
478
479         priv->previous_node = priv->current_node;
480         priv->current_node = json_array_get_element (array, index_);
481       }
482       break;
483
484     case JSON_NODE_OBJECT:
485       {
486         JsonObject *object = json_node_get_object (priv->current_node);
487         GList *members;
488         const gchar *name;
489
490         if (index_ >= json_object_get_size (object))
491           return json_reader_set_error (reader, JSON_READER_ERROR_INVALID_INDEX,
492                                         _("The index '%d' is greater than the size "
493                                           "of the object at the current position."),
494                                         index_);
495
496         priv->previous_node = priv->current_node;
497         g_free (priv->current_member);
498
499         members = json_object_get_members (object);
500         name = g_list_nth_data (members, index_);
501
502         priv->current_node = json_object_get_member (object, name);
503         priv->current_member = g_strdup (name);
504
505         g_list_free (members);
506       }
507       break;
508
509     default:
510       g_assert_not_reached ();
511       return FALSE;
512     }
513
514   return TRUE;
515 }
516
517 /**
518  * json_reader_end_element:
519  * @reader: a #JsonReader
520  *
521  * Moves the cursor back to the previous node after being positioned
522  * inside an array
523  *
524  * This function resets the error state of @reader, if any was set
525  *
526  * Since: 0.12
527  */
528 void
529 json_reader_end_element (JsonReader *reader)
530 {
531   JsonReaderPrivate *priv;
532   JsonNode *tmp;
533
534   g_return_if_fail (JSON_IS_READER (reader));
535
536   json_reader_unset_error (reader);
537
538   priv = reader->priv;
539
540   if (priv->previous_node != NULL)
541     tmp = json_node_get_parent (priv->previous_node);
542   else
543     tmp = NULL;
544
545   g_free (priv->current_member);
546   priv->current_member = NULL;
547
548   priv->current_node = priv->previous_node;
549   priv->previous_node = tmp;
550 }
551
552 /**
553  * json_reader_count_elements:
554  * @reader: a #JsonReader
555  *
556  * Counts the elements of the current position, if @reader is
557  * positioned on an array
558  *
559  * Return value: the number of elements, or -1. In case of failure
560  *   the #JsonReader is set in an error state
561  *
562  * Since: 0.12
563  */
564 gint
565 json_reader_count_elements (JsonReader *reader)
566 {
567   JsonReaderPrivate *priv;
568
569   g_return_val_if_fail (JSON_IS_READER (reader), -1);
570
571   priv = reader->priv;
572
573   if (priv->current_node == NULL)
574     {
575       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE,
576                              _("No node available at the current position"));
577       return -1;
578     }
579
580   if (!JSON_NODE_HOLDS_ARRAY (priv->current_node))
581     {
582       json_reader_set_error (reader, JSON_READER_ERROR_NO_ARRAY,
583                              _("The current position holds a '%s' and not an array"),
584                              json_node_type_get_name (JSON_NODE_TYPE (priv->current_node)));
585       return -1;
586     }
587
588   return json_array_get_length (json_node_get_array (priv->current_node));
589 }
590
591 /**
592  * json_reader_read_member:
593  * @reader: a #JsonReader
594  * @member_name: the name of the member to read
595  *
596  * Advances the cursor of @reader to the @member_name of the object at the
597  * current position.
598  *
599  * You can use the json_reader_get_value* family of functions to retrieve
600  * the value of the member; for instance:
601  *
602  * |[
603  * json_reader_read_member (reader, "width");
604  * width = json_reader_get_int_value (reader);
605  * ]|
606  *
607  * After reading the value, json_reader_end_member() should be called to
608  * reposition the cursor inside the #JsonReader, e.g.:
609  *
610  * |[
611  * json_reader_read_member (reader, "author");
612  * author = json_reader_get_string_value (reader);
613  * json_reader_end_element (reader);
614  *
615  * json_reader_read_element (reader, "title");
616  * title = json_reader_get_string_value (reader);
617  * json_reader_end_element (reader);
618  * ]|
619  *
620  * If @reader is not currently on an object, or if the @member_name is not
621  * defined in the object, the #JsonReader will be put in an error state until
622  * json_reader_end_member() is called.
623  *
624  * Return value: %TRUE on success, and %FALSE otherwise
625  *
626  * Since: 0.12
627  */
628 gboolean
629 json_reader_read_member (JsonReader  *reader,
630                          const gchar *member_name)
631 {
632   JsonReaderPrivate *priv;
633   JsonObject *object;
634
635   g_return_val_if_fail (JSON_READER (reader), FALSE);
636   g_return_val_if_fail (member_name != NULL, FALSE);
637   json_reader_return_val_if_error_set (reader, FALSE);
638
639   priv = reader->priv;
640
641   if (priv->current_node == NULL)
642     priv->current_node = priv->root;
643
644   if (!JSON_NODE_HOLDS_OBJECT (priv->current_node))
645     return json_reader_set_error (reader, JSON_READER_ERROR_NO_OBJECT,
646                                   _("The current node is of type '%s', but "
647                                     "an object was expected."),
648                                   json_node_type_name (priv->current_node));
649
650   object = json_node_get_object (priv->current_node);
651   if (!json_object_has_member (object, member_name))
652     return json_reader_set_error (reader, JSON_READER_ERROR_INVALID_MEMBER,
653                                   _("The member '%s' is not defined in the "
654                                     "object at the current position."),
655                                   member_name);
656
657   g_free (priv->current_member);
658
659   priv->previous_node = priv->current_node;
660   priv->current_node = json_object_get_member (object, member_name);
661   priv->current_member = g_strdup (member_name);
662
663   return TRUE;
664 }
665
666 /**
667  * json_reader_end_member:
668  * @reader: a #JsonReader
669  *
670  * Moves the cursor back to the previous node after being positioned
671  * inside an object
672  *
673  * This function resets the error state of @reader, if any was set
674  *
675  * Since: 0.12
676  */
677 void
678 json_reader_end_member (JsonReader *reader)
679 {
680   JsonReaderPrivate *priv;
681   JsonNode *tmp;
682
683   g_return_if_fail (JSON_IS_READER (reader));
684
685   json_reader_unset_error (reader);
686
687   priv = reader->priv;
688
689   if (priv->previous_node != NULL)
690     tmp = json_node_get_parent (priv->previous_node);
691   else
692     tmp = NULL;
693
694   g_free (priv->current_member);
695   priv->current_member = NULL;
696
697   priv->current_node = priv->previous_node;
698   priv->previous_node = tmp;
699 }
700
701 /**
702  * json_reader_list_members:
703  * @reader: a #JsonReader
704  *
705  * Retrieves a list of member names from the current position, if @reader
706  * is positioned on an object.
707  *
708  * Return value: (transfer full): a newly allocated, %NULL-terminated
709  *   array of strings holding the members name. Use g_strfreev() when
710  *   done.
711  *
712  * Since: 0.14
713  */
714 gchar **
715 json_reader_list_members (JsonReader *reader)
716 {
717   JsonReaderPrivate *priv;
718   GList *members, *l;
719   gchar **retval;
720   gint i;
721
722   g_return_val_if_fail (JSON_IS_READER (reader), NULL);
723
724   priv = reader->priv;
725
726   if (priv->current_node == NULL)
727     {
728       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE,
729                              _("No node available at the current position"));
730       return NULL;
731     }
732
733   if (!JSON_NODE_HOLDS_OBJECT (priv->current_node))
734     {
735       json_reader_set_error (reader, JSON_READER_ERROR_NO_OBJECT,
736                              _("The current position holds a '%s' and not an object"),
737                              json_node_type_get_name (JSON_NODE_TYPE (priv->current_node)));
738       return NULL;
739     }
740
741   members = json_object_get_members (json_node_get_object (priv->current_node));
742   if (members == NULL)
743     return NULL;
744
745   retval = g_new (gchar*, g_list_length (members) + 1);
746   for (l = members, i = 0; l != NULL; l = l->next, i += 1)
747     retval[i] = g_strdup (l->data);
748
749   retval[i] = NULL;
750
751   g_list_free (members);
752
753   return retval;
754 }
755
756 /**
757  * json_reader_count_members:
758  * @reader: a #JsonReader
759  *
760  * Counts the members of the current position, if @reader is
761  * positioned on an object
762  *
763  * Return value: the number of members, or -1. In case of failure
764  *   the #JsonReader is set in an error state
765  *
766  * Since: 0.12
767  */
768 gint
769 json_reader_count_members (JsonReader *reader)
770 {
771   JsonReaderPrivate *priv;
772
773   g_return_val_if_fail (JSON_IS_READER (reader), -1);
774
775   priv = reader->priv;
776
777   if (priv->current_node == NULL)
778     {
779       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE,
780                              _("No node available at the current position"));
781       return -1;
782     }
783
784   if (!JSON_NODE_HOLDS_OBJECT (priv->current_node))
785     {
786       json_reader_set_error (reader, JSON_READER_ERROR_NO_OBJECT,
787                              _("The current position holds a '%s' and not an object"),
788                              json_node_type_get_name (JSON_NODE_TYPE (priv->current_node)));
789       return -1;
790     }
791
792   return json_object_get_size (json_node_get_object (priv->current_node));
793 }
794
795 /**
796  * json_reader_get_value:
797  * @reader: a #JsonReader
798  *
799  * Retrieves the #JsonNode of the current position of @reader
800  *
801  * Return value: (transfer none): a #JsonNode, or %NULL. The returned node
802  *   is owned by the #JsonReader and it should not be modified or freed
803  *   directly
804  *
805  * Since: 0.12
806  */
807 JsonNode *
808 json_reader_get_value (JsonReader *reader)
809 {
810   JsonNode *node;
811
812   g_return_val_if_fail (JSON_IS_READER (reader), NULL);
813   json_reader_return_val_if_error_set (reader, NULL);
814
815   if (reader->priv->current_node == NULL)
816     {
817       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE,
818                              _("No node available at the current position"));
819       return NULL;
820     }
821
822   node = reader->priv->current_node;
823
824   if (!JSON_NODE_HOLDS_VALUE (node))
825     {
826       json_reader_set_error (reader, JSON_READER_ERROR_NO_VALUE,
827                              _("The current position holds a '%s' and not a value"),
828                              json_node_type_get_name (JSON_NODE_TYPE (node)));
829       return NULL;
830     }
831
832   return reader->priv->current_node;
833 }
834
835 /**
836  * json_reader_get_int_value:
837  * @reader: a #JsonReader
838  *
839  * Retrieves the integer value of the current position of @reader
840  *
841  * Return value: the integer value
842  *
843  * Since: 0.12
844  */
845 gint64
846 json_reader_get_int_value (JsonReader *reader)
847 {
848   JsonNode *node;
849
850   g_return_val_if_fail (JSON_IS_READER (reader), 0);
851   json_reader_return_val_if_error_set (reader, 0);
852
853   if (reader->priv->current_node == NULL)
854     {
855       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE,
856                              _("No node available at the current position"));
857       return 0;
858     }
859
860   node = reader->priv->current_node;
861
862   if (!JSON_NODE_HOLDS_VALUE (node))
863     {
864       json_reader_set_error (reader, JSON_READER_ERROR_NO_VALUE,
865                              _("The current position holds a '%s' and not a value"),
866                              json_node_type_get_name (JSON_NODE_TYPE (node)));
867       return 0;
868     }
869
870   if (json_node_get_value_type (node) != G_TYPE_INT64)
871     {
872       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_TYPE,
873                              _("The current position does not hold an integer type"));
874       return 0;
875     }
876
877   return json_node_get_int (reader->priv->current_node);
878 }
879
880 /**
881  * json_reader_get_double_value:
882  * @reader: a #JsonReader
883  *
884  * Retrieves the floating point value of the current position of @reader
885  *
886  * Return value: the floating point value
887  *
888  * Since: 0.12
889  */
890 gdouble
891 json_reader_get_double_value (JsonReader *reader)
892 {
893   JsonNode *node;
894
895   g_return_val_if_fail (JSON_IS_READER (reader), 0.0);
896   json_reader_return_val_if_error_set (reader, 0.0);
897
898   if (reader->priv->current_node == NULL)
899     {
900       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE,
901                              _("No node available at the current position"));
902       return 0.0;
903     }
904
905   node = reader->priv->current_node;
906
907   if (!JSON_NODE_HOLDS_VALUE (node))
908     {
909       json_reader_set_error (reader, JSON_READER_ERROR_NO_VALUE,
910                              _("The current position holds a '%s' and not a value"),
911                              json_node_type_get_name (JSON_NODE_TYPE (node)));
912       return 0.0;
913     }
914
915   if (json_node_get_value_type (node) != G_TYPE_DOUBLE)
916     {
917       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_TYPE,
918                              _("The current position does not hold a floating point type"));
919       return 0.0;
920     }
921
922   return json_node_get_double (reader->priv->current_node);
923 }
924
925 /**
926  * json_reader_get_string_value:
927  * @reader: a #JsonReader
928  *
929  * Retrieves the string value of the current position of @reader
930  *
931  * Return value: the string value
932  *
933  * Since: 0.12
934  */
935 const gchar *
936 json_reader_get_string_value (JsonReader *reader)
937 {
938   JsonNode *node;
939
940   g_return_val_if_fail (JSON_IS_READER (reader), NULL);
941   json_reader_return_val_if_error_set (reader, NULL);
942
943   if (reader->priv->current_node == NULL)
944     {
945       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE,
946                              _("No node available at the current position"));
947       return NULL;
948     }
949
950   node = reader->priv->current_node;
951
952   if (!JSON_NODE_HOLDS_VALUE (node))
953     {
954       json_reader_set_error (reader, JSON_READER_ERROR_NO_VALUE,
955                              _("The current position holds a '%s' and not a value"),
956                              json_node_type_get_name (JSON_NODE_TYPE (node)));
957       return NULL;
958     }
959
960   if (json_node_get_value_type (node) != G_TYPE_STRING)
961     {
962       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_TYPE,
963                              _("The current position does not hold a string type"));
964       return NULL;
965     }
966
967   return json_node_get_string (reader->priv->current_node);
968 }
969
970 /**
971  * json_reader_get_boolean_value:
972  * @reader: a #JsonReader
973  *
974  * Retrieves the boolean value of the current position of @reader
975  *
976  * Return value: the boolean value
977  *
978  * Since: 0.12
979  */
980 gboolean
981 json_reader_get_boolean_value (JsonReader *reader)
982 {
983   JsonNode *node;
984
985   g_return_val_if_fail (JSON_IS_READER (reader), FALSE);
986   json_reader_return_val_if_error_set (reader, FALSE);
987
988   if (reader->priv->current_node == NULL)
989     {
990       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE,
991                              _("No node available at the current position"));
992       return FALSE;
993     }
994
995   node = reader->priv->current_node;
996
997   if (!JSON_NODE_HOLDS_VALUE (node))
998     {
999       json_reader_set_error (reader, JSON_READER_ERROR_NO_VALUE,
1000                              _("The current position holds a '%s' and not a value"),
1001                              json_node_type_get_name (JSON_NODE_TYPE (node)));
1002       return FALSE;
1003     }
1004
1005   if (json_node_get_value_type (node) != G_TYPE_BOOLEAN)
1006     {
1007       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_TYPE,
1008                              _("The current position does not hold a boolean type"));
1009       return FALSE;
1010     }
1011
1012   return json_node_get_boolean (node);
1013 }
1014
1015 /**
1016  * json_reader_get_null_value:
1017  * @reader: a #JsonReader
1018  *
1019  * Checks whether the value of the current position of @reader is 'null'
1020  *
1021  * Return value: %TRUE if 'null' is set, and %FALSE otherwise
1022  *
1023  * Since: 0.12
1024  */
1025 gboolean
1026 json_reader_get_null_value (JsonReader *reader)
1027 {
1028   g_return_val_if_fail (JSON_IS_READER (reader), FALSE);
1029   json_reader_return_val_if_error_set (reader, FALSE);
1030
1031   if (reader->priv->current_node == NULL)
1032     {
1033       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE,
1034                              _("No node available at the current position"));
1035       return FALSE;
1036     }
1037
1038   return JSON_NODE_HOLDS_NULL (reader->priv->current_node);
1039 }
1040
1041 /**
1042  * json_reader_get_member_name:
1043  * @reader: a #JsonReader
1044  *
1045  * Retrieves the name of the current member.
1046  *
1047  * Return value: (transfer none): the name of the member, or %NULL
1048  *
1049  * Since: 0.14
1050  */
1051 const gchar *
1052 json_reader_get_member_name (JsonReader *reader)
1053 {
1054   g_return_val_if_fail (JSON_IS_READER (reader), NULL);
1055   json_reader_return_val_if_error_set (reader, NULL);
1056
1057   if (reader->priv->current_node == NULL)
1058     {
1059       json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE,
1060                              _("No node available at the current position"));
1061       return FALSE;
1062     }
1063
1064   return reader->priv->current_member;
1065 }