static void json_object_lh_entry_free(struct lh_entry *ent)
{
- free(ent->k);
+ if (!ent->k_is_constant)
+ free(ent->k);
json_object_put((struct json_object*)ent->v);
}
}
}
+void json_object_object_add_ex(struct json_object* jso,
+ const char *const key,
+ struct json_object *const val,
+ const unsigned opts)
+{
+ // We lookup the entry and replace the value, rather than just deleting
+ // and re-adding it, so the existing key remains valid.
+ json_object *existing_value = NULL;
+ struct lh_entry *existing_entry;
+ const unsigned long hash = lh_get_hash(jso->o.c_object, (void*)key);
+ existing_entry = (opts & JSON_C_OBJECT_ADD_KEY_IS_NEW) ? NULL :
+ lh_table_lookup_entry_w_hash(jso->o.c_object, (void*)key, hash);
+ if (!existing_entry)
+ {
+ void *const k = (opts & JSON_C_OBJECT_KEY_IS_CONSTANT) ?
+ (void*)key : strdup(key);
+ lh_table_insert_w_hash(jso->o.c_object, k, val, hash, opts);
+ return;
+ }
+ existing_value = (void *)existing_entry->v;
+ if (existing_value)
+ json_object_put(existing_value);
+ existing_entry->v = val;
+}
+
void json_object_object_add(struct json_object* jso, const char *key,
struct json_object *val)
{
existing_entry = lh_table_lookup_entry_w_hash(jso->o.c_object, (void*)key, hash);
if (!existing_entry)
{
- lh_table_insert_w_hash(jso->o.c_object, strdup(key), val, hash);
+ lh_table_insert_w_hash(jso->o.c_object, strdup(key), val, hash, 0);
return;
}
existing_value = (void *)existing_entry->v;
*/
#define JSON_C_TO_STRING_NOZERO (1<<2)
+/**
+ * A flag for the json_object_object_add_ex function which
+ * causes the value to be added without a check if it already exists.
+ * Note: it is the responsibilty of the caller to ensure that no
+ * key is added multiple times. If this is done, results are
+ * unpredictable. While this option is somewhat dangerous, it
+ * permits potentially large performance savings in code that
+ * knows for sure the key values are unique (e.g. because the
+ * code adds a well-known set of constant key values).
+ */
+#define JSON_C_OBJECT_ADD_KEY_IS_NEW (1<<1)
+/**
+ * A flag for the json_object_object_add_ex function which
+ * flags the key as being constant memory. This means that
+ * the key will NOT be copied via strdup(), resulting in a
+ * potentially huge performance win (malloc, strdup and
+ * free are usually performance hogs). It is acceptable to
+ * use this flag for keys in non-constant memory blocks if
+ * the caller ensure that the memory holding the key lives
+ * longer than the corresponding json object. However, this
+ * is somewhat dangerous and should only be done if really
+ * justified.
+ * The general use-case for this flag is cases where the
+ * key is given as a real constant value in the function
+ * call, e.g. as in
+ * json_object_object_add_ex(obj, "ip", json,
+ * JSON_C_OBJECT_KEY_IS_CONSTANT);
+ */
+#define JSON_C_OBJECT_KEY_IS_CONSTANT (1<<2)
+
#undef FALSE
#define FALSE ((json_bool)0)
extern void json_object_object_add(struct json_object* obj, const char *key,
struct json_object *val);
+/** Add an object field to a json_object of type json_type_object
+ *
+ * The semantics are identical to json_object_object_add, except that an
+ * additional flag fields gives you more control over some detail aspects
+ * of processing. See the description of JSON_C_OBJECT_ADD_* flags for more
+ * details.
+ *
+ * @param obj the json_object instance
+ * @param key the object field name (a private copy will be duplicated)
+ * @param val a json_object or NULL member to associate with the given field
+ * @param opts process-modifying options. To specify multiple options, use
+ * arithmetic or (OPT1|OPT2)
+ */
+extern void json_object_object_add_ex(struct json_object* obj, const char *key,
+ struct json_object *val, const unsigned opts);
+
/** Get the json_object associate with a given object field
*
* *No* reference counts will be changed. There is no need to manually adjust
}
-int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const unsigned long h)
+int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const unsigned long h, const unsigned opts)
{
unsigned long n;
}
t->table[n].k = k;
+ t->table[n].k_is_constant = (opts & JSON_C_OBJECT_KEY_IS_CONSTANT);
t->table[n].v = v;
t->count++;
}
int lh_table_insert(struct lh_table *t, void *k, const void *v)
{
- return lh_table_insert_w_hash(t, k, v, lh_get_hash(t, k));
+ return lh_table_insert_w_hash(t, k, v, lh_get_hash(t, k), 0);
}
* The key.
*/
void *k;
+ int k_is_constant;
/**
* The value.
*/
* @param k a pointer to the key to insert.
* @param v a pointer to the value to insert.
* @param h hash value of the key to insert
+ * @param opts opts, a subset of JSON_OBJECT_ADD_* flags is supported
*/
-extern int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const unsigned long h);
+extern int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const unsigned long h, const unsigned opts);
/**