1767de84eSFilipe David Borba Manana /*
2767de84eSFilipe David Borba Manana  * Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
3767de84eSFilipe David Borba Manana  *
4767de84eSFilipe David Borba Manana  * Permission to use, copy, modify, and/or distribute this software for any
5767de84eSFilipe David Borba Manana  * purpose with or without fee is hereby granted, provided that the above
6767de84eSFilipe David Borba Manana  * copyright notice and this permission notice appear in all copies.
7767de84eSFilipe David Borba Manana  *
8767de84eSFilipe David Borba Manana  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9767de84eSFilipe David Borba Manana  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10767de84eSFilipe David Borba Manana  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11767de84eSFilipe David Borba Manana  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12767de84eSFilipe David Borba Manana  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13767de84eSFilipe David Borba Manana  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14767de84eSFilipe David Borba Manana  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15767de84eSFilipe David Borba Manana  */
16767de84eSFilipe David Borba Manana 
17767de84eSFilipe David Borba Manana /**
18767de84eSFilipe David Borba Manana  * \file yajl_parse.h
19767de84eSFilipe David Borba Manana  * Interface to YAJL's JSON stream parsing facilities.
20767de84eSFilipe David Borba Manana  */
21767de84eSFilipe David Borba Manana 
22767de84eSFilipe David Borba Manana #include <yajl/yajl_common.h>
23767de84eSFilipe David Borba Manana 
24767de84eSFilipe David Borba Manana #ifndef __YAJL_PARSE_H__
25767de84eSFilipe David Borba Manana #define __YAJL_PARSE_H__
26767de84eSFilipe David Borba Manana 
27767de84eSFilipe David Borba Manana #include <stddef.h>
28767de84eSFilipe David Borba Manana 
29767de84eSFilipe David Borba Manana #ifdef __cplusplus
30767de84eSFilipe David Borba Manana extern "C" {
31767de84eSFilipe David Borba Manana #endif
32767de84eSFilipe David Borba Manana     /** error codes returned from this interface */
33767de84eSFilipe David Borba Manana     typedef enum {
34767de84eSFilipe David Borba Manana         /** no error was encountered */
35767de84eSFilipe David Borba Manana         yajl_status_ok,
36767de84eSFilipe David Borba Manana         /** a client callback returned zero, stopping the parse */
37767de84eSFilipe David Borba Manana         yajl_status_client_canceled,
38767de84eSFilipe David Borba Manana         /** An error occured during the parse.  Call yajl_get_error for
39767de84eSFilipe David Borba Manana          *  more information about the encountered error */
40767de84eSFilipe David Borba Manana         yajl_status_error
41767de84eSFilipe David Borba Manana     } yajl_status;
42767de84eSFilipe David Borba Manana 
43767de84eSFilipe David Borba Manana     /** attain a human readable, english, string for an error */
44767de84eSFilipe David Borba Manana     YAJL_API const char * yajl_status_to_string(yajl_status code);
45767de84eSFilipe David Borba Manana 
46767de84eSFilipe David Borba Manana     /** an opaque handle to a parser */
47767de84eSFilipe David Borba Manana     typedef struct yajl_handle_t * yajl_handle;
48767de84eSFilipe David Borba Manana 
49767de84eSFilipe David Borba Manana     /** yajl is an event driven parser.  this means as json elements are
50767de84eSFilipe David Borba Manana      *  parsed, you are called back to do something with the data.  The
51767de84eSFilipe David Borba Manana      *  functions in this table indicate the various events for which
52767de84eSFilipe David Borba Manana      *  you will be called back.  Each callback accepts a "context"
53767de84eSFilipe David Borba Manana      *  pointer, this is a void * that is passed into the yajl_parse
54767de84eSFilipe David Borba Manana      *  function which the client code may use to pass around context.
55767de84eSFilipe David Borba Manana      *
56767de84eSFilipe David Borba Manana      *  All callbacks return an integer.  If non-zero, the parse will
57767de84eSFilipe David Borba Manana      *  continue.  If zero, the parse will be canceled and
58767de84eSFilipe David Borba Manana      *  yajl_status_client_canceled will be returned from the parse.
59767de84eSFilipe David Borba Manana      *
60767de84eSFilipe David Borba Manana      *  \attention {
61767de84eSFilipe David Borba Manana      *    A note about the handling of numbers:
62767de84eSFilipe David Borba Manana      *
63767de84eSFilipe David Borba Manana      *    yajl will only convert numbers that can be represented in a
64767de84eSFilipe David Borba Manana      *    double or a 64 bit (long long) int.  All other numbers will
65767de84eSFilipe David Borba Manana      *    be passed to the client in string form using the yajl_number
66767de84eSFilipe David Borba Manana      *    callback.  Furthermore, if yajl_number is not NULL, it will
67767de84eSFilipe David Borba Manana      *    always be used to return numbers, that is yajl_integer and
68767de84eSFilipe David Borba Manana      *    yajl_double will be ignored.  If yajl_number is NULL but one
69767de84eSFilipe David Borba Manana      *    of yajl_integer or yajl_double are defined, parsing of a
70767de84eSFilipe David Borba Manana      *    number larger than is representable in a double or 64 bit
71767de84eSFilipe David Borba Manana      *    integer will result in a parse error.
72767de84eSFilipe David Borba Manana      *  }
73767de84eSFilipe David Borba Manana      */
74767de84eSFilipe David Borba Manana     typedef struct {
75767de84eSFilipe David Borba Manana         int (* yajl_null)(void * ctx);
76767de84eSFilipe David Borba Manana         int (* yajl_boolean)(void * ctx, int boolVal);
77767de84eSFilipe David Borba Manana         int (* yajl_integer)(void * ctx, long long integerVal);
78767de84eSFilipe David Borba Manana         int (* yajl_double)(void * ctx, double doubleVal);
79767de84eSFilipe David Borba Manana         /** A callback which passes the string representation of the number
80767de84eSFilipe David Borba Manana          *  back to the client.  Will be used for all numbers when present */
81767de84eSFilipe David Borba Manana         int (* yajl_number)(void * ctx, const char * numberVal,
82767de84eSFilipe David Borba Manana                             size_t numberLen);
83767de84eSFilipe David Borba Manana 
84767de84eSFilipe David Borba Manana         /** strings are returned as pointers into the JSON text when,
85767de84eSFilipe David Borba Manana          * possible, as a result, they are _not_ null padded */
86767de84eSFilipe David Borba Manana         int (* yajl_string)(void * ctx, const unsigned char * stringVal,
87767de84eSFilipe David Borba Manana                             size_t stringLen);
88767de84eSFilipe David Borba Manana 
89767de84eSFilipe David Borba Manana         int (* yajl_start_map)(void * ctx);
90767de84eSFilipe David Borba Manana         int (* yajl_map_key)(void * ctx, const unsigned char * key,
91767de84eSFilipe David Borba Manana                              size_t stringLen);
92767de84eSFilipe David Borba Manana         int (* yajl_end_map)(void * ctx);
93767de84eSFilipe David Borba Manana 
94767de84eSFilipe David Borba Manana         int (* yajl_start_array)(void * ctx);
95767de84eSFilipe David Borba Manana         int (* yajl_end_array)(void * ctx);
96767de84eSFilipe David Borba Manana     } yajl_callbacks;
97767de84eSFilipe David Borba Manana 
98767de84eSFilipe David Borba Manana     /** allocate a parser handle
99767de84eSFilipe David Borba Manana      *  \param callbacks  a yajl callbacks structure specifying the
100767de84eSFilipe David Borba Manana      *                    functions to call when different JSON entities
101767de84eSFilipe David Borba Manana      *                    are encountered in the input text.  May be NULL,
102767de84eSFilipe David Borba Manana      *                    which is only useful for validation.
103767de84eSFilipe David Borba Manana      *  \param afs        memory allocation functions, may be NULL for to use
104767de84eSFilipe David Borba Manana      *                    C runtime library routines (malloc and friends)
105767de84eSFilipe David Borba Manana      *  \param ctx        a context pointer that will be passed to callbacks.
106767de84eSFilipe David Borba Manana      */
107767de84eSFilipe David Borba Manana     YAJL_API yajl_handle yajl_alloc(const yajl_callbacks * callbacks,
108767de84eSFilipe David Borba Manana                                     yajl_alloc_funcs * afs,
109767de84eSFilipe David Borba Manana                                     void * ctx);
110767de84eSFilipe David Borba Manana 
111767de84eSFilipe David Borba Manana 
112767de84eSFilipe David Borba Manana     /** configuration parameters for the parser, these may be passed to
113767de84eSFilipe David Borba Manana      *  yajl_config() along with option specific argument(s).  In general,
114767de84eSFilipe David Borba Manana      *  all configuration parameters default to *off*. */
115767de84eSFilipe David Borba Manana     typedef enum {
116767de84eSFilipe David Borba Manana         /** Ignore javascript style comments present in
117767de84eSFilipe David Borba Manana          *  JSON input.  Non-standard, but rather fun
118767de84eSFilipe David Borba Manana          *  arguments: toggled off with integer zero, on otherwise.
119767de84eSFilipe David Borba Manana          *
120767de84eSFilipe David Borba Manana          *  example:
121767de84eSFilipe David Borba Manana          *    yajl_config(h, yajl_allow_comments, 1); // turn comment support on
122767de84eSFilipe David Borba Manana          */
123767de84eSFilipe David Borba Manana         yajl_allow_comments = 0x01,
124767de84eSFilipe David Borba Manana         /**
125767de84eSFilipe David Borba Manana          * When set the parser will verify that all strings in JSON input are
126767de84eSFilipe David Borba Manana          * valid UTF8 and will emit a parse error if this is not so.  When set,
127767de84eSFilipe David Borba Manana          * this option makes parsing slightly more expensive (~7% depending
128767de84eSFilipe David Borba Manana          * on processor and compiler in use)
129767de84eSFilipe David Borba Manana          *
130767de84eSFilipe David Borba Manana          * example:
131767de84eSFilipe David Borba Manana          *   yajl_config(h, yajl_dont_validate_strings, 1); // disable utf8 checking
132767de84eSFilipe David Borba Manana          */
133767de84eSFilipe David Borba Manana         yajl_dont_validate_strings     = 0x02,
134767de84eSFilipe David Borba Manana         /**
135767de84eSFilipe David Borba Manana          * By default, upon calls to yajl_complete_parse(), yajl will
136767de84eSFilipe David Borba Manana          * ensure the entire input text was consumed and will raise an error
137767de84eSFilipe David Borba Manana          * otherwise.  Enabling this flag will cause yajl to disable this
138767de84eSFilipe David Borba Manana          * check.  This can be useful when parsing json out of a that contains more
139767de84eSFilipe David Borba Manana          * than a single JSON document.
140767de84eSFilipe David Borba Manana          */
141767de84eSFilipe David Borba Manana         yajl_allow_trailing_garbage = 0x04,
142767de84eSFilipe David Borba Manana         /**
143767de84eSFilipe David Borba Manana          * Allow multiple values to be parsed by a single handle.  The
144767de84eSFilipe David Borba Manana          * entire text must be valid JSON, and values can be seperated
145767de84eSFilipe David Borba Manana          * by any kind of whitespace.  This flag will change the
146767de84eSFilipe David Borba Manana          * behavior of the parser, and cause it continue parsing after
147767de84eSFilipe David Borba Manana          * a value is parsed, rather than transitioning into a
148767de84eSFilipe David Borba Manana          * complete state.  This option can be useful when parsing multiple
149767de84eSFilipe David Borba Manana          * values from an input stream.
150767de84eSFilipe David Borba Manana          */
151767de84eSFilipe David Borba Manana         yajl_allow_multiple_values = 0x08,
152767de84eSFilipe David Borba Manana         /**
153767de84eSFilipe David Borba Manana          * When yajl_complete_parse() is called the parser will
154767de84eSFilipe David Borba Manana          * check that the top level value was completely consumed.  I.E.,
155767de84eSFilipe David Borba Manana          * if called whilst in the middle of parsing a value
156767de84eSFilipe David Borba Manana          * yajl will enter an error state (premature EOF).  Setting this
157767de84eSFilipe David Borba Manana          * flag suppresses that check and the corresponding error.
158767de84eSFilipe David Borba Manana          */
159*588f33dcSFilipe David Borba Manana         yajl_allow_partial_values = 0x10,
160*588f33dcSFilipe David Borba Manana         /**
161*588f33dcSFilipe David Borba Manana            By default YAJL unescapes strings before passing them to the
162*588f33dcSFilipe David Borba Manana            string callback function. This options disables that behaviour.
163*588f33dcSFilipe David Borba Manana            Some applications might want the string escaped, and without this
164*588f33dcSFilipe David Borba Manana            option their string callback would have to escape the input string.
165*588f33dcSFilipe David Borba Manana          */
166*588f33dcSFilipe David Borba Manana         yajl_dont_unescape_strings = 0x20
167767de84eSFilipe David Borba Manana     } yajl_option;
168767de84eSFilipe David Borba Manana 
169767de84eSFilipe David Borba Manana     /** allow the modification of parser options subsequent to handle
170767de84eSFilipe David Borba Manana      *  allocation (via yajl_alloc)
171767de84eSFilipe David Borba Manana      *  \returns zero in case of errors, non-zero otherwise
172767de84eSFilipe David Borba Manana      */
173767de84eSFilipe David Borba Manana     YAJL_API int yajl_config(yajl_handle h, yajl_option opt, ...);
174767de84eSFilipe David Borba Manana 
175767de84eSFilipe David Borba Manana     /** free a parser handle */
176767de84eSFilipe David Borba Manana     YAJL_API void yajl_free(yajl_handle handle);
177767de84eSFilipe David Borba Manana 
178767de84eSFilipe David Borba Manana     /** Parse some json!
179767de84eSFilipe David Borba Manana      *  \param hand - a handle to the json parser allocated with yajl_alloc
180767de84eSFilipe David Borba Manana      *  \param jsonText - a pointer to the UTF8 json text to be parsed
181767de84eSFilipe David Borba Manana      *  \param jsonTextLength - the length, in bytes, of input text
182767de84eSFilipe David Borba Manana      */
183767de84eSFilipe David Borba Manana     YAJL_API yajl_status yajl_parse(yajl_handle hand,
184767de84eSFilipe David Borba Manana                                     const unsigned char * jsonText,
185767de84eSFilipe David Borba Manana                                     size_t jsonTextLength);
186767de84eSFilipe David Borba Manana 
187767de84eSFilipe David Borba Manana     /** Parse any remaining buffered json.
188767de84eSFilipe David Borba Manana      *  Since yajl is a stream-based parser, without an explicit end of
189767de84eSFilipe David Borba Manana      *  input, yajl sometimes can't decide if content at the end of the
190767de84eSFilipe David Borba Manana      *  stream is valid or not.  For example, if "1" has been fed in,
191767de84eSFilipe David Borba Manana      *  yajl can't know whether another digit is next or some character
192767de84eSFilipe David Borba Manana      *  that would terminate the integer token.
193767de84eSFilipe David Borba Manana      *
194767de84eSFilipe David Borba Manana      *  \param hand - a handle to the json parser allocated with yajl_alloc
195767de84eSFilipe David Borba Manana      */
196767de84eSFilipe David Borba Manana     YAJL_API yajl_status yajl_complete_parse(yajl_handle hand);
197767de84eSFilipe David Borba Manana 
198767de84eSFilipe David Borba Manana     /** get an error string describing the state of the
199767de84eSFilipe David Borba Manana      *  parse.
200767de84eSFilipe David Borba Manana      *
201767de84eSFilipe David Borba Manana      *  If verbose is non-zero, the message will include the JSON
202767de84eSFilipe David Borba Manana      *  text where the error occured, along with an arrow pointing to
203767de84eSFilipe David Borba Manana      *  the specific char.
204767de84eSFilipe David Borba Manana      *
205767de84eSFilipe David Borba Manana      *  \returns A dynamically allocated string will be returned which should
206767de84eSFilipe David Borba Manana      *  be freed with yajl_free_error
207767de84eSFilipe David Borba Manana      */
208767de84eSFilipe David Borba Manana     YAJL_API unsigned char * yajl_get_error(yajl_handle hand, int verbose,
209767de84eSFilipe David Borba Manana                                             const unsigned char * jsonText,
210767de84eSFilipe David Borba Manana                                             size_t jsonTextLength);
211767de84eSFilipe David Borba Manana 
212767de84eSFilipe David Borba Manana     /**
213767de84eSFilipe David Borba Manana      * get the amount of data consumed from the last chunk passed to YAJL.
214767de84eSFilipe David Borba Manana      *
215767de84eSFilipe David Borba Manana      * In the case of a successful parse this can help you understand if
216767de84eSFilipe David Borba Manana      * the entire buffer was consumed (which will allow you to handle
217767de84eSFilipe David Borba Manana      * "junk at end of input").
218767de84eSFilipe David Borba Manana      *
219767de84eSFilipe David Borba Manana      * In the event an error is encountered during parsing, this function
220767de84eSFilipe David Borba Manana      * affords the client a way to get the offset into the most recent
221767de84eSFilipe David Borba Manana      * chunk where the error occured.  0 will be returned if no error
222767de84eSFilipe David Borba Manana      * was encountered.
223767de84eSFilipe David Borba Manana      */
224767de84eSFilipe David Borba Manana     YAJL_API size_t yajl_get_bytes_consumed(yajl_handle hand);
225767de84eSFilipe David Borba Manana 
226767de84eSFilipe David Borba Manana     /** free an error returned from yajl_get_error */
227767de84eSFilipe David Borba Manana     YAJL_API void yajl_free_error(yajl_handle hand, unsigned char * str);
228767de84eSFilipe David Borba Manana 
229767de84eSFilipe David Borba Manana #ifdef __cplusplus
230767de84eSFilipe David Borba Manana }
231767de84eSFilipe David Borba Manana #endif
232767de84eSFilipe David Borba Manana 
233767de84eSFilipe David Borba Manana #endif
234