forked from Dependencies/lua-json
				
			
							parent
							
								
									8aa60078ca
								
							
						
					
					
						commit
						2e76cfb067
					
				
							
								
								
									
										80
									
								
								json.lua
								
								
								
								
							
							
						
						
									
										80
									
								
								json.lua
								
								
								
								
							|  | @ -31,23 +31,23 @@ local json = { _version = "0.1.2" } | ||||||
| local encode | local encode | ||||||
| 
 | 
 | ||||||
| local escape_char_map = { | local escape_char_map = { | ||||||
|   [ "\\" ] = "\\\\", |   [ "\\" ] = "\\", | ||||||
|   [ "\"" ] = "\\\"", |   [ "\"" ] = "\"", | ||||||
|   [ "\b" ] = "\\b", |   [ "\b" ] = "b", | ||||||
|   [ "\f" ] = "\\f", |   [ "\f" ] = "f", | ||||||
|   [ "\n" ] = "\\n", |   [ "\n" ] = "n", | ||||||
|   [ "\r" ] = "\\r", |   [ "\r" ] = "r", | ||||||
|   [ "\t" ] = "\\t", |   [ "\t" ] = "t", | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| local escape_char_map_inv = { [ "\\/" ] = "/" } | local escape_char_map_inv = { [ "/" ] = "/" } | ||||||
| for k, v in pairs(escape_char_map) do | for k, v in pairs(escape_char_map) do | ||||||
|   escape_char_map_inv[v] = k |   escape_char_map_inv[v] = k | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| local function escape_char(c) | local function escape_char(c) | ||||||
|   return escape_char_map[c] or string.format("\\u%04x", c:byte()) |   return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte())) | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -204,8 +204,8 @@ end | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| local function parse_unicode_escape(s) | local function parse_unicode_escape(s) | ||||||
|   local n1 = tonumber( s:sub(3, 6),  16 ) |   local n1 = tonumber( s:sub(1, 4),  16 ) | ||||||
|   local n2 = tonumber( s:sub(9, 12), 16 ) |   local n2 = tonumber( s:sub(7, 10), 16 ) | ||||||
|    -- Surrogate pair? |    -- Surrogate pair? | ||||||
|   if n2 then |   if n2 then | ||||||
|     return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) |     return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) | ||||||
|  | @ -216,54 +216,42 @@ end | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| local function parse_string(str, i) | local function parse_string(str, i) | ||||||
|   local has_unicode_escape = false |   local res = "" | ||||||
|   local has_surrogate_escape = false |   local j = i + 1 | ||||||
|   local has_escape = false |   local k = j | ||||||
|   local last | 
 | ||||||
|   for j = i + 1, #str do |   while j <= #str do | ||||||
|     local x = str:byte(j) |     local x = str:byte(j) | ||||||
| 
 | 
 | ||||||
|     if x < 32 then |     if x < 32 then | ||||||
|       decode_error(str, j, "control character in string") |       decode_error(str, j, "control character in string") | ||||||
|     end |  | ||||||
| 
 | 
 | ||||||
|     if last == 92 then -- "\\" (escape char) |     elseif x == 92 then -- `\`: Escape | ||||||
|       if x == 117 then -- "u" (unicode escape sequence) |       res = res .. str:sub(k, j - 1) | ||||||
|         local hex = str:sub(j + 1, j + 5) |       j = j + 1 | ||||||
|         if not hex:find("%x%x%x%x") then |       local c = str:sub(j, j) | ||||||
|           decode_error(str, j, "invalid unicode escape in string") |       if c == "u" then | ||||||
|         end |         local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) | ||||||
|         if hex:find("^[dD][89aAbB]") then |                  or str:match("^%x%x%x%x", j + 1) | ||||||
|           has_surrogate_escape = true |                  or decode_error(str, j - 1, "invalid unicode escape in string") | ||||||
|  |         res = res .. parse_unicode_escape(hex) | ||||||
|  |         j = j + #hex | ||||||
|       else |       else | ||||||
|           has_unicode_escape = true |  | ||||||
|         end |  | ||||||
|       else |  | ||||||
|         local c = string.char(x) |  | ||||||
|         if not escape_chars[c] then |         if not escape_chars[c] then | ||||||
|           decode_error(str, j, "invalid escape char '" .. c .. "' in string") |           decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string") | ||||||
|         end |         end | ||||||
|         has_escape = true |         res = res .. escape_char_map_inv[c] | ||||||
|       end |       end | ||||||
|       last = nil |       k = j + 1 | ||||||
| 
 | 
 | ||||||
|     elseif x == 34 then -- '"' (end of string) |     elseif x == 34 then -- `"`: End of string | ||||||
|       local s = str:sub(i + 1, j - 1) |       res = res .. str:sub(k, j - 1) | ||||||
|       if has_surrogate_escape then |       return res, j + 1 | ||||||
|         s = s:gsub("\\u[dD][89aAbB]..\\u....", parse_unicode_escape) |  | ||||||
|     end |     end | ||||||
|       if has_unicode_escape then |  | ||||||
|         s = s:gsub("\\u....", parse_unicode_escape) |  | ||||||
|       end |  | ||||||
|       if has_escape then |  | ||||||
|         s = s:gsub("\\.", escape_char_map_inv) |  | ||||||
|       end |  | ||||||
|       return s, j + 1 |  | ||||||
| 
 | 
 | ||||||
|     else |     j = j + 1 | ||||||
|       last = x |  | ||||||
|     end |  | ||||||
|   end |   end | ||||||
|  | 
 | ||||||
|   decode_error(str, i, "expected closing quote for string") |   decode_error(str, i, "expected closing quote for string") | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue