From 71c5dd86f14a73d97e2cb57e81755c4844938697 Mon Sep 17 00:00:00 2001 From: Mark Pulford Date: Mon, 12 Dec 2011 23:23:32 +1030 Subject: Convert documentation to AsciiDoc - Rename README to manual.txt and add AsciiDoc markup - Rewrite some sections of documentation (more outstanding) - Add "doc" Makefile target - Update RPM spec file to include HTML output --- Makefile | 7 +- NEWS | 1 + README | 328 ---------------------------------------- lua-cjson.spec | 2 +- manual.txt | 460 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 468 insertions(+), 330 deletions(-) delete mode 100644 README create mode 100644 manual.txt diff --git a/Makefile b/Makefile index 1eb1090..cad06be 100644 --- a/Makefile +++ b/Makefile @@ -48,10 +48,12 @@ INSTALL_CMD = install CJSON_CFLAGS += -fpic -I$(LUA_INCLUDE_DIR) -DVERSION=\"$(CJSON_VERSION)\" OBJS := lua_cjson.o strbuf.o -.PHONY: all clean install package +.PHONY: all clean install package doc all: cjson.so +doc: manual.html + .c.o: $(CC) -c $(CFLAGS) $(CPPFLAGS) $(CJSON_CFLAGS) -o $@ $< @@ -62,6 +64,9 @@ install: cjson.so mkdir -p $(DESTDIR)/$(LUA_MODULE_DIR) $(INSTALL_CMD) cjson.so $(DESTDIR)/$(LUA_MODULE_DIR) +manual.html: manual.txt + asciidoc -n -a toc manual.txt + clean: rm -f *.o *.so diff --git a/NEWS b/NEWS index 26ab879..c17317e 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ Version 1.0.5 (?) * Updated Makefile for compatibility with non-GNU make implementations +* Added HTML reference manual Version 1.0.4 (Nov 30 2011) * Fixed numeric conversion under locales with a comma decimal separator diff --git a/README b/README deleted file mode 100644 index 36c9a64..0000000 --- a/README +++ /dev/null @@ -1,328 +0,0 @@ -Lua CJSON v1.0.4 -================ - -Lua CJSON is covered by the MIT license. See the file "LICENSE" for -details. - -Lua CJSON provides fast JSON parsing and encoding support for Lua. - -Features: -- 10x to 20x quicker (or more) than the fastest pure Lua JSON modules. -- Full support for JSON with UTF-8, including decoding surrogate - pairs. -- Optional run-time support for common exceptions to the JSON - specification (NaN, Inf,..). - -Caveats: -- UTF-16 and UTF-32 are not supported. -- Multi-threading within a single Lua state is not supported. - However, this is not a recommended configuration under Lua. - -To obtain the latest version of Lua CJSON visit: - - http://www.kyne.com.au/~mark/software/lua-cjson.php - -Feel free to email me if you have any patches, suggestions, or -comments. - -- Mark Pulford - - -Installing -========== - -Build requirements: -- Lua (http://www.lua.org/) -Or: -- LuaJIT (http://www.luajit.org/) - -There are 3 build methods available: -- Make: POSIX, OSX -- RPM: Various Linux distributions -- LuaRocks (http://www.luarocks.org/): POSIX, OSX, Windows - - -Make ----- - -Review and update the included Makefile to suit your platform. Next, -build and install the module: - - # make - # make install - OR - # cp cjson.so [your_module_directory] - - -RPM ---- - -RPM-based Linux distributions should be able to create a package using -the included RPM spec file. Install the "rpm-build" package, or -similar, then: - - # rpmbuild -tb lua-cjson-1.0.4.tar.gz - - -LuaRocks --------- - -LuaRocks (http://luarocks.org/) can be used to install and manage Lua -modules on a wide range of platforms (including Windows). - -Extract the Lua CJSON source package into a directory and run: - - # cd lua-cjson-1.0.4; luarocks make - -LuaRocks does not support platform specific configuration for Solaris. -On Solaris, you may need to manually uncomment "USE_INTERNAL_ISINF" in -the rockspec before building this module. - -See the LuaRocks documentation for further details. - - -Lua CJSON API -============= - -Synopsis --------- - - require "cjson" - -- Or: - local cjson = require "cjson" - - -- Translate Lua value to/from JSON - text = cjson.encode(value) - value = cjson.decode(text) - - -- Get and/or set CJSON configuration - setting = cjson.refuse_invalid_numbers([setting]) - depth = cjson.encode_max_depth([depth]) - convert, ratio, safe = cjson.encode_sparse_array([convert[, ratio[, safe]]]) - keep = cjson.encode_keep_buffer([keep]) - - -Encoding --------- - - json_text = cjson.encode(value) - -cjson.encode() will serialise the following types: - * number, string, table, boolean, lightuserdata (NULL) or nil - -The remaining Lua types cannot be serialised: - * thread, userdata, lightuserdata (non-NULL), function - -Numbers are encoded using the standard Lua number format. - -ASCII 0 - 31, double-quote, forward-slash, black-slash and ASCII 127 -are escaped when encoding strings. Other octets are passed -transparently. It is expected the application will perform UTF-8 error -checking if required. - -A Lua table will only be recognised as an array if all keys are type -"number" and are positive integers (>0). Otherwise CJSON will encode -the table as a JSON object. - -CJSON will also recognise and handle sparse arrays. Missing entries -will be encoded as "null". Eg: - { [3] = "data" } -becomes: - [null,null,"data"] - -Note: standards compliant JSON must be encapsulated in either an -object ({}) or an array ([]). You must pass a table to cjson.encode() -if you want to generate standards compliant JSON output. - -By default, errors will be raised for: -- Excessively sparse arrays (see below) -- More than 20 nested tables -- Invalid numbers (NaN, Infinity) - -These defaults can be changed with: -- cjson.encode_sparse_array() -- cjson.encode_max_depth() -- cjson.refuse_invalid_numbers() - -Example: - data_obj = { true, { foo = "bar" } } - data_json = cjson.encode(data_obj) - - -Decoding --------- - - value = cjson.decode(json_text) - -cjson.decode() will deserialise any UTF-8 JSON string into a Lua data -structure. It can return any of the types that cjson.encode() -supports. - -UTF-16 and UTF-32 JSON strings are not supported. - -CJSON requires that NULL (\0) and double quote (\") are escaped within -strings. All escape codes will be decoded and other characters will be -passed transparently. UTF-8 characters are not validated during -decoding and should be checked elsewhere if required. - -JSON "null" will be converted to a NULL lightuserdata value. This can -be compared with cjson.null for convenience. - -By default, invalid numbers (NaN, Infinity, Hexidecimal) will be -decoded. - -Example: - data_json = '[ true, { "foo": "bar" } ]' - data_obj = cjson.decode(data_json) - - -Invalid numbers ---------------- - - setting = cjson.refuse_invalid_numbers([setting]) - -- "setting" must be on of: - -- false, "encode", "decode", "both", true - -CJSON considers numbers which are outside the JSON specification to be -"invalid". Eg: -- Infinity -- NaN -- Hexadecimal numbers - -By default CJSON will decode "invalid" numbers, but will refuse to -encode them. - -This setting can be configured separately for encoding and/or -decoding: -- Enabled: an error will be generated if an invalid number is found. -- Disabled (encoding): NaN and Infinity can be encoded. -- Disabled (decoding): All numbers supported by strtod(3) will be - parsed. - - -Sparse arrays -------------- - - convert, ratio, safe = cjson.encode_sparse_array([convert[, ratio[, safe]]]) - -- "convert" must be a boolean. Default: false. - -- "ratio" must be a positive integer (>0). Default: 2 - -- "safe" must be a positive integer (>0). Default: 10 - -A Lua array is sparse if it is missing a value for at least 1 index. -Lua CJSON encodes missing values as "null". Eg: - Lua array: { [3] = "sparse" } - JSON array: [null,null,"sparse"] - -CJSON detects excessively sparse arrays by comparing the number of -items in a Lua array with the maximum index. In particular: - - maximum index > safe AND maximum index > array_items * ratio - -By default, attempting to encode excessively sparse arrays will -generate an error. - -If "convert" is set to "true", excessively sparse arrays will be -encoded as a JSON object: - Lua array: { [1000] = "excessively sparse" } - JSON array: {"1000":"excessively sparse"} - -Setting "ratio" to 0 disables checking for excessively sparse arrays. - - -Nested tables -------------- - - depth = cjson.encode_max_depth([depth]) - -- "depth" must be a positive integer (>0). - -By default, CJSON will reject data structure with more than 20 nested -tables. - -This check is used to prevent a nested data structure from crashing -the application. Eg: - a = {}; b = { a }; a[1] = b - - -Number precision ----------------- - - precision = cjson.encode_number_precision([precision]) - -- "precision" must be between 1 and 14 (inclusive) - -By default CJSON will output 14 significant digits when converting a -number to text. - -Reducing number precision to 3 can improve performance of number -heavy conversions by up to 50%. - - -Persistent encoding buffer --------------------------- - - keep = cjson.keep_encode_buffer([keep]) - -- "keep" must be a boolean - -By default, CJSON will reuse the JSON encoding buffer to improve -performance. The buffer will grow to the largest size required and is -not freed until CJSON is garbage collected. Setting this option to -"false" will cause the buffer to be freed after each call to -cjson.encode(). - - -JSON and handling under Lua CJSON -================================= - -Nulls ------ - -Lua CJSON decodes JSON "null" as a Lua lightuserdata NULL pointer. - -As a convenience, "cjson.null" is provided for comparison. - - -Table keys ----------- - -JSON object keys must be strings - other types are not supported. Lua -CJSON will convert numeric keys to a string, and other non-string -types will generate an error. - -JSON object keys are always be decoded as Lua strings. - -If all Lua table keys are numbers (not strings), Lua CJSON will -encode the table as a JSON array. See "Sparse arrays" above for -more details. - - -Metamethods ------------ - -Lua CJSON does not use metamethods when serialising tables. -- next() is used to iterate over tables. -- rawget() is used to iterate over arrays. - - -Functions, Userdata, Threads ----------------------------- - -Lua CJSON will generate an error if asked to serialise Lua functions, -userdata, lightuserdata or threads. - - -Locales -------- - -Lua CJSON uses strtod() and snprintf() to perform numeric conversion -as they are usually well supported, fast and bug free. - -To ensure JSON encoding/decoding works correctly for locales using -comma decimal separators, Lua CJSON must be compiled with either -USE_POSIX_USELOCALE or USE_POSIX_SETLOCALE. See the Makefile or the -rockspec for details. - - -References -========== - -- http://tools.ietf.org/html/rfc4627 -- http://www.json.org/ diff --git a/lua-cjson.spec b/lua-cjson.spec index 07064e9..c446bfb 100644 --- a/lua-cjson.spec +++ b/lua-cjson.spec @@ -39,7 +39,7 @@ rm -rf "$RPM_BUILD_ROOT" %files %defattr(-,root,root,-) -%doc LICENSE NEWS performance.txt README rfc4627.txt tests THANKS TODO +%doc LICENSE NEWS performance.txt manual.txt rfc4627.txt tests THANKS TODO %{lualibdir}/* diff --git a/manual.txt b/manual.txt new file mode 100644 index 0000000..20d95bd --- /dev/null +++ b/manual.txt @@ -0,0 +1,460 @@ +Lua CJSON Manual +================ +Mark Pulford +v1.0.4, November 30 2011 + +Overview +-------- + +Lua CJSON provides fast JSON parsing and encoding support for Lua. + +.Features +- More than 10x to 20x faster than the efficient pure Lua JSON modules. +- Full support for JSON with UTF-8, including decoding surrogate + pairs. +- Optional run-time support for common exceptions to the JSON + specification (NaN, Inf,..). + +.Caveats +- UTF-16 and UTF-32 are not supported. +- Multi-threading within a single Lua state is not supported. + However, this is not a recommended configuration under Lua. + +Lua CJSON is covered by the MIT license. See the file +LICENSE+ for +details. + +The latest version of this software is available from the +http://www.kyne.com.au/~mark/software/lua-cjson.php[Lua CJSON website]. + +Feel free to email me if you have any patches, suggestions, or +comments. + + +Installation Methods +-------------------- + +Lua CJSON requires either http://www.lua.org[Lua] or +http://www.luajit.org[LuaJIT] to build. + +There are 3 build methods available: + +- Make: POSIX, OSX +- RPM: Various Linux distributions +- http://www.luarocks.org[LuaRocks]: POSIX, OSX, Windows + + +Make +~~~~ + +Review and update the included Makefile to suit your platform. Next, +build and install the module: + +[source,sh] +----------- +make install +----------- + +Or install manually: + +[source,sh] +----------- +make +cp cjson.so $your_lua_module_directory +----------- + + +RPM +~~~ + +Linux distributions using RPM should be able to create a package via +the included RPM spec file. Install the +rpm-build+ package (or +similar) then: + +[source,sh] +----------- +rpmbuild -tb lua-cjson-1.0.4.tar.gz +rpm -Uvh $newly_built_lua_cjson_rpm +----------- + + +LuaRocks +~~~~~~~~ + +http://luarocks.org[LuaRocks] can be used to install and manage Lua +modules on a wide range of platforms (including Windows). + +Extract the Lua CJSON source package into a directory and run: + +[source,sh] +----------- +cd lua-cjson-1.0.4 +luarocks make +----------- + +LuaRocks does not support platform specific configuration for Solaris. +On Solaris, you may need to manually uncomment +USE_INTERNAL_ISINF+ in +the rockspec before building this module. + +See the http://luarocks.org/en/Documentation[LuaRocks documentation] for +further details. + + +Lua API +------- + +Synopsis +~~~~~~~~ + +[source,lua] +------------ +require "cjson" +-- Or: +local cjson = require "cjson" + +-- Translate Lua value to/from JSON +text = cjson.encode(value) +value = cjson.decode(text) + +-- Get and/or set Lua CJSON configuration +setting = cjson.refuse_invalid_numbers([setting]) +depth = cjson.encode_max_depth([depth]) +convert, ratio, safe = cjson.encode_sparse_array([convert[, ratio[, safe]]]) +keep = cjson.encode_keep_buffer([keep]) +------------ + + +cjson.encode +~~~~~~~~~~~~ + +[source,lua] +------------ +json_text = cjson.encode(value) +------------ + ++cjson.encode+ will serialise a Lua value into a string containing the +JSON representation. + ++cjson.encode+ supports the following types: + +- +boolean+ +- +lightuserdata+ (NULL value only) +- +nil+ +- +number+ +- +string+ +- +table+ + +The remaining Lua types cannot be serialised: + +- +function+ +- +lightuserdata+ (non-NULL values) +- +thread+ +- +userdata+ + +Numbers are encoded using the standard Lua number format. + +Lua CJSON will escape the following characters within each string: + +- Control characters (ASCII 0 - 31) +- Double quote (ASCII 34) +- Forward slash (ASCII 47) +- Blackslash (ASCII 92) +- Delete (ASCII 127) + +All other characters are passed transparently. Any UTF-8 error +checking must be done by the application. + +Lua CJSON uses a heuristic to determine whether to encode a Lua table +as a JSON array or an object. A Lua table which only has positive +integers (>0) keys of type +number+ will be encoded as a JSON array. +All other tables will be encoded as a JSON object. + +Missing entries from sparse Lua arrays are encoded as +null+. For +example: + +.Lua input +[source,lua] +------------ +{ [3] = "data" } +------------ + +.JSON output +[source,javascript] +------------------- +[null,null,"data"] +------------------- + +[NOTE] +Standards compliant JSON must be encapsulated in either an +object (+{}+) or an array (+[]+). Hence a table must be passed to ++cjson.encode+ to generate standards compliant JSON output. + +By default, the following will generate errors: + +- Excessively <> +- More than 20 nested tables +- Invalid numbers (NaN, Infinity) + +These defaults can be changed with: + +- +cjson.encode_sparse_array+ +- +cjson.encode_max_depth+ +- +cjson.refuse_invalid_numbers+ + +.Example: encoding +[source,lua] +------------ +data_obj = { true, { foo = "bar" } } +data_json = cjson.encode(data_obj) +------------ + + +cjson.decode +~~~~~~~~~~~~ + +[source,lua] +------------ +value = cjson.decode(json_text) +------------ + ++cjson.decode+ will deserialise any UTF-8 JSON string into a Lua value +or table. It may return any of the types that +cjson.encode+ supports. + +UTF-16 and UTF-32 JSON strings are not supported. + ++cjson.decode+ requires that any NULL (ASCII 0) and double quote +(ASCII 34) characters are escaped within strings. All escape codes +will be decoded and other characters will be passed transparently. +UTF-8 characters are not validated during decoding and should be +checked elsewhere if required. + +JSON +null+ will be converted to a NULL +lightuserdata+ value. This +can be compared with +cjson.null+ for convenience. + +By default, _invalid_ numbers (NaN, Infinity, Hexidecimal) will be +decoded. This default can be changed with ++cjson.refuse_invalid_numbers+. + +.Example: decoding +[source,lua] +------------ +data_json = '[ true, { "foo": "bar" } ]' +data_obj = cjson.decode(data_json) +------------ + + +cjson.refuse_invalid_numbers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +[source,lua] +------------ +setting = cjson.refuse_invalid_numbers([setting]) +-- "setting" must be on of: +-- false, "encode", "decode", "both", true +------------ + +Lua CJSON considers numbers which are outside the JSON specification to be +_invalid_: + +- Infinity +- NaN +- Hexadecimal numbers + +By default Lua CJSON will decode _invalid_ numbers, but will refuse to +encode them. + +This setting can be configured separately for encoding and/or +decoding: + +Enabled:: + an error will be generated if an _invalid_ number is found. +Disabled (encoding):: + NaN and Infinity can be encoded. +Disabled (decoding):: + All numbers supported by +strtod+(3) will be parsed. + + +[[sparse_arrays]] +cjson.encode_sparse_array +~~~~~~~~~~~~~~~~~~~~~~~~~ + +[source,lua] +------------ +convert, ratio, safe = cjson.encode_sparse_array([convert[, ratio[, safe]]]) +-- "convert" must be a boolean. Default: false. +-- "ratio" must be a positive integer (>0). Default: 2 +-- "safe" must be a positive integer (>0). Default: 10 +------------ + +A Lua array is sparse if it is missing a value for at least 1 index. +Lua CJSON encodes missing values as JSON +null+. Eg, Lua array: + +.Lua input +[source,lua] +------------ +{ [3] = "sparse" } +------------ + +.JSON output +[source,javascript] +------------------- +[null,null,"sparse"] +------------------- + +Lua CJSON detects excessively sparse arrays by comparing the number of +items in a Lua array with the maximum index. In particular: + +----- +maximum index > safe AND maximum index > array_items * ratio +----- + +By default, attempting to encode excessively sparse arrays will +generate an error. + +If _convert_ is set to +true+, excessively sparse arrays will be +encoded as a JSON object: + +.Lua input +[source,lua] +{ [1000] = "excessively sparse" } + +.JSON output +[source,javascript] +{"1000":"excessively sparse"} + +Setting +ratio+ to +0+ disables checking for excessively sparse arrays. + + +cjson.encode_max_depth +~~~~~~~~~~~~~~~~~~~~~~ + +[source,lua] +------------ +depth = cjson.encode_max_depth([depth]) +-- "depth" must be a positive integer (>0). +------------ + +By default, Lua CJSON will reject data structure with more than 20 nested +tables. + +This check prevents a deeply nested or recursive data structure from +crashing the application. + +.Example +[source,lua] +a = {}; b = { a }; a[1] = b + + +cjson.encode_number_precision +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +[source,lua] +------------ +precision = cjson.encode_number_precision([precision]) +-- "precision" must be between 1 and 14 (inclusive) +------------ + +By default, Lua CJSON will output 14 significant digits when +converting a number to text. + +Reducing number precision to _3_ can improve performance of number +heavy JSON conversions by up to 50%. + + +cjson.keep_encode_buffer +~~~~~~~~~~~~~~~~~~~~~~~~ + +[source,lua] +------------ +keep = cjson.keep_encode_buffer([keep]) +-- "keep" must be a boolean +------------ + +By default, Lua CJSON will reuse the JSON encoding buffer to improve +performance. The buffer will grow to the largest size required and is +not freed until the Lua CJSON module is garbage collected. Setting this +option to +false+ will cause the buffer to be freed after each call to ++cjson.encode+. + + +cjson.version +~~~~~~~~~~~~~ + +[source,lua] +------------ +ver = cjson.version +-- variable containing the package version (1.0.4) +------------ + +FIXME + + +JSON and handling under Lua CJSON +--------------------------------- + +Nulls +~~~~~ + +Lua CJSON decodes JSON +null+ as a Lua lightuserdata NULL pointer. + +As a convenience, +cjson.null+ is provided for comparison. + + +Table keys +~~~~~~~~~~ + +If all Lua table keys are type +number+ (not +string+), Lua CJSON will +encode the table as a JSON array. See +<> above for more details. + +All other tables will be encoded as a JSON object. + +JSON requires that object keys must be type string. +cjson.encode+ +will convert numeric keys to a string, and other non-string types will +generate an error. + +[CAUTION] +========= +Care must be taken when encoding/decoding objects which contain keys of type ++number+. +[source,lua] +------------ +val = cjson.decode(cjson.encode{[1] = "1", a = "a"}) +-- Returns: { ["1"] = "1", ... +-- NOT: { [1] = "1", ... +------------ +========= + +Metamethods +~~~~~~~~~~~ + +Lua CJSON does not use metamethods when serialising tables. + +- +rawget+ is used to iterate over Lua arrays. +- +next+ is used to iterate over Lua objects. + + +Functions, Userdata, Threads +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Lua CJSON will generate an error if asked to serialise Lua functions, +userdata, lightuserdata or threads. + + +Locales +~~~~~~~ + +Lua CJSON uses +strtod+(3) and +snprintf+(3) to perform numeric conversion +as they are usually well supported, fast and bug free. + +To ensure JSON encoding/decoding works correctly for locales using +comma decimal separators, Lua CJSON must be compiled with either ++USE_POSIX_USELOCALE+ or +USE_POSIX_SETLOCALE+. See the +Makefile+ or the +rockspec for details. + + +[sect1] +References +---------- + +- http://tools.ietf.org/html/rfc4627[RFC 4627] +- http://www.json.org/[JSON website] -- cgit v1.2.3-55-g6feb