![]() |
JSON Parser
1.0
|
| list_object* json_parse_data_block | ( | char * | json_data_block, |
| JSON_value_types * | 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 | ||
| ) |
Call the JSON Parser and return a hierarchical list_object containing the parsed contents of the JSON data block requested.
The original JSON data block will be modified.
The JSON data block can be parsed in 1 or 2 passes. If the JSON data originates from an unknown or unreliable source, it would be wise to pass it through the validator json_valid_data_block() first. Once identified as valid it can be parsed with this function. Alternatively, if the JSON data being parsed comes from a known good and reliable source (for example ARIN) then sending it to the parser in one pass is probably the right choice.
This function parses the contents of the JSON data block while performing syntax and data validation, building a set of D-List list_objects and elements that contains all the JSON data with all the whitespace, syntax and non-data removed. This function, like all those in the JSON Parser Package, is fully thread safe and MP safe.
The original JSON data block provided by the caller is heavily modified as part of the parsing process. If you want to retain the original JSON data block intact, you must provide a copy of it to this function.
The goal of the function is to parse the JSON data block creating as little as possible in additional resources, and providing the data contents in a form of D-List list_objects that is natively variable and non-determinate. Rather than attempting to crow-bar variable data objects into some form of static C language array. This makes the parsing code much simpler to write and maintain, while the results of the JSON data parsing activity are much easier to handle, find, or modify by the caller.
For example it is now very easy to rearrange the original JSON data elements, or sort them by arbitrary keys etc, or perform arbitrary searches for data or keys.
Upon successful return, a pointer to a list_object is returned. It is very important to realize that the data values (such as strings) pointed to from within the elements of these hierarchical list_objects, are still inside the original JSON data block that was provided to this function. That original JSON data block was extensively modified to allow the strings it contains to be nul terminated etc. and left in-situ. It is very important that the root list_object returned to the caller is properly disposed first, BEFORE any attempt is made to release the original JSON data block.
So for example:
big_lump = (char *)malloc(big_lump_to_fit_json_data_block);
{... read file or grab data from socket to fill big_lump ...}
if (json_valid_data_block(big_lump, NULL, NULL, FALSE) {
json_object_ptr = json_parse_data_block(big_lump, &return_type, NULL, NULL, FALSE);
if (json_object_ptr) {
while (still_working) {
do something useful with the returned list_objects
...
}
list_erase(json_object_ptr);
if (json_object_ptr) free(json_object_ptr);
}
}
if (big_lump) free(big_lump);
The root list_object returned is self cleaning, all data is managed internally, and the single list_erase of the root object, will cause all the element records, arrays, and sub-level list_objects to be deallocated and removed. No special JSON Parser calls are required to manage the root list_object, all data processing can be performed with the standard D-List function calls. If you wish to perform sorts, searches, etc. the default JSON search and compare functions have already been attached to both the root, and all the subordinate list_objects. The attached search and compare functions have already been tailored to either JSON Object or JSON Array type lists.
Additionally upon return, the output argument json_data_type is set to tell the caller what the top level list_object retuned describes. In JSON the root of a data block can only have one item. It can be a single value, or an array or an object. Rather than have a list_object that only has a single element, that itself is a list_object pointing to an array, etc; the root level list_object alway describes the top level JSON data block, so if that is a JSON Array, then the elements of the root list_object will be the elements of that array. If it is a single JSON value there will be a single element describing that value.
You may optionally select a replacement search or compare function for the list_objects to be built during the parsing operation. If none are provided, then in-built default functions are used. You can select from any of the other available built-in function, described below, or you may write your own to suit your specific data processing needs. If you chose to replace the default search and compare functions after the lists are created, the process to add them to every list_object in the data hierarchy would be very tedious. You can always override a specific search or compare function for a specific list_object as needed, during later processing of the parsing results.
The JSON Parser normally converts all value tokens found in the JSON data block. However the basic C language has limited ability to properly represent high precision exponential numbers. As this code was designed to be highly portable, only requiring a minimum of C99 to compile and run, it uses the base forms of the language for numbers. For some users either the limited precision of these forms, or their inability to hold huge numbers will be an issue. So there is an option to instruct the parser to instead provide these exponent numbers as a string value instead, and allow the user to use whatever methods they want to convert or use those numbers. Integers and numbers with no exponent are always converted. Integers to C type long integer, and fractional numbers to C type long double. It is beyond the scope of this parser to accurately deal with very large numbers with the precision used by some professions.
You can use the json_element_t typedef, to properly access the list element data. The values of JSON_value_types are used to decode what type of data or value each list element contains.
| [in,out] | json_data_block | a nul terminated string containing the JSON data block to parse. The contents of this character buffer will be extensively modified, and will be unusable by the caller upon return. However as noted above, do not release or free this buffer, until after the returned list_object has been erased. |
| [out] | json_data_type | Upon successful return, this argument is modified to reflect what the top level of the JSON data block represents, the 3 possible options are: JSON_object the list_object returned is a parsed JSON object JSON_array the list_object returned is a parsed JSON array JSON_value the list_object returned contains a single JSON value element, which is one of the type in the list JSON_value_types |
| [in] | object_search_function | a D-List search function to add to each list_object that represents a JSON Object, that is created by the JSON parsing activity. Or NULL if the default search function default_search_function_member_name() is to be added. |
| [in] | object_compare_function | a D-List compare function to add to each list_object represents a JSON Object, that is created by the JSON parsing activity. Or NULL if the default compare function default_compare_function_member_names() is to be added. |
| [in] | array_search_function | a D-List search function to add to each list_object that represents a JSON Array, that is created by the JSON parsing activity. Or NULL if the default search function default_search_function_array_values() is to be added. |
| [in] | array_compare_function | a D-List compare function to add to each list_object represents a JSON Array, that is created by the JSON parsing activity. Or NULL if the default compare function default_compare_function_array_values() is to be added. |
| [in] | keep_exponent | FALSE - Exponent numbers are converted to long double TRUE - Exponent numbers are retained as text strings |
| pointer | Upon successful parsing of the JSON data block, a pointer to a root list_object is returned, which is the top of the hierarchical JSON data block. |
| NULL | If there was an error found in the JSON data block, a NULL pointer is returned. |