Software / code / prosody
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(); |