233 lines
4.9 KiB
C
233 lines
4.9 KiB
C
#include "IPC_buffer.h"
|
|
#include <string.h>
|
|
#include "../debug.h"
|
|
#include <ctype.h>
|
|
|
|
|
|
|
|
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);
|
|
}
|