Project import
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..277b66f --- /dev/null +++ b/Makefile
@@ -0,0 +1,88 @@ +# +# Copyright (c) 2010-2011 Nest, Inc. +# All rights reserved. +# +# This document is the property of Nest. It is considered +# confidential and proprietary information. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Nest. +# +# Description: +# This Makefile is used to build luajson, a JSON parser written in lua +# + +.NOTPARALLEL: + +BuildConfigSpecialized := No +BuildProductSpecialized := No + +include pre.mak + +PackageName := luajson + +PackageExtension := tar.bz2 +PackageSeparator := - + +PackageArchive := $(PackageName).$(PackageExtension) +PackageSourceDir := $(PackageName)$(PackageSeparator)$(PackageVersion) + +PackageBuildMakefile = $(call GenerateBuildPaths,Makefile) + +CleanPaths += $(PackageLicenseFile) + +all: $(PackageDefaultGoal) + +# Generate the package license contents. + +$(PackageSourceDir)/LICENSE: source + +$(PackageLicenseFile): $(PackageSourceDir)/LICENSE + $(copy-result) + +# Extract the source from the archive and apply patches, if any. + +$(PackageSourceDir): $(PackageArchive) $(PackagePatchPaths) + $(expand-and-patch-package) + +# Prepare the sources. + +.PHONY: source +source: | ${PackageSourceDir} + +# Patch the sources, if necessary. + +.PHONY: patch +patch: source + +# Generate the package build makefile. + +$(PackageBuildMakefile): | $(PackageSourceDir) $(BuildDirectory) + $(call create-links,$(CURDIR)/$(PackageSourceDir),$(BuildDirectory)) + +# Configure the source for building. + +.PHONY: configure +configure: patch | ${PackageBuildMakefile} + +.PHONY: build +build: configure | $(BuildDirectory) + + +# Stage the build to a temporary installation area. +# +# We have to unset MAKEFLAGS since they confuse the package build otherwise. +.PHONY filestocopy: + cp -r ${call Slashify,${CURDIR}}${call Slashify,${PackageSourceDir}}lua ${ResultDirectory} + + +.PHONY: stage +stage: build filestocopy | $(ResultDirectory) + +clean: + $(Verbose)$(RM) $(RMFLAGS) -r $(PackageSourceDir) + $(Verbose)$(RM) $(RMFLAGS) -r $(BuildDirectory) + $(Verbose)$(RM) $(RMFLAGS) -r $(ResultDirectory) + +include post.mak
diff --git a/luajson-1.2.1/LICENSE b/luajson-1.2.1/LICENSE new file mode 100644 index 0000000..f12cb56 --- /dev/null +++ b/luajson-1.2.1/LICENSE
@@ -0,0 +1,27 @@ +The following license is applied to all documents in this project with the +exception of the 'tests' directory at the root. +The 'tests' directory is dual-licenses Public Domain / MIT, whichever is +least restrictive in your legal jurisdiction. + +The MIT License + +Copyright (c) 2008 Thomas Harning Jr. <harningt@gmail.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +
diff --git a/luajson-1.2.1/Makefile b/luajson-1.2.1/Makefile new file mode 100644 index 0000000..b21d5f6 --- /dev/null +++ b/luajson-1.2.1/Makefile
@@ -0,0 +1,45 @@ +# +# Makefile to prepare releases and run tests +# + +.PHONY: all clean check dist dist-all dist-bzip2 dist-gzip dist-zip distcheck + +DIST_DIR=dist +LUA_BIN=lua + + +all: + @echo Building nothing - no binaries + +clean: + @echo Cleaning nothing - no binaries + + +dist dist-all: distdir dist-bzip2 dist-gzip dist-zip + +distdir: + mkdir -p dist + +VERSION=luajson-$(shell git describe --abbrev=4 HEAD 2>/dev/null) +dist-bzip2: distdir + git archive --format=tar --prefix=$(VERSION)/ HEAD | bzip2 -9v > $(DIST_DIR)/$(VERSION).tar.bz2 +dist-gzip: distdir + git archive --format=tar --prefix=$(VERSION)/ HEAD | gzip -9v > $(DIST_DIR)/$(VERSION).tar.gz +dist-zip: distdir + git archive --format=zip --prefix=$(VERSION)/ HEAD > $(DIST_DIR)/$(VERSION).zip + +# Config to make sure that Lua uses the contained Lua code +LUA_PATH_SETUP=LUA_PATH="?/init.lua;../lua/?.lua;../lua/?/init.lua;$(LUA_PATH);" +LUA_SETUP=LUA_OLD_INIT="$(LUA_INIT)" LUA_INIT="@hook_require.lua" $(LUA_PATH_SETUP) +check-regression: + cd tests && $(LUA_SETUP) lua regressionTest.lua +check-unit: + cd tests && $(LUA_SETUP) lunit lunit-*.lua +check: check-regression check-unit + + +distcheck: dist-bzip2 + mkdir -p tmp + tar -C tmp -xf $(DIST_DIR)/$(VERSION).tar.bz2 + cd tmp/$(VERSION) && make check + rm -rf tmp
diff --git a/luajson-1.2.1/README b/luajson-1.2.1/README new file mode 100644 index 0000000..16d52ff --- /dev/null +++ b/luajson-1.2.1/README
@@ -0,0 +1,59 @@ +LuaJSON + JSON Parser/Constructor for Lua + +Author: Thomas Harning Jr. <harningt@gmail.com> + +Source code: + http://repo.or.cz/luajson + +Bug reports: + http://github.com/harningt/luajson + harningt@gmail.com + +Requirements + Lua 5.1 + LPeg (Tested with 0.7, 0.8, 0.9 ... 0.6 mostly works) + For regressionTest: + lfs (Tested with 1.4.1) + For lunit-tests: + lunit >= 0.4 + +License + All-but tests: MIT-style, See LICENSE for details + tests/*: Public Domain / MIT - whichever is least restrictive + +Module/Function overview: + json.encode (callable module referencing json.encode.encode) + --encode ( value : ANY-valid ) + + Takes in a JSON-encodable value and returns the JSON-encoded text + Valid input types: + table + array-like table (spec below) + string + number + boolean + 'null' - represented by json.util.null + Table keys (string,number,boolean) are encoded as strings, others are erroneus + Table values are any valid input-type + Array-like tables are converted into JSON arrays... + Position 1 maps to JSON Array position 0 + --isEncodable ( value : ANY ) + Returns a boolean stating whether is is encodeable or not + NOTE: Tables/arrays are not deeply inspected + + json.decode (callable module referencing json.decode.decode) + --decode (data : string, strict : optional boolean) + Takes in a string of JSON data and converts it into a Lua object + If 'strict' is set, then the strict JSON rule-set is used + + json.util + --printValue (tab : ANY, name : string) + recursively prints out all object values - if duplicates found, reference printed + --null + Reference value to represent 'null' in a well-defined way to + allow for null values to be inserted into an array/table + +Attribution: + parsing test suite from JSON_checker project of http://www.json.org/ + No listed license for these files in their package.
diff --git a/luajson-1.2.1/ReleaseNotes.txt b/luajson-1.2.1/ReleaseNotes.txt new file mode 120000 index 0000000..e05acb0 --- /dev/null +++ b/luajson-1.2.1/ReleaseNotes.txt
@@ -0,0 +1 @@ +docs/ReleaseNotes-1.2.1.txt \ No newline at end of file
diff --git a/luajson-1.2.1/docs/LuaJSON.txt b/luajson-1.2.1/docs/LuaJSON.txt new file mode 100644 index 0000000..c18e2e4 --- /dev/null +++ b/luajson-1.2.1/docs/LuaJSON.txt
@@ -0,0 +1,206 @@ +LuaJSON(3) +========== +:Author: Thomas Harning +:Email: harningt@gmail.com +:Date: 2009/04/29 + +NAME +---- +luajson - JSON encoder/decoder for Lua + +SYNOPSIS +-------- +require("json") + +json.decode("json-string" [, parameters]) + +json.decode.getDecoder(parameters) + +json.encode(lua_value [, parameters]) + +json.encode.getEncoder(parameters) + +DESCRIPTION +----------- +json.decode("json-string" [, parameters]):: + Obtains a JSON decoder using `getDecoder` with the parameters specified, + then performs the decoding operation. + +json.encode(lua_value [, parameters]):: + Obtains a JSON encoder using `getEncoder` with the parameters specified, + then performs the encoding operation. + +json.decode.getDecoder(parameters):: + Obtains a JSON decoder configured with the given parameters or defaults. + +json.encode.getEncoder(parameters):: + Obtains a JSON encoder configured with the given parameters or defaults. + +json.encode.strict:: + A default parameter specification containing 'strict' rules for encoding + +json.decode.strict:: + A default parameter specification containing 'strict' rules for decoding + +=== COMMON PARAMETERS + +initialObject : boolean:: + Specifies if the outermost element be an array or object + +allowUndefined : boolean:: + Specifies if 'undefined' is an allowed value + +null : any:: + Placeholder object for null values + +undefined : any:: + Placeholder for undefined values + +number.nan : boolean:: + Specifies if NaN is an allowed value + +number.inf : boolean:: + Specifies if +/-Infinity is an allowed value + +=== ENCODER-SPECIFIC PARAMETERS + +preProcess : `function(object)`:: + Called for every value to be encoded, optionally altering. + If returns `nil` then no value change occurs. + +output : function:: + Function that returns an encoder specification (TBD), if null + default used that returns a string. + +array.isArray : `function(object)`:: + If `true`/`false` returned, then the value is authoritatively + an array or not + +strings.xEncode : boolean:: + Specifies if binary values are to be encoded with \xNN rather than \uNNNN + +strings.encodeSet : string:: + http://www.lua.org/manual/5.1/manual.html#5.4.1[gmatch-style] set of + characters that need to be escaped (to be contained in `[]`) + +strings.encodeSetAppend : string:: + Set of characters that need to be escaped (to be contained in `[]`). + Appended to the current encodeSet. + +==== Default Configuration +[source,lua] +---- +array.isArray == json-util's isArray implementation +allowUndefined = true +number.nan = true +number.inf = true +strings.xEncode = false +strings.encodeSet = '\\"/%z\1-\031' +---- + +==== Strict Configuration +[source,lua] +---- +initialObject = true +allowUndefined = false +number.nan = false +number.inf = false +---- + +=== DECODER-SPECIFIC PARAMETERS + +unicodeWhitespace : boolean:: + Specifies if unicode whitespace characters are counted + +array.trailingComma / object.trailingComma : boolean:: + Specifies if extraneous trailing commas are ignored in declaration + +calls.defs : map<string | LPEG, function | boolean>:: + Defines set of specifically permitted function definitions. + If boolean value, determines if allowed or not, decoded as a call object. + Function return-value is the decoded result. + Function definition: `function(name, [arguments])` : output-value + +calls.allowUndefined : boolean:: + Specifies if undefined call definitions are decoded as call objects. + +number.frac : boolean:: + Specifies if numbers can have a decimal component (ex: `.01`) + +number.exp : boolean:: + Specifies if exponents are allowed (ex: `1e2`) + +number.hex : boolean:: + Specifies if hexadecimal numbers are allowed (ex: `0xDEADBEEF`) + +object.number : boolean:: + Specifies if numbers can be object keys + +object.identifier : boolean:: + Specifies if unquoted 'identifiers' can be object keys (matching `[A-Za-z_][A-Za-z0-9_]*`) + +strings.badChars : string:: + Set of characters that should not be present in a string + +strings.additionalEscapes : LPeg expression:: + LPeg expression to handle output (ex: `lpeg.C(1)` would take `\k` and spit out `k`) + +strings.escapeCheck : non-consuming LPeg expression:: + LPeg expression to check if a given character is allowed to be an escape value + +strings.decodeUnicode:: + `function (XX, YY)` handling \uXXYY situation to output decoded unicode sequence + +strings.strict_quotes : boolean:: + Specifies if the `'` character is considered a quoting specifier + +==== Default configuration + +[source,lua] +---- +unicodeWhitespace = true +initialObject = false +allowUndefined = true +array.trailingComma = true +number.frac = true +number.exp = true +number.hex = false +object.number = true +object.identifier = true +object.trailingComma = true +strings.badChars = '' -- No characters considered bad in a string +strings.additionalEscapes = false, -- disallow untranslated escapes +strings.escapeCheck = #lpeg.S('bfnrtv/\\"xu\'z'), +strings.decodeUnicode = utf8DecodeUnicode, +strings.strict_quotes = false +---- + +==== Strict configuration + +[source,lua] +---- +initialObject = true +allowUndefined = false +array.trailingComma = false +object.identifier = false +object.trailingComma = false +strings.badChars = '\b\f\n\r\t\v' +strings.additionalEscapes = false -- no additional escapes +strings.escapeCheck = #lpeg.S('bfnrtv/\\"u') --only these are allowed to be escaped +strings.strict_quotes = true +---- + +AUTHOR +------ +Written by Thomas Harning Jr., <harningt@gmail.com> + +REFERENCES +---------- +http://www.inf.puc-rio.br/~roberto/lpeg[LPeg] + +http://json.org[JSON] + +COPYING +------- +Copyright (C) 2008-2009 Thomas Harning Jr. Free use of this software is granted +under the terms of the MIT license.
diff --git a/luajson-1.2.1/docs/ReleaseNotes-0.10.txt b/luajson-1.2.1/docs/ReleaseNotes-0.10.txt new file mode 100644 index 0000000..ca678c9 --- /dev/null +++ b/luajson-1.2.1/docs/ReleaseNotes-0.10.txt
@@ -0,0 +1,105 @@ +luajson v0.10 Release Notes +=========================== + +User Visible Changes +-------------------- +This release changes the system quite a bit from previous versions in +that there is more configurability. There still is quite a bit of strong +defaulting to make it accept more data formats and encode such that the +most strict decoder *should* decode it. + +It is now possible to obtain wrapped-up encoders and decoders with options +"compiled" in. With decoders this is particularly bound-up (LPEG patterns), +encoders take advantage of this with less closure-count. + +Extended features of newer LPEG versions can also be used as they are +available, either via function detection or version # parsing. + +New decoder features: + + * Single-quoted strings + * Function-call decoding + * Generic string management + * String post-processing option + * UTF-16 -> UTF-8 code decoding for "\uXXXX" from Emil Renner Berthing by default (not req) + * Handle extended UTF-8 spacing characters and BOF for inter-element spacing + +New encoder features: + + * Function-call encoding + * String pre-processing option + * Fully modular encoding system + * Encoding with similar option system as decoding + + +Plans for next release +---------------------- + +0.11 + + * UTF-8 encoding/decoding validation (currently decoding only supported) + * Optional \xXX encoding + * JSON encoding with fully 'strict' options + * Generic output mechanism (ropes, IO, etc) + +1.0 beta + + * Full API documentation + * Stable encoder/decoder option-apis. Final 1.0 release will maintain + that all options used in code will be future-proof, at least until 2.0 + +Updates since 0.9.1 +=================== + +Emil Renner Berthing (1): + decoder: + Added proper utf8 decoding of strings +Thomas Harning Jr (38): + -ungrouped- + Merge branch '0.9-rockspec' + base: + Setup 0.9.1 rockspec with md5 of luaforge release + added luarocks module to check out luajson from git (requires git patch) + Preparing for next release pre-emptively + decode-util: + during a table merge, if a nil is located, skip it + decoder/test: + Added preliminary function-call handling + Require name is string and func is function + Support both patterns and strings as function name specifiers + function calls receive as first argument the name used + added support for multiple arguments to functions + Moved function-call decoder to separate module + added string post-processing utility + decoder/tests: + adds support for single-quoted strings w/ expected escape-handling + support unicode whitespaces as whitespace around values + decoder: + Fully modularized strings/number/calls data-types + Refactored boolean/null/undefined out into the 'others' module + Provide workaround for missing lpeg.type in lpeg 0.6, 0.7, ... + More stabilization of string decoder configuration as well as hooking unicode-handling in + optimized 'number' option-defaulting + unified configuration system into a fast-cached Tokend which only permits card-readng ops (writing in seprate referece...) + Fixed return assertion to prevent 'Invalid JSON data' from being returned as second result + Added simple LPEG version parser "x.y.z.." => x.y + Added support for LPEG 0.9 accumulator replacement (fold) which may be faster + string.char => string_char for optimization in utf8 decoder + encoder/decoder: + added support for 'undefined' value + encoder/test: + exposed and test string preprocessing option + encoder: + add string preprocessor handler (for encoding->utf8 mgmt) + Break apart the encoder into distinct modules + add call encoding + split out number encoder into own file to mirror decoder + added applicable configuration options from the decoder to the number encoder + enhanced configuration support to match the decoder's optionset where appropriate + added 'initialObject' check to assert that the root object is in fact an object/array + mirrored decoder's getDecoder => getEncoder setup + performed full modularization of the encoder + added function-encode tests + tests: + Removed package.path alteration since 'make check' handles that as well as luarocks + applied configuration optimizations take advantage of the encoder optimizations and simplifications from the decoders + added UTF-16 => UTF-8 encoder test + extends UTF tests with boundary tests and test # for break detect
diff --git a/luajson-1.2.1/docs/ReleaseNotes-0.9.1.txt b/luajson-1.2.1/docs/ReleaseNotes-0.9.1.txt new file mode 100644 index 0000000..a3e4e1c --- /dev/null +++ b/luajson-1.2.1/docs/ReleaseNotes-0.9.1.txt
@@ -0,0 +1,19 @@ +luajson v0.9.1 Release Notes +============================ + +User Visible Changes +-------------------- +LuaRocks package created. + +Plans for next release +---------------------- + * Make the encoder customizable in a manner similar to the decoder + * Try to create an integration point for unicode handling + * Add in custom 'function' handling for decoder (ex: b64(stringvalue)) + +Updates since 0.9 +================= + +Thomas Harning Jr (1): + base: + Preparation to make luajson work as a luarocks rock
diff --git a/luajson-1.2.1/docs/ReleaseNotes-0.9.txt b/luajson-1.2.1/docs/ReleaseNotes-0.9.txt new file mode 100644 index 0000000..82d5930 --- /dev/null +++ b/luajson-1.2.1/docs/ReleaseNotes-0.9.txt
@@ -0,0 +1,43 @@ +luajson v0.9 Release Notes +========================== + +User Visible Changes +-------------------- +There are more tests added in using the lunit framework. These are particularly useful for +testing and debugging small components in the luajson decoder/encoder sections. + +Decoders are now customizable in a modular manner. For example: You can construct a decoder +that allows for NaN and Inf values, but be strict on everything else. The support framework +should permit for more enhancements and custom elements. + +Plans for next release +---------------------- + * Make the encoder customizable in a manner similar to the decoder + * Try to create an integration point for unicode handling + * Add in custom 'function' handling for decoder (ex: b64(stringvalue)) + * Create luarocks + +Updates since 0.6 +================= + +Thomas Harning Jr (15): + base: + Added changelog (with details for 0.6) + Noted lunit 0.4 requirement + Make distcheck properly run the check inside the dist + decoder/encoder: + Added support for primitive Array metatable marker to mark arrays as such + decoder/test: + Added hex decode capability + decoder: + Cleaned up unused values in the base decoder + Refactored decoding mechanism to permit building even more customized decoders + Fixed decoder generation to return cached versions + fixed decoder to remove misnamed parameters (causing failed tests) + Allow negative inf + test: + Reconfigured the tests to behave more correctly and allow for a simpler addition mechanism. + Enhanced the regression tests to handle roundtripping in a sane manner + Updated regression tests for roundtripping to have a better output format and handle outer whitespace and moved tests + Added lunit-based tests for fine-grained tests + Made lunit tests use 'setup' to simplify decoder hooking
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.0.1.txt b/luajson-1.2.1/docs/ReleaseNotes-1.0.1.txt new file mode 100644 index 0000000..ae679c7 --- /dev/null +++ b/luajson-1.2.1/docs/ReleaseNotes-1.0.1.txt
@@ -0,0 +1,39 @@ +luajson v1.0.1 Release Notes +============================ + +User Visible Changes +-------------------- +Duplicate references are allowed if it does not cause circular references. + +This allows something like the following to be valid, where it was not before: + + a = {1, 2, 3} + json.encode({a, a}) + +Decoding this will not be handled in any special way, it will be encoded as: + + [ [1,2,3], [1,2,3] ] + +Plans for next release +---------------------- +The 1.1 release will contain support for arbitrary configurations in the same +manner as the built-in configurations. It will also contain support for +a simple decoder where `null` and `undefined` values are mapped to nil, +rather than the more complicated round-trip capable constants. + +Updates since 1.0 +================= + +Thomas Harning Jr (3): + base: + updates utility to help construct lua rocks to provide stable output + encoder: + adds support for non-circular duplicate object references + tests: + adds encoding test for circular/non-circular duplicate values + +Contributions +============= + +Thanks to Marcus Irven <marcus@marcusirven.com> for reporting +the issue with duplicate objects that aren't circular.
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.0.2.txt b/luajson-1.2.1/docs/ReleaseNotes-1.0.2.txt new file mode 100644 index 0000000..a73e20f --- /dev/null +++ b/luajson-1.2.1/docs/ReleaseNotes-1.0.2.txt
@@ -0,0 +1,46 @@ +luajson v1.0.2 Release Notes +============================ + +User Visible Changes +-------------------- +In Windows, Lua's tostring and tonumber handling occur differently for +the boundary cases of NaN, Infinity, and -Infinity values. This broke +Windows encoding/decoding of JSON for which these values are present. + +Example input/outputs: + +Windows: + + * tonumber("Infinity") == nil + * tostring(1/0) == "1.#INF" + * tostring(0/0) == "-1.#IND" + +Linux: + + * tonumber("Infinity") == inf + * tostring(1/0) == "inf" + * tostring(0/0) == "nan" + +The code that decoded was changed to report the output manually on decode +rather than decode 'generically' using 'tonumber'. + +The code that encoded was changed to use numerical equivalence checking +before returning what 'tostring' would have, which should catch nearly +all cases. + +Checks were updated to do: + + * nan => value ~= value + * inf => value == math.huge + * -inf => value == -math.huge + +Plans for next release +---------------------- +Bugfixes only in the 1.0.x series. + +Updates since 1.0.1 +=================== + +Thomas Harning Jr (2): + decoder/encoder: + better handles number encoding/decoding for cases where tonumber/tostring don't work as expected
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.0.txt b/luajson-1.2.1/docs/ReleaseNotes-1.0.txt new file mode 100644 index 0000000..f69e556 --- /dev/null +++ b/luajson-1.2.1/docs/ReleaseNotes-1.0.txt
@@ -0,0 +1,93 @@ +luajson v1.0 Release Notes +========================== + +User Visible Changes +-------------------- +This release marks the 1.0 release that has been in the works for quite some time. +One of the major release items is detailed documentation and a reasonably stable/ +clean API. Some features have been eliminated since they were not effective or +used. + +Features removed: + * Lax number handling... before this release, numbers with ugly definition were + permitted, such as leading zeroes, multiple negative signs, ... + * String post-processing... this feature was unused and appears to serve no + useful purpose. Removing it made unifying encoding/decoding options simpler + * Adds global pre-processing to handle arbitrary conversion of values during + encoding. + +Changes: + * String escape codes updated to match what the JSON spec uses for encoding + +Additions: + * Add optional \x00 character encoding to handle encoding single bytes + * Custom output stream functionality to create optimal output mechanisms + that can stream JSON output. + +Plans for next release +---------------------- +Currently there is nothing in the works for the next release. The project +is very open to outside suggestions and patches for enhanced functionality... +so please contribute. + +Updates since 0.10 +================== + +Thomas Harning Jr (46): + -ungrouped- + Rockspec 0.10 + moved lua sources into 'lua' to assist luarocks management + base: + makefiles learn high bzip2 and gzip compression + adds new rockspec for github + updated github rockspec to reference all of the files + Makefile learns split-apart checking + rockspec 0.10-2 update -- previous one had improper luaforge link + decoder/strings: + removed unused 'postProcess' option + removed unused 'null' decoder + remove catchall escape handler from default + applied minor cleanups + added error analysis for strings + generic bad-character utility + decoder/tests: + remove depth limiting support code, implementation, and tests + implemented non-defined call captures and updated tests to handle cases + removed lax number handling (leading zeroes, multiple negatives, and spaces between - and digits) + fixes ambiguous/invalid hex numbers with decimal/scientific format + decoder: + reorders replacements based on spec, adds 'x' escape + allow whitespace before strict object/array + generalizes decoding using grammar entries + docs: + preliminary documentation of options + created markdown documentation to be translated into manpage-style documentation + moves documentation to asciidoc + encoder/decoder/tests: + moves json.decode.util.merge => json.util.merge + call-generation/handling moved to json.util and unified + removes discrimination between calls with 1 and * arguments + encoder/decoder: + applied license headers to files missing them + encoder/tests: + move preprocessing to root to permit global pre-processor (ex: take special strings and base64-encode to call) + encoder: + add vertical tabulation character to the encoded set + adds \xXX encoding and customizable encoding set + adds custom output-encoder support while keeping default case optimal using templates + adds output-stream writer for encoding + consulted JSON specification and updated string definitions to match + note encoding > 7F with escapes is hazardous + properly capture expected range-of-characters to map + updates strict encoding to use correct calls check and ordering + correct language of disabled 'undefined' value + cleans up code and errors + removes extraneous 'defs' from the default options + tests: + adds \u and \x escape encoding/decoding test cases + test strict form of string decoding tests + updates strict string test to use strict encoder + regression-test uses test strict encoder in strict tests + adds strict encoder regression tests + report error cause during regressionTest encoding failures + added pre-value whitespace tests + updated tests to match new stricter default syntax
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.1.1.txt b/luajson-1.2.1/docs/ReleaseNotes-1.1.1.txt new file mode 100644 index 0000000..d75fafd --- /dev/null +++ b/luajson-1.2.1/docs/ReleaseNotes-1.1.1.txt
@@ -0,0 +1,51 @@ + +luajson v1.1.1 Release Notes +============================ + +User Visible Changes +-------------------- +In Windows, Lua's tostring and tonumber handling occur differently for +the boundary cases of NaN, Infinity, and -Infinity values. This broke +Windows encoding/decoding of JSON for which these values are present. + +Example input/outputs: + +Windows: + + * tonumber("Infinity") == nil + * tostring(1/0) == "1.#INF" + * tostring(0/0) == "-1.#IND" + +Linux: + + * tonumber("Infinity") == inf + * tostring(1/0) == "inf" + * tostring(0/0) == "nan" + +The code that decoded was changed to report the output manually on decode +rather than decode 'generically' using 'tonumber'. + +The code that encoded was changed to use numerical equivalence checking +before returning what 'tostring' would have, which should catch nearly +all cases. + +Checks were updated to do: + + * nan => value ~= value + * inf => value == math.huge + * -inf => value == -math.huge + +Plans for next release +---------------------- +The next version should hopefully have more error reporting capabilities, +such as returning where an error occurred and possibly details. +How this will be done is a research-item. + +Updates since 1.1 +================= + +Thomas Harning Jr (3): + -ungrouped- + Merge branch '1.0.x' + decoder/encoder: + better handles number encoding/decoding for cases where tonumber/tostring don't work as expected
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.1.txt b/luajson-1.2.1/docs/ReleaseNotes-1.1.txt new file mode 100644 index 0000000..ecf5600 --- /dev/null +++ b/luajson-1.2.1/docs/ReleaseNotes-1.1.txt
@@ -0,0 +1,31 @@ +luajson v1.1 Release Notes +========================== + +User Visible Changes +-------------------- +A new default configuration "simple" is available that does not use +`json.util.null` and `json.util.undefined` to represent their associated +JSON values. + +There is also a change in the decoding of arrays with nulls to avoid +special casing it. + +Plans for next release +---------------------- +No plans yet for what a future release might contain. + +Updates since 1.0.1 +=================== + +Thomas Harning Jr (9): + -ungrouped- + Merge branch '1.0.x' + decoder: + learns how to handle arbitrary sets of defaults (now + simple) + adds support for nil return values + fixes bug where function call returns nothing => error + adds support for 'simple' decoding to map null and undefined => nil + removes special casing of null values in an array + adds support for caching new arbitrary configs + tests: + tests added for simple/default decoders stand-alone, in arrays, in objects
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.2.1.txt b/luajson-1.2.1/docs/ReleaseNotes-1.2.1.txt new file mode 100644 index 0000000..d6aadf7 --- /dev/null +++ b/luajson-1.2.1/docs/ReleaseNotes-1.2.1.txt
@@ -0,0 +1,27 @@ +luajson v1.2.1 Release Notes +============================ + +User Visible Changes +-------------------- +LPeg 0.10 now supported. The only problem was the mechanism for +version detection. I now use object detection which should better +work for future version updates. + +Plans for next release +---------------------- +No change in the plans for the next release. +For the next feature release, I plan on better fleshing out the enhanced +error handling and possibly adding in the more customizable output +system. For previews of the features that might make it into the +next release, please see the "next" branch. Note that this branch +is volatile and features may vanish rather than be reverted for cleanliness. + +Enhanced error handling introduced in LPeg 0.10 might help this task. + + +Updates since 1.2 +================= + +Thomas Harning Jr (6): + decode/object: + compatibility fix for LPeg 0.10 - function-checking vs number parsing
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.2.txt b/luajson-1.2.1/docs/ReleaseNotes-1.2.txt new file mode 100644 index 0000000..22d319f --- /dev/null +++ b/luajson-1.2.1/docs/ReleaseNotes-1.2.txt
@@ -0,0 +1,67 @@ +luajson v1.2 Release Notes +========================== + +Tested LPeg versions: + + * 0.9 - pass + * 0.8 - pass + * 0.7 - pass + * 0.6 - fail : cannot handle 'nil' returns -> tranforms into booleans + +Note that 0.6 passes strict mode tests and behaviors. It just breaks +down when decoding the plain return value `null` or `undefined` that +would result in a `nil` return value. + +User Visible Changes +-------------------- + +setObjectKey +~~~~~~~~~~~~ +Thanks to Alexander Gladysh, we now have the "setObjectKey" +hook to permit more customizable behavior during object construction. + +There is a new 'object' option that you can set to handle custom +key-value setting. If you set in the configuration table +.object.setObjectKey to a function with the signature +`(tab, key, value)`, you will override the `rawset` style behavior. + +Example: + json.decode("{'1':true, x:true}") + --> { ["1"] = true, x = true } + function newSetObjectKey(tab, key, value) + local numkey = tonumber(key) + key = numkey or key + rawset(tab, key, value) + end + json.decode("{'1':true, x:true}", { object = { setObjectKey = newSetObjectKey } }) + --> { [1] = true, x = true } + +require builtins update +~~~~~~~~~~~~~~~~~~~~~~~ +Also changed is the major change to `require` as many of the default +packages as possible to better help custom embedding scenarios where +'default' tables such as `io` and `os` may require on-demand loading +via `require`. + +Plans for next release +---------------------- +For the next feature release, I plan on better fleshing out the enhanced +error handling and possibly adding in the more customizable output +system. For previews of the features that might make it into the +next release, please see the "next" branch. Note that this branch +is volatile and features may vanish rather than be reverted for cleanliness. + +Updates since 1.1.1 +=================== + +Thomas Harning Jr (4): + all: + pulls in all but base/package modules via require (io,os,string,table,math) + decoder: + implements setObjectKey for LPeg < 0.9 + Moves 'setObjectKey' from root of `options` to `options.object` + docs: + adds reference for where bug reporting should go +Alexander Gladysh (1): + decoder: + configurable object key filter
diff --git a/luajson-1.2.1/lua/json.lua b/luajson-1.2.1/lua/json.lua new file mode 100644 index 0000000..296fb0d --- /dev/null +++ b/luajson-1.2.1/lua/json.lua
@@ -0,0 +1,12 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local decode = require("json.decode") +local encode = require("json.encode") +local util = require("json.util") + +module("json") +_M.decode = decode +_M.encode = encode +_M.util = util
diff --git a/luajson-1.2.1/lua/json/decode.lua b/luajson-1.2.1/lua/json/decode.lua new file mode 100644 index 0000000..3086366 --- /dev/null +++ b/luajson-1.2.1/lua/json/decode.lua
@@ -0,0 +1,132 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local lpeg = require("lpeg") + +local error = error + +local object = require("json.decode.object") +local array = require("json.decode.array") + +local merge = require("json.util").merge +local util = require("json.decode.util") + +local setmetatable, getmetatable = setmetatable, getmetatable +local assert = assert +local ipairs, pairs = ipairs, pairs +local string_char = require("string").char + +local require = require +module("json.decode") + +local modulesToLoad = { + "array", + "object", + "strings", + "number", + "calls", + "others" +} +local loadedModules = { +} + +default = { + unicodeWhitespace = true, + initialObject = false +} + +local modes_defined = { "default", "strict", "simple" } + +simple = {} + +strict = { + unicodeWhitespace = true, + initialObject = true +} + +-- Register generic value type +util.register_type("VALUE") +for _,name in ipairs(modulesToLoad) do + local mod = require("json.decode." .. name) + for _, mode in pairs(modes_defined) do + if mod[mode] then + _M[mode][name] = mod[mode] + end + end + loadedModules[name] = mod + -- Register types + if mod.register_types then + mod.register_types() + end +end + +-- Shift over default into defaultOptions to permit build optimization +local defaultOptions = default +default = nil + + +local function buildDecoder(mode) + mode = mode and merge({}, defaultOptions, mode) or defaultOptions + local ignored = mode.unicodeWhitespace and util.unicode_ignored or util.ascii_ignored + -- Store 'ignored' in the global options table + mode.ignored = ignored + + local value_id = util.types.VALUE + local value_type = lpeg.V(value_id) + local object_type = lpeg.V(util.types.OBJECT) + local array_type = lpeg.V(util.types.ARRAY) + local grammar = { + [1] = mode.initialObject and (ignored * (object_type + array_type)) or value_type + } + for _, name in pairs(modulesToLoad) do + local mod = loadedModules[name] + mod.load_types(mode[name], mode, grammar) + end + -- HOOK VALUE TYPE WITH WHITESPACE + grammar[value_id] = ignored * grammar[value_id] * ignored + grammar = lpeg.P(grammar) * ignored * lpeg.Cp() * -1 + return function(data) + local ret, next_index = lpeg.match(grammar, data) + assert(nil ~= next_index, "Invalid JSON data") + return ret + end +end + +-- Since 'default' is nil, we cannot take map it +local defaultDecoder = buildDecoder(default) +local prebuilt_decoders = {} +for _, mode in pairs(modes_defined) do + if _M[mode] ~= nil then + prebuilt_decoders[_M[mode]] = buildDecoder(_M[mode]) + end +end + +--[[ +Options: + number => number decode options + string => string decode options + array => array decode options + object => object decode options + initialObject => whether or not to require the initial object to be a table/array + allowUndefined => whether or not to allow undefined values +]] +function getDecoder(mode) + mode = mode == true and strict or mode or default + local decoder = mode == nil and defaultDecoder or prebuilt_decoders[mode] + if decoder then + return decoder + end + return buildDecoder(mode) +end + +function decode(data, mode) + local decoder = getDecoder(mode) + return decoder(data) +end + +local mt = getmetatable(_M) or {} +mt.__call = function(self, ...) + return decode(...) +end +setmetatable(_M, mt)
diff --git a/luajson-1.2.1/lua/json/decode/array.lua b/luajson-1.2.1/lua/json/decode/array.lua new file mode 100644 index 0000000..d7e823a --- /dev/null +++ b/luajson-1.2.1/lua/json/decode/array.lua
@@ -0,0 +1,64 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local lpeg = require("lpeg") + +local util = require("json.decode.util") +local jsonutil = require("json.util") + +local table_maxn = require("table").maxn + +local unpack = unpack + +module("json.decode.array") + +-- Utility function to help manage slighly sparse arrays +local function processArray(array) + local max_n = table_maxn(array) + -- Only populate 'n' if it is necessary + if #array ~= max_n then + array.n = max_n + end + if jsonutil.InitArray then + array = jsonutil.InitArray(array) or array + end + return array +end + +local defaultOptions = { + trailingComma = true +} + +default = nil -- Let the buildCapture optimization take place +strict = { + trailingComma = false +} + +local function buildCapture(options, global_options) + local ignored = global_options.ignored + -- arrayItem == element + local arrayItem = lpeg.V(util.types.VALUE) + local arrayElements = lpeg.Ct(arrayItem * (ignored * lpeg.P(',') * ignored * arrayItem)^0 + 0) / processArray + + options = options and jsonutil.merge({}, defaultOptions, options) or defaultOptions + local capture = lpeg.P("[") + capture = capture * ignored + * arrayElements * ignored + if options.trailingComma then + capture = capture * (lpeg.P(",") + 0) * ignored + end + capture = capture * lpeg.P("]") + return capture +end + +function register_types() + util.register_type("ARRAY") +end + +function load_types(options, global_options, grammar) + local capture = buildCapture(options, global_options) + local array_id = util.types.ARRAY + grammar[array_id] = capture + util.append_grammar_item(grammar, "VALUE", lpeg.V(array_id)) +end
diff --git a/luajson-1.2.1/lua/json/decode/calls.lua b/luajson-1.2.1/lua/json/decode/calls.lua new file mode 100644 index 0000000..4f9c8a0 --- /dev/null +++ b/luajson-1.2.1/lua/json/decode/calls.lua
@@ -0,0 +1,116 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local lpeg = require("lpeg") +local tostring = tostring +local pairs, ipairs = pairs, ipairs +local next, type = next, type +local error = error + +local util = require("json.decode.util") + +local buildCall = require("json.util").buildCall + +local getmetatable = getmetatable + +module("json.decode.calls") + +local defaultOptions = { + defs = nil, + -- By default, do not allow undefined calls to be de-serialized as call objects + allowUndefined = false +} + +-- No real default-option handling needed... +default = nil +strict = nil + +local isPattern +if lpeg.type then + function isPattern(value) + return lpeg.type(value) == 'pattern' + end +else + local metaAdd = getmetatable(lpeg.P("")).__add + function isPattern(value) + return getmetatable(value).__add == metaAdd + end +end + +local function buildDefinedCaptures(argumentCapture, defs) + local callCapture + if not defs then return end + for name, func in pairs(defs) do + if type(name) ~= 'string' and not isPattern(name) then + error("Invalid functionCalls name: " .. tostring(name) .. " not a string or LPEG pattern") + end + -- Allow boolean or function to match up w/ encoding permissions + if type(func) ~= 'boolean' and type(func) ~= 'function' then + error("Invalid functionCalls item: " .. name .. " not a function") + end + local nameCallCapture + if type(name) == 'string' then + nameCallCapture = lpeg.P(name .. "(") * lpeg.Cc(name) + else + -- Name matcher expected to produce a capture + nameCallCapture = name * "(" + end + -- Call func over nameCallCapture and value to permit function receiving name + + -- Process 'func' if it is not a function + if type(func) == 'boolean' then + local allowed = func + func = function(name, ...) + if not allowed then + error("Function call on '" .. name .. "' not permitted") + end + return buildCall(name, ...) + end + else + local inner_func = func + func = function(...) + return (inner_func(...)) + end + end + local newCapture = (nameCallCapture * argumentCapture) / func * ")" + if not callCapture then + callCapture = newCapture + else + callCapture = callCapture + newCapture + end + end + return callCapture +end + +local function buildCapture(options) + if not options -- No ops, don't bother to parse + or not (options.defs and (nil ~= next(options.defs)) or options.allowUndefined) then + return nil + end + -- Allow zero or more arguments separated by commas + local value = lpeg.V(util.types.VALUE) + local argumentCapture = (value * (lpeg.P(",") * value)^0) + 0 + local callCapture = buildDefinedCaptures(argumentCapture, options.defs) + if options.allowUndefined then + local function func(name, ...) + return buildCall(name, ...) + end + -- Identifier-type-match + local nameCallCapture = lpeg.C(util.identifier) * "(" + local newCapture = (nameCallCapture * argumentCapture) / func * ")" + if not callCapture then + callCapture = newCapture + else + callCapture = callCapture + newCapture + end + end + return callCapture +end + +function load_types(options, global_options, grammar) + local capture = buildCapture(options, global_options) + if capture then + util.append_grammar_item(grammar, "VALUE", capture) + end +end
diff --git a/luajson-1.2.1/lua/json/decode/number.lua b/luajson-1.2.1/lua/json/decode/number.lua new file mode 100644 index 0000000..efc7fd6 --- /dev/null +++ b/luajson-1.2.1/lua/json/decode/number.lua
@@ -0,0 +1,85 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local lpeg = require("lpeg") +local tonumber = tonumber +local merge = require("json.util").merge +local util = require("json.decode.util") + +module("json.decode.number") + +local digit = lpeg.R("09") +local digits = digit^1 + +int = (lpeg.P('-') + 0) * (lpeg.R("19") * digits + digit) +local int = int + +local frac = lpeg.P('.') * digits + +local exp = lpeg.S("Ee") * (lpeg.S("-+") + 0) * digits + +local nan = lpeg.S("Nn") * lpeg.S("Aa") * lpeg.S("Nn") +local inf = lpeg.S("Ii") * lpeg.P("nfinity") +local ninf = lpeg.P('-') * lpeg.S("Ii") * lpeg.P("nfinity") +local hex = (lpeg.P("0x") + lpeg.P("0X")) * lpeg.R("09","AF","af")^1 + +local defaultOptions = { + nan = true, + inf = true, + frac = true, + exp = true, + hex = false +} + +default = nil -- Let the buildCapture optimization take place +strict = { + nan = false, + inf = false +} + +local nan_value = 0/0 +local inf_value = 1/0 +local ninf_value = -1/0 + +--[[ + Options: configuration options for number rules + nan: match NaN + inf: match Infinity + frac: match fraction portion (.0) + exp: match exponent portion (e1) + DEFAULT: nan, inf, frac, exp +]] +local function buildCapture(options) + options = options and merge({}, defaultOptions, options) or defaultOptions + local ret = int + if options.frac then + ret = ret * (frac + 0) + end + if options.exp then + ret = ret * (exp + 0) + end + if options.hex then + ret = hex + ret + end + -- Capture number now + ret = ret / tonumber + if options.nan then + ret = ret + nan / function() return nan_value end + end + if options.inf then + ret = ret + ninf / function() return ninf_value end + inf / function() return inf_value end + end + return ret +end + +function register_types() + util.register_type("INTEGER") +end + +function load_types(options, global_options, grammar) + local integer_id = util.types.INTEGER + local capture = buildCapture(options) + util.append_grammar_item(grammar, "VALUE", capture) + grammar[integer_id] = int / tonumber +end
diff --git a/luajson-1.2.1/lua/json/decode/object.lua b/luajson-1.2.1/lua/json/decode/object.lua new file mode 100644 index 0000000..94b699d --- /dev/null +++ b/luajson-1.2.1/lua/json/decode/object.lua
@@ -0,0 +1,103 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local lpeg = require("lpeg") + +local util = require("json.decode.util") +local merge = require("json.util").merge + +local tonumber = tonumber +local unpack = unpack +local print = print +local tostring = tostring + +local rawset = rawset + +module("json.decode.object") + +-- BEGIN LPEG < 0.9 SUPPORT +local initObject, applyObjectKey +if not (lpeg.Cg and lpeg.Cf and lpeg.Ct) then + function initObject() + return {} + end + function applyObjectKey(tab, key, val) + tab[key] = val + return tab + end +end +-- END LPEG < 0.9 SUPPORT + +local defaultOptions = { + number = true, + identifier = true, + trailingComma = true +} + +default = nil -- Let the buildCapture optimization take place + +strict = { + number = false, + identifier = false, + trailingComma = false +} + +local function buildItemSequence(objectItem, ignored) + return (objectItem * (ignored * lpeg.P(",") * ignored * objectItem)^0) + 0 +end + +local function buildCapture(options, global_options) + local ignored = global_options.ignored + local string_type = lpeg.V(util.types.STRING) + local integer_type = lpeg.V(util.types.INTEGER) + local value_type = lpeg.V(util.types.VALUE) + options = options and merge({}, defaultOptions, options) or defaultOptions + local key = string_type + if options.identifier then + key = key + lpeg.C(util.identifier) + end + if options.number then + key = key + integer_type + end + local objectItems + local objectItem = (key * ignored * lpeg.P(":") * ignored * value_type) + -- BEGIN LPEG < 0.9 SUPPORT + if not (lpeg.Cg and lpeg.Cf and lpeg.Ct) then + local set_key = applyObjectKey + if options.setObjectKey then + local setObjectKey = options.setObjectKey + set_key = function(tab, key, val) + setObjectKey(tab, key, val) + return tab + end + end + + objectItems = buildItemSequence(objectItem / set_key, ignored) + objectItems = lpeg.Ca(lpeg.Cc(false) / initObject * objectItems) + -- END LPEG < 0.9 SUPPORT + else + objectItems = buildItemSequence(lpeg.Cg(objectItem), ignored) + objectItems = lpeg.Cf(lpeg.Ct(0) * objectItems, options.setObjectKey or rawset) + end + + + local capture = lpeg.P("{") * ignored + capture = capture * objectItems * ignored + if options.trailingComma then + capture = capture * (lpeg.P(",") + 0) * ignored + end + capture = capture * lpeg.P("}") + return capture +end + +function register_types() + util.register_type("OBJECT") +end + +function load_types(options, global_options, grammar) + local capture = buildCapture(options, global_options) + local object_id = util.types.OBJECT + grammar[object_id] = capture + util.append_grammar_item(grammar, "VALUE", lpeg.V(object_id)) +end
diff --git a/luajson-1.2.1/lua/json/decode/others.lua b/luajson-1.2.1/lua/json/decode/others.lua new file mode 100644 index 0000000..01d60db --- /dev/null +++ b/luajson-1.2.1/lua/json/decode/others.lua
@@ -0,0 +1,54 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local lpeg = require("lpeg") +local jsonutil = require("json.util") +local util = require("json.decode.util") + +local rawset = rawset + +-- Container module for other JavaScript types (bool, null, undefined) +module("json.decode.others") + +-- For null and undefined, use the util.null value to preserve null-ness +local booleanCapture = + lpeg.P("true") * lpeg.Cc(true) + + lpeg.P("false") * lpeg.Cc(false) + +local nullCapture = lpeg.P("null") +local undefinedCapture = lpeg.P("undefined") + +local defaultOptions = { + allowUndefined = true, + null = jsonutil.null, + undefined = jsonutil.undefined, + setObjectKey = rawset +} + +default = nil -- Let the buildCapture optimization take place +simple = { + null = false, -- Mapped to nil + undefined = false -- Mapped to nil +} +strict = { + allowUndefined = false +} + +local function buildCapture(options) + -- The 'or nil' clause allows false to map to a nil value since 'nil' cannot be merged + options = options and jsonutil.merge({}, defaultOptions, options) or defaultOptions + local valueCapture = ( + booleanCapture + + nullCapture * lpeg.Cc(options.null or nil) + ) + if options.allowUndefined then + valueCapture = valueCapture + undefinedCapture * lpeg.Cc(options.undefined or nil) + end + return valueCapture +end + +function load_types(options, global_options, grammar) + local capture = buildCapture(options) + util.append_grammar_item(grammar, "VALUE", capture) +end
diff --git a/luajson-1.2.1/lua/json/decode/strings.lua b/luajson-1.2.1/lua/json/decode/strings.lua new file mode 100644 index 0000000..f092558 --- /dev/null +++ b/luajson-1.2.1/lua/json/decode/strings.lua
@@ -0,0 +1,130 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local lpeg = require("lpeg") +local util = require("json.decode.util") +local merge = require("json.util").merge + +local tonumber = tonumber +local string_char = require("string").char +local floor = require("math").floor +local table_concat = require("table").concat + +local error = error +module("json.decode.strings") +local function get_error(item) + local fmt_string = item .. " in string [%q] @ %i:%i" + return function(data, index) + local line, line_index, bad_char, last_line = util.get_invalid_character_info(data, index) + local err = fmt_string:format(bad_char, line, line_index) + error(err) + end +end + +local bad_unicode = get_error("Illegal unicode escape") +local bad_hex = get_error("Illegal hex escape") +local bad_character = get_error("Illegal character") +local bad_escape = get_error("Illegal escape") + +local knownReplacements = { + ["'"] = "'", + ['"'] = '"', + ['\\'] = '\\', + ['/'] = '/', + b = '\b', + f = '\f', + n = '\n', + r = '\r', + t = '\t', + v = '\v', + z = '\z' +} + +-- according to the table at http://da.wikipedia.org/wiki/UTF-8 +local function utf8DecodeUnicode(code1, code2) + code1, code2 = tonumber(code1, 16), tonumber(code2, 16) + if code1 == 0 and code2 < 0x80 then + return string_char(code2) + end + if code1 < 0x08 then + return string_char( + 0xC0 + code1 * 4 + floor(code2 / 64), + 0x80 + code2 % 64) + end + return string_char( + 0xE0 + floor(code1 / 16), + 0x80 + (code1 % 16) * 4 + floor(code2 / 64), + 0x80 + code2 % 64) +end + +local function decodeX(code) + code = tonumber(code, 16) + return string_char(code) +end + +local doSimpleSub = lpeg.C(lpeg.S("'\"\\/bfnrtvz")) / knownReplacements +local doUniSub = lpeg.P('u') * (lpeg.C(util.hexpair) * lpeg.C(util.hexpair) + lpeg.P(bad_unicode)) +local doXSub = lpeg.P('x') * (lpeg.C(util.hexpair) + lpeg.P(bad_hex)) + +local defaultOptions = { + badChars = '', + additionalEscapes = false, -- disallow untranslated escapes + escapeCheck = #lpeg.S('bfnrtv/\\"xu\'z'), -- no check on valid characters + decodeUnicode = utf8DecodeUnicode, + strict_quotes = false +} + +default = nil -- Let the buildCapture optimization take place + +strict = { + badChars = '\b\f\n\r\t\v', + additionalEscapes = false, -- no additional escapes + escapeCheck = #lpeg.S('bfnrtv/\\"u'), --only these chars are allowed to be escaped + strict_quotes = true +} + +local function buildCaptureString(quote, badChars, escapeMatch) + local captureChar = (1 - lpeg.S("\\" .. badChars .. quote)) + (lpeg.P("\\") / "" * escapeMatch) + captureChar = captureChar + (-#lpeg.P(quote) * lpeg.P(bad_character)) + local captureString = captureChar^0 + return lpeg.P(quote) * lpeg.Cs(captureString) * lpeg.P(quote) +end + +local function buildCapture(options) + options = options and merge({}, defaultOptions, options) or defaultOptions + local quotes = { '"' } + if not options.strict_quotes then + quotes[#quotes + 1] = "'" + end + local escapeMatch = doSimpleSub + escapeMatch = escapeMatch + doXSub / decodeX + escapeMatch = escapeMatch + doUniSub / options.decodeUnicode + if options.additionalEscapes then + escapeMatch = escapeMatch + options.additionalEscapes + end + if options.escapeCheck then + escapeMatch = options.escapeCheck * escapeMatch + lpeg.P(bad_escape) + end + local captureString + for i = 1, #quotes do + local cap = buildCaptureString(quotes[i], options.badChars, escapeMatch) + if captureString == nil then + captureString = cap + else + captureString = captureString + cap + end + end + return captureString +end + +function register_types() + util.register_type("STRING") +end + +function load_types(options, global_options, grammar) + local capture = buildCapture(options) + local string_id = util.types.STRING + grammar[string_id] = capture + util.append_grammar_item(grammar, "VALUE", lpeg.V(string_id)) +end
diff --git a/luajson-1.2.1/lua/json/decode/util.lua b/luajson-1.2.1/lua/json/decode/util.lua new file mode 100644 index 0000000..f34335c --- /dev/null +++ b/luajson-1.2.1/lua/json/decode/util.lua
@@ -0,0 +1,98 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local lpeg = require("lpeg") +local select = select +local pairs, ipairs = pairs, ipairs +local tonumber = tonumber +local string_char = require("string").char +local rawset = rawset + +local error = error +local setmetatable = setmetatable + +module("json.decode.util") + +-- 09, 0A, 0B, 0C, 0D, 20 +ascii_space = lpeg.S("\t\n\v\f\r ") +do + local chr = string_char + local u_space = ascii_space + -- \u0085 \u00A0 + u_space = u_space + lpeg.P(chr(0xC2)) * lpeg.S(chr(0x85) .. chr(0xA0)) + -- \u1680 \u180E + u_space = u_space + lpeg.P(chr(0xE1)) * (lpeg.P(chr(0x9A, 0x80)) + chr(0xA0, 0x8E)) + -- \u2000 - \u200A, also 200B + local spacing_end = "" + for i = 0x80,0x8b do + spacing_end = spacing_end .. chr(i) + end + -- \u2028 \u2029 \u202F + spacing_end = spacing_end .. chr(0xA8) .. chr(0xA9) .. chr(0xAF) + u_space = u_space + lpeg.P(chr(0xE2, 0x80)) * lpeg.S(spacing_end) + -- \u205F + u_space = u_space + lpeg.P(chr(0xE2, 0x81, 0x9F)) + -- \u3000 + u_space = u_space + lpeg.P(chr(0xE3, 0x80, 0x80)) + -- BOM \uFEFF + u_space = u_space + lpeg.P(chr(0xEF, 0xBB, 0xBF)) + _M.unicode_space = u_space +end + +identifier = lpeg.R("AZ","az","__") * lpeg.R("AZ","az", "__", "09") ^0 + +hex = lpeg.R("09","AF","af") +hexpair = hex * hex + +comments = { + cpp = lpeg.P("//") * (1 - lpeg.P("\n"))^0 * lpeg.P("\n"), + c = lpeg.P("/*") * (1 - lpeg.P("*/"))^0 * lpeg.P("*/") +} + +comment = comments.cpp + comments.c + +ascii_ignored = (ascii_space + comment)^0 + +unicode_ignored = (unicode_space + comment)^0 + +local types = setmetatable({false}, { + __index = function(self, k) + error("Unknown type: " .. k) + end +}) + +function register_type(name) + types[#types + 1] = name + types[name] = #types + return #types +end + +_M.types = types + +function append_grammar_item(grammar, name, capture) + local id = types[name] + local original = grammar[id] + if original then + grammar[id] = original + capture + else + grammar[id] = capture + end +end + +-- Parse the lpeg version skipping patch-values +-- LPEG <= 0.7 have no version value... so 0.7 is value +DecimalLpegVersion = lpeg.version and tonumber(lpeg.version():match("^(%d+%.%d+)")) or 0.7 + +function get_invalid_character_info(input, index) + local parsed = input:sub(1, index) + local bad_character = input:sub(index, index) + local _, line_number = parsed:gsub('\n',{}) + local last_line = parsed:match("\n([^\n]+.)$") or parsed + return line_number, #last_line, bad_character, last_line +end + +function setObjectKeyForceNumber(t, key, value) + key = tonumber(key) or key + return rawset(t, key, value) +end
diff --git a/luajson-1.2.1/lua/json/encode.lua b/luajson-1.2.1/lua/json/encode.lua new file mode 100644 index 0000000..961872d --- /dev/null +++ b/luajson-1.2.1/lua/json/encode.lua
@@ -0,0 +1,159 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local type = type +local assert, error = assert, error +local getmetatable, setmetatable = getmetatable, setmetatable +local util = require("json.util") + +local ipairs, pairs = ipairs, pairs +local require = require + +local output = require("json.encode.output") + +local util = require("json.util") +local util_merge, isCall = util.merge, util.isCall + +module("json.encode") + +--[[ + List of encoding modules to load. + Loaded in sequence such that earlier encoders get priority when + duplicate type-handlers exist. +]] +local modulesToLoad = { + "strings", + "number", + "calls", + "others", + "array", + "object" +} +-- Modules that have been loaded +local loadedModules = {} + +-- Default configuration options to apply +local defaultOptions = {} +-- Configuration bases for client apps +default = nil +strict = { + initialObject = true -- Require an object at the root +} + +-- For each module, load it and its defaults +for _,name in ipairs(modulesToLoad) do + local mod = require("json.encode." .. name) + defaultOptions[name] = mod.default + strict[name] = mod.strict + loadedModules[name] = mod +end + +-- Merges values, assumes all tables are arrays, inner values flattened, optionally constructing output +local function flattenOutput(out, values) + out = not out and {} or type(out) == 'table' and out or {out} + if type(values) == 'table' then + for _, v in ipairs(values) do + out[#out + 1] = v + end + else + out[#out + 1] = values + end + return out +end + +-- Prepares the encoding map from the already provided modules and new config +local function prepareEncodeMap(options) + local map = {} + for _, name in ipairs(modulesToLoad) do + local encodermap = loadedModules[name].getEncoder(options[name]) + for valueType, encoderSet in pairs(encodermap) do + map[valueType] = flattenOutput(map[valueType], encoderSet) + end + end + return map +end + +--[[ + Encode a value with a given encoding map and state +]] +local function encodeWithMap(value, map, state) + local t = type(value) + local encoderList = assert(map[t], "Failed to encode value, unhandled type: " .. t) + for _, encoder in ipairs(encoderList) do + local ret = encoder(value, state) + if false ~= ret then + return ret + end + end + error("Failed to encode value, encoders for " .. t .. " deny encoding") +end + + +local function getBaseEncoder(options) + local encoderMap = prepareEncodeMap(options) + if options.preProcess then + local preProcess = options.preProcess + return function(value, state) + local ret = preProcess(value) + if nil ~= ret then + value = ret + end + return encodeWithMap(value, encoderMap, state) + end + end + return function(value, state) + return encodeWithMap(value, encoderMap, state) + end +end +--[[ + Retreive an initial encoder instance based on provided options + the initial encoder is responsible for initializing state + State has at least these values configured: encode, check_unique, already_encoded +]] +function getEncoder(options) + options = options and util_merge({}, defaultOptions, options) or defaultOptions + local encode = getBaseEncoder(options) + + local function initialEncode(value) + if options.initialObject then + local errorMessage = "Invalid arguments: expects a JSON Object or Array at the root" + assert(type(value) == 'table' and not isCall(value, options), errorMessage) + end + + local alreadyEncoded = {} + local function check_unique(value) + assert(not alreadyEncoded[value], "Recursive encoding of value") + alreadyEncoded[value] = true + end + + local outputEncoder = options.output and options.output() or output.getDefault() + local state = { + encode = encode, + check_unique = check_unique, + already_encoded = alreadyEncoded, -- To unmark encoding when moving up stack + outputEncoder = outputEncoder + } + local ret = encode(value, state) + if nil ~= ret then + return outputEncoder.simple and outputEncoder.simple(ret) or ret + end + end + return initialEncode +end + +-- CONSTRUCT STATE WITH FOLLOWING (at least) +--[[ + encoder + check_unique -- used by inner encoders to make sure value is unique + already_encoded -- used to unmark a value as unique +]] +function encode(data, options) + return getEncoder(options)(data) +end + +local mt = getmetatable(_M) or {} +mt.__call = function(self, ...) + return encode(...) +end +setmetatable(_M, mt)
diff --git a/luajson-1.2.1/lua/json/encode/array.lua b/luajson-1.2.1/lua/json/encode/array.lua new file mode 100644 index 0000000..45e300c --- /dev/null +++ b/luajson-1.2.1/lua/json/encode/array.lua
@@ -0,0 +1,99 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local jsonutil = require("json.util") + +local type = type +local pairs = pairs +local assert = assert + +local table = require("table") +local math = require("math") +local table_concat = table.concat +local math_floor, math_modf = math.floor, math.modf + +local util_merge = require("json.util").merge +local util_IsArray = require("json.util").IsArray + +module("json.encode.array") + +local defaultOptions = { + isArray = util_IsArray +} + +default = nil +strict = nil + +--[[ + Utility function to determine whether a table is an array or not. + Criteria for it being an array: + * ExternalIsArray returns true (or false directly reports not-array) + * If the table has an 'n' value that is an integer >= 1 then it + is an array... may result in false positives (should check some values + before it) + * It is a contiguous list of values with zero string-based keys +]] +function isArray(val, options) + local externalIsArray = options and options.isArray + + if externalIsArray then + local ret = externalIsArray(val) + if ret == true or ret == false then + return ret + end + end + -- Use the 'n' element if it's a number + if type(val.n) == 'number' and math_floor(val.n) == val.n and val.n >= 1 then + return true + end + local len = #val + for k,v in pairs(val) do + if type(k) ~= 'number' then + return false + end + local _, decim = math_modf(k) + if not (decim == 0 and 1<=k) then + return false + end + if k > len then -- Use Lua's length as absolute determiner + return false + end + end + + return true +end + +--[[ + Cleanup function to unmark a value as in the encoding process and return + trailing results +]] +local function unmarkAfterEncode(tab, state, ...) + state.already_encoded[tab] = nil + return ... +end +function getEncoder(options) + options = options and util_merge({}, defaultOptions, options) or defaultOptions + local function encodeArray(tab, state) + if not isArray(tab, options) then + return false + end + -- Make sure this value hasn't been encoded yet + state.check_unique(tab) + local encode = state.encode + local compositeEncoder = state.outputEncoder.composite + local valueEncoder = [[ + for i = 1, (composite.n or #composite) do + local val = composite[i] + PUTINNER(i ~= 1) + val = encode(val, state) + val = val or '' + if val then + PUTVALUE(val) + end + end + ]] + return unmarkAfterEncode(tab, state, compositeEncoder(valueEncoder, '[', ']', ',', tab, encode, state)) + end + return { table = encodeArray } +end
diff --git a/luajson-1.2.1/lua/json/encode/calls.lua b/luajson-1.2.1/lua/json/encode/calls.lua new file mode 100644 index 0000000..c1cc646 --- /dev/null +++ b/luajson-1.2.1/lua/json/encode/calls.lua
@@ -0,0 +1,61 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local jsonutil = require("json.util") + +local table = require("table") +local table_concat = table.concat + +local select = select +local getmetatable, setmetatable = getmetatable, setmetatable +local assert = assert + +local util = require("json.util") + +local util_merge, isCall, decodeCall = util.merge, util.isCall, util.decodeCall + +module("json.encode.calls") + + +local defaultOptions = { +} + +-- No real default-option handling needed... +default = nil +strict = nil + + +--[[ + Encodes 'value' as a function call + Must have parameters in the 'callData' field of the metatable + name == name of the function call + parameters == array of parameters to encode +]] +function getEncoder(options) + options = options and util_merge({}, defaultOptions, options) or defaultOptions + local function encodeCall(value, state) + if not isCall(value) then + return false + end + local encode = state.encode + local name, params = decodeCall(value) + local compositeEncoder = state.outputEncoder.composite + local valueEncoder = [[ + for i = 1, (composite.n or #composite) do + local val = composite[i] + PUTINNER(i ~= 1) + val = encode(val, state) + val = val or '' + if val then + PUTVALUE(val) + end + end + ]] + return compositeEncoder(valueEncoder, name .. '(', ')', ',', params, encode, state) + end + return { + table = encodeCall, + ['function'] = encodeCall + } +end
diff --git a/luajson-1.2.1/lua/json/encode/number.lua b/luajson-1.2.1/lua/json/encode/number.lua new file mode 100644 index 0000000..62d5765 --- /dev/null +++ b/luajson-1.2.1/lua/json/encode/number.lua
@@ -0,0 +1,46 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local tostring = tostring +local assert = assert +local util = require("json.util") +local huge = require("math").huge + +module("json.encode.number") + +local defaultOptions = { + nan = true, + inf = true +} + +default = nil -- Let the buildCapture optimization take place +strict = { + nan = false, + inf = false +} + +local function encodeNumber(number, options) + if number ~= number then + assert(options.nan, "Invalid number: NaN not enabled") + return "NaN" + end + if number == huge then + assert(options.inf, "Invalid number: Infinity not enabled") + return "Infinity" + end + if number == -huge then + assert(options.inf, "Invalid number: Infinity not enabled") + return "-Infinity" + end + return tostring(number) +end + +function getEncoder(options) + options = options and util.merge({}, defaultOptions, options) or defaultOptions + return { + number = function(number, state) + return encodeNumber(number, options) + end + } +end
diff --git a/luajson-1.2.1/lua/json/encode/object.lua b/luajson-1.2.1/lua/json/encode/object.lua new file mode 100644 index 0000000..262742d --- /dev/null +++ b/luajson-1.2.1/lua/json/encode/object.lua
@@ -0,0 +1,67 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local pairs = pairs +local assert = assert + +local type = type +local tostring = tostring + +local table_concat = require("table").concat +local util_merge = require("json.util").merge + +module("json.encode.object") + +local defaultOptions = { +} + +default = nil +strict = nil + +--[[ + Cleanup function to unmark a value as in the encoding process and return + trailing results +]] +local function unmarkAfterEncode(tab, state, ...) + state.already_encoded[tab] = nil + return ... +end +--[[ + Encode a table as a JSON Object ( keys = strings, values = anything else ) +]] +local function encodeTable(tab, options, state) + -- Make sure this value hasn't been encoded yet + state.check_unique(tab) + local encode = state.encode + local compositeEncoder = state.outputEncoder.composite + local valueEncoder = [[ + local first = true + for k, v in pairs(composite) do + local ti = type(k) + assert(ti == 'string' or ti == 'number' or ti == 'boolean', "Invalid object index type: " .. ti) + local name = encode(tostring(k), state) + if first then + first = false + else + name = ',' .. name + end + PUTVALUE(name .. ':') + local val = encode(v, state) + val = val or '' + if val then + PUTVALUE(val) + end + end + ]] + return unmarkAfterEncode(tab, state, compositeEncoder(valueEncoder, '{', '}', nil, tab, encode, state)) +end + +function getEncoder(options) + options = options and util_merge({}, defaultOptions, options) or defaultOptions + return { + table = function(tab, state) + return encodeTable(tab, options, state) + end + } +end
diff --git a/luajson-1.2.1/lua/json/encode/others.lua b/luajson-1.2.1/lua/json/encode/others.lua new file mode 100644 index 0000000..ea2c88f --- /dev/null +++ b/luajson-1.2.1/lua/json/encode/others.lua
@@ -0,0 +1,55 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local tostring = tostring + +local assert = assert +local jsonutil = require("json.util") +local util_merge = require("json.util").merge +local type = type + +module("json.encode.others") + +-- Shortcut that works +encodeBoolean = tostring + +local defaultOptions = { + allowUndefined = true, + null = jsonutil.null, + undefined = jsonutil.undefined +} + +default = nil -- Let the buildCapture optimization take place +strict = { + allowUndefined = false +} + +function getEncoder(options) + options = options and util_merge({}, defaultOptions, options) or defaultOptions + local function encodeOthers(value, state) + if value == options.null then + return 'null' + elseif value == options.undefined then + assert(options.allowUndefined, "Invalid value: Unsupported 'Undefined' parameter") + return 'undefined' + else + return false + end + end + local function encodeBoolean(value, state) + return value and 'true' or 'false' + end + local nullType = type(options.null) + local undefinedType = options.undefined and type(options.undefined) + -- Make sure that all of the types handled here are handled + local ret = { + boolean = encodeBoolean, + ['nil'] = function() return 'null' end, + [nullType] = encodeOthers + } + if undefinedType then + ret[undefinedType] = encodeOthers + end + return ret +end
diff --git a/luajson-1.2.1/lua/json/encode/output.lua b/luajson-1.2.1/lua/json/encode/output.lua new file mode 100644 index 0000000..a5dbd79 --- /dev/null +++ b/luajson-1.2.1/lua/json/encode/output.lua
@@ -0,0 +1,84 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local type = type +local assert, error = assert, error +local table_concat = require("table").concat +local loadstring = loadstring + +local io = require("io") + +local setmetatable = setmetatable + +local output_utility = require("json.encode.output_utility") + +module("json.encode.output") + +local tableCompositeCache = setmetatable({}, {__mode = 'v'}) + +local TABLE_VALUE_WRITER = [[ + ret[#ret + 1] = %VALUE% +]] + +local TABLE_INNER_WRITER = "" + +--[[ + nextValues can output a max of two values to throw into the data stream + expected to be called until nil is first return value + value separator should either be attached to v1 or in innerValue +]] +local function defaultTableCompositeWriter(nextValues, beginValue, closeValue, innerValue, composite, encode, state) + if type(nextValues) == 'string' then + local fun = output_utility.prepareEncoder(defaultTableCompositeWriter, nextValues, innerValue, TABLE_VALUE_WRITER, TABLE_INNER_WRITER) + local ret = {} + fun(composite, ret, encode, state) + return beginValue .. table_concat(ret, innerValue) .. closeValue + end +end + +-- no 'simple' as default action is just to return the value +function getDefault() + return { composite = defaultTableCompositeWriter } +end + +-- BEGIN IO-WRITER OUTPUT +local IO_INNER_WRITER = [[ + if %WRITE_INNER% then + state.__outputFile:write(%INNER_VALUE%) + end +]] +local IO_VALUE_WRITER = [[ + state.__outputFile:write(%VALUE%) +]] + +local function buildIoWriter(output) + if not output then -- Default to stdout + output = io.output() + end + local function ioWriter(nextValues, beginValue, closeValue, innerValue, composite, encode, state) + -- HOOK OUTPUT STATE + state.__outputFile = output + if type(nextValues) == 'string' then + local fun = output_utility.prepareEncoder(ioWriter, nextValues, innerValue, IO_VALUE_WRITER, IO_INNER_WRITER) + local ret = {} + output:write(beginValue) + fun(composite, ret, encode, state) + output:write(closeValue) + return nil + end + end + + local function ioSimpleWriter(encoded) + if encoded then + output:write(encoded) + end + return nil + end + return { composite = ioWriter, simple = ioSimpleWriter } +end +function getIoWriter(output) + return function() + return buildIoWriter(output) + end +end
diff --git a/luajson-1.2.1/lua/json/encode/output_utility.lua b/luajson-1.2.1/lua/json/encode/output_utility.lua new file mode 100644 index 0000000..b8d3573 --- /dev/null +++ b/luajson-1.2.1/lua/json/encode/output_utility.lua
@@ -0,0 +1,48 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local setmetatable = setmetatable +local assert, loadstring = assert, loadstring + +module("json.encode.output_utility") + +-- Key == weak, if main key goes away, then cache cleared +local outputCache = setmetatable({}, {__mode = 'k'}) +-- TODO: inner tables weak? + +local function buildFunction(nextValues, innerValue, valueWriter, innerWriter) + local putInner = "" + if innerValue and innerWriter then + -- Prepare the lua-string representation of the separator to put in between values + local formattedInnerValue = ("%q"):format(innerValue) + -- Fill in the condition %WRITE_INNER% and the %INNER_VALUE% to actually write + putInner = innerWriter:gsub("%%WRITE_INNER%%", "%%1"):gsub("%%INNER_VALUE%%", formattedInnerValue) + end + -- Template-in the value writer (if present) and its conditional argument + local functionCode = nextValues:gsub("PUTINNER(%b())", putInner) + -- %VALUE% is to be filled in by the value-to-write + valueWriter = valueWriter:gsub("%%VALUE%%", "%%1") + -- Template-in the value writer with its argument + functionCode = functionCode:gsub("PUTVALUE(%b())", valueWriter) + functionCode = [[ + return function(composite, ret, encode, state) + ]] .. functionCode .. [[ + end + ]] + return assert(loadstring(functionCode))() +end + +function prepareEncoder(cacheKey, nextValues, innerValue, valueWriter, innerWriter) + local cache = outputCache[cacheKey] + if not cache then + cache = {} + outputCache[cacheKey] = cache + end + local fun = cache[nextValues] + if not fun then + fun = buildFunction(nextValues, innerValue, valueWriter, innerWriter) + cache[nextValues] = fun + end + return fun +end
diff --git a/luajson-1.2.1/lua/json/encode/strings.lua b/luajson-1.2.1/lua/json/encode/strings.lua new file mode 100644 index 0000000..8603305 --- /dev/null +++ b/luajson-1.2.1/lua/json/encode/strings.lua
@@ -0,0 +1,67 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local string_char = require("string").char +local pairs = pairs + +local util_merge = require("json.util").merge +module("json.encode.strings") + +local normalEncodingMap = { + ['"'] = '\\"', + ['\\'] = '\\\\', + ['/'] = '\\/', + ['\b'] = '\\b', + ['\f'] = '\\f', + ['\n'] = '\\n', + ['\r'] = '\\r', + ['\t'] = '\\t', + ['\v'] = '\\v' -- not in official spec, on report, removing +} + +local xEncodingMap = {} +for char, encoded in pairs(normalEncodingMap) do + xEncodingMap[char] = encoded +end + +-- Pre-encode the control characters to speed up encoding... +-- NOTE: UTF-8 may not work out right w/ JavaScript +-- JavaScript uses 2 bytes after a \u... yet UTF-8 is a +-- byte-stream encoding, not pairs of bytes (it does encode +-- some letters > 1 byte, but base case is 1) +for i = 0, 255 do + local c = string_char(i) + if c:match('[%z\1-\031\128-\255]') and not normalEncodingMap[c] then + -- WARN: UTF8 specializes values >= 0x80 as parts of sequences... + -- without \x encoding, do not allow encoding > 7F + normalEncodingMap[c] = ('\\u%.4X'):format(i) + xEncodingMap[c] = ('\\x%.2X'):format(i) + end +end + +local defaultOptions = { + xEncode = false, -- Encode single-bytes as \xXX + -- / is not required to be quoted but it helps with certain decoding + -- Required encoded characters, " \, and 00-1F (0 - 31) + encodeSet = '\\"/%z\1-\031', + encodeSetAppend = nil -- Chars to append to the default set +} + +default = nil +strict = nil + +function getEncoder(options) + options = options and util_merge({}, defaultOptions, options) or defaultOptions + local encodeSet = options.encodeSet + if options.encodeSetAppend then + encodeSet = encodeSet .. options.encodeSetAppend + end + local encodingMap = options.xEncode and xEncodingMap or normalEncodingMap + local function encodeString(s, state) + return '"' .. s:gsub('[' .. encodeSet .. ']', encodingMap) .. '"' + end + return { + string = encodeString + } +end
diff --git a/luajson-1.2.1/lua/json/util.lua b/luajson-1.2.1/lua/json/util.lua new file mode 100644 index 0000000..28e47ea --- /dev/null +++ b/luajson-1.2.1/lua/json/util.lua
@@ -0,0 +1,108 @@ +--[[ + Licensed according to the included 'LICENSE' document + Author: Thomas Harning Jr <harningt@gmail.com> +]] +local type = type +local print = print +local tostring = tostring +local pairs = pairs +local getmetatable, setmetatable = getmetatable, setmetatable +local select = select + +module("json.util") +local function foreach(tab, func) + for k, v in pairs(tab) do + func(k,v) + end +end +function printValue(tab, name) + local parsed = {} + local function doPrint(key, value, space) + space = space or '' + if type(value) == 'table' then + if parsed[value] then + print(space .. key .. '= <' .. parsed[value] .. '>') + else + parsed[value] = key + print(space .. key .. '= {') + space = space .. ' ' + foreach(value, function(key, value) doPrint(key, value, space) end) + end + else + if type(value) == 'string' then + value = '[[' .. tostring(value) .. ']]' + end + print(space .. key .. '=' .. tostring(value)) + end + end + doPrint(name, tab) +end + +function clone(t) + local ret = {} + for k,v in pairs(t) do + ret[k] = v + end + return ret +end + +local function merge(t, from, ...) + if not from then + return t + end + for k,v in pairs(from) do + t[k] = v + end + return merge(t, ...) +end +_M.merge = merge + +-- Function to insert nulls into the JSON stream +function null() + return null +end + +-- Marker for 'undefined' values +function undefined() + return undefined +end + +local ArrayMT = {} + +--[[ + Return's true if the metatable marks it as an array.. + Or false if it has no array component at all + Otherwise nil to get the normal detection component working +]] +function IsArray(value) + if type(value) ~= 'table' then return false end + local ret = getmetatable(value) == ArrayMT + if not ret then + if #value == 0 then return false end + else + return ret + end +end +function InitArray(array) + setmetatable(array, ArrayMT) + return array +end + +local CallMT = {} + +function isCall(value) + return CallMT == getmetatable(value) +end + +function buildCall(name, ...) + local callData = { + name = name, + parameters = {n = select('#', ...), ...} + } + return setmetatable(callData, CallMT) +end + +function decodeCall(callData) + if not isCall(callData) then return nil end + return callData.name, callData.parameters +end
diff --git a/luajson-1.2.1/rockspecs/luajson-0.10-1.rockspec b/luajson-1.2.1/rockspecs/luajson-0.10-1.rockspec new file mode 100644 index 0000000..efbe14b --- /dev/null +++ b/luajson-1.2.1/rockspecs/luajson-0.10-1.rockspec
@@ -0,0 +1,43 @@ +package = "luajson" +version = "0.10-1" +source = { + url = "http://luaforge.net/frs/download.php/3637/luajson-0.10.tar.bz2", + md5 = "0b6fa5e3a07daabe79241922b0bfda92" +} +description = { + summary = "customizable JSON decoder/encoder", + detailed = [[ + LuaJSON is a customizable JSON decoder/encoder using + LPEG for parsing. + ]], + homepage = "http://github.com/harningt/luajson", + maintainer = "Thomas Harning <harningt@gmail.com>", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1", + "lunit >= 0.4", + "lpeg >= 0.8.1" +} +build = { + type = "module", + modules = { + json = "src/json.lua", + ["json.util"] = "src/json/util.lua", + ["json.decode"] = "src/json/decode.lua", + ["json.decode.array"] = "src/json/decode/array.lua", + ["json.decode.calls"] = "src/json/decode/calls.lua", + ["json.decode.number"] = "src/json/decode/number.lua", + ["json.decode.object"] = "src/json/decode/object.lua", + ["json.decode.others"] = "src/json/decode/others.lua", + ["json.decode.strings"] = "src/json/decode/strings.lua", + ["json.decode.util"] = "src/json/decode/util.lua", + ["json.encode"] = "src/json/encode.lua", + ["json.encode.array"] = "src/json/encode/array.lua", + ["json.encode.calls"] = "src/json/encode/calls.lua", + ["json.encode.number"] = "src/json/encode/number.lua", + ["json.encode.object"] = "src/json/encode/object.lua", + ["json.encode.others"] = "src/json/encode/others.lua", + ["json.encode.strings"] = "src/json/encode/strings.lua" + } +}
diff --git a/luajson-1.2.1/rockspecs/luajson-0.10-2.rockspec b/luajson-1.2.1/rockspecs/luajson-0.10-2.rockspec new file mode 100644 index 0000000..c29df87 --- /dev/null +++ b/luajson-1.2.1/rockspecs/luajson-0.10-2.rockspec
@@ -0,0 +1,43 @@ +package = "luajson" +version = "0.10-2" +source = { + url = "http://luaforge.net/frs/download.php/3893/luajson-0.10.tar.bz2", + md5 = "0b6fa5e3a07daabe79241922b0bfda92" +} +description = { + summary = "customizable JSON decoder/encoder", + detailed = [[ + LuaJSON is a customizable JSON decoder/encoder using + LPEG for parsing. + ]], + homepage = "http://github.com/harningt/luajson", + maintainer = "Thomas Harning <harningt@gmail.com>", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1", + "lunit >= 0.4", + "lpeg >= 0.8.1" +} +build = { + type = "module", + modules = { + json = "src/json.lua", + ["json.util"] = "src/json/util.lua", + ["json.decode"] = "src/json/decode.lua", + ["json.decode.array"] = "src/json/decode/array.lua", + ["json.decode.calls"] = "src/json/decode/calls.lua", + ["json.decode.number"] = "src/json/decode/number.lua", + ["json.decode.object"] = "src/json/decode/object.lua", + ["json.decode.others"] = "src/json/decode/others.lua", + ["json.decode.strings"] = "src/json/decode/strings.lua", + ["json.decode.util"] = "src/json/decode/util.lua", + ["json.encode"] = "src/json/encode.lua", + ["json.encode.array"] = "src/json/encode/array.lua", + ["json.encode.calls"] = "src/json/encode/calls.lua", + ["json.encode.number"] = "src/json/encode/number.lua", + ["json.encode.object"] = "src/json/encode/object.lua", + ["json.encode.others"] = "src/json/encode/others.lua", + ["json.encode.strings"] = "src/json/encode/strings.lua" + } +}
diff --git a/luajson-1.2.1/rockspecs/luajson-0.9.1-1.rockspec b/luajson-1.2.1/rockspecs/luajson-0.9.1-1.rockspec new file mode 100644 index 0000000..64ba4b6 --- /dev/null +++ b/luajson-1.2.1/rockspecs/luajson-0.9.1-1.rockspec
@@ -0,0 +1,35 @@ +package = "luajson" +version = "0.9.1-1" +source = { + url = "http://luaforge.net/frs/download.php/3637/luajson-0.9.1.tar.bz2", + md5 = "49a6a3b7912a053a2b7ad6bbcf4d3564" +} +description = { + summary = "customizable JSON decoder/encoder", + detailed = [[ + LuaJSON is a customizable JSON decoder/encoder using + LPEG for parsing. + ]], + homepage = "http://gitrepo.or.cz/w/luajson.git", + maintainer = "Thomas Harning <harningt@gmail.com>", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1", + "lunit >= 0.4", + "lpeg >= 0.8.1" +} +build = { + type = "module", + modules = { + json = "src/json.lua", + ["json.util"] = "src/json/util.lua", + ["json.encode"] = "src/json/encode.lua", + ["json.decode"] = "src/json/decode.lua", + ["json.decode.array"] = "src/json/decode/array.lua", + ["json.decode.number"] = "src/json/decode/number.lua", + ["json.decode.object"] = "src/json/decode/object.lua", + ["json.decode.string"] = "src/json/decode/strings.lua", + ["json.decode.util"] = "src/json/decode/util.lua" + } +}
diff --git a/luajson-1.2.1/rockspecs/luajson-1.0-1.rockspec b/luajson-1.2.1/rockspecs/luajson-1.0-1.rockspec new file mode 100644 index 0000000..143f01d --- /dev/null +++ b/luajson-1.2.1/rockspecs/luajson-1.0-1.rockspec
@@ -0,0 +1,46 @@ +package = "luajson" +version = "1.0-1" +source = { + url = "http://luaforge.net/frs/download.php/4105/luajson-1.0.tar.bz2", + md5 = "0e3ee192f93d40c4947e828668828e91" +} +description = { + summary = "customizable JSON decoder/encoder", + detailed = [[ + LuaJSON is a customizable JSON decoder/encoder using + LPEG for parsing. + ]], + homepage = "http://github.com/harningt/luajson", + maintainer = "Thomas Harning <harningt@gmail.com>", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1", + "lunit >= 0.4", + "lpeg >= 0.8.1" +} +build = { + type = "module", + modules = { + ["json.decode.array"] = "lua/json/decode/array.lua", + ["json.decode.calls"] = "lua/json/decode/calls.lua", + ["json.decode.number"] = "lua/json/decode/number.lua", + ["json.decode.object"] = "lua/json/decode/object.lua", + ["json.decode.others"] = "lua/json/decode/others.lua", + ["json.decode.strings"] = "lua/json/decode/strings.lua", + ["json.decode.util"] = "lua/json/decode/util.lua", + ["json.decode"] = "lua/json/decode.lua", + ["json.encode.array"] = "lua/json/encode/array.lua", + ["json.encode.calls"] = "lua/json/encode/calls.lua", + ["json.encode.number"] = "lua/json/encode/number.lua", + ["json.encode.object"] = "lua/json/encode/object.lua", + ["json.encode.others"] = "lua/json/encode/others.lua", + ["json.encode.output"] = "lua/json/encode/output.lua", + ["json.encode.output_utility"] = "lua/json/encode/output_utility.lua", + ["json.encode.strings"] = "lua/json/encode/strings.lua", + ["json.encode"] = "lua/json/encode.lua", + ["json.util"] = "lua/json/util.lua", + ["json"] = "lua/json.lua" + } +} +
diff --git a/luajson-1.2.1/rockspecs/luajson-1.0.1-1.rockspec b/luajson-1.2.1/rockspecs/luajson-1.0.1-1.rockspec new file mode 100644 index 0000000..35584dc --- /dev/null +++ b/luajson-1.2.1/rockspecs/luajson-1.0.1-1.rockspec
@@ -0,0 +1,46 @@ +package = "luajson" +version = "1.0.1-1" +source = { + url = "http://luaforge.net/frs/download.php/4311/luajson-1.0.1.tar.bz2", + md5 = "f6d52689e0bc4cbbfffff29308e78812" +} +description = { + summary = "customizable JSON decoder/encoder", + detailed = [[ + LuaJSON is a customizable JSON decoder/encoder using + LPEG for parsing. + ]], + homepage = "http://github.com/harningt/luajson", + maintainer = "Thomas Harning <harningt@gmail.com>", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1", + "lunit >= 0.4", + "lpeg >= 0.8.1" +} +build = { + type = "module", + modules = { + ["json"] = "lua/json.lua", + ["json.decode"] = "lua/json/decode.lua", + ["json.decode.array"] = "lua/json/decode/array.lua", + ["json.decode.calls"] = "lua/json/decode/calls.lua", + ["json.decode.number"] = "lua/json/decode/number.lua", + ["json.decode.object"] = "lua/json/decode/object.lua", + ["json.decode.others"] = "lua/json/decode/others.lua", + ["json.decode.strings"] = "lua/json/decode/strings.lua", + ["json.decode.util"] = "lua/json/decode/util.lua", + ["json.encode"] = "lua/json/encode.lua", + ["json.encode.array"] = "lua/json/encode/array.lua", + ["json.encode.calls"] = "lua/json/encode/calls.lua", + ["json.encode.number"] = "lua/json/encode/number.lua", + ["json.encode.object"] = "lua/json/encode/object.lua", + ["json.encode.others"] = "lua/json/encode/others.lua", + ["json.encode.output"] = "lua/json/encode/output.lua", + ["json.encode.output_utility"] = "lua/json/encode/output_utility.lua", + ["json.encode.strings"] = "lua/json/encode/strings.lua", + ["json.util"] = "lua/json/util.lua" + } +} +
diff --git a/luajson-1.2.1/rockspecs/luajson-1.1-1.rockspec b/luajson-1.2.1/rockspecs/luajson-1.1-1.rockspec new file mode 100644 index 0000000..5be6026 --- /dev/null +++ b/luajson-1.2.1/rockspecs/luajson-1.1-1.rockspec
@@ -0,0 +1,46 @@ +package = "luajson" +version = "1.1-1" +source = { + url = "http://luaforge.net/frs/download.php/4312/luajson-1.1.tar.bz2", + md5 = "9c4d267b7383b54576ed307e451aefa4" +} +description = { + summary = "customizable JSON decoder/encoder", + detailed = [[ + LuaJSON is a customizable JSON decoder/encoder using + LPEG for parsing. + ]], + homepage = "http://github.com/harningt/luajson", + maintainer = "Thomas Harning <harningt@gmail.com>", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1", + "lunit >= 0.4", + "lpeg >= 0.8.1" +} +build = { + type = "module", + modules = { + ["json"] = "lua/json.lua", + ["json.decode"] = "lua/json/decode.lua", + ["json.decode.array"] = "lua/json/decode/array.lua", + ["json.decode.calls"] = "lua/json/decode/calls.lua", + ["json.decode.number"] = "lua/json/decode/number.lua", + ["json.decode.object"] = "lua/json/decode/object.lua", + ["json.decode.others"] = "lua/json/decode/others.lua", + ["json.decode.strings"] = "lua/json/decode/strings.lua", + ["json.decode.util"] = "lua/json/decode/util.lua", + ["json.encode"] = "lua/json/encode.lua", + ["json.encode.array"] = "lua/json/encode/array.lua", + ["json.encode.calls"] = "lua/json/encode/calls.lua", + ["json.encode.number"] = "lua/json/encode/number.lua", + ["json.encode.object"] = "lua/json/encode/object.lua", + ["json.encode.others"] = "lua/json/encode/others.lua", + ["json.encode.output"] = "lua/json/encode/output.lua", + ["json.encode.output_utility"] = "lua/json/encode/output_utility.lua", + ["json.encode.strings"] = "lua/json/encode/strings.lua", + ["json.util"] = "lua/json/util.lua" + } +} +
diff --git a/luajson-1.2.1/rockspecs/luajson-1.2-1.rockspec b/luajson-1.2.1/rockspecs/luajson-1.2-1.rockspec new file mode 100644 index 0000000..10755c3 --- /dev/null +++ b/luajson-1.2.1/rockspecs/luajson-1.2-1.rockspec
@@ -0,0 +1,46 @@ +package = "luajson" +version = "1.2-1" +source = { + url = "http://luaforge.net/frs/download.php/4672/luajson-1.2.tar.bz2", + md5 = "a80aa3c2d96d73afbf63f7146857e116" +} +description = { + summary = "customizable JSON decoder/encoder", + detailed = [[ + LuaJSON is a customizable JSON decoder/encoder using + LPEG for parsing. + ]], + homepage = "http://github.com/harningt/luajson", + maintainer = "Thomas Harning <harningt@gmail.com>", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1", + "lunit >= 0.4", + "lpeg >= 0.8.1" +} +build = { + type = "module", + modules = { + ["json"] = "lua/json.lua", + ["json.decode"] = "lua/json/decode.lua", + ["json.decode.array"] = "lua/json/decode/array.lua", + ["json.decode.calls"] = "lua/json/decode/calls.lua", + ["json.decode.number"] = "lua/json/decode/number.lua", + ["json.decode.object"] = "lua/json/decode/object.lua", + ["json.decode.others"] = "lua/json/decode/others.lua", + ["json.decode.strings"] = "lua/json/decode/strings.lua", + ["json.decode.util"] = "lua/json/decode/util.lua", + ["json.encode"] = "lua/json/encode.lua", + ["json.encode.array"] = "lua/json/encode/array.lua", + ["json.encode.calls"] = "lua/json/encode/calls.lua", + ["json.encode.number"] = "lua/json/encode/number.lua", + ["json.encode.object"] = "lua/json/encode/object.lua", + ["json.encode.others"] = "lua/json/encode/others.lua", + ["json.encode.output"] = "lua/json/encode/output.lua", + ["json.encode.output_utility"] = "lua/json/encode/output_utility.lua", + ["json.encode.strings"] = "lua/json/encode/strings.lua", + ["json.util"] = "lua/json/util.lua" + } +} +
diff --git a/luajson-1.2.1/rockspecs/luajson-1.2.1-1.rockspec b/luajson-1.2.1/rockspecs/luajson-1.2.1-1.rockspec new file mode 100644 index 0000000..7ec8805 --- /dev/null +++ b/luajson-1.2.1/rockspecs/luajson-1.2.1-1.rockspec
@@ -0,0 +1,44 @@ +package = "luajson" +version = "1.2.1-1" +source = { +} +description = { + summary = "customizable JSON decoder/encoder", + detailed = [[ + LuaJSON is a customizable JSON decoder/encoder using + LPEG for parsing. + ]], + homepage = "http://github.com/harningt/luajson", + maintainer = "Thomas Harning <harningt@gmail.com>", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1", + "lunit >= 0.4", + "lpeg >= 0.8.1" +} +build = { + type = "module", + modules = { + ["json"] = "lua/json.lua", + ["json.decode"] = "lua/json/decode.lua", + ["json.decode.array"] = "lua/json/decode/array.lua", + ["json.decode.calls"] = "lua/json/decode/calls.lua", + ["json.decode.number"] = "lua/json/decode/number.lua", + ["json.decode.object"] = "lua/json/decode/object.lua", + ["json.decode.others"] = "lua/json/decode/others.lua", + ["json.decode.strings"] = "lua/json/decode/strings.lua", + ["json.decode.util"] = "lua/json/decode/util.lua", + ["json.encode"] = "lua/json/encode.lua", + ["json.encode.array"] = "lua/json/encode/array.lua", + ["json.encode.calls"] = "lua/json/encode/calls.lua", + ["json.encode.number"] = "lua/json/encode/number.lua", + ["json.encode.object"] = "lua/json/encode/object.lua", + ["json.encode.others"] = "lua/json/encode/others.lua", + ["json.encode.output"] = "lua/json/encode/output.lua", + ["json.encode.output_utility"] = "lua/json/encode/output_utility.lua", + ["json.encode.strings"] = "lua/json/encode/strings.lua", + ["json.util"] = "lua/json/util.lua" + } +} +
diff --git a/luajson-1.2.1/rockspecs/luajson-scm-1.rockspec b/luajson-1.2.1/rockspecs/luajson-scm-1.rockspec new file mode 100644 index 0000000..e54a7f4 --- /dev/null +++ b/luajson-1.2.1/rockspecs/luajson-scm-1.rockspec
@@ -0,0 +1,34 @@ +package = "luajson" +version = "scm-1" +source = { + url = "git://repo.or.cz/luajson.git" +} +description = { + summary = "customizable JSON decoder/encoder", + detailed = [[ + LuaJSON is a customizable JSON decoder/encoder using + LPEG for parsing. + ]], + homepage = "http://gitrepo.or.cz/w/luajson.git", + maintainer = "Thomas Harning <harningt@gmail.com>", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1", + "lunit >= 0.4", + "lpeg >= 0.8.1" +} +build = { + type = "module", + modules = { + json = "src/json.lua", + ["json.util"] = "src/json/util.lua", + ["json.encode"] = "src/json/encode.lua", + ["json.decode"] = "src/json/decode.lua", + ["json.decode.array"] = "src/json/decode/array.lua", + ["json.decode.number"] = "src/json/decode/number.lua", + ["json.decode.object"] = "src/json/decode/object.lua", + ["json.decode.string"] = "src/json/decode/strings.lua", + ["json.decode.util"] = "src/json/decode/util.lua" + } +}
diff --git a/luajson-1.2.1/rockspecs/luajson-scm-2.rockspec b/luajson-1.2.1/rockspecs/luajson-scm-2.rockspec new file mode 100644 index 0000000..471195c --- /dev/null +++ b/luajson-1.2.1/rockspecs/luajson-scm-2.rockspec
@@ -0,0 +1,42 @@ +package = "luajson" +version = "scm-1" +source = { + url = "git://github.com/harningt/luajson.git" +} +description = { + summary = "customizable JSON decoder/encoder", + detailed = [[ + LuaJSON is a customizable JSON decoder/encoder using + LPEG for parsing. + ]], + homepage = "http://github.com/harningt/luajson", + maintainer = "Thomas Harning <harningt@gmail.com>", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1", + "lunit >= 0.4", + "lpeg >= 0.8.1" +} +build = { + type = "module", + modules = { + json = "src/json.lua", + ["json.util"] = "src/json/util.lua", + ["json.decode"] = "src/json/decode.lua", + ["json.decode.array"] = "src/json/decode/array.lua", + ["json.decode.calls"] = "src/json/decode/calls.lua", + ["json.decode.number"] = "src/json/decode/number.lua", + ["json.decode.object"] = "src/json/decode/object.lua", + ["json.decode.others"] = "src/json/decode/others.lua", + ["json.decode.strings"] = "src/json/decode/strings.lua", + ["json.decode.util"] = "src/json/decode/util.lua", + ["json.encode"] = "src/json/encode.lua", + ["json.encode.array"] = "src/json/encode/array.lua", + ["json.encode.calls"] = "src/json/encode/calls.lua", + ["json.encode.number"] = "src/json/encode/number.lua", + ["json.encode.object"] = "src/json/encode/object.lua", + ["json.encode.others"] = "src/json/encode/others.lua", + ["json.encode.strings"] = "src/json/encode/strings.lua" + } +}
diff --git a/luajson-1.2.1/rockspecs/luajson-scm-3.rockspec b/luajson-1.2.1/rockspecs/luajson-scm-3.rockspec new file mode 100644 index 0000000..ad6147f --- /dev/null +++ b/luajson-1.2.1/rockspecs/luajson-scm-3.rockspec
@@ -0,0 +1,45 @@ +package = "luajson" +version = "scm-3" +source = { + url = "git://github.com/harningt/luajson.git" +} +description = { + summary = "customizable JSON decoder/encoder", + detailed = [[ + LuaJSON is a customizable JSON decoder/encoder using + LPEG for parsing. + ]], + homepage = "http://github.com/harningt/luajson", + maintainer = "Thomas Harning <harningt@gmail.com>", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1", + "lunit >= 0.4", + "lpeg >= 0.8.1" +} +build = { + type = "module", + modules = { + ["json.decode.array"] = "lua/json/decode/array.lua", + ["json.decode.calls"] = "lua/json/decode/calls.lua", + ["json.decode.number"] = "lua/json/decode/number.lua", + ["json.decode.object"] = "lua/json/decode/object.lua", + ["json.decode.others"] = "lua/json/decode/others.lua", + ["json.decode.strings"] = "lua/json/decode/strings.lua", + ["json.decode.util"] = "lua/json/decode/util.lua", + ["json.decode"] = "lua/json/decode.lua", + ["json.encode.array"] = "lua/json/encode/array.lua", + ["json.encode.calls"] = "lua/json/encode/calls.lua", + ["json.encode.number"] = "lua/json/encode/number.lua", + ["json.encode.object"] = "lua/json/encode/object.lua", + ["json.encode.others"] = "lua/json/encode/others.lua", + ["json.encode.output"] = "lua/json/encode/output.lua", + ["json.encode.output_utility"] = "lua/json/encode/output_utility.lua", + ["json.encode.strings"] = "lua/json/encode/strings.lua", + ["json.encode"] = "lua/json/encode.lua", + ["json.util"] = "lua/json/util.lua", + ["json"] = "lua/json.lua" + } +} +
diff --git a/luajson-1.2.1/tests/data.txt b/luajson-1.2.1/tests/data.txt new file mode 100644 index 0000000..7ae4f34 --- /dev/null +++ b/luajson-1.2.1/tests/data.txt
@@ -0,0 +1 @@ +{"a317":null,"a50":50,"a108":true,"a482":482,"a397":null,"a228":true,"a193":null,"a58":58,"a71":[],"a2":2,"a376":true,"a46":46,"a337":null,"a366":366,"a239":[],"a347":[],"a388":true,"a424":true,"a386":386,"a387":[],"a81":null,"a49":null,"a60":true,"a496":true,"a346":346,"a497":null,"a328":true,"a370":370,"a427":[],"a194":194,"a269":null,"a354":354,"a265":null,"a454":454,"a276":true,"a494":494,"a96":true,"a392":true,"a492":true,"a273":null,"a339":[],"a491":[],"a490":490,"a266":266,"a37":null,"a489":null,"a447":[],"a488":true,"a487":[],"a486":486,"a278":278,"a149":null,"a59":[],"a103":[],"a153":null,"a395":[],"a357":null,"a483":[],"a481":null,"a480":true,"a51":[],"a479":[],"a299":[],"a127":[],"a123":[],"a467":[],"a475":[],"a474":474,"a173":null,"a82":82,"a165":null,"a244":true,"a375":[],"a472":true,"a377":null,"a471":[],"a83":[],"a147":[],"a87":[],"a456":true,"a315":[],"a145":null,"a249":null,"a406":406,"a40":true,"a29":null,"a468":true,"a114":114,"a128":true,"a409":null,"a355":[],"a293":null,"a48":true,"a476":true,"a227":[],"a466":466,"a267":[],"a465":null,"a464":true,"a463":[],"a92":true,"a237":null,"a76":true,"a462":462,"a461":null,"a275":[],"a139":[],"a460":true,"a247":[],"a97":null,"a459":[],"a174":174,"a458":458,"a415":[],"a172":true,"a457":null,"a301":null,"a295":[],"a39":[],"a34":34,"a291":[],"a116":true,"a202":202,"a255":[],"a200":true,"a433":null,"a35":[],"a407":[],"a470":470,"a212":true,"a126":126,"a292":true,"a62":62,"a134":134,"a321":null,"a455":[],"a222":222,"a143":[],"a175":[],"a136":true,"a198":198,"a63":[],"a120":true,"a67":[],"a452":true,"a437":null,"a450":450,"a156":true,"a195":[],"a201":null,"a44":true,"a449":null,"a155":[],"a391":[],"a89":null,"a105":null,"a351":[],"a300":true,"a28":true,"a45":null,"a135":[],"a426":426,"a1":null,"a448":true,"a144":true,"a72":true,"a340":true,"a56":true,"a446":446,"a125":null,"a90":90,"a182":182,"a73":null,"a343":[],"a211":[],"a444":true,"a443":[],"a442":442,"a245":null,"a441":null,"a440":true,"a15":[],"a439":[],"a364":true,"a402":402,"a246":246,"a132":true,"a99":[],"a14":14,"a451":[],"a324":true,"a91":[],"a78":78,"a176":true,"a382":382,"a109":null,"a435":[],"a434":434,"a66":66,"a110":110,"a166":166,"a336":true,"a422":422,"a432":true,"a431":[],"a47":[],"a190":190,"a43":[],"a430":430,"a356":true,"a283":[],"a429":null,"a25":null,"a361":null,"a428":true,"a80":true,"a69":null,"a305":null,"a146":146,"a196":true,"a333":null,"a24":true,"a425":null,"a500":true,"a3":[],"a423":[],"a186":186,"a88":true,"a421":null,"a36":true,"a350":350,"a52":true,"a389":null,"a171":[],"a236":true,"a325":null,"a411":[],"a298":298,"a57":null,"a204":true,"a181":null,"a349":null,"a418":418,"a138":138,"a169":null,"a417":null,"a416":true,"a414":414,"a413":null,"a79":[],"a319":[],"a412":true,"a124":true,"a75":[],"a394":394,"a384":true,"a408":true,"a118":118,"a405":null,"a268":true,"a231":[],"a279":[],"a27":[],"a404":true,"a23":[],"a306":306,"a271":[],"a401":null,"a289":null,"a400":true,"a150":150,"a399":[],"a398":398,"a22":22,"a238":238,"a281":null,"a396":true,"a84":true,"a484":true,"a393":null,"a493":null,"a390":390,"a178":178,"a419":[],"a85":null,"a5":null,"a133":null,"a499":[],"a218":218,"a162":162,"a368":true,"a235":[],"a379":[],"a410":410,"a260":true,"a383":[],"a436":true,"a33":null,"a335":[],"a371":[],"a141":null,"a290":290,"a220":true,"a380":true,"a32":true,"a338":338,"a381":null,"a142":142,"a374":374,"a140":true,"a373":null,"a372":true,"a119":[],"a101":null,"a205":null,"a197":null,"a55":[],"a159":[],"a495":[],"a261":null,"a187":[],"a129":null,"a30":30,"a318":318,"a369":null,"a329":null,"a223":[],"a160":true,"a158":158,"a252":true,"a148":true,"a121":null,"a304":true,"a241":null,"a365":null,"a26":26,"a438":438,"a168":true,"a111":[],"a363":[],"a64":true,"a362":362,"a360":true,"a151":[],"a216":true,"a219":[],"a21":null,"a191":[],"a100":true,"a65":null,"a359":[],"a7":[],"a192":true,"a312":true,"a102":102,"a188":true,"a234":234,"a131":[],"a189":null,"a17":null,"a353":null,"a112":true,"a352":true,"a13":null,"a420":true,"a348":true,"a313":null,"a179":[],"a122":122,"a345":null,"a12":true,"a344":true,"a18":18,"a342":342,"a251":[],"a303":[],"a341":null,"a378":378,"a334":334,"a157":null,"a130":130,"a332":true,"a331":[],"a330":330,"a10":10,"a367":[],"a327":[],"a326":326,"a323":[],"a322":322,"a225":null,"a86":86,"a316":true,"a177":null,"a314":314,"a358":358,"a311":[],"a185":null,"a310":310,"a309":null,"a217":null,"a206":206,"a115":[],"a164":true,"a240":true,"a208":true,"a403":[],"a302":302,"a9":null,"a257":null,"a478":478,"a297":null,"a296":true,"a294":294,"a161":null,"a307":[],"a287":[],"a286":286,"a285":null,"a20":true,"a284":true,"a282":282,"a280":true,"a485":null,"a152":true,"a277":null,"a274":274,"a272":true,"a270":270,"a264":true,"a263":[],"a77":null,"a106":106,"a154":154,"a167":[],"a215":[],"a308":true,"a98":98,"a94":94,"a70":70,"a74":74,"a11":[],"a256":true,"a254":254,"a253":null,"a19":[],"a207":[],"a95":[],"a262":262,"a250":250,"a248":true,"a184":true,"a243":[],"a242":242,"a385":null,"a41":null,"a233":null,"a68":true,"a232":true,"a230":230,"a229":null,"a209":null,"a226":226,"a320":true,"a224":true,"a16":true,"a221":null,"a54":54,"a117":null,"a113":null,"a38":38,"a259":[],"a137":null,"a214":214,"a213":null,"a183":[],"a469":null,"a107":[],"a163":[],"a61":null,"a93":null,"a42":42,"a453":null,"a203":[],"a199":[],"a445":null,"a31":[],"a210":210,"a6":6,"a477":null,"a258":258,"a104":true,"a4":true,"a180":true,"a498":498,"a170":170,"a473":null,"a288":true,"a8":true,"a53":null}
diff --git a/luajson-1.2.1/tests/dataTest.lua b/luajson-1.2.1/tests/dataTest.lua new file mode 100644 index 0000000..f59421c --- /dev/null +++ b/luajson-1.2.1/tests/dataTest.lua
@@ -0,0 +1,11 @@ +local io = require("io") +require("json") +local f = io.open("data.txt") +local data = f:read('*a') +f:close() +local opt = (...) +local strict = opt and opt:match('--strict') +local decode = json.decode.decode +for i = 1,1000 do + decode(data, strict) +end
diff --git a/luajson-1.2.1/tests/dataTest.php b/luajson-1.2.1/tests/dataTest.php new file mode 100644 index 0000000..8bdddac --- /dev/null +++ b/luajson-1.2.1/tests/dataTest.php
@@ -0,0 +1,5 @@ +<?php + $data = file_get_contents('data.txt'); + for($i = 0; $i < 1000; $i++) + $v = json_decode($data); +?>
diff --git a/luajson-1.2.1/tests/hook_require.lua b/luajson-1.2.1/tests/hook_require.lua new file mode 100644 index 0000000..4853c38 --- /dev/null +++ b/luajson-1.2.1/tests/hook_require.lua
@@ -0,0 +1,15 @@ +local os = require("os") +local old_require = require +if os.getenv('LUA_OLD_INIT') then + assert(loadstring(os.getenv('LUA_OLD_INIT')))() +else + require("luarocks.require") +end +local luarocks_require = require + +function require(module, ...) + if module == "json" or module:match("^json%.") then + return old_require(module, ...) + end + return luarocks_require(module, ...) +end
diff --git a/luajson-1.2.1/tests/lunit-calls.lua b/luajson-1.2.1/tests/lunit-calls.lua new file mode 100644 index 0000000..2c7a65b --- /dev/null +++ b/luajson-1.2.1/tests/lunit-calls.lua
@@ -0,0 +1,171 @@ +local json = require("json") +local lunit = require("lunit") +local math = require("math") +local testutil = require("testutil") + +local encode = json.encode +-- DECODE NOT 'local' due to requirement for testutil to access it +decode = json.decode.getDecoder(false) + +module("lunit-calls", lunit.testcase, package.seeall) + +function setup() + -- Ensure that the decoder is reset + _G["decode"] = json.decode.getDecoder(false) +end + +local values = { + 0, + 1, + 0.2, + "Hello", + true, + {hi=true}, + {1,2} +} + +function test_identity() + local function testFunction(capturedName, ...) + assert_equal('call', capturedName) + return (...) + end + local strict = { + calls = { defs = { + call = testFunction + } } + } + local decode = json.decode.getDecoder(strict) + for i, v in ipairs(values) do + local str = "call(" .. encode(v) .. ")" + local decoded = decode(str) + if type(decoded) == 'table' then + for k2, v2 in pairs(v) do + assert_equal(v2, decoded[k2]) + decoded[k2] = nil + end + assert_nil(next(decoded)) + else + assert_equal(v, decoded) + end + end +end + +-- Test for a function that throws +function test_function_failure() + local function testFunction(...) + error("CANNOT CONTINUE") + end + local strict = { + calls = { defs = { + call = testFunction + } } + } + local decode = json.decode.getDecoder(strict) + for i, v in ipairs(values) do + local str = "call(" .. encode(v) .. ")" + assert_error(function() + decode(str) + end) + end +end + +-- Test for a function that is not a function +function test_not_a_function_fail() + local notFunction = { + 0/0, 1/0, -1/0, 0, 1, "Hello", {}, coroutine.create(function() end) + } + for _, v in ipairs(notFunction) do + assert_error(function() + local strict = { + calls = { defs = { + call = v + }, allowUndefined = false } + } + json.decode.getDecoder(strict) + end) + end +end + +function test_not_permitted_fail() + local strict = { + calls = { + defs = { call = false } + } + } + local decoder = json.decode.getDecoder(strict) + assert_error(function() + decoder("call(1)") + end) +end + +function test_permitted() + local strict = { + calls = { + defs = { call = true } + } + } + local decoder = json.decode.getDecoder(strict) + assert(decoder("call(1)").name == 'call') +end + +function test_not_defined_fail() + local decoder = json.decode.getDecoder({ + calls = { + allowUndefined = false + } + }) + assert_error(function() + decoder("call(1)") + end) +end + +function test_not_defined_succeed() + local decoder = json.decode.getDecoder({ + calls = { + allowUndefined = true + } + }) + assert(decoder("call(1)").name == 'call') +end + +-- Test for a name that is not a string +function test_name_not_string() + local notString = { + true, false, 0/0, 1/0, -1/0, 0, 1, {}, function() end, coroutine.create(function() end) + } + for _, v in ipairs(notString) do + assert_error(function() + local defs = { + [v] = function() end + } + local strict = { + calls = { defs = defs } + } + json.decode.getDecoder(strict) + end) + end +end + +-- Test for a name that is a string or a pattern +function test_name_matches_string_or_pattern() + local matchedValues = { + ["mystring"] = "mystring", + [lpeg.C(lpeg.P("m") * (lpeg.P("y") + lpeg.P("Y")) * "string")] = "mystring", + [lpeg.C(lpeg.P("m") * (lpeg.P("y") + lpeg.P("Y")) * "string")] = "mYstring" + } + for pattern, value in pairs(matchedValues) do + local matched = false + local function mustBeCalled(capturedName, ...) + assert_equal(value, capturedName) + matched = true + end + matched = false + local strict = { + calls = { defs = { + [pattern] = mustBeCalled + } } + } + json.decode.getDecoder(strict)(value .. "(true)") + assert_true(matched, "Value <" .. value .. "> did not match the given pattern") + end +end
diff --git a/luajson-1.2.1/tests/lunit-encoderfunc.lua b/luajson-1.2.1/tests/lunit-encoderfunc.lua new file mode 100644 index 0000000..c07c764 --- /dev/null +++ b/luajson-1.2.1/tests/lunit-encoderfunc.lua
@@ -0,0 +1,30 @@ +local json = require("json") +local lunit = require("lunit") +local math = require("math") +local testutil = require("testutil") + +local setmetatable = setmetatable + +module("lunit-encoderfunc", lunit.testcase, package.seeall) + +local function build_call(name, parameters) + return json.util.buildCall(name, unpack(parameters, parameters.n)) +end + +function test_param_counts() + local encoder = json.encode.getEncoder() + assert(encoder(build_call('noparam', {}))) + assert(encoder(build_call('oneparam', {1}))) + assert(encoder(build_call('multiparam', {1,2}))) +end + +function test_output() + local encoder = json.encode.getEncoder() + assert_equal('b64("hello")', encoder(build_call('b64', {'hello'}))) + assert_equal('add(1,2)', encoder(build_call('add', {1,2}))) + assert_equal('dood([b64("hello"),add(1,2)])', + encoder(build_call('dood', { { + build_call('b64', {'hello'}), + build_call('add', {1,2}) + } }))) +end
diff --git a/luajson-1.2.1/tests/lunit-encoding.lua b/luajson-1.2.1/tests/lunit-encoding.lua new file mode 100644 index 0000000..bdeb1c2 --- /dev/null +++ b/luajson-1.2.1/tests/lunit-encoding.lua
@@ -0,0 +1,52 @@ +local json = require("json") +local lunit = require("lunit") + +module("lunit-encoding", lunit.testcase, package.seeall) + +function test_cloned_array_sibling() + local obj = {} + assert_pass(function() + json.encode({obj, obj}) + end) +end + +function test_cloned_object_sibling() + local obj = {} + assert_pass(function() + json.encode({x = obj, y = obj}) + end) +end + +function test_cloned_array_deep_sibling() + local obj = {} + assert_pass(function() + json.encode({ + {obj}, {obj} + }) + end) +end + +function test_cloned_array_multilevel_sibling() + local obj = {} + assert_pass(function() + json.encode({ + {obj, {obj}} + }) + end) +end + +function test_recursive_object() + local obj = {} + obj.x = obj + assert_error(function() + json.encode(obj) + end) +end + +function test_recursive_array() + local obj = {} + obj[1] = obj + assert_error(function() + json.encode(obj) + end) +end
diff --git a/luajson-1.2.1/tests/lunit-numbers.lua b/luajson-1.2.1/tests/lunit-numbers.lua new file mode 100644 index 0000000..2d42fd7 --- /dev/null +++ b/luajson-1.2.1/tests/lunit-numbers.lua
@@ -0,0 +1,151 @@ +local json = require("json") +local lunit = require("lunit") +local math = require("math") +local testutil = require("testutil") +local string = require("string") + +local encode = json.encode +-- DECODE NOT 'local' due to requirement for testutil to access it +decode = json.decode.getDecoder(false) + +module("lunit-numbers", lunit.testcase, package.seeall) + +function setup() + -- Ensure that the decoder is reset + _G["decode"] = json.decode.getDecoder(false) +end + +local function assert_near(expect, received) + local pctDiff + if expect == received then + pctDiff = 0 + else + pctDiff = math.abs(1 - expect / received) + end + local msg = ("expected '%s' but was '%s' .. '%s'%% apart"):format(expect, received, pctDiff * 100) + assert(pctDiff < 0.000001, msg) +end +local function test_simple(num) + assert_near(num, decode(tostring(num))) +end +local function test_simple_w_encode(num) + assert_near(num, decode(encode(num))) +end +local function test_scientific(num) + assert_near(num, decode(string.format('%e', num))) + assert_near(num, decode(string.format('%E', num))) +end +local numbers = { + 0, 1, -1, math.pi, -math.pi +} +math.randomseed(0xDEADBEEF) +-- Add sequence of numbers at low/high end of value-set +for i = -300,300,60 do + numbers[#numbers + 1] = math.random() * math.pow(10, i) + numbers[#numbers + 1] = -math.random() * math.pow(10, i) +end + +local function get_number_tester(f) + return function () + for _, v in ipairs(numbers) do + f(v) + end + end +end + +test_simple_numbers = get_number_tester(test_simple) +test_simple_numbers_w_encode = get_number_tester(test_simple_w_encode) +test_simple_numbers_scientific = get_number_tester(test_scientific) + +function test_infinite_nostrict() + assert_equal(math.huge, decode("Infinity")) + assert_equal(math.huge, decode("infinity")) + assert_equal(-math.huge, decode("-Infinity")) + assert_equal(-math.huge, decode("-infinity")) +end + +function test_nan_nostrict() + local value = decode("nan") + assert_true(value ~= value) + local value = decode("NaN") + assert_true(value ~= value) +end + +function test_expression() + assert_error(function() + decode("1 + 2") + end) +end + +-- For strict tests, small concession must be made to allow non-array/objects as root +local strict = json.util.merge({}, json.decode.strict, {initialObject = false}) +local strictDecoder = json.decode.getDecoder(strict) + +local numberValue = {hex = true} + +local hex = {number = numberValue} +local hexDecoder = json.decode.getDecoder(hex) + +function test_hex() + if decode == hexDecoder then -- MUST SKIP FAIL UNTIL BETTER METHOD SETUP + return + end + assert_error(function() + decode("0x20") + end) +end + +local hexNumbers = { + 0xDEADBEEF, + 0xCAFEBABE, + 0x00000000, + 0xFFFFFFFF, + 0xCE, + 0x01 +} + +function test_hex_only() + _G["decode"] = hexDecoder + for _, v in ipairs(hexNumbers) do + assert_equal(v, decode(("0x%x"):format(v))) + assert_equal(v, decode(("0X%X"):format(v))) + assert_equal(v, decode(("0x%X"):format(v))) + assert_equal(v, decode(("0X%x"):format(v))) + end +end + +local decimal_hexes = { + "0x0.1", + "0x.1", + "0x0e+1", + "0x0E-1" +} +function test_no_decimal_hex_only() + for _, str in ipairs(decimal_hexes) do + assert_error(function() + hexDecoder(str) + end) + end +end + +function test_nearly_scientific_hex_only() + assert_equal(0x00E1, hexDecoder("0x00e1")) +end + +local function buildStrictDecoder(f) + return testutil.buildPatchedDecoder(f, strictDecoder) +end +local function buildFailedStrictDecoder(f) + return testutil.buildFailedPatchedDecoder(f, strictDecoder) +end +-- SETUP CHECKS FOR SEQUENCE OF DECODERS +for k, v in pairs(_M) do + if k:match("^test_") and not k:match("_gen$") and not k:match("_only$") then + if k:match("_nostrict") then + _M[k .. "_strict_gen"] = buildFailedStrictDecoder(v) + else + _M[k .. "_strict_gen"] = buildStrictDecoder(v) + end + _M[k .. "_hex_gen"] = testutil.buildPatchedDecoder(v, hexDecoder) + end +end
diff --git a/luajson-1.2.1/tests/lunit-simple-decode.lua b/luajson-1.2.1/tests/lunit-simple-decode.lua new file mode 100644 index 0000000..73c4c45 --- /dev/null +++ b/luajson-1.2.1/tests/lunit-simple-decode.lua
@@ -0,0 +1,65 @@ +local json = require("json") +local lunit = require("lunit") + +-- Test module for handling the simple decoding that behaves more like expected +module("lunit-simple-decode", lunit.testcase, package.seeall) + +function test_decode_simple_undefined() + assert_nil(json.decode('undefined', json.decode.simple)) +end +function test_decode_default_undefined() + assert_equal(json.util.undefined, json.decode('undefined')) +end + +function test_decode_simple_null() + assert_nil(json.decode('null', json.decode.simple)) +end + +function test_decode_default_null() + assert_equal(json.util.null, json.decode('null')) +end + +function test_decode_array_simple_with_null() + local result = assert(json.decode('[1, null, 3]', json.decode.simple)) + assert_equal(1, result[1]) + assert_nil(result[2]) + assert_equal(3, result[3]) + assert_equal(3, result.n) +end + +function test_decode_array_default_with_null() + local result = assert(json.decode('[1, null, 3]')) + assert_equal(1, result[1]) + assert_equal(json.util.null, result[2]) + assert_equal(3, result[3]) + assert_equal(3, #result) +end + +function test_decode_object_simple_with_null() + local result = assert(json.decode('{x: null}', json.decode.simple)) + assert_nil(result.x) + assert_nil(next(result)) +end + +function test_decode_object_default_with_null() + local result = assert(json.decode('{x: null}')) + assert_equal(json.util.null, result.x) + assert_not_nil(next(result)) +end + +function test_decode_object_with_stringized_numeric_keys_default() + local result = assert(json.decode('{"1": "one"}')) + assert_equal("one", result["1"]) + assert_equal(nil, result[1]) +end + +function test_decode_object_with_stringized_numeric_keys_force_numeric() + local result = assert( + json.decode( + '{"1": "one"}', + { object = { setObjectKey = assert(json.decode.util.setObjectKeyForceNumber) } } + ) + ) + assert_equal(nil, result["1"]) + assert_equal("one", result[1]) +end
diff --git a/luajson-1.2.1/tests/lunit-strings.lua b/luajson-1.2.1/tests/lunit-strings.lua new file mode 100644 index 0000000..305df16 --- /dev/null +++ b/luajson-1.2.1/tests/lunit-strings.lua
@@ -0,0 +1,168 @@ +local json = require("json") +local lunit = require("lunit") +local testutil = require("testutil") +local string= require("string") + +local encode = json.encode +-- DECODE NOT 'local' due to requirement for testutil to access it +decode = json.decode.getDecoder(false) + +local error = error + +module("lunit-strings", lunit.testcase, package.seeall) + +local function assert_table_equal(expect, t) + if type(expect) ~= 'table' then + return assert_equal(expect, t) + end + for k,v in pairs(expect) do + if type(k) ~= 'string' and type(k) ~= 'number' and type(k) ~= 'boolean' then + error("INVALID expected table key") + end + local found = t[k] + if found == nil then + fail(tostring(k) .. " not found but expected") + end + assert_table_equal(v, t[k]) + end + for k,v in pairs(t) do + if nil == expect[k] then + fail(tostring(k) .. " found but not expected") + end + end +end + +function setup() + -- Ensure that the decoder is reset + _G["decode"] = json.decode.getDecoder(false) +end + +function test_strict_quotes() + local opts = { + strings = { + strict_quotes = true + } + } + assert_error(function() + local decoder = json.decode.getDecoder(opts) + decoder("'hello'") + end) + opts.strings.strict_quotes = false + assert_equal("hello", json.decode.getDecoder(opts)("'hello'")) + -- Quote test + assert_equal("he'\"llo'", json.decode.getDecoder(opts)("'he\\'\"llo\\''")) + +end + +local utf16_matches = { + -- 1-byte + { '"\\u0000"', string.char(0x00) }, + { '"\\u007F"', string.char(0x7F) }, + -- 2-byte + { '"\\u0080"', string.char(0xC2, 0x80) }, + { '"\\u00A2"', string.char(0xC2, 0xA2) }, + { '"\\u07FF"', string.char(0xDF, 0xBF) }, + -- 3-byte + { '"\\u0800"', string.char(0xE0, 0xA0, 0x80) }, + { '"\\u20AC"', string.char(0xE2, 0x82, 0xAC) }, + { '"\\uFEFF"', string.char(0xEF, 0xBB, 0xBF) }, + { '"\\uFFFF"', string.char(0xEF, 0xBF, 0xBF) } +} + +function test_utf16_decode() + for i, v in ipairs(utf16_matches) do + -- Test that the default \u decoder outputs UTF8 + local num = tostring(i) .. ' ' + assert_equal(num .. v[2], num .. json.decode(v[1])) + end +end + +local BOM = string.char(0xEF, 0xBB, 0xBF) +-- BOM skipping tests - here due to relation to UTF8/16 +local BOM_skip_tests = { + { BOM .. '"x"', "x" }, + { BOM .. '["\\uFFFF",true]', { string.char(0xEF, 0xBF, 0xBF), true } }, + -- Other uses of unicode spaces +} + +function test_bom_skip() + for i,v in ipairs(BOM_skip_tests) do + assert_table_equal(v[2], json.decode(v[1])) + end +end + +-- Unicode whitespace codepoints gleaned from unicode.org +local WHITESPACES = { + "\\u0009", -- \t + "\\u000A", -- \n + "\\u000B", -- \v + "\\u000C", -- \f + "\\u000D", -- \r + "\\u0020", -- space + "\\u0085", + "\\u00A0", + "\\u1680", + "\\u180E", + "\\u2000", + "\\u2001", + "\\u2002", + "\\u2003", + "\\u2004", + "\\u2005", + "\\u2006", + "\\u2007", + "\\u2008", + "\\u2009", + "\\u200A", + "\\u200B", -- addition, zero-width space + "\\u2028", + "\\u2029", + "\\u202F", + "\\u205F", + "\\u3000", + "\\uFEFF" -- Zero-width non-breaking space (BOM) +} + +local inject_ws_values = { + "%WS%true", + " %WS%'the%WS blob' %WS%", + "%WS%{ key: %WS%\"valueMan\",%WS% key2:%WS%4.4}", + "%WS%false%WS%" +} +function test_whitespace_ignore() + for _, ws in ipairs(WHITESPACES) do + ws = json.decode('"' .. ws .. '"') + for _, v in ipairs(inject_ws_values) do + v = v:gsub("%%WS%%", ws) + assert_true(nil ~= json.decode(v)) + end + end +end + +function test_u_encoding() + local encoder = json.encode.getEncoder() + local decoder = json.decode.getDecoder() + for i = 0, 255 do + local char = string.char(i) + assert_equal(char, decoder(encoder(char))) + end +end + +function test_x_encoding() + local encoder = json.encode.getEncoder({ strings = { xEncode = true } }) + local decoder = json.decode.getDecoder() + for i = 0, 255 do + local char = string.char(i) + assert_equal(char, decoder(encoder(char))) + end +end + +function test_strict_decoding() + local encoder = json.encode.getEncoder(json.encode.strict) + local decoder = json.decode.getDecoder(json.decode.strict) + for i = 0, 255 do + local char = string.char(i) + -- Must wrap character in array due to decoder strict-ness + assert_equal(char, decoder(encoder({char}))[1]) + end +end
diff --git a/luajson-1.2.1/tests/lunit-tests.lua b/luajson-1.2.1/tests/lunit-tests.lua new file mode 100644 index 0000000..30e82df --- /dev/null +++ b/luajson-1.2.1/tests/lunit-tests.lua
@@ -0,0 +1,55 @@ +local json = require("json") +local lunit = require("lunit") +local testutil = require("testutil") +-- DECODE NOT 'local' due to requirement for testutil to access it +decode = json.decode.getDecoder(false) + +module("lunit-tests", lunit.testcase, package.seeall) + +function setup() + _G["decode"] = json.decode.getDecoder(false) +end + +function test_array_empty() + local ret = assert_table(decode("[]")) + assert_equal(0, #ret) + assert_nil(next(ret)) +end + +function test_array_trailComma_nostrict() + local ret = assert_table(decode("[true,]")) + assert_equal(true, ret[1]) + assert_nil(next(ret, 1)) + assert_equal(1, #ret) +end + +function test_array_innerComma() + assert_error(function() + decode("[true,,true]") + end) +end + +function test_preprocess() + assert_equal('"Hello"', json.encode(1, {preProcess = function() return "Hello" end})) + assert_equal('-1', json.encode(1, {preProcess = function(x) return -x end})) + assert_equal('-Infinity', json.encode(1/0, {preProcess = function(x) return -x end})) +end + +local strictDecoder = json.decode.getDecoder(true) + +local function buildStrictDecoder(f) + return testutil.buildPatchedDecoder(f, strictDecoder) +end +local function buildFailedStrictDecoder(f) + return testutil.buildFailedPatchedDecoder(f, strictDecoder) +end +-- SETUP CHECKS FOR SEQUENCE OF DECODERS +for k, v in pairs(_M) do + if k:match("^test_") and not k:match("_gen$") then + if k:match("_nostrict") then + _M[k .. "_strict_gen"] = buildFailedStrictDecoder(v) + else + _M[k .. "_strict_gen"] = buildStrictDecoder(v) + end + end +end
diff --git a/luajson-1.2.1/tests/regressionTest.lua b/luajson-1.2.1/tests/regressionTest.lua new file mode 100644 index 0000000..e5711a6 --- /dev/null +++ b/luajson-1.2.1/tests/regressionTest.lua
@@ -0,0 +1,114 @@ +-- Additional path that may be required +require("json") +local io = require("io") +local os = require("os") + +require("lfs") + +local success = true + +local function getFileData(fileName) + local f = io.open(fileName, 'rb') + if not f then return end + local data = f:read('*a') + f:close() + return data +end + +local function putTempData(data) + local name = os.tmpname() + local f = assert(io.open(name, 'wb')) + f:write(data) + f:close() + return name +end + +-- Ensure that the encoder/decoder can round-trip valid JSON +local function RoundTripTest(parseFunc, encodeFunc, jsonData, luaData, fullRoundTrip, failRoundTrip) + local success, dataString = pcall(encodeFunc, luaData) + if failRoundTrip then + assert(not success, "Round trip encoding test result not as expected") + return true + else + assert(success, "Couldn't encode the lua data..." .. tostring(dataString)) + end + local success, result = pcall(parseFunc, dataString) + if not success then + print("Could not parse the generated JSON of (", luaData) + print("GENERATED: [[" .. dataString .. "]]") + print("DATA STORED IN: ", putTempData(dataString)) + return + end + if fullRoundTrip then + -- Ensure that whitespace is trimmed off ends + dataString = dataString:match("^[%s]*(.-)[%s]*$") + jsonData = jsonData:match("^[%s]*(.-)[%s]*$") + if dataString ~= jsonData then + print("Encoded values do not match") + print("ORIGINAL: << " .. jsonData .. " >>") + print("RE-ENCOD: << " .. dataString .. " >>") + return + end + end + return true +end + +local function testFile(fileName, parseFunc, encodeFunc, expectSuccess, fullRoundTrip, failRoundTrip) + local data = getFileData(fileName) + if not data then return end + io.write(".") + local succeed, result = pcall(parseFunc, data) + if expectSuccess ~= succeed then + print("Wrongly " .. (expectSuccess and "Failed" or "Succeeded") .. " on : " .. fileName .. "(" .. tostring(result) .. ")") + success = false + elseif succeed then + if not RoundTripTest(parseFunc, encodeFunc, data, result, fullRoundTrip, failRoundTrip) then + print("FAILED TO ROUND TRIP: " .. fileName) + success = false + end + end +end + +local function testDirectories(parseFunc, encodeFunc, directories, ...) + if not directories then return end + for _,directory in ipairs(directories) do + if lfs.attributes(directory, 'mode') == 'directory' then + for f in lfs.dir(directory) do + testFile(directory .. "/" .. f, parseFunc, encodeFunc, ...) + end + end + end + io.write("\n") +end + +local function TestParser(parseFunc, encodeFunc, successNames, failNames, roundTripNames) + testDirectories(parseFunc, encodeFunc, successNames, true, false) + testDirectories(parseFunc, encodeFunc, failNames, false, false) + testDirectories(parseFunc, encodeFunc, roundTripNames, true, true) +end +print("Testing lax/fast mode:") +TestParser(json.decode.getDecoder(), json.encode.getEncoder(), {"test/pass","test/fail_strict"}, {"test/fail_all"},{"test/roundtrip","test/roundtrip_lax"}) + +print("Testing (mostly) strict mode:") +local strict = json.util.merge({}, json.decode.strict, { + number = { + nan = false, + inf = true, + strict = true + } +}) +local strict_encode = json.util.merge({}, json.encode.strict, { + number = { + nan = false, + inf = true, + strict = true + } +}) +TestParser(json.decode.getDecoder(strict), json.encode.getEncoder(strict_encode), {"test/pass"}, {"test/fail_strict","test/fail_all"}, {"test/roundtrip"}) + +print("Testing (mostly) strict encoder with non-strict decodings") +testDirectories(json.decode.getDecoder(), json.encode.getEncoder(json.encode.strict), {"test/fail_strict_encode"}, true, true, true) + +if not success then + os.exit(1) +end
diff --git a/luajson-1.2.1/tests/test.lua b/luajson-1.2.1/tests/test.lua new file mode 100644 index 0000000..c5162f5 --- /dev/null +++ b/luajson-1.2.1/tests/test.lua
@@ -0,0 +1,71 @@ +-- Additional path that may be required +require("json") + +local testStrings = { + [[{1:[1213.3e12, 123 , 123, "hello", [12, 2], {1:true /*test*/}]}]], + [[{"username":"demo1","message":null,"password":""}]], + [[{"challenge":"b64d-fnNQ6bRZ7CYiNIKwmdHoNgl9JR9MIYtzjBhpQzYXCFrgARt9mNmgUuO7FoODGr1NieT9yTeB2SLztGkvIA4NXmN9Bi27hqx1ybJIQq6S2L-AjQ3VTDClSmCsYFPOm9EMVZDZ0jhBX1fXw3o9VYj1j9KzSY5VCSAzGqYo-cBPY\n.b64","cert":"b64MIIGyjCCBbKgAwIBAgIKFAC1ZgAAAAAUYzANBgkqhkiG9w0BAQUFADBZMRUwEwYKCZImiZPyLGQBGRYFbG9tp8uQuFjWGS_KxTHXz9vkLNFjOoZY2bOwzsdEpshuYSdvX-9bRvHTQcoMNz8Q9nXG1aMl5x1nbV5byQNTCJlz4gzMJeNfeKGcipdCj7B6e_VpF-n2P-dFZizUHjxMksCVZ3nTr51x3Uw\n.b64","key":"D79B30BA7954DF520B44897A6FF58919"}]], + [[{"key":"D79B30BA7954DF520B44897A6FF58919"}]], + [[{"val":undefined}]], + [[{ + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": "100" + }, + "IDs": [116, 943, 234, 38793] + } +}]], + [[ [ + { + "precision": "zip", + "Latitude": 37.7668, + "Longitude": -122.3959, + "Address": "", + "City": "SAN FRANCISCO", + "State": "CA", + "Zip": "94107", + "Country": "US" + }, + { + "precision": "zip", + "Latitude": 37.371991, + "Longitude": -122.026020, + "Address": "", + "City": "SUNNYVALE", + "State": "CA", + "Zip": "94085", + "Country": "US" + } + ] ]], + [[[null,true,[1,2,3],"hello\"],[world!"] ]], + [[ [{"0":"tan\\\\","model\\\\":"sedan"},{"0":"red","model":"sports"}] ]], + [[ {"1":"one","2":"two","5":"five"} ]], + [=[ [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] ]=] +} + +for i, v in ipairs(testStrings) do + print("Testing: #" .. i) + local dec = json.decode(v) + json.util.printValue(dec, "JSONVALUE") + local reenc = json.encode(dec) + print("RE_ENC: ", reenc) + local redec = json.decode(reenc) + json.util.printValue(redec, "REDECJSONVALUE") +end + +local testValues = { + {[300] = {nil, true, 1,2,3, nil, 3}} +} + +for _, v in ipairs(testValues) do + local ret = json.encode(v) + print(ret) + local dec = json.decode(ret) + json.util.printValue(dec, "Encoded value") + print("Re-encoded", json.encode(dec)) +end
diff --git a/luajson-1.2.1/tests/test/fail_all/colonInArray.json b/luajson-1.2.1/tests/test/fail_all/colonInArray.json new file mode 100644 index 0000000..a775258 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/colonInArray.json
@@ -0,0 +1 @@ +["Colon instead of comma": false] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/commaAfterValue.json b/luajson-1.2.1/tests/test/fail_all/commaAfterValue.json new file mode 100644 index 0000000..8a96af3 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/commaAfterValue.json
@@ -0,0 +1 @@ +["Comma after the close"], \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/doubleColon.json b/luajson-1.2.1/tests/test/fail_all/doubleColon.json new file mode 100644 index 0000000..27c1af3 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/doubleColon.json
@@ -0,0 +1 @@ +{"Double colon":: null} \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/extraArrayClose.json b/luajson-1.2.1/tests/test/fail_all/extraArrayClose.json new file mode 100644 index 0000000..b28479c --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/extraArrayClose.json
@@ -0,0 +1 @@ +["Extra close"]] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/extraValueAfterClose.json b/luajson-1.2.1/tests/test/fail_all/extraValueAfterClose.json new file mode 100644 index 0000000..5d8c004 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/extraValueAfterClose.json
@@ -0,0 +1 @@ +{"Extra value after close": true} "misplaced quoted value" \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/functionExpression.json b/luajson-1.2.1/tests/test/fail_all/functionExpression.json new file mode 100644 index 0000000..77580a4 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/functionExpression.json
@@ -0,0 +1 @@ +{"Illegal invocation": alert()} \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/hexNumber.json b/luajson-1.2.1/tests/test/fail_all/hexNumber.json new file mode 100644 index 0000000..0ed366b --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/hexNumber.json
@@ -0,0 +1 @@ +{"Numbers cannot be hex": 0x14} \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/lineBreakInString-escaped.json b/luajson-1.2.1/tests/test/fail_all/lineBreakInString-escaped.json new file mode 100644 index 0000000..621a010 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/lineBreakInString-escaped.json
@@ -0,0 +1,2 @@ +["line\ +break"] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/mathExpression.json b/luajson-1.2.1/tests/test/fail_all/mathExpression.json new file mode 100644 index 0000000..76eb95b --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/mathExpression.json
@@ -0,0 +1 @@ +{"Illegal expression": 1 + 2} \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/missingArrayValue.json b/luajson-1.2.1/tests/test/fail_all/missingArrayValue.json new file mode 100644 index 0000000..ed91580 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/missingArrayValue.json
@@ -0,0 +1 @@ +[ , "<-- missing value"] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/missingColon.json b/luajson-1.2.1/tests/test/fail_all/missingColon.json new file mode 100644 index 0000000..3b9c46f --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/missingColon.json
@@ -0,0 +1 @@ +{"Missing colon" null} \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/missingColon2.json b/luajson-1.2.1/tests/test/fail_all/missingColon2.json new file mode 100644 index 0000000..6247457 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/missingColon2.json
@@ -0,0 +1 @@ +{"Comma instead of colon", null} \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/octalEscape.json b/luajson-1.2.1/tests/test/fail_all/octalEscape.json new file mode 100644 index 0000000..62b9214 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/octalEscape.json
@@ -0,0 +1 @@ +["Illegal backslash escape: \017"] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/octalNumber.json b/luajson-1.2.1/tests/test/fail_all/octalNumber.json new file mode 100644 index 0000000..379406b --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/octalNumber.json
@@ -0,0 +1 @@ +{"Numbers cannot have leading zeroes": 013} \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/tabInString-escaped.json b/luajson-1.2.1/tests/test/fail_all/tabInString-escaped.json new file mode 100644 index 0000000..845d26a --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/tabInString-escaped.json
@@ -0,0 +1 @@ +["tab\ character\ in\ string\ "] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/trailingDoubleComma.json b/luajson-1.2.1/tests/test/fail_all/trailingDoubleComma.json new file mode 100644 index 0000000..ddf3ce3 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/trailingDoubleComma.json
@@ -0,0 +1 @@ +["double extra comma",,] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/unclosed_array.json b/luajson-1.2.1/tests/test/fail_all/unclosed_array.json new file mode 100644 index 0000000..6b7c11e --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/unclosed_array.json
@@ -0,0 +1 @@ +["Unclosed array" \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/unknownLiteral.json b/luajson-1.2.1/tests/test/fail_all/unknownLiteral.json new file mode 100644 index 0000000..494add1 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_all/unknownLiteral.json
@@ -0,0 +1 @@ +["Bad value", truth] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/hexEscape.json b/luajson-1.2.1/tests/test/fail_strict/hexEscape.json new file mode 100644 index 0000000..fc8376b --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict/hexEscape.json
@@ -0,0 +1 @@ +["Illegal backslash escape: \x15"] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/lineBreakInString.json b/luajson-1.2.1/tests/test/fail_strict/lineBreakInString.json new file mode 100644 index 0000000..6b01a2c --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict/lineBreakInString.json
@@ -0,0 +1,2 @@ +["line +break"] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/mustBeArrayOrObject.json b/luajson-1.2.1/tests/test/fail_strict/mustBeArrayOrObject.json new file mode 100644 index 0000000..6216b86 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict/mustBeArrayOrObject.json
@@ -0,0 +1 @@ +"A JSON payload should be an object or array, not a string." \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/singleQuoteEscape.json b/luajson-1.2.1/tests/test/fail_strict/singleQuoteEscape.json new file mode 100644 index 0000000..c43ae3c --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict/singleQuoteEscape.json
@@ -0,0 +1 @@ +["Illegal backslash escape: \'"] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/singleQuotes.json b/luajson-1.2.1/tests/test/fail_strict/singleQuotes.json new file mode 100644 index 0000000..caff239 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict/singleQuotes.json
@@ -0,0 +1 @@ +['single quote'] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/tabInString.json b/luajson-1.2.1/tests/test/fail_strict/tabInString.json new file mode 100644 index 0000000..0d3456f --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict/tabInString.json
@@ -0,0 +1 @@ +["tab character in string "]
diff --git a/luajson-1.2.1/tests/test/fail_strict/trailingArrayComma.json b/luajson-1.2.1/tests/test/fail_strict/trailingArrayComma.json new file mode 100644 index 0000000..9de168b --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict/trailingArrayComma.json
@@ -0,0 +1 @@ +["extra comma",] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/trailingObjectComma.json b/luajson-1.2.1/tests/test/fail_strict/trailingObjectComma.json new file mode 100644 index 0000000..5815574 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict/trailingObjectComma.json
@@ -0,0 +1 @@ +{"Extra comma": true,} \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/unquotedKey.json b/luajson-1.2.1/tests/test/fail_strict/unquotedKey.json new file mode 100644 index 0000000..168c81e --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict/unquotedKey.json
@@ -0,0 +1 @@ +{unquoted_key: "keys must be quoted"} \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/whitespace_before_value.json b/luajson-1.2.1/tests/test/fail_strict/whitespace_before_value.json new file mode 100644 index 0000000..51abe00 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict/whitespace_before_value.json
@@ -0,0 +1,2 @@ + +"test string" \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/bool.json b/luajson-1.2.1/tests/test/fail_strict_encode/bool.json new file mode 100644 index 0000000..27ba77d --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict_encode/bool.json
@@ -0,0 +1 @@ +true
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/inf.json b/luajson-1.2.1/tests/test/fail_strict_encode/inf.json new file mode 100644 index 0000000..c90da34 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict_encode/inf.json
@@ -0,0 +1 @@ +{x: Infinity}
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/nan.json b/luajson-1.2.1/tests/test/fail_strict_encode/nan.json new file mode 100644 index 0000000..5f497c6 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict_encode/nan.json
@@ -0,0 +1 @@ +{x: NaN}
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/null.json b/luajson-1.2.1/tests/test/fail_strict_encode/null.json new file mode 100644 index 0000000..19765bd --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict_encode/null.json
@@ -0,0 +1 @@ +null
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/number.json b/luajson-1.2.1/tests/test/fail_strict_encode/number.json new file mode 100644 index 0000000..29d6383 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict_encode/number.json
@@ -0,0 +1 @@ +100
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/string.json b/luajson-1.2.1/tests/test/fail_strict_encode/string.json new file mode 100644 index 0000000..a0b0c28 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict_encode/string.json
@@ -0,0 +1 @@ +"Heloo world"
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/undefined.json b/luajson-1.2.1/tests/test/fail_strict_encode/undefined.json new file mode 100644 index 0000000..311eb44 --- /dev/null +++ b/luajson-1.2.1/tests/test/fail_strict_encode/undefined.json
@@ -0,0 +1 @@ +{x: undefined}
diff --git a/luajson-1.2.1/tests/test/pass/extremeNesting.json b/luajson-1.2.1/tests/test/pass/extremeNesting.json new file mode 100644 index 0000000..edac927 --- /dev/null +++ b/luajson-1.2.1/tests/test/pass/extremeNesting.json
@@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/pass/pass1.json b/luajson-1.2.1/tests/test/pass/pass1.json new file mode 100644 index 0000000..7828fcc --- /dev/null +++ b/luajson-1.2.1/tests/test/pass/pass1.json
@@ -0,0 +1,56 @@ +[ + "JSON Test Pattern pass1", + {"object with 1 member":["array with 1 element"]}, + {}, + [], + -42, + true, + false, + null, + { + "integer": 1234567890, + "real": -9876.543210, + "e": 0.123456789e-12, + "E": 1.234567890E+34, + "": 23456789012E666, + "zero": 0, + "one": 1, + "space": " ", + "quote": "\"", + "backslash": "\\", + "controls": "\b\f\n\r\t", + "slash": "/ & \/", + "alpha": "abcdefghijklmnopqrstuvwyz", + "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", + "digit": "0123456789", + "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?", + "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", + "true": true, + "false": false, + "null": null, + "array":[ ], + "object":{ }, + "address": "50 St. James Street", + "url": "http://www.JSON.org/", + "comment": "// /* <!-- --", + "# -- --> */": " ", + " s p a c e d " :[1,2 , 3 + +, + +4 , 5 , 6 ,7 ], + "compact": [1,2,3,4,5,6,7], + "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", + "quotes": "" \u0022 %22 0x22 034 "", + "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" +: "A key can be any string" + }, + 0.5 ,98.6 +, +99.44 +, + +1066 + + +,"rosebud"] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/pass/pass3.json b/luajson-1.2.1/tests/test/pass/pass3.json new file mode 100644 index 0000000..4528d51 --- /dev/null +++ b/luajson-1.2.1/tests/test/pass/pass3.json
@@ -0,0 +1,6 @@ +{ + "JSON Test Pattern pass3": { + "The outermost value": "must be an object or array.", + "In this test": "It is an object." + } +}
diff --git a/luajson-1.2.1/tests/test/pass/stringWithEscapedAndUnescapedSlash.json b/luajson-1.2.1/tests/test/pass/stringWithEscapedAndUnescapedSlash.json new file mode 100644 index 0000000..4b174a9 --- /dev/null +++ b/luajson-1.2.1/tests/test/pass/stringWithEscapedAndUnescapedSlash.json
@@ -0,0 +1 @@ +["/ & \/"]
diff --git a/luajson-1.2.1/tests/test/pass/whitespace_before_array.json b/luajson-1.2.1/tests/test/pass/whitespace_before_array.json new file mode 100644 index 0000000..5a5b662 --- /dev/null +++ b/luajson-1.2.1/tests/test/pass/whitespace_before_array.json
@@ -0,0 +1 @@ + [1,2] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/pass/whitespace_before_object.json b/luajson-1.2.1/tests/test/pass/whitespace_before_object.json new file mode 100644 index 0000000..1e5f843 --- /dev/null +++ b/luajson-1.2.1/tests/test/pass/whitespace_before_object.json
@@ -0,0 +1 @@ + {"a":"Whitespace before object"} \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/roundtrip/deepArray.json b/luajson-1.2.1/tests/test/roundtrip/deepArray.json new file mode 100644 index 0000000..d3c63c7 --- /dev/null +++ b/luajson-1.2.1/tests/test/roundtrip/deepArray.json
@@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] \ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/roundtrip/emptyArray.json b/luajson-1.2.1/tests/test/roundtrip/emptyArray.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/luajson-1.2.1/tests/test/roundtrip/emptyArray.json
@@ -0,0 +1 @@ +[]
diff --git a/luajson-1.2.1/tests/test/roundtrip/emptyObject.json b/luajson-1.2.1/tests/test/roundtrip/emptyObject.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/luajson-1.2.1/tests/test/roundtrip/emptyObject.json
@@ -0,0 +1 @@ +{}
diff --git a/luajson-1.2.1/tests/test/roundtrip/simpleArrayInObject.json b/luajson-1.2.1/tests/test/roundtrip/simpleArrayInObject.json new file mode 100644 index 0000000..63771e7 --- /dev/null +++ b/luajson-1.2.1/tests/test/roundtrip/simpleArrayInObject.json
@@ -0,0 +1 @@ +{"object with 1 member":["array with 1 element"]}
diff --git a/luajson-1.2.1/tests/testutil.lua b/luajson-1.2.1/tests/testutil.lua new file mode 100644 index 0000000..66d8595 --- /dev/null +++ b/luajson-1.2.1/tests/testutil.lua
@@ -0,0 +1,22 @@ +local pcall, error = pcall, error + +local lunit = require("lunit") +local assert_error = lunit.assert_error + +-- Allow module to alter decoder +local function setDecoder(d) + decode = d +end +module("testutil", package.seeall) +function buildPatchedDecoder(f, newDecoder) + return function() + setDecoder(newDecoder) + f() + end +end +function buildFailedPatchedDecoder(f, newDecoder) + return function() + setDecoder(newDecoder) + assert_error(f) + end +end
diff --git a/luajson-1.2.1/tests/timetrials.lua b/luajson-1.2.1/tests/timetrials.lua new file mode 100644 index 0000000..1ffa121 --- /dev/null +++ b/luajson-1.2.1/tests/timetrials.lua
@@ -0,0 +1,52 @@ +--[[ + Some Time Trails for the JSON4Lua package +]]-- + +require('json') +local os = require('os') +local table = require('table') +local string = require("string") + +local skipDecode = (...) == '--skipDecode' +local count = tonumber(select(2, ...) or 500) or 500 +local strDup = tonumber(select(3, ...) or 1) or 1 +local t1 = os.clock() +local jstr +local v +for i=1,count do + local t = {} + for j=1,500 do + t[#t + 1] = j + end + for j=1,500 do + t[#t + 1] = string.rep("VALUE", strDup) + end + jstr = json.encode(t) + if not skipDecode then v = json.decode(jstr) end + --print(json.encode(t)) +end + +for i = 1,count do + local t = {} + for j=1,500 do + local m= j % 4 + local idx = string.rep('a'..j, strDup) + if (m==0) then + t[idx] = true + elseif m==1 then + t[idx] = json.util.null + elseif m==2 then + t[idx] = j + else + t[idx] = string.char(j % 0xFF) + end + end + jstr = json.encode(t) + if not skipDecode then v = json.decode(jstr) end +end + +print (jstr) +--print(type(t1)) +local t2 = os.clock() + +print ("Elapsed time=" .. os.difftime(t2,t1) .. "s")
diff --git a/luajson-1.2.1/util/createRock.lua b/luajson-1.2.1/util/createRock.lua new file mode 100644 index 0000000..d4481c9 --- /dev/null +++ b/luajson-1.2.1/util/createRock.lua
@@ -0,0 +1,45 @@ +local io = require("io") + +local version = assert((...), "Requires rock version on command-line") + +local template = [=[ +package = "luajson" +version = %VERSION% +source = { + url = "git://github.com/harningt/luajson.git" +} +description = { + summary = "customizable JSON decoder/encoder", + detailed = [[ + LuaJSON is a customizable JSON decoder/encoder using + LPEG for parsing. + ]], + homepage = "http://github.com/harningt/luajson", + maintainer = "Thomas Harning <harningt@gmail.com>", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1", + "lunit >= 0.4", + "lpeg >= 0.8.1" +} +build = { + type = "module", + modules = { +%MODULES% + } +} +]=] + +local in_modules = io.popen("find lua -type f -name '*.lua' -not -iname '.*' | sort", "r") +local modules = in_modules:read("*a") +in_modules:close() + +modules = modules:gsub("lua/([^\n]*)%.lua", function(module) + return "\t\t[" .. ("%q"):format(module:gsub("/",".")) .. "] = " .. ("%q"):format("lua/" .. module .. ".lua") .. "," +end) +local out = template:gsub("%%(.-)%%", { + VERSION = ("%q"):format(version), + MODULES = modules +}) +print(out)
diff --git a/luajson-1.2.1/util/prepareNextRelease.lua b/luajson-1.2.1/util/prepareNextRelease.lua new file mode 100755 index 0000000..842c4be --- /dev/null +++ b/luajson-1.2.1/util/prepareNextRelease.lua
@@ -0,0 +1,29 @@ +#!/usr/bin/env lua +local io = require("io") +local from, tover = ... +if not from or not tover then + print("Format: prepareNextRelease.lua <from-tag> <tover-tag>") + return +end + +local f = assert(io.open("docs/ReleaseNotes-" .. tover .. ".txt", "w")) +local headLine = "luajson v" .. tover .. " Release Notes" +f:write(headLine, "\n", ("="):rep(#headLine), "\n\n") + +f:write([[ +User Visible Changes +-------------------- + +Plans for next release +---------------------- + +]]) +local tailLine = "Updates since " .. from +f:write(tailLine, "\n", ("="):rep(#tailLine), "\n\n") + +local data = assert(io.popen("git shortlog " .. from .. "..HEAD | util/processShortlog.lua", "r")) +local tail = data:read("*a") +data:close() + +f:write(tail) +f:close()
diff --git a/luajson-1.2.1/util/processShortlog.lua b/luajson-1.2.1/util/processShortlog.lua new file mode 100755 index 0000000..4149198 --- /dev/null +++ b/luajson-1.2.1/util/processShortlog.lua
@@ -0,0 +1,44 @@ +#!/usr/bin/env lua +local io = require("io") +local table = require("table") +local authors = {} + +local currentAuthor + +local function pushValue(t, group, value) + local items = t[group] or {} + t[group] = items + items[#items + 1] = value +end +for line in io.lines() do + local author = line:match("^(.- %(%d*%):)$") + line = line:match("^%s*(.-)%s*$") + if author then + currentAuthor = authors[author] or {} + authors[author] = currentAuthor + elseif currentAuthor and #line > 0 then + local msg = line:gsub("^%s*","") + local group, data = msg:match("^([^:]*[%s]*:)[%s]*(.*)$") + if not group then + pushValue(currentAuthor, "-ungrouped-", msg) + else + pushValue(currentAuthor, group, data) + end + end +end +for author, groups in pairs(authors) do + print(author) + -- SORT GROUPS + local sorted = {} + for group, groupValues in pairs(groups) do + sorted[#sorted + 1] = {group, groupValues} + end + table.sort(sorted, function(a,b) return a[1] < b[1] end) + for _, gv in ipairs(sorted) do + local group, groupValues = unpack(gv) + print("\t" .. group) + for _, entry in ipairs(groupValues) do + print("\t\t" .. entry) + end + end +end
diff --git a/luajson.tar.bz2 b/luajson.tar.bz2 new file mode 100644 index 0000000..882d43c --- /dev/null +++ b/luajson.tar.bz2 Binary files differ
diff --git a/luajson.url b/luajson.url new file mode 100644 index 0000000..b703b87 --- /dev/null +++ b/luajson.url
@@ -0,0 +1 @@ +http://luaforge.net/frs/download.php/4676/luajson-1.2.1.tar.bz2
diff --git a/luajson.version b/luajson.version new file mode 100644 index 0000000..6085e94 --- /dev/null +++ b/luajson.version
@@ -0,0 +1 @@ +1.2.1