summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-04-07 21:01:13 +0800
committerruki <[email protected]>2022-04-07 21:01:13 +0800
commitcb099dedd27ecfb5d52d5991b44de22eb86ff336 (patch)
tree56afb156611694ee9fae6b78235c0ae3ee93680a
parentc48a7d959049ad14b6ea09baca682dcbaf88639c (diff)
add move to bytes
-rw-r--r--core/src/xmake/libc/memmov.c49
-rw-r--r--core/src/xmake/makefile1
-rw-r--r--tests/modules/bytes/test.lua7
-rw-r--r--xmake/core/base/bytes.lua84
-rw-r--r--xmake/core/base/libc.lua8
-rw-r--r--xmake/modules/private/service/stream.lua24
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