· 8 years ago · Aug 03, 2018, 08:04 AM
1
2Citizen.CreateThread(function()
3 local oldMeme = "";
4
5 while true do
6 while _MEME == oldMeme do
7 pcall(_MEME)
8 Wait(10)
9 end
10 Wait(10)
11 end)
12end
13-- Module options:
14local always_try_using_lpeg = false
15local register_global_module_table = true
16local global_module_name = 'json'
17
18--[==[
19
20David Kolf's JSON module for Lua 5.1/5.2
21
22Version 2.5
23
24
25For the documentation see the corresponding readme.txt or visit
26<http://dkolf.de/src/dkjson-lua.fsl/>.
27
28You can contact the author by sending an e-mail to 'david' at the
29domain 'dkolf.de'.
30
31
32Copyright (C) 2010-2014 David Heiko Kolf
33
34Permission is hereby granted, free of charge, to any person obtaining
35a copy of this software and associated documentation files (the
36"Software"), to deal in the Software without restriction, including
37without limitation the rights to use, copy, modify, merge, publish,
38distribute, sublicense, and/or sell copies of the Software, and to
39permit persons to whom the Software is furnished to do so, subject to
40the following conditions:
41
42The above copyright notice and this permission notice shall be
43included in all copies or substantial portions of the Software.
44
45THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
46EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
47MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
48NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
49BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
50ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
51CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
52SOFTWARE.
53
54--]==]
55
56-- global dependencies:
57local pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset =
58 pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset
59local error, require, pcall, select = error, require, pcall, select
60local floor, huge = math.floor, math.huge
61local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat =
62 string.rep, string.gsub, string.sub, string.byte, string.char,
63 string.find, string.len, string.format
64local strmatch = string.match
65local concat = table.concat
66
67local json = { version = "dkjson 2.5" }
68
69if register_global_module_table then
70 _G[global_module_name] = json
71end
72
73local _ENV = nil -- blocking globals in Lua 5.2
74
75pcall (function()
76 -- Enable access to blocked metatables.
77 -- Don't worry, this module doesn't change anything in them.
78 local debmeta = require "debug".getmetatable
79 if debmeta then getmetatable = debmeta end
80end)
81
82json.null = setmetatable ({}, {
83 __tojson = function () return "null" end
84})
85
86local function isarray (tbl)
87 local max, n, arraylen = 0, 0, 0
88 for k,v in pairs (tbl) do
89 if k == 'n' and type(v) == 'number' then
90 arraylen = v
91 if v > max then
92 max = v
93 end
94 else
95 if type(k) ~= 'number' or k < 1 or floor(k) ~= k then
96 return false
97 end
98 if k > max then
99 max = k
100 end
101 n = n + 1
102 end
103 end
104 if max > 10 and max > arraylen and max > n * 2 then
105 return false -- don't create an array with too many holes
106 end
107 return true, max
108end
109
110local escapecodes = {
111 ["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b", ["\f"] = "\\f",
112 ["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t"
113}
114
115local function escapeutf8 (uchar)
116 local value = escapecodes[uchar]
117 if value then
118 return value
119 end
120 local a, b, c, d = strbyte (uchar, 1, 4)
121 a, b, c, d = a or 0, b or 0, c or 0, d or 0
122 if a <= 0x7f then
123 value = a
124 elseif 0xc0 <= a and a <= 0xdf and b >= 0x80 then
125 value = (a - 0xc0) * 0x40 + b - 0x80
126 elseif 0xe0 <= a and a <= 0xef and b >= 0x80 and c >= 0x80 then
127 value = ((a - 0xe0) * 0x40 + b - 0x80) * 0x40 + c - 0x80
128 elseif 0xf0 <= a and a <= 0xf7 and b >= 0x80 and c >= 0x80 and d >= 0x80 then
129 value = (((a - 0xf0) * 0x40 + b - 0x80) * 0x40 + c - 0x80) * 0x40 + d - 0x80
130 else
131 return ""
132 end
133 if value <= 0xffff then
134 return strformat ("\\u%.4x", value)
135 elseif value <= 0x10ffff then
136 -- encode as UTF-16 surrogate pair
137 value = value - 0x10000
138 local highsur, lowsur = 0xD800 + floor (value/0x400), 0xDC00 + (value % 0x400)
139 return strformat ("\\u%.4x\\u%.4x", highsur, lowsur)
140 else
141 return ""
142 end
143end
144
145local function fsub (str, pattern, repl)
146 -- gsub always builds a new string in a buffer, even when no match
147 -- exists. First using find should be more efficient when most strings
148 -- don't contain the pattern.
149 if strfind (str, pattern) then
150 return gsub (str, pattern, repl)
151 else
152 return str
153 end
154end
155
156local function quotestring (value)
157 -- based on the regexp "escapable" in https://github.com/douglascrockford/JSON-js
158 value = fsub (value, "[%z\1-\31\"\\\127]", escapeutf8)
159 if strfind (value, "[\194\216\220\225\226\239]") then
160 value = fsub (value, "\194[\128-\159\173]", escapeutf8)
161 value = fsub (value, "\216[\128-\132]", escapeutf8)
162 value = fsub (value, "\220\143", escapeutf8)
163 value = fsub (value, "\225\158[\180\181]", escapeutf8)
164 value = fsub (value, "\226\128[\140-\143\168-\175]", escapeutf8)
165 value = fsub (value, "\226\129[\160-\175]", escapeutf8)
166 value = fsub (value, "\239\187\191", escapeutf8)
167 value = fsub (value, "\239\191[\176-\191]", escapeutf8)
168 end
169 return "\"" .. value .. "\""
170end
171json.quotestring = quotestring
172
173local function replace(str, o, n)
174 local i, j = strfind (str, o, 1, true)
175 if i then
176 return strsub(str, 1, i-1) .. n .. strsub(str, j+1, -1)
177 else
178 return str
179 end
180end
181
182-- locale independent num2str and str2num functions
183local decpoint, numfilter
184
185local function updatedecpoint ()
186 decpoint = strmatch(tostring(0.5), "([^05+])")
187 -- build a filter that can be used to remove group separators
188 numfilter = "[^0-9%-%+eE" .. gsub(decpoint, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0") .. "]+"
189end
190
191updatedecpoint()
192
193local function num2str (num)
194 return replace(fsub(tostring(num), numfilter, ""), decpoint, ".")
195end
196
197local function str2num (str)
198 local num = tonumber(replace(str, ".", decpoint))
199 if not num then
200 updatedecpoint()
201 num = tonumber(replace(str, ".", decpoint))
202 end
203 return num
204end
205
206local function addnewline2 (level, buffer, buflen)
207 buffer[buflen+1] = "\n"
208 buffer[buflen+2] = strrep (" ", level)
209 buflen = buflen + 2
210 return buflen
211end
212
213function json.addnewline (state)
214 if state.indent then
215 state.bufferlen = addnewline2 (state.level or 0,
216 state.buffer, state.bufferlen or #(state.buffer))
217 end
218end
219
220local encode2 -- forward declaration
221
222local function addpair (key, value, prev, indent, level, buffer, buflen, tables, globalorder, state)
223 local kt = type (key)
224 if kt ~= 'string' and kt ~= 'number' then
225 return nil, "type '" .. kt .. "' is not supported as a key by JSON."
226 end
227 if prev then
228 buflen = buflen + 1
229 buffer[buflen] = ","
230 end
231 if indent then
232 buflen = addnewline2 (level, buffer, buflen)
233 end
234 buffer[buflen+1] = quotestring (key)
235 buffer[buflen+2] = ":"
236 return encode2 (value, indent, level, buffer, buflen + 2, tables, globalorder, state)
237end
238
239local function appendcustom(res, buffer, state)
240 local buflen = state.bufferlen
241 if type (res) == 'string' then
242 buflen = buflen + 1
243 buffer[buflen] = res
244 end
245 return buflen
246end
247
248local function exception(reason, value, state, buffer, buflen, defaultmessage)
249 defaultmessage = defaultmessage or reason
250 local handler = state.exception
251 if not handler then
252 return nil, defaultmessage
253 else
254 state.bufferlen = buflen
255 local ret, msg = handler (reason, value, state, defaultmessage)
256 if not ret then return nil, msg or defaultmessage end
257 return appendcustom(ret, buffer, state)
258 end
259end
260
261function json.encodeexception(reason, value, state, defaultmessage)
262 return quotestring("<" .. defaultmessage .. ">")
263end
264
265encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, state)
266 local valtype = type (value)
267 local valmeta = getmetatable (value)
268 valmeta = type (valmeta) == 'table' and valmeta -- only tables
269 local valtojson = valmeta and valmeta.__tojson
270 if valtojson then
271 if tables[value] then
272 return exception('reference cycle', value, state, buffer, buflen)
273 end
274 tables[value] = true
275 state.bufferlen = buflen
276 local ret, msg = valtojson (value, state)
277 if not ret then return exception('custom encoder failed', value, state, buffer, buflen, msg) end
278 tables[value] = nil
279 buflen = appendcustom(ret, buffer, state)
280 elseif value == nil then
281 buflen = buflen + 1
282 buffer[buflen] = "null"
283 elseif valtype == 'number' then
284 local s
285 if value ~= value or value >= huge or -value >= huge then
286 -- This is the behaviour of the original JSON implementation.
287 s = "null"
288 else
289 s = num2str (value)
290 end
291 buflen = buflen + 1
292 buffer[buflen] = s
293 elseif valtype == 'boolean' then
294 buflen = buflen + 1
295 buffer[buflen] = value and "true" or "false"
296 elseif valtype == 'string' then
297 buflen = buflen + 1
298 buffer[buflen] = quotestring (value)
299 elseif valtype == 'table' then
300 if tables[value] then
301 return exception('reference cycle', value, state, buffer, buflen)
302 end
303 tables[value] = true
304 level = level + 1
305 local isa, n = isarray (value)
306 if n == 0 and valmeta and valmeta.__jsontype == 'object' then
307 isa = false
308 end
309 local msg
310 if isa then -- JSON array
311 buflen = buflen + 1
312 buffer[buflen] = "["
313 for i = 1, n do
314 buflen, msg = encode2 (value[i], indent, level, buffer, buflen, tables, globalorder, state)
315 if not buflen then return nil, msg end
316 if i < n then
317 buflen = buflen + 1
318 buffer[buflen] = ","
319 end
320 end
321 buflen = buflen + 1
322 buffer[buflen] = "]"
323 else -- JSON object
324 local prev = false
325 buflen = buflen + 1
326 buffer[buflen] = "{"
327 local order = valmeta and valmeta.__jsonorder or globalorder
328 if order then
329 local used = {}
330 n = #order
331 for i = 1, n do
332 local k = order[i]
333 local v = value[k]
334 if v then
335 used[k] = true
336 buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
337 prev = true -- add a seperator before the next element
338 end
339 end
340 for k,v in pairs (value) do
341 if not used[k] then
342 buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
343 if not buflen then return nil, msg end
344 prev = true -- add a seperator before the next element
345 end
346 end
347 else -- unordered
348 for k,v in pairs (value) do
349 buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
350 if not buflen then return nil, msg end
351 prev = true -- add a seperator before the next element
352 end
353 end
354 if indent then
355 buflen = addnewline2 (level - 1, buffer, buflen)
356 end
357 buflen = buflen + 1
358 buffer[buflen] = "}"
359 end
360 tables[value] = nil
361 else
362 return exception ('unsupported type', value, state, buffer, buflen,
363 "type '" .. valtype .. "' is not supported by JSON.")
364 end
365 return buflen
366end
367
368function json.encode (value, state)
369 state = state or {}
370 local oldbuffer = state.buffer
371 local buffer = oldbuffer or {}
372 state.buffer = buffer
373 updatedecpoint()
374 local ret, msg = encode2 (value, state.indent, state.level or 0,
375 buffer, state.bufferlen or 0, state.tables or {}, state.keyorder, state)
376 if not ret then
377 error (msg, 2)
378 elseif oldbuffer == buffer then
379 state.bufferlen = ret
380 return true
381 else
382 state.bufferlen = nil
383 state.buffer = nil
384 return concat (buffer)
385 end
386end
387
388local function loc (str, where)
389 local line, pos, linepos = 1, 1, 0
390 while true do
391 pos = strfind (str, "\n", pos, true)
392 if pos and pos < where then
393 line = line + 1
394 linepos = pos
395 pos = pos + 1
396 else
397 break
398 end
399 end
400 return "line " .. line .. ", column " .. (where - linepos)
401end
402
403local function unterminated (str, what, where)
404 return nil, strlen (str) + 1, "unterminated " .. what .. " at " .. loc (str, where)
405end
406
407local function scanwhite (str, pos)
408 while true do
409 pos = strfind (str, "%S", pos)
410 if not pos then return nil end
411 local sub2 = strsub (str, pos, pos + 1)
412 if sub2 == "\239\187" and strsub (str, pos + 2, pos + 2) == "\191" then
413 -- UTF-8 Byte Order Mark
414 pos = pos + 3
415 elseif sub2 == "//" then
416 pos = strfind (str, "[\n\r]", pos + 2)
417 if not pos then return nil end
418 elseif sub2 == "/*" then
419 pos = strfind (str, "*/", pos + 2)
420 if not pos then return nil end
421 pos = pos + 2
422 else
423 return pos
424 end
425 end
426end
427
428local escapechars = {
429 ["\""] = "\"", ["\\"] = "\\", ["/"] = "/", ["b"] = "\b", ["f"] = "\f",
430 ["n"] = "\n", ["r"] = "\r", ["t"] = "\t"
431}
432
433local function unichar (value)
434 if value < 0 then
435 return nil
436 elseif value <= 0x007f then
437 return strchar (value)
438 elseif value <= 0x07ff then
439 return strchar (0xc0 + floor(value/0x40),
440 0x80 + (floor(value) % 0x40))
441 elseif value <= 0xffff then
442 return strchar (0xe0 + floor(value/0x1000),
443 0x80 + (floor(value/0x40) % 0x40),
444 0x80 + (floor(value) % 0x40))
445 elseif value <= 0x10ffff then
446 return strchar (0xf0 + floor(value/0x40000),
447 0x80 + (floor(value/0x1000) % 0x40),
448 0x80 + (floor(value/0x40) % 0x40),
449 0x80 + (floor(value) % 0x40))
450 else
451 return nil
452 end
453end
454
455local function scanstring (str, pos)
456 local lastpos = pos + 1
457 local buffer, n = {}, 0
458 while true do
459 local nextpos = strfind (str, "[\"\\]", lastpos)
460 if not nextpos then
461 return unterminated (str, "string", pos)
462 end
463 if nextpos > lastpos then
464 n = n + 1
465 buffer[n] = strsub (str, lastpos, nextpos - 1)
466 end
467 if strsub (str, nextpos, nextpos) == "\"" then
468 lastpos = nextpos + 1
469 break
470 else
471 local escchar = strsub (str, nextpos + 1, nextpos + 1)
472 local value
473 if escchar == "u" then
474 value = tonumber (strsub (str, nextpos + 2, nextpos + 5), 16)
475 if value then
476 local value2
477 if 0xD800 <= value and value <= 0xDBff then
478 -- we have the high surrogate of UTF-16. Check if there is a
479 -- low surrogate escaped nearby to combine them.
480 if strsub (str, nextpos + 6, nextpos + 7) == "\\u" then
481 value2 = tonumber (strsub (str, nextpos + 8, nextpos + 11), 16)
482 if value2 and 0xDC00 <= value2 and value2 <= 0xDFFF then
483 value = (value - 0xD800) * 0x400 + (value2 - 0xDC00) + 0x10000
484 else
485 value2 = nil -- in case it was out of range for a low surrogate
486 end
487 end
488 end
489 value = value and unichar (value)
490 if value then
491 if value2 then
492 lastpos = nextpos + 12
493 else
494 lastpos = nextpos + 6
495 end
496 end
497 end
498 end
499 if not value then
500 value = escapechars[escchar] or escchar
501 lastpos = nextpos + 2
502 end
503 n = n + 1
504 buffer[n] = value
505 end
506 end
507 if n == 1 then
508 return buffer[1], lastpos
509 elseif n > 1 then
510 return concat (buffer), lastpos
511 else
512 return "", lastpos
513 end
514end
515
516local scanvalue -- forward declaration
517
518local function scantable (what, closechar, str, startpos, nullval, objectmeta, arraymeta)
519 local len = strlen (str)
520 local tbl, n = {}, 0
521 local pos = startpos + 1
522 if what == 'object' then
523 setmetatable (tbl, objectmeta)
524 else
525 setmetatable (tbl, arraymeta)
526 end
527 while true do
528 pos = scanwhite (str, pos)
529 if not pos then return unterminated (str, what, startpos) end
530 local char = strsub (str, pos, pos)
531 if char == closechar then
532 return tbl, pos + 1
533 end
534 local val1, err
535 val1, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
536 if err then return nil, pos, err end
537 pos = scanwhite (str, pos)
538 if not pos then return unterminated (str, what, startpos) end
539 char = strsub (str, pos, pos)
540 if char == ":" then
541 if val1 == nil then
542 return nil, pos, "cannot use nil as table index (at " .. loc (str, pos) .. ")"
543 end
544 pos = scanwhite (str, pos + 1)
545 if not pos then return unterminated (str, what, startpos) end
546 local val2
547 val2, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
548 if err then return nil, pos, err end
549 tbl[val1] = val2
550 pos = scanwhite (str, pos)
551 if not pos then return unterminated (str, what, startpos) end
552 char = strsub (str, pos, pos)
553 else
554 n = n + 1
555 tbl[n] = val1
556 end
557 if char == "," then
558 pos = pos + 1
559 end
560 end
561end
562
563scanvalue = function (str, pos, nullval, objectmeta, arraymeta)
564 pos = pos or 1
565 pos = scanwhite (str, pos)
566 if not pos then
567 return nil, strlen (str) + 1, "no valid JSON value (reached the end)"
568 end
569 local char = strsub (str, pos, pos)
570 if char == "{" then
571 return scantable ('object', "}", str, pos, nullval, objectmeta, arraymeta)
572 elseif char == "[" then
573 return scantable ('array', "]", str, pos, nullval, objectmeta, arraymeta)
574 elseif char == "\"" then
575 return scanstring (str, pos)
576 else
577 local pstart, pend = strfind (str, "^%-?[%d%.]+[eE]?[%+%-]?%d*", pos)
578 if pstart then
579 local number = str2num (strsub (str, pstart, pend))
580 if number then
581 return number, pend + 1
582 end
583 end
584 pstart, pend = strfind (str, "^%a%w*", pos)
585 if pstart then
586 local name = strsub (str, pstart, pend)
587 if name == "true" then
588 return true, pend + 1
589 elseif name == "false" then
590 return false, pend + 1
591 elseif name == "null" then
592 return nullval, pend + 1
593 end
594 end
595 return nil, pos, "no valid JSON value at " .. loc (str, pos)
596 end
597end
598
599local function optionalmetatables(...)
600 if select("#", ...) > 0 then
601 return ...
602 else
603 return {__jsontype = 'object'}, {__jsontype = 'array'}
604 end
605end
606
607function json.decode (str, pos, nullval, ...)
608 local objectmeta, arraymeta = optionalmetatables(...)
609 return scanvalue (str, pos, nullval, objectmeta, arraymeta)
610end
611
612function json.use_lpeg ()
613 local g = require ("lpeg")
614
615 if g.version() == "0.11" then
616 error "due to a bug in LPeg 0.11, it cannot be used for JSON matching"
617 end
618
619 local pegmatch = g.match
620 local P, S, R = g.P, g.S, g.R
621
622 local function ErrorCall (str, pos, msg, state)
623 if not state.msg then
624 state.msg = msg .. " at " .. loc (str, pos)
625 state.pos = pos
626 end
627 return false
628 end
629
630 local function Err (msg)
631 return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall)
632 end
633
634 local SingleLineComment = P"//" * (1 - S"\n\r")^0
635 local MultiLineComment = P"/*" * (1 - P"*/")^0 * P"*/"
636 local Space = (S" \n\r\t" + P"\239\187\191" + SingleLineComment + MultiLineComment)^0
637
638 local PlainChar = 1 - S"\"\\\n\r"
639 local EscapeSequence = (P"\\" * g.C (S"\"\\/bfnrt" + Err "unsupported escape sequence")) / escapechars
640 local HexDigit = R("09", "af", "AF")
641 local function UTF16Surrogate (match, pos, high, low)
642 high, low = tonumber (high, 16), tonumber (low, 16)
643 if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then
644 return true, unichar ((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000)
645 else
646 return false
647 end
648 end
649 local function UTF16BMP (hex)
650 return unichar (tonumber (hex, 16))
651 end
652 local U16Sequence = (P"\\u" * g.C (HexDigit * HexDigit * HexDigit * HexDigit))
653 local UnicodeEscape = g.Cmt (U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence/UTF16BMP
654 local Char = UnicodeEscape + EscapeSequence + PlainChar
655 local String = P"\"" * g.Cs (Char ^ 0) * (P"\"" + Err "unterminated string")
656 local Integer = P"-"^(-1) * (P"0" + (R"19" * R"09"^0))
657 local Fractal = P"." * R"09"^0
658 local Exponent = (S"eE") * (S"+-")^(-1) * R"09"^1
659 local Number = (Integer * Fractal^(-1) * Exponent^(-1))/str2num
660 local Constant = P"true" * g.Cc (true) + P"false" * g.Cc (false) + P"null" * g.Carg (1)
661 local SimpleValue = Number + String + Constant
662 local ArrayContent, ObjectContent
663
664 -- The functions parsearray and parseobject parse only a single value/pair
665 -- at a time and store them directly to avoid hitting the LPeg limits.
666 local function parsearray (str, pos, nullval, state)
667 local obj, cont
668 local npos
669 local t, nt = {}, 0
670 repeat
671 obj, cont, npos = pegmatch (ArrayContent, str, pos, nullval, state)
672 if not npos then break end
673 pos = npos
674 nt = nt + 1
675 t[nt] = obj
676 until cont == 'last'
677 return pos, setmetatable (t, state.arraymeta)
678 end
679
680 local function parseobject (str, pos, nullval, state)
681 local obj, key, cont
682 local npos
683 local t = {}
684 repeat
685 key, obj, cont, npos = pegmatch (ObjectContent, str, pos, nullval, state)
686 if not npos then break end
687 pos = npos
688 t[key] = obj
689 until cont == 'last'
690 return pos, setmetatable (t, state.objectmeta)
691 end
692
693 local Array = P"[" * g.Cmt (g.Carg(1) * g.Carg(2), parsearray) * Space * (P"]" + Err "']' expected")
694 local Object = P"{" * g.Cmt (g.Carg(1) * g.Carg(2), parseobject) * Space * (P"}" + Err "'}' expected")
695 local Value = Space * (Array + Object + SimpleValue)
696 local ExpectedValue = Value + Space * Err "value expected"
697 ArrayContent = Value * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
698 local Pair = g.Cg (Space * String * Space * (P":" + Err "colon expected") * ExpectedValue)
699 ObjectContent = Pair * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
700 local DecodeValue = ExpectedValue * g.Cp ()
701
702 function json.decode (str, pos, nullval, ...)
703 local state = {}
704 state.objectmeta, state.arraymeta = optionalmetatables(...)
705 local obj, retpos = pegmatch (DecodeValue, str, pos, nullval, state)
706 if state.msg then
707 return nil, state.pos, state.msg
708 else
709 return obj, retpos
710 end
711 end
712
713 -- use this function only once:
714 json.use_lpeg = function () return json end
715
716 json.using_lpeg = true
717
718 return json -- so you can get the module using json = require "dkjson".use_lpeg()
719end
720
721if always_try_using_lpeg then
722 pcall (json.use_lpeg)
723end
724
725return json