From 02e8acc0d2dd4effa073ee82fb69504254652e96 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Mon, 13 Feb 2023 19:37:59 -0400 Subject: [PATCH] Add ByteData methods for getting/setting number values. See #1594 --- src/modules/data/wrap_ByteData.cpp | 176 +++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) diff --git a/src/modules/data/wrap_ByteData.cpp b/src/modules/data/wrap_ByteData.cpp index 1b4a2d919..8ca6f48e2 100644 --- a/src/modules/data/wrap_ByteData.cpp +++ b/src/modules/data/wrap_ByteData.cpp @@ -20,6 +20,9 @@ #include "wrap_ByteData.h" #include "wrap_Data.h" +#include "common/config.h" + +#include namespace love { @@ -41,9 +44,182 @@ int w_ByteData_clone(lua_State *L) return 1; } +template +int w_ByteData_setT(lua_State *L) +{ + ByteData *t = luax_checkbytedata(L, 1); + int64 offset = (int64) luaL_checknumber(L, 2); + + bool istable = lua_type(L, 3) == LUA_TTABLE; + int nargs = std::max(1, istable ? (int) luax_objlen(L, 3) : lua_gettop(L) - 2); + + if (offset < 0 || offset + sizeof(T) * nargs > t->getSize()) + return luaL_error(L, ""); + + auto data = (T *)((uint8 *) t->getData() + offset); + + if (istable) + { + for (int i = 0; i < nargs; i++) + { + lua_rawgeti(L, 3, i + 1); + data[i] = (T) luaL_checknumber(L, -1); + lua_pop(L, 1); + } + } + else + { + for (int i = 0; i < nargs; i++) + data[i] = (T) luaL_checknumber(L, 3 + i); + } + + return 0; +} + +template +int w_ByteData_getT(lua_State *L) +{ + ByteData *t = luax_checkbytedata(L, 1); + int64 offset = (int64) luaL_checknumber(L, 2); + int count = (int) luaL_optinteger(L, 3, 1); + + if (count <= 0) + return luaL_error(L, "Invalid count parameter (must be greater than 0)"); + + if (offset < 0 || offset + sizeof(T) * count > t->getSize()) + return luaL_error(L, "The given offset and count parameters don't fit within the ByteData's size."); + + auto data = (const T *)((uint8 *) t->getData() + offset); + + for (int i = 0; i < count; i++) + lua_pushnumber(L, (lua_Number) data[i]); + + return count; +} + +int w_ByteData_setFloat(lua_State *L) +{ + return w_ByteData_setT(L); +} + +int w_ByteData_setDouble(lua_State *L) +{ + return w_ByteData_setT(L); +} + +int w_ByteData_setInt8(lua_State *L) +{ + return w_ByteData_setT(L); +} + +int w_ByteData_setUInt8(lua_State *L) +{ + return w_ByteData_setT(L); +} + +int w_ByteData_setInt16(lua_State *L) +{ + return w_ByteData_setT(L); +} + +int w_ByteData_setUInt16(lua_State *L) +{ + return w_ByteData_setT(L); +} + +int w_ByteData_setInt32(lua_State *L) +{ + return w_ByteData_setT(L); +} + +int w_ByteData_setUInt32(lua_State *L) +{ + return w_ByteData_setT(L); +} + +int w_ByteData_setInt64(lua_State *L) +{ + return w_ByteData_setT(L); +} + +int w_ByteData_setUInt64(lua_State *L) +{ + return w_ByteData_setT(L); +} + +int w_ByteData_getFloat(lua_State *L) +{ + return w_ByteData_getT(L); +} + +int w_ByteData_getDouble(lua_State *L) +{ + return w_ByteData_getT(L); +} + +int w_ByteData_getInt8(lua_State *L) +{ + return w_ByteData_getT(L); +} + +int w_ByteData_getUInt8(lua_State *L) +{ + return w_ByteData_getT(L); +} + +int w_ByteData_getInt16(lua_State *L) +{ + return w_ByteData_getT(L); +} + +int w_ByteData_getUInt16(lua_State *L) +{ + return w_ByteData_getT(L); +} + +int w_ByteData_getInt32(lua_State *L) +{ + return w_ByteData_getT(L); +} + +int w_ByteData_getUInt32(lua_State *L) +{ + return w_ByteData_getT(L); +} + +int w_ByteData_getInt64(lua_State *L) +{ + return w_ByteData_getT(L); +} + +int w_ByteData_getUInt64(lua_State *L) +{ + return w_ByteData_getT(L); +} + static const luaL_Reg w_ByteData_functions[] = { { "clone", w_ByteData_clone }, + { "setFloat", w_ByteData_setFloat }, + { "setDouble", w_ByteData_setDouble }, + { "setInt8", w_ByteData_setInt8 }, + { "setUInt8", w_ByteData_setUInt8 }, + { "setInt16", w_ByteData_setInt16 }, + { "setUInt16", w_ByteData_setUInt16 }, + { "setInt32", w_ByteData_setInt32 }, + { "setUInt32", w_ByteData_setUInt32 }, + { "setInt64", w_ByteData_setInt64 }, + { "setUInt64", w_ByteData_setUInt64 }, + { "getFloat", w_ByteData_getFloat }, + { "getDouble", w_ByteData_getDouble }, + { "getInt8", w_ByteData_getInt8 }, + { "getUInt8", w_ByteData_getUInt8 }, + { "getInt16", w_ByteData_getInt16 }, + { "getUInt16", w_ByteData_getUInt16 }, + { "getInt32", w_ByteData_getInt32 }, + { "getUInt32", w_ByteData_getUInt32 }, + { "getInt64", w_ByteData_getInt64 }, + { "getUInt64", w_ByteData_getUInt64 }, { 0, 0 } };