介绍
lutil 模块是一个用于 Lua 程序的辅助模块。它包含了一些功能函数,用于执行与操作系统和网络字节序相关的操作。使用来执行一些计时、休眠和网络数据转换的操作,以满足应用程序的需求。
核心代码分析
- 此函数用于获取当前时间的毫秒数。
- 它通过调用系统函数 gettimeofday 获取当前时间的秒和微秒,并将其转换为毫秒表示。
- 在 Lua 中,它会将毫秒数压入栈顶并返回。
static int _l_gettimeofday(lua_State * L){
struct timeval tv;
gettimeofday(&tv, NULL);
uint32_t r = (uint32_t)(((uint64_t)tv.tv_sec * 1000 + (uint64_t)tv.tv_usec / 1000) & 0x7ffffffful);
lua_pushinteger(L, r);
return 1;
}
- 此函数用于让程序暂停一段时间,以毫秒为单位。
- 一个参数 millisecond 作为需要休眠的毫秒数。
- 在 UNIX 系统中使用 usleep 函数进行休眠,在 Windows 系统中使用 Sleep 函数进行休眠。
/* sleep in millisecond */
static int _l_isleep(lua_State* L)
{
uint32_t millisecond = luaL_checkinteger(L, 1);
#ifdef __unix
usleep((millisecond << 10) - (millisecond << 4) - (millisecond << 3));
#elif defined(_WIN32)
Sleep(millisecond);
#endif
return 0;
}
- 此函数用于将一个 4 字节的网络字节序的字符串转换为无符号整数。
- 一个参数 s,即需要进行转换的 4 字节字符串。
- 在转换过程中,它会将字符串中的每个字节按照网络字节序进行组合,并将结果压入栈顶并返回。
static int _netbytes2uint32(lua_State* L){
const char* s = luaL_checkstring(L, 1);
uint32_t a0 = (uint8_t)s[0] << 24;
uint32_t a1 = (uint8_t)s[1] << 16;
uint32_t a2 = (uint8_t)s[2] << 8;
uint32_t a3 = (uint8_t)s[3];
uint32_t ret = (uint32_t)(a0 | a1 | a2 | a3);
lua_pushinteger(L, ret);
return 1;
}
- 此函数用于将一个无符号整数转换为 4 字节的网络字节序的字符串。
- 一个参数 i,即需要进行转换的无符号整数。
- 在转换过程中,它将整数按照网络字节序进行分割,并将结果作为 Lua 字符串进行返回。
static int _uint322netbytes(lua_State* L){
uint32_t i = lua_tointeger(L, 1);
char s[4];
s[0] = (char)(i >> 24);
s[1] = (char)(i >> 16);
s[2] = (char)(i >> 8);
s[3] = (char)(i);
lua_pushlstring(L, s, 4);
return 1;
}
- 此函数是 lutil 模块的入口函数,由 Lua 调用以导入模块。
- 在函数内,它通过调用 luaL_newlib 创建一个新的 Lua 库,并将上述几个功能函数注册到库中。
- 最后,它将创建的库作为返回值返回给 Lua。
int luaopen_lutil(lua_State *L) {
luaL_Reg libs[] = {
{"gettimeofday", _l_gettimeofday},
{"isleep", _l_isleep},
{"netbytes2uint32", _netbytes2uint32},
{"uint322netbytes", _uint322netbytes},
{NULL, NULL},
};
luaL_newlib(L, libs);
return 1;
}