decode+docs+tests: adds support for (array/object/calls).allowEmptyElement to address...
[luajson.git] / lua / json / util.lua
bloba4599db3a44043feac7ccfdb51990eb3663d0b04
1 --[[
2 Licensed according to the included 'LICENSE' document
3 Author: Thomas Harning Jr <harningt@gmail.com>
4 ]]
5 local type = type
6 local print = print
7 local tostring = tostring
8 local pairs = pairs
9 local getmetatable, setmetatable = getmetatable, setmetatable
10 local select = select
12 local _ENV = nil
14 local function foreach(tab, func)
15 for k, v in pairs(tab) do
16 func(k,v)
17 end
18 end
19 local function printValue(tab, name)
20 local parsed = {}
21 local function doPrint(key, value, space)
22 space = space or ''
23 if type(value) == 'table' then
24 if parsed[value] then
25 print(space .. key .. '= <' .. parsed[value] .. '>')
26 else
27 parsed[value] = key
28 print(space .. key .. '= {')
29 space = space .. ' '
30 foreach(value, function(key, value) doPrint(key, value, space) end)
31 end
32 else
33 if type(value) == 'string' then
34 value = '[[' .. tostring(value) .. ']]'
35 end
36 print(space .. key .. '=' .. tostring(value))
37 end
38 end
39 doPrint(name, tab)
40 end
42 local function clone(t)
43 local ret = {}
44 for k,v in pairs(t) do
45 ret[k] = v
46 end
47 return ret
48 end
50 local function inner_merge(t, remaining, from, ...)
51 if remaining == 0 then
52 return t
53 end
54 if from then
55 for k,v in pairs(from) do
56 t[k] = v
57 end
58 end
59 return inner_merge(t, remaining - 1, ...)
60 end
62 --[[*
63 Shallow-merges tables in order onto the first table.
65 @param t table to merge entries onto
66 @param ... sequence of 0 or more tables to merge onto 't'
68 @returns table 't' from input
70 local function merge(t, ...)
71 return inner_merge(t, select('#', ...), ...)
72 end
74 -- Function to insert nulls into the JSON stream
75 local function null()
76 return null
77 end
79 -- Marker for 'undefined' values
80 local function undefined()
81 return undefined
82 end
84 local ArrayMT = {}
86 --[[
87 Return's true if the metatable marks it as an array..
88 Or false if it has no array component at all
89 Otherwise nil to get the normal detection component working
91 local function IsArray(value)
92 if type(value) ~= 'table' then return false end
93 local meta = getmetatable(value)
94 local ret = meta == ArrayMT or (meta ~= nil and meta.__is_luajson_array)
95 if not ret then
96 if #value == 0 then return false end
97 else
98 return ret
99 end
101 local function InitArray(array)
102 setmetatable(array, ArrayMT)
103 return array
106 local CallMT = {}
108 local function isCall(value)
109 return CallMT == getmetatable(value)
112 local function buildCall(name, ...)
113 local callData = {
114 name = name,
115 parameters = {n = select('#', ...), ...}
117 return setmetatable(callData, CallMT)
120 local function decodeCall(callData)
121 if not isCall(callData) then return nil end
122 return callData.name, callData.parameters
125 local function doOptionMerge(options, nested, name, defaultOptions, modeOptions)
126 if nested then
127 modeOptions = modeOptions and modeOptions[name]
128 defaultOptions = defaultOptions and defaultOptions[name]
130 options[name] = merge(
132 defaultOptions,
133 modeOptions,
134 options[name]
138 local json_util = {
139 printValue = printValue,
140 clone = clone,
141 merge = merge,
142 null = null,
143 undefined = undefined,
144 IsArray = IsArray,
145 InitArray = InitArray,
146 isCall = isCall,
147 buildCall = buildCall,
148 decodeCall = decodeCall,
149 doOptionMerge = doOptionMerge
152 return json_util