-
Notifications
You must be signed in to change notification settings - Fork 4
/
sqlite3_base64.c
74 lines (57 loc) · 1.98 KB
/
sqlite3_base64.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "sqlite3_base64.h"
#include "cencode.h"
#include "cdecode.h"
#include <string.h>
#include <stdint.h>
static
void sqlite3_base64(sqlite3_context * context, int argc, sqlite3_value ** argv) {
if (argc < 1) {
sqlite3_result_null(context);
} else {
// THANKS FOR GUIDANCE:
// https://www.sqlite.org/cgi/src/artifact/43916c1d8e6da5d1
// (src/func.c:hexFunc)
sqlite3_value * first = argv[0];
const uint8_t * blob = sqlite3_value_blob(first);
const int blen = sqlite3_value_bytes(first);
char * b64 = sqlite3_malloc(blen*2);
base64_encodestate es;
base64_init_encodestate(&es);
{
const int len1 = base64_encode_block(blob, blen, b64, &es);
const int len = len1 + base64_encode_blockend(b64 + len1, &es);
sqlite3_result_text(context, b64, len, sqlite3_free);
}
}
}
static
void sqlite3_blobfrombase64(
sqlite3_context * context,
int argc,
sqlite3_value ** argv
) {
// Base64 value is WANTED in TEXT format
// It *may* be possible to get Base64 from INTEGER, does not seem interesting.
if (argc < 1 || sqlite3_value_type(argv[0]) != SQLITE_TEXT) {
sqlite3_result_null(context);
} else {
// get the info
sqlite3_value * first = argv[0];
const uint8_t * base64 = sqlite3_value_text(first);
const int base64_length = sqlite3_value_bytes(first);
// overestimating length needed is **much** better than underestimating !!
const uint8_t * blob = sqlite3_malloc(base64_length);
base64_decodestate ds;
base64_init_decodestate(&ds);
{
const int len = base64_decode_block(base64, base64_length, blob, &ds);
sqlite3_result_blob(context, blob, len, sqlite3_free);
}
}
}
int sqlite3_base64_init(sqlite3 * db)
{
sqlite3_create_function_v2(db, "BASE64", 1, SQLITE_ANY | SQLITE_DETERMINISTIC, NULL, sqlite3_base64, NULL, NULL, NULL);
sqlite3_create_function_v2(db, "BLOBFROMBASE64", 1, SQLITE_ANY | SQLITE_DETERMINISTIC, NULL, sqlite3_blobfrombase64, NULL, NULL, NULL);
return 0;
}