[十万个为什么] [lua] 自定义byte_buffer
#include "lprefix.h"
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#define BYTE_BUFFER_META_TABLE_NAME "byte_buffer*"
#define GET_BYTE_BUFFER(L) ((byte_buffer_t*)luaL_checkudata(L, 1, BYTE_BUFFER_META_TABLE_NAME))
// ---------------------------------------------------------------------------
typedef struct byte_buffer_t byte_buffer_t;
struct byte_buffer_t
{
int m_size;
uint8_t m_buffer[0];
};
// 创建自定义类型byte_buffer_t
// ---------------------------------------------------------------------------
static int byte_buffer_new(lua_State* L)
{
int size = luaL_checkinteger(L, 1);
if (size <= 0)
{
return 0;
}
byte_buffer_t* bf = (byte_buffer_t*)lua_newuserdatauv(L, 4+size, 0);
if (bf == NULL)
{
return 0;
}
bf->m_size = size;
luaL_setmetatable(L, BYTE_BUFFER_META_TABLE_NAME);
return 1;
}
// ---------------------------------------------------------------------------
static int bf_meta_len(lua_State* L)
{
byte_buffer_t* bf = GET_BYTE_BUFFER(L);
lua_pushinteger(L, bf->m_size);
return 1;
}
// ---------------------------------------------------------------------------
static int bf_meta_tostring(lua_State* L)
{
byte_buffer_t* bf = GET_BYTE_BUFFER(L);
lua_pushfstring(L, "byte_buffer(%d)@%p", bf->m_size, bf);
return 1;
}
// ---------------------------------------------------------------------------
static int bf_get(lua_State* L)
{
byte_buffer_t* bf = GET_BYTE_BUFFER(L);
int index = luaL_checkinteger(L, 2);
if (index >= 0 && index < bf->m_size)
{
lua_pushinteger(L, bf->m_buffer[index]);
return 1;
}
return 0;
}
// ---------------------------------------------------------------------------
static int bf_set(lua_State* L)
{
byte_buffer_t* bf = GET_BYTE_BUFFER(L);
int index = luaL_checkinteger(L, 2);
int value = luaL_checkinteger(L, 3);
if (index >= 0 && index < bf->m_size)
{
bf->m_buffer[index] = value&0xFF;
lua_pushboolean(L, 1);
return 1;
}
return 0;
}
// ---------------------------------------------------------------------------
static const luaL_Reg byte_buffer_func[] =
{
{"new", byte_buffer_new},
{NULL, NULL},
};
// ---------------------------------------------------------------------------
static const luaL_Reg bf_meta_func[] =
{
{"__index", NULL}, /* placeholder */
{"__len", bf_meta_len},
{"__tostring", bf_meta_tostring},
{NULL, NULL},
};
// ---------------------------------------------------------------------------
static const luaL_Reg bf_func[] =
{
{"len", bf_meta_len},
{"get", bf_get},
{"set", bf_set},
{NULL, NULL},
};
// ---------------------------------------------------------------------------
LUAMOD_API int luaopen_byte_buffer(lua_State *L);
LUAMOD_API int luaopen_byte_buffer(lua_State *L)
{
// 创建 byte_bufer = {...}
luaL_newlib(L, byte_buffer_func);
// 创建 bf_meta = {..}
luaL_newmetatable(L, BYTE_BUFFER_META_TABLE_NAME);
luaL_setfuncs(L, bf_meta_func, 0);
// 创建bf = {...}
luaL_newlibtable(L, bf_func);
luaL_setfuncs(L, bf_func, 0);
// 设置buf_meta.__index = bf
lua_setfield(L, -2, "__index");
lua_pop(L, 1);
return 1;
}