Advertisement
DaikiKaminari

json-cc-modified

Jul 17th, 2021 (edited)
1,182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.81 KB | None | 0 0
  1. -- Original code written by ElvishJerricco ( http://www.computercraft.info/forums2/index.php?/topic/5854-json-api-v201-for-computercraft/ )
  2. -- Code modified by DaikiKaminari for personnal purpose, transformed it to a library that can be loaded using the "require" function
  3. -- v2.0.5-DAIKI-1
  4.  
  5.  
  6. ------------------------------------------------------------------ library
  7. local json = {}
  8.  
  9. ------------------------------------------------------------------ utils
  10. local controls = {["\n"]="\\n", ["\r"]="\\r", ["\t"]="\\t", ["\b"]="\\b", ["\f"]="\\f", ["\""]="\\\"", ["\\"]="\\\\"}
  11.  
  12. local function isArray(t)
  13.     local max = 0
  14.     for k,v in pairs(t) do
  15.         if type(k) ~= "number" then
  16.             return false
  17.         elseif k > max then
  18.             max = k
  19.         end
  20.     end
  21.     return max == #t
  22. end
  23. json.isArray = isArray
  24.  
  25. local whites = {['\n']=true; ['\r']=true; ['\t']=true; [' ']=true; [',']=true; [':']=true}
  26. local function removeWhite(str)
  27.     while whites[str:sub(1, 1)] do
  28.         str = str:sub(2)
  29.     end
  30.     return str
  31. end
  32. json.removeWhite = removeWhite
  33.  
  34. ------------------------------------------------------------------ encoding
  35.  
  36. local function encodeCommon(val, pretty, tabLevel, tTracking)
  37.     local str = ""
  38.  
  39.     -- Tabbing util
  40.     local function tab(s)
  41.         str = str .. ("\t"):rep(tabLevel) .. s
  42.     end
  43.  
  44.     local function arrEncoding(val, bracket, closeBracket, iterator, loopFunc)
  45.         str = str .. bracket
  46.         if pretty then
  47.             str = str .. "\n"
  48.             tabLevel = tabLevel + 1
  49.         end
  50.         for k,v in iterator(val) do
  51.             tab("")
  52.             loopFunc(k,v)
  53.             str = str .. ","
  54.             if pretty then str = str .. "\n" end
  55.         end
  56.         if pretty then
  57.             tabLevel = tabLevel - 1
  58.         end
  59.         if str:sub(-2) == ",\n" then
  60.             str = str:sub(1, -3) .. "\n"
  61.         elseif str:sub(-1) == "," then
  62.             str = str:sub(1, -2)
  63.         end
  64.         tab(closeBracket)
  65.     end
  66.  
  67.     -- Table encoding
  68.     if type(val) == "table" then
  69.         assert(not tTracking[val], "Cannot encode a table holding itself recursively")
  70.         tTracking[val] = true
  71.         if isArray(val) then
  72.             arrEncoding(val, "[", "]", ipairs, function(k,v)
  73.                 str = str .. encodeCommon(v, pretty, tabLevel, tTracking)
  74.             end)
  75.         else
  76.             arrEncoding(val, "{", "}", pairs, function(k,v)
  77.                 assert(type(k) == "string", "JSON object keys must be strings", 2)
  78.                 str = str .. encodeCommon(k, pretty, tabLevel, tTracking)
  79.                 str = str .. (pretty and ": " or ":") .. encodeCommon(v, pretty, tabLevel, tTracking)
  80.             end)
  81.         end
  82.     -- String encoding
  83.     elseif type(val) == "string" then
  84.         str = '"' .. val:gsub("[%c\"\\]", controls) .. '"'
  85.     -- Number encoding
  86.     elseif type(val) == "number" or type(val) == "boolean" then
  87.         str = tostring(val)
  88.     else
  89.         error("JSON only supports arrays, objects, numbers, booleans, and strings", 2)
  90.     end
  91.     return str
  92. end
  93. json.encodeCommon = encodeCommon
  94.  
  95. function encode(val)
  96.     return encodeCommon(val, false, 0, {})
  97. end
  98. json.encode = encode
  99.  
  100. function encodePretty(val)
  101.     return encodeCommon(val, true, 0, {})
  102. end
  103. json.encodePretty = encodePretty
  104.  
  105. ------------------------------------------------------------------ decoding
  106.  
  107. local decodeControls = {}
  108. for k,v in pairs(controls) do
  109.     decodeControls[v] = k
  110. end
  111.  
  112. local function parseBoolean(str)
  113.     if str:sub(1, 4) == "true" then
  114.         return true, removeWhite(str:sub(5))
  115.     else
  116.         return false, removeWhite(str:sub(6))
  117.     end
  118. end
  119. json.parseBoolean = parseBoolean
  120.  
  121. local function parseNull(str)
  122.     return nil, removeWhite(str:sub(5))
  123. end
  124. json.parseNull = parseNull
  125.  
  126. local numChars = {['e']=true; ['E']=true; ['+']=true; ['-']=true; ['.']=true}
  127. local function parseNumber(str)
  128.     local i = 1
  129.     while numChars[str:sub(i, i)] or tonumber(str:sub(i, i)) do
  130.         i = i + 1
  131.     end
  132.     local val = tonumber(str:sub(1, i - 1))
  133.     str = removeWhite(str:sub(i))
  134.     return val, str
  135. end
  136. json.parseNumber = parseNumber
  137.  
  138. local function parseString(str)
  139.     str = str:sub(2)
  140.     local s = ""
  141.     while str:sub(1,1) ~= "\"" do
  142.         local next = str:sub(1,1)
  143.         str = str:sub(2)
  144.         assert(next ~= "\n", "Unclosed string")
  145.  
  146.         if next == "\\" then
  147.             local escape = str:sub(1,1)
  148.             str = str:sub(2)
  149.  
  150.             next = assert(decodeControls[next..escape], "Invalid escape character")
  151.         end
  152.  
  153.         s = s .. next
  154.     end
  155.     return s, removeWhite(str:sub(2))
  156. end
  157. json.parseString = parseString
  158.  
  159. local function parseArray(str)
  160.     str = removeWhite(str:sub(2))
  161.  
  162.     local val = {}
  163.     local i = 1
  164.     while str:sub(1, 1) ~= "]" do
  165.         local v = nil
  166.         v, str = json.parseValue(str)
  167.         val[i] = v
  168.         i = i + 1
  169.         str = removeWhite(str)
  170.     end
  171.     str = removeWhite(str:sub(2))
  172.     return val, str
  173. end
  174. json.parseArray = parseArray
  175.  
  176. local function parseObject(str)
  177.     str = removeWhite(str:sub(2))
  178.  
  179.     local val = {}
  180.     while str:sub(1, 1) ~= "}" do
  181.         local k, v = nil, nil
  182.         k, v, str = json.parseMember(str)
  183.         val[k] = v
  184.         str = removeWhite(str)
  185.     end
  186.     str = removeWhite(str:sub(2))
  187.     return val, str
  188. end
  189. json.parseObject = parseObject
  190.  
  191. local function parseMember(str)
  192.     local k = nil
  193.     k, str = json.parseValue(str)
  194.     local val = nil
  195.     val, str = json.parseValue(str)
  196.     return k, val, str
  197. end
  198. json.parseMember = parseMember
  199.  
  200. local function parseValue(str)
  201.     local fchar = str:sub(1, 1)
  202.     if fchar == "{" then
  203.         return json.parseObject(str)
  204.     elseif fchar == "[" then
  205.         return json.parseArray(str)
  206.     elseif tonumber(fchar) ~= nil or numChars[fchar] then
  207.         return json.parseNumber(str)
  208.     elseif str:sub(1, 4) == "true" or str:sub(1, 5) == "false" then
  209.         return json.parseBoolean(str)
  210.     elseif fchar == "\"" then
  211.         return json.parseString(str)
  212.     elseif str:sub(1, 4) == "null" then
  213.         return json.parseNull(str)
  214.     end
  215.     return nil
  216. end
  217. json.parseValue = parseValue
  218.  
  219. function decode(str)
  220.     str = removeWhite(str)
  221.     t = json.parseValue(str)
  222.     return t
  223. end
  224. json.decode = decode
  225.  
  226. function decodeFromFile(path)
  227.     local file = assert(fs.open(path, "r"))
  228.     local decoded = decode(file.readAll())
  229.     file.close()
  230.     return decoded
  231. end
  232. json.decodeFromFile = decodeFromFile
  233.  
  234. return json
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement