open62541 1.4.15
Open source implementation of OPC UA
Loading...
Searching...
No Matches
cj5.h
Go to the documentation of this file.
1// MIT License
2//
3// Copyright (c) 2020 Sepehr Taghdisian
4// Copyright (c) 2022 Julius Pfrommer
5//
6// Permission is hereby granted, free of charge, to any person obtaining a copy
7// of this software and associated documentation files (the "Software"), to deal
8// in the Software without restriction, including without limitation the rights
9// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10// copies of the Software, and to permit persons to whom the Software is
11// furnished to do so, subject to the following conditions:
12//
13// The above copyright notice and this permission notice shall be included in all
14// copies or substantial portions of the Software.
15//
16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22// SOFTWARE.
23//
24// Very minimal single header JSON5 parser in C99, dervied from jsmn This is the
25// modified version of jsmn library Thus main parts of the code is taken from
26// jsmn project (https://github.com/zserge/jsmn).
27//
28// Compliance with JSON5:
29// [x] Object keys may be an ECMAScript 5.1 IdentifierName.
30// [x] Objects may have a single trailing comma.
31// [x] Strings may be single quoted.
32// [x] Strings may span multiple lines by escaping new line characters.
33// [x] Strings may include character escapes.
34// [x] Numbers may be hexadecimal.
35// [x] Numbers may have a leading or trailing decimal point.
36// [x] Numbers may be IEEE 754 positive infinity, negative infinity, and NaN.
37// [x] Numbers may begin with an explicit plus sign.
38// [x] Single and multi-line comments are allowed.
39// [x] Additional white space characters are allowed.
40//
41// Extensions to JSON5 (more permissive):
42// [x] Root objects can be an array or a primitive value
43// [x] The root object may omit the surrounding brackets
44// [x] Hash ('#') comments out until the end of the line.
45// [x] Strings may include unescaped utf8 bytes
46// [x] Optionally: Stop early when the first encountered JSON element (object,
47// array, value) has been successfully parsed. Do not return an error when
48// the input string was not processed to its full length. This allows the
49// detection of JSON sub-strings as part of an input "lexer".
50//
51// Usage:
52// The main function to parse json is `cj5_parse`. Like in jsmn, you provide
53// all tokens to be filled as an array and provide the maximum count The result
54// will be return in `cj5_result` struct, and `num_tokens` will represent the
55// actual token count that is parsed. In case of errors, cj_result.error will
56// be set to an error code Here's a quick example of the usage.
57//
58// #include "cj5.h"
59//
60// cj5_token tokens[32];
61// cj5_result r = cj5_parse(g_json, (int)strlen(g_json), tokens, 32, NULL);
62// if(r.error != CJ5_ERROR_NONE) {
63// if(r.error == CJ5_ERROR_OVERFLOW) {
64// // you can use r.num_tokens to determine the actual token count and reparse
65// printf("Error: line: %d, col: %d\n", r.error_line, r.error_code);
66// }
67// }
68
69#ifndef __CJ5_H_
70#define __CJ5_H_
71
72#ifdef __cplusplus
73# define CJ5_API extern "C"
74#else
75# define CJ5_API
76#endif
77
78#if !defined(_MSC_VER) || _MSC_VER >= 1800
79# include <stdint.h>
80# include <stdbool.h>
81#else
82# include "ms_stdint.h"
83# if !defined(__bool_true_false_are_defined)
84# define bool unsigned char
85# define true 1
86# define false 0
87# define __bool_true_false_are_defined
88# endif
89#endif
90
99
100typedef enum cj5_error_code {
102 CJ5_ERROR_INVALID, // Invalid character/syntax
103 CJ5_ERROR_INCOMPLETE, // Incomplete JSON string
104 CJ5_ERROR_OVERFLOW, // Token buffer overflow (see cj5_result.num_tokens)
107
108typedef struct cj5_token {
110 unsigned int start; // Start position in the json5 string
111 unsigned int end; // Position of the last character (included)
112 unsigned int size; // For objects and arrays the number of direct
113 // children. Note that this is *not* the number of
114 // overall (recursively nested) child tokens. For
115 // other tokens the length of token in the json
116 // encoding.
117 unsigned int parent_id; // The root object is at position zero. It is an
118 // object that has itself as parent.
120
121typedef struct cj5_result {
123 unsigned int error_line;
124 unsigned int error_col;
125 unsigned int num_tokens;
127 const char* json5;
129
130typedef struct cj5_options {
131 bool stop_early; /* Return when the first element was parsed. Otherwise an
132 * error is returned if the input was not fully
133 * processed. (default: false) */
135
136/** Options can be NULL */
138cj5_parse(const char *json5, unsigned int len,
139 cj5_token *tokens, unsigned int max_tokens,
140 cj5_options *options);
141
143cj5_get_bool(const cj5_result *r, unsigned int tok_index, bool *out);
144
146cj5_get_float(const cj5_result *r, unsigned int tok_index, double *out);
147
149cj5_get_int(const cj5_result *r, unsigned int tok_index, int64_t *out);
150
152cj5_get_uint(const cj5_result *r, unsigned int tok_index, uint64_t *out);
153
154// Replaces escape characters, utf8 codepoints, etc.
155// The buffer shall have a length of at least token->size + 1.
156// Upon success, the length is written to buflen.
157// The output string is terminated with \0.
159cj5_get_str(const cj5_result *r, unsigned int tok_index,
160 char *buf, unsigned int *buflen);
161
162// Skips the (nested) structure that starts at the current index. The index is
163// updated accordingly. Afterwards it points to the beginning of the following
164// structure.
165//
166// Attention! The index can point to the first element after the token array if
167// the root object is skipped.
168//
169// Cannot fail as long as the token array is the result of cj5_parse.
170CJ5_API void
171cj5_skip(const cj5_result *r, unsigned int *tok_index);
172
173// Lookup of a key within an object (linear search).
174// The current token (index) must point to an object.
175// The error code CJ5_ERROR_NOTFOUND is returned if the key is not present.
176// Otherwise the index is updated to point to the value associated with the key.
178cj5_find(const cj5_result *r, unsigned int *tok_index, const char *key);
179
180#endif /* __CJ5_H_ */
cj5_error_code cj5_get_float(const cj5_result *r, unsigned int tok_index, double *out)
cj5_error_code cj5_get_uint(const cj5_result *r, unsigned int tok_index, uint64_t *out)
cj5_result cj5_parse(const char *json5, unsigned int len, cj5_token *tokens, unsigned int max_tokens, cj5_options *options)
Options can be NULL.
cj5_error_code cj5_get_int(const cj5_result *r, unsigned int tok_index, int64_t *out)
void cj5_skip(const cj5_result *r, unsigned int *tok_index)
cj5_error_code cj5_find(const cj5_result *r, unsigned int *tok_index, const char *key)
#define CJ5_API
Definition cj5.h:75
cj5_token_type
Definition cj5.h:91
@ CJ5_TOKEN_STRING
Definition cj5.h:95
@ CJ5_TOKEN_ARRAY
Definition cj5.h:93
@ CJ5_TOKEN_NULL
Definition cj5.h:97
@ CJ5_TOKEN_OBJECT
Definition cj5.h:92
@ CJ5_TOKEN_BOOL
Definition cj5.h:96
@ CJ5_TOKEN_NUMBER
Definition cj5.h:94
cj5_error_code cj5_get_str(const cj5_result *r, unsigned int tok_index, char *buf, unsigned int *buflen)
cj5_error_code
Definition cj5.h:100
@ CJ5_ERROR_NONE
Definition cj5.h:101
@ CJ5_ERROR_NOTFOUND
Definition cj5.h:105
@ CJ5_ERROR_INVALID
Definition cj5.h:102
@ CJ5_ERROR_OVERFLOW
Definition cj5.h:104
@ CJ5_ERROR_INCOMPLETE
Definition cj5.h:103
cj5_error_code cj5_get_bool(const cj5_result *r, unsigned int tok_index, bool *out)
bool stop_early
Definition cj5.h:131
const cj5_token * tokens
Definition cj5.h:126
cj5_error_code error
Definition cj5.h:122
unsigned int error_col
Definition cj5.h:124
const char * json5
Definition cj5.h:127
unsigned int error_line
Definition cj5.h:123
unsigned int num_tokens
Definition cj5.h:125
unsigned int size
Definition cj5.h:112
unsigned int parent_id
Definition cj5.h:117
unsigned int start
Definition cj5.h:110
cj5_token_type type
Definition cj5.h:109
unsigned int end
Definition cj5.h:111