阿赵Json工具AzhaoJson的Lua版本

发布于:2024-04-29 ⋅ 阅读:(26) ⋅ 点赞:(0)

  大家好,我是阿赵。
  之前分享了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