Home | History | Annotate | Download | only in json-c
      1 /*
      2  * $Id: json_tokener.h,v 1.10 2006/07/25 03:24:50 mclark Exp $
      3  *
      4  * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
      5  * Michael Clark <michael (at) metaparadigm.com>
      6  *
      7  * This library is free software; you can redistribute it and/or modify
      8  * it under the terms of the MIT license. See COPYING for details.
      9  *
     10  */
     11 
     12 #ifndef _json_tokener_h_
     13 #define _json_tokener_h_
     14 
     15 #include <stddef.h>
     16 #include "json_object.h"
     17 
     18 #ifdef __cplusplus
     19 extern "C" {
     20 #endif
     21 
     22 enum json_tokener_error {
     23   json_tokener_success,
     24   json_tokener_continue,
     25   json_tokener_error_depth,
     26   json_tokener_error_parse_eof,
     27   json_tokener_error_parse_unexpected,
     28   json_tokener_error_parse_null,
     29   json_tokener_error_parse_boolean,
     30   json_tokener_error_parse_number,
     31   json_tokener_error_parse_array,
     32   json_tokener_error_parse_object_key_name,
     33   json_tokener_error_parse_object_key_sep,
     34   json_tokener_error_parse_object_value_sep,
     35   json_tokener_error_parse_string,
     36   json_tokener_error_parse_comment,
     37   json_tokener_error_size
     38 };
     39 
     40 enum json_tokener_state {
     41   json_tokener_state_eatws,
     42   json_tokener_state_start,
     43   json_tokener_state_finish,
     44   json_tokener_state_null,
     45   json_tokener_state_comment_start,
     46   json_tokener_state_comment,
     47   json_tokener_state_comment_eol,
     48   json_tokener_state_comment_end,
     49   json_tokener_state_string,
     50   json_tokener_state_string_escape,
     51   json_tokener_state_escape_unicode,
     52   json_tokener_state_boolean,
     53   json_tokener_state_number,
     54   json_tokener_state_array,
     55   json_tokener_state_array_add,
     56   json_tokener_state_array_sep,
     57   json_tokener_state_object_field_start,
     58   json_tokener_state_object_field,
     59   json_tokener_state_object_field_end,
     60   json_tokener_state_object_value,
     61   json_tokener_state_object_value_add,
     62   json_tokener_state_object_sep,
     63   json_tokener_state_array_after_sep,
     64   json_tokener_state_object_field_start_after_sep,
     65   json_tokener_state_inf
     66 };
     67 
     68 struct json_tokener_srec
     69 {
     70   enum json_tokener_state state, saved_state;
     71   struct json_object *obj;
     72   struct json_object *current;
     73   char *obj_field_name;
     74 };
     75 
     76 #define JSON_TOKENER_DEFAULT_DEPTH 32
     77 
     78 struct json_tokener
     79 {
     80   char *str;
     81   struct printbuf *pb;
     82   int max_depth, depth, is_double, st_pos, char_offset;
     83   enum json_tokener_error err;
     84   unsigned int ucs_char;
     85   char quote_char;
     86   struct json_tokener_srec *stack;
     87   int flags;
     88 };
     89 
     90 /**
     91  * Be strict when parsing JSON input.  Use caution with
     92  * this flag as what is considered valid may become more
     93  * restrictive from one release to the next, causing your
     94  * code to fail on previously working input.
     95  *
     96  * This flag is not set by default.
     97  *
     98  * @see json_tokener_set_flags()
     99  */
    100 #define JSON_TOKENER_STRICT  0x01
    101 
    102 /**
    103  * Given an error previously returned by json_tokener_get_error(),
    104  * return a human readable description of the error.
    105  *
    106  * @return a generic error message is returned if an invalid error value is provided.
    107  */
    108 const char *json_tokener_error_desc(enum json_tokener_error jerr);
    109 
    110 /**
    111  * Retrieve the error caused by the last call to json_tokener_parse_ex(),
    112  * or json_tokener_success if there is no error.
    113  *
    114  * When parsing a JSON string in pieces, if the tokener is in the middle
    115  * of parsing this will return json_tokener_continue.
    116  *
    117  * See also json_tokener_error_desc().
    118  */
    119 enum json_tokener_error json_tokener_get_error(struct json_tokener *tok);
    120 
    121 extern struct json_tokener* json_tokener_new(void);
    122 extern struct json_tokener* json_tokener_new_ex(int depth);
    123 extern void json_tokener_free(struct json_tokener *tok);
    124 extern void json_tokener_reset(struct json_tokener *tok);
    125 extern struct json_object* json_tokener_parse(const char *str);
    126 extern struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error);
    127 
    128 /**
    129  * Set flags that control how parsing will be done.
    130  */
    131 extern void json_tokener_set_flags(struct json_tokener *tok, int flags);
    132 
    133 /**
    134  * Parse a string and return a non-NULL json_object if a valid JSON value
    135  * is found.  The string does not need to be a JSON object or array;
    136  * it can also be a string, number or boolean value.
    137  *
    138  * A partial JSON string can be parsed.  If the parsing is incomplete,
    139  * NULL will be returned and json_tokener_get_error() will be return
    140  * json_tokener_continue.
    141  * json_tokener_parse_ex() can then be called with additional bytes in str
    142  * to continue the parsing.
    143  *
    144  * If json_tokener_parse_ex() returns NULL and the error anything other than
    145  * json_tokener_continue, a fatal error has occurred and parsing must be
    146  * halted.  Then tok object must not be re-used until json_tokener_reset() is
    147  * called.
    148  *
    149  * When a valid JSON value is parsed, a non-NULL json_object will be
    150  * returned.  Also, json_tokener_get_error() will return json_tokener_success.
    151  * Be sure to check the type with json_object_is_type() or
    152  * json_object_get_type() before using the object.
    153  *
    154  * @b XXX this shouldn't use internal fields:
    155  * Trailing characters after the parsed value do not automatically cause an
    156  * error.  It is up to the caller to decide whether to treat this as an
    157  * error or to handle the additional characters, perhaps by parsing another
    158  * json value starting from that point.
    159  *
    160  * Extra characters can be detected by comparing the tok->char_offset against
    161  * the length of the last len parameter passed in.
    162  *
    163  * The tokener does \b not maintain an internal buffer so the caller is
    164  * responsible for calling json_tokener_parse_ex with an appropriate str
    165  * parameter starting with the extra characters.
    166  *
    167  * This interface is presently not 64-bit clean due to the int len argument
    168  * so the function limits the maximum string size to INT32_MAX (2GB).
    169  * If the function is called with len == -1 then strlen is called to check
    170  * the string length is less than INT32_MAX (2GB)
    171  *
    172  * Example:
    173  * @code
    174 json_object *jobj = NULL;
    175 const char *mystring = NULL;
    176 int stringlen = 0;
    177 enum json_tokener_error jerr;
    178 do {
    179 	mystring = ...  // get JSON string, e.g. read from file, etc...
    180 	stringlen = strlen(mystring);
    181 	jobj = json_tokener_parse_ex(tok, mystring, stringlen);
    182 } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
    183 if (jerr != json_tokener_success)
    184 {
    185 	fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
    186 	// Handle errors, as appropriate for your application.
    187 }
    188 if (tok->char_offset < stringlen) // XXX shouldn't access internal fields
    189 {
    190 	// Handle extra characters after parsed object as desired.
    191 	// e.g. issue an error, parse another object from that point, etc...
    192 }
    193 // Success, use jobj here.
    194 
    195 @endcode
    196  *
    197  * @param tok a json_tokener previously allocated with json_tokener_new()
    198  * @param str an string with any valid JSON expression, or portion of.  This does not need to be null terminated.
    199  * @param len the length of str
    200  */
    201 extern struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
    202 						 const char *str, int len);
    203 
    204 #ifdef __cplusplus
    205 }
    206 #endif
    207 
    208 #endif
    209