/src/openvswitch/include/openvswitch/json.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2009, 2010, 2015, 2016 Nicira, Inc. |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at: |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | #ifndef OPENVSWITCH_JSON_H |
18 | | #define OPENVSWITCH_JSON_H 1 |
19 | | |
20 | | /* This is an implementation of JavaScript Object Notation (JSON) as specified |
21 | | * by RFC 4627. It is intended to fully comply with RFC 4627, with the |
22 | | * following known exceptions and clarifications: |
23 | | * |
24 | | * - Null bytes (\u0000) are not allowed in strings. |
25 | | * |
26 | | * - Only UTF-8 encoding is supported (RFC 4627 allows for other Unicode |
27 | | * encodings). |
28 | | * |
29 | | * - Names within an object must be unique (RFC 4627 says that they |
30 | | * "should" be unique). |
31 | | */ |
32 | | |
33 | | #include <stdio.h> |
34 | | #include "openvswitch/shash.h" |
35 | | #include "openvswitch/util.h" |
36 | | |
37 | | #ifdef __cplusplus |
38 | | extern "C" { |
39 | | #endif |
40 | | |
41 | | struct ds; |
42 | | struct uuid; |
43 | | |
44 | | /* Type of a JSON value. */ |
45 | | enum json_type { |
46 | | JSON_NULL, /* null */ |
47 | | JSON_FALSE, /* false */ |
48 | | JSON_TRUE, /* true */ |
49 | | JSON_OBJECT, /* {"a": b, "c": d, ...} */ |
50 | | JSON_ARRAY, /* [1, 2, 3, ...] */ |
51 | | JSON_INTEGER, /* 123. */ |
52 | | JSON_REAL, /* 123.456. */ |
53 | | JSON_STRING, /* "..." */ |
54 | | JSON_N_TYPES, |
55 | | JSON_SERIALIZED_OBJECT, /* Internal type to hold serialized version of |
56 | | * data of other types. */ |
57 | | }; |
58 | | |
59 | | const char *json_type_to_string(enum json_type); |
60 | | |
61 | | /* A JSON array. */ |
62 | | struct json_array { |
63 | | size_t size, allocated; |
64 | | struct json **elements; |
65 | | }; |
66 | | |
67 | | /* Maximum string length that can be stored inline ('\0' is not included). */ |
68 | 0 | #define JSON_STRING_INLINE_LEN (sizeof(struct json_array) - 1) |
69 | | |
70 | | #define JSON_ARRAY_INLINE_LEN 3 |
71 | | BUILD_ASSERT_DECL(sizeof(struct json_array) / sizeof(struct json *) |
72 | | >= JSON_ARRAY_INLINE_LEN); |
73 | | |
74 | | enum json_storage_type { |
75 | | /* JSON_STRING storage types. */ |
76 | | JSON_STRING_DYNAMIC = 0, /* Stored via 'str_ptr'. */ |
77 | | JSON_STRING_INLINE, /* Stored in 'str' array. */ |
78 | | /* JSON_ARRAY storage types.*/ |
79 | | JSON_ARRAY_DYNAMIC, /* 'elements' is a dynamically allocated array. */ |
80 | | JSON_ARRAY_INLINE_1, /* Static 'elements' with exactly 1 element. */ |
81 | | JSON_ARRAY_INLINE_2, /* Static 'elements' with exactly 2 elements. */ |
82 | | JSON_ARRAY_INLINE_3, /* Static 'elements' with exactly 3 elements. */ |
83 | | }; |
84 | | |
85 | | /* A JSON value. */ |
86 | | struct json { |
87 | | enum json_type type; |
88 | | enum json_storage_type storage_type; |
89 | | size_t count; |
90 | | union { |
91 | | struct shash *object; /* Contains "struct json *"s. */ |
92 | | union { |
93 | | struct json *elements[JSON_ARRAY_INLINE_LEN]; |
94 | | struct json_array array; |
95 | | }; /* JSON_ARRAY. */ |
96 | | long long int integer; |
97 | | double real; |
98 | | union { |
99 | | char str[JSON_STRING_INLINE_LEN + 1]; |
100 | | char *str_ptr; |
101 | | }; /* JSON_STRING or JSON_SERIALIZED_OBJECT. */ |
102 | | }; |
103 | | }; |
104 | | |
105 | | struct json *json_null_create(void); |
106 | | struct json *json_boolean_create(bool); |
107 | | struct json *json_string_create(const char *); |
108 | | struct json *json_string_create_nocopy(char *); |
109 | | struct json *json_string_create_uuid(const struct uuid *); |
110 | | struct json *json_serialized_object_create(const struct json *); |
111 | | struct json *json_integer_create(long long int); |
112 | | struct json *json_real_create(double); |
113 | | |
114 | | struct json *json_array_create_empty(void); |
115 | | void json_array_add(struct json *, struct json *element); |
116 | | void json_array_set(struct json *, size_t index, struct json *element); |
117 | | struct json *json_array_pop(struct json *); |
118 | | void json_array_trim(struct json *); |
119 | | struct json *json_array_create(struct json **, size_t n); |
120 | | struct json *json_array_create_1(struct json *); |
121 | | struct json *json_array_create_2(struct json *, struct json *); |
122 | | struct json *json_array_create_3(struct json *, struct json *, struct json *); |
123 | | bool json_array_contains_string(const struct json *, const char *); |
124 | | |
125 | | struct json *json_object_create(void); |
126 | | bool json_object_is_empty(struct json *); |
127 | | void json_object_put(struct json *, const char *name, struct json *value); |
128 | | void json_object_put_nocopy(struct json *, char *name, struct json *value); |
129 | | void json_object_put_string(struct json *, |
130 | | const char *name, const char *value); |
131 | | void json_object_put_format(struct json *, |
132 | | const char *name, const char *format, ...) |
133 | | OVS_PRINTF_FORMAT(3, 4); |
134 | | void json_object_put_uuid(struct json *, const char *name, |
135 | | const struct uuid *); |
136 | | |
137 | | const char *json_string(const struct json *); |
138 | | const char *json_serialized_object(const struct json *); |
139 | | size_t json_array_size(const struct json *); |
140 | | const struct json *json_array_at(const struct json *, size_t index); |
141 | | struct shash *json_object(const struct json *); |
142 | | bool json_boolean(const struct json *); |
143 | | double json_real(const struct json *); |
144 | | int64_t json_integer(const struct json *); |
145 | | |
146 | | struct json *json_deep_clone(const struct json *); |
147 | | static inline struct json *json_clone(const struct json *); |
148 | | struct json *json_nullable_clone(const struct json *); |
149 | | static inline void json_destroy(struct json *); |
150 | | |
151 | | size_t json_hash(const struct json *, size_t basis); |
152 | | bool json_equal(const struct json *, const struct json *); |
153 | | |
154 | | /* Parsing JSON. */ |
155 | | enum { |
156 | | JSPF_TRAILER = 1 << 0 /* Check for garbage following input. */ |
157 | | }; |
158 | | |
159 | | struct json_parser *json_parser_create(int flags); |
160 | | size_t json_parser_feed(struct json_parser *, const char *, size_t); |
161 | | bool json_parser_is_done(const struct json_parser *); |
162 | | struct json *json_parser_finish(struct json_parser *); |
163 | | void json_parser_abort(struct json_parser *); |
164 | | |
165 | | struct json *json_from_string(const char *string); |
166 | | struct json *json_from_serialized_object(const struct json *); |
167 | | struct json *json_from_file(const char *file_name); |
168 | | struct json *json_from_stream(FILE *stream); |
169 | | |
170 | | /* Serializing JSON. */ |
171 | | |
172 | | enum { |
173 | | JSSF_PRETTY = 1 << 0, /* Multiple lines with indentation, if true. */ |
174 | | JSSF_SORT = 1 << 1 /* Object members in sorted order, if true. */ |
175 | | }; |
176 | | char *json_to_string(const struct json *, int flags); |
177 | | void json_to_ds(const struct json *, int flags, struct ds *); |
178 | | |
179 | | /* JSON string formatting operations. */ |
180 | | |
181 | | bool json_string_unescape(const char *in, size_t in_len, char **outp); |
182 | | void json_string_escape(const char *in, struct ds *out); |
183 | | |
184 | | /* Inline functions. */ |
185 | | |
186 | | /* Returns 'json', with the reference count incremented. */ |
187 | | static inline struct json * |
188 | | json_clone(const struct json *json_) |
189 | 0 | { |
190 | 0 | struct json *json = CONST_CAST(struct json *, json_); |
191 | 0 | json->count++; |
192 | 0 | return json; |
193 | 0 | } Unexecuted instantiation: unixctl.c:json_clone Unexecuted instantiation: json.c:json_clone Unexecuted instantiation: jsonrpc.c:json_clone Unexecuted instantiation: netdev.c:json_clone Unexecuted instantiation: ofp-port.c:json_clone Unexecuted instantiation: ofp-table.c:json_clone Unexecuted instantiation: ofp-util.c:json_clone Unexecuted instantiation: ovs-router.c:json_clone Unexecuted instantiation: smap.c:json_clone Unexecuted instantiation: userspace-tso.c:json_clone Unexecuted instantiation: dpif-offload.c:json_clone Unexecuted instantiation: dpif-offload-dummy.c:json_clone Unexecuted instantiation: namemap.c:json_clone Unexecuted instantiation: dpif-offload-tc.c:json_clone Unexecuted instantiation: dpdk-stub.c:json_clone Unexecuted instantiation: vswitch-idl.c:json_clone Unexecuted instantiation: ovsdb-data.c:json_clone Unexecuted instantiation: ovsdb-error.c:json_clone Unexecuted instantiation: ovsdb-idl.c:json_clone Unexecuted instantiation: ovsdb-map-op.c:json_clone Unexecuted instantiation: ovsdb-set-op.c:json_clone Unexecuted instantiation: ovsdb-parser.c:json_clone Unexecuted instantiation: ovsdb-types.c:json_clone Unexecuted instantiation: ovsdb-cs.c:json_clone |
194 | | |
195 | | void json_destroy__(struct json *json, bool); |
196 | | |
197 | | /* Frees 'json' and everything it points to, recursively. */ |
198 | | static inline void |
199 | | json_destroy(struct json *json) |
200 | 0 | { |
201 | 0 | if (json && !--json->count) { |
202 | | json_destroy__(json, false); |
203 | 0 | } |
204 | 0 | } Unexecuted instantiation: unixctl.c:json_destroy Unexecuted instantiation: json.c:json_destroy Unexecuted instantiation: jsonrpc.c:json_destroy Unexecuted instantiation: netdev.c:json_destroy Unexecuted instantiation: ofp-port.c:json_destroy Unexecuted instantiation: ofp-table.c:json_destroy Unexecuted instantiation: ofp-util.c:json_destroy Unexecuted instantiation: ovs-router.c:json_destroy Unexecuted instantiation: smap.c:json_destroy Unexecuted instantiation: userspace-tso.c:json_destroy Unexecuted instantiation: dpif-offload.c:json_destroy Unexecuted instantiation: dpif-offload-dummy.c:json_destroy Unexecuted instantiation: namemap.c:json_destroy Unexecuted instantiation: dpif-offload-tc.c:json_destroy Unexecuted instantiation: dpdk-stub.c:json_destroy Unexecuted instantiation: vswitch-idl.c:json_destroy Unexecuted instantiation: ovsdb-data.c:json_destroy Unexecuted instantiation: ovsdb-error.c:json_destroy Unexecuted instantiation: ovsdb-idl.c:json_destroy Unexecuted instantiation: ovsdb-map-op.c:json_destroy Unexecuted instantiation: ovsdb-set-op.c:json_destroy Unexecuted instantiation: ovsdb-parser.c:json_destroy Unexecuted instantiation: ovsdb-types.c:json_destroy Unexecuted instantiation: ovsdb-cs.c:json_destroy |
205 | | |
206 | | #ifdef __cplusplus |
207 | | } |
208 | | #endif |
209 | | |
210 | | #endif /* OPENVSWITCH_JSON_H */ |