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; }