diff options
Diffstat (limited to 'util/json.lua')
-rw-r--r-- | util/json.lua | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/util/json.lua b/util/json.lua index efc602f0..9c2dd2c6 100644 --- a/util/json.lua +++ b/util/json.lua @@ -1,3 +1,10 @@ +-- Prosody IM +-- Copyright (C) 2008-2010 Matthew Wild +-- Copyright (C) 2008-2010 Waqas Hussain +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- local type = type; local t_insert, t_concat, t_remove, t_sort = table.insert, table.concat, table.remove, table.sort; @@ -9,6 +16,9 @@ local error = error; local newproxy, getmetatable = newproxy, getmetatable; local print = print; +local has_array, array = pcall(require, "util.array"); +local array_mt = hasarray and getmetatable(array()) or {}; + --module("json") local json = {}; @@ -29,6 +39,19 @@ for i=0,31 do if not escapes[ch] then escapes[ch] = ("\\u%.4X"):format(i); end end +local function codepoint_to_utf8(code) + if code < 0x80 then return s_char(code); end + local bits0_6 = code % 64; + if code < 0x800 then + local bits6_5 = (code - bits0_6) / 64; + return s_char(0x80 + 0x40 + bits6_5, 0x80 + bits0_6); + end + local bits0_12 = code % 4096; + local bits6_6 = (bits0_12 - bits0_6) / 64; + local bits12_4 = (code - bits0_12) / 4096; + return s_char(0x80 + 0x40 + 0x20 + bits12_4, 0x80 + bits6_6, 0x80 + bits0_6); +end + local valid_types = { number = true, string = true, @@ -130,7 +153,12 @@ function simplesave(o, buffer) elseif t == "string" then stringsave(o, buffer); elseif t == "table" then - tablesave(o, buffer); + local mt = getmetatable(o); + if mt == array_mt then + arraysave(o, buffer); + else + tablesave(o, buffer); + end elseif t == "boolean" then t_insert(buffer, (o and "true" or "false")); else @@ -148,6 +176,11 @@ function json.encode_ordered(obj) simplesave(obj, t); return t_concat(t); end +function json.encode_array(obj) + local t = {}; + arraysave(obj, t); + return t_concat(t); +end ----------------------------------- @@ -197,7 +230,7 @@ function json.decode(json) local readvalue; local function readarray() - local t = {}; + local t = setmetatable({}, array_mt); next(); -- skip '[' skipstuff(); if ch == "]" then next(); return t; end @@ -244,7 +277,7 @@ function json.decode(json) if not ch:match("[0-9a-fA-F]") then error("invalid unicode escape sequence in string"); end seq = seq..ch; end - s = s..s.char(tonumber(seq, 16)); -- FIXME do proper utf-8 + s = s..codepoint_to_utf8(tonumber(seq, 16)); next(); else error("invalid escape sequence in string"); end end |