arbitrary type support (e.g., LuaJIT's cdata)

This commit is contained in:
Cheyi Lin 2013-06-19 19:33:16 +08:00
parent 091b62cd5d
commit f9575fd443

View File

@ -5,6 +5,17 @@
-- inspired by http://lua-users.org/wiki/TableSerialization
-----------------------------------------------------------------------------------------------------------------------
local type = type
local ipairs, pairs = ipairs, pairs
local string = string
local table = table
local tostring = tostring
local rawget = rawget
local pcall = pcall
local getmetatable, setmetatable = getmetatable, setmetatable
local rawget, rawset = rawget, rawset
local math = math
local inspect ={}
inspect.__VERSION = '1.2.0'
@ -34,19 +45,24 @@ local function isIdentifier(str)
end
local function isArrayKey(k, length)
return type(k)=='number' and 1 <= k and k <= length
return type(k) == 'number' and 1 <= k and k <= length
end
local function isDictionaryKey(k, length)
return not isArrayKey(k, length)
end
local sortOrdersByType = {
local sortOrdersByType = setmetatable({
['number'] = 1, ['boolean'] = 2, ['string'] = 3, ['table'] = 4,
['function'] = 5, ['userdata'] = 6, ['thread'] = 7
}
},
{ __index = function (t, k)
if not rawget(t, k) then
return math.huge
end
end })
local function sortKeys(a,b)
local function sortKeys(a, b)
local ta, tb = type(a), type(b)
if ta ~= tb then return sortOrdersByType[ta] < sortOrdersByType[tb] end
if ta == 'string' or ta == 'number' then return a < b end
@ -57,7 +73,7 @@ local function getDictionaryKeys(t)
local length = #t
local keys = {}
for k,_ in pairs(t) do
if isDictionaryKey(k, length) then table.insert(keys,k) end
if isDictionaryKey(k, length) then table.insert(keys, k) end
end
table.sort(keys, sortKeys)
return keys
@ -73,6 +89,26 @@ local function getToStringResultSafely(t, mt)
return string
end
local inspectorMaxIdsMetaTable = {
__index = function (t, k)
if not rawget(t, k) then
rawset(t, k, 0)
end
return 0
end
}
local inspectorIdsMetaTable = {
__index = function (t, k)
local v = rawget(t, k)
if not v then
rawset(t, k, setmetatable({}, {__mode = "kv"}))
v = rawget(t, k)
end
return v
end
}
local Inspector = {}
function Inspector:new(t, depth)
@ -80,18 +116,8 @@ function Inspector:new(t, depth)
buffer = {},
depth = depth,
level = 0,
maxIds = {
['function'] = 0,
['userdata'] = 0,
['thread'] = 0,
['table'] = 0
},
ids = {
['function'] = setmetatable({}, {__mode = "kv"}),
['userdata'] = setmetatable({}, {__mode = "kv"}),
['thread'] = setmetatable({}, {__mode = "kv"}),
['table'] = setmetatable({}, {__mode = "kv"})
},
maxIds = setmetatable({}, inspectorMaxIdsMetaTable),
ids = setmetatable({}, inspectorIdsMetaTable),
tableAppearances = setmetatable({}, {__mode = "k"})
}