This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
niubinghui-luapluginmanage/src/lua_plugin_data.c
2024-08-06 16:16:34 +08:00

210 lines
6.0 KiB
C

/*************************************************************************
> File Name: lua_plugin_data.c
> Author:
> Created Time: 2024-08
> Encoding : UTF-8
************************************************************************/
/*************************************************************************
* version
* [ v0.1 ]
* 08-06
* 1. 实现函数
* int lua_cdata_push_stack;
* int lua_cdata_pop_stack;
* void lua_cdata_destory;
* struct lua_context * lua_context_new;
* int lua_context_push_stack;
* void lua_context_free;
************************************************************************/
#include "lua_plugin_manage_internal.h"
/*
* Function: lua_cdata_push_stack
* Input: | lua_State * | state | 入栈数据使用的状态机
* | struct lua_cdata * | cdata | 需要入栈的数据
* Output:
* Return: | -1 | 参数错误
* | 1 | 入栈数据类型有误
* | 0 | 入栈成功
* Description: 将一个数据元素入栈
*/
int lua_cdata_push_stack(
lua_State *state,
struct lua_cdata *cdata)
{
if (__glibc_unlikely(!state || !cdata))
return -1;
switch (cdata->cdata_type)
{
case DATATYPE_NIL:
lua_pushnil(state);
return 0;
case DATATYPE_BOOL:
lua_pushboolean(state, cdata->cdata_bool);
return 0;
case DATATYPE_INT:
lua_pushinteger(state, cdata->cdata_int);
return 0;
case DATATYPE_NUM:
lua_pushnumber(state, cdata->cdata_num);
return 0;
case DATATYPE_STRING:
lua_pushstring(state, cdata->cdata_string);
return 0;
case DATATYPE_TABLE:
lua_rawgeti(state, LUA_REGISTRYINDEX, cdata->cdata_table);
return 0;
case DATATYPE_POINTER:
lua_pushlightuserdata(state, (void *)cdata->cdata_pointer);
return 0;
case DATATYPE_CONTEXT:
lua_context_push_stack(cdata->cdata_context);
return 0;
default:
LOGERROR("can't recorgnize data type %d", cdata->cdata_type);
}
return 1;
}
/*
* Function: lua_cdata_pop_stack
* Input: | lua_State * | state | 出栈数据使用的状态机
* | struct lua_cdata * | cdata | 保存出栈的元素
* Output:
* Return: | -1 | 参数错误
* | -2 | 出栈数据类型有误
* | 0 | 出栈成功
* Description: 将一个数据元素出栈, 出栈过程中无法出栈context与table类型
* TODO: 扩展类型, 支持更多数据类型
*/
int lua_cdata_pop_stack(
lua_State *state,
struct lua_cdata *cdata)
{
if (__glibc_unlikely(!state || !cdata))
return -1;
if (!lua_gettop(state))
return 0;
switch (lua_type(state, -1))
{
case LUA_TNIL:
cdata->cdata_type = DATATYPE_NIL;
break;
case LUA_TBOOLEAN:
cdata->cdata_type = DATATYPE_BOOL;
cdata->cdata_bool = lua_toboolean(state, -1);
break;
case LUA_TNUMBER:
cdata->cdata_type = DATATYPE_NUM;
cdata->cdata_num = lua_tonumber(state, -1);
int try_int = (int)cdata->cdata_num;
if ((double)try_int == cdata->cdata_num)
{
cdata->cdata_type = DATATYPE_INT;
cdata->cdata_int = lua_tointeger(state, -1);
}
break;
case LUA_TSTRING:
cdata->cdata_type = DATATYPE_STRING;
cdata->cdata_string = (char *)strdup(lua_tostring(state, -1));
break;
case LUA_TLIGHTUSERDATA:
cdata->cdata_type = DATATYPE_POINTER;
cdata->cdata_pointer = (void *)lua_topointer(state, -1);
break;
default:
/* 其他数据类型之后处理 */
LOGERROR("other lua type can't pop out, %d", lua_type(state, -1));
return -2;
}
lua_pop(state, 1);
return 0;
}
/*
* Function: lua_cdata_destory
* Input: | struct lua_cdata * | cdata | 待销毁的data结构
* Output:
* Return:
* Description: 销毁是一个data结构, 释放内部占用内存
* 目前该函数仅数据类型为string的时候需要调用一次
*/
void lua_cdata_destory(struct lua_cdata *cdata)
{
if (__glibc_unlikely(!cdata))
return;
if (cdata->cdata_type == DATATYPE_STRING && cdata->cdata_string)
free(cdata->cdata_string);
return;
}
/*
* Function: lua_context_new
* Input: | lua_State * | state | 创建context使用的状态机
* Output:
* Return: | NULL | 创建失败
* | pointer | 创建成功, 返回创建的context指针
* Description: 创建一个context结构, 由于context结构使用需要在状态机中生成引用值, 单独重写一个new函数
*/
struct lua_context *lua_context_new(lua_State *state)
{
if (__glibc_unlikely(!state))
return NULL;
lua_newtable(state);
int ref_id = luaL_ref(state, LUA_REGISTRYINDEX);
lua_settop(state, 0);
if (ref_id == LUA_REFNIL)
{
return NULL;
}
struct lua_context *new_context = (struct lua_context *)calloc(1, sizeof(struct lua_context));
if (__glibc_unlikely(!new_context))
{
luaL_unref(state, LUA_REGISTRYINDEX, ref_id);
return NULL;
}
new_context->context_state = state;
new_context->context_ref_id = ref_id;
return new_context;
}
/*
* Function: lua_context_push_stack
* Input: | struct lua_context * | context | 待入栈的context结构
* Output:
* Return: | 0 | 入栈成功
* | -1 | 参数错误
* Description: 将一个context入栈, 实际入栈流程与table一致
*/
int lua_context_push_stack(struct lua_context *context)
{
if (luai_unlikely(!context))
return -1;
lua_rawgeti(context->context_state, LUA_REGISTRYINDEX, context->context_ref_id);
return 0;
}
/*
* Function: lua_context_free
* Input: | struct lua_context * | context | 释放一个context
* Output:
* Return:
* Description: 释放一个context
*/
void lua_context_free(struct lua_context *context)
{
if (__glibc_unlikely(!context))
return;
luaL_unref(context->context_state, LUA_REGISTRYINDEX, context->context_ref_id);
free(context);
return;
}