1/*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
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
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell 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
14 * all 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
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25#if defined(LWS_WITH_STRUCT_SQLITE3)
26#include <sqlite3.h>
27#endif
28
29typedef enum {
30 LSMT_SIGNED,
31 LSMT_UNSIGNED,
32 LSMT_BOOLEAN,
33 LSMT_STRING_CHAR_ARRAY,
34 LSMT_STRING_PTR,
35 LSMT_LIST,
36 LSMT_CHILD_PTR,
37 LSMT_SCHEMA,
38 LSMT_BLOB_PTR,
39
40} lws_struct_map_type_eum;
41
42typedef struct lejp_collation {
43 struct lws_dll2 chunks;
44 int len;
45 char buf[LEJP_STRING_CHUNK + 1];
46} lejp_collation_t;
47
48typedef struct lws_struct_map {
49 const char *colname;
50 const struct lws_struct_map *child_map;
51 lejp_callback lejp_cb;
52 size_t ofs; /* child dll2; points to dll2_owner */
53 size_t aux;
54 size_t ofs_clist;
55 size_t child_map_size;
56 lws_struct_map_type_eum type;
57} lws_struct_map_t;
58
59typedef int (*lws_struct_args_cb)(void *obj, void *cb_arg);
60
61typedef struct lws_struct_args {
62 const lws_struct_map_t *map_st[LEJP_MAX_PARSING_STACK_DEPTH];
63 lws_struct_args_cb cb;
64 struct lwsac *ac;
65 void *cb_arg;
66 void *dest;
67
68 size_t dest_len;
69 size_t toplevel_dll2_ofs;
70 size_t map_entries_st[LEJP_MAX_PARSING_STACK_DEPTH];
71 size_t ac_block_size;
72 int subtype;
73
74 int top_schema_index;
75
76 /*
77 * temp ac used to collate unknown possibly huge strings before final
78 * allocation and copy
79 */
80 struct lwsac *ac_chunks;
81 struct lws_dll2_owner chunks_owner;
82 size_t chunks_length;
83} lws_struct_args_t;
84
85#define LSM_SIGNED(type, name, qname) \
86 { \
87 qname, \
88 NULL, \
89 NULL, \
90 offsetof(type, name), \
91 sizeof ((type *)0)->name, \
92 0, \
93 0, \
94 LSMT_SIGNED \
95 }
96
97#define LSM_UNSIGNED(type, name, qname) \
98 { \
99 qname, \
100 NULL, \
101 NULL, \
102 offsetof(type, name), \
103 sizeof ((type *)0)->name, \
104 0, \
105 0, \
106 LSMT_UNSIGNED \
107 }
108
109#define LSM_BOOLEAN(type, name, qname) \
110 { \
111 qname, \
112 NULL, \
113 NULL, \
114 offsetof(type, name), \
115 sizeof ((type *)0)->name, \
116 0, \
117 0, \
118 LSMT_BOOLEAN \
119 }
120
121#define LSM_CARRAY(type, name, qname) \
122 { \
123 qname, \
124 NULL, \
125 NULL, \
126 offsetof(type, name), \
127 sizeof (((type *)0)->name), \
128 0, \
129 0, \
130 LSMT_STRING_CHAR_ARRAY \
131 }
132
133#define LSM_STRING_PTR(type, name, qname) \
134 { \
135 qname, \
136 NULL, \
137 NULL, \
138 offsetof(type, name), \
139 sizeof (((type *)0)->name), \
140 0, \
141 0, \
142 LSMT_STRING_PTR \
143 }
144
145#define LSM_LIST(ptype, pname, ctype, cname, lejp_cb, cmap, qname) \
146 { \
147 qname, \
148 cmap, \
149 lejp_cb, \
150 offsetof(ptype, pname), \
151 sizeof (ctype), \
152 offsetof(ctype, cname), \
153 LWS_ARRAY_SIZE(cmap), \
154 LSMT_LIST \
155 }
156
157#define LSM_CHILD_PTR(ptype, pname, ctype, lejp_cb, cmap, qname) \
158 { \
159 qname, \
160 cmap, \
161 lejp_cb, \
162 offsetof(ptype, pname), \
163 sizeof (ctype), \
164 0, \
165 LWS_ARRAY_SIZE(cmap), \
166 LSMT_CHILD_PTR \
167 }
168
169#define LSM_SCHEMA(ctype, lejp_cb, map, schema_name) \
170 { \
171 schema_name, \
172 map, \
173 lejp_cb, \
174 0, \
175 sizeof (ctype), \
176 0, \
177 LWS_ARRAY_SIZE(map), \
178 LSMT_SCHEMA \
179 }
180
181#define LSM_SCHEMA_DLL2(ctype, cdll2mem, lejp_cb, map, schema_name) \
182 { \
183 schema_name, \
184 map, \
185 lejp_cb, \
186 offsetof(ctype, cdll2mem), \
187 sizeof (ctype), \
188 0, \
189 LWS_ARRAY_SIZE(map), \
190 LSMT_SCHEMA \
191 }
192
193/*
194 * This is just used to create the table schema, it is not part of serialization
195 * and deserialization. Blobs should be accessed separately.
196 */
197
198#define LSM_BLOB_PTR(type, blobptr_name, qname) \
199 { \
200 qname, /* JSON item, or sqlite3 column name */ \
201 NULL, \
202 NULL, \
203 offsetof(type, blobptr_name), /* member that points to blob */ \
204 sizeof (((type *)0)->blobptr_name), /* size of blob pointer */ \
205 0, /* member holding blob len */ \
206 0, /* size of blob length member */ \
207 LSMT_BLOB_PTR \
208 }
209
210typedef struct lws_struct_serialize_st {
211 const struct lws_dll2 *dllpos;
212 const lws_struct_map_t *map;
213 const char *obj;
214 size_t map_entries;
215 size_t map_entry;
216 size_t size;
217 char subsequent;
218 char idt;
219} lws_struct_serialize_st_t;
220
221enum {
222 LSSERJ_FLAG_PRETTY = (1 << 0),
223 LSSERJ_FLAG_OMIT_SCHEMA = (1 << 1)
224};
225
226typedef struct lws_struct_serialize {
227 lws_struct_serialize_st_t st[LEJP_MAX_PARSING_STACK_DEPTH];
228
229 size_t offset;
230 size_t remaining;
231
232 int sp;
233 int flags;
234} lws_struct_serialize_t;
235
236typedef enum {
237 LSJS_RESULT_CONTINUE,
238 LSJS_RESULT_FINISH,
239 LSJS_RESULT_ERROR
240} lws_struct_json_serialize_result_t;
241
242LWS_VISIBLE LWS_EXTERN int
243lws_struct_json_init_parse(struct lejp_ctx *ctx, lejp_callback cb,
244 void *user);
245
246LWS_VISIBLE LWS_EXTERN signed char
247lws_struct_schema_only_lejp_cb(struct lejp_ctx *ctx, char reason);
248
249LWS_VISIBLE LWS_EXTERN signed char
250lws_struct_default_lejp_cb(struct lejp_ctx *ctx, char reason);
251
252LWS_VISIBLE LWS_EXTERN lws_struct_serialize_t *
253lws_struct_json_serialize_create(const lws_struct_map_t *map,
254 size_t map_entries, int flags,
255 const void *ptoplevel);
256
257LWS_VISIBLE LWS_EXTERN void
258lws_struct_json_serialize_destroy(lws_struct_serialize_t **pjs);
259
260LWS_VISIBLE LWS_EXTERN lws_struct_json_serialize_result_t
261lws_struct_json_serialize(lws_struct_serialize_t *js, uint8_t *buf,
262 size_t len, size_t *written);
263
264typedef struct sqlite3 sqlite3;
265
266LWS_VISIBLE LWS_EXTERN int
267lws_struct_sq3_serialize(sqlite3 *pdb, const lws_struct_map_t *schema,
268 lws_dll2_owner_t *owner, uint32_t manual_idx);
269
270LWS_VISIBLE LWS_EXTERN int
271lws_struct_sq3_deserialize(sqlite3 *pdb, const char *filter, const char *order,
272 const lws_struct_map_t *schema, lws_dll2_owner_t *o,
273 struct lwsac **ac, int start, int limit);
274
275LWS_VISIBLE LWS_EXTERN int
276lws_struct_sq3_create_table(sqlite3 *pdb, const lws_struct_map_t *schema);
277
278LWS_VISIBLE LWS_EXTERN int
279lws_struct_sq3_open(struct lws_context *context, const char *sqlite3_path,
280 char create_if_missing, sqlite3 **pdb);
281
282LWS_VISIBLE LWS_EXTERN int
283lws_struct_sq3_close(sqlite3 **pdb);
284
285