Advertisement
Alakazard12

JSON

Mar 26th, 2014
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 29.28 KB | None | 0 0
  1. -- -*- coding: utf-8 -*-
  2. --
  3. -- Simple JSON encoding and decoding in pure Lua.
  4. --
  5. -- Copyright 2010-2013 Jeffrey Friedl
  6. -- http://regex.info/blog/
  7. --
  8. -- Latest version: http://regex.info/blog/lua/json
  9. --
  10. -- This code is released under a Creative Commons CC-BY "Attribution" License:
  11. -- http://creativecommons.org/licenses/by/3.0/deed.en_US
  12. --
  13. -- It can be used for any purpose so long as the copyright notice and
  14. -- web-page links above are maintained. Enjoy.
  15. --
  16. local VERSION = 20140116.10  -- version history at end of file
  17. local OBJDEF = { VERSION = VERSION }
  18.  
  19.  
  20. --
  21. -- Simple JSON encoding and decoding in pure Lua.
  22. -- http://www.json.org/
  23. --
  24. --
  25. --   JSON = (loadfile "JSON.lua")() -- one-time load of the routines
  26. --
  27. --   local lua_value = JSON:decode(raw_json_text)
  28. --
  29. --   local raw_json_text    = JSON:encode(lua_table_or_value)
  30. --   local pretty_json_text = JSON:encode_pretty(lua_table_or_value) -- "pretty printed" version for human readability
  31. --
  32. --
  33. -- DECODING
  34. --
  35. --   JSON = (loadfile "JSON.lua")() -- one-time load of the routines
  36. --
  37. --   local lua_value = JSON:decode(raw_json_text)
  38. --
  39. --   If the JSON text is for an object or an array, e.g.
  40. --     { "what": "books", "count": 3 }
  41. --   or
  42. --     [ "Larry", "Curly", "Moe" ]
  43. --
  44. --   the result is a Lua table, e.g.
  45. --     { what = "books", count = 3 }
  46. --   or
  47. --     { "Larry", "Curly", "Moe" }
  48. --
  49. --
  50. --   The encode and decode routines accept an optional second argument, "etc", which is not used
  51. --   during encoding or decoding, but upon error is passed along to error handlers. It can be of any
  52. --   type (including nil).
  53. --
  54. --   With most errors during decoding, this code calls
  55. --
  56. --      JSON:onDecodeError(message, text, location, etc)
  57. --
  58. --   with a message about the error, and if known, the JSON text being parsed and the byte count
  59. --   where the problem was discovered. You can replace the default JSON:onDecodeError() with your
  60. --   own function.
  61. --
  62. --   The default onDecodeError() merely augments the message with data about the text and the
  63. --   location if known (and if a second 'etc' argument had been provided to decode(), its value is
  64. --   tacked onto the message as well), and then calls JSON.assert(), which itself defaults to Lua's
  65. --   built-in assert(), and can also be overridden.
  66. --
  67. --   For example, in an Adobe Lightroom plugin, you might use something like
  68. --
  69. --          function JSON:onDecodeError(message, text, location, etc)
  70. --             LrErrors.throwUserError("Internal Error: invalid JSON data")
  71. --          end
  72. --
  73. --   or even just
  74. --
  75. --          function JSON.assert(message)
  76. --             LrErrors.throwUserError("Internal Error: " .. message)
  77. --          end
  78. --
  79. --   If JSON:decode() is passed a nil, this is called instead:
  80. --
  81. --      JSON:onDecodeOfNilError(message, nil, nil, etc)
  82. --
  83. --   and if JSON:decode() is passed HTML instead of JSON, this is called:
  84. --
  85. --      JSON:onDecodeOfHTMLError(message, text, nil, etc)
  86. --
  87. --   The use of the fourth 'etc' argument allows stronger coordination between decoding and error
  88. --   reporting, especially when you provide your own error-handling routines. Continuing with the
  89. --   the Adobe Lightroom plugin example:
  90. --
  91. --          function JSON:onDecodeError(message, text, location, etc)
  92. --             local note = "Internal Error: invalid JSON data"
  93. --             if type(etc) = 'table' and etc.photo then
  94. --                note = note .. " while processing for " .. etc.photo:getFormattedMetadata('fileName')
  95. --             end
  96. --             LrErrors.throwUserError(note)
  97. --          end
  98. --
  99. --            :
  100. --            :
  101. --
  102. --          for i, photo in ipairs(photosToProcess) do
  103. --               :            
  104. --               :            
  105. --               local data = JSON:decode(someJsonText, { photo = photo })
  106. --               :            
  107. --               :            
  108. --          end
  109. --
  110. --
  111. --
  112. --
  113.  
  114. -- DECODING AND STRICT TYPES
  115. --
  116. --   Because both JSON objects and JSON arrays are converted to Lua tables, it's not normally
  117. --   possible to tell which a JSON type a particular Lua table was derived from, or guarantee
  118. --   decode-encode round-trip equivalency.
  119. --
  120. --   However, if you enable strictTypes, e.g.
  121. --
  122. --      JSON = (loadfile "JSON.lua")() --load the routines
  123. --      JSON.strictTypes = true
  124. --
  125. --   then the Lua table resulting from the decoding of a JSON object or JSON array is marked via Lua
  126. --   metatable, so that when re-encoded with JSON:encode() it ends up as the appropriate JSON type.
  127. --
  128. --   (This is not the default because other routines may not work well with tables that have a
  129. --   metatable set, for example, Lightroom API calls.)
  130. --
  131. --
  132. -- ENCODING
  133. --
  134. --   JSON = (loadfile "JSON.lua")() -- one-time load of the routines
  135. --
  136. --   local raw_json_text    = JSON:encode(lua_table_or_value)
  137. --   local pretty_json_text = JSON:encode_pretty(lua_table_or_value) -- "pretty printed" version for human readability
  138.  
  139. --   On error during encoding, this code calls:
  140. --
  141. --    JSON:onEncodeError(message, etc)
  142. --
  143. --   which you can override in your local JSON object.
  144. --
  145. --   If the Lua table contains both string and numeric keys, it fits neither JSON's
  146. --   idea of an object, nor its idea of an array. To get around this, when any string
  147. --   key exists (or when non-positive numeric keys exist), numeric keys are converted
  148. --   to strings.
  149. --
  150. --   For example,
  151. --     JSON:encode({ "one", "two", "three", SOMESTRING = "some string" }))
  152. --   produces the JSON object
  153. --     {"1":"one","2":"two","3":"three","SOMESTRING":"some string"}
  154. --
  155. --   To prohibit this conversion and instead make it an error condition, set
  156. --      JSON.noKeyConversion = true
  157.  
  158.  
  159. --
  160. -- SUMMARY OF METHODS YOU CAN OVERRIDE IN YOUR LOCAL LUA JSON OBJECT
  161. --
  162. --    assert
  163. --    onDecodeError
  164. --    onDecodeOfNilError
  165. --    onDecodeOfHTMLError
  166. --    onEncodeError
  167. --
  168. --  If you want to create a separate Lua JSON object with its own error handlers,
  169. --  you can reload JSON.lua or use the :new() method.
  170. --
  171. ---------------------------------------------------------------------------
  172.  
  173.  
  174. local author = "-[ JSON.lua package by Jeffrey Friedl (http://regex.info/blog/lua/json), version " .. tostring(VERSION) .. " ]-"
  175. local isArray  = { __tostring = function() return "JSON array"  end }    isArray.__index  = isArray
  176. local isObject = { __tostring = function() return "JSON object" end }    isObject.__index = isObject
  177.  
  178.  
  179. function OBJDEF:newArray(tbl)
  180.    return setmetatable(tbl or {}, isArray)
  181. end
  182.  
  183. function OBJDEF:newObject(tbl)
  184.    return setmetatable(tbl or {}, isObject)
  185. end
  186.  
  187. local function unicode_codepoint_as_utf8(codepoint)
  188.    --
  189.    -- codepoint is a number
  190.    --
  191.    if codepoint <= 127 then
  192.       return string.char(codepoint)
  193.  
  194.    elseif codepoint <= 2047 then
  195.       --
  196.       -- 110yyyxx 10xxxxxx         <-- useful notation from http://en.wikipedia.org/wiki/Utf8
  197.       --
  198.       local highpart = math.floor(codepoint / 0x40)
  199.       local lowpart  = codepoint - (0x40 * highpart)
  200.       return string.char(0xC0 + highpart,
  201.                          0x80 + lowpart)
  202.  
  203.    elseif codepoint <= 65535 then
  204.       --
  205.       -- 1110yyyy 10yyyyxx 10xxxxxx
  206.       --
  207.       local highpart  = math.floor(codepoint / 0x1000)
  208.       local remainder = codepoint - 0x1000 * highpart
  209.       local midpart   = math.floor(remainder / 0x40)
  210.       local lowpart   = remainder - 0x40 * midpart
  211.  
  212.       highpart = 0xE0 + highpart
  213.       midpart  = 0x80 + midpart
  214.       lowpart  = 0x80 + lowpart
  215.  
  216.       --
  217.       -- Check for an invalid character (thanks Andy R. at Adobe).
  218.       -- See table 3.7, page 93, in http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf#G28070
  219.       --
  220.       if ( highpart == 0xE0 and midpart < 0xA0 ) or
  221.          ( highpart == 0xED and midpart > 0x9F ) or
  222.          ( highpart == 0xF0 and midpart < 0x90 ) or
  223.          ( highpart == 0xF4 and midpart > 0x8F )
  224.       then
  225.          return "?"
  226.       else
  227.          return string.char(highpart,
  228.                             midpart,
  229.                             lowpart)
  230.       end
  231.  
  232.    else
  233.       --
  234.       -- 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
  235.       --
  236.       local highpart  = math.floor(codepoint / 0x40000)
  237.       local remainder = codepoint - 0x40000 * highpart
  238.       local midA      = math.floor(remainder / 0x1000)
  239.       remainder       = remainder - 0x1000 * midA
  240.       local midB      = math.floor(remainder / 0x40)
  241.       local lowpart   = remainder - 0x40 * midB
  242.  
  243.       return string.char(0xF0 + highpart,
  244.                          0x80 + midA,
  245.                          0x80 + midB,
  246.                          0x80 + lowpart)
  247.    end
  248. end
  249.  
  250. function OBJDEF:onDecodeError(message, text, location, etc)
  251.    if text then
  252.       if location then
  253.          message = string.format("%s at char %d of: %s", message, location, text)
  254.       else
  255.          message = string.format("%s: %s", message, text)
  256.       end
  257.    end
  258.  
  259.    if etc ~= nil then
  260.       message = message .. " (" .. OBJDEF:encode(etc) .. ")"
  261.    end
  262.  
  263.    if self.assert then
  264.       self.assert(false, message)
  265.    else
  266.       assert(false, message)
  267.    end
  268. end
  269.  
  270. OBJDEF.onDecodeOfNilError  = OBJDEF.onDecodeError
  271. OBJDEF.onDecodeOfHTMLError = OBJDEF.onDecodeError
  272.  
  273. function OBJDEF:onEncodeError(message, etc)
  274.    if etc ~= nil then
  275.       message = message .. " (" .. OBJDEF:encode(etc) .. ")"
  276.    end
  277.  
  278.    if self.assert then
  279.       self.assert(false, message)
  280.    else
  281.       assert(false, message)
  282.    end
  283. end
  284.  
  285. local function grok_number(self, text, start, etc)
  286.    --
  287.    -- Grab the integer part
  288.    --
  289.    local integer_part = text:match('^-?[1-9]%d*', start)
  290.                      or text:match("^-?0",        start)
  291.  
  292.    if not integer_part then
  293.       self:onDecodeError("expected number", text, start, etc)
  294.    end
  295.  
  296.    local i = start + integer_part:len()
  297.  
  298.    --
  299.    -- Grab an optional decimal part
  300.    --
  301.    local decimal_part = text:match('^%.%d+', i) or ""
  302.  
  303.    i = i + decimal_part:len()
  304.  
  305.    --
  306.    -- Grab an optional exponential part
  307.    --
  308.    local exponent_part = text:match('^[eE][-+]?%d+', i) or ""
  309.  
  310.    i = i + exponent_part:len()
  311.  
  312.    local full_number_text = integer_part .. decimal_part .. exponent_part
  313.    local as_number = tonumber(full_number_text)
  314.  
  315.    if not as_number then
  316.       self:onDecodeError("bad number", text, start, etc)
  317.    end
  318.  
  319.    return as_number, i
  320. end
  321.  
  322.  
  323. local function grok_string(self, text, start, etc)
  324.  
  325.    if text:sub(start,start) ~= '"' then
  326.       self:onDecodeError("expected string's opening quote", text, start, etc)
  327.    end
  328.  
  329.    local i = start + 1 -- +1 to bypass the initial quote
  330.    local text_len = text:len()
  331.    local VALUE = ""
  332.    while i <= text_len do
  333.       local c = text:sub(i,i)
  334.       if c == '"' then
  335.          return VALUE, i + 1
  336.       end
  337.       if c ~= '\\' then
  338.          VALUE = VALUE .. c
  339.          i = i + 1
  340.       elseif text:match('^\\b', i) then
  341.          VALUE = VALUE .. "\b"
  342.          i = i + 2
  343.       elseif text:match('^\\f', i) then
  344.          VALUE = VALUE .. "\f"
  345.          i = i + 2
  346.       elseif text:match('^\\n', i) then
  347.          VALUE = VALUE .. "\n"
  348.          i = i + 2
  349.       elseif text:match('^\\r', i) then
  350.          VALUE = VALUE .. "\r"
  351.          i = i + 2
  352.       elseif text:match('^\\t', i) then
  353.          VALUE = VALUE .. "\t"
  354.          i = i + 2
  355.       else
  356.          local hex = text:match('^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])', i)
  357.          if hex then
  358.             i = i + 6 -- bypass what we just read
  359.  
  360.             -- We have a Unicode codepoint. It could be standalone, or if in the proper range and
  361.             -- followed by another in a specific range, it'll be a two-code surrogate pair.
  362.             local codepoint = tonumber(hex, 16)
  363.             if codepoint >= 0xD800 and codepoint <= 0xDBFF then
  364.                -- it's a hi surrogate... see whether we have a following low
  365.                local lo_surrogate = text:match('^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])', i)
  366.                if lo_surrogate then
  367.                   i = i + 6 -- bypass the low surrogate we just read
  368.                   codepoint = 0x2400 + (codepoint - 0xD800) * 0x400 + tonumber(lo_surrogate, 16)
  369.                else
  370.                   -- not a proper low, so we'll just leave the first codepoint as is and spit it out.
  371.                end
  372.             end
  373.             VALUE = VALUE .. unicode_codepoint_as_utf8(codepoint)
  374.  
  375.          else
  376.  
  377.             -- just pass through what's escaped
  378.             VALUE = VALUE .. text:match('^\\(.)', i)
  379.             i = i + 2
  380.          end
  381.       end
  382.    end
  383.  
  384.    self:onDecodeError("unclosed string", text, start, etc)
  385. end
  386.  
  387. local function skip_whitespace(text, start)
  388.  
  389.    local match_start, match_end = text:find("^[ \n\r\t]+", start) -- [http://www.ietf.org/rfc/rfc4627.txt] Section 2
  390.    if match_end then
  391.       return match_end + 1
  392.    else
  393.       return start
  394.    end
  395. end
  396.  
  397. local grok_one -- assigned later
  398.  
  399. local function grok_object(self, text, start, etc)
  400.    if not text:sub(start,start) == '{' then
  401.       self:onDecodeError("expected '{'", text, start, etc)
  402.    end
  403.  
  404.    local i = skip_whitespace(text, start + 1) -- +1 to skip the '{'
  405.  
  406.    local VALUE = self.strictTypes and self:newObject { } or { }
  407.  
  408.    if text:sub(i,i) == '}' then
  409.       return VALUE, i + 1
  410.    end
  411.    local text_len = text:len()
  412.    while i <= text_len do
  413.       local key, new_i = grok_string(self, text, i, etc)
  414.  
  415.       i = skip_whitespace(text, new_i)
  416.  
  417.       if text:sub(i, i) ~= ':' then
  418.          self:onDecodeError("expected colon", text, i, etc)
  419.       end
  420.  
  421.       i = skip_whitespace(text, i + 1)
  422.  
  423.       local val, new_i = grok_one(self, text, i)
  424.  
  425.       VALUE[key] = val
  426.  
  427.       --
  428.       -- Expect now either '}' to end things, or a ',' to allow us to continue.
  429.       --
  430.       i = skip_whitespace(text, new_i)
  431.  
  432.       local c = text:sub(i,i)
  433.  
  434.       if c == '}' then
  435.          return VALUE, i + 1
  436.       end
  437.  
  438.       if text:sub(i, i) ~= ',' then
  439.          self:onDecodeError("expected comma or '}'", text, i, etc)
  440.       end
  441.  
  442.       i = skip_whitespace(text, i + 1)
  443.    end
  444.  
  445.    self:onDecodeError("unclosed '{'", text, start, etc)
  446. end
  447.  
  448. local function grok_array(self, text, start, etc)
  449.    if not text:sub(start,start) == '[' then
  450.       self:onDecodeError("expected '['", text, start, etc)
  451.    end
  452.  
  453.    local i = skip_whitespace(text, start + 1) -- +1 to skip the '['
  454.    local VALUE = self.strictTypes and self:newArray { } or { }
  455.    if text:sub(i,i) == ']' then
  456.       return VALUE, i + 1
  457.    end
  458.  
  459.    local text_len = text:len()
  460.    while i <= text_len do
  461.       local val, new_i = grok_one(self, text, i)
  462.  
  463.       table.insert(VALUE, val)
  464.  
  465.       i = skip_whitespace(text, new_i)
  466.  
  467.       --
  468.       -- Expect now either ']' to end things, or a ',' to allow us to continue.
  469.       --
  470.       local c = text:sub(i,i)
  471.       if c == ']' then
  472.          return VALUE, i + 1
  473.       end
  474.       if text:sub(i, i) ~= ',' then
  475.          self:onDecodeError("expected comma or '['", text, i, etc)
  476.       end
  477.       i = skip_whitespace(text, i + 1)
  478.    end
  479.    self:onDecodeError("unclosed '['", text, start, etc)
  480. end
  481.  
  482.  
  483. grok_one = function(self, text, start, etc)
  484.    -- Skip any whitespace
  485.    start = skip_whitespace(text, start)
  486.  
  487.    if start > text:len() then
  488.       self:onDecodeError("unexpected end of string", text, nil, etc)
  489.    end
  490.  
  491.    if text:find('^"', start) then
  492.       return grok_string(self, text, start, etc)
  493.  
  494.    elseif text:find('^[-0123456789 ]', start) then
  495.       return grok_number(self, text, start, etc)
  496.  
  497.    elseif text:find('^%{', start) then
  498.       return grok_object(self, text, start, etc)
  499.  
  500.    elseif text:find('^%[', start) then
  501.       return grok_array(self, text, start, etc)
  502.  
  503.    elseif text:find('^true', start) then
  504.       return true, start + 4
  505.  
  506.    elseif text:find('^false', start) then
  507.       return false, start + 5
  508.  
  509.    elseif text:find('^null', start) then
  510.       return nil, start + 4
  511.  
  512.    else
  513.       self:onDecodeError("can't parse JSON", text, start, etc)
  514.    end
  515. end
  516.  
  517. function OBJDEF:decode(text, etc)
  518.    if type(self) ~= 'table' or self.__index ~= OBJDEF then
  519.       OBJDEF:onDecodeError("JSON:decode must be called in method format", nil, nil, etc)
  520.    end
  521.  
  522.    if text == nil then
  523.       self:onDecodeOfNilError(string.format("nil passed to JSON:decode()"), nil, nil, etc)
  524.    elseif type(text) ~= 'string' then
  525.       self:onDecodeError(string.format("expected string argument to JSON:decode(), got %s", type(text)), nil, nil, etc)
  526.    end
  527.  
  528.    if text:match('^%s*$') then
  529.       return nil
  530.    end
  531.  
  532.    if text:match('^%s*<') then
  533.       -- Can't be JSON... we'll assume it's HTML
  534.       self:onDecodeOfHTMLError(string.format("html passed to JSON:decode()"), text, nil, etc)
  535.    end
  536.  
  537.    --
  538.    -- Ensure that it's not UTF-32 or UTF-16.
  539.    -- Those are perfectly valid encodings for JSON (as per RFC 4627 section 3),
  540.    -- but this package can't handle them.
  541.    --
  542.    if text:sub(1,1):byte() == 0 or (text:len() >= 2 and text:sub(2,2):byte() == 0) then
  543.       self:onDecodeError("JSON package groks only UTF-8, sorry", text, nil, etc)
  544.    end
  545.  
  546.    local success, value = pcall(grok_one, self, text, 1, etc)
  547.  
  548.    if success then
  549.       return value
  550.    else
  551.       -- if JSON:onDecodeError() didn't abort out of the pcall, we'll have received the error message here as "value", so pass it along as an assert.
  552.       if self.assert then
  553.          self.assert(false, value)
  554.       else
  555.          assert(false, value)
  556.       end
  557.       -- and if we're still here, return a nil and throw the error message on as a second arg
  558.       return nil, value
  559.    end
  560. end
  561.  
  562. local function backslash_replacement_function(c)
  563.    if c == "\n" then
  564.       return "\\n"
  565.    elseif c == "\r" then
  566.       return "\\r"
  567.    elseif c == "\t" then
  568.       return "\\t"
  569.    elseif c == "\b" then
  570.       return "\\b"
  571.    elseif c == "\f" then
  572.       return "\\f"
  573.    elseif c == '"' then
  574.       return '\\"'
  575.    elseif c == '\\' then
  576.       return '\\\\'
  577.    else
  578.       return string.format("\\u%04x", c:byte())
  579.    end
  580. end
  581.  
  582. local chars_to_be_escaped_in_JSON_string
  583.    = '['
  584.    ..    '"'    -- class sub-pattern to match a double quote
  585.    ..    '%\\'  -- class sub-pattern to match a backslash
  586.    ..    '%z'   -- class sub-pattern to match a null
  587.    ..    '\001' .. '-' .. '\031' -- class sub-pattern to match control characters
  588.    .. ']'
  589.  
  590. local function json_string_literal(value)
  591.    local newval = value:gsub(chars_to_be_escaped_in_JSON_string, backslash_replacement_function)
  592.    return '"' .. newval .. '"'
  593. end
  594.  
  595. local function object_or_array(self, T, etc)
  596.    --
  597.    -- We need to inspect all the keys... if there are any strings, we'll convert to a JSON
  598.    -- object. If there are only numbers, it's a JSON array.
  599.    --
  600.    -- If we'll be converting to a JSON object, we'll want to sort the keys so that the
  601.    -- end result is deterministic.
  602.    --
  603.    local string_keys = { }
  604.    local number_keys = { }
  605.    local number_keys_must_be_strings = false
  606.    local maximum_number_key
  607.  
  608.    for key in pairs(T) do
  609.       if type(key) == 'string' then
  610.          table.insert(string_keys, key)
  611.       elseif type(key) == 'number' then
  612.          table.insert(number_keys, key)
  613.          if key <= 0 or key >= math.huge then
  614.             number_keys_must_be_strings = true
  615.          elseif not maximum_number_key or key > maximum_number_key then
  616.             maximum_number_key = key
  617.          end
  618.       else
  619.          self:onEncodeError("can't encode table with a key of type " .. type(key), etc)
  620.       end
  621.    end
  622.  
  623.    if #string_keys == 0 and not number_keys_must_be_strings then
  624.       --
  625.       -- An empty table, or a numeric-only array
  626.       --
  627.       if #number_keys > 0 then
  628.          return nil, maximum_number_key -- an array
  629.       elseif tostring(T) == "JSON array" then
  630.          return nil
  631.       elseif tostring(T) == "JSON object" then
  632.          return { }
  633.       else
  634.          -- have to guess, so we'll pick array, since empty arrays are likely more common than empty objects
  635.          return nil
  636.       end
  637.    end
  638.  
  639.    table.sort(string_keys)
  640.  
  641.    local map
  642.    if #number_keys > 0 then
  643.       --
  644.       -- If we're here then we have either mixed string/number keys, or numbers inappropriate for a JSON array
  645.       -- It's not ideal, but we'll turn the numbers into strings so that we can at least create a JSON object.
  646.       --
  647.  
  648.       if JSON.noKeyConversion then
  649.          self:onEncodeError("a table with both numeric and string keys could be an object or array; aborting", etc)
  650.       end
  651.  
  652.       --
  653.       -- Have to make a shallow copy of the source table so we can remap the numeric keys to be strings
  654.       --
  655.       map = { }
  656.       for key, val in pairs(T) do
  657.          map[key] = val
  658.       end
  659.  
  660.       table.sort(number_keys)
  661.  
  662.       --
  663.       -- Throw numeric keys in there as strings
  664.       --
  665.       for _, number_key in ipairs(number_keys) do
  666.          local string_key = tostring(number_key)
  667.          if map[string_key] == nil then
  668.             table.insert(string_keys , string_key)
  669.             map[string_key] = T[number_key]
  670.          else
  671.             self:onEncodeError("conflict converting table with mixed-type keys into a JSON object: key " .. number_key .. " exists both as a string and a number.", etc)
  672.          end
  673.       end
  674.    end
  675.  
  676.    return string_keys, nil, map
  677. end
  678.  
  679. --
  680. -- Encode
  681. --
  682. local encode_value -- must predeclare because it calls itself
  683. function encode_value(self, value, parents, etc, indent) -- non-nil indent means pretty-printing
  684.  
  685.    if value == nil then
  686.       return 'null'
  687.  
  688.    elseif type(value) == 'string' then
  689.       return json_string_literal(value)
  690.  
  691.    elseif type(value) == 'number' then
  692.       if value ~= value then
  693.          --
  694.          -- NaN (Not a Number).
  695.          -- JSON has no NaN, so we have to fudge the best we can. This should really be a package option.
  696.          --
  697.          return "null"
  698.       elseif value >= math.huge then
  699.          --
  700.          -- Positive infinity. JSON has no INF, so we have to fudge the best we can. This should
  701.          -- really be a package option. Note: at least with some implementations, positive infinity
  702.          -- is both ">= math.huge" and "<= -math.huge", which makes no sense but that's how it is.
  703.          -- Negative infinity is properly "<= -math.huge". So, we must be sure to check the ">="
  704.          -- case first.
  705.          --
  706.          return "1e+9999"
  707.       elseif value <= -math.huge then
  708.          --
  709.          -- Negative infinity.
  710.          -- JSON has no INF, so we have to fudge the best we can. This should really be a package option.
  711.          --
  712.          return "-1e+9999"
  713.       else
  714.          return tostring(value)
  715.       end
  716.  
  717.    elseif type(value) == 'boolean' then
  718.       return tostring(value)
  719.  
  720.    elseif type(value) ~= 'table' then
  721.       self:onEncodeError("can't convert " .. type(value) .. " to JSON", etc)
  722.  
  723.    else
  724.       --
  725.       -- A table to be converted to either a JSON object or array.
  726.       --
  727.       local T = value
  728.  
  729.       if parents[T] then
  730.          self:onEncodeError("table " .. tostring(T) .. " is a child of itself", etc)
  731.       else
  732.          parents[T] = true
  733.       end
  734.  
  735.       local result_value
  736.  
  737.       local object_keys, maximum_number_key, map = object_or_array(self, T, etc)
  738.       if maximum_number_key then
  739.          --
  740.          -- An array...
  741.          --
  742.          local ITEMS = { }
  743.          for i = 1, maximum_number_key do
  744.             table.insert(ITEMS, encode_value(self, T[i], parents, etc, indent))
  745.          end
  746.  
  747.          if indent then
  748.             result_value = "[ " .. table.concat(ITEMS, ", ") .. " ]"
  749.          else
  750.             result_value = "[" .. table.concat(ITEMS, ",") .. "]"
  751.          end
  752.  
  753.       elseif object_keys then
  754.          --
  755.          -- An object
  756.          --
  757.          local TT = map or T
  758.  
  759.          if indent then
  760.  
  761.             local KEYS = { }
  762.             local max_key_length = 0
  763.             for _, key in ipairs(object_keys) do
  764.                local encoded = encode_value(self, tostring(key), parents, etc, "")
  765.                max_key_length = math.max(max_key_length, #encoded)
  766.                table.insert(KEYS, encoded)
  767.             end
  768.             local key_indent = indent .. "    "
  769.             local subtable_indent = indent .. string.rep(" ", max_key_length + 2 + 4)
  770.             local FORMAT = "%s%" .. string.format("%d", max_key_length) .. "s: %s"
  771.  
  772.             local COMBINED_PARTS = { }
  773.             for i, key in ipairs(object_keys) do
  774.                local encoded_val = encode_value(self, TT[key], parents, etc, subtable_indent)
  775.                table.insert(COMBINED_PARTS, string.format(FORMAT, key_indent, KEYS[i], encoded_val))
  776.             end
  777.             result_value = "{\n" .. table.concat(COMBINED_PARTS, ",\n") .. "\n" .. indent .. "}"
  778.  
  779.          else
  780.  
  781.             local PARTS = { }
  782.             for _, key in ipairs(object_keys) do
  783.                local encoded_val = encode_value(self, TT[key],       parents, etc, indent)
  784.                local encoded_key = encode_value(self, tostring(key), parents, etc, indent)
  785.                table.insert(PARTS, string.format("%s:%s", encoded_key, encoded_val))
  786.             end
  787.             result_value = "{" .. table.concat(PARTS, ",") .. "}"
  788.  
  789.          end
  790.       else
  791.          --
  792.          -- An empty array/object... we'll treat it as an array, though it should really be an option
  793.          --
  794.          result_value = "[]"
  795.       end
  796.  
  797.       parents[T] = false
  798.       return result_value
  799.    end
  800. end
  801.  
  802.  
  803. function OBJDEF:encode(value, etc)
  804.    if type(self) ~= 'table' or self.__index ~= OBJDEF then
  805.       OBJDEF:onEncodeError("JSON:encode must be called in method format", etc)
  806.    end
  807.    return encode_value(self, value, {}, etc, nil)
  808. end
  809.  
  810. function OBJDEF:encode_pretty(value, etc)
  811.    if type(self) ~= 'table' or self.__index ~= OBJDEF then
  812.       OBJDEF:onEncodeError("JSON:encode_pretty must be called in method format", etc)
  813.    end
  814.    return encode_value(self, value, {}, etc, "")
  815. end
  816.  
  817. function OBJDEF.__tostring()
  818.    return "JSON encode/decode package"
  819. end
  820.  
  821. OBJDEF.__index = OBJDEF
  822.  
  823. function OBJDEF:new(args)
  824.    local new = { }
  825.  
  826.    if args then
  827.       for key, val in pairs(args) do
  828.          new[key] = val
  829.       end
  830.    end
  831.  
  832.    return setmetatable(new, OBJDEF)
  833. end
  834.  
  835. return OBJDEF:new()
  836.  
  837. --
  838. -- Version history:
  839. --
  840. --   20140116.10   The user's JSON.assert() wasn't always being used. Thanks to "blue" for the heads up.
  841. --
  842. --   20131118.9    Update for Lua 5.3... it seems that tostring(2/1) produces "2.0" instead of "2",
  843. --                 and this caused some problems.
  844. --
  845. --   20131031.8    Unified the code for encode() and encode_pretty(); they had been stupidly separate,
  846. --                 and had of course diverged (encode_pretty didn't get the fixes that encode got, so
  847. --                 sometimes produced incorrect results; thanks to Mattie for the heads up).
  848. --
  849. --                 Handle encoding tables with non-positive numeric keys (unlikely, but possible).
  850. --
  851. --                 If a table has both numeric and string keys, or its numeric keys are inappropriate
  852. --                 (such as being non-positive or infinite), the numeric keys are turned into
  853. --                 string keys appropriate for a JSON object. So, as before,
  854. --                         JSON:encode({ "one", "two", "three" })
  855. --                 produces the array
  856. --                         ["one","two","three"]
  857. --                 but now something with mixed key types like
  858. --                         JSON:encode({ "one", "two", "three", SOMESTRING = "some string" }))
  859. --                 instead of throwing an error produces an object:
  860. --                         {"1":"one","2":"two","3":"three","SOMESTRING":"some string"}
  861. --
  862. --                 To maintain the prior throw-an-error semantics, set
  863. --                      JSON.noKeyConversion = true
  864. --                
  865. --   20131004.7    Release under a Creative Commons CC-BY license, which I should have done from day one, sorry.
  866. --
  867. --   20130120.6    Comment update: added a link to the specific page on my blog where this code can
  868. --                 be found, so that folks who come across the code outside of my blog can find updates
  869. --                 more easily.
  870. --
  871. --   20111207.5    Added support for the 'etc' arguments, for better error reporting.
  872. --
  873. --   20110731.4    More feedback from David Kolf on how to make the tests for Nan/Infinity system independent.
  874. --
  875. --   20110730.3    Incorporated feedback from David Kolf at http://lua-users.org/wiki/JsonModules:
  876. --
  877. --                   * When encoding lua for JSON, Sparse numeric arrays are now handled by
  878. --                     spitting out full arrays, such that
  879. --                        JSON:encode({"one", "two", [10] = "ten"})
  880. --                     returns
  881. --                        ["one","two",null,null,null,null,null,null,null,"ten"]
  882. --
  883. --                     In 20100810.2 and earlier, only up to the first non-null value would have been retained.
  884. --
  885. --                   * When encoding lua for JSON, numeric value NaN gets spit out as null, and infinity as "1+e9999".
  886. --                     Version 20100810.2 and earlier created invalid JSON in both cases.
  887. --
  888. --                   * Unicode surrogate pairs are now detected when decoding JSON.
  889. --
  890. --   20100810.2    added some checking to ensure that an invalid Unicode character couldn't leak in to the UTF-8 encoding
  891. --
  892. --   20100731.1    initial public release
  893. --
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement