Install json_object_private.h file
[platform/upstream/json-c.git] / json_object_iterator.c
1 /**
2 *******************************************************************************
3 * @file json_object_iterator.c
4 *
5 * Copyright (c) 2009-2012 Hewlett-Packard Development Company, L.P.
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the MIT license. See COPYING for details.
9 *
10 *******************************************************************************
11 */
12 #include "config.h"
13
14 #include <stddef.h>
15
16 #include "json.h"
17 #include "json_object_private.h"
18
19 #include "json_object_iterator.h"
20
21 /**
22  * How It Works
23  *
24  * For each JSON Object, json-c maintains a linked list of zero
25  * or more lh_entry (link-hash entry) structures inside the
26  * Object's link-hash table (lh_table).
27  *
28  * Each lh_entry structure on the JSON Object's linked list
29  * represents a single name/value pair.  The "next" field of the
30  * last lh_entry in the list is set to NULL, which terminates
31  * the list.
32  *
33  * We represent a valid iterator that refers to an actual
34  * name/value pair via a pointer to the pair's lh_entry
35  * structure set as the iterator's opaque_ field.
36  *
37  * We follow json-c's current pair list representation by
38  * representing a valid "end" iterator (one that refers past the
39  * last pair) with a NULL value in the iterator's opaque_ field.
40  *
41  * A JSON Object without any pairs in it will have the "head"
42  * field of its lh_table structure set to NULL.  For such an
43  * object, json_object_iter_begin will return an iterator with
44  * the opaque_ field set to NULL, which is equivalent to the
45  * "end" iterator.
46  *
47  * When iterating, we simply update the iterator's opaque_ field
48  * to point to the next lh_entry structure in the linked list.
49  * opaque_ will become NULL once we iterate past the last pair
50  * in the list, which makes the iterator equivalent to the "end"
51  * iterator.
52  */
53
54 /// Our current representation of the "end" iterator;
55 ///
56 /// @note May not always be NULL
57 static const void *kObjectEndIterValue = NULL;
58
59 /**
60  * ****************************************************************************
61  */
62 struct json_object_iterator json_object_iter_begin(struct json_object *obj)
63 {
64         struct json_object_iterator iter;
65         struct lh_table *pTable;
66
67         /// @note json_object_get_object will return NULL if passed NULL
68         ///       or a non-json_type_object instance
69         pTable = json_object_get_object(obj);
70         JASSERT(NULL != pTable);
71
72         /// @note For a pair-less Object, head is NULL, which matches our
73         ///       definition of the "end" iterator
74         iter.opaque_ = pTable->head;
75         return iter;
76 }
77
78 /**
79  * ****************************************************************************
80  */
81 struct json_object_iterator json_object_iter_end(const struct json_object *obj)
82 {
83         struct json_object_iterator iter;
84
85         JASSERT(NULL != obj);
86         JASSERT(json_object_is_type(obj, json_type_object));
87
88         iter.opaque_ = kObjectEndIterValue;
89
90         return iter;
91 }
92
93 /**
94  * ****************************************************************************
95  */
96 void json_object_iter_next(struct json_object_iterator *iter)
97 {
98         JASSERT(NULL != iter);
99         JASSERT(kObjectEndIterValue != iter->opaque_);
100
101         iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next;
102 }
103
104 /**
105  * ****************************************************************************
106  */
107 const char *json_object_iter_peek_name(const struct json_object_iterator *iter)
108 {
109         JASSERT(NULL != iter);
110         JASSERT(kObjectEndIterValue != iter->opaque_);
111
112         return (const char *)(((const struct lh_entry *)iter->opaque_)->k);
113 }
114
115 /**
116  * ****************************************************************************
117  */
118 struct json_object *json_object_iter_peek_value(const struct json_object_iterator *iter)
119 {
120         JASSERT(NULL != iter);
121         JASSERT(kObjectEndIterValue != iter->opaque_);
122
123         return (struct json_object *)lh_entry_v((const struct lh_entry *)iter->opaque_);
124 }
125
126 /**
127  * ****************************************************************************
128  */
129 json_bool json_object_iter_equal(const struct json_object_iterator *iter1,
130                                  const struct json_object_iterator *iter2)
131 {
132         JASSERT(NULL != iter1);
133         JASSERT(NULL != iter2);
134
135         return (iter1->opaque_ == iter2->opaque_);
136 }
137
138 /**
139  * ****************************************************************************
140  */
141 struct json_object_iterator json_object_iter_init_default(void)
142 {
143         struct json_object_iterator iter;
144
145         /**
146          * @note Make this a negative, invalid value, such that
147          *       accidental access to it would likely be trapped by the
148          *       hardware as an invalid address.
149          */
150         iter.opaque_ = NULL;
151
152         return iter;
153 }