Merge pull request #21 from kdopen/add_iterator
Add new iterator implementation and some NULL-pointer safety
This commit is contained in:
30
debug.h
30
debug.h
@@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||||
* Michael Clark <michael@metaparadigm.com>
|
* Michael Clark <michael@metaparadigm.com>
|
||||||
|
* Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See COPYING for details.
|
* it under the terms of the MIT license. See COPYING for details.
|
||||||
@@ -12,6 +13,8 @@
|
|||||||
#ifndef _DEBUG_H_
|
#ifndef _DEBUG_H_
|
||||||
#define _DEBUG_H_
|
#define _DEBUG_H_
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -25,21 +28,40 @@ extern void mc_debug(const char *msg, ...);
|
|||||||
extern void mc_error(const char *msg, ...);
|
extern void mc_error(const char *msg, ...);
|
||||||
extern void mc_info(const char *msg, ...);
|
extern void mc_info(const char *msg, ...);
|
||||||
|
|
||||||
|
#ifndef __STRING
|
||||||
|
#define __STRING(x) #x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PARSER_BROKEN_FIXED
|
||||||
|
|
||||||
|
#define JASSERT(cond) do {} while(0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define JASSERT(cond) do { \
|
||||||
|
if (!(cond)) { \
|
||||||
|
mc_error("cjson assert failure %s:%d : cond \"" __STRING(cond) "failed\n", __FILE__, __LINE__); \
|
||||||
|
*(int *)0 = 1;\
|
||||||
|
abort(); \
|
||||||
|
}\
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MC_ABORT(x, ...) mc_abort(x, ##__VA_ARGS__)
|
||||||
|
#define MC_ERROR(x, ...) mc_error(x, ##__VA_ARGS__)
|
||||||
|
|
||||||
#ifdef MC_MAINTAINER_MODE
|
#ifdef MC_MAINTAINER_MODE
|
||||||
#define MC_SET_DEBUG(x) mc_set_debug(x)
|
#define MC_SET_DEBUG(x) mc_set_debug(x)
|
||||||
#define MC_GET_DEBUG() mc_get_debug()
|
#define MC_GET_DEBUG() mc_get_debug()
|
||||||
#define MC_SET_SYSLOG(x) mc_set_syslog(x)
|
#define MC_SET_SYSLOG(x) mc_set_syslog(x)
|
||||||
#define MC_ABORT(x, ...) mc_abort(x, ##__VA_ARGS__)
|
|
||||||
#define MC_DEBUG(x, ...) mc_debug(x, ##__VA_ARGS__)
|
#define MC_DEBUG(x, ...) mc_debug(x, ##__VA_ARGS__)
|
||||||
#define MC_ERROR(x, ...) mc_error(x, ##__VA_ARGS__)
|
|
||||||
#define MC_INFO(x, ...) mc_info(x, ##__VA_ARGS__)
|
#define MC_INFO(x, ...) mc_info(x, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define MC_SET_DEBUG(x) if (0) mc_set_debug(x)
|
#define MC_SET_DEBUG(x) if (0) mc_set_debug(x)
|
||||||
#define MC_GET_DEBUG() (0)
|
#define MC_GET_DEBUG() (0)
|
||||||
#define MC_SET_SYSLOG(x) if (0) mc_set_syslog(x)
|
#define MC_SET_SYSLOG(x) if (0) mc_set_syslog(x)
|
||||||
#define MC_ABORT(x, ...) if (0) mc_abort(x, ##__VA_ARGS__)
|
|
||||||
#define MC_DEBUG(x, ...) if (0) mc_debug(x, ##__VA_ARGS__)
|
#define MC_DEBUG(x, ...) if (0) mc_debug(x, ##__VA_ARGS__)
|
||||||
#define MC_ERROR(x, ...) if (0) mc_error(x, ##__VA_ARGS__)
|
|
||||||
#define MC_INFO(x, ...) if (0) mc_info(x, ##__VA_ARGS__)
|
#define MC_INFO(x, ...) if (0) mc_info(x, ##__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
2
json.h
2
json.h
@@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||||
* Michael Clark <michael@metaparadigm.com>
|
* Michael Clark <michael@metaparadigm.com>
|
||||||
|
* Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See COPYING for details.
|
* it under the terms of the MIT license. See COPYING for details.
|
||||||
@@ -23,6 +24,7 @@ extern "C" {
|
|||||||
#include "json_util.h"
|
#include "json_util.h"
|
||||||
#include "json_object.h"
|
#include "json_object.h"
|
||||||
#include "json_tokener.h"
|
#include "json_tokener.h"
|
||||||
|
#include "json_object_iterator.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||||
* Michael Clark <michael@metaparadigm.com>
|
* Michael Clark <michael@metaparadigm.com>
|
||||||
|
* Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See COPYING for details.
|
* it under the terms of the MIT license. See COPYING for details.
|
||||||
@@ -24,11 +25,13 @@
|
|||||||
#include "json_object.h"
|
#include "json_object.h"
|
||||||
#include "json_object_private.h"
|
#include "json_object_private.h"
|
||||||
#include "json_util.h"
|
#include "json_util.h"
|
||||||
|
#include "json_tokener.h"
|
||||||
|
|
||||||
#if !HAVE_STRNDUP
|
#if !HAVE_STRNDUP
|
||||||
char* strndup(const char* str, size_t n);
|
char* strndup(const char* str, size_t n);
|
||||||
#endif /* !HAVE_STRNDUP */
|
#endif /* !HAVE_STRNDUP */
|
||||||
|
|
||||||
|
// Don't define this. It's not thread-safe.
|
||||||
/* #define REFCOUNT_DEBUG 1 */
|
/* #define REFCOUNT_DEBUG 1 */
|
||||||
|
|
||||||
const char *json_number_chars = "0123456789.+-eE";
|
const char *json_number_chars = "0123456789.+-eE";
|
||||||
@@ -260,8 +263,24 @@ void json_object_object_add(struct json_object* jso, const char *key,
|
|||||||
|
|
||||||
struct json_object* json_object_object_get(struct json_object* jso, const char *key)
|
struct json_object* json_object_object_get(struct json_object* jso, const char *key)
|
||||||
{
|
{
|
||||||
if(!jso) return NULL;
|
struct json_object *result;
|
||||||
return (struct json_object*) lh_table_lookup(jso->o.c_object, key);
|
json_object_object_get_ex(jso, key, &result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
|
||||||
|
{
|
||||||
|
if (NULL == jso) return FALSE;
|
||||||
|
|
||||||
|
switch(jso->o_type) {
|
||||||
|
case json_type_object:
|
||||||
|
return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
|
||||||
|
default:
|
||||||
|
if (value != NULL) {
|
||||||
|
*value = NULL;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void json_object_object_del(struct json_object* jso, const char *key)
|
void json_object_object_del(struct json_object* jso, const char *key)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||||
* Michael Clark <michael@metaparadigm.com>
|
* Michael Clark <michael@metaparadigm.com>
|
||||||
|
* Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See COPYING for details.
|
* it under the terms of the MIT license. See COPYING for details.
|
||||||
@@ -172,10 +173,33 @@ extern void json_object_object_add(struct json_object* obj, const char *key,
|
|||||||
* @param obj the json_object instance
|
* @param obj the json_object instance
|
||||||
* @param key the object field name
|
* @param key the object field name
|
||||||
* @returns the json_object associated with the given field name
|
* @returns the json_object associated with the given field name
|
||||||
|
* @deprecated Please use json_object_object_get_ex
|
||||||
*/
|
*/
|
||||||
extern struct json_object* json_object_object_get(struct json_object* obj,
|
extern struct json_object* json_object_object_get(struct json_object* obj,
|
||||||
const char *key);
|
const char *key);
|
||||||
|
|
||||||
|
/** Get the json_object associated with a given object field.
|
||||||
|
*
|
||||||
|
* This returns true if the key is found, false in all other cases (including
|
||||||
|
* if obj isn't a json_type_object).
|
||||||
|
*
|
||||||
|
* *No* reference counts will be changed. There is no need to manually adjust
|
||||||
|
* reference counts through the json_object_put/json_object_get methods unless
|
||||||
|
* you need to have the child (value) reference maintain a different lifetime
|
||||||
|
* than the owning parent (obj). Ownership of value is retained by obj.
|
||||||
|
*
|
||||||
|
* @param obj the json_object instance
|
||||||
|
* @param key the object field name
|
||||||
|
* @param value a pointer where to store a reference to the json_object
|
||||||
|
* associated with the given field name.
|
||||||
|
*
|
||||||
|
* It is safe to pass a NULL value.
|
||||||
|
* @returns whether or not the key exists
|
||||||
|
*/
|
||||||
|
extern json_bool json_object_object_get_ex(struct json_object* obj,
|
||||||
|
const char *key,
|
||||||
|
struct json_object **value);
|
||||||
|
|
||||||
/** Delete the given json_object field
|
/** Delete the given json_object field
|
||||||
*
|
*
|
||||||
* The reference count will be decremented for the deleted object. If there
|
* The reference count will be decremented for the deleted object. If there
|
||||||
|
|||||||
169
json_object_iterator.c
Normal file
169
json_object_iterator.c
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
/**
|
||||||
|
*******************************************************************************
|
||||||
|
* @file cjson_object_iterator.c
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the MIT license. See COPYING for details.
|
||||||
|
*
|
||||||
|
* @brief cjson forces clients to use its private data
|
||||||
|
* structures for JSON Object iteration. This API
|
||||||
|
* implementation corrects that by abstracting the
|
||||||
|
* private cjson details.
|
||||||
|
*
|
||||||
|
*******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "json.h"
|
||||||
|
#include "json_object_private.h"
|
||||||
|
|
||||||
|
#include "json_object_iterator.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How It Works
|
||||||
|
*
|
||||||
|
* For each JSON Object, cjson maintains a linked list of zero
|
||||||
|
* or more lh_entry (link-hash entry) structures inside the
|
||||||
|
* Object's link-hash table (lh_table).
|
||||||
|
*
|
||||||
|
* Each lh_entry structure on the JSON Object's linked list
|
||||||
|
* represents a single name/value pair. The "next" field of the
|
||||||
|
* last lh_entry in the list is set to NULL, which terminates
|
||||||
|
* the list.
|
||||||
|
*
|
||||||
|
* We represent a valid iterator that refers to an actual
|
||||||
|
* name/value pair via a pointer to the pair's lh_entry
|
||||||
|
* structure set as the iterator's opaque_ field.
|
||||||
|
*
|
||||||
|
* We follow cjson's current pair list representation by
|
||||||
|
* representing a valid "end" iterator (one that refers past the
|
||||||
|
* last pair) with a NULL value in the iterator's opaque_ field.
|
||||||
|
*
|
||||||
|
* A JSON Object without any pairs in it will have the "head"
|
||||||
|
* field of its lh_table structure set to NULL. For such an
|
||||||
|
* object, json_object_iter_begin will return an iterator with
|
||||||
|
* the opaque_ field set to NULL, which is equivalent to the
|
||||||
|
* "end" iterator.
|
||||||
|
*
|
||||||
|
* When iterating, we simply update the iterator's opaque_ field
|
||||||
|
* to point to the next lh_entry structure in the linked list.
|
||||||
|
* opaque_ will become NULL once we iterate past the last pair
|
||||||
|
* in the list, which makes the iterator equivalent to the "end"
|
||||||
|
* iterator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// Our current representation of the "end" iterator;
|
||||||
|
///
|
||||||
|
/// @note May not always be NULL
|
||||||
|
static const void* kObjectEndIterValue = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ****************************************************************************
|
||||||
|
*/
|
||||||
|
struct json_object_iterator
|
||||||
|
json_object_iter_begin(struct json_object* obj)
|
||||||
|
{
|
||||||
|
struct json_object_iterator iter;
|
||||||
|
struct lh_table* pTable;
|
||||||
|
|
||||||
|
/// @note json_object_get_object will return NULL if passed NULL
|
||||||
|
/// or a non-json_type_object instance
|
||||||
|
pTable = json_object_get_object(obj);
|
||||||
|
JASSERT(NULL != pTable);
|
||||||
|
|
||||||
|
/// @note For a pair-less Object, head is NULL, which matches our
|
||||||
|
/// definition of the "end" iterator
|
||||||
|
iter.opaque_ = pTable->head;
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ****************************************************************************
|
||||||
|
*/
|
||||||
|
struct json_object_iterator
|
||||||
|
json_object_iter_end(const struct json_object* obj)
|
||||||
|
{
|
||||||
|
struct json_object_iterator iter;
|
||||||
|
|
||||||
|
JASSERT(NULL != obj);
|
||||||
|
JASSERT(json_object_is_type(obj, json_type_object));
|
||||||
|
|
||||||
|
iter.opaque_ = kObjectEndIterValue;
|
||||||
|
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ****************************************************************************
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_object_iter_next(struct json_object_iterator* iter)
|
||||||
|
{
|
||||||
|
JASSERT(NULL != iter);
|
||||||
|
JASSERT(kObjectEndIterValue != iter->opaque_);
|
||||||
|
|
||||||
|
iter->opaque_ = ((struct lh_entry *)iter->opaque_)->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ****************************************************************************
|
||||||
|
*/
|
||||||
|
const char*
|
||||||
|
json_object_iter_peek_name(const struct json_object_iterator* iter)
|
||||||
|
{
|
||||||
|
JASSERT(NULL != iter);
|
||||||
|
JASSERT(kObjectEndIterValue != iter->opaque_);
|
||||||
|
|
||||||
|
return (const char*)(((struct lh_entry *)iter->opaque_)->k);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ****************************************************************************
|
||||||
|
*/
|
||||||
|
struct json_object*
|
||||||
|
json_object_iter_peek_value(const struct json_object_iterator* iter)
|
||||||
|
{
|
||||||
|
JASSERT(NULL != iter);
|
||||||
|
JASSERT(kObjectEndIterValue != iter->opaque_);
|
||||||
|
|
||||||
|
return (struct json_object*)(((struct lh_entry *)iter->opaque_)->v);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ****************************************************************************
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
json_object_iter_equal(const struct json_object_iterator* iter1,
|
||||||
|
const struct json_object_iterator* iter2)
|
||||||
|
{
|
||||||
|
JASSERT(NULL != iter1);
|
||||||
|
JASSERT(NULL != iter2);
|
||||||
|
|
||||||
|
return (iter1->opaque_ == iter2->opaque_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ****************************************************************************
|
||||||
|
*/
|
||||||
|
struct json_object_iterator
|
||||||
|
json_object_iter_init_default(void)
|
||||||
|
{
|
||||||
|
struct json_object_iterator iter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @note Make this a negative, invalid value, such that
|
||||||
|
* accidental access to it would likely be trapped by the
|
||||||
|
* hardware as an invalid address.
|
||||||
|
*/
|
||||||
|
iter.opaque_ = NULL;
|
||||||
|
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
254
json_object_iterator.h
Normal file
254
json_object_iterator.h
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
/**
|
||||||
|
*******************************************************************************
|
||||||
|
* @file json_object_iterator.h
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the MIT license. See COPYING for details.
|
||||||
|
*
|
||||||
|
* @brief cjson forces clients to use its private data
|
||||||
|
* structures for JSON Object iteration. This API
|
||||||
|
* corrects that by abstracting the private cjson
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* The intention is to add this API (and its
|
||||||
|
* implementation) to Palm's version of the cjson
|
||||||
|
* library, at which point it can be removed from the
|
||||||
|
* Wireless System Framework library implementation.
|
||||||
|
*
|
||||||
|
* API attributes:
|
||||||
|
* * Thread-safe: NO
|
||||||
|
* * Re-entrant: NO
|
||||||
|
*
|
||||||
|
*******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef JSON_OBJECT_ITERATOR_H
|
||||||
|
#define JSON_OBJECT_ITERATOR_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declaration for the opaque iterator information.
|
||||||
|
*/
|
||||||
|
struct json_object_iter_info_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The opaque iterator that references a name/value pair within
|
||||||
|
* a JSON Object intance or the "end" iterator value.
|
||||||
|
*/
|
||||||
|
struct json_object_iterator {
|
||||||
|
const void* opaque_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* forward declaration of cjson's JSON value instance structure
|
||||||
|
*/
|
||||||
|
struct json_object;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes an iterator structure to a "default" value that
|
||||||
|
* is convenient for initializing an iterator variable to a
|
||||||
|
* default state (e.g., initialization list in a class'
|
||||||
|
* constructor).
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* struct json_object_iterator iter = json_object_iter_init_default();
|
||||||
|
* MyClass() : iter_(json_object_iter_init_default())
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @note The initialized value doesn't reference any specific
|
||||||
|
* pair, is considered an invalid iterator, and MUST NOT
|
||||||
|
* be passed to any cjson API that expects a valid
|
||||||
|
* iterator.
|
||||||
|
*
|
||||||
|
* @note User and internal code MUST NOT make any assumptions
|
||||||
|
* about and dependencies on the value of the "default"
|
||||||
|
* iterator value.
|
||||||
|
*
|
||||||
|
* @return json_object_iterator
|
||||||
|
*/
|
||||||
|
struct json_object_iterator
|
||||||
|
json_object_iter_init_default(void);
|
||||||
|
|
||||||
|
/** Retrieves an iterator to the first pair of the JSON Object.
|
||||||
|
*
|
||||||
|
* @note WARNING: Any modification of the underlying pair
|
||||||
|
* invalidates all iterators to that pair.
|
||||||
|
*
|
||||||
|
* @param obj JSON Object instance (MUST be of type
|
||||||
|
* json_type_object)
|
||||||
|
*
|
||||||
|
* @return json_object_iterator If the JSON Object has at
|
||||||
|
* least one pair, on return, the iterator refers
|
||||||
|
* to the first pair. If the JSON Object doesn't
|
||||||
|
* have any pairs, the returned iterator is
|
||||||
|
* equivalent to the "end" iterator for the same
|
||||||
|
* JSON Object instance.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* struct json_object_iterator it;
|
||||||
|
* struct json_object_iterator itEnd;
|
||||||
|
* struct json_object* obj = json_tokener_parse(
|
||||||
|
* "{'first':'george', 'age':100}");
|
||||||
|
* json_object_iter_begin(obj, &it);
|
||||||
|
* json_object_iter_end(obj, &itEnd);
|
||||||
|
* while (!json_object_iter_equal(&it, &itEnd)) {
|
||||||
|
* printf("%s\n",
|
||||||
|
* json_object_iter_peek_name(&it));
|
||||||
|
* json_object_iter_next(&it);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* struct json_object* obj = json_tokener_parse(
|
||||||
|
* "{'first':'george', 'age':100}");
|
||||||
|
* struct json_object_iterator it;
|
||||||
|
* bool iterable = json_object_iter_begin(&it);
|
||||||
|
* if (iterable) {
|
||||||
|
* do {
|
||||||
|
* printf("%s\n", json_object_iter_peek_name(&it));
|
||||||
|
* } while (json_object_iter_next(&it));
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
struct json_object_iterator
|
||||||
|
json_object_iter_begin(struct json_object* obj);
|
||||||
|
|
||||||
|
/** Retrieves the iterator that represents the position beyond the
|
||||||
|
* last pair of the given JSON Object instance.
|
||||||
|
*
|
||||||
|
* @note WARNING: Do NOT write code that assumes that the "end"
|
||||||
|
* iterator value is NULL, even if it is so in a
|
||||||
|
* particular instance of the implementation.
|
||||||
|
*
|
||||||
|
* @note The reason we do not (and MUST NOT) provide
|
||||||
|
* "json_object_iter_is_end(json_object_iterator* iter)"
|
||||||
|
* type of API is because it would limit the underlying
|
||||||
|
* representation of name/value containment (or force us
|
||||||
|
* to add additional, otherwise unnecessary, fields to
|
||||||
|
* the iterator structure). The "end" iterator and the
|
||||||
|
* equality test method, on the other hand, permit us to
|
||||||
|
* cleanly abstract pretty much any reasonable underlying
|
||||||
|
* representation without burdening the iterator
|
||||||
|
* structure with unnecessary data.
|
||||||
|
*
|
||||||
|
* @note For performance reasons, memoize the "end" iterator prior
|
||||||
|
* to any loop.
|
||||||
|
*
|
||||||
|
* @param obj JSON Object instance (MUST be of type
|
||||||
|
* json_type_object)
|
||||||
|
*
|
||||||
|
* @return json_object_iterator On return, the iterator refers
|
||||||
|
* to the "end" of the Object instance's pairs
|
||||||
|
* (i.e., NOT the last pair, but "beyond the last
|
||||||
|
* pair" value)
|
||||||
|
*/
|
||||||
|
struct json_object_iterator
|
||||||
|
json_object_iter_end(const struct json_object* obj);
|
||||||
|
|
||||||
|
/** Returns an iterator to the next pair, if any
|
||||||
|
*
|
||||||
|
* @note WARNING: Any modification of the underlying pair
|
||||||
|
* invalidates all iterators to that pair.
|
||||||
|
*
|
||||||
|
* @param iter Iterator that references a name/value pair;
|
||||||
|
*
|
||||||
|
* @param iter [IN/OUT] Pointer to iterator that references a
|
||||||
|
* name/value pair; MUST be a valid, non-end iterator.
|
||||||
|
* WARNING: bad things will happen if invalid or "end"
|
||||||
|
* iterator is passed. Upon return will contain the
|
||||||
|
* reference to the next pair if there is one; if there
|
||||||
|
* are no more pairs, will contain the "end" iterator
|
||||||
|
* value, which may be compared against the return value
|
||||||
|
* of json_object_iter_end() for the same JSON Object
|
||||||
|
* instance.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_object_iter_next(struct json_object_iterator* iter);
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns a const pointer to the name of the pair referenced
|
||||||
|
* by the given iterator.
|
||||||
|
*
|
||||||
|
* @param iter pointer to iterator that references a name/value
|
||||||
|
* pair; MUST be a valid, non-end iterator.
|
||||||
|
* WARNING: bad things will happen if invalid or
|
||||||
|
* "end" iterator is passed.
|
||||||
|
*
|
||||||
|
* @return const char* Pointer to the name of the rerferenced
|
||||||
|
* name/value pair. The name memory belongs to the
|
||||||
|
* name/value pair, will be freed when the pair is
|
||||||
|
* deleted or modified, and MUST NOT be modified or
|
||||||
|
* freed by the user.
|
||||||
|
*/
|
||||||
|
const char*
|
||||||
|
json_object_iter_peek_name(const struct json_object_iterator* iter);
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns a pointer to the cjson instance representing the
|
||||||
|
* value of the referenced name/value pair, without altering
|
||||||
|
* the instance's reference count.
|
||||||
|
*
|
||||||
|
* @param iter pointer to iterator that references a name/value
|
||||||
|
* pair; MUST be a valid, non-end iterator.
|
||||||
|
* WARNING: bad things will happen if invalid or
|
||||||
|
* "end" iterator is passed.
|
||||||
|
*
|
||||||
|
* @return struct json_object* Pointer to the cjson value
|
||||||
|
* instance of the referenced name/value pair; the
|
||||||
|
* value's reference count is not changed by this
|
||||||
|
* function: if you plan to hold on to this cjson node,
|
||||||
|
* take a look at json_object_get() and
|
||||||
|
* json_object_put(). IMPORTANT: cjson API represents
|
||||||
|
* the JSON Null value as a NULL json_object instance
|
||||||
|
* pointer.
|
||||||
|
*/
|
||||||
|
struct json_object*
|
||||||
|
json_object_iter_peek_value(const struct json_object_iterator* iter);
|
||||||
|
|
||||||
|
|
||||||
|
/** Tests two iterators for equality. Typically used to test
|
||||||
|
* for end of iteration by comparing an iterator to the
|
||||||
|
* corresponding "end" iterator (that was derived from the same
|
||||||
|
* JSON Object instance).
|
||||||
|
*
|
||||||
|
* @note The reason we do not (and MUST NOT) provide
|
||||||
|
* "json_object_iter_is_end(json_object_iterator* iter)"
|
||||||
|
* type of API is because it would limit the underlying
|
||||||
|
* representation of name/value containment (or force us
|
||||||
|
* to add additional, otherwise unnecessary, fields to
|
||||||
|
* the iterator structure). The equality test method, on
|
||||||
|
* the other hand, permits us to cleanly abstract pretty
|
||||||
|
* much any reasonable underlying representation.
|
||||||
|
*
|
||||||
|
* @param iter1 Pointer to first valid, non-NULL iterator
|
||||||
|
* @param iter2 POinter to second valid, non-NULL iterator
|
||||||
|
*
|
||||||
|
* @note WARNING: if a NULL iterator pointer or an uninitialized
|
||||||
|
* or invalid iterator, or iterators derived from
|
||||||
|
* different JSON Object instances are passed, bad things
|
||||||
|
* will happen!
|
||||||
|
*
|
||||||
|
* @return bool non-zero if iterators are equal (i.e., both
|
||||||
|
* reference the same name/value pair or are both at
|
||||||
|
* "end"); zero if they are not equal.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
json_object_iter_equal(const struct json_object_iterator* iter1,
|
||||||
|
const struct json_object_iterator* iter2);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif // JSON_OBJECT_ITERATOR_H
|
||||||
17
linkhash.c
17
linkhash.c
@@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||||
* Michael Clark <michael@metaparadigm.com>
|
* Michael Clark <michael@metaparadigm.com>
|
||||||
|
* Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See COPYING for details.
|
* it under the terms of the MIT license. See COPYING for details.
|
||||||
@@ -174,11 +175,21 @@ struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k)
|
|||||||
|
|
||||||
const void* lh_table_lookup(struct lh_table *t, const void *k)
|
const void* lh_table_lookup(struct lh_table *t, const void *k)
|
||||||
{
|
{
|
||||||
struct lh_entry *e = lh_table_lookup_entry(t, k);
|
void *result;
|
||||||
if(e) return e->v;
|
lh_table_lookup_ex(t, k, &result);
|
||||||
return NULL;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json_bool lh_table_lookup_ex(struct lh_table* t, const void* k, void **v)
|
||||||
|
{
|
||||||
|
struct lh_entry *e = lh_table_lookup_entry(t, k);
|
||||||
|
if (e != NULL) {
|
||||||
|
if (v != NULL) *v = (void *)e->v;
|
||||||
|
return TRUE; /* key found */
|
||||||
|
}
|
||||||
|
if (v != NULL) *v = NULL;
|
||||||
|
return FALSE; /* key not found */
|
||||||
|
}
|
||||||
|
|
||||||
int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e)
|
int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e)
|
||||||
{
|
{
|
||||||
|
|||||||
12
linkhash.h
12
linkhash.h
@@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||||
* Michael Clark <michael@metaparadigm.com>
|
* Michael Clark <michael@metaparadigm.com>
|
||||||
|
* Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See COPYING for details.
|
* it under the terms of the MIT license. See COPYING for details.
|
||||||
@@ -12,6 +13,8 @@
|
|||||||
#ifndef _linkhash_h_
|
#ifndef _linkhash_h_
|
||||||
#define _linkhash_h_
|
#define _linkhash_h_
|
||||||
|
|
||||||
|
#include "json_object.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -241,9 +244,18 @@ extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k)
|
|||||||
* @param t the table to lookup
|
* @param t the table to lookup
|
||||||
* @param k a pointer to the key to lookup
|
* @param k a pointer to the key to lookup
|
||||||
* @return a pointer to the found value or NULL if it does not exist.
|
* @return a pointer to the found value or NULL if it does not exist.
|
||||||
|
* @deprecated Use lh_table_lookup_ex instead.
|
||||||
*/
|
*/
|
||||||
extern const void* lh_table_lookup(struct lh_table *t, const void *k);
|
extern const void* lh_table_lookup(struct lh_table *t, const void *k);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup a record in the table
|
||||||
|
* @param t the table to lookup
|
||||||
|
* @param k a pointer to the key to lookup
|
||||||
|
* @param v a pointer to a where to store the found value (set to NULL if it doesn't exist).
|
||||||
|
* @return whether or not the key was found
|
||||||
|
*/
|
||||||
|
extern json_bool lh_table_lookup_ex(struct lh_table *t, const void *k, void **v);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a record from the table.
|
* Delete a record from the table.
|
||||||
|
|||||||
Reference in New Issue
Block a user