diff options
| author | ruki <[email protected]> | 2022-04-07 21:01:13 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2022-04-07 21:01:13 +0800 |
| commit | cb099dedd27ecfb5d52d5991b44de22eb86ff336 (patch) | |
| tree | 56afb156611694ee9fae6b78235c0ae3ee93680a | |
| parent | c48a7d959049ad14b6ea09baca682dcbaf88639c (diff) | |
add move to bytes
| -rw-r--r-- | core/src/xmake/libc/memmov.c | 49 | ||||
| -rw-r--r-- | core/src/xmake/makefile | 1 | ||||
| -rw-r--r-- | tests/modules/bytes/test.lua | 7 | ||||
| -rw-r--r-- | xmake/core/base/bytes.lua | 84 | ||||
| -rw-r--r-- | xmake/core/base/libc.lua | 8 | ||||
| -rw-r--r-- | xmake/modules/private/service/stream.lua | 24 |
6 files changed, 160 insertions, 13 deletions
diff --git a/core/src/xmake/libc/memmov.c b/core/src/xmake/libc/memmov.c new file mode 100644 index 000000000..c5ec47e90 --- /dev/null +++ b/core/src/xmake/libc/memmov.c @@ -0,0 +1,49 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, TBOOX Open Source Group. + * + * @author ruki + * @file memmov.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "memmov" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_libc_memmov(lua_State* lua) +{ + // check + tb_assert_and_check_return_val(lua, 0); + + // do memmov + tb_pointer_t dst = (tb_pointer_t)(tb_size_t)luaL_checkinteger(lua, 1); + tb_pointer_t src = (tb_pointer_t)(tb_size_t)luaL_checkinteger(lua, 2); + tb_int_t size = (tb_int_t)lua_tointeger(lua, 3); + if (dst && src && size > 0) + tb_memmov(dst, src, size); + return 0; +} + diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile index dbe9bc201..908ed3cc3 100644 --- a/core/src/xmake/makefile +++ b/core/src/xmake/makefile @@ -123,6 +123,7 @@ xmake_C_FILES += \ libc/free \ libc/memset \ libc/memcpy \ + libc/memmov \ libc/dataptr \ libc/byteof \ libc/setbyte \ diff --git a/tests/modules/bytes/test.lua b/tests/modules/bytes/test.lua index 5e1d29a61..ef450ebce 100644 --- a/tests/modules/bytes/test.lua +++ b/tests/modules/bytes/test.lua @@ -39,9 +39,16 @@ end function test_copy(t) t:are_equal(bytes(9):copy("123456789"):str(), "123456789") + t:are_equal(bytes(5):copy("123456789", 5, 9):str(), "56789") end function test_copy2(t) t:are_equal(bytes(18):copy("123456789"):copy2(10, "123456789"):str(), "123456789123456789") + t:are_equal(bytes(14):copy("123456789"):copy2(10, "123456789", 5, 9):str(), "12345678956789") +end + +function test_move(t) + t:are_equal(bytes(9):copy("123456789"):move(5, 9):str(), "567896789") + t:are_equal(bytes(9):copy("123456789"):move2(2, 5, 9):str(), "156789789") end diff --git a/xmake/core/base/bytes.lua b/xmake/core/base/bytes.lua index f90adfb84..b9aa748f2 100644 --- a/xmake/core/base/bytes.lua +++ b/xmake/core/base/bytes.lua @@ -201,36 +201,104 @@ function _instance:slice(start, last) end -- copy bytes -function _instance:copy(src) +function _instance:copy(src, start, last) if self:readonly() then os.raise("%s: cannot be modified!", self) end if type(src) == "string" then src = bytes(src) end - 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()) + local srcsize = src:size() + start = start or 1 + last = last or srcsize + if start < 1 or start > srcsize then + os.raise("%s: invalid start(%d)!", self, start) end - libc.memcpy(self:cdata(), src:cdata(), src:size()) + if last < start - 1 or last > srcsize + start - 1 then + os.raise("%s: invalid last(%d)!", self, last) + end + local copysize = last + 1 - start + if copysize > self:size() then + os.raise("%s: cannot copy bytes, src:size(%d) must be smaller than %d!", self, copysize, self:size()) + end + libc.memcpy(self:cdata(), src:cdata() + start - 1, copysize) return self end -- copy bytes to the given position -function _instance:copy2(pos, src) +function _instance:copy2(pos, src, start, last) if self:readonly() then os.raise("%s: cannot be modified!", self) end if type(src) == "string" then src = bytes(src) end + local srcsize = src:size() + start = start or 1 + last = last or srcsize + if start < 1 or start > srcsize then + os.raise("%s: invalid start(%d)!", self, start) + end + if last < start - 1 or last > srcsize + start - 1 then + os.raise("%s: invalid last(%d)!", self, last) + end if pos < 1 or pos > self:size() then os.raise("%s: invalid pos(%d)!", self, pos) end + local copysize = last + 1 - start 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) + if copysize > leftsize then + os.raise("%s: cannot copy bytes, src:size(%d) must be smaller than %d!", self, copysize, leftsize) + end + libc.memcpy(self:cdata() + pos - 1, src:cdata() + start - 1, copysize) + return self +end + +-- move bytes to the begin position +function _instance:move(start, last) + if self:readonly() then + os.raise("%s: cannot be modified!", self) + end + local totalsize = self:size() + start = start or 1 + last = last or totalsize + if start < 1 or start > totalsize then + os.raise("%s: invalid start(%d)!", self, start) + end + if last < start - 1 or last > totalsize + start - 1 then + os.raise("%s: invalid last(%d)!", self, last) + end + local movesize = last + 1 - start + if movesize > totalsize then + os.raise("%s: cannot move bytes, move size(%d) must be smaller than %d!", self, movesize, totalsize) + end + libc.memmov(self:cdata(), self:cdata() + start - 1, movesize) + return self +end + +-- move bytes to the given position +function _instance:move2(pos, start, last) + if self:readonly() then + os.raise("%s: cannot be modified!", self) + end + local totalsize = self:size() + start = start or 1 + last = last or totalsize + if start < 1 or start > totalsize then + os.raise("%s: invalid start(%d)!", self, start) + end + if last < start - 1 or last > totalsize + start - 1 then + os.raise("%s: invalid last(%d)!", self, last) + end + if pos < 1 or pos > totalsize then + os.raise("%s: invalid pos(%d)!", self, pos) + end + local movesize = last + 1 - start + local leftsize = totalsize + 1 - pos + if movesize > leftsize then + os.raise("%s: cannot move bytes, move size(%d) must be smaller than %d!", self, movesize, leftsize) end - libc.memcpy(self:cdata() + pos - 1, src:cdata(), src:size()) + libc.memmov(self:cdata() + pos - 1, self:cdata() + start - 1, movesize) return self end diff --git a/xmake/core/base/libc.lua b/xmake/core/base/libc.lua index 9aecb8af5..655a7cde0 100644 --- a/xmake/core/base/libc.lua +++ b/xmake/core/base/libc.lua @@ -74,6 +74,14 @@ function libc.memcpy(dst, src, size) end end +function libc.memmov(dst, src, size) + if ffi then + return ffi.move(dst, src, size) + else + return libc._memmov(dst, src, size) + end +end + function libc.memset(data, ch, size) if ffi then return ffi.fill(data, size, ch) diff --git a/xmake/modules/private/service/stream.lua b/xmake/modules/private/service/stream.lua index 8aa31386e..c785777de 100644 --- a/xmake/modules/private/service/stream.lua +++ b/xmake/modules/private/service/stream.lua @@ -57,12 +57,12 @@ function stream:recv_bytes(buff, size) local cache_size = self._RCACHE_SIZE local cache_maxn = cache:size() if size <= cache_size then - buff:copy(cache:slice(1, size)) + buff:copy(cache, 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)) + buff:copy(cache, 1, cache_size) buffsize = cache_size cache_size = 0 end @@ -75,9 +75,23 @@ function stream:recv_bytes(buff, size) 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 + -- append data to buffer + local leftsize = size - buffsize + if real < leftsize then + buff:copy2(buffsize, data) + buffsize = buffsize + real + else + buff:copy2(buffsize, data, 1, leftsize) + buffsize = buffsize + leftsize + + -- move left cache to head + cache_size = real - leftsize + if cache_size > 0 then + cache:move(leftsize, cache_size) + end + self._RCACHE_SIZE = cache_size + return buff:slice(1, buffsize) + end wait = false elseif real == 0 and not wait then if sock:wait(socket.EV_RECV, -1) == socket.EV_RECV then |
