1 /*------------------------------------------------------------------------- 2 * 3 * jsonapi.h 4 * Declarations for JSON API support. 5 * 6 * Portions Copyright (c) 1996-2017, 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 "jsonb.h" 18 #include "lib/stringinfo.h" 19 20 typedef enum 21 { 22 JSON_TOKEN_INVALID, 23 JSON_TOKEN_STRING, 24 JSON_TOKEN_NUMBER, 25 JSON_TOKEN_OBJECT_START, 26 JSON_TOKEN_OBJECT_END, 27 JSON_TOKEN_ARRAY_START, 28 JSON_TOKEN_ARRAY_END, 29 JSON_TOKEN_COMMA, 30 JSON_TOKEN_COLON, 31 JSON_TOKEN_TRUE, 32 JSON_TOKEN_FALSE, 33 JSON_TOKEN_NULL, 34 JSON_TOKEN_END 35 } JsonTokenType; 36 37 38 /* 39 * All the fields in this structure should be treated as read-only. 40 * 41 * If strval is not null, then it should contain the de-escaped value 42 * of the lexeme if it's a string. Otherwise most of these field names 43 * should be self-explanatory. 44 * 45 * line_number and line_start are principally for use by the parser's 46 * error reporting routines. 47 * token_terminator and prev_token_terminator point to the character 48 * AFTER the end of the token, i.e. where there would be a nul byte 49 * if we were using nul-terminated strings. 50 */ 51 typedef struct JsonLexContext 52 { 53 char *input; 54 int input_length; 55 char *token_start; 56 char *token_terminator; 57 char *prev_token_terminator; 58 JsonTokenType token_type; 59 int lex_level; 60 int line_number; 61 char *line_start; 62 StringInfo strval; 63 } JsonLexContext; 64 65 typedef void (*json_struct_action) (void *state); 66 typedef void (*json_ofield_action) (void *state, char *fname, bool isnull); 67 typedef void (*json_aelem_action) (void *state, bool isnull); 68 typedef void (*json_scalar_action) (void *state, char *token, JsonTokenType tokentype); 69 70 71 /* 72 * Semantic Action structure for use in parsing json. 73 * Any of these actions can be NULL, in which case nothing is done at that 74 * point, Likewise, semstate can be NULL. Using an all-NULL structure amounts 75 * to doing a pure parse with no side-effects, and is therefore exactly 76 * what the json input routines do. 77 * 78 * The 'fname' and 'token' strings passed to these actions are palloc'd. 79 * They are not free'd or used further by the parser, so the action function 80 * is free to do what it wishes with them. 81 */ 82 typedef struct JsonSemAction 83 { 84 void *semstate; 85 json_struct_action object_start; 86 json_struct_action object_end; 87 json_struct_action array_start; 88 json_struct_action array_end; 89 json_ofield_action object_field_start; 90 json_ofield_action object_field_end; 91 json_aelem_action array_element_start; 92 json_aelem_action array_element_end; 93 json_scalar_action scalar; 94 } JsonSemAction; 95 96 /* 97 * parse_json will parse the string in the lex calling the 98 * action functions in sem at the appropriate points. It is 99 * up to them to keep what state they need in semstate. If they 100 * need access to the state of the lexer, then its pointer 101 * should be passed to them as a member of whatever semstate 102 * points to. If the action pointers are NULL the parser 103 * does nothing and just continues. 104 */ 105 extern void pg_parse_json(JsonLexContext *lex, JsonSemAction *sem); 106 107 /* 108 * json_count_array_elements performs a fast secondary parse to determine the 109 * number of elements in passed array lex context. It should be called from an 110 * array_start action. 111 */ 112 extern int json_count_array_elements(JsonLexContext *lex); 113 114 /* 115 * constructors for JsonLexContext, with or without strval element. 116 * If supplied, the strval element will contain a de-escaped version of 117 * the lexeme. However, doing this imposes a performance penalty, so 118 * it should be avoided if the de-escaped lexeme is not required. 119 * 120 * If you already have the json as a text* value, use the first of these 121 * functions, otherwise use makeJsonLexContextCstringLen(). 122 */ 123 extern JsonLexContext *makeJsonLexContext(text *json, bool need_escapes); 124 extern JsonLexContext *makeJsonLexContextCstringLen(char *json, 125 int len, 126 bool need_escapes); 127 128 /* 129 * Utility function to check if a string is a valid JSON number. 130 * 131 * str argument does not need to be nul-terminated. 132 */ 133 extern bool IsValidJsonNumber(const char *str, int len); 134 135 /* an action that will be applied to each value in iterate_json(b)_string_vaues functions */ 136 typedef void (*JsonIterateStringValuesAction) (void *state, char *elem_value, int elem_len); 137 138 /* an action that will be applied to each value in transform_json(b)_string_values functions */ 139 typedef text *(*JsonTransformStringValuesAction) (void *state, char *elem_value, int elem_len); 140 141 extern void iterate_jsonb_string_values(Jsonb *jb, void *state, 142 JsonIterateStringValuesAction action); 143 extern void iterate_json_string_values(text *json, void *action_state, 144 JsonIterateStringValuesAction action); 145 extern Jsonb *transform_jsonb_string_values(Jsonb *jsonb, void *action_state, 146 JsonTransformStringValuesAction transform_action); 147 extern text *transform_json_string_values(text *json, void *action_state, 148 JsonTransformStringValuesAction transform_action); 149 150 #endif /* JSONAPI_H */ 151