#define json_object_object_foreach(obj, key, val) \
char *key = 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; \
({ \
if (entry##key) \
{ \
key = (char *)lh_entry_k(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; \
}); \
struct json_object *val = NULL; \
struct lh_entry *entry##key; \
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), \
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); \
entry##key = entry_next##key)
* @param iter the object iterator, use type json_object_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.val = (struct json_object *)lh_entry_v(iter.entry), iter.entry) \
: 0); \
- iter.entry = iter.entry->next)
+ iter.entry = lh_entry_next(iter.entry))
/* Array type methods */
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
{
/**
- * 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;
/**
* A flag for users of linkhash to know whether or not they
* need to free k.
+ * @deprecated use lh_entry_k_is_constant() instead.
*/
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;
/**
- * The next entry
+ * The next entry.
+ * @deprecated Use lh_entry_next() instead of accessing this directly.
*/
struct lh_entry *next;
/**
* The previous entry.
+ * @deprecated Use lh_entry_prev() instead of accessing this directly.
*/
struct lh_entry *prev;
};
/**
- * The hash table structure.
+ * The hash table structure. Outside of linkhash.c, treat this as opaque.
*/
struct lh_table
{
/**
* Size of our hash.
+ * @deprecated do not use outside of linkhash.c
*/
int size;
/**
* Numbers of entries.
+ * @deprecated Use lh_table_length() instead.
*/
int count;
/**
* The first entry.
+ * @deprecated Use lh_table_head() instead.
*/
struct lh_entry *head;
/**
* The last entry.
+ * @deprecated Do not use, may be removed in a future release.
*/
struct lh_entry *tail;
+ /**
+ * Internal storage of the actual table of entries.
+ * @deprecated do not use outside of linkhash.c
+ */
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;
+ /**
+ * @deprecated do not use outside of linkhash.c
+ */
lh_hash_fn *hash_fn;
+ /**
+ * @deprecated do not use outside of linkhash.c
+ */
lh_equal_fn *equal_fn;
};
typedef struct lh_table lh_table;
/**
* 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.
* @param tmp a struct lh_entry * variable to hold a temporary pointer to the next element
*/
#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.
*/
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);
/**
#define _LH_INLINE inline
#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.
*
return t->hash_fn(k);
}
-#undef _LH_INLINE
/**
* @deprecated Don't use this outside of linkhash.h:
*
* 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.
- * See also lh_entry.k_is_constant
+ * @see lh_entry_k_is_constant()
+ */
+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()
*/
-#define lh_entry_k(entry) _LH_UNCONST((entry)->k)
+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.
* 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.
*/
-#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
}