From 8e00e73b8e3fa954743dacee8c3d654b7144eec5 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 6 Nov 2024 16:26:35 +0300 Subject: [PATCH] add utf8.encode(...) --- doc/en/scripting/builtins/libutf8.md | 3 +++ doc/ru/scripting/builtins/libutf8.md | 3 +++ src/logic/scripting/lua/libs/libutf8.cpp | 25 ++++++++++++++----- src/logic/scripting/lua/lua_util.hpp | 16 +++++++++++- .../lua/usertypes/lua_type_bytearray.cpp | 2 +- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/doc/en/scripting/builtins/libutf8.md b/doc/en/scripting/builtins/libutf8.md index db8b31c5..86714fce 100644 --- a/doc/en/scripting/builtins/libutf8.md +++ b/doc/en/scripting/builtins/libutf8.md @@ -16,6 +16,9 @@ utf8.length(text: str) -> int -- Returns the code of the first character of the string utf8.codepoint(chars: str) -> int +-- Encodes codepoint in UTF-8 +utf8.encode(codepoint: int) -> str + -- Returns a substring from position startchar to endchar inclusive utf8.sub(text: str, startchar: int, [optional] endchar: int) -> str diff --git a/doc/ru/scripting/builtins/libutf8.md b/doc/ru/scripting/builtins/libutf8.md index 50d64e72..394eb522 100644 --- a/doc/ru/scripting/builtins/libutf8.md +++ b/doc/ru/scripting/builtins/libutf8.md @@ -16,6 +16,9 @@ utf8.length(text: str) -> int -- Возвращает код первого символа строки utf8.codepoint(chars: str) -> int +-- Кодирует код в в UTF-8 +utf8.encode(codepoint: int) -> str + -- Возвращает подстроку от позиции startchar до endchar включительно utf8.sub(text: str, startchar: int, [опционально] endchar: int) -> str diff --git a/src/logic/scripting/lua/libs/libutf8.cpp b/src/logic/scripting/lua/libs/libutf8.cpp index 3512624f..8d0628f0 100644 --- a/src/logic/scripting/lua/libs/libutf8.cpp +++ b/src/logic/scripting/lua/libs/libutf8.cpp @@ -6,8 +6,8 @@ #include "../lua_custom_types.hpp" #include "util/stringutil.hpp" -static int l_encode(lua::State* L) { - std::string_view string = lua::require_string(L, 1); +static int l_tobytes(lua::State* L) { + std::string_view string = lua::require_lstring(L, 1); if (lua::toboolean(L, 2)) { lua::createtable(L, string.length(), 0); for (size_t i = 0; i < string.length(); i++) { @@ -23,11 +23,16 @@ static int l_encode(lua::State* L) { return 1; } -static int l_decode(lua::State* L) { +static int l_tostring(lua::State* L) { if (lua::istable(L, 1)) { size_t size = lua::objlen(L, 1); util::Buffer buffer(size); - return lua::pushstring(L, std::string(buffer.data(), size)); + for (size_t i = 0; i < size; i++) { + lua::rawgeti(L, i + 1); + buffer[i] = lua::tointeger(L, -1); + lua::pop(L); + } + return lua::pushlstring(L, buffer.data(), size); } else if (auto bytes = lua::touserdata(L, 1)) { return lua::pushstring( L, @@ -80,13 +85,21 @@ static int l_lower(lua::State* L) { return lua::pushstring(L, util::u32str2str_utf8(string)); } +static int l_encode(lua::State* L) { + auto integer = lua::tointeger(L, 1); + ubyte bytes[4]; + size_t count = util::encode_utf8(integer, bytes); + return lua::pushlstring(L, bytes, count); +} + const luaL_Reg utf8lib[] = { - {"tobytes", lua::wrap}, - {"tostring", lua::wrap}, + {"tobytes", lua::wrap}, + {"tostring", lua::wrap}, {"length", lua::wrap}, {"codepoint", lua::wrap}, {"sub", lua::wrap}, {"upper", lua::wrap}, {"lower", lua::wrap}, + {"encode", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/lua_util.hpp b/src/logic/scripting/lua/lua_util.hpp index c6e56e4b..138aa73c 100644 --- a/src/logic/scripting/lua/lua_util.hpp +++ b/src/logic/scripting/lua/lua_util.hpp @@ -177,6 +177,11 @@ namespace lua { return 1; } + inline int pushlstring(lua::State* L, const void* chars, size_t size) { + lua_pushlstring(L, reinterpret_cast(chars), size); + return 1; + } + template inline int pushfstring(lua_State* L, const char* fmt, Args... args) { lua_pushfstring(L, fmt, args...); @@ -456,7 +461,16 @@ namespace lua { if (!isstring(L, idx)) { throw luaerror("string expected at " + std::to_string(idx)); } - return tostring(L, idx); + return lua_tostring(L, idx); + } + + inline std::string_view require_lstring(lua::State* L, int idx) { + if (!isstring(L, idx)) { + throw luaerror("string expected at " + std::to_string(idx)); + } + size_t len; + const char* chars = lua_tolstring(L, idx, &len); + return std::string_view(chars, len); } std::wstring require_wstring(lua::State*, int idx); diff --git a/src/logic/scripting/lua/usertypes/lua_type_bytearray.cpp b/src/logic/scripting/lua/usertypes/lua_type_bytearray.cpp index 7be3fc10..0493995b 100644 --- a/src/logic/scripting/lua/usertypes/lua_type_bytearray.cpp +++ b/src/logic/scripting/lua/usertypes/lua_type_bytearray.cpp @@ -94,7 +94,7 @@ static int l_meta_index(lua::State* L) { if (static_cast(index) > data.size()) { return 0; } - return pushinteger(L, data[index]); + return pushinteger(L, data.at(index)); } static int l_meta_newindex(lua::State* L) {