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