• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 	LSMT_BLOB_PTR,
39 
40 } lws_struct_map_type_eum;
41 
42 typedef struct lejp_collation {
43 	struct lws_dll2 chunks;
44 	int len;
45 	char buf[LEJP_STRING_CHUNK + 1];
46 } lejp_collation_t;
47 
48 typedef 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 
59 typedef int (*lws_struct_args_cb)(void *obj, void *cb_arg);
60 
61 typedef 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 
210 typedef 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 
221 enum {
222 	LSSERJ_FLAG_PRETTY	= (1 << 0),
223 	LSSERJ_FLAG_OMIT_SCHEMA = (1 << 1)
224 };
225 
226 typedef 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 
236 typedef enum {
237 	LSJS_RESULT_CONTINUE,
238 	LSJS_RESULT_FINISH,
239 	LSJS_RESULT_ERROR
240 } lws_struct_json_serialize_result_t;
241 
242 LWS_VISIBLE LWS_EXTERN int
243 lws_struct_json_init_parse(struct lejp_ctx *ctx, lejp_callback cb,
244 			   void *user);
245 
246 LWS_VISIBLE LWS_EXTERN signed char
247 lws_struct_schema_only_lejp_cb(struct lejp_ctx *ctx, char reason);
248 
249 LWS_VISIBLE LWS_EXTERN signed char
250 lws_struct_default_lejp_cb(struct lejp_ctx *ctx, char reason);
251 
252 LWS_VISIBLE LWS_EXTERN lws_struct_serialize_t *
253 lws_struct_json_serialize_create(const lws_struct_map_t *map,
254 				 size_t map_entries, int flags,
255 				 const void *ptoplevel);
256 
257 LWS_VISIBLE LWS_EXTERN void
258 lws_struct_json_serialize_destroy(lws_struct_serialize_t **pjs);
259 
260 LWS_VISIBLE LWS_EXTERN lws_struct_json_serialize_result_t
261 lws_struct_json_serialize(lws_struct_serialize_t *js, uint8_t *buf,
262 			  size_t len, size_t *written);
263 
264 typedef struct sqlite3 sqlite3;
265 
266 LWS_VISIBLE LWS_EXTERN int
267 lws_struct_sq3_serialize(sqlite3 *pdb, const lws_struct_map_t *schema,
268 			 lws_dll2_owner_t *owner, uint32_t manual_idx);
269 
270 LWS_VISIBLE LWS_EXTERN int
271 lws_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 
275 LWS_VISIBLE LWS_EXTERN int
276 lws_struct_sq3_create_table(sqlite3 *pdb, const lws_struct_map_t *schema);
277 
278 LWS_VISIBLE LWS_EXTERN int
279 lws_struct_sq3_open(struct lws_context *context, const char *sqlite3_path,
280 		    char create_if_missing, sqlite3 **pdb);
281 
282 LWS_VISIBLE LWS_EXTERN int
283 lws_struct_sq3_close(sqlite3 **pdb);
284 
285