json.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. -- Copyright 2008 Steven Barth <steven@midlink.org>
  2. -- Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
  3. -- Licensed to the public under the Apache License 2.0.
  4. local nixio = require "nixio"
  5. local util = require "luci.util"
  6. local table = require "table"
  7. local string = require "string"
  8. local coroutine = require "coroutine"
  9. local assert = assert
  10. local tonumber = tonumber
  11. local tostring = tostring
  12. local error = error
  13. local type = type
  14. local pairs = pairs
  15. local ipairs = ipairs
  16. local next = next
  17. local pcall = pcall
  18. local band = nixio.bit.band
  19. local bor = nixio.bit.bor
  20. local rshift = nixio.bit.rshift
  21. local char = string.char
  22. local getmetatable = getmetatable
  23. module "luci.json"
  24. function decode(json, ...)
  25. local a = ActiveDecoder(function() return nil end, ...)
  26. a.chunk = json
  27. local s, obj = pcall(a.get, a)
  28. return s and obj or nil
  29. end
  30. function encode(obj, ...)
  31. local out = {}
  32. local e = Encoder(obj, 1, ...):source()
  33. local chnk, err
  34. repeat
  35. chnk, err = e()
  36. out[#out+1] = chnk
  37. until not chnk
  38. return not err and table.concat(out) or nil
  39. end
  40. function null()
  41. return null
  42. end
  43. Encoder = util.class()
  44. function Encoder.__init__(self, data, buffersize, fastescape)
  45. self.data = data
  46. self.buffersize = buffersize or 512
  47. self.buffer = ""
  48. self.fastescape = fastescape
  49. getmetatable(self).__call = Encoder.source
  50. end
  51. function Encoder.source(self)
  52. local source = coroutine.create(self.dispatch)
  53. return function()
  54. local res, data = coroutine.resume(source, self, self.data, true)
  55. if res then
  56. return data
  57. else
  58. return nil, data
  59. end
  60. end
  61. end
  62. function Encoder.dispatch(self, data, start)
  63. local parser = self.parsers[type(data)]
  64. parser(self, data)
  65. if start then
  66. if #self.buffer > 0 then
  67. coroutine.yield(self.buffer)
  68. end
  69. coroutine.yield()
  70. end
  71. end
  72. function Encoder.put(self, chunk)
  73. if self.buffersize < 2 then
  74. coroutine.yield(chunk)
  75. else
  76. if #self.buffer + #chunk > self.buffersize then
  77. local written = 0
  78. local fbuffer = self.buffersize - #self.buffer
  79. coroutine.yield(self.buffer .. chunk:sub(written + 1, fbuffer))
  80. written = fbuffer
  81. while #chunk - written > self.buffersize do
  82. fbuffer = written + self.buffersize
  83. coroutine.yield(chunk:sub(written + 1, fbuffer))
  84. written = fbuffer
  85. end
  86. self.buffer = chunk:sub(written + 1)
  87. else
  88. self.buffer = self.buffer .. chunk
  89. end
  90. end
  91. end
  92. function Encoder.parse_nil(self)
  93. self:put("null")
  94. end
  95. function Encoder.parse_bool(self, obj)
  96. self:put(obj and "true" or "false")
  97. end
  98. function Encoder.parse_number(self, obj)
  99. self:put(tostring(obj))
  100. end
  101. function Encoder.parse_string(self, obj)
  102. if self.fastescape then
  103. self:put('"' .. obj:gsub('\\', '\\\\'):gsub('"', '\\"') .. '"')
  104. else
  105. self:put('"' ..
  106. obj:gsub('[%c\\"]',
  107. function(char)
  108. return '\\u00%02x' % char:byte()
  109. end
  110. )
  111. .. '"')
  112. end
  113. end
  114. function Encoder.parse_iter(self, obj)
  115. if obj == null then
  116. return self:put("null")
  117. end
  118. if type(obj) == "table" and (#obj == 0 and next(obj)) then
  119. self:put("{")
  120. local first = true
  121. for key, entry in pairs(obj) do
  122. if key ~= null then
  123. first = first or self:put(",")
  124. first = first and false
  125. self:parse_string(tostring(key))
  126. self:put(":")
  127. self:dispatch(entry)
  128. end
  129. end
  130. self:put("}")
  131. else
  132. self:put("[")
  133. local first = true
  134. if type(obj) == "table" then
  135. for i=1, #obj do
  136. first = first or self:put(",")
  137. first = first and nil
  138. self:dispatch(obj[i])
  139. end
  140. else
  141. for entry in obj do
  142. first = first or self:put(",")
  143. first = first and nil
  144. self:dispatch(entry)
  145. end
  146. end
  147. self:put("]")
  148. end
  149. end
  150. function Encoder.parse_udata(self, obj)
  151. return self:parse_string(tostring(obj))
  152. end
  153. Encoder.parsers = {
  154. ['nil'] = Encoder.parse_nil,
  155. ['table'] = Encoder.parse_iter,
  156. ['number'] = Encoder.parse_number,
  157. ['string'] = Encoder.parse_string,
  158. ['boolean'] = Encoder.parse_bool,
  159. ['function'] = Encoder.parse_iter,
  160. ['userdata'] = Encoder.parse_udata,
  161. }
  162. Decoder = util.class()
  163. function Decoder.__init__(self, customnull)
  164. self.cnull = customnull
  165. getmetatable(self).__call = Decoder.sink
  166. end
  167. function Decoder.sink(self)
  168. local sink = coroutine.create(self.dispatch)
  169. return function(...)
  170. return coroutine.resume(sink, self, ...)
  171. end
  172. end
  173. function Decoder.get(self)
  174. return self.data
  175. end
  176. function Decoder.dispatch(self, chunk, src_err, strict)
  177. local robject, object
  178. local oset = false
  179. while chunk do
  180. while chunk and #chunk < 1 do
  181. chunk = self:fetch()
  182. end
  183. assert(not strict or chunk, "Unexpected EOS")
  184. if not chunk then break end
  185. local char = chunk:sub(1, 1)
  186. local parser = self.parsers[char]
  187. or (char:match("%s") and self.parse_space)
  188. or (char:match("[0-9-]") and self.parse_number)
  189. or error("Unexpected char '%s'" % char)
  190. chunk, robject = parser(self, chunk)
  191. if parser ~= self.parse_space then
  192. assert(not oset, "Scope violation: Too many objects")
  193. object = robject
  194. oset = true
  195. if strict then
  196. return chunk, object
  197. end
  198. end
  199. end
  200. assert(not src_err, src_err)
  201. assert(oset, "Unexpected EOS")
  202. self.data = object
  203. end
  204. function Decoder.fetch(self)
  205. local tself, chunk, src_err = coroutine.yield()
  206. assert(chunk or not src_err, src_err)
  207. return chunk
  208. end
  209. function Decoder.fetch_atleast(self, chunk, bytes)
  210. while #chunk < bytes do
  211. local nchunk = self:fetch()
  212. assert(nchunk, "Unexpected EOS")
  213. chunk = chunk .. nchunk
  214. end
  215. return chunk
  216. end
  217. function Decoder.fetch_until(self, chunk, pattern)
  218. local start = chunk:find(pattern)
  219. while not start do
  220. local nchunk = self:fetch()
  221. assert(nchunk, "Unexpected EOS")
  222. chunk = chunk .. nchunk
  223. start = chunk:find(pattern)
  224. end
  225. return chunk, start
  226. end
  227. function Decoder.parse_space(self, chunk)
  228. local start = chunk:find("[^%s]")
  229. while not start do
  230. chunk = self:fetch()
  231. if not chunk then
  232. return nil
  233. end
  234. start = chunk:find("[^%s]")
  235. end
  236. return chunk:sub(start)
  237. end
  238. function Decoder.parse_literal(self, chunk, literal, value)
  239. chunk = self:fetch_atleast(chunk, #literal)
  240. assert(chunk:sub(1, #literal) == literal, "Invalid character sequence")
  241. return chunk:sub(#literal + 1), value
  242. end
  243. function Decoder.parse_null(self, chunk)
  244. return self:parse_literal(chunk, "null", self.cnull and null)
  245. end
  246. function Decoder.parse_true(self, chunk)
  247. return self:parse_literal(chunk, "true", true)
  248. end
  249. function Decoder.parse_false(self, chunk)
  250. return self:parse_literal(chunk, "false", false)
  251. end
  252. function Decoder.parse_number(self, chunk)
  253. local chunk, start = self:fetch_until(chunk, "[^0-9eE.+-]")
  254. local number = tonumber(chunk:sub(1, start - 1))
  255. assert(number, "Invalid number specification")
  256. return chunk:sub(start), number
  257. end
  258. function Decoder.parse_string(self, chunk)
  259. local str = ""
  260. local object = nil
  261. assert(chunk:sub(1, 1) == '"', 'Expected "')
  262. chunk = chunk:sub(2)
  263. while true do
  264. local spos = chunk:find('[\\"]')
  265. if spos then
  266. str = str .. chunk:sub(1, spos - 1)
  267. local char = chunk:sub(spos, spos)
  268. if char == '"' then -- String end
  269. chunk = chunk:sub(spos + 1)
  270. break
  271. elseif char == "\\" then -- Escape sequence
  272. chunk, object = self:parse_escape(chunk:sub(spos))
  273. str = str .. object
  274. end
  275. else
  276. str = str .. chunk
  277. chunk = self:fetch()
  278. assert(chunk, "Unexpected EOS while parsing a string")
  279. end
  280. end
  281. return chunk, str
  282. end
  283. function Decoder.utf8_encode(self, s1, s2)
  284. local n = s1 * 256 + s2
  285. if n >= 0 and n <= 0x7F then
  286. return char(n)
  287. elseif n >= 0 and n <= 0x7FF then
  288. return char(
  289. bor(band(rshift(n, 6), 0x1F), 0xC0),
  290. bor(band(n, 0x3F), 0x80)
  291. )
  292. elseif n >= 0 and n <= 0xFFFF then
  293. return char(
  294. bor(band(rshift(n, 12), 0x0F), 0xE0),
  295. bor(band(rshift(n, 6), 0x3F), 0x80),
  296. bor(band(n, 0x3F), 0x80)
  297. )
  298. elseif n >= 0 and n <= 0x10FFFF then
  299. return char(
  300. bor(band(rshift(n, 18), 0x07), 0xF0),
  301. bor(band(rshift(n, 12), 0x3F), 0x80),
  302. bor(band(rshift(n, 6), 0x3F), 0x80),
  303. bor(band(n, 0x3F), 0x80)
  304. )
  305. else
  306. return "?"
  307. end
  308. end
  309. function Decoder.parse_escape(self, chunk)
  310. local str = ""
  311. chunk = self:fetch_atleast(chunk:sub(2), 1)
  312. local char = chunk:sub(1, 1)
  313. chunk = chunk:sub(2)
  314. if char == '"' then
  315. return chunk, '"'
  316. elseif char == "\\" then
  317. return chunk, "\\"
  318. elseif char == "u" then
  319. chunk = self:fetch_atleast(chunk, 4)
  320. local s1, s2 = chunk:sub(1, 2), chunk:sub(3, 4)
  321. s1, s2 = tonumber(s1, 16), tonumber(s2, 16)
  322. assert(s1 and s2, "Invalid Unicode character")
  323. return chunk:sub(5), self:utf8_encode(s1, s2)
  324. elseif char == "/" then
  325. return chunk, "/"
  326. elseif char == "b" then
  327. return chunk, "\b"
  328. elseif char == "f" then
  329. return chunk, "\f"
  330. elseif char == "n" then
  331. return chunk, "\n"
  332. elseif char == "r" then
  333. return chunk, "\r"
  334. elseif char == "t" then
  335. return chunk, "\t"
  336. else
  337. error("Unexpected escaping sequence '\\%s'" % char)
  338. end
  339. end
  340. function Decoder.parse_array(self, chunk)
  341. chunk = chunk:sub(2)
  342. local array = {}
  343. local nextp = 1
  344. local chunk, object = self:parse_delimiter(chunk, "%]")
  345. if object then
  346. return chunk, array
  347. end
  348. repeat
  349. chunk, object = self:dispatch(chunk, nil, true)
  350. table.insert(array, nextp, object)
  351. nextp = nextp + 1
  352. chunk, object = self:parse_delimiter(chunk, ",%]")
  353. assert(object, "Delimiter expected")
  354. until object == "]"
  355. return chunk, array
  356. end
  357. function Decoder.parse_object(self, chunk)
  358. chunk = chunk:sub(2)
  359. local array = {}
  360. local name
  361. local chunk, object = self:parse_delimiter(chunk, "}")
  362. if object then
  363. return chunk, array
  364. end
  365. repeat
  366. chunk = self:parse_space(chunk)
  367. assert(chunk, "Unexpected EOS")
  368. chunk, name = self:parse_string(chunk)
  369. chunk, object = self:parse_delimiter(chunk, ":")
  370. assert(object, "Separator expected")
  371. chunk, object = self:dispatch(chunk, nil, true)
  372. array[name] = object
  373. chunk, object = self:parse_delimiter(chunk, ",}")
  374. assert(object, "Delimiter expected")
  375. until object == "}"
  376. return chunk, array
  377. end
  378. function Decoder.parse_delimiter(self, chunk, delimiter)
  379. while true do
  380. chunk = self:fetch_atleast(chunk, 1)
  381. local char = chunk:sub(1, 1)
  382. if char:match("%s") then
  383. chunk = self:parse_space(chunk)
  384. assert(chunk, "Unexpected EOS")
  385. elseif char:match("[%s]" % delimiter) then
  386. return chunk:sub(2), char
  387. else
  388. return chunk, nil
  389. end
  390. end
  391. end
  392. Decoder.parsers = {
  393. ['"'] = Decoder.parse_string,
  394. ['t'] = Decoder.parse_true,
  395. ['f'] = Decoder.parse_false,
  396. ['n'] = Decoder.parse_null,
  397. ['['] = Decoder.parse_array,
  398. ['{'] = Decoder.parse_object
  399. }
  400. ActiveDecoder = util.class(Decoder)
  401. function ActiveDecoder.__init__(self, source, customnull)
  402. Decoder.__init__(self, customnull)
  403. self.source = source
  404. self.chunk = nil
  405. getmetatable(self).__call = self.get
  406. end
  407. function ActiveDecoder.get(self)
  408. local chunk, src_err, object
  409. if not self.chunk then
  410. chunk, src_err = self.source()
  411. else
  412. chunk = self.chunk
  413. end
  414. self.chunk, object = self:dispatch(chunk, src_err, true)
  415. return object
  416. end
  417. function ActiveDecoder.fetch(self)
  418. local chunk, src_err = self.source()
  419. assert(chunk or not src_err, src_err)
  420. return chunk
  421. end