int serialize_kvp_as_json(lua_sandbox* lsb, serialization_data* data, int isHash) { static const char array_start = '[', array_end = ']'; static const char hash_start = '{', hash_end = '}'; int kindex = -2, vindex = -1, result = 0; if (ignore_value_type_json(lsb, vindex)) return 0; if (ignore_key(lsb, kindex)) return 0; if (isHash) { if (serialize_data_as_json(lsb, kindex, &lsb->output)) return 1; if (appendc(&lsb->output, ':')) return 1; } if (lua_type(lsb->lua, vindex) == LUA_TTABLE) { const void* ptr = lua_topointer(lsb->lua, vindex); table_ref* seen = find_table_ref(&data->tables, ptr); if (seen == NULL) { seen = add_table_ref(&data->tables, ptr, 0); if (seen != NULL) { char start, end; lua_rawgeti(lsb->lua, vindex, 1); int hash = lua_isnil(lsb->lua, -1); lua_pop(lsb->lua, 1); // remove the test value if (hash) { start = hash_start; end = hash_end; } else { start = array_start; end = array_end; } if (appendc(&lsb->output, start)) return 1; if (serialize_table_as_json(lsb, data, hash)) return 1; if (appendc(&lsb->output, end)) return 1; } else { snprintf(lsb->error_message, LSB_ERROR_SIZE, "serialize table out of memory"); return 1; } } else { snprintf(lsb->error_message, LSB_ERROR_SIZE, "table contains an internal or circular reference"); return 1; } } else { result = serialize_data_as_json(lsb, vindex, &lsb->output); } return result; }
int serialize_kvp(lua_sandbox* lsb, serialization_data* data, size_t parent) { int kindex = -2, vindex = -1; if (ignore_value_type(lsb, data, vindex)) return 0; int result = serialize_data(lsb, kindex, &lsb->m_output); if (result != 0) return result; size_t pos = data->m_keys.m_pos; if (dynamic_snprintf(&data->m_keys, "%s[%s]", data->m_keys.m_data + parent, lsb->m_output.m_data)) { return 1; } fprintf(data->m_fh, "%s = ", data->m_keys.m_data + pos); if (lua_type(lsb->m_lua, vindex) == LUA_TTABLE) { const void* ptr = lua_topointer(lsb->m_lua, vindex); table_ref* seen = find_table_ref(&data->m_tables, ptr); if (seen == NULL) { seen = add_table_ref(&data->m_tables, ptr, pos); if (seen != NULL) { data->m_keys.m_pos += 1; fprintf(data->m_fh, "{}\n"); result = serialize_table(lsb, data, pos); } else { snprintf(lsb->m_error_message, ERROR_SIZE, "preserve table out of memory"); return 1; } } else { data->m_keys.m_pos = pos; fprintf(data->m_fh, "%s\n", data->m_keys.m_data + seen->m_name_pos); } } else { data->m_keys.m_pos = pos; result = serialize_data(lsb, vindex, &lsb->m_output); if (result == 0) { fprintf(data->m_fh, "%s\n", lsb->m_output.m_data); } } return result; }
static lsb_err_value serialize_kvp(lsb_lua_sandbox *lsb, serialization_data *data, size_t parent) { lsb_err_value ret = NULL; lua_CFunction fp = NULL; int kindex = -2, vindex = -1; if (ignore_value_type(lsb, data, vindex, &fp)) { return ret; } ret = serialize_data(lsb, kindex, &lsb->output); if (ret) { return ret; } size_t pos = data->keys.pos; ret = lsb_outputf(&data->keys, "%s[%s]", data->keys.buf + parent, lsb->output.buf); if (ret) return ret; if (lua_type(lsb->lua, vindex) == LUA_TTABLE) { const void *ptr = lua_topointer(lsb->lua, vindex); table_ref *seen = find_table_ref(&data->tables, ptr); if (seen == NULL) { seen = add_table_ref(&data->tables, ptr, pos); if (seen != NULL) { data->keys.pos += 1; fprintf(data->fh, "%s = {}\n", data->keys.buf + pos); ret = serialize_table(lsb, data, pos); } else { snprintf(lsb->error_message, LSB_ERROR_SIZE, "lsb_serialize preserve table out of memory"); return LSB_ERR_UTIL_OOM; } } else { fprintf(data->fh, "%s = ", data->keys.buf + pos); data->keys.pos = pos; fprintf(data->fh, "%s\n", data->keys.buf + seen->name_pos); } } else if (lua_type(lsb->lua, vindex) == LUA_TUSERDATA) { void *ud = lua_touserdata(lsb->lua, vindex); table_ref *seen = find_table_ref(&data->tables, ud); if (seen == NULL) { seen = add_table_ref(&data->tables, ud, pos); if (seen != NULL) { data->keys.pos += 1; lua_pushlightuserdata(lsb->lua, data->keys.buf + pos); lua_pushlightuserdata(lsb->lua, &lsb->output); lsb->output.pos = 0; int result = fp(lsb->lua); lua_pop(lsb->lua, 2); // remove the key and the output if (!result) { size_t n = fwrite(lsb->output.buf, 1, lsb->output.pos, data->fh); if (n != lsb->output.pos) { snprintf(lsb->error_message, LSB_ERROR_SIZE, "lsb_serialize failed %s", data->keys.buf + pos); return LSB_ERR_LUA; } } } else { snprintf(lsb->error_message, LSB_ERROR_SIZE, "lsb_serialize out of memory %s", data->keys.buf + pos); return LSB_ERR_UTIL_OOM; } } else { fprintf(data->fh, "%s = ", data->keys.buf + pos); data->keys.pos = pos; fprintf(data->fh, "%s\n", data->keys.buf + seen->name_pos); } } else { fprintf(data->fh, "%s = ", data->keys.buf + pos); data->keys.pos = pos; ret = serialize_data(lsb, vindex, &lsb->output); if (!ret) { fprintf(data->fh, "%s\n", lsb->output.buf); } } return ret; }