summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-04-07 00:53:39 +0800
committerruki <[email protected]>2022-04-06 23:22:21 +0800
commitc48a7d959049ad14b6ea09baca682dcbaf88639c (patch)
treeb023420a92e8c74aeea35b3ce02ba55f98395729
parent79e14625b3977bf7953c2150e584332a0ea8dd16 (diff)
improve bytes
-rw-r--r--tests/modules/bytes/test.lua9
-rw-r--r--xmake/core/base/bytes.lua28
-rw-r--r--xmake/core/base/pipe.lua8
-rw-r--r--xmake/core/base/socket.lua16
-rw-r--r--xmake/modules/private/service/stream.lua44
5 files changed, 90 insertions, 15 deletions
diff --git a/tests/modules/bytes/test.lua b/tests/modules/bytes/test.lua
index 4cb272c94..5e1d29a61 100644
--- a/tests/modules/bytes/test.lua
+++ b/tests/modules/bytes/test.lua
@@ -36,3 +36,12 @@ function test_concat(t)
t:are_equal((bytes("123") .. bytes("456")):str(), "123456")
t:are_equal(bytes(bytes("123"), bytes("456")):str(), "123456")
end
+
+function test_copy(t)
+ t:are_equal(bytes(9):copy("123456789"):str(), "123456789")
+end
+
+function test_copy2(t)
+ t:are_equal(bytes(18):copy("123456789"):copy2(10, "123456789"):str(), "123456789123456789")
+end
+
diff --git a/xmake/core/base/bytes.lua b/xmake/core/base/bytes.lua
index b95260237..f90adfb84 100644
--- a/xmake/core/base/bytes.lua
+++ b/xmake/core/base/bytes.lua
@@ -205,13 +205,32 @@ function _instance:copy(src)
if self:readonly() then
os.raise("%s: cannot be modified!", self)
end
- if type(src) == 'string' then
+ if type(src) == "string" then
src = bytes(src)
end
- if src:size() ~= self:size() then
- os.raise("%s: cannot copy bytes, src and dst must have same size(%d->%d)!", self, src:size(), self:size())
+ if src:size() > self:size() then
+ os.raise("%s: cannot copy bytes, src:size(%d) must be smaller than %d!", self, src:size(), self:size())
end
- libc.memcpy(self:cdata(), src:cdata(), self:size())
+ libc.memcpy(self:cdata(), src:cdata(), src:size())
+ return self
+end
+
+-- copy bytes to the given position
+function _instance:copy2(pos, src)
+ if self:readonly() then
+ os.raise("%s: cannot be modified!", self)
+ end
+ if type(src) == "string" then
+ src = bytes(src)
+ end
+ if pos < 1 or pos > self:size() then
+ os.raise("%s: invalid pos(%d)!", self, pos)
+ end
+ local leftsize = self:size() + 1 - pos
+ if src:size() > leftsize then
+ os.raise("%s: cannot copy bytes, src:size(%d) must be smaller than %d!", self, src:size(), leftsize)
+ end
+ libc.memcpy(self:cdata() + pos - 1, src:cdata(), src:size())
return self
end
@@ -224,7 +243,6 @@ end
-- dump whole bytes data
function _instance:dump()
-
local i = 0
local n = 147
local p = 0
diff --git a/xmake/core/base/pipe.lua b/xmake/core/base/pipe.lua
index ddf62411d..affade303 100644
--- a/xmake/core/base/pipe.lua
+++ b/xmake/core/base/pipe.lua
@@ -120,6 +120,7 @@ end
-- read data from pipe
function _instance:read(buff, size, opt)
+ assert(buff)
-- ensure opened
local ok, errors = self:_ensure_opened()
@@ -128,7 +129,8 @@ function _instance:read(buff, size, opt)
end
-- check buffer
- if not buff and buff:size() < size then
+ size = size or buff:size()
+ if buff:size() < size then
return -1, string.format("%s: too small buffer!", self)
end
@@ -168,14 +170,14 @@ function _instance:read(buff, size, opt)
end
end
if read == size then
- data_or_errors = bytes(buff, start, read)
+ data_or_errors = buff:slice(start, read)
else
read = -1
end
else
read, data_or_errors = io.pipe_read(self:cdata(), buff:caddr() + pos, math.min(buff:size() - pos, size))
if read > 0 then
- data_or_errors = bytes(buff, start, read)
+ data_or_errors = buff:slice(start, read)
end
end
if read < 0 and data_or_errors then
diff --git a/xmake/core/base/socket.lua b/xmake/core/base/socket.lua
index f2866ccfd..25bff99d0 100644
--- a/xmake/core/base/socket.lua
+++ b/xmake/core/base/socket.lua
@@ -385,6 +385,7 @@ end
-- recv data from socket
function _instance:recv(buff, size, opt)
+ assert(buff)
-- ensure opened
local ok, errors = self:_ensure_opened()
@@ -393,7 +394,8 @@ function _instance:recv(buff, size, opt)
end
-- check buffer
- if not buff and buff:size() < size then
+ size = size or buff:size()
+ if buff:size() < size then
return -1, string.format("%s: too small buffer!", self)
end
@@ -436,14 +438,14 @@ function _instance:recv(buff, size, opt)
end
end
if recv == size then
- data_or_errors = bytes(buff, start, recv)
+ data_or_errors = buff:slice(start, recv)
else
recv = -1
end
else
recv, data_or_errors = io.socket_recv(self:cdata(), buff:caddr() + pos, math.min(buff:size() - pos, size))
if recv > 0 then
- data_or_errors = bytes(buff, start, recv)
+ data_or_errors = buff:slice(start, recv)
end
end
if recv < 0 and data_or_errors then
@@ -519,6 +521,7 @@ end
-- recv udp data from peer
function _instance:recvfrom(buff, size, opt)
+ assert(buff)
-- ensure opened
local ok, errors = self:_ensure_opened()
@@ -532,7 +535,8 @@ function _instance:recvfrom(buff, size, opt)
end
-- check buffer
- if not buff and buff:size() < size then
+ size = size or buff:size()
+ if buff:size() < size then
return -1, string.format("%s: too small buffer!", self)
end
@@ -559,7 +563,7 @@ function _instance:recvfrom(buff, size, opt)
while true do
recv, data_or_errors, addr, port = io.socket_recvfrom(self:cdata(), buff:caddr() + pos, math.min(buff:size() - pos, size))
if recv > 0 then
- data_or_errors = bytes(buff, start, recv)
+ data_or_errors = buff:slice(start, recv)
break
elseif recv == 0 and not wait then
local events, waiterrs = _instance.wait(self, socket.EV_RECV, opt.timeout or -1)
@@ -577,7 +581,7 @@ function _instance:recvfrom(buff, size, opt)
else
recv, data_or_errors, addr, port = io.socket_recvfrom(self:cdata(), buff:caddr() + pos, math.min(buff:size() - pos, size))
if recv > 0 then
- data_or_errors = bytes(buff, start, recv)
+ data_or_errors = buff:slice(start, recv)
end
end
if recv < 0 and data_or_errors then
diff --git a/xmake/modules/private/service/stream.lua b/xmake/modules/private/service/stream.lua
index 437abed4a..8aa31386e 100644
--- a/xmake/modules/private/service/stream.lua
+++ b/xmake/modules/private/service/stream.lua
@@ -28,6 +28,8 @@ local stream = stream or object()
-- init stream
function stream:init(sock)
self._SOCK = sock
+ self._RCACHE = bytes(8192)
+ self._RCACHE_SIZE = 0
end
-- is empty?
@@ -47,7 +49,47 @@ function stream:send_string(str)
end
-- recv bytes
-function stream:recv_bytes(size)
+function stream:recv_bytes(buff, size)
+
+ -- read data from cache first
+ local buffsize = 0
+ local cache = self._RCACHE
+ local cache_size = self._RCACHE_SIZE
+ local cache_maxn = cache:size()
+ if size <= cache_size then
+ buff:copy(cache:slice(1, size))
+ cache_size = cache_size - size
+ self._RCACHE_SIZE = cache_size
+ return buff:slice(1, size)
+ elseif cache_size > 0 then
+ buff:copy(cache:slice(1, cache_size))
+ buffsize = cache_size
+ cache_size = 0
+ end
+ assert(cache_size == 0)
+
+ -- recv data from socket
+ local real = 0
+ local data = nil
+ local wait = false
+ while buffsize < size do
+ real, data = sock:recv(cache)
+ if real > 0 then
+ --buff:append(data, 1, leftbuff)
+ -- TODO move left cache to head
+ buffsize = buffsize + real
+ wait = false
+ elseif real == 0 and not wait then
+ if sock:wait(socket.EV_RECV, -1) == socket.EV_RECV then
+ wait = true
+ else
+ break
+ end
+ else
+ -- TODO
+ break
+ end
+ end
end
-- recv table