Line data Source code
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 0 : 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 0 : 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 0 : iter.opaque_ = pTable->head; 75 0 : return iter; 76 : } 77 : 78 : /** 79 : * **************************************************************************** 80 : */ 81 0 : struct json_object_iterator json_object_iter_end(const struct json_object *obj) 82 : { 83 : (void)obj; 84 : struct json_object_iterator iter; 85 : 86 : JASSERT(NULL != obj); 87 : JASSERT(json_object_is_type(obj, json_type_object)); 88 : 89 0 : iter.opaque_ = kObjectEndIterValue; 90 : 91 0 : return iter; 92 : } 93 : 94 : /** 95 : * **************************************************************************** 96 : */ 97 0 : void json_object_iter_next(struct json_object_iterator *iter) 98 : { 99 : JASSERT(NULL != iter); 100 : JASSERT(kObjectEndIterValue != iter->opaque_); 101 : 102 0 : iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next; 103 0 : } 104 : 105 : /** 106 : * **************************************************************************** 107 : */ 108 0 : const char *json_object_iter_peek_name(const struct json_object_iterator *iter) 109 : { 110 : JASSERT(NULL != iter); 111 : JASSERT(kObjectEndIterValue != iter->opaque_); 112 : 113 0 : return (const char *)(((const struct lh_entry *)iter->opaque_)->k); 114 : } 115 : 116 : /** 117 : * **************************************************************************** 118 : */ 119 0 : struct json_object *json_object_iter_peek_value(const struct json_object_iterator *iter) 120 : { 121 : JASSERT(NULL != iter); 122 : JASSERT(kObjectEndIterValue != iter->opaque_); 123 : 124 0 : return (struct json_object *)lh_entry_v((const struct lh_entry *)iter->opaque_); 125 : } 126 : 127 : /** 128 : * **************************************************************************** 129 : */ 130 0 : json_bool json_object_iter_equal(const struct json_object_iterator *iter1, 131 : const struct json_object_iterator *iter2) 132 : { 133 : JASSERT(NULL != iter1); 134 : JASSERT(NULL != iter2); 135 : 136 0 : return (iter1->opaque_ == iter2->opaque_); 137 : } 138 : 139 : /** 140 : * **************************************************************************** 141 : */ 142 0 : struct json_object_iterator json_object_iter_init_default(void) 143 : { 144 : struct json_object_iterator iter; 145 : 146 : /** 147 : * @note Make this a negative, invalid value, such that 148 : * accidental access to it would likely be trapped by the 149 : * hardware as an invalid address. 150 : */ 151 0 : iter.opaque_ = NULL; 152 : 153 0 : return iter; 154 : }