summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-11-01 00:59:06 +0800
committerruki <[email protected]>2019-10-31 23:54:38 +0800
commitaf6fdbab0210beddd18a787ebb5eae7da4136609 (patch)
tree9b6345abfd40848d57db0d407e42eb8122c4cc65
parent56178606d872629cb3553bf912a742c84cf244e4 (diff)
add bytes test
-rw-r--r--tests/modules/bytes/test.lua32
-rw-r--r--xmake/core/base/bytes.lua60
2 files changed, 72 insertions, 20 deletions
diff --git a/tests/modules/bytes/test.lua b/tests/modules/bytes/test.lua
new file mode 100644
index 000000000..3756aaeaf
--- /dev/null
+++ b/tests/modules/bytes/test.lua
@@ -0,0 +1,32 @@
+
+function test_ctor(t)
+ t:are_equal(bytes("123456789"):str(), "123456789")
+ t:are_equal(bytes(bytes("123456789")):str(), "123456789")
+ t:are_equal(bytes(bytes("123456789"), 3, 5):str(), "345")
+ t:are_equal(bytes("123456789"):size(), 9)
+ t:are_equal(bytes(10):size(), 10)
+ t:are_equal(bytes(bytes("123"), bytes("456"), bytes("789")):str(), "123456789")
+end
+
+function test_clone(t)
+ t:are_equal(bytes(10):clone():size(), 10)
+ t:are_equal(bytes("123456789"):clone():str(), "123456789")
+end
+
+function test_slice(t)
+ t:are_equal(bytes(10):slice(1, 2):size(), 2)
+ t:are_equal(bytes("123456789"):slice(1, 4):str(), "1234")
+end
+
+function test_index(t)
+ local b = bytes("123456789")
+ t:are_equal(b[{1, 4}]:str(), "1234")
+ t:will_raise(function() b[1] = string.byte('2') end)
+ b = bytes(9)
+ b[{1, 9}] = bytes("123456789")
+ t:are_equal(b:str(), "123456789")
+ b[1] = string.byte('2')
+ t:are_equal(b:str(), "223456789")
+ t:will_raise(function() b[100] = string.byte('2') end)
+end
+
diff --git a/xmake/core/base/bytes.lua b/xmake/core/base/bytes.lua
index c92bb065f..06180c06a 100644
--- a/xmake/core/base/bytes.lua
+++ b/xmake/core/base/bytes.lua
@@ -65,14 +65,16 @@ function _instance.new(...)
instance._CDATA = ffi.gc(ffi.cast("unsigned char*", ptr), ffi.C.xm_ffi_free)
instance._MANAGED = true
end
- instance._SIZE = size
+ instance._SIZE = size
+ instance._READONLY = false
elseif type(arg1) == "string" then
-- bytes(str): mounts a buffer from the given string
local str = arg1
- instance._SIZE = #str
- instance._CDATA = ffi.cast("unsigned char*", str)
- instance._REF = str -- keep ref for GC
- instance._MANAGED = false
+ instance._SIZE = #str
+ instance._CDATA = ffi.cast("unsigned char*", str)
+ instance._REF = str -- keep ref for GC
+ instance._MANAGED = false
+ instance._READONLY = true
elseif type(arg1) == "table" then
if type(arg2) == 'number' then
-- bytes(bytes, start, last): mounts a buffer from another one, with start/last limits:
@@ -82,10 +84,11 @@ function _instance.new(...)
if start < 1 or last > b:size() then
os.raise("incorrect bounds(%d-%d) for bytes(...)!", start, last)
end
- instance._SIZE = last - start + 1
- instance._CDATA = b:cdata() - 1 + start
- instance._REF = b -- keep lua ref for GC
- instance._MANAGED = false
+ instance._SIZE = last - start + 1
+ instance._CDATA = b:cdata() - 1 + start
+ instance._REF = b -- keep lua ref for GC
+ instance._MANAGED = false
+ instance._READONLY = b:readonly()
elseif type(arg2) == "table" then
-- bytes(bytes1, bytes2, bytes3, ...): allocates and concat buffer from list of byte buffers
instance._SIZE = 0
@@ -98,7 +101,8 @@ function _instance.new(...)
ffi.copy(instance._CDATA + offset, b:cdata(), b:size())
offset = offset + b:size()
end
- instance._MANAGED = true
+ instance._MANAGED = true
+ instance._READONLY = false
elseif not arg2 and arg1:size() then
-- bytes(bytes): allocates a buffer from another one (strict replica, sharing memory)
local b = arg1
@@ -107,10 +111,11 @@ function _instance.new(...)
if start < 1 or last > b:size() then
os.raise("incorrect bounds(%d-%d)!", start, last)
end
- instance._SIZE = last - start + 1
- instance._CDATA = b:cdata() - 1 + start
- instance._REF = b -- keep lua ref for GC
- instance._MANAGED = false
+ instance._SIZE = last - start + 1
+ instance._CDATA = b:cdata() - 1 + start
+ instance._REF = b -- keep lua ref for GC
+ instance._MANAGED = false
+ instance._READONLY = b:readonly()
end
end
if instance:cdata() == nil then
@@ -130,6 +135,11 @@ function _instance:cdata()
return self._CDATA
end
+-- readonly?
+function _instance:readonly()
+ return self._READONLY
+end
+
-- bytes:ipairs()
function _instance:ipairs()
local index = 0
@@ -148,11 +158,14 @@ end
-- copy bytes
function _instance:copy(src)
+ 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("cannot copy bytes, src and dst must have same size(%d->%d)!", src:size(), self:size())
+ os.raise("%s: cannot copy bytes, src and dst must have same size(%d->%d)!", self, src:size(), self:size())
end
ffi.copy(self:cdata(), src:cdata(), self:size())
return self
@@ -179,7 +192,7 @@ end
function _instance:__index(key)
if type(key) == "number" then
if key < 1 or key > self:size() then
- os.raise("bytes index(%d/%d) out of bounds!", key, self:size())
+ os.raise("%s: index(%d/%d) out of bounds!", self, key, self:size())
end
return self._CDATA[key - 1]
elseif type(key) == "table" then
@@ -189,15 +202,18 @@ function _instance:__index(key)
return rawget(self, key)
end
--- get byte or bytes slice at the given index position
+-- set byte or bytes slice at the given index position
--
-- bytes[1] = 0x1
-- bytes[{1, 2}] = bytes(2)
--
function _instance:__newindex(key, value)
+ if self:readonly() then
+ os.raise("%s: cannot modify value at index[%s]!", self, key)
+ end
if type(key) == "number" then
if key < 1 or key > self:size() then
- os.raise("bytes index(%d/%d) out of bounds!", key, self:size())
+ os.raise("%s: index(%d/%d) out of bounds!", self, key, self:size())
end
self._CDATA[key - 1] = value
return
@@ -220,10 +236,14 @@ end
-- tostring(bytes)
function _instance:__tostring()
local parts = {}
- for i = 1, tonumber(self:size()) do
+ local size = self:size()
+ if size > 16 then
+ size = 16
+ end
+ for i = 1, size do
parts[i] = bit.tohex(self[i], 2)
end
- return "<bytes: " .. table.concat(parts, " ") .. ">"
+ return "<bytes(" .. self:size() .. "): " .. table.concat(parts, " ") .. (self:size() > 16 and "..>" or ">")
end
-- new an bytes instance