Advertisement
OHOVERSUM

encoder

Dec 16th, 2018
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.31 KB | None | 0 0
  1. local json = { _version = "0.1.1" }
  2.  
  3. local encode
  4.  
  5. local escape_char_map = {
  6.   [ "\\" ] = "\\\\",
  7.   [ "\"" ] = "\\\"",
  8.   [ "\b" ] = "\\b",
  9.   [ "\f" ] = "\\f",
  10.   [ "\n" ] = "\\n",
  11.   [ "\r" ] = "\\r",
  12.   [ "\t" ] = "\\t",
  13. }
  14.  
  15. local escape_char_map_inv = { [ "\\/" ] = "/" }
  16. for k, v in pairs(escape_char_map) do
  17.   escape_char_map_inv[v] = k
  18. end
  19.  
  20.  
  21. local function escape_char(c)
  22.   return escape_char_map[c] or string.format("\\u%04x", c:byte())
  23. end
  24.  
  25.  
  26. local function encode_nil(val)
  27.   return "null"
  28. end
  29.  
  30.  
  31. local function encode_table(val, stack)
  32.   local res = {}
  33.   stack = stack or {}
  34.  
  35.   -- Circular reference?
  36.   if stack[val] then error("circular reference") end
  37.  
  38.   stack[val] = true
  39.  
  40.   if val[1] ~= nil or next(val) == nil then
  41.     -- Treat as array -- check keys are valid and it is not sparse
  42.     local n = 0
  43.     for k in pairs(val) do
  44.       if type(k) ~= "number" then
  45.         error("invalid table: mixed or invalid key types")
  46.       end
  47.       n = n + 1
  48.     end
  49.     if n ~= #val then
  50.       error("invalid table: sparse array")
  51.     end
  52.     -- Encode
  53.     for i, v in ipairs(val) do
  54.       table.insert(res, encode(v, stack))
  55.     end
  56.     stack[val] = nil
  57.     return "[" .. table.concat(res, ",") .. "]"
  58.  
  59.   else
  60.     -- Treat as an object
  61.     for k, v in pairs(val) do
  62.       if type(k) ~= "string" then
  63.         error("invalid table: mixed or invalid key types")
  64.       end
  65.       table.insert(res, encode(k, stack) .. ":" .. encode(v, stack))
  66.     end
  67.     stack[val] = nil
  68.     return "{" .. table.concat(res, ",") .. "}"
  69.   end
  70. end
  71.  
  72.  
  73. local function encode_string(val)
  74.   return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
  75. end
  76.  
  77.  
  78. local function encode_number(val)
  79.   -- Check for NaN, -inf and inf
  80.   if val ~= val or val <= -math.huge or val >= math.huge then
  81.     error("unexpected number value '" .. tostring(val) .. "'")
  82.   end
  83.   return string.format("%.14g", val)
  84. end
  85.  
  86.  
  87. local type_func_map = {
  88.   [ "nil"     ] = encode_nil,
  89.   [ "table"   ] = encode_table,
  90.   [ "string"  ] = encode_string,
  91.   [ "number"  ] = encode_number,
  92.   [ "boolean" ] = tostring,
  93. }
  94.  
  95.  
  96. encode = function(val, stack)
  97. local t = type(val)
  98. local f = type_func_map[t]
  99. if f then
  100.   return f(val, stack)
  101. end
  102. error("unexpected type '" .. t .. "'")
  103. end
  104.  
  105.  
  106. function jsonencode(val)
  107. return ( encode(val) )
  108. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement