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 
29 typedef 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 
39 } lws_struct_map_type_eum;
40 
41 typedef struct lejp_collation {
42 	struct lws_dll2 chunks;
43 	int len;
44 	char buf[LEJP_STRING_CHUNK + 1];
45 } lejp_collation_t;
46 
47 typedef struct lws_struct_map {
48 	const char *colname;
49 	const struct lws_struct_map *child_map;
50 	lejp_callback lejp_cb;
51 	size_t ofs;			/* child dll2; points to dll2_owner */
52 	size_t aux;
53 	size_t ofs_clist;
54 	size_t child_map_size;
55 	lws_struct_map_type_eum type;
56 } lws_struct_map_t;
57 
58 typedef int (*lws_struct_args_cb)(void *obj, void *cb_arg);
59 
60 typedef struct lws_struct_args {
61 	const lws_struct_map_t *map_st[LEJP_MAX_PARSING_STACK_DEPTH];
62 	lws_struct_args_cb cb;
63 	struct lwsac *ac;
64 	void *cb_arg;
65 	void *dest;
66 
67 	size_t dest_len;
68 	size_t toplevel_dll2_ofs;
69 	size_t map_entries_st[LEJP_MAX_PARSING_STACK_DEPTH];
70 	size_t ac_block_size;
71 	int subtype;
72 
73 	int top_schema_index;
74 
75 	/*
76 	 * temp ac used to collate unknown possibly huge strings before final
77 	 * allocation and copy
78 	 */
79 	struct lwsac *ac_chunks;
80 	struct lws_dll2_owner chunks_owner;
81 	size_t chunks_length;
82 } lws_struct_args_t;
83 
84 #define LSM_SIGNED(type, name, qname) \
85 	{ \
86 	  qname, \
87 	  NULL, \
88 	  NULL, \
89 	  offsetof(type, name), \
90 	  sizeof ((type *)0)->name, \
91 	  0, \
92 	  0, \
93 	  LSMT_SIGNED \
94 	}
95 
96 #define LSM_UNSIGNED(type, name, qname) \
97 	{ \
98 	  qname, \
99 	  NULL, \
100 	  NULL, \
101 	  offsetof(type, name), \
102 	  sizeof ((type *)0)->name, \
103 	  0, \
104 	  0, \
105 	  LSMT_UNSIGNED \
106 	}
107 
108 #define LSM_BOOLEAN(type, name, qname) \
109 	{ \
110 	  qname, \
111 	  NULL, \
112 	  NULL, \
113 	  offsetof(type, name), \
114 	  sizeof ((type *)0)->name, \
115 	  0, \
116 	  0, \
117 	  LSMT_BOOLEAN \
118 	}
119 
120 #define LSM_CARRAY(type, name, qname) \
121 	{ \
122 	  qname, \
123 	  NULL, \
124 	  NULL, \
125 	  offsetof(type, name), \
126 	  sizeof (((type *)0)->name), \
127 	  0, \
128 	  0, \
129 	  LSMT_STRING_CHAR_ARRAY \
130 	}
131 
132 #define LSM_STRING_PTR(type, name, qname) \
133 	{ \
134 	  qname, \
135 	  NULL, \
136 	  NULL, \
137 	  offsetof(type, name), \
138 	  sizeof (((type *)0)->name), \
139 	  0, \
140 	  0, \
141 	  LSMT_STRING_PTR \
142 	}
143 
144 #define LSM_LIST(ptype, pname, ctype, cname, lejp_cb, cmap, qname) \
145 	{ \
146 	  qname, \
147 	  cmap, \
148 	  lejp_cb, \
149 	  offsetof(ptype, pname), \
150 	  sizeof (ctype), \
151 	  offsetof(ctype, cname), \
152 	  LWS_ARRAY_SIZE(cmap), \
153 	  LSMT_LIST \
154 	}
155 
156 #define LSM_CHILD_PTR(ptype, pname, ctype, lejp_cb, cmap, qname) \
157 	{ \
158 	  qname, \
159 	  cmap, \
160 	  lejp_cb, \
161 	  offsetof(ptype, pname), \
162 	  sizeof (ctype), \
163 	  0, \
164 	  LWS_ARRAY_SIZE(cmap), \
165 	  LSMT_CHILD_PTR \
166 	}
167 
168 #define LSM_SCHEMA(ctype, lejp_cb, map, schema_name) \
169 	{ \
170 	  schema_name, \
171 	  map, \
172 	  lejp_cb, \
173 	  0, \
174 	  sizeof (ctype), \
175 	  0, \
176 	  LWS_ARRAY_SIZE(map), \
177 	  LSMT_SCHEMA \
178 	}
179 
180 #define LSM_SCHEMA_DLL2(ctype, cdll2mem, lejp_cb, map, schema_name) \
181 	{ \
182 	  schema_name, \
183 	  map, \
184 	  lejp_cb, \
185 	  offsetof(ctype, cdll2mem), \
186 	  sizeof (ctype), \
187 	  0, \
188 	  LWS_ARRAY_SIZE(map), \
189 	  LSMT_SCHEMA \
190 	}
191 
192 typedef struct lws_struct_serialize_st {
193 	const struct lws_dll2 *dllpos;
194 	const lws_struct_map_t *map;
195 	const char *obj;
196 	size_t map_entries;
197 	size_t map_entry;
198 	size_t size;
199 	char subsequent;
200 	char idt;
201 } lws_struct_serialize_st_t;
202 
203 enum {
204 	LSSERJ_FLAG_PRETTY = 1
205 };
206 
207 typedef struct lws_struct_serialize {
208 	lws_struct_serialize_st_t st[LEJP_MAX_PARSING_STACK_DEPTH];
209 
210 	size_t offset;
211 	size_t remaining;
212 
213 	int sp;
214 	int flags;
215 } lws_struct_serialize_t;
216 
217 typedef enum {
218 	LSJS_RESULT_CONTINUE,
219 	LSJS_RESULT_FINISH,
220 	LSJS_RESULT_ERROR
221 } lws_struct_json_serialize_result_t;
222 
223 LWS_VISIBLE LWS_EXTERN int
224 lws_struct_json_init_parse(struct lejp_ctx *ctx, lejp_callback cb,
225 			   void *user);
226 
227 LWS_VISIBLE LWS_EXTERN signed char
228 lws_struct_schema_only_lejp_cb(struct lejp_ctx *ctx, char reason);
229 
230 LWS_VISIBLE LWS_EXTERN signed char
231 lws_struct_default_lejp_cb(struct lejp_ctx *ctx, char reason);
232 
233 LWS_VISIBLE LWS_EXTERN lws_struct_serialize_t *
234 lws_struct_json_serialize_create(const lws_struct_map_t *map,
235 				 size_t map_entries, int flags,
236 				 const void *ptoplevel);
237 
238 LWS_VISIBLE LWS_EXTERN void
239 lws_struct_json_serialize_destroy(lws_struct_serialize_t **pjs);
240 
241 LWS_VISIBLE LWS_EXTERN lws_struct_json_serialize_result_t
242 lws_struct_json_serialize(lws_struct_serialize_t *js, uint8_t *buf,
243 			  size_t len, size_t *written);
244 
245 #if defined(LWS_WITH_STRUCT_SQLITE3)
246 
247 LWS_VISIBLE LWS_EXTERN int
248 lws_struct_sq3_serialize(sqlite3 *pdb, const lws_struct_map_t *schema,
249 			 lws_dll2_owner_t *owner, uint32_t manual_idx);
250 
251 LWS_VISIBLE LWS_EXTERN int
252 lws_struct_sq3_deserialize(sqlite3 *pdb, const char *filter, const char *order,
253 			   const lws_struct_map_t *schema, lws_dll2_owner_t *o,
254 			   struct lwsac **ac, int start, int limit);
255 
256 LWS_VISIBLE LWS_EXTERN int
257 lws_struct_sq3_create_table(sqlite3 *pdb, const lws_struct_map_t *schema);
258 
259 LWS_VISIBLE LWS_EXTERN int
260 lws_struct_sq3_open(struct lws_context *context, const char *sqlite3_path,
261 		    sqlite3 **pdb);
262 
263 LWS_VISIBLE LWS_EXTERN int
264 lws_struct_sq3_close(sqlite3 **pdb);
265 
266 #endif
267