iodine 0.6.5 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +4 -4
- data/SPEC-Websocket-Draft.md +3 -6
- data/bin/mustache.rb +128 -0
- data/examples/test_template.mustache +16 -0
- data/ext/iodine/fio.c +9397 -0
- data/ext/iodine/fio.h +4723 -0
- data/ext/iodine/fio_ary.h +353 -54
- data/ext/iodine/fio_cli.c +351 -361
- data/ext/iodine/fio_cli.h +84 -105
- data/ext/iodine/fio_hashmap.h +70 -16
- data/ext/iodine/fio_json_parser.h +35 -24
- data/ext/iodine/fio_siphash.c +104 -4
- data/ext/iodine/fio_siphash.h +18 -2
- data/ext/iodine/fio_str.h +1218 -0
- data/ext/iodine/fio_tmpfile.h +1 -1
- data/ext/iodine/fiobj.h +13 -8
- data/ext/iodine/fiobj4sock.h +6 -8
- data/ext/iodine/fiobj_ary.c +107 -17
- data/ext/iodine/fiobj_ary.h +36 -4
- data/ext/iodine/fiobj_data.c +146 -127
- data/ext/iodine/fiobj_data.h +25 -23
- data/ext/iodine/fiobj_hash.c +7 -7
- data/ext/iodine/fiobj_hash.h +6 -5
- data/ext/iodine/fiobj_json.c +20 -17
- data/ext/iodine/fiobj_json.h +5 -5
- data/ext/iodine/fiobj_mem.h +71 -0
- data/ext/iodine/fiobj_mustache.c +310 -0
- data/ext/iodine/fiobj_mustache.h +40 -0
- data/ext/iodine/fiobj_numbers.c +199 -94
- data/ext/iodine/fiobj_numbers.h +7 -7
- data/ext/iodine/fiobj_str.c +142 -333
- data/ext/iodine/fiobj_str.h +65 -55
- data/ext/iodine/fiobject.c +49 -11
- data/ext/iodine/fiobject.h +40 -39
- data/ext/iodine/http.c +382 -190
- data/ext/iodine/http.h +124 -80
- data/ext/iodine/http1.c +99 -127
- data/ext/iodine/http1.h +5 -5
- data/ext/iodine/http1_parser.c +3 -2
- data/ext/iodine/http1_parser.h +2 -2
- data/ext/iodine/http_internal.c +14 -12
- data/ext/iodine/http_internal.h +25 -19
- data/ext/iodine/iodine.c +37 -18
- data/ext/iodine/iodine.h +4 -0
- data/ext/iodine/iodine_caller.c +9 -2
- data/ext/iodine/iodine_caller.h +2 -0
- data/ext/iodine/iodine_connection.c +82 -117
- data/ext/iodine/iodine_defer.c +57 -50
- data/ext/iodine/iodine_defer.h +0 -1
- data/ext/iodine/iodine_fiobj2rb.h +4 -2
- data/ext/iodine/iodine_helpers.c +4 -4
- data/ext/iodine/iodine_http.c +25 -32
- data/ext/iodine/iodine_json.c +2 -1
- data/ext/iodine/iodine_mustache.c +423 -0
- data/ext/iodine/iodine_mustache.h +6 -0
- data/ext/iodine/iodine_pubsub.c +48 -153
- data/ext/iodine/iodine_pubsub.h +5 -4
- data/ext/iodine/iodine_rack_io.c +7 -5
- data/ext/iodine/iodine_store.c +16 -13
- data/ext/iodine/iodine_tcp.c +26 -34
- data/ext/iodine/mustache_parser.h +1085 -0
- data/ext/iodine/redis_engine.c +740 -646
- data/ext/iodine/redis_engine.h +13 -15
- data/ext/iodine/resp_parser.h +11 -5
- data/ext/iodine/websocket_parser.h +13 -13
- data/ext/iodine/websockets.c +240 -393
- data/ext/iodine/websockets.h +52 -113
- data/lib/iodine.rb +1 -1
- data/lib/iodine/mustache.rb +140 -0
- data/lib/iodine/version.rb +1 -1
- metadata +15 -28
- data/ext/iodine/defer.c +0 -566
- data/ext/iodine/defer.h +0 -148
- data/ext/iodine/evio.c +0 -26
- data/ext/iodine/evio.h +0 -161
- data/ext/iodine/evio_callbacks.c +0 -26
- data/ext/iodine/evio_epoll.c +0 -251
- data/ext/iodine/evio_kqueue.c +0 -194
- data/ext/iodine/facil.c +0 -2325
- data/ext/iodine/facil.h +0 -616
- data/ext/iodine/fio_base64.c +0 -277
- data/ext/iodine/fio_base64.h +0 -71
- data/ext/iodine/fio_llist.h +0 -257
- data/ext/iodine/fio_mem.c +0 -675
- data/ext/iodine/fio_mem.h +0 -143
- data/ext/iodine/fio_random.c +0 -248
- data/ext/iodine/fio_random.h +0 -45
- data/ext/iodine/fio_sha1.c +0 -362
- data/ext/iodine/fio_sha1.h +0 -107
- data/ext/iodine/fio_sha2.c +0 -842
- data/ext/iodine/fio_sha2.h +0 -169
- data/ext/iodine/pubsub.c +0 -867
- data/ext/iodine/pubsub.h +0 -221
- data/ext/iodine/sock.c +0 -1366
- data/ext/iodine/sock.h +0 -566
- data/ext/iodine/spnlock.inc +0 -111
data/ext/iodine/fio_base64.c
DELETED
@@ -1,277 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
Copyright: Boaz Segev, 2016-2018
|
3
|
-
License: MIT except for any non-public-domain algorithms (none that I'm aware
|
4
|
-
of), which might be subject to their own licenses.
|
5
|
-
|
6
|
-
Feel free to copy, use and enjoy in accordance with to the license(s).
|
7
|
-
*/
|
8
|
-
#ifndef _GNU_SOURCE
|
9
|
-
#define _GNU_SOURCE
|
10
|
-
#endif
|
11
|
-
#include "fio_base64.h"
|
12
|
-
|
13
|
-
#include <stdint.h>
|
14
|
-
#include <stdlib.h>
|
15
|
-
/* ****************************************************************************
|
16
|
-
Base64 encoding
|
17
|
-
***************************************************************************** */
|
18
|
-
|
19
|
-
/** the base64 encoding array */
|
20
|
-
static char base64_encodes[] =
|
21
|
-
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
22
|
-
|
23
|
-
/**
|
24
|
-
a base64 decoding array
|
25
|
-
*/
|
26
|
-
static unsigned base64_decodes[] = {
|
27
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
28
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
29
|
-
0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60,
|
30
|
-
61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
31
|
-
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0,
|
32
|
-
0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
|
33
|
-
43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
34
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
35
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
36
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
37
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
38
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
39
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
40
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0};
|
41
|
-
|
42
|
-
/**
|
43
|
-
This will encode a byte array (data) of a specified length (len) and
|
44
|
-
place the encoded data into the target byte buffer (target). The target buffer
|
45
|
-
MUST have enough room for the expected data.
|
46
|
-
|
47
|
-
Base64 encoding always requires 4 bytes for each 3 bytes. Padding is added if
|
48
|
-
the raw data's length isn't devisable by 3.
|
49
|
-
|
50
|
-
Always assume the target buffer should have room enough for (len*4/3 + 4)
|
51
|
-
bytes.
|
52
|
-
|
53
|
-
Returns the number of bytes actually written to the target buffer
|
54
|
-
(including the Base64 required padding and excluding a NULL terminator).
|
55
|
-
|
56
|
-
A NULL terminator char is NOT written to the target buffer.
|
57
|
-
*/
|
58
|
-
int fio_base64_encode(char *target, const char *data, int len) {
|
59
|
-
/* walk backwards, allowing fo inplace decoding (target == data) */
|
60
|
-
int groups = len / 3;
|
61
|
-
const int mod = len - (groups * 3);
|
62
|
-
const int target_size = (groups + (mod != 0)) * 4;
|
63
|
-
char *writer = target + target_size - 1;
|
64
|
-
const char *reader = data + len - 1;
|
65
|
-
writer[1] = 0;
|
66
|
-
switch (mod) {
|
67
|
-
case 2: {
|
68
|
-
char tmp2 = *(reader--);
|
69
|
-
char tmp1 = *(reader--);
|
70
|
-
*(writer--) = '=';
|
71
|
-
*(writer--) = base64_encodes[((tmp2 & 15) << 2)];
|
72
|
-
*(writer--) = base64_encodes[((tmp1 & 3) << 4) | ((tmp2 >> 4) & 15)];
|
73
|
-
*(writer--) = base64_encodes[(tmp1 >> 2) & 63];
|
74
|
-
} break;
|
75
|
-
case 1: {
|
76
|
-
char tmp1 = *(reader--);
|
77
|
-
*(writer--) = '=';
|
78
|
-
*(writer--) = '=';
|
79
|
-
*(writer--) = base64_encodes[(tmp1 & 3) << 4];
|
80
|
-
*(writer--) = base64_encodes[(tmp1 >> 2) & 63];
|
81
|
-
} break;
|
82
|
-
}
|
83
|
-
while (groups) {
|
84
|
-
groups--;
|
85
|
-
const char tmp3 = *(reader--);
|
86
|
-
const char tmp2 = *(reader--);
|
87
|
-
const char tmp1 = *(reader--);
|
88
|
-
*(writer--) = base64_encodes[tmp3 & 63];
|
89
|
-
*(writer--) = base64_encodes[((tmp2 & 15) << 2) | ((tmp3 >> 6) & 3)];
|
90
|
-
*(writer--) = base64_encodes[(((tmp1 & 3) << 4) | ((tmp2 >> 4) & 15))];
|
91
|
-
*(writer--) = base64_encodes[(tmp1 >> 2) & 63];
|
92
|
-
}
|
93
|
-
return target_size;
|
94
|
-
}
|
95
|
-
|
96
|
-
/**
|
97
|
-
This will decode a Base64 encoded string of a specified length (len) and
|
98
|
-
place the decoded data into the target byte buffer (target).
|
99
|
-
|
100
|
-
The target buffer MUST have enough room for the expected data.
|
101
|
-
|
102
|
-
A NULL byte will be appended to the target buffer. The function will return
|
103
|
-
the number of bytes written to the target buffer.
|
104
|
-
|
105
|
-
If the target buffer is NULL, the encoded string will be destructively edited
|
106
|
-
and the decoded data will be placed in the original string's buffer.
|
107
|
-
|
108
|
-
Base64 encoding always requires 4 bytes for each 3 bytes. Padding is added if
|
109
|
-
the raw data's length isn't devisable by 3. Hence, the target buffer should
|
110
|
-
be, at least, `base64_len/4*3 + 3` long.
|
111
|
-
|
112
|
-
Returns the number of bytes actually written to the target buffer (excluding
|
113
|
-
the NULL terminator byte).
|
114
|
-
*/
|
115
|
-
int fio_base64_decode(char *target, char *encoded, int base64_len) {
|
116
|
-
if (!target)
|
117
|
-
target = encoded;
|
118
|
-
if (base64_len <= 0) {
|
119
|
-
target[0] = 0;
|
120
|
-
return 0;
|
121
|
-
}
|
122
|
-
int written = 0;
|
123
|
-
char tmp1, tmp2, tmp3, tmp4;
|
124
|
-
while (*encoded == '\r' || *encoded == '\n' || *encoded == ' ') {
|
125
|
-
base64_len--;
|
126
|
-
encoded++;
|
127
|
-
}
|
128
|
-
while (encoded[base64_len - 1] == '\r' || encoded[base64_len - 1] == '\n' ||
|
129
|
-
encoded[base64_len - 1] == ' ' || encoded[base64_len - 1] == 0) {
|
130
|
-
base64_len--;
|
131
|
-
}
|
132
|
-
while (base64_len >= 4) {
|
133
|
-
tmp1 = *(encoded++);
|
134
|
-
tmp2 = *(encoded++);
|
135
|
-
tmp3 = *(encoded++);
|
136
|
-
tmp4 = *(encoded++);
|
137
|
-
*(target++) = (base64_decodes[(size_t)tmp1] << 2) |
|
138
|
-
(base64_decodes[(size_t)tmp2] >> 4);
|
139
|
-
*(target++) = (base64_decodes[(size_t)tmp2] << 4) |
|
140
|
-
(base64_decodes[(size_t)tmp3] >> 2);
|
141
|
-
*(target++) =
|
142
|
-
(base64_decodes[(size_t)tmp3] << 6) | (base64_decodes[(size_t)tmp4]);
|
143
|
-
// make sure we don't loop forever.
|
144
|
-
base64_len -= 4;
|
145
|
-
// count written bytes
|
146
|
-
written += 3;
|
147
|
-
// skip white space
|
148
|
-
while (base64_len &&
|
149
|
-
(*encoded == '\r' || *encoded == '\n' || *encoded == ' ')) {
|
150
|
-
base64_len--;
|
151
|
-
encoded++;
|
152
|
-
}
|
153
|
-
}
|
154
|
-
// deal with the "tail" of the mis-encoded stream - this shouldn't happen
|
155
|
-
tmp1 = 0;
|
156
|
-
tmp2 = 0;
|
157
|
-
tmp3 = 0;
|
158
|
-
tmp4 = 0;
|
159
|
-
switch (base64_len) {
|
160
|
-
case 1:
|
161
|
-
tmp1 = *(encoded++);
|
162
|
-
*(target++) = base64_decodes[(size_t)tmp1];
|
163
|
-
written += 1;
|
164
|
-
break;
|
165
|
-
case 2:
|
166
|
-
tmp1 = *(encoded++);
|
167
|
-
tmp2 = *(encoded++);
|
168
|
-
*(target++) = (base64_decodes[(size_t)tmp1] << 2) |
|
169
|
-
(base64_decodes[(size_t)tmp2] >> 6);
|
170
|
-
*(target++) = (base64_decodes[(size_t)tmp2] << 4);
|
171
|
-
written += 2;
|
172
|
-
break;
|
173
|
-
case 3:
|
174
|
-
tmp1 = *(encoded++);
|
175
|
-
tmp2 = *(encoded++);
|
176
|
-
tmp3 = *(encoded++);
|
177
|
-
*(target++) = (base64_decodes[(size_t)tmp1] << 2) |
|
178
|
-
(base64_decodes[(size_t)tmp2] >> 6);
|
179
|
-
*(target++) = (base64_decodes[(size_t)tmp2] << 4) |
|
180
|
-
(base64_decodes[(size_t)tmp3] >> 2);
|
181
|
-
*(target++) = base64_decodes[(size_t)tmp3] << 6;
|
182
|
-
written += 3;
|
183
|
-
break;
|
184
|
-
}
|
185
|
-
if (encoded[-1] == '=') {
|
186
|
-
target--;
|
187
|
-
written--;
|
188
|
-
if (encoded[-2] == '=') {
|
189
|
-
target--;
|
190
|
-
written--;
|
191
|
-
}
|
192
|
-
}
|
193
|
-
*target = 0;
|
194
|
-
return written;
|
195
|
-
}
|
196
|
-
|
197
|
-
/* *****************************************************************************
|
198
|
-
Base64 Testing
|
199
|
-
***************************************************************************** */
|
200
|
-
#if defined(DEBUG) && DEBUG == 1
|
201
|
-
#include <stdio.h>
|
202
|
-
#include <string.h>
|
203
|
-
#include <time.h>
|
204
|
-
|
205
|
-
void fio_base64_test(void) {
|
206
|
-
struct {
|
207
|
-
char *str;
|
208
|
-
char *base64;
|
209
|
-
} sets[] = {
|
210
|
-
// {"Man is distinguished, not only by his reason, but by this singular "
|
211
|
-
// "passion from other animals, which is a lust of the mind, that by a "
|
212
|
-
// "perseverance of delight in the continued and indefatigable generation
|
213
|
-
// "
|
214
|
-
// "of knowledge, exceeds the short vehemence of any carnal pleasure.",
|
215
|
-
// "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB"
|
216
|
-
// "0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIG"
|
217
|
-
// "x1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpb"
|
218
|
-
// "iB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xl"
|
219
|
-
// "ZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3V"
|
220
|
-
// "yZS4="},
|
221
|
-
{"any carnal pleasure.", "YW55IGNhcm5hbCBwbGVhc3VyZS4="},
|
222
|
-
{"any carnal pleasure", "YW55IGNhcm5hbCBwbGVhc3VyZQ=="},
|
223
|
-
{"any carnal pleasur", "YW55IGNhcm5hbCBwbGVhc3Vy"},
|
224
|
-
{"", ""},
|
225
|
-
{"f", "Zg=="},
|
226
|
-
{"fo", "Zm8="},
|
227
|
-
{"foo", "Zm9v"},
|
228
|
-
{"foob", "Zm9vYg=="},
|
229
|
-
{"fooba", "Zm9vYmE="},
|
230
|
-
{"foobar", "Zm9vYmFy"},
|
231
|
-
{NULL, NULL} // Stop
|
232
|
-
};
|
233
|
-
int i = 0;
|
234
|
-
char buffer[1024];
|
235
|
-
fprintf(stderr, "+ fio");
|
236
|
-
while (sets[i].str) {
|
237
|
-
fio_base64_encode(buffer, sets[i].str, strlen(sets[i].str));
|
238
|
-
if (strcmp(buffer, sets[i].base64)) {
|
239
|
-
fprintf(stderr,
|
240
|
-
":\n--- fio Base64 Test FAILED!\nstring: %s\nlength: %lu\n "
|
241
|
-
"expected: %s\ngot: %s\n\n",
|
242
|
-
sets[i].str, strlen(sets[i].str), sets[i].base64, buffer);
|
243
|
-
break;
|
244
|
-
}
|
245
|
-
i++;
|
246
|
-
}
|
247
|
-
if (!sets[i].str)
|
248
|
-
fprintf(stderr, " Base64 encode passed.\n");
|
249
|
-
|
250
|
-
i = 0;
|
251
|
-
fprintf(stderr, "+ fio");
|
252
|
-
while (sets[i].str) {
|
253
|
-
fio_base64_decode(buffer, sets[i].base64, strlen(sets[i].base64));
|
254
|
-
if (strcmp(buffer, sets[i].str)) {
|
255
|
-
fprintf(stderr,
|
256
|
-
":\n--- fio Base64 Test FAILED!\nbase64: %s\nexpected: "
|
257
|
-
"%s\ngot: %s\n\n",
|
258
|
-
sets[i].base64, sets[i].str, buffer);
|
259
|
-
return;
|
260
|
-
}
|
261
|
-
i++;
|
262
|
-
}
|
263
|
-
fprintf(stderr, " Base64 decode passed.\n");
|
264
|
-
{
|
265
|
-
char buff_b64[] = "any carnal pleasure.";
|
266
|
-
clock_t start = clock();
|
267
|
-
for (i = 0; i < 100000; i++) {
|
268
|
-
size_t b64_len =
|
269
|
-
fio_base64_encode(buffer, buff_b64, sizeof(buff_b64) - 1);
|
270
|
-
fio_base64_decode(buff_b64, buffer, b64_len);
|
271
|
-
}
|
272
|
-
fprintf(stderr, "fio 100K Base64: %lf\n",
|
273
|
-
(double)(clock() - start) / CLOCKS_PER_SEC);
|
274
|
-
(void)buff_b64;
|
275
|
-
}
|
276
|
-
}
|
277
|
-
#endif
|
data/ext/iodine/fio_base64.h
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
Copyright: Boaz Segev, 2016-2018
|
3
|
-
License: MIT except for any non-public-domain algorithms (none that I'm aware
|
4
|
-
of), which might be subject to their own licenses.
|
5
|
-
|
6
|
-
Feel free to copy, use and enjoy in accordance with to the license(s).
|
7
|
-
*/
|
8
|
-
#ifndef H_FIO_BASE64_H
|
9
|
-
#define H_FIO_BASE64_H
|
10
|
-
/* *****************************************************************************
|
11
|
-
C++ extern
|
12
|
-
*/
|
13
|
-
#if defined(__cplusplus)
|
14
|
-
extern "C" {
|
15
|
-
#endif
|
16
|
-
|
17
|
-
/* ***************************************************************************
|
18
|
-
Base64 encoding
|
19
|
-
*/
|
20
|
-
|
21
|
-
/**
|
22
|
-
This will encode a byte array (data) of a specified length (len) and
|
23
|
-
place the encoded data into the target byte buffer (target). The target buffer
|
24
|
-
MUST have enough room for the expected data.
|
25
|
-
|
26
|
-
Base64 encoding always requires 4 bytes for each 3 bytes. Padding is added if
|
27
|
-
the raw data's length isn't devisable by 3.
|
28
|
-
|
29
|
-
Always assume the target buffer should have room enough for (len*4/3 + 4)
|
30
|
-
bytes.
|
31
|
-
|
32
|
-
Returns the number of bytes actually written to the target buffer
|
33
|
-
(including the Base64 required padding and excluding a NULL terminator).
|
34
|
-
|
35
|
-
A NULL terminator char is NOT written to the target buffer.
|
36
|
-
*/
|
37
|
-
int fio_base64_encode(char *target, const char *data, int len);
|
38
|
-
|
39
|
-
/**
|
40
|
-
This will decode a Base64 encoded string of a specified length (len) and
|
41
|
-
place the decoded data into the target byte buffer (target).
|
42
|
-
|
43
|
-
The target buffer MUST have enough room for the expected data.
|
44
|
-
|
45
|
-
A NULL byte will be appended to the target buffer. The function will return
|
46
|
-
the number of bytes written to the target buffer.
|
47
|
-
|
48
|
-
If the target buffer is NULL, the encoded string will be destructively edited
|
49
|
-
and the decoded data will be placed in the original string's buffer.
|
50
|
-
|
51
|
-
Base64 encoding always requires 4 bytes for each 3 bytes. Padding is added if
|
52
|
-
the raw data's length isn't devisable by 3. Hence, the target buffer should
|
53
|
-
be, at least, `base64_len/4*3 + 3` long.
|
54
|
-
|
55
|
-
Returns the number of bytes actually written to the target buffer (excluding
|
56
|
-
the NULL terminator byte).
|
57
|
-
*/
|
58
|
-
int fio_base64_decode(char *target, char *encoded, int base64_len);
|
59
|
-
|
60
|
-
#if defined(DEBUG) && DEBUG == 1
|
61
|
-
void fio_base64_test(void);
|
62
|
-
#endif
|
63
|
-
|
64
|
-
/* *****************************************************************************
|
65
|
-
C++ extern finish
|
66
|
-
*/
|
67
|
-
#if defined(__cplusplus)
|
68
|
-
}
|
69
|
-
#endif
|
70
|
-
|
71
|
-
#endif
|
data/ext/iodine/fio_llist.h
DELETED
@@ -1,257 +0,0 @@
|
|
1
|
-
#ifndef H_FIO_SIMPLE_LIST_H
|
2
|
-
/*
|
3
|
-
Copyright: Boaz Segev, 2017-2018
|
4
|
-
License: MIT
|
5
|
-
*/
|
6
|
-
|
7
|
-
/* *****************************************************************************
|
8
|
-
Simple Linked List - Used for existing objects (not embeddable).
|
9
|
-
***************************************************************************** */
|
10
|
-
|
11
|
-
/**
|
12
|
-
This header includes all the internal rescources / data and types required to
|
13
|
-
create object types.
|
14
|
-
*/
|
15
|
-
#define H_FIO_SIMPLE_LIST_H
|
16
|
-
|
17
|
-
#ifndef _GNU_SOURCE
|
18
|
-
#define _GNU_SOURCE
|
19
|
-
#endif
|
20
|
-
|
21
|
-
#ifndef FIO_FUNC
|
22
|
-
#define FIO_FUNC static __attribute__((unused))
|
23
|
-
#endif
|
24
|
-
|
25
|
-
#include <errno.h>
|
26
|
-
#include <stdio.h>
|
27
|
-
#include <stdlib.h>
|
28
|
-
|
29
|
-
/* *****************************************************************************
|
30
|
-
Data Structure and Initialization.
|
31
|
-
***************************************************************************** */
|
32
|
-
|
33
|
-
/** an embeded linked list. */
|
34
|
-
typedef struct fio_ls_embd_s {
|
35
|
-
struct fio_ls_embd_s *prev;
|
36
|
-
struct fio_ls_embd_s *next;
|
37
|
-
} fio_ls_embd_s;
|
38
|
-
|
39
|
-
/** an independent linked list. */
|
40
|
-
typedef struct fio_ls_s {
|
41
|
-
struct fio_ls_s *prev;
|
42
|
-
struct fio_ls_s *next;
|
43
|
-
const void *obj;
|
44
|
-
} fio_ls_s;
|
45
|
-
|
46
|
-
#define FIO_LS_INIT(name) \
|
47
|
-
{ .next = &(name), .prev = &(name) }
|
48
|
-
|
49
|
-
/* *****************************************************************************
|
50
|
-
Independent List API
|
51
|
-
***************************************************************************** */
|
52
|
-
|
53
|
-
/** Adds an object to the list's head. */
|
54
|
-
FIO_FUNC inline void fio_ls_push(fio_ls_s *pos, const void *obj);
|
55
|
-
|
56
|
-
/** Adds an object to the list's tail. */
|
57
|
-
FIO_FUNC inline void fio_ls_unshift(fio_ls_s *pos, const void *obj);
|
58
|
-
|
59
|
-
/** Removes an object from the list's head. */
|
60
|
-
FIO_FUNC inline void *fio_ls_pop(fio_ls_s *list);
|
61
|
-
|
62
|
-
/** Removes an object from the list's tail. */
|
63
|
-
FIO_FUNC inline void *fio_ls_shift(fio_ls_s *list);
|
64
|
-
|
65
|
-
/** Removes a node from the list, returning the contained object. */
|
66
|
-
FIO_FUNC inline void *fio_ls_remove(fio_ls_s *node);
|
67
|
-
|
68
|
-
/** Tests if the list is empty. */
|
69
|
-
FIO_FUNC inline int fio_ls_is_empty(fio_ls_s *list);
|
70
|
-
|
71
|
-
/** Tests if the list is NOT empty (contains any nodes). */
|
72
|
-
FIO_FUNC inline int fio_ls_any(fio_ls_s *list);
|
73
|
-
|
74
|
-
/**
|
75
|
-
* Iterates through the list using a `for` loop.
|
76
|
-
*
|
77
|
-
* Access the data with `pos->obj` (`pos` can be named however you pleas..
|
78
|
-
*/
|
79
|
-
#define FIO_LS_FOR(list, pos)
|
80
|
-
|
81
|
-
/* *****************************************************************************
|
82
|
-
Embedded List API
|
83
|
-
***************************************************************************** */
|
84
|
-
|
85
|
-
/** Adds a node to the list's head. */
|
86
|
-
FIO_FUNC inline void fio_ls_embd_push(fio_ls_embd_s *dest, fio_ls_embd_s *node);
|
87
|
-
|
88
|
-
/** Adds a node to the list's tail. */
|
89
|
-
FIO_FUNC inline void fio_ls_embd_unshift(fio_ls_embd_s *dest,
|
90
|
-
fio_ls_embd_s *node);
|
91
|
-
|
92
|
-
/** Removes a node from the list's head. */
|
93
|
-
FIO_FUNC inline fio_ls_embd_s *fio_ls_embd_pop(fio_ls_embd_s *list);
|
94
|
-
|
95
|
-
/** Removes a node from the list's tail. */
|
96
|
-
FIO_FUNC inline fio_ls_embd_s *fio_ls_embd_shift(fio_ls_embd_s *list);
|
97
|
-
|
98
|
-
/** Removes a node from the containing node. */
|
99
|
-
FIO_FUNC inline fio_ls_embd_s *fio_ls_embd_remove(fio_ls_embd_s *node);
|
100
|
-
|
101
|
-
/** Tests if the list is empty. */
|
102
|
-
FIO_FUNC inline int fio_ls_embd_is_empty(fio_ls_embd_s *list);
|
103
|
-
|
104
|
-
/** Tests if the list is NOT empty (contains any nodes). */
|
105
|
-
FIO_FUNC inline int fio_ls_embd_any(fio_ls_embd_s *list);
|
106
|
-
|
107
|
-
/**
|
108
|
-
* Iterates through the list using a `for` loop.
|
109
|
-
*
|
110
|
-
* Access the data with `pos->obj` (`pos` can be named however you pleas..
|
111
|
-
*/
|
112
|
-
#define FIO_LS_EMBD_FOR(list, node)
|
113
|
-
|
114
|
-
/**
|
115
|
-
* Takes a list pointer `plist` and returns a pointer to it's container.
|
116
|
-
*
|
117
|
-
* This uses pointer offset calculations and can be used to calculate any
|
118
|
-
* struct's pointer (not just list containers) as an offset from a pointer of
|
119
|
-
* one of it's members.
|
120
|
-
*
|
121
|
-
* Very useful.
|
122
|
-
*/
|
123
|
-
#define FIO_LS_EMBD_OBJ(type, member, plist) \
|
124
|
-
((type *)((uintptr_t)(plist) - (uintptr_t)(&(((type *)0)->member))))
|
125
|
-
|
126
|
-
/* *****************************************************************************
|
127
|
-
Independent Implementation
|
128
|
-
***************************************************************************** */
|
129
|
-
|
130
|
-
/** Adds an object to the list's head. */
|
131
|
-
FIO_FUNC inline void fio_ls_push(fio_ls_s *pos, const void *obj) {
|
132
|
-
/* prepare item */
|
133
|
-
fio_ls_s *item = (fio_ls_s *)malloc(sizeof(*item));
|
134
|
-
if (!item) {
|
135
|
-
perror("ERROR: simple list couldn't allocate memory");
|
136
|
-
exit(errno);
|
137
|
-
}
|
138
|
-
*item = (fio_ls_s){.prev = pos, .next = pos->next, .obj = obj};
|
139
|
-
/* inject item */
|
140
|
-
pos->next->prev = item;
|
141
|
-
pos->next = item;
|
142
|
-
}
|
143
|
-
|
144
|
-
/** Adds an object to the list's tail. */
|
145
|
-
FIO_FUNC inline void fio_ls_unshift(fio_ls_s *pos, const void *obj) {
|
146
|
-
pos = pos->prev;
|
147
|
-
fio_ls_push(pos, obj);
|
148
|
-
}
|
149
|
-
|
150
|
-
/** Removes an object from the list's head. */
|
151
|
-
FIO_FUNC inline void *fio_ls_pop(fio_ls_s *list) {
|
152
|
-
if (list->next == list)
|
153
|
-
return NULL;
|
154
|
-
fio_ls_s *item = list->next;
|
155
|
-
const void *ret = item->obj;
|
156
|
-
list->next = item->next;
|
157
|
-
list->next->prev = list;
|
158
|
-
free(item);
|
159
|
-
return (void *)ret;
|
160
|
-
}
|
161
|
-
|
162
|
-
/** Removes an object from the list's tail. */
|
163
|
-
FIO_FUNC inline void *fio_ls_shift(fio_ls_s *list) {
|
164
|
-
if (list->prev == list)
|
165
|
-
return NULL;
|
166
|
-
fio_ls_s *item = list->prev;
|
167
|
-
const void *ret = item->obj;
|
168
|
-
list->prev = item->prev;
|
169
|
-
list->prev->next = list;
|
170
|
-
free(item);
|
171
|
-
return (void *)ret;
|
172
|
-
}
|
173
|
-
|
174
|
-
/** Removes an object from the containing node. */
|
175
|
-
FIO_FUNC inline void *fio_ls_remove(fio_ls_s *node) {
|
176
|
-
const void *ret = node->obj;
|
177
|
-
node->next->prev = node->prev;
|
178
|
-
node->prev->next = node->next;
|
179
|
-
free(node);
|
180
|
-
return (void *)ret;
|
181
|
-
}
|
182
|
-
|
183
|
-
/** Tests if the list is empty. */
|
184
|
-
FIO_FUNC inline int fio_ls_is_empty(fio_ls_s *list) {
|
185
|
-
return list->next == list;
|
186
|
-
}
|
187
|
-
|
188
|
-
/** Tests if the list is NOT empty (contains any nodes). */
|
189
|
-
FIO_FUNC inline int fio_ls_any(fio_ls_s *list) { return list->next != list; }
|
190
|
-
|
191
|
-
#undef FIO_LS_FOR
|
192
|
-
#define FIO_LS_FOR(list, pos) \
|
193
|
-
for (fio_ls_s *pos = (list)->next; pos != (list); pos = pos->next)
|
194
|
-
|
195
|
-
/* *****************************************************************************
|
196
|
-
Embeded List Implementation
|
197
|
-
***************************************************************************** */
|
198
|
-
|
199
|
-
/** Adds a node to the list's head. */
|
200
|
-
FIO_FUNC inline void fio_ls_embd_push(fio_ls_embd_s *dest,
|
201
|
-
fio_ls_embd_s *node) {
|
202
|
-
node->next = dest->next;
|
203
|
-
node->prev = dest->next->prev;
|
204
|
-
dest->next->prev = node;
|
205
|
-
dest->next = node;
|
206
|
-
}
|
207
|
-
|
208
|
-
/** Adds a node to the list's tail. */
|
209
|
-
FIO_FUNC inline void fio_ls_embd_unshift(fio_ls_embd_s *dest,
|
210
|
-
fio_ls_embd_s *node) {
|
211
|
-
fio_ls_embd_push(dest->prev, node);
|
212
|
-
}
|
213
|
-
|
214
|
-
/** Removes a node from the list's head. */
|
215
|
-
FIO_FUNC inline fio_ls_embd_s *fio_ls_embd_pop(fio_ls_embd_s *list) {
|
216
|
-
if (list->next == list)
|
217
|
-
return NULL;
|
218
|
-
fio_ls_embd_s *item = list->next;
|
219
|
-
list->next = item->next;
|
220
|
-
list->next->prev = list;
|
221
|
-
return item;
|
222
|
-
}
|
223
|
-
|
224
|
-
/** Removes a node from the list's tail. */
|
225
|
-
FIO_FUNC inline fio_ls_embd_s *fio_ls_embd_shift(fio_ls_embd_s *list) {
|
226
|
-
if (list->prev == list)
|
227
|
-
return NULL;
|
228
|
-
fio_ls_embd_s *item = list->prev;
|
229
|
-
list->prev = item->prev;
|
230
|
-
list->prev->next = list;
|
231
|
-
return item;
|
232
|
-
}
|
233
|
-
|
234
|
-
/** Removes a node from the containing node. */
|
235
|
-
FIO_FUNC inline fio_ls_embd_s *fio_ls_embd_remove(fio_ls_embd_s *node) {
|
236
|
-
node->next->prev = node->prev;
|
237
|
-
node->prev->next = node->next;
|
238
|
-
return node;
|
239
|
-
}
|
240
|
-
|
241
|
-
/** Tests if the list is empty. */
|
242
|
-
FIO_FUNC inline int fio_ls_embd_is_empty(fio_ls_embd_s *list) {
|
243
|
-
return list->next == list;
|
244
|
-
}
|
245
|
-
|
246
|
-
/** Tests if the list is NOT empty (contains any nodes). */
|
247
|
-
FIO_FUNC inline int fio_ls_embd_any(fio_ls_embd_s *list) {
|
248
|
-
return list->next != list;
|
249
|
-
}
|
250
|
-
|
251
|
-
#undef FIO_LS_EMBD_FOR
|
252
|
-
#define FIO_LS_EMBD_FOR(list, node) \
|
253
|
-
for (fio_ls_embd_s *node = (list)->next; node != (list); node = node->next)
|
254
|
-
|
255
|
-
#undef FIO_FUNC
|
256
|
-
|
257
|
-
#endif
|