webmcp
view framework/env/encode/json.lua @ 267:56d237b81c18
Support for external redirects and redirects to static files
| author | jbe | 
|---|---|
| date | Fri Mar 20 15:12:31 2015 +0100 (2015-03-20) | 
| parents | 32ec28229bb5 | 
| children | aacddd07e471 | 
 line source
     1 --[[--
     2 json_string =  -- JavaScript code representing the given datum (with quotes, if needed)
     3 encode.json(
     4   obj          -- true, false, nil or a number or string
     5 )
     7 This function encodes any native datatype or atom in JavaScript object notation (JSON). It ensures that the returned string can be safely included in inline scripts both in HTML and XHTML (within CDATA section).
     9 TODO: can't distinguish unambiguously between empty object and empty list!
    11 TODO: replace with JSON library
    13 --]]--
    15 -- TODO: check if numeric representations are JSON compatible
    17 function encode.json(obj)
    18   if obj == nil then
    19     return "null";
    20   elseif atom.has_type(obj, atom.boolean) then
    21     return tostring(obj)
    22   elseif atom.has_type(obj, atom.number) then
    23     return tostring(obj)
    24   elseif type(obj) == "table" then
    25     local parts = {}
    26     local first = true
    27     if #obj > 0 then
    28       parts[#parts+1] = "["
    29       for idx, value in ipairs(obj) do
    30         if first then
    31           first = false
    32         else
    33           parts[#parts+1] = ","
    34         end
    35         parts[#parts+1] = tostring(value)
    36       end
    37       parts[#parts+1] = "]"
    38     else
    39       parts[#parts+1] = "{"
    40       for key, value in pairs(obj) do
    41         if first then
    42           first = false
    43         else
    44           parts[#parts+1] = ","
    45         end
    46         parts[#parts+1] = encode.json(key)
    47         parts[#parts+1] = ":"
    48         parts[#parts+1] = encode.json(value)
    49       end
    50       parts[#parts+1] = "}"
    51     end
    52     return table.concat(parts)
    53   else
    54     local str = atom.dump(obj)
    55     str = string.gsub(str, ".",
    56       function (char)
    57         if char == '\r' then return '\\r'  end
    58         if char == '\n' then return '\\n'  end
    59         if char == '\\' then return '\\\\' end
    60         if char == '"'  then return '\\"'  end
    61         local byte = string.byte(char)
    62         if byte < 32 then return string.format("\\u%04x", byte) end
    63       end
    64     )
    65     str = string.gsub(str, "</", "<\\/")
    66     str = string.gsub(str, "<!%[CDATA%[", "\\u003c![CDATA[")
    67     str = string.gsub(str, "]]>", "]]\\u003e")
    68     return '"' .. str .. '"'
    69   end
    70 end
