diff options
| author | ruki <[email protected]> | 2019-10-31 21:04:32 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2019-10-31 00:27:17 +0800 |
| commit | 7d47837062fba756f66e7bea313cb59f9a026477 (patch) | |
| tree | 1faef02540808728046c67d23c874f6118a0c774 | |
| parent | 057e930e41972cc5ee1812d16792dc6f6945279d (diff) | |
impl bytes index and ipairs
| -rw-r--r-- | xmake/core/base/bytes.lua | 123 | ||||
| -rw-r--r-- | xmake/core/base/io.lua | 20 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/bytes.lua | 23 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/ipairs.lua | 41 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/pairs.lua | 45 |
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 |
