[core] add li_value_to_key_value_list: convert value hash to key-value list

personal/stbuehler/wip
Stefan Bühler 9 years ago
parent ab47f9b33c
commit 969818083e
  1. 5
      include/lighttpd/value.h
  2. 109
      src/main/value.c

@ -41,7 +41,9 @@ LI_API void li_value_list_append(liValue *list, liValue *item); /* list MUST be
LI_API void li_value_wrap_in_list(liValue *val);
LI_API liValue* li_value_copy(liValue* val);
LI_API void li_value_clear(liValue *val); /* frees content, sets value to LI_VALUE_NONE */
LI_API void li_value_free(liValue* val);
LI_API void li_value_move(liValue *dest, liValue *src);
LI_API const char* li_value_type_string(liValueType type);
@ -63,4 +65,7 @@ LI_API liCondition* li_value_extract_condition(liValue *val);
/* move the value content to a new value, set the old type to none */
LI_API liValue* li_value_extract(liValue *val);
/* converts value type to LI_VALUE_LIST, makes sure list contains (key,value) tuples, and the keys are all LI_VALUE_STRING or LI_VALUE_NONE */
LI_API liValue* li_value_to_key_value_list(liValue *val);
#endif

@ -118,8 +118,13 @@ liValue* li_value_copy(liValue* val) {
return NULL;
}
void li_value_free(liValue* val) {
if (!val) return;
static void _li_value_clear(liValue *val) {
memset(val, 0, sizeof(*val));
val->type = LI_VALUE_NONE;
}
void li_value_clear(liValue *val) {
if (NULL == val) return;
switch (val->type) {
case LI_VALUE_NONE:
@ -143,10 +148,22 @@ void li_value_free(liValue* val) {
li_condition_release(val->data.val_cond.srv, val->data.val_cond.cond);
break;
}
val->type = LI_VALUE_NONE;
_li_value_clear(val);
}
void li_value_free(liValue* val) {
if (NULL == val) return;
li_value_clear(val);
g_slice_free(liValue, val);
}
void li_value_move(liValue *dest, liValue *src) {
assert(NULL != dest && NULL != src && dest != src);
li_value_clear(dest);
*dest = *src;
_li_value_clear(src);
}
const char* li_value_type_string(liValueType type) {
switch(type) {
case LI_VALUE_NONE:
@ -231,7 +248,6 @@ GString *li_value_to_string(liValue *val) {
i++;
}
g_string_append_c(str, ']');
break;
}
@ -264,7 +280,7 @@ gpointer li_value_extract_ptr(liValue *val) {
ptr = val->data.string;
break;
case LI_VALUE_LIST:
ptr = val->data.list;
ptr = val->data.list;
break;
case LI_VALUE_HASH:
ptr = val->data.hash;
@ -276,44 +292,103 @@ gpointer li_value_extract_ptr(liValue *val) {
ptr = val->data.val_action.action;
break;
}
val->type = LI_VALUE_NONE;
_li_value_clear(val);
return ptr;
}
GString* li_value_extract_string(liValue *val) {
GString* result;
if (val->type != LI_VALUE_STRING) return NULL;
val->type = LI_VALUE_NONE;
return val->data.string;
result = val->data.string;
_li_value_clear(val);
return result;
}
GArray* li_value_extract_list(liValue *val) {
GArray* result;
if (val->type != LI_VALUE_LIST) return NULL;
val->type = LI_VALUE_NONE;
return val->data.list;
result = val->data.list;
_li_value_clear(val);
return result;
}
GHashTable* li_value_extract_hash(liValue *val) {
GHashTable* result;
if (val->type != LI_VALUE_HASH) return NULL;
val->type = LI_VALUE_NONE;
return val->data.hash;
result = val->data.hash;
_li_value_clear(val);
return result;
}
liAction* li_value_extract_action(liValue *val) {
liAction* result;
if (val->type != LI_VALUE_ACTION) return NULL;
val->type = LI_VALUE_NONE;
return val->data.val_action.action;
result = val->data.val_action.action;
_li_value_clear(val);
return result;
}
liCondition* li_value_extract_condition(liValue *val) {
liCondition* result;
if (val->type != LI_VALUE_CONDITION) return NULL;
val->type = LI_VALUE_NONE;
return val->data.val_cond.cond;
result = val->data.val_cond.cond;
_li_value_clear(val);
return result;
}
liValue* li_value_extract(liValue *val) {
liValue *v = li_value_new_none();
*v = *val;
val->type = LI_VALUE_NONE;
_li_value_clear(val);
return v;
}
liValue* li_value_to_key_value_list(liValue *val) {
if (val->type == LI_VALUE_HASH) {
GHashTable *table = li_value_extract_hash(val);
GArray *list;
GHashTableIter hti;
gpointer hkey, hvalue;
{
/* convert val to list */
liValue *vlist = li_value_new_list();
li_value_move(val, vlist);
li_value_free(vlist);
}
list = val->data.list;
g_hash_table_iter_init(&hti, table);
while (g_hash_table_iter_next(&hti, &hkey, &hvalue)) {
GString *htkey = hkey; liValue *htval = hvalue;
liValue *hkeyval = li_value_new_string(htkey);
liValue *pair = li_value_new_list();
g_array_append_val(pair->data.list, hkeyval);
g_array_append_val(pair->data.list, htval);
g_array_append_val(list, pair);
}
g_hash_table_steal_all(table); /* content was moved to list */
g_hash_table_destroy(table);
return val;
} else if (val->type == LI_VALUE_LIST) {
/* verify key-value list properties */
GArray *list = val->data.list;
guint i;
for (i = 0; i < list->len; ++i) {
liValue *lentry = g_array_index(list, liValue*, i);
GArray *entrylist;
liValue *key;
if (lentry->type != LI_VALUE_LIST) return NULL;
entrylist = lentry->data.list;
if (2 != entrylist->len) return NULL;
key = g_array_index(entrylist, liValue*, 0);
if (key->type != LI_VALUE_STRING && key->type != LI_VALUE_NONE) return NULL;
}
return val;
}
return NULL;
}

Loading…
Cancel
Save