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
29 extern "C" {
30 #endif
31 
32 /**
33  * Forward declaration for the opaque iterator information.
34  */
35 struct 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  */
41 struct json_object_iterator {
42     const void* opaque_;
43 };
44 
45 
46 /**
47  * forward declaration of json-c's JSON value instance structure
48  */
49 struct 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  */
74 struct json_object_iterator
75 json_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  */
108 struct json_object_iterator
109 json_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  */
139 struct json_object_iterator
140 json_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  */
157 void
158 json_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  */
176 const char*
177 json_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  */
199 struct json_object*
200 json_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  */
229 json_bool
230 json_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