summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-10-31 21:04:32 +0800
committerruki <[email protected]>2019-10-31 00:27:17 +0800
commit7d47837062fba756f66e7bea313cb59f9a026477 (patch)
tree1faef02540808728046c67d23c874f6118a0c774
parent057e930e41972cc5ee1812d16792dc6f6945279d (diff)
impl bytes index and ipairs
-rw-r--r--xmake/core/base/bytes.lua123
-rw-r--r--xmake/core/base/io.lua20
-rw-r--r--xmake/core/sandbox/modules/bytes.lua23
-rw-r--r--xmake/core/sandbox/modules/ipairs.lua41
-rw-r--r--xmake/core/sandbox/modules/pairs.lua45
5 files changed, 166 insertions, 86 deletions
diff --git a/xmake/core/base/bytes.lua b/xmake/core/base/bytes.lua
index 38f79c324..9f5a9ead2 100644
--- a/xmake/core/base/bytes.lua
+++ b/xmake/core/base/bytes.lua
@@ -23,21 +23,130 @@ local bytes = bytes or {}
local _instance = _instance or {}
-- load modules
-local bit = require('bit')
-local ffi = require('ffi')
-local string = require("base/string")
+local bit = require('bit')
+local ffi = require('ffi')
+local os = require("base/os")
+
+-- define ffi interfaces
+ffi.cdef[[
+ void* malloc(size_t __size);
+ void free(void *__ptr);
+]]
-- new a bytes instance
-function _instance.new(size)
- local instance = table.inherit(_instance)
+--
+-- new(size): allocates a buffer of given size
+-- new(size, ptr [, manage]) : mounts buffer on existing storage (manage memory or not)
+-- new(str): allocates a buffer from the given string
+--
+function _instance.new(arg1, arg2, arg3)
+ local instance = table.inherit(_instance)
+ if type(arg1) == "number" then
+ local size = arg1
+ local ptr = arg2
+ if ptr then
+ -- new(size, ptr [, manage]) : mounts buffer on existing storage (manage memory or not)
+ local manage = arg3
+ if manage then
+ instance._CDATA = ffi.gc(ffi.cast("unsigned char*", ptr), ffi.C.free)
+ instance._MANAGED = true
+ else
+ instance._CDATA = ffi.cast("unsigned char*", ptr)
+ instance._MANAGED = false
+ end
+ else
+ -- new(size): allocates a buffer of given size
+ ptr = ffi.C.malloc(size)
+ instance._CDATA = ffi.gc(ffi.cast("unsigned char*", ptr), ffi.C.free)
+ instance._MANAGED = true
+ end
+ instance._SIZE = size
+ elseif type(arg1) == "string" then
+ -- new(str): allocates 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
+ else
+ os.raise("invalid arguments for bytes(...)!")
+ end
setmetatable(instance, _instance)
return instance
end
--- new an instance
-function bytes.new(str_or_size)
+-- get bytes size
+function _instance:size()
+ return self._SIZE
+end
+-- bytes:ipairs()
+function _instance:ipairs()
+ local index = 0
+ return function (...)
+ if index < self:size() then
+ index = index + 1
+ return index, self[index]
+ end
+ end
end
+-- bytes[key]
+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())
+ end
+ return self._CDATA[key - 1]
+ --[[
+ elseif type(key) == "table" then
+ local start, last = key[1], key[2]
+ return self:slice(start, last)
+ --]]
+ end
+ return rawget(self, key)
+end
+
+-- bytes[key] = value
+function _instance:__newindex(key, value)
+ 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())
+ end
+ self._CDATA[key - 1] = value
+ return
+ --[[
+ elseif type(key) == "table" then
+ local start,last = key[1],key[2]
+ self:slice(start,last):copy(value)
+ return]]
+ end
+ rawset(self, key, value)
+end
+
+-- tostring(bytes)
+function _instance:__tostring()
+ local parts = {}
+ for i = 1, tonumber(self:size()) do
+ parts[i] = bit.tohex(self[i], 2)
+ end
+ return "<bytes: " .. table.concat(parts, " ") .. ">"
+end
+
+-- new an bytes instance
+function bytes.new(...)
+ return _instance.new(...)
+end
+
+-- register call function
+setmetatable(bytes, {
+ __call = function (_, ...)
+ return bytes.new(...)
+ end,
+ __tostring = function()
+ return "<bytes>"
+ end
+})
+
-- return module: bytes
return bytes
diff --git a/xmake/core/base/io.lua b/xmake/core/base/io.lua
index 6cc340242..6dc13ca30 100644
--- a/xmake/core/base/io.lua
+++ b/xmake/core/base/io.lua
@@ -219,18 +219,16 @@ function _file:_ensure_opened()
return true
end
--- iterator of lines
-function _file._lines_iter(data)
- local l = data.file:read("l", data.opt)
- if not l and data.opt.close_on_finished then
- data.file:close()
- end
- return l
-end
-
--- read all lines from a file
+-- read all lines from file
function _file:lines(opt)
- return _file._lines_iter, { file = assert(self), opt = opt or {} }
+ opt = opt or {}
+ return function()
+ local l = self:read("l", opt)
+ if not l and opt.close_on_finished then
+ self:close()
+ end
+ return l
+ end
end
-- print file
diff --git a/xmake/core/sandbox/modules/bytes.lua b/xmake/core/sandbox/modules/bytes.lua
new file mode 100644
index 000000000..c1cbbcb2a
--- /dev/null
+++ b/xmake/core/sandbox/modules/bytes.lua
@@ -0,0 +1,23 @@
+--!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 - 2019, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file bytes.lua
+--
+
+-- load modules
+return require("base/bytes")
+
diff --git a/xmake/core/sandbox/modules/ipairs.lua b/xmake/core/sandbox/modules/ipairs.lua
index ee62dd87c..1d936b274 100644
--- a/xmake/core/sandbox/modules/ipairs.lua
+++ b/xmake/core/sandbox/modules/ipairs.lua
@@ -21,45 +21,22 @@
-- load modules
local table = require("base/table")
--- ipairs
---
--- e.g.
---
--- @code
---
--- for idx, val in ipairs({"a", "b", "c", "d", "e", "f"}) do
--- print("%d %s", idx, val)
--- end
---
--- for idx, val in ipairs({"a", "b", "c", "d", "e", "f"}, function (v) return v:upper() end) do
--- print("%d %s", idx, val)
--- end
---
--- for idx, val in ipairs({"a", "b", "c", "d", "e", "f"}, function (v, a, b) return v:upper() .. a .. b end, "a", "b") do
--- print("%d %s", idx, val)
--- end
---
--- @endcode
-function sandbox_ipairs(t, filter, ...)
+-- improve ipairs, wrap nil and single value
+function sandbox_ipairs(t)
- -- has filter?
- local has_filter = type(filter) == "function"
+ -- exists the custom ipairs?
+ if type(t) == "table" and t.ipairs then
+ return t:ipairs()
+ end
- -- init iterator
- local args = table.pack(...)
- local iter = function (t, i)
+ -- wrap table and return iterator
+ return function (t, i)
i = i + 1
local v = t[i]
if v ~= nil then
- if has_filter then
- v = filter(v, table.unpack(args, 1, args.n))
- end
return i, v
end
- end
-
- -- return iterator and initialized state
- return iter, table.wrap(t), 0
+ end, table.wrap(t), 0
end
-- load module
diff --git a/xmake/core/sandbox/modules/pairs.lua b/xmake/core/sandbox/modules/pairs.lua
index 92f533fe2..3aec2ebfc 100644
--- a/xmake/core/sandbox/modules/pairs.lua
+++ b/xmake/core/sandbox/modules/pairs.lua
@@ -21,45 +21,18 @@
-- load modules
local table = require("base/table")
--- pairs
---
--- e.g.
---
--- @code
---
--- local t = {a = "a", b = "b", c = "c", d = "d", e = "e", f = "f"}
---
--- for key, val in pairs(t) do
--- print("%s: %s", key, val)
--- end
---
--- for key, val in pairs(t, function (v) return v:upper() end) do
--- print("%s: %s", key, val)
--- end
---
--- for key, val in pairs(t, function (v, a, b) return v:upper() .. a .. b end, "a", "b") do
--- print("%s: %s", key, val)
--- end
---
--- @endcode
---
-function sandbox_pairs(t, filter, ...)
-
- -- has filter?
- local has_filter = type(filter) == "function"
+-- improve pairs, wrap nil/single value
+function sandbox_pairs(t)
- -- init iterator
- local args = {...}
- local iter = function (t, i)
- local k, v = next(t, i)
- if v and has_filter then
- v = filter(v, unpack(args))
- end
- return k, v
+ -- exists the custom ipairs?
+ if type(t) == "table" and t.pairs then
+ return t:pairs()
end
- -- return iterator and initialized state
- return iter, table.wrap(t), nil
+ -- wrap table and return iterator
+ return function (t, i)
+ return next(t, i)
+ end, table.wrap(t), nil
end
-- load module