diff options
| author | ruki <[email protected]> | 2022-04-07 00:53:39 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2022-04-06 23:22:21 +0800 |
| commit | c48a7d959049ad14b6ea09baca682dcbaf88639c (patch) | |
| tree | b023420a92e8c74aeea35b3ce02ba55f98395729 | |
| parent | 79e14625b3977bf7953c2150e584332a0ea8dd16 (diff) | |
improve bytes
| -rw-r--r-- | tests/modules/bytes/test.lua | 9 | ||||
| -rw-r--r-- | xmake/core/base/bytes.lua | 28 | ||||
| -rw-r--r-- | xmake/core/base/pipe.lua | 8 | ||||
| -rw-r--r-- | xmake/core/base/socket.lua | 16 | ||||
| -rw-r--r-- | xmake/modules/private/service/stream.lua | 44 |
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 |
