Exemple #1
0
static void
pop_lstring(lua_State *L, struct socket_buffer *sb, int sz, int skip) {
	struct buffer_node * current = sb->head;
	if (sz < current->sz - sb->offset) {
		lua_pushlstring(L, current->msg + sb->offset, sz-skip);
		sb->offset+=sz;
		return;
	}
	if (sz == current->sz - sb->offset) {
		lua_pushlstring(L, current->msg + sb->offset, sz-skip);
		return_free_node(L,2,sb);
		return;
	}

	luaL_Buffer b;
	luaL_buffinit(L, &b);
	for (;;) {
		int bytes = current->sz - sb->offset;
		if (bytes >= sz) {
			if (sz > skip) {
				luaL_addlstring(&b, current->msg + sb->offset, sz - skip);
			} 
			sb->offset += sz;
			if (bytes == sz) {
				return_free_node(L,2,sb);
			}
			break;
		}
		int real_sz = sz - skip;
		if (real_sz > 0) {
			luaL_addlstring(&b, current->msg + sb->offset, (real_sz < bytes) ? real_sz : bytes);
		}
		return_free_node(L,2,sb);
		sz-=bytes;
		if (sz==0)
			break;
		current = sb->head;
		assert(current);
	}
	luaL_pushresult(&b);
}
Exemple #2
0
/*
	userdata send_buffer
	table pool
 */
static int
lclearbuffer(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);
	while(sb->head) {
		return_free_node(L,2,sb);
	}
	return 0;
}
Exemple #3
0
static int
lreadall(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);
	luaL_Buffer b;
	luaL_buffinit(L, &b);
	while(sb->head) {
		struct buffer_node *current = sb->head;
		luaL_addlstring(&b, current->msg + sb->offset, current->sz - sb->offset);
		return_free_node(L,2,sb);
	}
	luaL_pushresult(&b);
	return 1;
}
Exemple #4
0
// local ret = driver.readall(s.buffer, buffer_pool)
// socket.read(id, sz) socket.lua
static int
lreadall(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);
	luaL_Buffer b;
	luaL_buffinit(L, &b);
	// 遍历缓冲区链表
	while(sb->head) {
		struct buffer_node *current = sb->head;
		// 把缓冲区节点的所有数据都放入字符串缓存
		luaL_addlstring(&b, current->msg + sb->offset, current->sz - sb->offset);
		return_free_node(L,2,sb);
	}
	// 结束对字符串缓存的使用,将最终的字符串留在栈顶,作为lua返回值
	luaL_pushresult(&b);
	sb->size = 0;
	return 1;
}
Exemple #5
0
// sz 需要读的数据长度
// skip 需要跳过的数据长度 比如\n的长度
static void
pop_lstring(lua_State *L, struct socket_buffer *sb, int sz, int skip) {
	struct buffer_node * current = sb->head;
	if (sz < current->sz - sb->offset) {
		// 如果需要读的长度小于剩余可读的长度
		// 把缓冲区数据压入栈中作为lua返回值
		lua_pushlstring(L, current->msg + sb->offset, sz-skip);
		// 偏移量增加
		sb->offset+=sz;
		return;
	}
	if (sz == current->sz - sb->offset) {
		// 如果需要读的长度等于剩余可读的长度
		// 把缓冲区数据压入栈中作为lua返回值
		lua_pushlstring(L, current->msg + sb->offset, sz-skip);
		// 当前缓冲区节点已读完,归还缓冲区节点到缓冲池
		return_free_node(L,2,sb);
		return;
	}

	// 字符串缓存可以让c代码分段构造一个Lua字符串

	// 定义一个字符串缓存
	luaL_Buffer b;
	// 初始化字符串缓存
	luaL_buffinit(L, &b);

	// 循环读取缓冲区链表的数据
	for (;;) {
		// 当前缓冲区节点可读数据长度
		int bytes = current->sz - sb->offset;
		if (bytes >= sz) {
			// 如果需要读的长度小于剩余可读的长度
			// 刚开始进入循环,不会走这段逻辑,首节点此种情况已处理,此后遍历的节点仍可能出现此种情况
			if (sz > skip) {
				// 把缓冲区数据放入字符串缓存
				luaL_addlstring(&b, current->msg + sb->offset, sz - skip);
			} 
			// 偏移量增加
			sb->offset += sz;
			if (bytes == sz) {
				// 如果正好全部读完,归还缓冲区节点到缓冲池
				return_free_node(L,2,sb);
			}
			// 需要读的已读完,跳出循环不必再读
			break;
		}
		// 实际要读的数据长度,除sep分隔符之外
		int real_sz = sz - skip;
		if (real_sz > 0) {
			// 把缓冲区数据放入字符串缓存
			luaL_addlstring(&b, current->msg + sb->offset, (real_sz < bytes) ? real_sz : bytes);
		}
		// 当前缓冲区节点已读完,归还缓冲区节点到缓冲池
		return_free_node(L,2,sb);
		sz-=bytes;
		if (sz==0)
			// 如果全部读完,跳出循环不必再读
			break;
		// 换下一个缓冲区节点
		current = sb->head;
		assert(current);
	}
	// 结束对字符串缓存的使用,将最终的字符串留在栈顶
	luaL_pushresult(&b);
}