#include "IPC_buffer.h" #include #include "../debug.h" #include static int syscalls_indexIPC_buffer(lua_State* L) { struct IPC_buffer* r = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); const char* index = luaL_checkstring(L, 2); if (strcmp(index, "used") == 0) { lua_pushinteger(L, r->used); } else if (strcmp(index, "lock") == 0) { lua_pushboolean(L, r->lock); } else if (strcmp(index, "size") == 0) { lua_pushnumber(L, r->size); } else { lua_pushnil(L); } return 1; } static int syscalls_newindexIPC_buffer(lua_State* L) { struct IPC_buffer* r = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); const char* index = luaL_checkstring(L, 2); int val = luaL_checkinteger(L, 3); if (strcmp(index, "used") == 0) { r->used = val; } else if (strcmp(index, "lock") == 0) { r->lock = val; } else { luaL_error(L, "wrong index: %s", index); } return 0; } static bool compare_ipc_buffer(ksys_ipc_buffer* a, ksys_ipc_buffer* b) { // блять че за высер... if (a == b) return true; if (a->used == b->used) { return memcmp( a + (2 * sizeof(unsigned)), b + (2 * sizeof(unsigned)), a->used ); } else // длина сообщений не совпадает, занчитт они зразу не могут быть равны { return false; } } static int syscalls_eqIPC_buffer(lua_State* L) { lua_pushboolean( L, compare_ipc_buffer( luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name), luaL_checkudata(L, 2, syscalls_IPC_buffer_metatable_name) ) ); return 1; } static int syscalls_IPC_buffer_lock(lua_State* L) { ksys_ipc_buffer* buffer = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); buffer->lock = 1; return 0; } static int syscalls_IPC_buffer_unlock(lua_State* L) { ksys_ipc_buffer* buffer = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); buffer->lock = 0; return 0; } /** * @brief Получить сообщение под номером * @param buffer * @param i * @return указатель на сообщение, если такого сообщения ещё нет, то возвращает */ static ksys_ipc_msg* IPC_buffer_get_message(struct IPC_buffer* buffer, int i) { ksys_ipc_msg* j = (ksys_ipc_msg*)(buffer + 8); unsigned diff = 0; for (int k = 0; k < i; k++) { diff += j->datalen + 8; // прибавление длинны сообщения и заголовка j += diff; if (diff >= buffer->used) return 0; } return j; } static ksys_ipc_msg* IPC_buffer_get_last_message(struct IPC_buffer* buffer) { ksys_ipc_msg* j = (ksys_ipc_msg*)(buffer + 8); unsigned diff = 0; while (diff < buffer->used) { j += diff; diff += j->datalen + 8; // прибавление длинны сообщения и заголовка } return j; } static int syscalls_IPC_buffer_get_message(lua_State* L) { struct IPC_buffer* buffer = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); unsigned i = luaL_checkinteger(L, 1); ksys_ipc_msg* msg = IPC_buffer_get_message(buffer, i); if (msg) { lua_pushlightuserdata(L, msg); } else { lua_pushnil(L); } return 1; } static int syscalls_IPC_buffer_get_last_message(lua_State* L) { struct IPC_buffer* buffer = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); lua_pushlightuserdata(L, IPC_buffer_get_last_message(buffer)); return 1; } static int syscalls_IPC_buffer_reset(lua_State* L) { struct IPC_buffer* buffer = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); buffer->used = 0; memset(&buffer->data, 0, buffer->size); return 0; } static const luaL_Reg syscalls_IPC_buffer_m[] = { {"__index", syscalls_indexIPC_buffer}, {"__newindex", syscalls_newindexIPC_buffer}, {"__eq", syscalls_eqIPC_buffer}, {"Lock", syscalls_IPC_buffer_lock}, {"Unlock", syscalls_IPC_buffer_unlock}, {"GetMessage", syscalls_IPC_buffer_get_message}, {"GetLastMessage", syscalls_IPC_buffer_get_last_message}, {"Reset", syscalls_IPC_buffer_reset}, {NULL, NULL} }; struct IPC_buffer* syscalls_pushIPC_buffer(lua_State* L, size_t size) { DEBUG_LINE("push " syscalls_IPC_buffer_name " entry"); struct IPC_buffer* buffer = lua_newuserdata(L, sizeof(struct IPC_buffer) + size); luaL_setmetatable(L, syscalls_IPC_buffer_metatable_name); buffer->used = 0; buffer->size = size; return buffer; } static int syscalls_newIPC_buffer(lua_State* L) { size_t size = luaL_checkinteger(L, 1); struct IPC_buffer* buffer = syscalls_pushIPC_buffer(L, size); return 1; } static const luaL_Reg syscalls_IPC_buffer_lib[] = { {"new", syscalls_newIPC_buffer}, {NULL, NULL} }; void syscalls_register_IPC_buffer(lua_State* L) { DEBUG_LINE("register " syscalls_IPC_buffer_name " entry"); luaL_newlib(L, syscalls_IPC_buffer_lib); lua_setfield(L, -2, syscalls_IPC_buffer_name); luaL_newmetatable(L, syscalls_IPC_buffer_metatable_name); luaL_setfuncs(L, syscalls_IPC_buffer_m, 0); lua_pop(L, 1); }