documentation updates
This commit is contained in:
parent
575226189f
commit
c152ba0ab3
|
@ -34,20 +34,19 @@ main(void)
|
|||
/* read the entire config file */
|
||||
rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
|
||||
|
||||
/* file read error handling */
|
||||
if (rd == 0 && !feof(stdin)) {
|
||||
fprintf(stderr, "error encountered on file read\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (rd >= sizeof(fileData) - 1) {
|
||||
} else if (rd >= sizeof(fileData) - 1) {
|
||||
fprintf(stderr, "config file too big\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* we have the whole config file in memory. let's parse it */
|
||||
/* we have the whole config file in memory. let's parse it ... */
|
||||
node = yajl_tree_parse((const char *) fileData, errbuf, sizeof(errbuf));
|
||||
|
||||
/* error handling */
|
||||
/* parse error handling */
|
||||
if (node == NULL) {
|
||||
fprintf(stderr, "parse_error: ");
|
||||
if (strlen(errbuf)) fprintf(stderr, " %s", errbuf);
|
||||
|
@ -56,11 +55,11 @@ main(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* now extract a nested value from the config file */
|
||||
/* ... and extract a nested value from the config file */
|
||||
{
|
||||
const char * path[] = { "Logging", "timeFormat", (const char *) 0 };
|
||||
yajl_val v = yajl_tree_get(node, path, yajl_t_string);
|
||||
if (v) printf("Logging/timeFomat: %s\n", YAJL_GET_STRING(v));
|
||||
if (v) printf("%s/%s: %s\n", path[0], path[1], YAJL_GET_STRING(v));
|
||||
else printf("no such node: %s/%s\n", path[0], path[1]);
|
||||
}
|
||||
|
||||
|
|
|
@ -518,7 +518,7 @@ EXCLUDE_SYMBOLS =
|
|||
# directories that contain example code fragments that are included (see
|
||||
# the \include command).
|
||||
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATH = ..
|
||||
|
||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
/**
|
||||
* \file yajl_parse.h
|
||||
* Interface to YAJL's JSON parsing facilities.
|
||||
* Interface to YAJL's JSON stream parsing facilities.
|
||||
*/
|
||||
|
||||
#include <yajl/yajl_common.h>
|
||||
|
@ -57,15 +57,19 @@ extern "C" {
|
|||
* continue. If zero, the parse will be canceled and
|
||||
* yajl_status_client_canceled will be returned from the parse.
|
||||
*
|
||||
* Note about handling of numbers:
|
||||
* yajl will only convert numbers that can be represented in a double
|
||||
* or a 64 bit (long long) int. All other numbers will be passed to the client
|
||||
* in string form using the yajl_number callback. Furthermore, if
|
||||
* yajl_number is not NULL, it will always be used to return numbers,
|
||||
* that is yajl_integer and yajl_double will be ignored. If
|
||||
* yajl_number is NULL but one of yajl_integer or yajl_double are
|
||||
* defined, parsing of a number larger than is representable
|
||||
* in a double or 64 bit integer will result in a parse error.
|
||||
* \attention {
|
||||
* A note about the handling of numbers:
|
||||
*
|
||||
* yajl will only convert numbers that can be represented in a
|
||||
* double or a 64 bit (long long) int. All other numbers will
|
||||
* be passed to the client in string form using the yajl_number
|
||||
* callback. Furthermore, if yajl_number is not NULL, it will
|
||||
* always be used to return numbers, that is yajl_integer and
|
||||
* yajl_double will be ignored. If yajl_number is NULL but one
|
||||
* of yajl_integer or yajl_double are defined, parsing of a
|
||||
* number larger than is representable in a double or 64 bit
|
||||
* integer will result in a parse error.
|
||||
* }
|
||||
*/
|
||||
typedef struct {
|
||||
int (* yajl_null)(void * ctx);
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
*
|
||||
* \author Florian Forster
|
||||
* \date August 2010
|
||||
*
|
||||
* This interface makes quick parsing and extraction of
|
||||
* smallish JSON docs trivial:
|
||||
*
|
||||
* \include example/parse_config.c
|
||||
*/
|
||||
|
||||
#ifndef YAJL_TREE_H
|
||||
|
@ -50,17 +55,18 @@ typedef enum {
|
|||
typedef struct yajl_val_s * yajl_val;
|
||||
|
||||
/**
|
||||
* A JSON value:is one of the seven types above. For "string", "number",
|
||||
* "object", and "array" additional data is available in the "data" union.
|
||||
* The "YAJL_IS_*" and "YAJL_GET_*" macros below allow type checking
|
||||
* and convenient value extraction.
|
||||
* A JSON value representation capable of holding one of the seven
|
||||
* types above. For "string", "number", "object", and "array"
|
||||
* additional data is available in the union. The "YAJL_IS_*"
|
||||
* and "YAJL_GET_*" macros below allow type checking and convenient
|
||||
* value extraction.
|
||||
*/
|
||||
struct yajl_val_s
|
||||
{
|
||||
/** Type of the value contained. Use the "YAJL_IS_*" macors to check for a
|
||||
* specific type. */
|
||||
yajl_type type;
|
||||
/** Type-specific data. Use the "YAJL_TO_*" macros to access these
|
||||
/** Type-specific data. You may use the "YAJL_GET_*" macros to access these
|
||||
* members. */
|
||||
union
|
||||
{
|
||||
|
@ -76,7 +82,7 @@ struct yajl_val_s
|
|||
} number;
|
||||
struct {
|
||||
const char **keys; /*< Array of keys */
|
||||
yajl_val *values; /** Array of values. */
|
||||
yajl_val *values; /*< Array of values. */
|
||||
size_t len; /*< Number of key-value-pairs. */
|
||||
} object;
|
||||
struct {
|
||||
|
@ -92,7 +98,7 @@ struct yajl_val_s
|
|||
* Parses an null-terminated string containing JSON data and returns a pointer
|
||||
* to the top-level value (root of the parse tree).
|
||||
*
|
||||
* \param input Pointer to a null-terminated string containing
|
||||
* \param input Pointer to a null-terminated utf8 string containing
|
||||
* JSON data.
|
||||
* \param error_buffer Pointer to a buffer in which an error message will
|
||||
* be stored if \em yajl_tree_parse fails, or
|
||||
|
@ -112,9 +118,7 @@ YAJL_API yajl_val yajl_tree_parse (const char *input,
|
|||
char *error_buffer, size_t error_buffer_size);
|
||||
|
||||
/**
|
||||
* Free a parse tree.
|
||||
*
|
||||
* Recursively frees a pointer returned by "yajl_tree_parse".
|
||||
* Free a parse tree returned by "yajl_tree_parse".
|
||||
*
|
||||
* \param v Pointer to a JSON value returned by "yajl_tree_parse". Passing NULL
|
||||
* is valid and results in a no-op.
|
||||
|
@ -122,7 +126,18 @@ YAJL_API yajl_val yajl_tree_parse (const char *input,
|
|||
YAJL_API void yajl_tree_free (yajl_val v);
|
||||
|
||||
/**
|
||||
* Access a nested value.
|
||||
* Access a nested value inside a tree.
|
||||
*
|
||||
* \param parent the node under which you'd like to extract values.
|
||||
* \param path A null terminated array of strings, each the name of an object key
|
||||
* \param type the yajl_type of the object you seek, or yajl_t_any if any will do.
|
||||
*
|
||||
* \returns a pointer to the found value, or NULL if we came up empty.
|
||||
*
|
||||
* Future Ideas: it'd be nice to move path to a string and implement support for
|
||||
* a teeny tiny micro language here, so you can extract array elements, do things
|
||||
* like .first and .last, even .length. Inspiration from JSONPath and css selectors?
|
||||
* No it wouldn't be fast, but that's not what this API is about.
|
||||
*/
|
||||
YAJL_API yajl_val yajl_tree_get(yajl_val parent, const char ** path, yajl_type type);
|
||||
|
||||
|
|
194
src/yajl
194
src/yajl
|
@ -1,3 +1,8 @@
|
|||
/**
|
||||
\example reformatter/json_reformat.c
|
||||
\example example/parse_config.c
|
||||
*/
|
||||
|
||||
/*!
|
||||
\mainpage Yet Another JSON Library (YAJL)
|
||||
\author Lloyd Hilaiel
|
||||
|
@ -5,9 +10,7 @@
|
|||
|
||||
Yet Another JSON Library (YAJL) is a small event-driven (SAX-style)
|
||||
JSON parser written in ANSI C, and a small validating JSON
|
||||
generator. It also includes a small simplified tree interface for
|
||||
simplified parsing and extraction of data from smallish JSON documents.
|
||||
YAJL is released under the permissive ISC license.
|
||||
generator. YAJL is released under the permissive ISC license.
|
||||
|
||||
\section features Features
|
||||
|
||||
|
@ -17,186 +20,15 @@ YAJL is released under the permissive ISC license.
|
|||
-# tiny
|
||||
-# event driven
|
||||
-# support for generating "beautified" JSON
|
||||
-# includes
|
||||
It also includes a small simplified tree interface for
|
||||
simplified parsing and extraction of data from smallish JSON documents.
|
||||
|
||||
\section usage Usage
|
||||
|
||||
The following code sample is a complete JSON "reformating" program. It
|
||||
demonstrates how to perform stream parsing and generation.
|
||||
The following code sample is a complete JSON "reformating" program.
|
||||
See <a href="reformatter_2json_reformat_8c-example.html">json_reformat.c</a> for a complete example of stream based parsing
|
||||
and generation of JSON. See <a href="example_2parse_config_8c-example.html">parse_config.c</a> for an example of the
|
||||
simplified tree interface.
|
||||
|
||||
\code
|
||||
#include <yajl/yajl_parse.h>
|
||||
#include <yajl/yajl_gen.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static int reformat_null(void * ctx)
|
||||
{
|
||||
yajl_gen g = (yajl_gen) ctx;
|
||||
return yajl_gen_status_ok == yajl_gen_null(g);
|
||||
}
|
||||
|
||||
static int reformat_boolean(void * ctx, int boolean)
|
||||
{
|
||||
yajl_gen g = (yajl_gen) ctx;
|
||||
return yajl_gen_status_ok == yajl_gen_bool(g, boolean);
|
||||
}
|
||||
|
||||
static int reformat_number(void * ctx, const char * s, size_t l)
|
||||
{
|
||||
yajl_gen g = (yajl_gen) ctx;
|
||||
return yajl_gen_status_ok == yajl_gen_number(g, s, l);
|
||||
}
|
||||
|
||||
static int reformat_string(void * ctx, const unsigned char * stringVal,
|
||||
size_t stringLen)
|
||||
{
|
||||
yajl_gen g = (yajl_gen) ctx;
|
||||
return yajl_gen_status_ok == yajl_gen_string(g, stringVal, stringLen);
|
||||
}
|
||||
|
||||
static int reformat_map_key(void * ctx, const unsigned char * stringVal,
|
||||
size_t stringLen)
|
||||
{
|
||||
yajl_gen g = (yajl_gen) ctx;
|
||||
return yajl_gen_status_ok == yajl_gen_string(g, stringVal, stringLen);
|
||||
}
|
||||
|
||||
static int reformat_start_map(void * ctx)
|
||||
{
|
||||
yajl_gen g = (yajl_gen) ctx;
|
||||
return yajl_gen_status_ok == yajl_gen_map_open(g);
|
||||
}
|
||||
|
||||
|
||||
static int reformat_end_map(void * ctx)
|
||||
{
|
||||
yajl_gen g = (yajl_gen) ctx;
|
||||
return yajl_gen_status_ok == yajl_gen_map_close(g);
|
||||
}
|
||||
|
||||
static int reformat_start_array(void * ctx)
|
||||
{
|
||||
yajl_gen g = (yajl_gen) ctx;
|
||||
return yajl_gen_status_ok == yajl_gen_array_open(g);
|
||||
}
|
||||
|
||||
static int reformat_end_array(void * ctx)
|
||||
{
|
||||
yajl_gen g = (yajl_gen) ctx;
|
||||
return yajl_gen_status_ok == yajl_gen_array_close(g);
|
||||
}
|
||||
|
||||
static yajl_callbacks callbacks = {
|
||||
reformat_null,
|
||||
reformat_boolean,
|
||||
NULL,
|
||||
NULL,
|
||||
reformat_number,
|
||||
reformat_string,
|
||||
reformat_start_map,
|
||||
reformat_map_key,
|
||||
reformat_end_map,
|
||||
reformat_start_array,
|
||||
reformat_end_array
|
||||
};
|
||||
|
||||
static void
|
||||
usage(const char * progname)
|
||||
{
|
||||
fprintf(stderr, "%s: reformat json from stdin\n"
|
||||
"usage: json_reformat [options]\n"
|
||||
" -m minimize json rather than beautify (default)\n"
|
||||
" -u allow invalid UTF8 inside strings during parsing\n",
|
||||
progname);
|
||||
exit(1);
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char ** argv)
|
||||
{
|
||||
yajl_handle hand;
|
||||
static unsigned char fileData[65536];
|
||||
/* generator config */
|
||||
yajl_gen g;
|
||||
yajl_status stat;
|
||||
size_t rd;
|
||||
int retval = 0;
|
||||
|
||||
g = yajl_gen_alloc(NULL);
|
||||
yajl_gen_config(g, yajl_gen_beautify, 1);
|
||||
yajl_gen_config(g, yajl_gen_validate_utf8, 1);
|
||||
|
||||
/* ok. open file. let's read and parse */
|
||||
hand = yajl_alloc(&callbacks, NULL, (void *) g);
|
||||
/* and let's allow comments by default */
|
||||
yajl_config(hand, yajl_allow_comments, 1);
|
||||
|
||||
/* check arguments.*/
|
||||
int a = 1;
|
||||
while ((a < argc) && (argv[a][0] == '-') && (strlen(argv[a]) > 1)) {
|
||||
unsigned int i;
|
||||
for ( i=1; i < strlen(argv[a]); i++) {
|
||||
switch (argv[a][i]) {
|
||||
case 'm':
|
||||
yajl_gen_config(g, yajl_gen_beautify, 0);
|
||||
break;
|
||||
case 'u':
|
||||
yajl_config(hand, yajl_dont_validate_strings, 1);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unrecognized option: '%c'\n\n",
|
||||
argv[a][i]);
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
++a;
|
||||
}
|
||||
if (a < argc) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
|
||||
for (;;) {
|
||||
rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
|
||||
|
||||
if (rd == 0) {
|
||||
if (!feof(stdin)) {
|
||||
fprintf(stderr, "error on file read.\n");
|
||||
retval = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
fileData[rd] = 0;
|
||||
|
||||
stat = yajl_parse(hand, fileData, rd);
|
||||
|
||||
if (stat != yajl_status_ok) break;
|
||||
|
||||
{
|
||||
const unsigned char * buf;
|
||||
size_t len;
|
||||
yajl_gen_get_buf(g, &buf, &len);
|
||||
fwrite(buf, 1, len, stdout);
|
||||
yajl_gen_clear(g);
|
||||
}
|
||||
}
|
||||
|
||||
stat = yajl_complete_parse(hand);
|
||||
|
||||
if (stat != yajl_status_ok) {
|
||||
unsigned char * str = yajl_get_error(hand, 1, fileData, rd);
|
||||
fprintf(stderr, "%s", (const char *) str);
|
||||
yajl_free_error(hand, str);
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
yajl_gen_free(g);
|
||||
yajl_free(hand);
|
||||
|
||||
return retval;
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue