Download Latest Version json-parser-1.0.tar.gz (780.9 kB)
Email in envelope

Get an email when there's a new version of JSON Parser

Home
Name Modified Size InfoDownloads / Week
json-parser-1.0.tar.gz 2022-09-26 780.9 kB
README 2022-09-24 15.6 kB
Totals: 2 Items   796.5 kB 8
version:    1.0
website:    http:/info.fwsentry.org/projects/dlist/
contact:    dbw <dbw@fwsentry.org>
license:    BSD revised (see http://www.opensource.org/licenses/bsd-license.php)


USAGE / INSTALLATION
====================

JSON-parser is 3 clause BSD-licensed, so you can use source code, in whole or part, 
and integrate it into your project or application. 

JSON Parser is a highly efficient JSON data decoder written in C, and parses JSON
data into a form that is very easy to use from within C code.

You only need to include the json-parser.h file in your source code. If your project
does not already incorporate D-List, you will also need to include dlist.h (before
json-parser.h in your source code).

Alternately JSON Parser can be installed as a shared library.  Here is a suggested
command set to build a shared library, install it in one of your default search
paths for the linker.

1. enter the package root directory
2. cd src
3. compile
	standard, no debug messages
		$ gcc -c -std=gnu99 -O2 -Wall -Werror -fpic json-parser.c

	or, if you want debug messages enabled (very helpful for D-List code development)
		$ gcc -c -std=gnu99 -g -O2 -Wall -Werror -fpic json-parser.c -DDEBUG

4. link
        $ gcc -shared -o libjson-parser.so json-parser.o

To build the test package:

	$cd package root directory
	$ ./configure
	$ make install

to run, must be in the same build working directory to access the test files
	$ json-parser-test
  or
	$ /usr/local/bin/json-parser-test

PACKAGE CONTENTS
================

-- src/json-parser			source code for the library ( json-parser.c, json-parser.h)
-- src/dlist				source for D-List (dlist.c, dlist.h etc)
-- src						source code for regression test package (json-parser-test.c etc)
-- test-data				used by json-parser-test to regression test the JSON Package
-- GUIDES					documentation files to help users of the JSON Package
-- EXAMPLES					some same JSON data
-- doxy						Doxygen config file, input files and pre-bilt html. 

There are 3 external JSON conversation functions in the package, and numerous
JSON Support functions available, to perform searches etc. Documentation is included
in both the json-parser.h file, GUIDES directory and in the doxy html. Extra helpful
notes, code snippets and ideas are included in the documents inside GUIDES.

If you already use D-List you will only need the contents of src/json-parser to
add to your project. Othwerwise also add in the contents of src/dlist.

The regression test package is not required for your code development. It may
however contain useful code snippets for you to understand how to access the
JSON data after parsing, or how to use the JSON Support Functions.

The package has autoconf and automake files. To simplify build and usage.


API'S & DOCUMENTATION
=====================

There are 3 conversion functions provided for callers to use. 

A JSON Validator, that will take as input a character array with a JSON data block
in it, and run a linear validation of the JSON data, returning a boolean value if 
it passes or fails validation. Optional error reporting is output to stderr.

A JSON Parser function takes the same character array JSON data block, and uses 
recursive parsing to translate it to D-List list_object structures for usage in a
C language code module. 

A JSON Generator function takes a hierarchical D-List list_object structure and
converts it into a character array as JSON textural data block, that strictly 
conforms to RFC 8259.

Both the JSON Parser and JSON Generator use recursive parsing to translate the 
input data. The JSON Validator uses, by design, a liner byte by byte approach to 
validate every single byte of an unknown JSON data block.

Both the JSON Parser and JSON Validator functions perform full and complete
validation of the JSON data, the differences are the amount of error reporting 
available, and whether the function uses resources or not. The JSON Validator uses 
no additional resources and performs a very strict linear syntax scan of the JSON
data. The parser uses additional resources.

If the JSON data being parsed comes from a known good source (e.g. ARIN) then
immediately passing it to the JSON Parser is the right choice. But if the JSON 
data is from an unknown source, it might be wiser to pass it through the JSON 
Validator first. As the JSON Validator uses no extra resources as it parses, it
would be impossible for a deliberately crafted poisonous JSON data block to cause
any harm to a system, or cause unknown code to be executed. The JSON Parser was
also designed to withstand attack, but as it does use resources, there is always
the possibility that some cleaver criminal can find a way of causing trouble,
especially on a small RAM embedded system. So for safety always pass a JSON Data
file of dubious origin through the JSON Validator first.

The JSON validator has a nested object or nested array depth limit of 2048 
levels. The JSON Parser, being fully recursive, has no such limits, except those
imposed by the operating system being run on (heap space etc).

The JSON parser reuses the JSON data block to create all the value items used in
the lists, it does not waste memory space recreating them, however the JSON data
block itself is irreversibly modified, and must be discarded after it has been 
used.

Please refer to json-parser.h for details.

list_object *json_parse_data_block(	char *json_data_block, 
									unsigned int *json_data_type,
									element_search object_search_function,
									element_compare object_compare_function,
									element_search array_search_function,
									element_compare array_compare_function,
									const boolean keep_exponent);

boolean json_valid_data_block(	const char *json_object, 
								char **object_error, 
								unsigned long int *line_number,
								const boolean suppress_warnings);

int json_generate_data_block(	list_object *json_data, 
								unsigned int json_data_type,
								char **json_text_buffer);


The regression test program json-parser-test was not designed to be a flexible
command, it is only designed to pass a set of specific valid and invalid JSON
data files through the validator and parser to confirm proper operation. It has
no options, and must be run from the package working directory to locate the
test files. Other than coding samples it has no other value, was therefore not
released in a form that works in a general purpose manner. You are welcome to
modify it to make it general purpose, if you need to process lots of unknown
JSON files. But it would be better to use the code snippets from within it to
develop your own utilities.

This package also includes numerous JSON Support Functions to help users
access or search for various non-uniform JSON data. These are described in
the documents found in the GUIDES directory, and in header file documentation.

	json_find_members_value_string()
	json_find_members_value_integer()
	json_find_members_value_double()
	json_find_members_value_type()
	json_find_member_value()
	json_path_locate()
	json_create_new_list_object()
	json_report_list_object_type()
	json_list_object_member_add_string()
	json_list_object_member_add_number()
	json_list_object_member_add_boolean()
	json_list_object_member_add_null()
	json_list_object_member_add_list()
	json_list_object_array_value_add_string()
	json_list_object_array_value_add_number()
	json_list_object_array_value_add_boolean()
	json_list_object_array_value_add_null()
	json_list_object_array_value_add_list()
	json_path_to_list_object()
	json_parse_dotted_path()
	json_generate_path_from_links()
	json_print_path_from_links()
	display_parsed_json_object()

Please note:	All these JSON Conversion and Support functions are fully
------------	thread / MP safe. However, it is still the callers 
				responsibility to ensure that multiple threads do not attempt
				to simultaneously modify and access the same data structures 
				or list_object(s) used by these JSON functions. This should
				be done by using mutex locks, semaphores, gates, barriers 
				etc, or whatever mechanisms you deem fit.


JSON data representation
========================

Simply put, 
	a JSON Object is mapped to a subordinate D-List list_object
	a JSON Object name/value pair is an element within that list_object 
	a JSON array is a subordinate D-List list_object within an element 
		of the enclosing JSON object
	
	JSON value types -
		JSON_string is a pointer to the original string in the original JSON buffer,
			it is now nul terminated. The pointer points to the first char
			after the original double quote character, and the last character
			is the character before the ending double quote.
		JSON_array is a pointer to a new list_object which will contain the 
			values, one element per array value. If the array in the JSON code
			was a single entry then that single entry is a single element in
			the new subordinate list.
		JSON_object is a pointer to a new list_object which will contain the 
			name value pairs, one element per JSON object element. If the JSON 
			Object in the JSON data block was a single entry then that single
			entry is a single element in the new subordinate list. 
			If the JSON Object was empty " { } " then the subordinate list will
			have zero elements.
		All other JSON value types are converted and stored in the name/value, or
			value only, element, this includes numbers, boolean, etc.
	
The D-List list objects that now represent the JSON object, array and value 
structures, can be used just like any other D-List list object. They can be sorted
and manipulated as needed. All data pointers within the lists point to portions
of the original JSON string buffer that was parsed.

DO NOT release the JSON buffer, until after the D-List lists that describe it have
been erased. All D-List lists used for parsing JSON objects are built with the 
COPY_DATA attribute, so all list storage is handled internally by the JSON parsing
code, and the deletions use D-List functions to properly free all the allocated
regions.

This representation of a JSON object eliminates all white space, and compresses
strings to remove escape characters, etc.

jCard representations are handled in the same way, a vCardArray would be an
array object, a new list_object, and each of the elements in that array would
be elements in the new list. elements with nul parameters, would have a NULL
entry in the parameters pointer, or there would be pointer to another list.

Important. For every element in every list object, root or subordinate, that is
returned by the JSON Parser, you must always check the JSON_value_type in each
element BEFORE attempting to access the element value. Inaccurate handling of 
element values in your code will lead to code or data corruption. Please refer
to the typedef json_element_t in json-parser.h for more information. Fields that
are not used in an element will always be 0x00000000.

Default D-List user functions for JSON Parser lists.
====================================================
	
The following is the list of available search and compare functions that are
built into JSON Parser. Callers may use any of these as they need, or use
them as templates for writing functions that suit their specific data needs.

	default_search_function_object_name(const void *element, const void *key);	
	default_search_function_partial_object_name(const void *element, const void *key);

	default_search_function_array_values(const void *element, const void *key);

	default_search_function_array_string_value(const void *element, const void *key);
	default_search_function_partial_array_string_value(const void *element, const void *key);
	default_search_function_array_integer_value(const void *element, const void *key);
	default_search_function_array_double_value(const void *element, const void *key);
	default_search_function_precise_array_double_value(const void *element, const void *key);
	default_search_function_sloppy_array_double_value(const void *element, const void *key);

	default_compare_function_object_names(const void *element, const void *key);

	default_compare_function_array_values(const void *element, const void *key);

	default_compare_function_array_number_values(const void *element, const void *key);
	default_compare_function_array_string_values(const void *element, const void *key);
	default_compare_function_array_integer_values(const void *element, const void *key);
	default_compare_function_array_double_values(const void *element, const void *key);

For more information about each of these functions, please see the prototype 
information in the json-parser.h file.																						*/

STANDARDS
=========

This implementation of this JSON Parser package is completely compliant with 
RFC 8259 and ECMA-404. It does not impose any restrictions on what may or may 
not be deemed fully interoperable between JSON peers sharing data, it does 
conform to the specifications of RFC 8259, but does not impose restrictions
based its guidelines of interoperability. 

There is a document inside the GUIDES directory that describes in detail the
various nuances of stands compliance for this JSON Package.

But in brief,
	
	JSON grammar is strictly enforced by the validator and the parser. They
	enforce the same requirements as those imposed by RFC 8259 Section 10, and
	do not allow variations beyond those standards as MAY be permitted but not
	required or standard, by Section 9.
	
	Extra Note
	----------
	
	It seems that the issue of whether or not comments

		/* blah blah blah */ or // more blah 

	should be permitted in JSON data blocks is rather contentious among the user
	community. It does seem clear that there is no contention at all in the 
	standards community, IETF and ECMA both clearly state the JSON grammar does
	not include comments.
	
	This implementation of both the JSON Validator and JSON Parser sticks to the 
	standards, and will reject any JSON data block that contains comments, or 
	other non JSON grammar encoding. Although RFC 8259 section 9 states that 
	
		"A JSON parser MAY accept non-JSON forms or extensions."
		
	This implementation does not accept any non standard grammar forms or syntax.
	Not just for the obvious operability argument, but also because the next 
	section (10. Generators) states very clearly, that 
		
		"A JSON generator produces JSON text. The resulting text MUST 
		strictly conform to the JSON grammar."
	
	There would be no point in having a JSON Parser that works on a different 
	standard of grammar than that imposed on the JSON Generator of that grammar, 
	when both are in the same JSON Package.
	
	If at some point in the future the IETF and/or ECMA change the standard to 
	accept comments or update the available JSON grammar and syntax, this package
	will be updated accordingly.
	
	If you as a JSON user feel strongly about incorporating comments into the
	JSON grammar specification, i urge you to communicate with the IETF and ECMA
	about the issue. I also implore you to NOT just go and start changing software
	to accept what is not allowed by specification, just because you personally 
	don't like it. 
	
	Until then, just put your comments in a value field! It is not hard and 
	works within the existing standards. It also allows everyone to properly
	interoperate and exchange data, which was the whole point.
		
		{ 	"myobject" 	: "valuable data",
			"another" 	: 3.14159,					"//" : "was that pi ?",
			"comment"	: "simple enough isn't it",
			"more data"	: true,						"" : "Another style of comment",
			"label_b"	: "something important"		}
	
Source: README, updated 2022-09-24