La documentación para este módulo se puede crear en Módulo: JSON / doc
- - json.lua - - Copyright (c) 2018 rxi - - Por la presente se otorga permiso, sin cargo, a cualquier persona que obtenga una copia de - este software y los archivos de documentación asociados (el "Software" ), para negociar - el Software sin restricciones, incluidos, entre otros, los derechos para - usar, copiar, modificar, fusionar, publicar, distribuir, sublicenciar y / o vender copias - del Software, y para permitir que las personas a quién se le proporciona el Software para hacerlo, sujeto a las siguientes condiciones: - El aviso de copyright anterior y este aviso de permiso se incluirán en todas las copias o partes sustanciales del Software. - - EL SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O IMPLÍCITA, INCLUYENDO, PERO NO LIMITADO A, LAS GARANTÍAS DE COMERCIABILIDAD, - IDONEIDAD PARA UN PROPÓSITO PARTICULAR Y NO INFRACCIÓN. EN NINGÚN CASO LOS AUTORES O TITULARES DE LOS DERECHOS DE AUTOR SERÁN RESPONSABLES DE CUALQUIER RECLAMO, DAÑOS U OTRA RESPONSABILIDAD, YA SEA EN UNA ACCIÓN DE CONTRATO, AGRAVIO O DE OTRO MODO, QUE SURJA DE, - FUERA DE O EN RELACIÓN CON EL SOFTWARE O EL USO U OTRAS NEGOCIACIONES EN EL SOFTWARE. - json local = {_version = "0.1.1"} ------------------------------------ ------------------------------------------- - Codificar ---- -------------------------------------------------- ------------------------- codificación local local escape_char_map = {[""] = "\", ["" "] =" "", ["b"] = " b", ["f"] = " f", ["n"] = " n", ["r"] = " r", ["t "] =" t ",} local escape_char_map_inv = {[" / "] =" / "} para k, v en pares (escape_char_map) do escape_char_map_inv [v] = k finaliza la función local escape_char (c) return escape_char_map [ c] o string.format (" u% 04x", c: byte ()) end local function encode_nil (val) return "null" end local function encode_table (val, stack) local res = {} stack = stack o { } -- ¿Referencia circular? if stack [val] then error ("circular reference") end stack [val] = true if val [1] ~ = nil or next (val) == nil then - Tratar como matriz - comprobar que las claves son válidas y no es local disperso n = 0 para k en pares (val) hacer si tipo (k) ~ = "número" entonces error ("tabla inválida: tipos de clave mixtos o inválidos") final n = n + 1 final si n ~ = #val luego error ("tabla inválida: matriz dispersa") end - Codificar para i, v en ipairs (val) do table.insert (res, encode (v, stack)) end stack [val] = retorno nulo "[ ".. table.concat (res, ",") .. "]" else - Tratar como un objeto para k, v en pares (val) hacer si tipo (k) ~ = "cadena" entonces error ("tabla inválida: tipos de clave mixtos o inválidos") end table.insert (res , codificar (k, pila) .. ":" .. encode (v, stack)) end stack [val] = nil return "{" .. table.concat (res, ",") .. "}" end end función local encode_string (val) return '"' .. val: gsub ('[% z1-31 "]', escape_char) .. '"' end local function encode_number (val) - Verifica NaN, -inf e inf si val ~ = val o val <= -math.huge o val> = math.huge luego error (" valor numérico inesperado '". . tostring (val) .. "'") end return string.format ("%. 14g", val) end local type_func_map = {["nil"] = encode_nil, ["table"] = encode_table, ["string"] = encode_string, ["número "] = encode_number, [" boolean "] = tostring,} encode = function (val, stack) local t = type (val) local f = type_func_map [t] if f then return f (val, stack) end error (" tipo inesperado '".. t .. "'") end function json.encode (val) return (encode (val)) end ------------------------------ ------------------------------------------------- - - Decodificar ------------------------------------------------ ------------------------------- local parse función local create_set (...) local res = {} para i = 1 , select ("#", ...) do res [select (i, ...)] = true end return res end local space_chars = create_set ("", "t", "r", "n") local delim_chars = create_set ("", "t", "r", "n", "]", "}", ",") local escape_chars = create_set ("", "/", '"'," b "," f "," n "," r "," t "," u ") literales locales = create_set (" verdadero "," falso "," nulo ") literal_map local = {[" verdadero "] = verdadero , ["false"] = false, ["null"] = nil,} función local next_char (str, idx, set, negate) for i = idx, #str do if set [str: sub (i, i)] ~ = negar luego regresar i end end return #str + 1 end función local decode_error (str, idx, msg) local line_count = 1 local col_count = 1 para i = 1, idx - 1 do col_count = col_count + 1 if str: sub (i, i) == "n" el n line_count = line_count + 1 col_count = 1 end end error (string.format ("% s en la línea% d col% d", msg, line_count, col_count)) end función local codepoint_to_utf8 (n) - http: // scripts .sil.org / cms / scripts / page.php? site_id = nrsi & id = iws-appendixa local f = math.floor if n <= 0x7f then return string.char (n) elseif n <= 0x7ff then return string.char ( f (n / 64) + 192, n% 64 + 128) elseif n <= 0xffff luego devuelve string.char (f (n / 4096) + 224, f (n% 4096/64) + 128, n% 64 + 128) elseif n <= 0x10ffff luego devuelve string.char (f (n / 262144) + 240, f (n% 262144/4096) + 128, f (n% 4096/64) + 128, n% 64 + 128) end error (string.format ("punto de código Unicode inválido '% x'", n)) función local final parse_unicode_escape (s) local n1 = tonumber (s: sub (3, 6), 16) local n2 = tonumber (s: sub (9, 12), 16) - ¿Pareja sustituta? si n2 devuelve codepoint_to_utf8 ((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) de lo contrario, devuelve codepoint_to_utf8 (n1) finaliza la función local parse_string (str, i) local has_unicode_escape = falso local has_surrogate local has_escape = falso local último para j = i + 1, #str do local x = str: byte (j) si x <32 entonces decode_error (str, j, "carácter de control en cadena") final si último == 92 entonces - " "(carácter de escape) si x == 117 entonces -" u "(secuencia de escape unicode) local hex = str: sub (j + 1, j + 5) si no es hex: find ("% x% x% x% x ") luego decode_error (str, j," escape Unicode inválido en cadena ") end if hex: find (" ^ [dD] [89aAbB] ") then has_surrogate_escape = true else has_unicode_escape = true end else local c = string.char (x) si no es escape_chars [c] entonces decode_error (str, j, "carácter de escape inválido '" .. C .. "'in string") end has_escape = true end last = nil elseif x == 34 then -' "'(end of string) local s = str: sub (i + 1, j - 1) if has_surrogate_escape then s = s: gsub (" u [dD] [89aAbB] .. u ....", parse_unicode_escape) 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 last = x end end decode_error (str, i, "cita de cierre esperada para la cadena") end local function parse_number (str, i) local x = next_char (str, i, delim_chars) local s = str: sub (i, x - 1) local n = tonumber (s) if not n then decode_error (str, i, "invalid number '" .. s .. "'") end return n, x end función local parse_literal (str, i) local x = next_char (str, i, delim_chars) palabra local = str: sub (i, x - 1) si no son literales [word] entonces decode_error (str, i, "literal inválido '" .. palabra .. "'") end return literal_map [word], x end local function parse_array (str, i) local res = {} local n = 1 i = i + 1 while 1 do local xi = next_char (str, i, space_chars, true ) - ¿Vacío / final de la matriz? if str: sub (i, i) == "]" entonces i = i + 1 break end - Leer token x, i = parse (str, i) res [n] = xn = n + 1 - Siguiente token i = next_char (str, i, space_chars, true) local chr = str: sub (i, i) i = i + 1 if chr == "]" luego romper end if chr ~ = "," luego decode_error (str, i, "esperado ']' o ','") end end return res, i end local function parse_object (str, i) local res = {} i = i + 1 while 1 do local key, val i = next_char (str , i, space_chars, true) - ¿Vacío / final del objeto? if str: sub (i, i) == "}" then i = i + 1 break end - Leer clave if str: sub (i, i) ~ = '"' then decode_error (str, i," cadena esperada for key ") end key, i = parse (str, i) - Leer ':' delimiter i = next_char (str, i, space_chars, true) if str: sub (i, i) ~ =": "luego decode_error (str, i, "esperado ':' after key") end i = next_char (str, i + 1, space_chars, true) - Leer valor val, i = parse (str, i) - Establecer res [key] = val - Siguiente token i = next_char (str, i, space_chars, true) local chr = str: sub (i, i) i = i + 1 if chr == "}" luego romper end si chr ~ = ", "luego decode_error (str, i," esperado '}' o ',' ") end end return res, i end local char_func_map = {['"'] = parse_string, ["0"] = parse_number, ["1" ] = parse_number, ["2"] = parse_number, ["3"] = parse_number, ["4"] = parse_number, ["5"] = parse_number, ["6"] = parse_number, ["7"] = parse_number, ["8"] = parse_number, ["9"] = parse_number, ["-"] = parse_number, ["t"] = parse_literal, ["f"] = parse_literal, ["n"] = parse_l iteral, ["["] = parse_array, ["{"] = parse_object,} parse = function (str, idx) local chr = str: sub (idx, idx) local f = char_func_map [chr] si f entonces devuelve f (str, idx) end decode_error (str, idx, "carácter inesperado '" .. chr .. "'") end function json.decode (str) if type (str) ~ = "string" then error ("argumento esperado de tipo string, obtenido" ..