/* userdata send_buffer table pool integer sz or string (big endian) */ static int lpopbuffer(lua_State *L) { struct socket_buffer * sb = lua_touserdata(L, 1); if (sb == NULL) { return luaL_error(L, "Need buffer object at param 1"); } luaL_checktype(L,2,LUA_TTABLE); int type = lua_type(L,3); int sz; if (type == LUA_TNUMBER) { sz = lua_tointeger(L,3); } else { size_t len; const uint8_t * s = (const uint8_t *)luaL_checklstring(L, 3, &len); if (len > 4 || len < 1) { return luaL_error(L, "Invalid read %s", s); } int i; sz = 0; for (i=0;i<(int)len;i++) { sz <<= 8; sz |= s[i]; } } if (sb->size < sz || sz == 0) { lua_pushnil(L); } else { pop_lstring(L,sb,sz,0); sb->size -= sz; } lua_pushinteger(L, sb->size); return 2; }
// local ret = driver.readline(s.buffer, buffer_pool, sep) // return msg/true/nil // buffer_pool 缓冲池,如果传入nil 返回是否存在分隔符,如果传入table,返回读入的缓冲区数据 // sep 分隔符 比如\n static int lreadline(lua_State *L) { struct socket_buffer * sb = lua_touserdata(L, 1); if (sb == NULL) { return luaL_error(L, "Need buffer object at param 1"); } // only check // 如果第二个参数是lua table,check为false,否则check为true bool check = !lua_istable(L, 2); size_t seplen = 0; // 获取第三个参数值,分隔符字符串,同时获取其长度 const char *sep = luaL_checklstring(L,3,&seplen); int i; struct buffer_node *current = sb->head; if (current == NULL) return 0; int from = sb->offset; // 当前缓冲区节点可读数据长度 int bytes = current->sz - from; for (i=0;i<=sb->size - (int)seplen;i++) { if (check_sep(current, from, sep, seplen)) { // 如果有分隔符 if (check) { // 如果没有传入buffer_pool参数,则返回true /* 比如 socket.lua if driver.readline(s.buffer, nil, rr) then s.read_required = nil wakeup(s) end */ lua_pushboolean(L,true); } else { // 读入缓冲区数据并压栈作为lua返回值 pop_lstring(L, sb, i+seplen, seplen); sb->size -= i+seplen; } return 1; } // 如果没有分隔符,移动一个字符继续检索 ++from; --bytes; if (bytes == 0) { // 读完一个缓冲区节点,换下一个缓冲区节点 current = current->next; from = 0; if (current == NULL) // 下一个为空,跳出循环 break; bytes = current->sz; } } // 如果没有分隔符,没有返回参数 return 0; }
/* userdata send_buffer table pool integer sz */ static int lpopbuffer(lua_State *L) { struct socket_buffer * sb = lua_touserdata(L, 1); if (sb == NULL) { return luaL_error(L, "Need buffer object at param 1"); } luaL_checktype(L,2,LUA_TTABLE); int sz = luaL_checkinteger(L,3); if (sb->size < sz || sz == 0) { lua_pushnil(L); } else { pop_lstring(L,sb,sz,0); sb->size -= sz; } lua_pushinteger(L, sb->size); return 2; }
/* userdata send_buffer table pool , nil for check string sep */ static int lreadline(lua_State *L) { struct socket_buffer * sb = lua_touserdata(L, 1); if (sb == NULL) { return luaL_error(L, "Need buffer object at param 1"); } // only check bool check = !lua_istable(L, 2); size_t seplen = 0; const char *sep = luaL_checklstring(L,3,&seplen); int i; struct buffer_node *current = sb->head; if (current == NULL) return 0; int from = sb->offset; int bytes = current->sz - from; for (i=0;i<=sb->size - (int)seplen;i++) { if (check_sep(current, from, sep, seplen)) { if (check) { lua_pushboolean(L,true); } else { pop_lstring(L, sb, i+seplen, seplen); sb->size -= i+seplen; } return 1; } ++from; --bytes; if (bytes == 0) { current = current->next; from = 0; if (current == NULL) break; bytes = current->sz; } } return 0; }