大家好,我是阿赵。
之前分享了AzhaoJson的C#版本,这里顺便分享一下Lua的版本:
AzhaoJson.lua:
require "util/jsonParser"
AzhaoJson = {}
--lua table转json字符串
function AzhaoJson.Encode( tab )
local str = jsonParser.encode(tab)
return str
end
--json字符串转lua table
function AzhaoJson.Decode( str)
local tab = jsonParser.parser(tostring(str))
return tab
end
由于Lua是弱类型的,所以转换起来很简单,不需要用反射,只需要table转string,或者string转table就行了。所以主要的工具类里面只提供了这两个方法。
然后实际实现的类是jsonParser.lua:
jsonParser = {};
local this = jsonParser
function jsonParser.parser( str )
this.curPos = 1
this.orgStr = str
this.len = string.len(str)
this.token = this.read_un_space()
if this.token == "{" then
this.tab = this.get_obj()
elseif this.token == "[" then
this.tab = this.get_array()
end
if this.tab~=nil then
return this.tab
else
return nil
end
end
function jsonParser.read_un_space( )
if this.curPos>=this.len then
return ""
end
local s = string.sub(this.orgStr,this.curPos,this.curPos)
this.curPos = this.curPos +1
while (s == "\n" or s=="\r" or s=="\t" or s== "\\" or s == " ") do
if this.curPos>=this.len then
return ""
end
s = string.sub(this.orgStr,this.curPos,this.curPos)
this.curPos = this.curPos +1
end
return s
end
function jsonParser.read( )
if this.curPos>=this.len then
return ""
end
local s = string.sub(this.orgStr,this.curPos,this.curPos)
this.curPos = this.curPos +1
while (s == "\n" or s=="\r" or s=="\t" or s == "\\") do
if this.curPos>=this.len then
return ""
end
s = string.sub(this.orgStr,this.curPos,this.curPos)
this.curPos = this.curPos +1
end
return s
end
function jsonParser.read_str( )
if this.curPos>=this.len then
return ""
end
local s = string.sub(this.orgStr,this.curPos,this.curPos)
this.curPos = this.curPos +1
return s
end
function jsonParser.trim (s)
local trimStr = string.gsub(s, "^%s*(.-)%s*$", "%1")
return trimStr
end
function jsonParser.is_null(str )
if str == nil then
return true
elseif str =="" then
return true
else
return false
end
end
function jsonParser.get_obj()
local jd = {}
-- jd[type] = "object"
this.token = this.read_un_space()
while(this.token~="}" and this.curPos<this.len and this.is_null(this.token) == false) do
if this.token ~="," then
local key = this.get_key()
key = this.trim(key)
if this.is_null(key) == true then
break
end
local v = this.get_value()
local numKey = tonumber(key)
if numKey~=nil then
jd[numKey] = v
else
jd[key] = v
end
end
this.token = this.read_un_space()
end
return jd
end
function jsonParser.get_array()
local list = {}
this.token = this.read_un_space()
while(this.token~="]" and this.is_null(this.token) == false) do
if this.token == "{" then
table.insert(list,this.get_obj())
elseif this.token == "[" then
table.insert(list,this.get_array())
elseif this.token~="," then
local arrJd = this.get_final_value()
if arrJd~=nil then
table.insert(list,arrJd)
end
end
this.token = this.read_un_space()
end
return list
end
function jsonParser.get_key()
local k = ""
while(this.token ~=":" and this.token~="}" and this.is_null(this.token)==false) do
if this.token~="\"" and this.token~="{" then
k = this.concat(k,this.token)
end
this.token = this.read()
end
return k
end
function jsonParser.get_value()
this.token = this.read_un_space()
if this.token == "{" then
return this.get_obj()
elseif this.token == "[" then
return this.get_array()
else
return this.get_final_value()
end
end
function jsonParser.get_final_value()
local k = ""
local t = this.token
local tl = string.lower(t)
if t == "\"" then
local addStr = this.get_string()
return addStr
elseif tl == "t" or tl == "f" then
local addStr = this.get_bool()
k = this.concat(k,t)
k = this.concat(k,addStr)
local b = true
if string.lower(k) == "false" then
b = false
end
return b
elseif tl == "n" then
local addStr = this.get_null()
k = this.concat(k,t)
k = this.concat(k,addStr)
return nil
else
k = this.concat(k,t)
local addStr = this.get_num()
k = this.concat(k,addStr)
k = this.trim(k)
if string.lower(k) == "null" then
return nil
end
if k == "}" or k == "]" then
this.curPos = curPos -1
return nil
end
return tonumber(k)
end
return nil
end
function jsonParser.get_string( )
local k = ""
local last = nil
this.token = this.read_str()
while(this.token~="\"" and this.is_null(this.token)==false) do
if this.token ~= "\\" then
k = this.concat(k,this.token)
end
this.token = this.read_str()
end
if this.token == "}" or this.token == "]" then
this.curPos = this.curPos -1
end
--print("---------get_string------",k)
return k
end
function jsonParser.get_bool()
local k = ""
this.token = this.read()
while(this.token~="\"" and this.token~="," and this.token~="}" and this.token~="]" and this.is_null(this.token)==false) do
k = this.concat(k,this.token)
this.token = this.read()
end
if this.token == "}" or this.token == "]" then
this.curPos = this.curPos -1
end
return k
end
function jsonParser.get_null()
local k = ""
this.token = this.read()
while(this.token~="\"" and this.token~="," and this.token~="}" and this.token~="]" and this.is_null(this.token)==false) do
k = this.concat(k,this.token)
this.token = this.read()
end
if this.token == "}" or this.token == "]" then
this.curPos = this.curPos -1
end
return k
end
function jsonParser.get_num( )
local k = ""
this.token = this.read()
while(this.token~="\"" and this.token~="," and this.token~="}" and this.token~="]" and this.is_null(this.token)==false) do
k = this.concat(k,this.token)
this.token = this.read()
end
if this.token == "}" or this.token == "]" then
this.curPos = this.curPos -1
end
return k
end
function jsonParser.encode( obj )
this.tab = obj
return this.get_field(obj)
end
function jsonParser.get_field(obj)
if obj == nil then
return ""
end
local str = ""
local t = type(obj)
if t== "number" then
str = tostring(obj)
elseif t=="string" then
str = "\""
str = this.concat(str,tostring(obj))
str = this.concat(str,"\"")
elseif t=="boolean" or t=="bool" then
str = string.lower(tostring(obj))
else
str = this.get_obj_str(obj)
end
return str
end
function jsonParser.get_obj_str( obj )
if obj == nil then
return "null"
end
if type(obj) == "function" then
return "func"
end
local key_list = {}
local v_list = {}
for k,v in pairs(obj) do
table.insert(key_list,k)
table.insert(v_list,v)
end
local len = #key_list
if len <= 0 then
return "{}"
end
local str = "{"
for i=1,len do
local k = key_list[i]
local v = v_list[i]
str = this.concat(str,this.get_key_str(k))
str = this.concat(str,":")
str = this.concat(str,this.get_field(v))
if i<len then
str = this.concat(str,",")
end
end
str = this.concat(str,"}")
return str
end
function jsonParser.get_key_str( k )
if type(k) == "string" then
local str = "\""
str = this.concat(str,tostring(k))
str = this.concat(str,"\"")
return str
else
return tostring(k)
end
end
function jsonParser.concat(...)
local arg = { ... }
local resut = table.concat(arg);
return resut;
end