mirror of https://github.com/lcpz/lain.git
update dkjson to v2.6
This commit is contained in:
parent
958ab5ba81
commit
07cf82e3b2
|
@ -15,7 +15,8 @@ description = {
|
||||||
license = "GPL-2.0"
|
license = "GPL-2.0"
|
||||||
}
|
}
|
||||||
dependencies = {
|
dependencies = {
|
||||||
"lua >= 5.1"
|
"lua >= 5.1",
|
||||||
|
"dkjson >= 2.6-1"
|
||||||
}
|
}
|
||||||
supported_platforms = { "linux" }
|
supported_platforms = { "linux" }
|
||||||
build = {
|
build = {
|
||||||
|
|
104
util/dkjson.lua
104
util/dkjson.lua
|
@ -1,13 +1,13 @@
|
||||||
-- Module options:
|
-- Module options:
|
||||||
local always_try_using_lpeg = true
|
local always_use_lpeg = false
|
||||||
local register_global_module_table = false
|
local register_global_module_table = false
|
||||||
local global_module_name = 'json'
|
local global_module_name = 'json'
|
||||||
|
|
||||||
--[==[
|
--[==[
|
||||||
|
|
||||||
David Kolf's JSON module for Lua 5.1/5.2
|
David Kolf's JSON module for Lua 5.1 - 5.4
|
||||||
|
|
||||||
Version 2.5
|
Version 2.6
|
||||||
|
|
||||||
|
|
||||||
For the documentation see the corresponding readme.txt or visit
|
For the documentation see the corresponding readme.txt or visit
|
||||||
|
@ -17,7 +17,7 @@ You can contact the author by sending an e-mail to 'david' at the
|
||||||
domain 'dkolf.de'.
|
domain 'dkolf.de'.
|
||||||
|
|
||||||
|
|
||||||
Copyright (C) 2010-2013 David Heiko Kolf
|
Copyright (C) 2010-2021 David Heiko Kolf
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
@ -42,8 +42,8 @@ SOFTWARE.
|
||||||
--]==]
|
--]==]
|
||||||
|
|
||||||
-- global dependencies:
|
-- global dependencies:
|
||||||
local pairs, type, tostring, tonumber, getmetatable, setmetatable =
|
local pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset =
|
||||||
pairs, type, tostring, tonumber, getmetatable, setmetatable
|
pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset
|
||||||
local error, require, pcall, select = error, require, pcall, select
|
local error, require, pcall, select = error, require, pcall, select
|
||||||
local floor, huge = math.floor, math.huge
|
local floor, huge = math.floor, math.huge
|
||||||
local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat =
|
local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat =
|
||||||
|
@ -52,13 +52,19 @@ local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat =
|
||||||
local strmatch = string.match
|
local strmatch = string.match
|
||||||
local concat = table.concat
|
local concat = table.concat
|
||||||
|
|
||||||
local json = { version = "dkjson 2.5" }
|
local json = { version = "dkjson 2.6" }
|
||||||
|
|
||||||
|
local jsonlpeg = {}
|
||||||
|
|
||||||
if register_global_module_table then
|
if register_global_module_table then
|
||||||
_G[global_module_name] = json
|
if always_use_lpeg then
|
||||||
|
_G[global_module_name] = jsonlpeg
|
||||||
|
else
|
||||||
|
_G[global_module_name] = json
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local _ENV = nil -- blocking globals in Lua 5.2
|
local _ENV = nil -- blocking globals in Lua 5.2 and later
|
||||||
|
|
||||||
pcall (function()
|
pcall (function()
|
||||||
-- Enable access to blocked metatables.
|
-- Enable access to blocked metatables.
|
||||||
|
@ -246,7 +252,7 @@ local function exception(reason, value, state, buffer, buflen, defaultmessage)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function json.encodeexception(_, _, _, defaultmessage)
|
function json.encodeexception(reason, value, state, defaultmessage)
|
||||||
return quotestring("<" .. defaultmessage .. ">")
|
return quotestring("<" .. defaultmessage .. ">")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -319,9 +325,9 @@ encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, s
|
||||||
for i = 1, n do
|
for i = 1, n do
|
||||||
local k = order[i]
|
local k = order[i]
|
||||||
local v = value[k]
|
local v = value[k]
|
||||||
if v then
|
if v ~= nil then
|
||||||
used[k] = true
|
used[k] = true
|
||||||
buflen, _ = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
|
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
|
||||||
prev = true -- add a seperator before the next element
|
prev = true -- add a seperator before the next element
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -504,6 +510,7 @@ end
|
||||||
local scanvalue -- forward declaration
|
local scanvalue -- forward declaration
|
||||||
|
|
||||||
local function scantable (what, closechar, str, startpos, nullval, objectmeta, arraymeta)
|
local function scantable (what, closechar, str, startpos, nullval, objectmeta, arraymeta)
|
||||||
|
local len = strlen (str)
|
||||||
local tbl, n = {}, 0
|
local tbl, n = {}, 0
|
||||||
local pos = startpos + 1
|
local pos = startpos + 1
|
||||||
if what == 'object' then
|
if what == 'object' then
|
||||||
|
@ -618,14 +625,22 @@ function json.use_lpeg ()
|
||||||
return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall)
|
return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function ErrorUnterminatedCall (str, pos, what, state)
|
||||||
|
return ErrorCall (str, pos - 1, "unterminated " .. what, state)
|
||||||
|
end
|
||||||
|
|
||||||
local SingleLineComment = P"//" * (1 - S"\n\r")^0
|
local SingleLineComment = P"//" * (1 - S"\n\r")^0
|
||||||
local MultiLineComment = P"/*" * (1 - P"*/")^0 * P"*/"
|
local MultiLineComment = P"/*" * (1 - P"*/")^0 * P"*/"
|
||||||
local Space = (S" \n\r\t" + P"\239\187\191" + SingleLineComment + MultiLineComment)^0
|
local Space = (S" \n\r\t" + P"\239\187\191" + SingleLineComment + MultiLineComment)^0
|
||||||
|
|
||||||
|
local function ErrUnterminated (what)
|
||||||
|
return g.Cmt (g.Cc (what) * g.Carg (2), ErrorUnterminatedCall)
|
||||||
|
end
|
||||||
|
|
||||||
local PlainChar = 1 - S"\"\\\n\r"
|
local PlainChar = 1 - S"\"\\\n\r"
|
||||||
local EscapeSequence = (P"\\" * g.C (S"\"\\/bfnrt" + Err "unsupported escape sequence")) / escapechars
|
local EscapeSequence = (P"\\" * g.C (S"\"\\/bfnrt" + Err "unsupported escape sequence")) / escapechars
|
||||||
local HexDigit = R("09", "af", "AF")
|
local HexDigit = R("09", "af", "AF")
|
||||||
local function UTF16Surrogate (_, _, high, low)
|
local function UTF16Surrogate (match, pos, high, low)
|
||||||
high, low = tonumber (high, 16), tonumber (low, 16)
|
high, low = tonumber (high, 16), tonumber (low, 16)
|
||||||
if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then
|
if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then
|
||||||
return true, unichar ((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000)
|
return true, unichar ((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000)
|
||||||
|
@ -639,7 +654,7 @@ function json.use_lpeg ()
|
||||||
local U16Sequence = (P"\\u" * g.C (HexDigit * HexDigit * HexDigit * HexDigit))
|
local U16Sequence = (P"\\u" * g.C (HexDigit * HexDigit * HexDigit * HexDigit))
|
||||||
local UnicodeEscape = g.Cmt (U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence/UTF16BMP
|
local UnicodeEscape = g.Cmt (U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence/UTF16BMP
|
||||||
local Char = UnicodeEscape + EscapeSequence + PlainChar
|
local Char = UnicodeEscape + EscapeSequence + PlainChar
|
||||||
local String = P"\"" * g.Cs (Char ^ 0) * (P"\"" + Err "unterminated string")
|
local String = P"\"" * (g.Cs (Char ^ 0) * P"\"" + ErrUnterminated "string")
|
||||||
local Integer = P"-"^(-1) * (P"0" + (R"19" * R"09"^0))
|
local Integer = P"-"^(-1) * (P"0" + (R"19" * R"09"^0))
|
||||||
local Fractal = P"." * R"09"^0
|
local Fractal = P"." * R"09"^0
|
||||||
local Exponent = (S"eE") * (S"+-")^(-1) * R"09"^1
|
local Exponent = (S"eE") * (S"+-")^(-1) * R"09"^1
|
||||||
|
@ -652,41 +667,62 @@ function json.use_lpeg ()
|
||||||
-- at a time and store them directly to avoid hitting the LPeg limits.
|
-- at a time and store them directly to avoid hitting the LPeg limits.
|
||||||
local function parsearray (str, pos, nullval, state)
|
local function parsearray (str, pos, nullval, state)
|
||||||
local obj, cont
|
local obj, cont
|
||||||
|
local start = pos
|
||||||
local npos
|
local npos
|
||||||
local t, nt = {}, 0
|
local t, nt = {}, 0
|
||||||
repeat
|
repeat
|
||||||
obj, cont, npos = pegmatch (ArrayContent, str, pos, nullval, state)
|
obj, cont, npos = pegmatch (ArrayContent, str, pos, nullval, state)
|
||||||
if not npos then break end
|
if cont == 'end' then
|
||||||
|
return ErrorUnterminatedCall (str, start, "array", state)
|
||||||
|
end
|
||||||
pos = npos
|
pos = npos
|
||||||
nt = nt + 1
|
if cont == 'cont' or cont == 'last' then
|
||||||
t[nt] = obj
|
nt = nt + 1
|
||||||
until cont == 'last'
|
t[nt] = obj
|
||||||
|
end
|
||||||
|
until cont ~= 'cont'
|
||||||
return pos, setmetatable (t, state.arraymeta)
|
return pos, setmetatable (t, state.arraymeta)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function parseobject (str, pos, nullval, state)
|
local function parseobject (str, pos, nullval, state)
|
||||||
local obj, key, cont
|
local obj, key, cont
|
||||||
|
local start = pos
|
||||||
local npos
|
local npos
|
||||||
local t = {}
|
local t = {}
|
||||||
repeat
|
repeat
|
||||||
key, obj, cont, npos = pegmatch (ObjectContent, str, pos, nullval, state)
|
key, obj, cont, npos = pegmatch (ObjectContent, str, pos, nullval, state)
|
||||||
if not npos then break end
|
if cont == 'end' then
|
||||||
|
return ErrorUnterminatedCall (str, start, "object", state)
|
||||||
|
end
|
||||||
pos = npos
|
pos = npos
|
||||||
t[key] = obj
|
if cont == 'cont' or cont == 'last' then
|
||||||
until cont == 'last'
|
t[key] = obj
|
||||||
|
end
|
||||||
|
until cont ~= 'cont'
|
||||||
return pos, setmetatable (t, state.objectmeta)
|
return pos, setmetatable (t, state.objectmeta)
|
||||||
end
|
end
|
||||||
|
|
||||||
local Array = P"[" * g.Cmt (g.Carg(1) * g.Carg(2), parsearray) * Space * (P"]" + Err "']' expected")
|
local Array = P"[" * g.Cmt (g.Carg(1) * g.Carg(2), parsearray)
|
||||||
local Object = P"{" * g.Cmt (g.Carg(1) * g.Carg(2), parseobject) * Space * (P"}" + Err "'}' expected")
|
local Object = P"{" * g.Cmt (g.Carg(1) * g.Carg(2), parseobject)
|
||||||
local Value = Space * (Array + Object + SimpleValue)
|
local Value = Space * (Array + Object + SimpleValue)
|
||||||
local ExpectedValue = Value + Space * Err "value expected"
|
local ExpectedValue = Value + Space * Err "value expected"
|
||||||
ArrayContent = Value * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
|
local ExpectedKey = String + Err "key expected"
|
||||||
local Pair = g.Cg (Space * String * Space * (P":" + Err "colon expected") * ExpectedValue)
|
local End = P(-1) * g.Cc'end'
|
||||||
ObjectContent = Pair * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
|
local ErrInvalid = Err "invalid JSON"
|
||||||
|
ArrayContent = (Value * Space * (P"," * g.Cc'cont' + P"]" * g.Cc'last'+ End + ErrInvalid) + g.Cc(nil) * (P"]" * g.Cc'empty' + End + ErrInvalid)) * g.Cp()
|
||||||
|
local Pair = g.Cg (Space * ExpectedKey * Space * (P":" + Err "colon expected") * ExpectedValue)
|
||||||
|
ObjectContent = (g.Cc(nil) * g.Cc(nil) * P"}" * g.Cc'empty' + End + (Pair * Space * (P"," * g.Cc'cont' + P"}" * g.Cc'last' + End + ErrInvalid) + ErrInvalid)) * g.Cp()
|
||||||
local DecodeValue = ExpectedValue * g.Cp ()
|
local DecodeValue = ExpectedValue * g.Cp ()
|
||||||
|
|
||||||
function json.decode (str, pos, nullval, ...)
|
jsonlpeg.version = json.version
|
||||||
|
jsonlpeg.encode = json.encode
|
||||||
|
jsonlpeg.null = json.null
|
||||||
|
jsonlpeg.quotestring = json.quotestring
|
||||||
|
jsonlpeg.addnewline = json.addnewline
|
||||||
|
jsonlpeg.encodeexception = json.encodeexception
|
||||||
|
jsonlpeg.using_lpeg = true
|
||||||
|
|
||||||
|
function jsonlpeg.decode (str, pos, nullval, ...)
|
||||||
local state = {}
|
local state = {}
|
||||||
state.objectmeta, state.arraymeta = optionalmetatables(...)
|
state.objectmeta, state.arraymeta = optionalmetatables(...)
|
||||||
local obj, retpos = pegmatch (DecodeValue, str, pos, nullval, state)
|
local obj, retpos = pegmatch (DecodeValue, str, pos, nullval, state)
|
||||||
|
@ -697,16 +733,16 @@ function json.use_lpeg ()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- use this function only once:
|
-- cache result of this function:
|
||||||
json.use_lpeg = function () return json end
|
json.use_lpeg = function () return jsonlpeg end
|
||||||
|
jsonlpeg.use_lpeg = json.use_lpeg
|
||||||
|
|
||||||
json.using_lpeg = true
|
return jsonlpeg
|
||||||
|
|
||||||
return json -- so you can get the module using json = require "dkjson".use_lpeg()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if always_try_using_lpeg then
|
if always_use_lpeg then
|
||||||
pcall (json.use_lpeg)
|
return json.use_lpeg()
|
||||||
end
|
end
|
||||||
|
|
||||||
return json
|
return json
|
||||||
|
|
||||||
|
|
2
wiki
2
wiki
|
@ -1 +1 @@
|
||||||
Subproject commit c37d44d137c3a163095d155f09372f6da8fb8e51
|
Subproject commit 74a423dac2c8ea2f0f6827b209aa6de9b741a3a1
|
Loading…
Reference in New Issue