Add linkhash accessor functions (lh_table_head(), lh_entry_next(), etc...) to pave the way for making the lh_table and lh_entry structure opaque in the future.
Update the docs to mark all members of those structures deprecated, and suggest what to use instead.
This commit is contained in:
@@ -4,9 +4,11 @@ Next Release 0.16
|
|||||||
|
|
||||||
Significant changes and bug fixes
|
Significant changes and bug fixes
|
||||||
---------------------------------
|
---------------------------------
|
||||||
* Introduction of constant JSON_C_OBJECT_ADD_CONSTANT_KEY
|
* Introduce constant JSON_C_OBJECT_ADD_CONSTANT_KEY
|
||||||
as a replacement of JSON_C_OBJECT_KEY_IS_CONSTANT,
|
as a replacement of JSON_C_OBJECT_KEY_IS_CONSTANT,
|
||||||
JSON_C_OBJECT_KEY_IS_CONSTANT becoming legacy.
|
JSON_C_OBJECT_KEY_IS_CONSTANT becoming legacy.
|
||||||
|
* Direct access to lh_table and lh_entry structure members is deprecated.
|
||||||
|
Use access functions instead, lh_table_head(), lh_entry_next(), etc...
|
||||||
* Drop REFCOUNT_DEBUG code.
|
* Drop REFCOUNT_DEBUG code.
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|||||||
@@ -427,7 +427,7 @@ EXTRACT_PACKAGE = NO
|
|||||||
# included in the documentation.
|
# included in the documentation.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
EXTRACT_STATIC = NO
|
EXTRACT_STATIC = YES
|
||||||
|
|
||||||
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
|
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
|
||||||
# locally in source files will be included in the documentation. If set to NO
|
# locally in source files will be included in the documentation. If set to NO
|
||||||
@@ -1984,7 +1984,9 @@ INCLUDE_FILE_PATTERNS =
|
|||||||
# recursively expanded use the := operator instead of the = operator.
|
# recursively expanded use the := operator instead of the = operator.
|
||||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
PREDEFINED = THIS_FUNCTION_IS_DEPRECATED(f)=f
|
PREDEFINED = \
|
||||||
|
_LH_INLINE=inline \
|
||||||
|
JSON_C_CONST_FUNCTION(func)=func
|
||||||
|
|
||||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||||
# tag can be used to specify a list of macro names that should be expanded. The
|
# tag can be used to specify a list of macro names that should be expanded. The
|
||||||
|
|||||||
@@ -498,7 +498,7 @@ static int json_object_object_to_json_string(struct json_object *jso, struct pri
|
|||||||
|
|
||||||
static void json_object_lh_entry_free(struct lh_entry *ent)
|
static void json_object_lh_entry_free(struct lh_entry *ent)
|
||||||
{
|
{
|
||||||
if (!ent->k_is_constant)
|
if (!lh_entry_k_is_constant(ent))
|
||||||
free(lh_entry_k(ent));
|
free(lh_entry_k(ent));
|
||||||
json_object_put((struct json_object *)lh_entry_v(ent));
|
json_object_put((struct json_object *)lh_entry_v(ent));
|
||||||
}
|
}
|
||||||
@@ -569,7 +569,7 @@ int json_object_object_add_ex(struct json_object *jso, const char *const key,
|
|||||||
existing_value = (json_object *)lh_entry_v(existing_entry);
|
existing_value = (json_object *)lh_entry_v(existing_entry);
|
||||||
if (existing_value)
|
if (existing_value)
|
||||||
json_object_put(existing_value);
|
json_object_put(existing_value);
|
||||||
existing_entry->v = val;
|
lh_entry_set_val(existing_entry, val);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -483,14 +483,14 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key
|
|||||||
#define json_object_object_foreach(obj, key, val) \
|
#define json_object_object_foreach(obj, key, val) \
|
||||||
char *key = NULL; \
|
char *key = NULL; \
|
||||||
struct json_object *val __attribute__((__unused__)) = NULL; \
|
struct json_object *val __attribute__((__unused__)) = NULL; \
|
||||||
for (struct lh_entry *entry##key = json_object_get_object(obj)->head, \
|
for (struct lh_entry *entry##key = lh_table_head(json_object_get_object(obj)), \
|
||||||
*entry_next##key = NULL; \
|
*entry_next##key = NULL; \
|
||||||
({ \
|
({ \
|
||||||
if (entry##key) \
|
if (entry##key) \
|
||||||
{ \
|
{ \
|
||||||
key = (char *)lh_entry_k(entry##key); \
|
key = (char *)lh_entry_k(entry##key); \
|
||||||
val = (struct json_object *)lh_entry_v(entry##key); \
|
val = (struct json_object *)lh_entry_v(entry##key); \
|
||||||
entry_next##key = entry##key->next; \
|
entry_next##key = lh_entry_next(entry##key); \
|
||||||
}; \
|
}; \
|
||||||
entry##key; \
|
entry##key; \
|
||||||
}); \
|
}); \
|
||||||
@@ -503,10 +503,10 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key
|
|||||||
struct json_object *val = NULL; \
|
struct json_object *val = NULL; \
|
||||||
struct lh_entry *entry##key; \
|
struct lh_entry *entry##key; \
|
||||||
struct lh_entry *entry_next##key = NULL; \
|
struct lh_entry *entry_next##key = NULL; \
|
||||||
for (entry##key = json_object_get_object(obj)->head; \
|
for (entry##key = lh_table_head(json_object_get_object(obj)); \
|
||||||
(entry##key ? (key = (char *)lh_entry_k(entry##key), \
|
(entry##key ? (key = (char *)lh_entry_k(entry##key), \
|
||||||
val = (struct json_object *)lh_entry_v(entry##key), \
|
val = (struct json_object *)lh_entry_v(entry##key), \
|
||||||
entry_next##key = entry##key->next, entry##key) \
|
entry_next##key = lh_entry_next(entry##key), entry##key) \
|
||||||
: 0); \
|
: 0); \
|
||||||
entry##key = entry_next##key)
|
entry##key = entry_next##key)
|
||||||
|
|
||||||
@@ -517,11 +517,11 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key
|
|||||||
* @param iter the object iterator, use type json_object_iter
|
* @param iter the object iterator, use type json_object_iter
|
||||||
*/
|
*/
|
||||||
#define json_object_object_foreachC(obj, iter) \
|
#define json_object_object_foreachC(obj, iter) \
|
||||||
for (iter.entry = json_object_get_object(obj)->head; \
|
for (iter.entry = lh_table_head(json_object_get_object(obj)); \
|
||||||
(iter.entry ? (iter.key = (char *)lh_entry_k(iter.entry), \
|
(iter.entry ? (iter.key = (char *)lh_entry_k(iter.entry), \
|
||||||
iter.val = (struct json_object *)lh_entry_v(iter.entry), iter.entry) \
|
iter.val = (struct json_object *)lh_entry_v(iter.entry), iter.entry) \
|
||||||
: 0); \
|
: 0); \
|
||||||
iter.entry = iter.entry->next)
|
iter.entry = lh_entry_next(iter.entry))
|
||||||
|
|
||||||
/* Array type methods */
|
/* Array type methods */
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ struct json_object_iterator json_object_iter_begin(struct json_object *obj)
|
|||||||
|
|
||||||
/// @note For a pair-less Object, head is NULL, which matches our
|
/// @note For a pair-less Object, head is NULL, which matches our
|
||||||
/// definition of the "end" iterator
|
/// definition of the "end" iterator
|
||||||
iter.opaque_ = pTable->head;
|
iter.opaque_ = lh_table_head(pTable);
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ void json_object_iter_next(struct json_object_iterator *iter)
|
|||||||
JASSERT(NULL != iter);
|
JASSERT(NULL != iter);
|
||||||
JASSERT(kObjectEndIterValue != iter->opaque_);
|
JASSERT(kObjectEndIterValue != iter->opaque_);
|
||||||
|
|
||||||
iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next;
|
iter->opaque_ = lh_entry_next(((const struct lh_entry *)iter->opaque_));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
102
linkhash.h
102
linkhash.h
@@ -80,64 +80,84 @@ typedef unsigned long(lh_hash_fn)(const void *k);
|
|||||||
typedef int(lh_equal_fn)(const void *k1, const void *k2);
|
typedef int(lh_equal_fn)(const void *k1, const void *k2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An entry in the hash table
|
* An entry in the hash table. Outside of linkhash.c, treat this as opaque.
|
||||||
*/
|
*/
|
||||||
struct lh_entry
|
struct lh_entry
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The key. Use lh_entry_k() instead of accessing this directly.
|
* The key.
|
||||||
|
* @deprecated Use lh_entry_k() instead of accessing this directly.
|
||||||
*/
|
*/
|
||||||
const void *k;
|
const void *k;
|
||||||
/**
|
/**
|
||||||
* A flag for users of linkhash to know whether or not they
|
* A flag for users of linkhash to know whether or not they
|
||||||
* need to free k.
|
* need to free k.
|
||||||
|
* @deprecated use lh_entry_k_is_constant() instead.
|
||||||
*/
|
*/
|
||||||
int k_is_constant;
|
int k_is_constant;
|
||||||
/**
|
/**
|
||||||
* The value. Use lh_entry_v() instead of accessing this directly.
|
* The value.
|
||||||
|
* @deprecated Use lh_entry_v() instead of accessing this directly.
|
||||||
*/
|
*/
|
||||||
const void *v;
|
const void *v;
|
||||||
/**
|
/**
|
||||||
* The next entry
|
* The next entry.
|
||||||
|
* @deprecated Use lh_entry_next() instead of accessing this directly.
|
||||||
*/
|
*/
|
||||||
struct lh_entry *next;
|
struct lh_entry *next;
|
||||||
/**
|
/**
|
||||||
* The previous entry.
|
* The previous entry.
|
||||||
|
* @deprecated Use lh_entry_prev() instead of accessing this directly.
|
||||||
*/
|
*/
|
||||||
struct lh_entry *prev;
|
struct lh_entry *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The hash table structure.
|
* The hash table structure. Outside of linkhash.c, treat this as opaque.
|
||||||
*/
|
*/
|
||||||
struct lh_table
|
struct lh_table
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Size of our hash.
|
* Size of our hash.
|
||||||
|
* @deprecated do not use outside of linkhash.c
|
||||||
*/
|
*/
|
||||||
int size;
|
int size;
|
||||||
/**
|
/**
|
||||||
* Numbers of entries.
|
* Numbers of entries.
|
||||||
|
* @deprecated Use lh_table_length() instead.
|
||||||
*/
|
*/
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The first entry.
|
* The first entry.
|
||||||
|
* @deprecated Use lh_table_head() instead.
|
||||||
*/
|
*/
|
||||||
struct lh_entry *head;
|
struct lh_entry *head;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The last entry.
|
* The last entry.
|
||||||
|
* @deprecated Do not use, may be removed in a future release.
|
||||||
*/
|
*/
|
||||||
struct lh_entry *tail;
|
struct lh_entry *tail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal storage of the actual table of entries.
|
||||||
|
* @deprecated do not use outside of linkhash.c
|
||||||
|
*/
|
||||||
struct lh_entry *table;
|
struct lh_entry *table;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A pointer onto the function responsible for freeing an entry.
|
* A pointer to the function responsible for freeing an entry.
|
||||||
|
* @deprecated do not use outside of linkhash.c
|
||||||
*/
|
*/
|
||||||
lh_entry_free_fn *free_fn;
|
lh_entry_free_fn *free_fn;
|
||||||
|
/**
|
||||||
|
* @deprecated do not use outside of linkhash.c
|
||||||
|
*/
|
||||||
lh_hash_fn *hash_fn;
|
lh_hash_fn *hash_fn;
|
||||||
|
/**
|
||||||
|
* @deprecated do not use outside of linkhash.c
|
||||||
|
*/
|
||||||
lh_equal_fn *equal_fn;
|
lh_equal_fn *equal_fn;
|
||||||
};
|
};
|
||||||
typedef struct lh_table lh_table;
|
typedef struct lh_table lh_table;
|
||||||
@@ -145,7 +165,7 @@ typedef struct lh_table lh_table;
|
|||||||
/**
|
/**
|
||||||
* Convenience list iterator.
|
* Convenience list iterator.
|
||||||
*/
|
*/
|
||||||
#define lh_foreach(table, entry) for (entry = table->head; entry; entry = entry->next)
|
#define lh_foreach(table, entry) for (entry = lh_table_head(table); entry; entry = lh_entry_next(entry))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lh_foreach_safe allows calling of deletion routine while iterating.
|
* lh_foreach_safe allows calling of deletion routine while iterating.
|
||||||
@@ -155,7 +175,7 @@ typedef struct lh_table lh_table;
|
|||||||
* @param tmp a struct lh_entry * variable to hold a temporary pointer to the next element
|
* @param tmp a struct lh_entry * variable to hold a temporary pointer to the next element
|
||||||
*/
|
*/
|
||||||
#define lh_foreach_safe(table, entry, tmp) \
|
#define lh_foreach_safe(table, entry, tmp) \
|
||||||
for (entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp)
|
for (entry = lh_table_head(table); entry && ((tmp = lh_entry_next(entry)) || 1); entry = tmp)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new linkhash table.
|
* Create a new linkhash table.
|
||||||
@@ -295,6 +315,9 @@ extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e);
|
|||||||
*/
|
*/
|
||||||
extern int lh_table_delete(struct lh_table *t, const void *k);
|
extern int lh_table_delete(struct lh_table *t, const void *k);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of entries in the table.
|
||||||
|
*/
|
||||||
extern int lh_table_length(struct lh_table *t);
|
extern int lh_table_length(struct lh_table *t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -318,6 +341,15 @@ int lh_table_resize(struct lh_table *t, int new_size);
|
|||||||
#define _LH_INLINE inline
|
#define _LH_INLINE inline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the first entry in the lh_table.
|
||||||
|
* @see lh_entry_next()
|
||||||
|
*/
|
||||||
|
static _LH_INLINE struct lh_entry *lh_table_head(const lh_table *t)
|
||||||
|
{
|
||||||
|
return t->head;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the hash of a key for a given table.
|
* Calculate the hash of a key for a given table.
|
||||||
*
|
*
|
||||||
@@ -334,7 +366,6 @@ static _LH_INLINE unsigned long lh_get_hash(const struct lh_table *t, const void
|
|||||||
return t->hash_fn(k);
|
return t->hash_fn(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef _LH_INLINE
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Don't use this outside of linkhash.h:
|
* @deprecated Don't use this outside of linkhash.h:
|
||||||
@@ -350,9 +381,22 @@ static _LH_INLINE unsigned long lh_get_hash(const struct lh_table *t, const void
|
|||||||
*
|
*
|
||||||
* lh_entry.k is const to indicate and help ensure that linkhash itself doesn't modify
|
* lh_entry.k is const to indicate and help ensure that linkhash itself doesn't modify
|
||||||
* it, but callers are allowed to do what they want with it.
|
* it, but callers are allowed to do what they want with it.
|
||||||
* See also lh_entry.k_is_constant
|
* @see lh_entry_k_is_constant()
|
||||||
*/
|
*/
|
||||||
#define lh_entry_k(entry) _LH_UNCONST((entry)->k)
|
static _LH_INLINE void *lh_entry_k(const struct lh_entry *e)
|
||||||
|
{
|
||||||
|
return _LH_UNCONST(e->k);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns 1 if the key for the given entry is constant, and thus
|
||||||
|
* does not need to be freed when the lh_entry is freed.
|
||||||
|
* @see lh_table_insert_w_hash()
|
||||||
|
*/
|
||||||
|
static _LH_INLINE int lh_entry_k_is_constant(const struct lh_entry *e)
|
||||||
|
{
|
||||||
|
return e->k_is_constant;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a non-const version of lh_entry.v.
|
* Return a non-const version of lh_entry.v.
|
||||||
@@ -360,7 +404,41 @@ static _LH_INLINE unsigned long lh_get_hash(const struct lh_table *t, const void
|
|||||||
* v is const to indicate and help ensure that linkhash itself doesn't modify
|
* v is const to indicate and help ensure that linkhash itself doesn't modify
|
||||||
* it, but callers are allowed to do what they want with it.
|
* it, but callers are allowed to do what they want with it.
|
||||||
*/
|
*/
|
||||||
#define lh_entry_v(entry) _LH_UNCONST((entry)->v)
|
static _LH_INLINE void *lh_entry_v(const struct lh_entry *e)
|
||||||
|
{
|
||||||
|
return _LH_UNCONST(e->v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the value for an entry. The caller is responsible for freeing
|
||||||
|
* the previous value.
|
||||||
|
*/
|
||||||
|
static _LH_INLINE void lh_entry_set_val(struct lh_entry *e, void *newval)
|
||||||
|
{
|
||||||
|
e->v = newval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the next element, or NULL if there is no next element.
|
||||||
|
* @see lh_table_head()
|
||||||
|
* @see lh_entry_prev()
|
||||||
|
*/
|
||||||
|
static _LH_INLINE struct lh_entry *lh_entry_next(const struct lh_entry *e)
|
||||||
|
{
|
||||||
|
return e->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the previous element, or NULL if there is no previous element.
|
||||||
|
* @see lh_table_head()
|
||||||
|
* @see lh_entry_next()
|
||||||
|
*/
|
||||||
|
static _LH_INLINE struct lh_entry *lh_entry_prev(const struct lh_entry *e)
|
||||||
|
{
|
||||||
|
return e->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef _LH_INLINE
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user