Comparison

util/json.lua @ 5521:076534a0384a

Merge 0.9->trunk
author Matthew Wild <mwild1@gmail.com>
date Thu, 25 Apr 2013 20:37:51 +0100
parent 5517:9d7349bbe4d2
child 5561:52eef11cd8af
comparison
equal deleted inserted replaced
5515:865d82f21d12 5521:076534a0384a
1 -- Prosody IM 1 -- Prosody IM
2 -- Copyright (C) 2008-2010 Matthew Wild 2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain 3 -- Copyright (C) 2008-2010 Waqas Hussain
4 --
5 -- utf8char copyright (C) 2007 Rici Lake
6 -- 4 --
7 -- This project is MIT/X11 licensed. Please see the 5 -- This project is MIT/X11 licensed. Please see the
8 -- COPYING file in the source package for more information. 6 -- COPYING file in the source package for more information.
9 -- 7 --
10 8
16 local next = next; 14 local next = next;
17 local error = error; 15 local error = error;
18 local newproxy, getmetatable = newproxy, getmetatable; 16 local newproxy, getmetatable = newproxy, getmetatable;
19 local print = print; 17 local print = print;
20 18
19 local has_array, array = pcall(require, "util.array");
20 local array_mt = hasarray and getmetatable(array()) or {};
21
21 --module("json") 22 --module("json")
22 local json = {}; 23 local json = {};
23 24
24 local null = newproxy and newproxy(true) or {}; 25 local null = newproxy and newproxy(true) or {};
25 if getmetatable and getmetatable(null) then 26 if getmetatable and getmetatable(null) then
36 for i=0,31 do 37 for i=0,31 do
37 local ch = s_char(i); 38 local ch = s_char(i);
38 if not escapes[ch] then escapes[ch] = ("\\u%.4X"):format(i); end 39 if not escapes[ch] then escapes[ch] = ("\\u%.4X"):format(i); end
39 end 40 end
40 41
41 local function utf8char(i) 42 local function codepoint_to_utf8(code)
42 if i >= 0 then 43 if code < 0x80 then return s_char(code); end
43 i = i - i%1 44 local bits0_6 = code % 64;
44 if i < 128 then 45 if code < 0x800 then
45 return s_char(i) 46 local bits6_5 = (code - bits0_6) / 64;
46 else 47 return s_char(0x80 + 0x40 + bits6_5, 0x80 + bits0_6);
47 local c1 = i % 64 48 end
48 i = (i - c1) / 64 49 local bits0_12 = code % 4096;
49 if i < 32 then 50 local bits6_6 = (bits0_12 - bits0_6) / 64;
50 return s_char(0xC0+i, 0x80+c1) 51 local bits12_4 = (code - bits0_12) / 4096;
51 else 52 return s_char(0x80 + 0x40 + 0x20 + bits12_4, 0x80 + bits6_6, 0x80 + bits0_6);
52 local c2 = i % 64 53 end
53 i = (i - c2) / 64
54 if i < 16 and (i ~= 13 or c2 < 32) then
55 return s_char(0xE0+i, 0x80+c2, 0x80+c1)
56 elseif i >= 16 and i < 0x110 then
57 local c3 = i % 64
58 i = (i - c3) / 64
59 return s_char(0xF0+i, 0x80+c3, 0x80+c2, 0x80+c1)
60 end
61 end
62 end
63 end
64 end
65
66 54
67 local valid_types = { 55 local valid_types = {
68 number = true, 56 number = true,
69 string = true, 57 string = true,
70 table = true, 58 table = true,
163 if t == "number" then 151 if t == "number" then
164 t_insert(buffer, tostring(o)); 152 t_insert(buffer, tostring(o));
165 elseif t == "string" then 153 elseif t == "string" then
166 stringsave(o, buffer); 154 stringsave(o, buffer);
167 elseif t == "table" then 155 elseif t == "table" then
168 tablesave(o, buffer); 156 local mt = getmetatable(o);
157 if mt == array_mt then
158 arraysave(o, buffer);
159 else
160 tablesave(o, buffer);
161 end
169 elseif t == "boolean" then 162 elseif t == "boolean" then
170 t_insert(buffer, (o and "true" or "false")); 163 t_insert(buffer, (o and "true" or "false"));
171 else 164 else
172 t_insert(buffer, "null"); 165 t_insert(buffer, "null");
173 end 166 end
235 end 228 end
236 end 229 end
237 230
238 local readvalue; 231 local readvalue;
239 local function readarray() 232 local function readarray()
240 local t = {}; 233 local t = setmetatable({}, array_mt);
241 next(); -- skip '[' 234 next(); -- skip '['
242 skipstuff(); 235 skipstuff();
243 if ch == "]" then next(); return t; end 236 if ch == "]" then next(); return t; end
244 t_insert(t, readvalue()); 237 t_insert(t, readvalue());
245 while true do 238 while true do
282 next(); 275 next();
283 if not ch then error("unexpected eof in string"); end 276 if not ch then error("unexpected eof in string"); end
284 if not ch:match("[0-9a-fA-F]") then error("invalid unicode escape sequence in string"); end 277 if not ch:match("[0-9a-fA-F]") then error("invalid unicode escape sequence in string"); end
285 seq = seq..ch; 278 seq = seq..ch;
286 end 279 end
287 s = s..utf8char(tonumber(seq, 16)); 280 s = s..codepoint_to_utf8(tonumber(seq, 16));
288 next(); 281 next();
289 else error("invalid escape sequence in string"); end 282 else error("invalid escape sequence in string"); end
290 end 283 end
291 if ch == "\"" then 284 if ch == "\"" then
292 next(); 285 next();