Mercurial > pub > dyncall > bindings
diff lua/luadyncall/src/ldynstruct.c @ 0:0cfcc391201f
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:26:28 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lua/luadyncall/src/ldynstruct.c Thu Mar 19 22:26:28 2015 +0100 @@ -0,0 +1,111 @@ +#include "lua.h" +#include "lauxlib.h" +#include "dyncall.h" +#include "dyncall_signature.h" +#include <stddef.h> + +static int lua_newstruct(lua_State *L) +{ + size_t size; + void *addr; + size = (size_t) luaL_checkinteger(L, 1); + addr = lua_newuserdata(L, size); + return 1; +} + +static int lua_aslightuserdata(lua_State *L) +{ + lua_pushlightuserdata(L, (void*) (ptrdiff_t) luaL_checkinteger(L, 1) ); + return 1; +} + +/* +static int lua_newdynstruct(lua_State *L) +{ + size_t size; + void *addr; + size = (size_t) luaL_checkinteger(L, 1); + luaL_checktype(L, 2, LUA_TTABLE); + addr = lua_newuserdata(L, size); + lua_pushvalue(L, 2); + lua_setmetatable(L, 3); + return 1; +} +*/ + +int lua_dynpoke(lua_State *L) +{ + const char *ptr = (const char *) lua_touserdata(L, 1); + size_t offset = (ptrdiff_t) lua_tointeger(L, 2); + const char *typesig = (const char*) lua_tostring(L, 3); + const char *sig = typesig; + char ch; + ptr += offset; + while ((ch=*sig++) != '\0') { + switch(ch) { + case DC_SIGCHAR_BOOL: *((int*)ptr) = lua_toboolean(L, 4); break; + case DC_SIGCHAR_CHAR: *((char*)ptr) = (char) lua_tointeger(L, 4); break; + case DC_SIGCHAR_UCHAR: *((unsigned char*)ptr) = (unsigned char) lua_tointeger(L, 4); break; + case DC_SIGCHAR_SHORT: *((short*)ptr) = (short) lua_tointeger(L, 4); break; + case DC_SIGCHAR_USHORT: *((unsigned short*)ptr) = (unsigned short) lua_tointeger(L, 4); break; + case DC_SIGCHAR_INT: *((int*)ptr) = lua_tointeger(L, 4); break; + case DC_SIGCHAR_UINT: *((unsigned int*)ptr) = (unsigned int) lua_tonumber(L, 4); break; + case DC_SIGCHAR_LONG: *((long*)ptr) = (long) lua_tonumber(L, 4); break; + case DC_SIGCHAR_ULONG: *((unsigned long*)ptr) = (unsigned long) lua_tonumber(L, 4); break; + case DC_SIGCHAR_LONGLONG: *((DClonglong*)ptr) = (long long) lua_tonumber(L, 4); break; + case DC_SIGCHAR_ULONGLONG: *((DCulonglong*)ptr) = (unsigned long long) lua_tonumber(L, 4); break; + case DC_SIGCHAR_FLOAT: *((float*)ptr) = (float) lua_tonumber(L, 4); break; + case DC_SIGCHAR_DOUBLE: *((double*)ptr) = (double) lua_tonumber(L, 4); break; + case DC_SIGCHAR_POINTER: *((const void**)ptr) = lua_topointer(L, 4); break; + case DC_SIGCHAR_STRING: *((const char**)ptr) = lua_topointer(L, 4); break; + default: luaL_error(L, "invalid type signature %s", typesig); return 0; + } + } + return 0; +} + +int lua_dynpeek(lua_State *L) +{ + const char *ptr = (const char *) lua_touserdata(L, 1); + size_t offset = (ptrdiff_t) lua_tointeger(L, 2); + const char *typesig = (const char*) lua_tostring(L, 3); + const char* sig = typesig; + char ch; + ptr += offset; + while ((ch = *sig++) != '\0') { + switch(ch) { + case DC_SIGCHAR_BOOL: lua_pushboolean(L, *((int*)ptr)); break; + case DC_SIGCHAR_CHAR: lua_pushinteger(L, (int) *((char*)ptr)); break; + case DC_SIGCHAR_UCHAR: lua_pushinteger(L, (int) *((unsigned char*)ptr)); break; + case DC_SIGCHAR_SHORT: lua_pushinteger(L, (int) *((short*)ptr)); break; + case DC_SIGCHAR_USHORT: lua_pushinteger(L, (int) *((unsigned short*)ptr)); break; + case DC_SIGCHAR_INT: lua_pushinteger(L, *((int*)ptr)); break; + case DC_SIGCHAR_UINT: lua_pushnumber(L, (lua_Number) *((unsigned int*)ptr)); break; + case DC_SIGCHAR_LONG: lua_pushnumber(L, (lua_Number) *((long*)ptr)); break; + case DC_SIGCHAR_ULONG: lua_pushnumber(L, (lua_Number) *((unsigned long*)ptr)); break; + case DC_SIGCHAR_LONGLONG: lua_pushnumber(L, (lua_Number) *((DClonglong*)ptr)); break; + case DC_SIGCHAR_ULONGLONG: lua_pushnumber(L, (lua_Number) *((DCulonglong*)ptr)); break; + case DC_SIGCHAR_FLOAT: lua_pushnumber(L, (lua_Number) *((float*)ptr)); break; + case DC_SIGCHAR_DOUBLE: lua_pushnumber(L, (lua_Number) *((double*)ptr)); break; + case DC_SIGCHAR_POINTER: lua_pushlightuserdata(L, *((void**)ptr) ); break; + case DC_SIGCHAR_STRING: lua_pushstring(L, (const char*)ptr); break; + default: luaL_error(L, "invalid type signature %s", typesig); return 0; + } + } + return 1; +} + +static const struct luaL_Reg luareg_dynstruct[] = +{ + { "newstruct", lua_newstruct }, + { "aslightuserdata", lua_aslightuserdata }, + { "dynpoke", lua_dynpoke }, + { "dynpeek", lua_dynpeek }, + { NULL, NULL } +}; + +LUA_API int luaopen_ldynstruct(lua_State *L) +{ + luaL_register(L, "ldynstruct", luareg_dynstruct); + return 1; +}