1 /*------------------------------------------------------------------------- 2 * 3 * jsonapi.h 4 * Declarations for JSON API support. 5 * 6 * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group 7 * Portions Copyright (c) 1994, Regents of the University of California 8 * 9 * src/include/utils/jsonapi.h 10 * 11 *------------------------------------------------------------------------- 12 */ 13 14 #ifndef JSONAPI_H 15 #define JSONAPI_H 16 17 #include "lib/stringinfo.h" 18 19 typedef enum 20 { 21 JSON_TOKEN_INVALID, 22 JSON_TOKEN_STRING, 23 JSON_TOKEN_NUMBER, 24 JSON_TOKEN_OBJECT_START, 25 JSON_TOKEN_OBJECT_END, 26 JSON_TOKEN_ARRAY_START, 27 JSON_TOKEN_ARRAY_END, 28 JSON_TOKEN_COMMA, 29 JSON_TOKEN_COLON, 30 JSON_TOKEN_TRUE, 31 JSON_TOKEN_FALSE, 32 JSON_TOKEN_NULL, 33 JSON_TOKEN_END 34 } JsonTokenType; 35 36 typedef enum 37 { 38 JSON_SUCCESS, 39 JSON_ESCAPING_INVALID, 40 JSON_ESCAPING_REQUIRED, 41 JSON_EXPECTED_ARRAY_FIRST, 42 JSON_EXPECTED_ARRAY_NEXT, 43 JSON_EXPECTED_COLON, 44 JSON_EXPECTED_END, 45 JSON_EXPECTED_JSON, 46 JSON_EXPECTED_MORE, 47 JSON_EXPECTED_OBJECT_FIRST, 48 JSON_EXPECTED_OBJECT_NEXT, 49 JSON_EXPECTED_STRING, 50 JSON_INVALID_TOKEN, 51 JSON_UNICODE_CODE_POINT_ZERO, 52 JSON_UNICODE_ESCAPE_FORMAT, 53 JSON_UNICODE_HIGH_ESCAPE, 54 JSON_UNICODE_HIGH_SURROGATE, 55 JSON_UNICODE_LOW_SURROGATE 56 } JsonParseErrorType; 57 58 59 /* 60 * All the fields in this structure should be treated as read-only. 61 * 62 * If strval is not null, then it should contain the de-escaped value 63 * of the lexeme if it's a string. Otherwise most of these field names 64 * should be self-explanatory. 65 * 66 * line_number and line_start are principally for use by the parser's 67 * error reporting routines. 68 * token_terminator and prev_token_terminator point to the character 69 * AFTER the end of the token, i.e. where there would be a nul byte 70 * if we were using nul-terminated strings. 71 */ 72 typedef struct JsonLexContext 73 { 74 char *input; 75 int input_length; 76 int input_encoding; 77 char *token_start; 78 char *token_terminator; 79 char *prev_token_terminator; 80 JsonTokenType token_type; 81 int lex_level; 82 int line_number; 83 char *line_start; 84 StringInfo strval; 85 } JsonLexContext; 86 87 typedef void (*json_struct_action) (void *state); 88 typedef void (*json_ofield_action) (void *state, char *fname, bool isnull); 89 typedef void (*json_aelem_action) (void *state, bool isnull); 90 typedef void (*json_scalar_action) (void *state, char *token, JsonTokenType tokentype); 91 92 93 /* 94 * Semantic Action structure for use in parsing json. 95 * Any of these actions can be NULL, in which case nothing is done at that 96 * point, Likewise, semstate can be NULL. Using an all-NULL structure amounts 97 * to doing a pure parse with no side-effects, and is therefore exactly 98 * what the json input routines do. 99 * 100 * The 'fname' and 'token' strings passed to these actions are palloc'd. 101 * They are not free'd or used further by the parser, so the action function 102 * is free to do what it wishes with them. 103 */ 104 typedef struct JsonSemAction 105 { 106 void *semstate; 107 json_struct_action object_start; 108 json_struct_action object_end; 109 json_struct_action array_start; 110 json_struct_action array_end; 111 json_ofield_action object_field_start; 112 json_ofield_action object_field_end; 113 json_aelem_action array_element_start; 114 json_aelem_action array_element_end; 115 json_scalar_action scalar; 116 } JsonSemAction; 117 118 /* 119 * pg_parse_json will parse the string in the lex calling the 120 * action functions in sem at the appropriate points. It is 121 * up to them to keep what state they need in semstate. If they 122 * need access to the state of the lexer, then its pointer 123 * should be passed to them as a member of whatever semstate 124 * points to. If the action pointers are NULL the parser 125 * does nothing and just continues. 126 */ 127 extern JsonParseErrorType pg_parse_json(JsonLexContext *lex, 128 JsonSemAction *sem); 129 130 /* the null action object used for pure validation */ 131 extern JsonSemAction nullSemAction; 132 133 /* 134 * json_count_array_elements performs a fast secondary parse to determine the 135 * number of elements in passed array lex context. It should be called from an 136 * array_start action. 137 * 138 * The return value indicates whether any error occurred, while the number 139 * of elements is stored into *elements (but only if the return value is 140 * JSON_SUCCESS). 141 */ 142 extern JsonParseErrorType json_count_array_elements(JsonLexContext *lex, 143 int *elements); 144 145 /* 146 * constructor for JsonLexContext, with or without strval element. 147 * If supplied, the strval element will contain a de-escaped version of 148 * the lexeme. However, doing this imposes a performance penalty, so 149 * it should be avoided if the de-escaped lexeme is not required. 150 */ 151 extern JsonLexContext *makeJsonLexContextCstringLen(char *json, 152 int len, 153 int encoding, 154 bool need_escapes); 155 156 /* lex one token */ 157 extern JsonParseErrorType json_lex(JsonLexContext *lex); 158 159 /* construct an error detail string for a json error */ 160 extern char *json_errdetail(JsonParseErrorType error, JsonLexContext *lex); 161 162 /* 163 * Utility function to check if a string is a valid JSON number. 164 * 165 * str argument does not need to be nul-terminated. 166 */ 167 extern bool IsValidJsonNumber(const char *str, int len); 168 169 #endif /* JSONAPI_H */ 170