druidbruce

infusion_altar_auto/json

Jun 13th, 2016
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.53 KB | None | 0 0
  1. ------------------------------------------------------------------ utils
  2. local controls = {["\n"]="\\n", ["\r"]="\\r", ["\t"]="\\t", ["\b"]="\\b", ["\f"]="\\f", ["\""]="\\\"", ["\\"]="\\\\"}
  3.  
  4. local function isArray(t)
  5. local max = 0
  6. for k,v in pairs(t) do
  7. if type(k) ~= "number" then
  8. return false
  9. elseif k > max then
  10. max = k
  11. end
  12. end
  13. return max == #t
  14. end
  15.  
  16. local whites = {['\n']=true; ['r']=true; ['\t']=true; [' ']=true; [',']=true; [':']=true}
  17. function removeWhite(str)
  18. while whites[str:sub(1, 1)] do
  19. str = str:sub(2)
  20. end
  21. return str
  22. end
  23.  
  24. ------------------------------------------------------------------ encoding
  25.  
  26. local function encodeCommon(val, pretty, tabLevel, tTracking)
  27. local str = ""
  28.  
  29. -- Tabbing util
  30. local function tab(s)
  31. str = str .. ("\t"):rep(tabLevel) .. s
  32. end
  33.  
  34. local function arrEncoding(val, bracket, closeBracket, iterator, loopFunc)
  35. str = str .. bracket
  36. if pretty then
  37. str = str .. "\n"
  38. tabLevel = tabLevel + 1
  39. end
  40. for k,v in iterator(val) do
  41. tab("")
  42. loopFunc(k,v)
  43. str = str .. ","
  44. if pretty then str = str .. "\n" end
  45. end
  46. if pretty then
  47. tabLevel = tabLevel - 1
  48. end
  49. if str:sub(-2) == ",\n" then
  50. str = str:sub(1, -3) .. "\n"
  51. elseif str:sub(-1) == "," then
  52. str = str:sub(1, -2)
  53. end
  54. tab(closeBracket)
  55. end
  56.  
  57. -- Table encoding
  58. if type(val) == "table" then
  59. assert(not tTracking[val], "Cannot encode a table holding itself recursively")
  60. tTracking[val] = true
  61. if isArray(val) then
  62. arrEncoding(val, "[", "]", ipairs, function(k,v)
  63. str = str .. encodeCommon(v, pretty, tabLevel, tTracking)
  64. end)
  65. else
  66. arrEncoding(val, "{", "}", pairs, function(k,v)
  67. assert(type(k) == "string", "JSON object keys must be strings", 2)
  68. str = str .. encodeCommon(k, pretty, tabLevel, tTracking)
  69. str = str .. (pretty and ": " or ":") .. encodeCommon(v, pretty, tabLevel, tTracking)
  70. end)
  71. end
  72. -- String encoding
  73. elseif type(val) == "string" then
  74. str = '"' .. val:gsub("[%c\"\\]", controls) .. '"'
  75. -- Number encoding
  76. elseif type(val) == "number" or type(val) == "boolean" then
  77. str = tostring(val)
  78. else
  79. error("JSON only supports arrays, objects, numbers, booleans, and strings", 2)
  80. end
  81. return str
  82. end
  83.  
  84. function encode(val)
  85. return encodeCommon(val, false, 0, {})
  86. end
  87.  
  88. function encodePretty(val)
  89. return encodeCommon(val, true, 0, {})
  90. end
  91.  
  92. ------------------------------------------------------------------ decoding
  93.  
  94. function parseBoolean(str)
  95. if str:sub(1, 4) == "true" then
  96. return true, removeWhite(str:sub(5))
  97. else
  98. return false, removeWhite(str:sub(6))
  99. end
  100. end
  101.  
  102. function parseNull(str)
  103. return nil, removeWhite(str:sub(5))
  104. end
  105.  
  106. local numChars = {['e']=true; ['E']=true; ['+']=true; ['-']=true; ['.']=true}
  107. function parseNumber(str)
  108. local i = 1
  109. while numChars[str:sub(i, i)] or tonumber(str:sub(i, i)) do
  110. i = i + 1
  111. end
  112. local val = tonumber(str:sub(1, i - 1))
  113. str = removeWhite(str:sub(i))
  114. return val, str
  115. end
  116.  
  117. function parseString(str)
  118. local i,j = str:find('[^\\]"')
  119. local s = str:sub(2, j - 1)
  120.  
  121. for k,v in pairs(controls) do
  122. s = s:gsub(v, k)
  123. end
  124. str = removeWhite(str:sub(j + 1))
  125. return s, str
  126. end
  127.  
  128. function parseArray(str)
  129. str = removeWhite(str:sub(2))
  130.  
  131. local val = {}
  132. local i = 1
  133. while str:sub(1, 1) ~= "]" do
  134. local v = nil
  135. v, str = parseValue(str)
  136. val[i] = v
  137. i = i + 1
  138. str = removeWhite(str)
  139. end
  140. str = removeWhite(str:sub(2))
  141. return val, str
  142. end
  143.  
  144. function parseObject(str)
  145. str = removeWhite(str:sub(2))
  146.  
  147. local val = {}
  148. while str:sub(1, 1) ~= "}" do
  149. local k, v = nil, nil
  150. k, v, str = parseMember(str)
  151. val[k] = v
  152. str = removeWhite(str)
  153. end
  154. str = removeWhite(str:sub(2))
  155. return val, str
  156. end
  157.  
  158. function parseMember(str)
  159. local k = nil
  160. k, str = parseValue(str)
  161. local val = nil
  162. val, str = parseValue(str)
  163. return k, val, str
  164. end
  165.  
  166. function parseValue(str)
  167. local fchar = str:sub(1, 1)
  168. if fchar == "{" then
  169. return parseObject(str)
  170. elseif fchar == "[" then
  171. return parseArray(str)
  172. elseif tonumber(fchar) ~= nil or numChars[fchar] then
  173. return parseNumber(str)
  174. elseif str:sub(1, 4) == "true" or str:sub(1, 5) == "false" then
  175. return parseBoolean(str)
  176. elseif fchar == "\"" then
  177. return parseString(str)
  178. elseif str:sub(1, 4) == "null" then
  179. return parseNull(str)
  180. end
  181. return nil
  182. end
  183.  
  184. function decode(str)
  185. str = removeWhite(str)
  186. t = parseValue(str)
  187. return t
  188. end
  189.  
  190. function decodeFromFile(path)
  191. local file = assert(fs.open(path, "r"))
  192. return decode(file.readAll())
  193. end
Add Comment
Please, Sign In to add comment