yajl_parse.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * Copyright (c) 2007-2014, Lloyd Hilaiel <me@lloyd.io>
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. /**
  17. * \file yajl_parse.h
  18. * Interface to YAJL's JSON stream parsing facilities.
  19. */
  20. #include "yajl_common.h"
  21. #ifndef __YAJL_PARSE_H__
  22. #define __YAJL_PARSE_H__
  23. #include <stddef.h>
  24. #ifdef __cplusplus
  25. extern "C" {
  26. #endif
  27. /** error codes returned from this interface */
  28. typedef enum {
  29. /** no error was encountered */
  30. yajl_status_ok,
  31. /** a client callback returned zero, stopping the parse */
  32. yajl_status_client_canceled,
  33. /** An error occured during the parse. Call yajl_get_error for
  34. * more information about the encountered error */
  35. yajl_status_error
  36. } yajl_status;
  37. /** attain a human readable, english, string for an error */
  38. YAJL_API const char * yajl_status_to_string(yajl_status code);
  39. /** an opaque handle to a parser */
  40. typedef struct yajl_handle_t * yajl_handle;
  41. /** yajl is an event driven parser. this means as json elements are
  42. * parsed, you are called back to do something with the data. The
  43. * functions in this table indicate the various events for which
  44. * you will be called back. Each callback accepts a "context"
  45. * pointer, this is a void * that is passed into the yajl_parse
  46. * function which the client code may use to pass around context.
  47. *
  48. * All callbacks return an integer. If non-zero, the parse will
  49. * continue. If zero, the parse will be canceled and
  50. * yajl_status_client_canceled will be returned from the parse.
  51. *
  52. * \attention {
  53. * A note about the handling of numbers:
  54. *
  55. * yajl will only convert numbers that can be represented in a
  56. * double or a 64 bit (long long) int. All other numbers will
  57. * be passed to the client in string form using the yajl_number
  58. * callback. Furthermore, if yajl_number is not NULL, it will
  59. * always be used to return numbers, that is yajl_integer,
  60. * yajl_unsigned_integer and yajl_double will be ignored.
  61. * If yajl_number is NULL but one of yajl_integer or
  62. * yajl_double are defined, parsing of a number larger than
  63. * is representable in a double or 64 bit integer will result
  64. * in a parse error.
  65. * }
  66. */
  67. typedef struct {
  68. int (* yajl_null)(void * ctx);
  69. int (* yajl_boolean)(void * ctx, int boolVal);
  70. int (* yajl_integer)(void * ctx, long long integerVal);
  71. int (* yajl_unsigned_integer)(void * ctx, unsigned long long integerVal);
  72. int (* yajl_double)(void * ctx, double doubleVal);
  73. /** A callback which passes the string representation of the number
  74. * back to the client. Will be used for all numbers when present */
  75. int (* yajl_number)(void * ctx, const char * numberVal,
  76. size_t numberLen);
  77. /** strings are returned as pointers into the JSON text when,
  78. * possible, as a result, they are _not_ null padded */
  79. int (* yajl_string)(void * ctx, const unsigned char * stringVal,
  80. size_t stringLen);
  81. int (* yajl_start_map)(void * ctx);
  82. int (* yajl_map_key)(void * ctx, const unsigned char * key,
  83. size_t stringLen);
  84. int (* yajl_end_map)(void * ctx);
  85. int (* yajl_start_array)(void * ctx);
  86. int (* yajl_end_array)(void * ctx);
  87. } yajl_callbacks;
  88. /** allocate a parser handle
  89. * \param callbacks a yajl callbacks structure specifying the
  90. * functions to call when different JSON entities
  91. * are encountered in the input text. May be NULL,
  92. * which is only useful for validation.
  93. * \param afs memory allocation functions, may be NULL for to use
  94. * C runtime library routines (malloc and friends)
  95. * \param ctx a context pointer that will be passed to callbacks.
  96. */
  97. YAJL_API yajl_handle yajl_alloc(const yajl_callbacks * callbacks,
  98. yajl_alloc_funcs * afs,
  99. void * ctx);
  100. /** configuration parameters for the parser, these may be passed to
  101. * yajl_config() along with option specific argument(s). In general,
  102. * all configuration parameters default to *off*. */
  103. typedef enum {
  104. /** Ignore javascript style comments present in
  105. * JSON input. Non-standard, but rather fun
  106. * arguments: toggled off with integer zero, on otherwise.
  107. *
  108. * example:
  109. * yajl_config(h, yajl_allow_comments, 1); // turn comment support on
  110. */
  111. yajl_allow_comments = 0x01,
  112. /**
  113. * When set the parser will verify that all strings in JSON input are
  114. * valid UTF8 and will emit a parse error if this is not so. When set,
  115. * this option makes parsing slightly more expensive (~7% depending
  116. * on processor and compiler in use)
  117. *
  118. * example:
  119. * yajl_config(h, yajl_dont_validate_strings, 1); // disable utf8 checking
  120. */
  121. yajl_dont_validate_strings = 0x02,
  122. /**
  123. * By default, upon calls to yajl_complete_parse(), yajl will
  124. * ensure the entire input text was consumed and will raise an error
  125. * otherwise. Enabling this flag will cause yajl to disable this
  126. * check. This can be useful when parsing json out of a that contains more
  127. * than a single JSON document.
  128. */
  129. yajl_allow_trailing_garbage = 0x04,
  130. /**
  131. * Allow multiple values to be parsed by a single handle. The
  132. * entire text must be valid JSON, and values can be seperated
  133. * by any kind of whitespace. This flag will change the
  134. * behavior of the parser, and cause it continue parsing after
  135. * a value is parsed, rather than transitioning into a
  136. * complete state. This option can be useful when parsing multiple
  137. * values from an input stream.
  138. */
  139. yajl_allow_multiple_values = 0x08,
  140. /**
  141. * When yajl_complete_parse() is called the parser will
  142. * check that the top level value was completely consumed. I.E.,
  143. * if called whilst in the middle of parsing a value
  144. * yajl will enter an error state (premature EOF). Setting this
  145. * flag suppresses that check and the corresponding error.
  146. */
  147. yajl_allow_partial_values = 0x10
  148. } yajl_option;
  149. /** allow the modification of parser options subsequent to handle
  150. * allocation (via yajl_alloc)
  151. * \returns zero in case of errors, non-zero otherwise
  152. */
  153. YAJL_API int yajl_config(yajl_handle h, yajl_option opt, ...);
  154. /** set limit for total size of internal buffers */
  155. YAJL_API void yajl_set_memory_limit(yajl_handle h, unsigned long limit);
  156. /** free a parser handle */
  157. YAJL_API void yajl_free(yajl_handle handle);
  158. /** Parse some json!
  159. * \param hand - a handle to the json parser allocated with yajl_alloc
  160. * \param jsonText - a pointer to the UTF8 json text to be parsed
  161. * \param jsonTextLength - the length, in bytes, of input text
  162. */
  163. YAJL_API yajl_status yajl_parse(yajl_handle hand,
  164. const unsigned char * jsonText,
  165. size_t jsonTextLength);
  166. /** Parse any remaining buffered json.
  167. * Since yajl is a stream-based parser, without an explicit end of
  168. * input, yajl sometimes can't decide if content at the end of the
  169. * stream is valid or not. For example, if "1" has been fed in,
  170. * yajl can't know whether another digit is next or some character
  171. * that would terminate the integer token.
  172. *
  173. * \param hand - a handle to the json parser allocated with yajl_alloc
  174. */
  175. YAJL_API yajl_status yajl_complete_parse(yajl_handle hand);
  176. /** get an error string describing the state of the
  177. * parse.
  178. *
  179. * If verbose is non-zero, the message will include the JSON
  180. * text where the error occured, along with an arrow pointing to
  181. * the specific char.
  182. *
  183. * \returns A dynamically allocated string will be returned which should
  184. * be freed with yajl_free_error
  185. */
  186. YAJL_API unsigned char * yajl_get_error(yajl_handle hand, int verbose,
  187. const unsigned char * jsonText,
  188. size_t jsonTextLength);
  189. /**
  190. * get the amount of data consumed from the last chunk passed to YAJL.
  191. *
  192. * In the case of a successful parse this can help you understand if
  193. * the entire buffer was consumed (which will allow you to handle
  194. * "junk at end of input").
  195. *
  196. * In the event an error is encountered during parsing, this function
  197. * affords the client a way to get the offset into the most recent
  198. * chunk where the error occured. 0 will be returned if no error
  199. * was encountered.
  200. */
  201. YAJL_API size_t yajl_get_bytes_consumed(yajl_handle hand);
  202. /** free an error returned from yajl_get_error */
  203. YAJL_API void yajl_free_error(yajl_handle hand, unsigned char * str);
  204. #ifdef __cplusplus
  205. }
  206. #endif
  207. #endif