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
@@ -0,0 +1,40 @@
|
|
1
|
+
#ifndef H_FIOBJ_MUSTACHE_H
|
2
|
+
#define H_FIOBJ_MUSTACHE_H
|
3
|
+
|
4
|
+
#include <fiobject.h>
|
5
|
+
|
6
|
+
#include <mustache_parser.h>
|
7
|
+
|
8
|
+
/**
|
9
|
+
* Loads a mustache template, converting it into an opaque instruction array.
|
10
|
+
*
|
11
|
+
* Returns a pointer to the instruction array.
|
12
|
+
*
|
13
|
+
* The `filename` argument should contain the template's file name.
|
14
|
+
*/
|
15
|
+
mustache_s *fiobj_mustache_load(fio_str_info_s filename);
|
16
|
+
|
17
|
+
/** Free the mustache template */
|
18
|
+
void fiobj_mustache_free(mustache_s *mustache);
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Creates a FIOBJ String containing the rendered template using the information
|
22
|
+
* in the `data` object.
|
23
|
+
*
|
24
|
+
* Returns FIOBJ_INVALID if an error occured and a FIOBJ String on success.
|
25
|
+
*/
|
26
|
+
FIOBJ fiobj_mustache_build(mustache_s *mustache, FIOBJ data);
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Renders a template into an existing FIOBJ String (`dest`'s end), using the
|
30
|
+
* information in the `data` object.
|
31
|
+
*
|
32
|
+
* Returns FIOBJ_INVALID if an error occured and a FIOBJ String on success.
|
33
|
+
*/
|
34
|
+
FIOBJ fiobj_mustache_build2(FIOBJ dest, mustache_s *mustache, FIOBJ data);
|
35
|
+
|
36
|
+
#if DEBUG
|
37
|
+
void fiobj_mustache_test(void);
|
38
|
+
#endif
|
39
|
+
|
40
|
+
#endif /* H_FIOBJ_MUSTACHE_H */
|
data/ext/iodine/fiobj_numbers.c
CHANGED
@@ -3,11 +3,11 @@ Copyright: Boaz Segev, 2017-2018
|
|
3
3
|
License: MIT
|
4
4
|
*/
|
5
5
|
|
6
|
-
#include
|
7
|
-
#include
|
6
|
+
#include <fiobj_numbers.h>
|
7
|
+
#include <fiobject.h>
|
8
8
|
|
9
9
|
#define FIO_OVERRIDE_MALLOC 1
|
10
|
-
#include
|
10
|
+
#include <fiobj_mem.h>
|
11
11
|
|
12
12
|
#include <assert.h>
|
13
13
|
#include <errno.h>
|
@@ -46,22 +46,24 @@ static double fio_f2f(const FIOBJ o) { return obj2float(o)->f; }
|
|
46
46
|
static size_t fio_itrue(const FIOBJ o) { return (obj2num(o)->i != 0); }
|
47
47
|
static size_t fio_ftrue(const FIOBJ o) { return (obj2float(o)->f != 0); }
|
48
48
|
|
49
|
-
static
|
50
|
-
return (
|
51
|
-
.
|
49
|
+
static fio_str_info_s fio_i2str(const FIOBJ o) {
|
50
|
+
return (fio_str_info_s){
|
51
|
+
.data = num_buffer,
|
52
|
+
.len = fio_ltoa(num_buffer, obj2num(o)->i, 10),
|
52
53
|
};
|
53
54
|
}
|
54
|
-
static
|
55
|
+
static fio_str_info_s fio_f2str(const FIOBJ o) {
|
55
56
|
if (isnan(obj2float(o)->f))
|
56
|
-
return (
|
57
|
+
return (fio_str_info_s){.data = "NaN", .len = 3};
|
57
58
|
else if (isinf(obj2float(o)->f)) {
|
58
59
|
if (obj2float(o)->f > 0)
|
59
|
-
return (
|
60
|
+
return (fio_str_info_s){.data = "Infinity", .len = 8};
|
60
61
|
else
|
61
|
-
return (
|
62
|
+
return (fio_str_info_s){.data = "-Infinity", .len = 9};
|
62
63
|
}
|
63
|
-
return (
|
64
|
-
.
|
64
|
+
return (fio_str_info_s){
|
65
|
+
.data = num_buffer,
|
66
|
+
.len = fio_ftoa(num_buffer, obj2float(o)->f, 10),
|
65
67
|
};
|
66
68
|
}
|
67
69
|
|
@@ -111,7 +113,8 @@ FIOBJ fiobj_num_new_bignum(intptr_t num) {
|
|
111
113
|
*o = (fiobj_num_s){
|
112
114
|
.head =
|
113
115
|
{
|
114
|
-
.type = FIOBJ_T_NUMBER,
|
116
|
+
.type = FIOBJ_T_NUMBER,
|
117
|
+
.ref = 1,
|
115
118
|
},
|
116
119
|
.i = num,
|
117
120
|
};
|
@@ -128,7 +131,8 @@ FIOBJ fiobj_num_new_bignum(intptr_t num) {
|
|
128
131
|
FIOBJ fiobj_num_tmp(intptr_t num) {
|
129
132
|
static __thread fiobj_num_s ret;
|
130
133
|
ret = (fiobj_num_s){
|
131
|
-
.head = {.type = FIOBJ_T_NUMBER, .ref = ((~(uint32_t)0) >> 4)},
|
134
|
+
.head = {.type = FIOBJ_T_NUMBER, .ref = ((~(uint32_t)0) >> 4)},
|
135
|
+
.i = num,
|
132
136
|
};
|
133
137
|
return (FIOBJ)&ret;
|
134
138
|
}
|
@@ -147,7 +151,8 @@ FIOBJ fiobj_float_new(double num) {
|
|
147
151
|
*o = (fiobj_float_s){
|
148
152
|
.head =
|
149
153
|
{
|
150
|
-
.type = FIOBJ_T_FLOAT,
|
154
|
+
.type = FIOBJ_T_FLOAT,
|
155
|
+
.ref = 1,
|
151
156
|
},
|
152
157
|
.f = num,
|
153
158
|
};
|
@@ -166,7 +171,8 @@ FIOBJ fiobj_float_tmp(double num) {
|
|
166
171
|
ret = (fiobj_float_s){
|
167
172
|
.head =
|
168
173
|
{
|
169
|
-
.type = FIOBJ_T_FLOAT,
|
174
|
+
.type = FIOBJ_T_FLOAT,
|
175
|
+
.ref = ((~(uint32_t)0) >> 4),
|
170
176
|
},
|
171
177
|
.f = num,
|
172
178
|
};
|
@@ -174,26 +180,28 @@ FIOBJ fiobj_float_tmp(double num) {
|
|
174
180
|
}
|
175
181
|
|
176
182
|
/* *****************************************************************************
|
177
|
-
|
183
|
+
Strings to Numbers
|
178
184
|
***************************************************************************** */
|
179
|
-
static const char hex_notation[] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
180
|
-
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
181
185
|
|
182
186
|
/**
|
183
187
|
* A helper function that converts between String data to a signed int64_t.
|
184
188
|
*
|
185
|
-
* Numbers are assumed to be in base 10. `
|
186
|
-
* `b##`) are recognized as
|
187
|
-
*
|
189
|
+
* Numbers are assumed to be in base 10. Octal (`0###`), Hex (`0x##`/`x##`) and
|
190
|
+
* binary (`0b##`/ `b##`) are recognized as well. For binary Most Significant
|
191
|
+
* Bit must come first.
|
192
|
+
*
|
193
|
+
* The most significant differance between this function and `strtol` (aside of
|
194
|
+
* API design), is the added support for binary representations.
|
188
195
|
*/
|
189
|
-
|
190
|
-
|
196
|
+
#pragma weak fio_atol
|
197
|
+
int64_t __attribute__((weak)) fio_atol(char **pstr) {
|
198
|
+
/* No binary representation in strtol */
|
191
199
|
char *str = *pstr;
|
192
|
-
|
200
|
+
uint64_t result = 0;
|
193
201
|
uint8_t invert = 0;
|
194
202
|
while (str[0] == '-') {
|
195
203
|
invert ^= 1;
|
196
|
-
str
|
204
|
+
++str;
|
197
205
|
}
|
198
206
|
if (str[0] == 'B' || str[0] == 'b' ||
|
199
207
|
(str[0] == '0' && (str[1] == 'b' || str[1] == 'B'))) {
|
@@ -212,7 +220,7 @@ intptr_t fio_atol(char **pstr) {
|
|
212
220
|
if (str[0] == '0')
|
213
221
|
str++;
|
214
222
|
str++;
|
215
|
-
|
223
|
+
for (;;) {
|
216
224
|
if (str[0] >= '0' && str[0] <= '9')
|
217
225
|
tmp = str[0] - '0';
|
218
226
|
else if (str[0] >= 'A' && str[0] <= 'F')
|
@@ -224,6 +232,19 @@ intptr_t fio_atol(char **pstr) {
|
|
224
232
|
result = (result << 4) | tmp;
|
225
233
|
str++;
|
226
234
|
}
|
235
|
+
} else if (str[0] == '0') {
|
236
|
+
++str;
|
237
|
+
/* base 8 */
|
238
|
+
const char *end = str;
|
239
|
+
while (end[0] >= '0' && end[0] <= '7' && (uintptr_t)(end - str) < 22)
|
240
|
+
end++;
|
241
|
+
if ((uintptr_t)(end - str) > 21) /* TODO: fix too large for a number */
|
242
|
+
return 0;
|
243
|
+
|
244
|
+
while (str < end) {
|
245
|
+
result = (result * 8) + (str[0] - '0');
|
246
|
+
str++;
|
247
|
+
}
|
227
248
|
} else {
|
228
249
|
/* base 10 */
|
229
250
|
const char *end = str;
|
@@ -241,107 +262,184 @@ finish:
|
|
241
262
|
if (invert)
|
242
263
|
result = 0 - result;
|
243
264
|
*pstr = str;
|
244
|
-
return (
|
265
|
+
return (int64_t)result;
|
245
266
|
}
|
246
267
|
|
247
|
-
/** A helper function that
|
248
|
-
|
268
|
+
/** A helper function that converts between String data to a signed double. */
|
269
|
+
#pragma weak fio_atof
|
270
|
+
double __attribute__((weak)) fio_atof(char **pstr) {
|
271
|
+
return strtold(*pstr, pstr);
|
272
|
+
}
|
249
273
|
|
250
274
|
/* *****************************************************************************
|
251
275
|
Numbers to Strings
|
252
276
|
***************************************************************************** */
|
253
277
|
|
254
278
|
/**
|
255
|
-
* A helper function that
|
279
|
+
* A helper function that writes a signed int64_t to a string.
|
256
280
|
*
|
257
|
-
* No overflow guard is provided, make sure there's at least
|
281
|
+
* No overflow guard is provided, make sure there's at least 68 bytes
|
258
282
|
* available (for base 2).
|
259
283
|
*
|
260
|
-
*
|
261
|
-
*
|
262
|
-
*
|
284
|
+
* Offers special support for base 2 (binary), base 8 (octal), base 10 and base
|
285
|
+
* 16 (hex). An unsupported base will silently default to base 10. Prefixes
|
286
|
+
* are automatically added (i.e., "0x" for hex and "0b" for base 2).
|
263
287
|
*
|
264
288
|
* Returns the number of bytes actually written (excluding the NUL
|
265
289
|
* terminator).
|
266
290
|
*/
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
return 1;
|
272
|
-
}
|
291
|
+
#pragma weak fio_ltoa
|
292
|
+
size_t __attribute__((weak)) fio_ltoa(char *dest, int64_t num, uint8_t base) {
|
293
|
+
const char notation[] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
294
|
+
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
273
295
|
|
274
296
|
size_t len = 0;
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
297
|
+
char buf[48]; /* we only need up to 20 for base 10, but base 3 needs 41... */
|
298
|
+
|
299
|
+
if (!num)
|
300
|
+
goto zero;
|
301
|
+
|
302
|
+
switch (base) {
|
303
|
+
case 1:
|
304
|
+
case 2:
|
305
|
+
/* Base 2 */
|
306
|
+
{
|
307
|
+
uint64_t n = num; /* avoid bit shifting inconsistencies with signed bit */
|
308
|
+
uint8_t i = 0; /* counting bits */
|
286
309
|
dest[len++] = '0';
|
310
|
+
dest[len++] = 'b';
|
311
|
+
|
312
|
+
while ((i < 64) && (n & 0x8000000000000000) == 0) {
|
313
|
+
n = n << 1;
|
314
|
+
i++;
|
315
|
+
}
|
316
|
+
/* make sure the Binary representation doesn't appear signed. */
|
317
|
+
if (i) {
|
318
|
+
dest[len++] = '0';
|
319
|
+
}
|
320
|
+
/* write to dest. */
|
321
|
+
while (i < 64) {
|
322
|
+
dest[len++] = ((n & 0x8000000000000000) ? '1' : '0');
|
323
|
+
n = n << 1;
|
324
|
+
i++;
|
325
|
+
}
|
326
|
+
dest[len] = 0;
|
327
|
+
return len;
|
287
328
|
}
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
329
|
+
case 8:
|
330
|
+
/* Base 8 */
|
331
|
+
{
|
332
|
+
uint64_t l = 0;
|
333
|
+
if (num < 0) {
|
334
|
+
dest[len++] = '-';
|
335
|
+
num = 0 - num;
|
336
|
+
}
|
337
|
+
dest[len++] = '0';
|
296
338
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
339
|
+
while (num) {
|
340
|
+
buf[l++] = '0' + (num & 7);
|
341
|
+
num = num >> 3;
|
342
|
+
}
|
343
|
+
while (l) {
|
344
|
+
--l;
|
345
|
+
dest[len++] = buf[l];
|
346
|
+
}
|
347
|
+
dest[len] = 0;
|
348
|
+
return len;
|
303
349
|
}
|
304
|
-
|
305
|
-
|
306
|
-
|
350
|
+
|
351
|
+
case 16:
|
352
|
+
/* Base 16 */
|
353
|
+
{
|
354
|
+
uint64_t n = num; /* avoid bit shifting inconsistencies with signed bit */
|
355
|
+
uint8_t i = 0; /* counting bits */
|
307
356
|
dest[len++] = '0';
|
357
|
+
dest[len++] = 'x';
|
358
|
+
while (i < 8 && (n & 0xFF00000000000000) == 0) {
|
359
|
+
n = n << 8;
|
360
|
+
i++;
|
361
|
+
}
|
362
|
+
/* make sure the Hex representation doesn't appear signed. */
|
363
|
+
if (i && (n & 0x8000000000000000)) {
|
364
|
+
dest[len++] = '0';
|
365
|
+
dest[len++] = '0';
|
366
|
+
}
|
367
|
+
/* write the damn thing */
|
368
|
+
while (i < 8) {
|
369
|
+
uint8_t tmp = (n & 0xF000000000000000) >> 60;
|
370
|
+
dest[len++] = notation[tmp];
|
371
|
+
tmp = (n & 0x0F00000000000000) >> 56;
|
372
|
+
dest[len++] = notation[tmp];
|
373
|
+
i++;
|
374
|
+
n = n << 8;
|
375
|
+
}
|
376
|
+
dest[len] = 0;
|
377
|
+
return len;
|
378
|
+
}
|
379
|
+
case 3:
|
380
|
+
case 4:
|
381
|
+
case 5:
|
382
|
+
case 6:
|
383
|
+
case 7:
|
384
|
+
case 9:
|
385
|
+
/* rare bases */
|
386
|
+
if (num < 0) {
|
387
|
+
dest[len++] = '-';
|
388
|
+
num = 0 - num;
|
308
389
|
}
|
309
|
-
|
310
|
-
while (
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
390
|
+
uint64_t l = 0;
|
391
|
+
while (num) {
|
392
|
+
uint64_t t = num / base;
|
393
|
+
buf[l++] = '0' + (num - (t * base));
|
394
|
+
num = t;
|
395
|
+
}
|
396
|
+
while (l) {
|
397
|
+
--l;
|
398
|
+
dest[len++] = buf[l];
|
317
399
|
}
|
318
400
|
dest[len] = 0;
|
319
401
|
return len;
|
402
|
+
|
403
|
+
default:
|
404
|
+
break;
|
320
405
|
}
|
406
|
+
/* Base 10, the default base */
|
321
407
|
|
322
|
-
/* fallback to base 10 */
|
323
|
-
uint64_t rem = 0;
|
324
|
-
uint64_t factor = 1;
|
325
408
|
if (num < 0) {
|
326
409
|
dest[len++] = '-';
|
327
410
|
num = 0 - num;
|
328
411
|
}
|
412
|
+
uint64_t l = 0;
|
413
|
+
while (num) {
|
414
|
+
uint64_t t = num / 10;
|
415
|
+
buf[l++] = '0' + (num - (t * 10));
|
416
|
+
num = t;
|
417
|
+
}
|
418
|
+
while (l) {
|
419
|
+
--l;
|
420
|
+
dest[len++] = buf[l];
|
421
|
+
}
|
422
|
+
dest[len] = 0;
|
423
|
+
return len;
|
329
424
|
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
425
|
+
zero:
|
426
|
+
switch (base) {
|
427
|
+
case 1:
|
428
|
+
case 2:
|
429
|
+
dest[len++] = '0';
|
430
|
+
dest[len++] = 'b';
|
431
|
+
case 16:
|
432
|
+
dest[len++] = '0';
|
433
|
+
dest[len++] = 'x';
|
434
|
+
dest[len++] = '0';
|
338
435
|
}
|
436
|
+
dest[len++] = '0';
|
339
437
|
dest[len] = 0;
|
340
438
|
return len;
|
341
439
|
}
|
342
440
|
|
343
441
|
/**
|
344
|
-
* A helper function that
|
442
|
+
* A helper function that converts between a double to a string.
|
345
443
|
*
|
346
444
|
* No overflow guard is provided, make sure there's at least 130 bytes
|
347
445
|
* available (for base 2).
|
@@ -353,7 +451,8 @@ size_t fio_ltoa(char *dest, int64_t num, uint8_t base) {
|
|
353
451
|
* Returns the number of bytes actually written (excluding the NUL
|
354
452
|
* terminator).
|
355
453
|
*/
|
356
|
-
|
454
|
+
#pragma weak fio_ftoa
|
455
|
+
size_t __attribute__((weak)) fio_ftoa(char *dest, double num, uint8_t base) {
|
357
456
|
if (base == 2 || base == 16) {
|
358
457
|
/* handle the binary / Hex representation the same as if it were an
|
359
458
|
* int64_t
|
@@ -381,13 +480,19 @@ size_t fio_ftoa(char *dest, double num, uint8_t base) {
|
|
381
480
|
return written;
|
382
481
|
}
|
383
482
|
|
483
|
+
/* *****************************************************************************
|
484
|
+
Numbers to Strings - Buffered
|
485
|
+
***************************************************************************** */
|
486
|
+
|
384
487
|
static __thread char num_buffer[512];
|
385
488
|
|
386
|
-
|
387
|
-
return (
|
489
|
+
fio_str_info_s fio_ltocstr(long i) {
|
490
|
+
return (fio_str_info_s){.data = num_buffer,
|
491
|
+
.len = fio_ltoa(num_buffer, i, 10)};
|
388
492
|
}
|
389
|
-
|
390
|
-
return (
|
493
|
+
fio_str_info_s fio_ftocstr(double f) {
|
494
|
+
return (fio_str_info_s){.data = num_buffer,
|
495
|
+
.len = fio_ftoa(num_buffer, f, 10)};
|
391
496
|
}
|
392
497
|
|
393
498
|
/* *****************************************************************************
|