static gboolean balancer_fill_backends(balancer *b, liServer *srv, liValue *val) { if (val->type == LI_VALUE_ACTION) { backend be = { val->data.val_action.action, 0, BE_ALIVE, 0 }; assert(srv == val->data.val_action.srv); li_action_acquire(be.act); g_array_append_val(b->backends, be); return TRUE; } else if (val->type == LI_VALUE_LIST) { guint i; if (val->data.list->len == 0) { ERROR(srv, "%s", "expected non-empty list"); return FALSE; } for (i = 0; i < val->data.list->len; i++) { liValue *oa = g_array_index(val->data.list, liValue*, i); if (oa->type != LI_VALUE_ACTION) { ERROR(srv, "expected action at entry %u of list, got %s", i, li_value_type_string(oa->type)); return FALSE; } assert(srv == oa->data.val_action.srv); { backend be = { oa->data.val_action.action, 0, BE_ALIVE, 0 }; li_action_acquire(be.act); g_array_append_val(b->backends, be); } } return TRUE; } else {
static gboolean balancer_fill_backends(balancer *b, liServer *srv, liValue *val) { val = li_value_get_single_argument(val); if (LI_VALUE_ACTION == li_value_type(val)) { backend be; be.act = val->data.val_action.action; be.load = 0; be.state = BE_ALIVE; be.wake = 0; assert(srv == val->data.val_action.srv); li_action_acquire(be.act); g_array_append_val(b->backends, be); return TRUE; } else if (LI_VALUE_LIST == li_value_type(val)) { if (li_value_list_has_len(val, 0)) { ERROR(srv, "%s", "expected non-empty list"); return FALSE; } LI_VALUE_FOREACH(oa, val) if (LI_VALUE_ACTION != li_value_type(oa)) { ERROR(srv, "expected action at entry %u of list, got %s", _oa_i, li_value_type_string(oa)); return FALSE; } assert(srv == oa->data.val_action.srv); { backend be; be.act = oa->data.val_action.action; be.load = 0; be.state = BE_ALIVE; be.wake = 0; li_action_acquire(be.act); g_array_append_val(b->backends, be); } LI_VALUE_END_FOREACH() return TRUE; } else {
int li_lua_push_value(lua_State *L, liValue *value) { if (NULL == value) { lua_pushnil(L); return 1; } switch (value->type) { case LI_VALUE_NONE: lua_pushnil(L); break; case LI_VALUE_BOOLEAN: lua_pushboolean(L, value->data.boolean); break; case LI_VALUE_NUMBER: lua_pushinteger(L, value->data.number); break; case LI_VALUE_STRING: lua_pushlstring(L, GSTR_LEN(value->data.string)); break; case LI_VALUE_LIST: { lua_newtable(L); LI_VALUE_FOREACH(entry, value) li_lua_push_value(L, entry); lua_rawseti(L, -2, _entry_i + 1); LI_VALUE_END_FOREACH() /* kvlist lookup for string/nil keys */ lua_push_kvlist_metatable(L); lua_setmetatable(L, -2); } break; case LI_VALUE_HASH: { GHashTableIter it; gpointer pkey, pvalue; lua_newtable(L); g_hash_table_iter_init(&it, value->data.hash); while (g_hash_table_iter_next(&it, &pkey, &pvalue)) { GString *key = pkey; liValue *subval = pvalue; lua_pushlstring(L, GSTR_LEN(key)); li_lua_push_value(L, subval); lua_rawset(L, -3); } } break; case LI_VALUE_ACTION: li_action_acquire(value->data.val_action.action); li_lua_push_action(value->data.val_action.srv, L, value->data.val_action.action); break; case LI_VALUE_CONDITION: li_condition_acquire(value->data.val_cond.cond); li_lua_push_condition(value->data.val_cond.srv, L, value->data.val_cond.cond); break; default: /* ignore error and push nil */ lua_pushnil(L); break; } return 1; }
int li_lua_push_value(lua_State *L, liValue *value) { if (NULL == value) { lua_pushnil(L); return 1; } switch (value->type) { case LI_VALUE_NONE: lua_pushnil(L); break; case LI_VALUE_BOOLEAN: lua_pushboolean(L, value->data.boolean); break; case LI_VALUE_NUMBER: lua_pushinteger(L, value->data.number); break; case LI_VALUE_STRING: lua_pushlstring(L, GSTR_LEN(value->data.string)); break; case LI_VALUE_LIST: { GArray *list = value->data.list; guint i; lua_newtable(L); for (i = 0; i < list->len; i++) { liValue *subval = g_array_index(list, liValue*, i); li_lua_push_value(L, subval); lua_rawseti(L, -2, i); } } break; case LI_VALUE_HASH: { GHashTableIter it; gpointer pkey, pvalue; lua_newtable(L); g_hash_table_iter_init(&it, value->data.hash); while (g_hash_table_iter_next(&it, &pkey, &pvalue)) { GString *key = pkey; liValue *subval = pvalue; lua_pushlstring(L, GSTR_LEN(key)); li_lua_push_value(L, subval); lua_rawset(L, -3); } } break; case LI_VALUE_ACTION: li_action_acquire(value->data.val_action.action); li_lua_push_action(value->data.val_action.srv, L, value->data.val_action.action); break; case LI_VALUE_CONDITION: li_condition_acquire(value->data.val_cond.cond); li_lua_push_condition(value->data.val_cond.srv, L, value->data.val_cond.cond); break; default: /* ignore error and push nil */ lua_pushnil(L); break; } return 1; }
liValue* li_value_copy(liValue* val) { liValue *n; if (NULL == val) return NULL; switch (val->type) { case LI_VALUE_ACTION: li_action_acquire(val->data.val_action.action); n = li_value_new_action(val->data.val_action.srv, val->data.val_action.action); return n; case LI_VALUE_CONDITION: li_condition_acquire(val->data.val_cond.cond); n = li_value_new_condition(val->data.val_cond.srv, val->data.val_cond.cond); return n; default: return li_common_value_copy_(val); } return NULL; }
liValue* li_value_copy(liValue* val) { liValue *n; if (NULL == val) return NULL; switch (val->type) { case LI_VALUE_NONE: return li_value_new_none(); case LI_VALUE_BOOLEAN: return li_value_new_bool(val->data.boolean); case LI_VALUE_NUMBER: return li_value_new_number(val->data.number); case LI_VALUE_STRING: return li_value_new_string(g_string_new_len(GSTR_LEN(val->data.string))); /* list: we have to copy every value in the list! */ case LI_VALUE_LIST: n = li_value_new_list(); g_array_set_size(n->data.list, val->data.list->len); for (guint i = 0; i < val->data.list->len; i++) { g_array_index(n->data.list, liValue*, i) = li_value_copy(g_array_index(val->data.list, liValue*, i)); } return n; /* hash: iterate over hashtable, clone each value */ case LI_VALUE_HASH: n = li_value_new_hash(); { GHashTableIter iter; gpointer k, v; g_hash_table_iter_init(&iter, val->data.hash); while (g_hash_table_iter_next(&iter, &k, &v)) g_hash_table_insert(n->data.hash, g_string_new_len(GSTR_LEN((GString*)k)), li_value_copy((liValue*)v)); } return n; case LI_VALUE_ACTION: li_action_acquire(val->data.val_action.action); n = li_value_new_action(val->data.val_action.srv, val->data.val_action.action); return n; case LI_VALUE_CONDITION: li_condition_acquire(val->data.val_cond.cond); n = li_value_new_condition(val->data.val_cond.srv, val->data.val_cond.cond); return n; } return NULL; }
liValue* li_value_from_lua(liServer *srv, lua_State *L) { liValue *val; switch (lua_type(L, -1)) { case LUA_TNIL: lua_pop(L, 1); return NULL; case LUA_TBOOLEAN: val = li_value_new_bool(lua_toboolean(L, -1)); lua_pop(L, 1); return val; case LUA_TNUMBER: val = li_value_new_number(lua_tonumber(L, -1)); lua_pop(L, 1); return val; case LUA_TSTRING: val = li_value_new_string(li_lua_togstring(L, -1)); lua_pop(L, 1); return val; case LUA_TTABLE: val = li_value_from_lua_table(srv, L, -1); lua_pop(L, 1); return val; case LUA_TUSERDATA: { /* check for action */ liAction *a = li_lua_get_action(L, -1); if (a) { li_action_acquire(a); lua_pop(L, 1); return li_value_new_action(srv, a); } } { /* check for condition */ liCondition *c = li_lua_get_condition(L, -1); if (c) { li_condition_acquire(c); lua_pop(L, 1); return li_value_new_condition(srv, c); } } ERROR(srv, "%s", "Unknown lua userdata"); lua_pop(L, 1); return NULL; case LUA_TFUNCTION: { liAction *a = li_lua_make_action(L, -1); lua_pop(L, 1); return li_value_new_action(srv, a); } case LUA_TLIGHTUSERDATA: case LUA_TTHREAD: case LUA_TNONE: default: ERROR(srv, "Unexpected lua type: %s (%i)", lua_typename(L, lua_type(L, -1)), lua_type(L, -1)); lua_pop(L, 1); return NULL; } }