-- Copyright 2008 Steven Barth <steven@midlink.org>
--- Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
+-- Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
local nixio = require "nixio"
local getmetatable = getmetatable
---- LuCI JSON-Library
--- @cstyle instance
module "luci.json"
---- Directly decode a JSON string
--- @param json JSON-String
--- @return Lua object
function decode(json, ...)
local a = ActiveDecoder(function() return nil end, ...)
a.chunk = json
end
---- Direcly encode a Lua object into a JSON string.
--- @param obj Lua Object
--- @return JSON string
function encode(obj, ...)
local out = {}
local e = Encoder(obj, 1, ...):source()
end
---- Null replacement function
--- @return null
function null()
return null
end
---- Create a new JSON-Encoder.
--- @class function
--- @name Encoder
--- @param data Lua-Object to be encoded.
--- @param buffersize Blocksize of returned data source.
--- @param fastescape Use non-standard escaping (don't escape control chars)
--- @return JSON-Encoder
Encoder = util.class()
function Encoder.__init__(self, data, buffersize, fastescape)
getmetatable(self).__call = Encoder.source
end
---- Create an LTN12 source providing the encoded JSON-Data.
--- @return LTN12 source
function Encoder.source(self)
local source = coroutine.create(self.dispatch)
return function()
local first = true
for key, entry in pairs(obj) do
- first = first or self:put(",")
- first = first and false
- self:parse_string(tostring(key))
- self:put(":")
- self:dispatch(entry)
+ if key ~= null then
+ first = first or self:put(",")
+ first = first and false
+ self:parse_string(tostring(key))
+ self:put(":")
+ self:dispatch(entry)
+ end
end
self:put("}")
end
end
+function Encoder.parse_udata(self, obj)
+ return self:parse_string(tostring(obj))
+end
+
Encoder.parsers = {
['nil'] = Encoder.parse_nil,
['table'] = Encoder.parse_iter,
['number'] = Encoder.parse_number,
['string'] = Encoder.parse_string,
['boolean'] = Encoder.parse_bool,
- ['function'] = Encoder.parse_iter
+ ['function'] = Encoder.parse_iter,
+ ['userdata'] = Encoder.parse_udata,
}
---- Create a new JSON-Decoder.
--- @class function
--- @name Decoder
--- @param customnull Use luci.json.null instead of nil for decoding null
--- @return JSON-Decoder
Decoder = util.class()
function Decoder.__init__(self, customnull)
getmetatable(self).__call = Decoder.sink
end
---- Create an LTN12 sink from the decoder object which accepts the JSON-Data.
--- @return LTN12 sink
function Decoder.sink(self)
local sink = coroutine.create(self.dispatch)
return function(...)
end
---- Get the decoded data packets after the rawdata has been sent to the sink.
--- @return Decoded data
function Decoder.get(self)
return self.data
end
}
---- Create a new Active JSON-Decoder.
--- @class function
--- @name ActiveDecoder
--- @param customnull Use luci.json.null instead of nil for decoding null
--- @return Active JSON-Decoder
ActiveDecoder = util.class(Decoder)
function ActiveDecoder.__init__(self, source, customnull)
end
---- Fetches one JSON-object from given source
--- @return Decoded object
function ActiveDecoder.get(self)
local chunk, src_err, object
if not self.chunk then