1/**
2*******************************************************************************
3* @file json_object_iterator.h
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* @brief  json-c forces clients to use its private data
11*         structures for JSON Object iteration.  This API
12*         corrects that by abstracting the private json-c
13*         details.
14*
15* API attributes: <br>
16*   * Thread-safe: NO<br>
17*   * Reentrant: NO
18*
19*******************************************************************************
20*/
21
22
23#ifndef JSON_OBJECT_ITERATOR_H
24#define JSON_OBJECT_ITERATOR_H
25
26#include <stddef.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32/**
33 * Forward declaration for the opaque iterator information.
34 */
35struct json_object_iter_info_;
36
37/**
38 * The opaque iterator that references a name/value pair within
39 * a JSON Object instance or the "end" iterator value.
40 */
41struct json_object_iterator {
42    const void* opaque_;
43};
44
45
46/**
47 * forward declaration of json-c's JSON value instance structure
48 */
49struct json_object;
50
51
52/**
53 * Initializes an iterator structure to a "default" value that
54 * is convenient for initializing an iterator variable to a
55 * default state (e.g., initialization list in a class'
56 * constructor).
57 *
58 * @code
59 * struct json_object_iterator iter = json_object_iter_init_default();
60 * MyClass() : iter_(json_object_iter_init_default())
61 * @endcode
62 *
63 * @note The initialized value doesn't reference any specific
64 *       pair, is considered an invalid iterator, and MUST NOT
65 *       be passed to any json-c API that expects a valid
66 *       iterator.
67 *
68 * @note User and internal code MUST NOT make any assumptions
69 *       about and dependencies on the value of the "default"
70 *       iterator value.
71 *
72 * @return json_object_iterator
73 */
74struct json_object_iterator
75json_object_iter_init_default(void);
76
77/** Retrieves an iterator to the first pair of the JSON Object.
78 *
79 * @warning 	Any modification of the underlying pair invalidates all
80 * 		iterators to that pair.
81 *
82 * @param obj	JSON Object instance (MUST be of type json_object)
83 *
84 * @return json_object_iterator If the JSON Object has at
85 *              least one pair, on return, the iterator refers
86 *              to the first pair. If the JSON Object doesn't
87 *              have any pairs, the returned iterator is
88 *              equivalent to the "end" iterator for the same
89 *              JSON Object instance.
90 *
91 * @code
92 * struct json_object_iterator it;
93 * struct json_object_iterator itEnd;
94 * struct json_object* obj;
95 *
96 * obj = json_tokener_parse("{'first':'george', 'age':100}");
97 * it = json_object_iter_begin(obj);
98 * itEnd = json_object_iter_end(obj);
99 *
100 * while (!json_object_iter_equal(&it, &itEnd)) {
101 *     printf("%s\n",
102 *            json_object_iter_peek_name(&it));
103 *     json_object_iter_next(&it);
104 * }
105 *
106 * @endcode
107 */
108struct json_object_iterator
109json_object_iter_begin(struct json_object* obj);
110
111/** Retrieves the iterator that represents the position beyond the
112 *  last pair of the given JSON Object instance.
113 *
114 *  @warning Do NOT write code that assumes that the "end"
115 *        iterator value is NULL, even if it is so in a
116 *        particular instance of the implementation.
117 *
118 *  @note The reason we do not (and MUST NOT) provide
119 *        "json_object_iter_is_end(json_object_iterator* iter)"
120 *        type of API is because it would limit the underlying
121 *        representation of name/value containment (or force us
122 *        to add additional, otherwise unnecessary, fields to
123 *        the iterator structure). The "end" iterator and the
124 *        equality test method, on the other hand, permit us to
125 *        cleanly abstract pretty much any reasonable underlying
126 *        representation without burdening the iterator
127 *        structure with unnecessary data.
128 *
129 *  @note For performance reasons, memorize the "end" iterator prior
130 *        to any loop.
131 *
132 * @param obj JSON Object instance (MUST be of type json_object)
133 *
134 * @return json_object_iterator On return, the iterator refers
135 *              to the "end" of the Object instance's pairs
136 *              (i.e., NOT the last pair, but "beyond the last
137 *              pair" value)
138 */
139struct json_object_iterator
140json_object_iter_end(const struct json_object* obj);
141
142/** Returns an iterator to the next pair, if any
143 *
144 * @warning	Any modification of the underlying pair
145 *       	invalidates all iterators to that pair.
146 *
147 * @param iter [IN/OUT] Pointer to iterator that references a
148 *         name/value pair; MUST be a valid, non-end iterator.
149 *         WARNING: bad things will happen if invalid or "end"
150 *         iterator is passed. Upon return will contain the
151 *         reference to the next pair if there is one; if there
152 *         are no more pairs, will contain the "end" iterator
153 *         value, which may be compared against the return value
154 *         of json_object_iter_end() for the same JSON Object
155 *         instance.
156 */
157void
158json_object_iter_next(struct json_object_iterator* iter);
159
160
161/** Returns a const pointer to the name of the pair referenced
162 *  by the given iterator.
163 *
164 * @param iter pointer to iterator that references a name/value
165 *             pair; MUST be a valid, non-end iterator.
166 *
167 * @warning	bad things will happen if an invalid or
168 *             	"end" iterator is passed.
169 *
170 * @return const char* Pointer to the name of the referenced
171 *         name/value pair.  The name memory belongs to the
172 *         name/value pair, will be freed when the pair is
173 *         deleted or modified, and MUST NOT be modified or
174 *         freed by the user.
175 */
176const char*
177json_object_iter_peek_name(const struct json_object_iterator* iter);
178
179
180/** Returns a pointer to the json-c instance representing the
181 *  value of the referenced name/value pair, without altering
182 *  the instance's reference count.
183 *
184 * @param iter 	pointer to iterator that references a name/value
185 *             	pair; MUST be a valid, non-end iterator.
186 *
187 * @warning	bad things will happen if invalid or
188 *             "end" iterator is passed.
189 *
190 * @return struct json_object* Pointer to the json-c value
191 *         instance of the referenced name/value pair;  the
192 *         value's reference count is not changed by this
193 *         function: if you plan to hold on to this json-c node,
194 *         take a look at json_object_get() and
195 *         json_object_put(). IMPORTANT: json-c API represents
196 *         the JSON Null value as a NULL json_object instance
197 *         pointer.
198 */
199struct json_object*
200json_object_iter_peek_value(const struct json_object_iterator* iter);
201
202
203/** Tests two iterators for equality.  Typically used to test
204 *  for end of iteration by comparing an iterator to the
205 *  corresponding "end" iterator (that was derived from the same
206 *  JSON Object instance).
207 *
208 *  @note The reason we do not (and MUST NOT) provide
209 *        "json_object_iter_is_end(json_object_iterator* iter)"
210 *        type of API is because it would limit the underlying
211 *        representation of name/value containment (or force us
212 *        to add additional, otherwise unnecessary, fields to
213 *        the iterator structure). The equality test method, on
214 *        the other hand, permits us to cleanly abstract pretty
215 *        much any reasonable underlying representation.
216 *
217 * @param iter1 Pointer to first valid, non-NULL iterator
218 * @param iter2 POinter to second valid, non-NULL iterator
219 *
220 * @warning	if a NULL iterator pointer or an uninitialized
221 *       	or invalid iterator, or iterators derived from
222 *       	different JSON Object instances are passed, bad things
223 *       	will happen!
224 *
225 * @return json_bool non-zero if iterators are equal (i.e., both
226 *         reference the same name/value pair or are both at
227 *         "end"); zero if they are not equal.
228 */
229json_bool
230json_object_iter_equal(const struct json_object_iterator* iter1,
231                       const struct json_object_iterator* iter2);
232
233
234#ifdef __cplusplus
235}
236#endif
237
238
239#endif /* JSON_OBJECT_ITERATOR_H */
240