Titan Core Initial Contribution
[deliverable/titan.core.git] / common / JSON_Tokenizer.hh
1 #ifndef JSON_TOKENIZER_HH
2 #define JSON_TOKENIZER_HH
3
4 #include <cstddef>
5
6 /** JSON token types */
7 enum json_token_t {
8 JSON_TOKEN_ERROR = 0, // not actually a token, used when get_next_token() fails
9 JSON_TOKEN_NONE, // not actually a token, used for initializing
10 JSON_TOKEN_OBJECT_START, // "{"
11 JSON_TOKEN_OBJECT_END, // "}"
12 JSON_TOKEN_ARRAY_START, // "["
13 JSON_TOKEN_ARRAY_END, // "]"
14 JSON_TOKEN_NAME, // field name (key) in a JSON object, followed by ":"
15 JSON_TOKEN_NUMBER, // JSON number value
16 JSON_TOKEN_STRING, // JSON string value
17 JSON_TOKEN_LITERAL_TRUE, // "true" value
18 JSON_TOKEN_LITERAL_FALSE, // "false" value
19 JSON_TOKEN_LITERAL_NULL // "null" value
20 };
21
22 /** A class for building and processing JSON documents. Stores the document in a buffer.
23 * Can build JSON documents by inserting tokens into an empty buffer.
24 * Can extract tokens from an existing JSON document. */
25 class JSON_Tokenizer {
26
27 private:
28
29 /** The buffer that stores the JSON document
30 * This is a buffer with exponential allocation (expstring), only uses expstring
31 * memory operations from memory.h (ex.: mputstr, mputprintf) */
32 char* buf_ptr;
33
34 /** Number of bytes currently in the buffer */
35 size_t buf_len;
36
37 /** Current position in the buffer */
38 size_t buf_pos;
39
40 /** Current depth in the JSON document (only used if pretty printing is set */
41 unsigned int depth;
42
43 /** Stores the previous JSON token inserted by put_next_token() */
44 json_token_t previous_token;
45
46 /** Activates or deactivates pretty printing
47 * If active, put_next_token() and put_separator() will add extra newlines
48 * and indenting to the JSON code to make it more readable for you humans,
49 * otherwise it will be compact (no white spaces). */
50 bool pretty;
51
52 /** Initializes the properties of the tokenizer.
53 * The buffer is initialized with the parameter data (unless it's empty). */
54 void init(const char* p_buf, const size_t p_buf_len);
55
56 /** Inserts a character to the end of the buffer */
57 void put_c(const char c);
58
59 /** Inserts a null-terminated string to the end of the buffer */
60 void put_s(const char* s);
61
62 /** Indents a new line in JSON code depending on the current depth.
63 * If the maximum depth is reached, the code is not indented further.
64 * Used only if pretty printing is set. */
65 void put_depth();
66
67 /** Skips white spaces until a non-white-space character is found.
68 * Returns false if the end of the buffer is reached before a non-white-space
69 * character is found, otherwise returns true. */
70 bool skip_white_spaces();
71
72 /** Attempts to find a JSON string at the current buffer position.
73 * Returns true if a valid string is found before the end of the buffer
74 * is reached, otherwise returns false. */
75 bool check_for_string();
76
77 /** Attempts to find a JSON number at the current buffer position.
78 * For number format see http://json.org/.
79 * Returns true if a valid number is found before the end of the buffer
80 * is reached, otherwise returns false. */
81 bool check_for_number();
82
83 /** Checks if the current character in the buffer is a valid JSON separator.
84 * Separators are: commas (,), colons (:) and curly and square brackets ({}[]).
85 * This function also steps over the separator if it's a comma.
86 * Returns true if a separator is found, otherwise returns false. */
87 bool check_for_separator();
88
89 /** Attempts to find a specific JSON literal at the current buffer position.
90 * Returns true if the literal is found, otherwise returns false.
91 * @param p_literal [in] Literal value to find */
92 bool check_for_literal(const char* p_literal);
93
94 /** Adds a separating comma (,) if the previous token is a value, or an object or
95 * array end mark. */
96 void put_separator();
97
98 /** No copy constructor. Implement if needed. */
99 JSON_Tokenizer(const JSON_Tokenizer&);
100
101 /** No assignment operator. Implement if needed. */
102 JSON_Tokenizer& operator=(const JSON_Tokenizer&);
103
104 public:
105 /** Constructs a tokenizer with an empty buffer.
106 * Use put_next_token() to build a JSON document and get_buffer()/get_buffer_length() to retrieve it */
107 JSON_Tokenizer(bool p_pretty = false) : pretty(p_pretty) { init(0, 0); }
108
109 /** Constructs a tokenizer with the buffer parameter.
110 * Use get_next_token() to read JSON tokens and get_pos()/set_pos() to move around in the buffer */
111 JSON_Tokenizer(const char* p_buf, const size_t p_buf_len) : pretty(false) { init(p_buf, p_buf_len); }
112
113 /** Destructor. Frees the buffer. */
114 ~JSON_Tokenizer();
115
116 /** Reinitializes the tokenizer with a new buffer. */
117 inline void set_buffer(const char* p_buf, const size_t p_buf_len) { init(p_buf, p_buf_len); }
118
119 /** Retrieves the buffer containing the JSON document. */
120 inline const char* get_buffer() { return buf_ptr; }
121
122 /** Retrieves the length of the buffer containing the JSON document. */
123 inline size_t get_buffer_length() { return buf_len; }
124
125 /** Extracts a JSON token from the current buffer position.
126 * @param p_token [out] Extracted token type, or JSON_TOKEN_ERROR if no token
127 * could be extracted, or JSON_TOKEN_NONE if the buffer end is reached
128 * @param p_token_str [out] A pointer to the token data (if any):
129 * the name of a JSON object field (without quotes), or the string representation
130 * of a JSON number, or a JSON string (with quotes and double-escaped).
131 * @param p_str_len [out] The character length of the token data (if there is data)
132 * @return The number of characters extracted
133 * @note The token data is not copied, *p_token_str will point to the start of the
134 * data in the tokenizer's buffer. */
135 int get_next_token(json_token_t* p_token, char** p_token_str, size_t* p_str_len);
136
137 /** Gets the current read position in the buffer.
138 * This is where get_next_token() will read from next. */
139 inline size_t get_buf_pos() { return buf_pos; }
140
141 /** Sets the current read position in the buffer.
142 * This is where get_next_buffer() will read from next. */
143 inline void set_buf_pos(const size_t p_buf_pos) { buf_pos = p_buf_pos; }
144
145 /** Adds the specified JSON token to end of the buffer.
146 * @param p_token [in] Token type
147 * @param p_token_str [in] The name of a JSON object field (without quotes), or
148 * the string representation of a JSON number, or a JSON string (with quotes
149 * and double-escaped). For all the other tokens this parameter will be ignored.
150 * @return The number of characters added to the JSON document */
151 int put_next_token(json_token_t p_token, const char* p_token_str = 0);
152
153 }; // class JSON_Tokenizer
154
155 // A dummy JSON tokenizer, use when there is no actual JSON document
156 static JSON_Tokenizer DUMMY_BUFFER;
157
158
159 #endif /* JSON_TOKENIZER_HH */
160
This page took 0.03582 seconds and 6 git commands to generate.