Skip to content

Commit f8411a8

Browse files
committed
WASM related refactoring
1 parent c2e0a1f commit f8411a8

File tree

3 files changed

+157
-158
lines changed

3 files changed

+157
-158
lines changed

src/cloudsync.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "sqlite3.h"
1717
#endif
1818

19-
#define CLOUDSYNC_VERSION "0.8.6"
19+
#define CLOUDSYNC_VERSION "0.8.7"
2020

2121
int sqlite3_cloudsync_init (sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi);
2222

src/network.c

Lines changed: 3 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@
1919
#include "curl/curl.h"
2020
#endif
2121
#else
22-
#include <stdlib.h>
23-
#include <emscripten/fetch.h>
24-
#include <emscripten/emscripten.h>
22+
#define curl_free(x) free(x)
23+
char *substr(const char *start, const char *end);
2524
#endif
2625

2726
#ifdef __ANDROID__
@@ -102,103 +101,6 @@ bool network_data_set_endpoints (network_data *data, char *auth, char *check, ch
102101
// MARK: - Utils -
103102

104103
#ifndef CLOUDSYNC_OMIT_CURL
105-
#ifdef SQLITE_WASM_EXTRA_INIT
106-
NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint, const char *authentication, bool zero_terminated, bool is_post_request, char *json_payload, const char *custom_header) {
107-
char *buffer = NULL;
108-
size_t blen = 0;
109-
110-
emscripten_fetch_attr_t attr;
111-
emscripten_fetch_attr_init(&attr);
112-
113-
// Set method
114-
if (json_payload || is_post_request) {
115-
strcpy(attr.requestMethod, "POST");
116-
} else {
117-
strcpy(attr.requestMethod, "GET");
118-
}
119-
attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_SYNCHRONOUS | EMSCRIPTEN_FETCH_REPLACE;
120-
121-
// Prepare header array (alternating key, value, NULL-terminated)
122-
const char *headers[11];
123-
int h = 0;
124-
125-
// Custom header (must be "Key: Value", split at ':')
126-
char *custom_key = NULL;
127-
if (custom_header) {
128-
const char *colon = strchr(custom_header, ':');
129-
if (colon) {
130-
size_t klen = colon - custom_header;
131-
custom_key = (char *)malloc(klen + 1);
132-
strncpy(custom_key, custom_header, klen);
133-
custom_key[klen] = 0;
134-
const char *custom_val = colon + 1;
135-
while (*custom_val == ' ') custom_val++;
136-
headers[h++] = custom_key;
137-
headers[h++] = custom_val;
138-
}
139-
}
140-
141-
// Authorization
142-
char auth_header[256];
143-
if (authentication) {
144-
snprintf(auth_header, sizeof(auth_header), "Bearer %s", authentication);
145-
headers[h++] = "Authorization";
146-
headers[h++] = auth_header;
147-
}
148-
149-
// Content-Type for JSON
150-
if (json_payload) {
151-
headers[h++] = "Content-Type";
152-
headers[h++] = "application/json";
153-
}
154-
155-
headers[h] = 0;
156-
attr.requestHeaders = headers;
157-
158-
// Body
159-
if (json_payload) {
160-
attr.requestData = json_payload;
161-
attr.requestDataSize = strlen(json_payload);
162-
}
163-
164-
emscripten_fetch_t *fetch = emscripten_fetch(&attr, endpoint); // Blocks here until the operation is complete.
165-
NETWORK_RESULT result = {0, NULL, 0, NULL, NULL};
166-
167-
if(fetch->readyState == 4){
168-
buffer = fetch->data;
169-
blen = fetch->totalBytes;
170-
}
171-
172-
if (fetch->status >= 200 && fetch->status < 300) {
173-
174-
if (blen > 0 && buffer) {
175-
char *buf = (char*)malloc(blen + 1);
176-
if (buf) {
177-
memcpy(buf, buffer, blen);
178-
buf[blen] = 0;
179-
result.code = CLOUDSYNC_NETWORK_BUFFER;
180-
result.buffer = buf;
181-
result.blen = blen;
182-
result.xfree = free;
183-
} else result.code = CLOUDSYNC_NETWORK_ERROR;
184-
} else result.code = CLOUDSYNC_NETWORK_OK;
185-
} else {
186-
result.code = CLOUDSYNC_NETWORK_ERROR;
187-
if (fetch->statusText && fetch->statusText[0]) {
188-
result.buffer = strdup(fetch->statusText);
189-
}
190-
result.blen = sizeof(fetch->statusText);
191-
result.xfree = free;
192-
}
193-
194-
// cleanup
195-
emscripten_fetch_close(fetch);
196-
if (custom_key) free(custom_key);
197-
198-
return result;
199-
}
200-
#else
201-
202104
static bool network_buffer_check (network_buffer *data, size_t needed) {
203105
// alloc/resize buffer
204106
if (data->bused + needed > data->balloc) {
@@ -307,7 +209,6 @@ NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint,
307209

308210
return result;
309211
}
310-
#endif
311212

312213
static size_t network_read_callback(char *buffer, size_t size, size_t nitems, void *userdata) {
313214
network_read_data *rd = (network_read_data *)userdata;
@@ -323,44 +224,6 @@ static size_t network_read_callback(char *buffer, size_t size, size_t nitems, vo
323224
return to_copy;
324225
}
325226

326-
#ifdef SQLITE_WASM_EXTRA_INIT
327-
bool network_send_buffer(network_data *data, const char *endpoint, const char *authentication, const void *blob, int blob_size) {
328-
329-
bool result = false;
330-
emscripten_fetch_attr_t attr;
331-
emscripten_fetch_attr_init(&attr);
332-
strcpy(attr.requestMethod, "PUT");
333-
attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_SYNCHRONOUS | EMSCRIPTEN_FETCH_REPLACE;
334-
335-
// Prepare headers (alternating key, value, NULL-terminated)
336-
// Max 3 headers: Accept, (optional Auth), Content-Type
337-
const char *headers[7];
338-
int h = 0;
339-
headers[h++] = "Accept";
340-
headers[h++] = "text/plain";
341-
char auth_header[256];
342-
if (authentication) {
343-
snprintf(auth_header, sizeof(auth_header), "Bearer %s", authentication);
344-
headers[h++] = "Authorization";
345-
headers[h++] = auth_header;
346-
}
347-
headers[h++] = "Content-Type";
348-
headers[h++] = "application/octet-stream";
349-
headers[h] = 0;
350-
attr.requestHeaders = headers;
351-
352-
// Set request body
353-
attr.requestData = (const char *)blob;
354-
attr.requestDataSize = blob_size;
355-
356-
emscripten_fetch_t *fetch = emscripten_fetch(&attr, endpoint); // Blocks here until the operation is complete.
357-
if (fetch->status >= 200 && fetch->status < 300) result = true;
358-
359-
emscripten_fetch_close(fetch);
360-
361-
return result;
362-
}
363-
#else
364227
bool network_send_buffer(network_data *data, const char *endpoint, const char *authentication, const void *blob, int blob_size) {
365228
struct curl_slist *headers = NULL;
366229
curl_mime *mime = NULL;
@@ -433,7 +296,6 @@ bool network_send_buffer(network_data *data, const char *endpoint, const char *a
433296
return result;
434297
}
435298
#endif
436-
#endif
437299

438300
int network_set_sqlite_result (sqlite3_context *context, NETWORK_RESULT *result) {
439301
int rc = 0;
@@ -539,19 +401,6 @@ int network_extract_query_param(const char *query, const char *key, char *output
539401
}
540402

541403
#ifndef CLOUDSYNC_OMIT_CURL
542-
543-
#ifdef SQLITE_WASM_EXTRA_INIT
544-
static char *substr(const char *start, const char *end) {
545-
size_t len = end - start;
546-
char *out = (char *)malloc(len + 1);
547-
if (out) {
548-
memcpy(out, start, len);
549-
out[len] = 0;
550-
}
551-
return out;
552-
}
553-
#endif
554-
555404
bool network_compute_endpoints (sqlite3_context *context, network_data *data, const char *conn_string) {
556405
// compute endpoints
557406
bool result = false;
@@ -632,6 +481,7 @@ bool network_compute_endpoints (sqlite3_context *context, network_data *data, co
632481
if (!scheme || !host || !database) goto finalize;
633482
char *port_or_default = port && strcmp(port, "8860") != 0 ? port : CLOUDSYNC_DEFAULT_ENDPOINT_PORT;
634483
#endif
484+
635485
if (query != NULL) {
636486
char value[MAX_QUERY_VALUE_LEN];
637487
if (!authentication && network_extract_query_param(query, "apikey", value, sizeof(value)) == 0) {
@@ -685,8 +535,6 @@ bool network_compute_endpoints (sqlite3_context *context, network_data *data, co
685535
// cleanup memory
686536
#ifndef SQLITE_WASM_EXTRA_INIT
687537
if (url) curl_url_cleanup(url);
688-
#else
689-
#define curl_free(x) free(x)
690538
#endif
691539
if (scheme) curl_free(scheme);
692540
if (host) curl_free(host);

src/wasm.c

Lines changed: 153 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
#ifdef SQLITE_WASM_EXTRA_INIT
22

3-
#include "sqlite3.h"
43
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <emscripten/fetch.h>
6+
#include <emscripten/emscripten.h>
7+
8+
#include "sqlite3.h"
9+
#include "netword_private.h"
510

611
#include "utils.c"
712
#include "network.c"
@@ -11,9 +16,155 @@
1116
#include "pk.c"
1217
#include "lz4.c"
1318

19+
// MARK: - WASM -
20+
21+
char *substr(const char *start, const char *end) {
22+
size_t len = end - start;
23+
char *out = (char *)malloc(len + 1);
24+
if (out) {
25+
memcpy(out, start, len);
26+
out[len] = 0;
27+
}
28+
return out;
29+
}
30+
31+
NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint, const char *authentication, bool zero_terminated, bool is_post_request, char *json_payload, const char *custom_header) {
32+
char *buffer = NULL;
33+
size_t blen = 0;
34+
35+
emscripten_fetch_attr_t attr;
36+
emscripten_fetch_attr_init(&attr);
37+
38+
// Set method
39+
if (json_payload || is_post_request) {
40+
strcpy(attr.requestMethod, "POST");
41+
} else {
42+
strcpy(attr.requestMethod, "GET");
43+
}
44+
attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_SYNCHRONOUS | EMSCRIPTEN_FETCH_REPLACE;
45+
46+
// Prepare header array (alternating key, value, NULL-terminated)
47+
const char *headers[11];
48+
int h = 0;
49+
50+
// Custom header (must be "Key: Value", split at ':')
51+
char *custom_key = NULL;
52+
if (custom_header) {
53+
const char *colon = strchr(custom_header, ':');
54+
if (colon) {
55+
size_t klen = colon - custom_header;
56+
custom_key = (char *)malloc(klen + 1);
57+
strncpy(custom_key, custom_header, klen);
58+
custom_key[klen] = 0;
59+
const char *custom_val = colon + 1;
60+
while (*custom_val == ' ') custom_val++;
61+
headers[h++] = custom_key;
62+
headers[h++] = custom_val;
63+
}
64+
}
65+
66+
// Authorization
67+
char auth_header[256];
68+
if (authentication) {
69+
snprintf(auth_header, sizeof(auth_header), "Bearer %s", authentication);
70+
headers[h++] = "Authorization";
71+
headers[h++] = auth_header;
72+
}
73+
74+
// Content-Type for JSON
75+
if (json_payload) {
76+
headers[h++] = "Content-Type";
77+
headers[h++] = "application/json";
78+
}
79+
80+
headers[h] = 0;
81+
attr.requestHeaders = headers;
82+
83+
// Body
84+
if (json_payload) {
85+
attr.requestData = json_payload;
86+
attr.requestDataSize = strlen(json_payload);
87+
}
88+
89+
emscripten_fetch_t *fetch = emscripten_fetch(&attr, endpoint); // Blocks here until the operation is complete.
90+
NETWORK_RESULT result = {0, NULL, 0, NULL, NULL};
91+
92+
if(fetch->readyState == 4){
93+
buffer = fetch->data;
94+
blen = fetch->totalBytes;
95+
}
96+
97+
if (fetch->status >= 200 && fetch->status < 300) {
98+
99+
if (blen > 0 && buffer) {
100+
char *buf = (char*)malloc(blen + 1);
101+
if (buf) {
102+
memcpy(buf, buffer, blen);
103+
buf[blen] = 0;
104+
result.code = CLOUDSYNC_NETWORK_BUFFER;
105+
result.buffer = buf;
106+
result.blen = blen;
107+
result.xfree = free;
108+
} else result.code = CLOUDSYNC_NETWORK_ERROR;
109+
} else result.code = CLOUDSYNC_NETWORK_OK;
110+
} else {
111+
result.code = CLOUDSYNC_NETWORK_ERROR;
112+
if (fetch->statusText && fetch->statusText[0]) {
113+
result.buffer = strdup(fetch->statusText);
114+
}
115+
result.blen = sizeof(fetch->statusText);
116+
result.xfree = free;
117+
}
118+
119+
// cleanup
120+
emscripten_fetch_close(fetch);
121+
if (custom_key) free(custom_key);
122+
123+
return result;
124+
}
125+
126+
bool network_send_buffer(network_data *data, const char *endpoint, const char *authentication, const void *blob, int blob_size) {
127+
128+
bool result = false;
129+
emscripten_fetch_attr_t attr;
130+
emscripten_fetch_attr_init(&attr);
131+
strcpy(attr.requestMethod, "PUT");
132+
attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_SYNCHRONOUS | EMSCRIPTEN_FETCH_REPLACE;
133+
134+
// Prepare headers (alternating key, value, NULL-terminated)
135+
// Max 3 headers: Accept, (optional Auth), Content-Type
136+
const char *headers[7];
137+
int h = 0;
138+
headers[h++] = "Accept";
139+
headers[h++] = "text/plain";
140+
char auth_header[256];
141+
if (authentication) {
142+
snprintf(auth_header, sizeof(auth_header), "Bearer %s", authentication);
143+
headers[h++] = "Authorization";
144+
headers[h++] = auth_header;
145+
}
146+
headers[h++] = "Content-Type";
147+
headers[h++] = "application/octet-stream";
148+
headers[h] = 0;
149+
attr.requestHeaders = headers;
150+
151+
// Set request body
152+
attr.requestData = (const char *)blob;
153+
attr.requestDataSize = blob_size;
154+
155+
emscripten_fetch_t *fetch = emscripten_fetch(&attr, endpoint); // Blocks here until the operation is complete.
156+
if (fetch->status >= 200 && fetch->status < 300) result = true;
157+
158+
emscripten_fetch_close(fetch);
159+
160+
return result;
161+
}
162+
163+
// MARK: -
164+
14165
int sqlite3_wasm_extra_init(const char *z) {
15166
fprintf(stderr, "%s: %s()\n", __FILE__, __func__);
16167
return sqlite3_auto_extension((void *) sqlite3_cloudsync_init);
17168
}
18169

19-
#endif
170+
#endif

0 commit comments

Comments
 (0)