xref: /5.5.2/couchdb/src/ejson/yajl/yajl_parse.h (revision 3925e856)
1*3925e856SFilipe David Borba Manana /*
2*3925e856SFilipe David Borba Manana  * Copyright 2010, Lloyd Hilaiel.
3*3925e856SFilipe David Borba Manana  *
4*3925e856SFilipe David Borba Manana  * Redistribution and use in source and binary forms, with or without
5*3925e856SFilipe David Borba Manana  * modification, are permitted provided that the following conditions are
6*3925e856SFilipe David Borba Manana  * met:
7*3925e856SFilipe David Borba Manana  *
8*3925e856SFilipe David Borba Manana  *  1. Redistributions of source code must retain the above copyright
9*3925e856SFilipe David Borba Manana  *     notice, this list of conditions and the following disclaimer.
10*3925e856SFilipe David Borba Manana  *
11*3925e856SFilipe David Borba Manana  *  2. Redistributions in binary form must reproduce the above copyright
12*3925e856SFilipe David Borba Manana  *     notice, this list of conditions and the following disclaimer in
13*3925e856SFilipe David Borba Manana  *     the documentation and/or other materials provided with the
14*3925e856SFilipe David Borba Manana  *     distribution.
15*3925e856SFilipe David Borba Manana  *
16*3925e856SFilipe David Borba Manana  *  3. Neither the name of Lloyd Hilaiel nor the names of its
17*3925e856SFilipe David Borba Manana  *     contributors may be used to endorse or promote products derived
18*3925e856SFilipe David Borba Manana  *     from this software without specific prior written permission.
19*3925e856SFilipe David Borba Manana  *
20*3925e856SFilipe David Borba Manana  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21*3925e856SFilipe David Borba Manana  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22*3925e856SFilipe David Borba Manana  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23*3925e856SFilipe David Borba Manana  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24*3925e856SFilipe David Borba Manana  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25*3925e856SFilipe David Borba Manana  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26*3925e856SFilipe David Borba Manana  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*3925e856SFilipe David Borba Manana  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28*3925e856SFilipe David Borba Manana  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29*3925e856SFilipe David Borba Manana  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30*3925e856SFilipe David Borba Manana  * POSSIBILITY OF SUCH DAMAGE.
31*3925e856SFilipe David Borba Manana  */
32*3925e856SFilipe David Borba Manana 
33*3925e856SFilipe David Borba Manana /**
34*3925e856SFilipe David Borba Manana  * \file yajl_parse.h
35*3925e856SFilipe David Borba Manana  * Interface to YAJL's JSON parsing facilities.
36*3925e856SFilipe David Borba Manana  */
37*3925e856SFilipe David Borba Manana 
38*3925e856SFilipe David Borba Manana #include "yajl_common.h"
39*3925e856SFilipe David Borba Manana 
40*3925e856SFilipe David Borba Manana #ifndef __YAJL_PARSE_H__
41*3925e856SFilipe David Borba Manana #define __YAJL_PARSE_H__
42*3925e856SFilipe David Borba Manana 
43*3925e856SFilipe David Borba Manana #ifdef __cplusplus
44*3925e856SFilipe David Borba Manana extern "C" {
45*3925e856SFilipe David Borba Manana #endif
46*3925e856SFilipe David Borba Manana     /** error codes returned from this interface */
47*3925e856SFilipe David Borba Manana     typedef enum {
48*3925e856SFilipe David Borba Manana         /** no error was encountered */
49*3925e856SFilipe David Borba Manana         yajl_status_ok,
50*3925e856SFilipe David Borba Manana         /** a client callback returned zero, stopping the parse */
51*3925e856SFilipe David Borba Manana         yajl_status_client_canceled,
52*3925e856SFilipe David Borba Manana         /** The parse cannot yet complete because more json input text
53*3925e856SFilipe David Borba Manana          *  is required, call yajl_parse with the next buffer of input text.
54*3925e856SFilipe David Borba Manana          *  (pertinent only when stream parsing) */
55*3925e856SFilipe David Borba Manana         yajl_status_insufficient_data,
56*3925e856SFilipe David Borba Manana         /** An error occured during the parse.  Call yajl_get_error for
57*3925e856SFilipe David Borba Manana          *  more information about the encountered error */
58*3925e856SFilipe David Borba Manana         yajl_status_error
59*3925e856SFilipe David Borba Manana     } yajl_status;
60*3925e856SFilipe David Borba Manana 
61*3925e856SFilipe David Borba Manana     /** attain a human readable, english, string for an error */
62*3925e856SFilipe David Borba Manana     YAJL_API const char * yajl_status_to_string(yajl_status code);
63*3925e856SFilipe David Borba Manana 
64*3925e856SFilipe David Borba Manana     /** an opaque handle to a parser */
65*3925e856SFilipe David Borba Manana     typedef struct yajl_handle_t * yajl_handle;
66*3925e856SFilipe David Borba Manana 
67*3925e856SFilipe David Borba Manana     /** yajl is an event driven parser.  this means as json elements are
68*3925e856SFilipe David Borba Manana      *  parsed, you are called back to do something with the data.  The
69*3925e856SFilipe David Borba Manana      *  functions in this table indicate the various events for which
70*3925e856SFilipe David Borba Manana      *  you will be called back.  Each callback accepts a "context"
71*3925e856SFilipe David Borba Manana      *  pointer, this is a void * that is passed into the yajl_parse
72*3925e856SFilipe David Borba Manana      *  function which the client code may use to pass around context.
73*3925e856SFilipe David Borba Manana      *
74*3925e856SFilipe David Borba Manana      *  All callbacks return an integer.  If non-zero, the parse will
75*3925e856SFilipe David Borba Manana      *  continue.  If zero, the parse will be canceled and
76*3925e856SFilipe David Borba Manana      *  yajl_status_client_canceled will be returned from the parse.
77*3925e856SFilipe David Borba Manana      *
78*3925e856SFilipe David Borba Manana      *  Note about handling of numbers:
79*3925e856SFilipe David Borba Manana      *    yajl will only convert numbers that can be represented in a double
80*3925e856SFilipe David Borba Manana      *    or a long int.  All other numbers will be passed to the client
81*3925e856SFilipe David Borba Manana      *    in string form using the yajl_number callback.  Furthermore, if
82*3925e856SFilipe David Borba Manana      *    yajl_number is not NULL, it will always be used to return numbers,
83*3925e856SFilipe David Borba Manana      *    that is yajl_integer and yajl_double will be ignored.  If
84*3925e856SFilipe David Borba Manana      *    yajl_number is NULL but one of yajl_integer or yajl_double are
85*3925e856SFilipe David Borba Manana      *    defined, parsing of a number larger than is representable
86*3925e856SFilipe David Borba Manana      *    in a double or long int will result in a parse error.
87*3925e856SFilipe David Borba Manana      */
88*3925e856SFilipe David Borba Manana     typedef struct {
89*3925e856SFilipe David Borba Manana         int (* yajl_null)(void * ctx);
90*3925e856SFilipe David Borba Manana         int (* yajl_boolean)(void * ctx, int boolVal);
91*3925e856SFilipe David Borba Manana         int (* yajl_integer)(void * ctx, long integerVal);
92*3925e856SFilipe David Borba Manana         int (* yajl_double)(void * ctx, double doubleVal);
93*3925e856SFilipe David Borba Manana         /** A callback which passes the string representation of the number
94*3925e856SFilipe David Borba Manana          *  back to the client.  Will be used for all numbers when present */
95*3925e856SFilipe David Borba Manana         int (* yajl_number)(void * ctx, const char * numberVal,
96*3925e856SFilipe David Borba Manana                             unsigned int numberLen);
97*3925e856SFilipe David Borba Manana 
98*3925e856SFilipe David Borba Manana         /** strings are returned as pointers into the JSON text when,
99*3925e856SFilipe David Borba Manana          * possible, as a result, they are _not_ null padded */
100*3925e856SFilipe David Borba Manana         int (* yajl_string)(void * ctx, const unsigned char * stringVal,
101*3925e856SFilipe David Borba Manana                             unsigned int stringLen);
102*3925e856SFilipe David Borba Manana 
103*3925e856SFilipe David Borba Manana         int (* yajl_start_map)(void * ctx);
104*3925e856SFilipe David Borba Manana         int (* yajl_map_key)(void * ctx, const unsigned char * key,
105*3925e856SFilipe David Borba Manana                              unsigned int stringLen);
106*3925e856SFilipe David Borba Manana         int (* yajl_end_map)(void * ctx);
107*3925e856SFilipe David Borba Manana 
108*3925e856SFilipe David Borba Manana         int (* yajl_start_array)(void * ctx);
109*3925e856SFilipe David Borba Manana         int (* yajl_end_array)(void * ctx);
110*3925e856SFilipe David Borba Manana     } yajl_callbacks;
111*3925e856SFilipe David Borba Manana 
112*3925e856SFilipe David Borba Manana     /** configuration structure for the generator */
113*3925e856SFilipe David Borba Manana     typedef struct {
114*3925e856SFilipe David Borba Manana         /** if nonzero, javascript style comments will be allowed in
115*3925e856SFilipe David Borba Manana          *  the json input, both slash star and slash slash */
116*3925e856SFilipe David Borba Manana         unsigned int allowComments;
117*3925e856SFilipe David Borba Manana         /** if nonzero, invalid UTF8 strings will cause a parse
118*3925e856SFilipe David Borba Manana          *  error */
119*3925e856SFilipe David Borba Manana         unsigned int checkUTF8;
120*3925e856SFilipe David Borba Manana     } yajl_parser_config;
121*3925e856SFilipe David Borba Manana 
122*3925e856SFilipe David Borba Manana     /** allocate a parser handle
123*3925e856SFilipe David Borba Manana      *  \param callbacks  a yajl callbacks structure specifying the
124*3925e856SFilipe David Borba Manana      *                    functions to call when different JSON entities
125*3925e856SFilipe David Borba Manana      *                    are encountered in the input text.  May be NULL,
126*3925e856SFilipe David Borba Manana      *                    which is only useful for validation.
127*3925e856SFilipe David Borba Manana      *  \param config     configuration parameters for the parse.
128*3925e856SFilipe David Borba Manana      *  \param ctx        a context pointer that will be passed to callbacks.
129*3925e856SFilipe David Borba Manana      */
130*3925e856SFilipe David Borba Manana     YAJL_API yajl_handle yajl_alloc(const yajl_callbacks * callbacks,
131*3925e856SFilipe David Borba Manana                                     const yajl_parser_config * config,
132*3925e856SFilipe David Borba Manana                                     const yajl_alloc_funcs * allocFuncs,
133*3925e856SFilipe David Borba Manana                                     void * ctx);
134*3925e856SFilipe David Borba Manana 
135*3925e856SFilipe David Borba Manana     /** free a parser handle */
136*3925e856SFilipe David Borba Manana     YAJL_API void yajl_free(yajl_handle handle);
137*3925e856SFilipe David Borba Manana 
138*3925e856SFilipe David Borba Manana     /** Parse some json!
139*3925e856SFilipe David Borba Manana      *  \param hand - a handle to the json parser allocated with yajl_alloc
140*3925e856SFilipe David Borba Manana      *  \param jsonText - a pointer to the UTF8 json text to be parsed
141*3925e856SFilipe David Borba Manana      *  \param jsonTextLength - the length, in bytes, of input text
142*3925e856SFilipe David Borba Manana      */
143*3925e856SFilipe David Borba Manana     YAJL_API yajl_status yajl_parse(yajl_handle hand,
144*3925e856SFilipe David Borba Manana                                     const unsigned char * jsonText,
145*3925e856SFilipe David Borba Manana                                     unsigned int jsonTextLength);
146*3925e856SFilipe David Borba Manana 
147*3925e856SFilipe David Borba Manana     /** Parse any remaining buffered json.
148*3925e856SFilipe David Borba Manana      *  Since yajl is a stream-based parser, without an explicit end of
149*3925e856SFilipe David Borba Manana      *  input, yajl sometimes can't decide if content at the end of the
150*3925e856SFilipe David Borba Manana      *  stream is valid or not.  For example, if "1" has been fed in,
151*3925e856SFilipe David Borba Manana      *  yajl can't know whether another digit is next or some character
152*3925e856SFilipe David Borba Manana      *  that would terminate the integer token.
153*3925e856SFilipe David Borba Manana      *
154*3925e856SFilipe David Borba Manana      *  \param hand - a handle to the json parser allocated with yajl_alloc
155*3925e856SFilipe David Borba Manana      */
156*3925e856SFilipe David Borba Manana     YAJL_API yajl_status yajl_parse_complete(yajl_handle hand);
157*3925e856SFilipe David Borba Manana 
158*3925e856SFilipe David Borba Manana     /** get an error string describing the state of the
159*3925e856SFilipe David Borba Manana      *  parse.
160*3925e856SFilipe David Borba Manana      *
161*3925e856SFilipe David Borba Manana      *  If verbose is non-zero, the message will include the JSON
162*3925e856SFilipe David Borba Manana      *  text where the error occured, along with an arrow pointing to
163*3925e856SFilipe David Borba Manana      *  the specific char.
164*3925e856SFilipe David Borba Manana      *
165*3925e856SFilipe David Borba Manana      *  \returns A dynamically allocated string will be returned which should
166*3925e856SFilipe David Borba Manana      *  be freed with yajl_free_error
167*3925e856SFilipe David Borba Manana      */
168*3925e856SFilipe David Borba Manana     YAJL_API unsigned char * yajl_get_error(yajl_handle hand, int verbose,
169*3925e856SFilipe David Borba Manana                                             const unsigned char * jsonText,
170*3925e856SFilipe David Borba Manana                                             unsigned int jsonTextLength);
171*3925e856SFilipe David Borba Manana 
172*3925e856SFilipe David Borba Manana     /**
173*3925e856SFilipe David Borba Manana      * get the amount of data consumed from the last chunk passed to YAJL.
174*3925e856SFilipe David Borba Manana      *
175*3925e856SFilipe David Borba Manana      * In the case of a successful parse this can help you understand if
176*3925e856SFilipe David Borba Manana      * the entire buffer was consumed (which will allow you to handle
177*3925e856SFilipe David Borba Manana      * "junk at end of input".
178*3925e856SFilipe David Borba Manana      *
179*3925e856SFilipe David Borba Manana      * In the event an error is encountered during parsing, this function
180*3925e856SFilipe David Borba Manana      * affords the client a way to get the offset into the most recent
181*3925e856SFilipe David Borba Manana      * chunk where the error occured.  0 will be returned if no error
182*3925e856SFilipe David Borba Manana      * was encountered.
183*3925e856SFilipe David Borba Manana      */
184*3925e856SFilipe David Borba Manana     YAJL_API unsigned int yajl_get_bytes_consumed(yajl_handle hand);
185*3925e856SFilipe David Borba Manana 
186*3925e856SFilipe David Borba Manana     /** free an error returned from yajl_get_error */
187*3925e856SFilipe David Borba Manana     YAJL_API void yajl_free_error(yajl_handle hand, unsigned char * str);
188*3925e856SFilipe David Borba Manana 
189*3925e856SFilipe David Borba Manana #ifdef __cplusplus
190*3925e856SFilipe David Borba Manana }
191*3925e856SFilipe David Borba Manana #endif
192*3925e856SFilipe David Borba Manana 
193*3925e856SFilipe David Borba Manana #endif
194