diff --git a/doc/en/scripting/filesystem.md b/doc/en/scripting/filesystem.md index 79e2e7f1..49a7b273 100644 --- a/doc/en/scripting/filesystem.md +++ b/doc/en/scripting/filesystem.md @@ -75,6 +75,55 @@ file.mkdirs(path: str) -> bool Create directories chain. Returns true if new directory created. +## *json* library + +The library contains functions for serializing and deserializing tables: + +```python +json.tostring(object: table, human_readable: bool=false) -> str +``` + +Serializes an object into a JSON string. If the second parameter is **true**, multi-line human-readable formatting will be used, rather than the compact format used by default. + +```python +json.parse(code: str) -> table +``` + +Parses a JSON string into a table. + +## *toml* library + +The library contains functions for serializing and deserializing tables: + +```python +toml.tostring(object: table) -> str +``` + +Serializes an object into a TOML string. + +```python +toml.parse(code: str) -> table +``` + +Parses a TOML string into a table. + +## *bjson* library + +The library contains functions for working with the binary data exchange format [vcbjson](../../specs/binary_json_spec.md). + +```lua +-- Encodes a table into a byte array +bjson.tobytes( + -- encoded table + value: table, + -- compression + [optional] compression: bool=true +) --> Bytearray + +-- Decodes a byte array into a table +bjson.frombytes(bytes: table | Bytearray) --> table +``` + ## Storing data in a world When saving pack data in the world, you should use the function: diff --git a/doc/ru/scripting/filesystem.md b/doc/ru/scripting/filesystem.md index 20cd3570..7e6d658f 100644 --- a/doc/ru/scripting/filesystem.md +++ b/doc/ru/scripting/filesystem.md @@ -125,6 +125,23 @@ toml.parse(code: str) -> table Парсит TOML строку в таблицу. +## Библиотека bjson + +Библиотека содержит функции для работы с двоичным форматом обмена данными [vcbjson](../../specs/binary_json_spec.md). + +```lua +-- Кодирует таблицу в массив байт +bjson.tobytes( + -- кодируемая таблица + value: table, + -- сжатие + [опционально] compression: bool=true +) --> Bytearray + +-- Декодирует массив байт в таблицу +bjson.frombytes(bytes: table | Bytearray) --> table +``` + ## Сохранение данных в мире При сохранении данных пака в мире следует использовать функцию diff --git a/src/logic/scripting/lua/libs/api_lua.hpp b/src/logic/scripting/lua/libs/api_lua.hpp index f856f5f4..2ac9c1e8 100644 --- a/src/logic/scripting/lua/libs/api_lua.hpp +++ b/src/logic/scripting/lua/libs/api_lua.hpp @@ -15,12 +15,14 @@ // Libraries extern const luaL_Reg audiolib[]; +extern const luaL_Reg bjsonlib[]; extern const luaL_Reg blocklib[]; extern const luaL_Reg cameralib[]; extern const luaL_Reg consolelib[]; extern const luaL_Reg corelib[]; extern const luaL_Reg entitylib[]; extern const luaL_Reg filelib[]; +extern const luaL_Reg generationlib[]; extern const luaL_Reg guilib[]; extern const luaL_Reg hudlib[]; extern const luaL_Reg inputlib[]; @@ -30,7 +32,6 @@ extern const luaL_Reg jsonlib[]; extern const luaL_Reg mat4lib[]; extern const luaL_Reg packlib[]; extern const luaL_Reg playerlib[]; -extern const luaL_Reg generationlib[]; extern const luaL_Reg quatlib[]; // quat.cpp extern const luaL_Reg timelib[]; extern const luaL_Reg tomllib[]; diff --git a/src/logic/scripting/lua/libs/libbjson.cpp b/src/logic/scripting/lua/libs/libbjson.cpp new file mode 100644 index 00000000..fa3dcfd7 --- /dev/null +++ b/src/logic/scripting/lua/libs/libbjson.cpp @@ -0,0 +1,40 @@ +#include "coders/binary_json.hpp" +#include "api_lua.hpp" +#include "util/Buffer.hpp" +#include "../lua_custom_types.hpp" + +static int l_tobytes(lua::State* L) { + auto value = lua::tovalue(L, 1); + bool compress = true; + if (lua::gettop(L) >= 2) { + compress = lua::toboolean(L, 2); + } + return lua::newuserdata( + L, json::to_binary(value, compress) + ); +} + +static int l_frombytes(lua::State* L) { + if (lua::istable(L, 1)) { + size_t len = lua::objlen(L, 1); + util::Buffer buffer(len); + for (size_t i = 0; i < len; i++) { + lua::rawgeti(L, i + 1); + buffer[i] = lua::tointeger(L, -1); + lua::pop(L); + } + return lua::pushvalue(L, json::from_binary(buffer.data(), len)); + } else if (auto bytes = lua::touserdata(L, -1)) { + const auto& buffer = bytes->data(); + return lua::pushvalue( + L, json::from_binary(buffer.data(), buffer.size()) + ); + } else { + throw std::runtime_error("table or Bytearray expected"); + } +} + +const luaL_Reg bjsonlib[] = { + {"tobytes", lua::wrap}, + {"frombytes", lua::wrap}, + {NULL, NULL}}; diff --git a/src/logic/scripting/lua/lua_engine.cpp b/src/logic/scripting/lua/lua_engine.cpp index 42ea18ec..fd40e612 100644 --- a/src/logic/scripting/lua/lua_engine.cpp +++ b/src/logic/scripting/lua/lua_engine.cpp @@ -39,6 +39,7 @@ static void remove_lib_funcs( } static void create_libs(State* L, StateType stateType) { + openlib(L, "bjson", bjsonlib); openlib(L, "block", blocklib); openlib(L, "core", corelib); openlib(L, "file", filelib);