iodine 0.4.14 → 0.4.15
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 +61 -33
- data/README.md +7 -5
- data/ext/iodine/base64.c +12 -0
- data/ext/iodine/defer.c +211 -108
- data/ext/iodine/defer.h +7 -0
- data/ext/iodine/facil.c +5 -1
- data/ext/iodine/facil.h +1 -1
- data/ext/iodine/fio2resp.c +19 -30
- data/ext/iodine/fio2resp.h +2 -1
- data/ext/iodine/fio_cli_helper.c +2 -2
- data/ext/iodine/fiobj.h +11 -624
- data/ext/iodine/fiobj_ary.c +65 -26
- data/ext/iodine/fiobj_ary.h +106 -0
- data/ext/iodine/fiobj_hash.c +175 -115
- data/ext/iodine/fiobj_hash.h +128 -0
- data/ext/iodine/fiobj_internal.c +189 -0
- data/ext/iodine/{fiobj_types.h → fiobj_internal.h} +126 -136
- data/ext/iodine/fiobj_json.c +161 -207
- data/ext/iodine/fiobj_json.h +43 -0
- data/ext/iodine/fiobj_numbers.c +53 -35
- data/ext/iodine/fiobj_numbers.h +49 -0
- data/ext/iodine/fiobj_primitives.c +103 -70
- data/ext/iodine/fiobj_primitives.h +55 -0
- data/ext/iodine/fiobj_str.c +171 -59
- data/ext/iodine/fiobj_str.h +113 -0
- data/ext/iodine/fiobj_sym.c +46 -124
- data/ext/iodine/fiobj_sym.h +60 -0
- data/ext/iodine/fiobject.c +589 -0
- data/ext/iodine/fiobject.h +276 -0
- data/ext/iodine/pubsub.h +1 -1
- data/ext/iodine/resp.c +2 -2
- data/ext/iodine/siphash.c +11 -0
- data/ext/iodine/spnlock.inc +7 -5
- data/ext/iodine/websocket_parser.h +44 -7
- data/lib/iodine/version.rb +1 -1
- metadata +13 -8
- data/ext/iodine/fiobj_alloc.c +0 -81
- data/ext/iodine/fiobj_generic.c +0 -260
- data/ext/iodine/fiobj_io.c +0 -58
- data/ext/iodine/fiobj_misc.c +0 -213
- data/ext/iodine/fiobj_tests.c +0 -474
@@ -0,0 +1,43 @@
|
|
1
|
+
#ifndef H_FIOBJ_JSON_H
|
2
|
+
#define H_FIOBJ_JSON_H
|
3
|
+
|
4
|
+
/*
|
5
|
+
Copyright: Boaz Segev, 2017
|
6
|
+
License: MIT
|
7
|
+
*/
|
8
|
+
|
9
|
+
#include "fiobj_ary.h"
|
10
|
+
#include "fiobj_hash.h"
|
11
|
+
#include "fiobj_numbers.h"
|
12
|
+
#include "fiobj_primitives.h"
|
13
|
+
#include "fiobj_str.h"
|
14
|
+
#include "fiobj_sym.h"
|
15
|
+
|
16
|
+
#ifdef __cplusplus
|
17
|
+
extern "C" {
|
18
|
+
#endif
|
19
|
+
|
20
|
+
/* *****************************************************************************
|
21
|
+
JSON API
|
22
|
+
***************************************************************************** */
|
23
|
+
|
24
|
+
/** Limit JSON nesting, we can handle more, but this is mostly for security. */
|
25
|
+
#ifndef JSON_MAX_DEPTH
|
26
|
+
#define JSON_MAX_DEPTH 24
|
27
|
+
#endif
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Parses JSON, setting `pobj` to point to the new Object.
|
31
|
+
*
|
32
|
+
* Returns the number of bytes consumed. On Error, 0 is returned and no data is
|
33
|
+
* consumed.
|
34
|
+
*/
|
35
|
+
size_t fiobj_json2obj(fiobj_s **pobj, const void *data, size_t len);
|
36
|
+
/* Formats an object into a JSON string. Remember to `fiobj_free`. */
|
37
|
+
fiobj_s *fiobj_obj2json(fiobj_s *, uint8_t pretty);
|
38
|
+
|
39
|
+
#ifdef __cplusplus
|
40
|
+
} /* extern "C" */
|
41
|
+
#endif
|
42
|
+
|
43
|
+
#endif
|
data/ext/iodine/fiobj_numbers.c
CHANGED
@@ -1,11 +1,26 @@
|
|
1
1
|
/*
|
2
|
-
Copyright: Boaz
|
2
|
+
Copyright: Boaz Segev, 2017
|
3
3
|
License: MIT
|
4
|
-
|
5
|
-
Feel free to copy, use and enjoy according to the license provided.
|
6
4
|
*/
|
7
5
|
|
8
|
-
#include "
|
6
|
+
#include "fiobj_internal.h"
|
7
|
+
|
8
|
+
/* *****************************************************************************
|
9
|
+
Numbers Type
|
10
|
+
***************************************************************************** */
|
11
|
+
|
12
|
+
typedef struct {
|
13
|
+
struct fiobj_vtable_s *vtable;
|
14
|
+
uint64_t i;
|
15
|
+
} fiobj_num_s;
|
16
|
+
|
17
|
+
typedef struct {
|
18
|
+
struct fiobj_vtable_s *vtable;
|
19
|
+
double f;
|
20
|
+
} fiobj_float_s;
|
21
|
+
|
22
|
+
#define obj2num(o) ((fiobj_num_s *)(o))
|
23
|
+
#define obj2float(o) ((fiobj_float_s *)(o))
|
9
24
|
|
10
25
|
/* *****************************************************************************
|
11
26
|
Numbers VTable
|
@@ -13,19 +28,22 @@ Numbers VTable
|
|
13
28
|
|
14
29
|
static __thread char num_buffer[512];
|
15
30
|
|
16
|
-
static int64_t fio_i2i(fiobj_s *o) { return obj2num(o)->i; }
|
17
|
-
static int64_t fio_f2i(fiobj_s *o) {
|
18
|
-
return (int64_t)floorl((
|
31
|
+
static int64_t fio_i2i(const fiobj_s *o) { return obj2num(o)->i; }
|
32
|
+
static int64_t fio_f2i(const fiobj_s *o) {
|
33
|
+
return (int64_t)floorl(obj2float(o)->f);
|
19
34
|
}
|
20
|
-
static double fio_i2f(fiobj_s *o) { return (double)obj2num(o)->i; }
|
21
|
-
static double fio_f2f(fiobj_s *o) { return obj2float(o)->f; }
|
35
|
+
static double fio_i2f(const fiobj_s *o) { return (double)obj2num(o)->i; }
|
36
|
+
static double fio_f2f(const fiobj_s *o) { return obj2float(o)->f; }
|
37
|
+
|
38
|
+
static int fio_itrue(const fiobj_s *o) { return (obj2num(o)->i != 0); }
|
39
|
+
static int fio_ftrue(const fiobj_s *o) { return (obj2float(o)->f != 0); }
|
22
40
|
|
23
|
-
static fio_cstr_s fio_i2str(fiobj_s *o) {
|
41
|
+
static fio_cstr_s fio_i2str(const fiobj_s *o) {
|
24
42
|
return (fio_cstr_s){
|
25
43
|
.buffer = num_buffer, .len = fio_ltoa(num_buffer, obj2num(o)->i, 10),
|
26
44
|
};
|
27
45
|
}
|
28
|
-
static fio_cstr_s fio_f2str(fiobj_s *o) {
|
46
|
+
static fio_cstr_s fio_f2str(const fiobj_s *o) {
|
29
47
|
if (isnan(obj2float(o)->f))
|
30
48
|
return (fio_cstr_s){.buffer = "NaN", .len = 3};
|
31
49
|
else if (isinf(obj2float(o)->f)) {
|
@@ -39,54 +57,56 @@ static fio_cstr_s fio_f2str(fiobj_s *o) {
|
|
39
57
|
};
|
40
58
|
}
|
41
59
|
|
42
|
-
static int fiobj_i_is_eq(fiobj_s *self, fiobj_s *other) {
|
43
|
-
|
44
|
-
obj2num(self)->i != obj2num(other)->i)
|
45
|
-
return 0;
|
46
|
-
return 1;
|
60
|
+
static int fiobj_i_is_eq(const fiobj_s *self, const fiobj_s *other) {
|
61
|
+
return self->type == other->type && obj2num(self)->i == obj2num(other)->i;
|
47
62
|
}
|
48
|
-
static int fiobj_f_is_eq(fiobj_s *self, fiobj_s *other) {
|
49
|
-
|
50
|
-
obj2float(self)->f != obj2float(other)->f)
|
51
|
-
return 0;
|
52
|
-
return 1;
|
63
|
+
static int fiobj_f_is_eq(const fiobj_s *self, const fiobj_s *other) {
|
64
|
+
return self->type == other->type && obj2float(self)->f == obj2float(other)->f;
|
53
65
|
}
|
54
66
|
|
55
67
|
static struct fiobj_vtable_s FIOBJ_VTABLE_INT = {
|
68
|
+
.name = "Number",
|
56
69
|
.free = fiobj_simple_dealloc,
|
57
70
|
.to_i = fio_i2i,
|
58
71
|
.to_f = fio_i2f,
|
59
72
|
.to_str = fio_i2str,
|
73
|
+
.is_true = fio_itrue,
|
60
74
|
.is_eq = fiobj_i_is_eq,
|
61
75
|
.count = fiobj_noop_count,
|
76
|
+
.unwrap = fiobj_noop_unwrap,
|
62
77
|
.each1 = fiobj_noop_each1,
|
63
78
|
};
|
64
79
|
|
80
|
+
const uintptr_t FIOBJ_T_NUMBER = (uintptr_t)&FIOBJ_VTABLE_INT;
|
81
|
+
|
65
82
|
static struct fiobj_vtable_s FIOBJ_VTABLE_FLOAT = {
|
83
|
+
.name = "Float",
|
66
84
|
.free = fiobj_simple_dealloc,
|
67
85
|
.to_i = fio_f2i,
|
68
86
|
.to_f = fio_f2f,
|
87
|
+
.is_true = fio_ftrue,
|
69
88
|
.to_str = fio_f2str,
|
70
89
|
.is_eq = fiobj_f_is_eq,
|
71
90
|
.count = fiobj_noop_count,
|
91
|
+
.unwrap = fiobj_noop_unwrap,
|
72
92
|
.each1 = fiobj_noop_each1,
|
73
93
|
};
|
74
94
|
|
95
|
+
const uintptr_t FIOBJ_T_FLOAT = (uintptr_t)&FIOBJ_VTABLE_FLOAT;
|
96
|
+
|
75
97
|
/* *****************************************************************************
|
76
98
|
Number API
|
77
99
|
***************************************************************************** */
|
78
100
|
|
79
101
|
/** Creates a Number object. Remember to use `fiobj_free`. */
|
80
102
|
fiobj_s *fiobj_num_new(int64_t num) {
|
81
|
-
|
82
|
-
|
83
|
-
if (!head)
|
103
|
+
fiobj_num_s *o = (fiobj_num_s *)fiobj_alloc(sizeof(*o));
|
104
|
+
if (!o)
|
84
105
|
perror("ERROR: fiobj number couldn't allocate memory"), exit(errno);
|
85
|
-
*
|
86
|
-
.
|
106
|
+
*o = (fiobj_num_s){
|
107
|
+
.vtable = &FIOBJ_VTABLE_INT, .i = num,
|
87
108
|
};
|
88
|
-
|
89
|
-
return HEAD2OBJ(head);
|
109
|
+
return (fiobj_s *)o;
|
90
110
|
}
|
91
111
|
|
92
112
|
/** Mutates a Number object's value. Effects every object's reference! */
|
@@ -98,15 +118,13 @@ Float API
|
|
98
118
|
|
99
119
|
/** Creates a Float object. Remember to use `fiobj_free`. */
|
100
120
|
fiobj_s *fiobj_float_new(double num) {
|
101
|
-
|
102
|
-
|
103
|
-
if (!head)
|
121
|
+
fiobj_float_s *o = (fiobj_float_s *)fiobj_alloc(sizeof(*o));
|
122
|
+
if (!o)
|
104
123
|
perror("ERROR: fiobj float couldn't allocate memory"), exit(errno);
|
105
|
-
*
|
106
|
-
.
|
124
|
+
*o = (fiobj_float_s){
|
125
|
+
.vtable = &FIOBJ_VTABLE_FLOAT, .f = num,
|
107
126
|
};
|
108
|
-
|
109
|
-
return HEAD2OBJ(head);
|
127
|
+
return (fiobj_s *)o;
|
110
128
|
}
|
111
129
|
|
112
130
|
/** Mutates a Float object's value. Effects every object's reference! */
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#ifndef H_FIOBJ_NUMBERS_H
|
2
|
+
#define H_FIOBJ_NUMBERS_H
|
3
|
+
/*
|
4
|
+
Copyright: Boaz Segev, 2017
|
5
|
+
License: MIT
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include "fiobject.h"
|
9
|
+
|
10
|
+
#ifdef __cplusplus
|
11
|
+
extern "C" {
|
12
|
+
#endif
|
13
|
+
|
14
|
+
/* *****************************************************************************
|
15
|
+
Numbers API (Integers)
|
16
|
+
***************************************************************************** */
|
17
|
+
|
18
|
+
extern const uintptr_t FIOBJ_T_NUMBER;
|
19
|
+
|
20
|
+
/** Creates a Number object. Remember to use `fiobj_free`. */
|
21
|
+
fiobj_s *fiobj_num_new(int64_t num);
|
22
|
+
|
23
|
+
/** Mutates a Number object's value. Effects every object's reference! */
|
24
|
+
void fiobj_num_set(fiobj_s *target, int64_t num);
|
25
|
+
|
26
|
+
/* *****************************************************************************
|
27
|
+
Float API (Double)
|
28
|
+
***************************************************************************** */
|
29
|
+
|
30
|
+
extern const uintptr_t FIOBJ_T_FLOAT;
|
31
|
+
|
32
|
+
/** Creates a Float object. Remember to use `fiobj_free`. */
|
33
|
+
fiobj_s *fiobj_float_new(double num);
|
34
|
+
|
35
|
+
/** Mutates a Float object's value. Effects every object's reference! */
|
36
|
+
void fiobj_float_set(fiobj_s *obj, double num);
|
37
|
+
|
38
|
+
/* *****************************************************************************
|
39
|
+
Pointer Wrapping Helper MACROs (uses integers)
|
40
|
+
***************************************************************************** */
|
41
|
+
|
42
|
+
#define fiobj_ptr_wrap(ptr) fiobj_num_new((int64_t)(ptr))
|
43
|
+
#define fiobj_ptr_unwrap(obj) ((void *)fiobj_obj2num((obj)))
|
44
|
+
|
45
|
+
#ifdef __cplusplus
|
46
|
+
} /* extern "C" */
|
47
|
+
#endif
|
48
|
+
|
49
|
+
#endif
|
@@ -1,98 +1,131 @@
|
|
1
1
|
/*
|
2
|
-
Copyright: Boaz
|
2
|
+
Copyright: Boaz Segev, 2017
|
3
3
|
License: MIT
|
4
|
+
*/
|
4
5
|
|
5
|
-
|
6
|
+
/**
|
7
|
+
Herein are defined some primitive types for the facil.io dynamic object system.
|
6
8
|
*/
|
7
|
-
#include "
|
9
|
+
#include "fiobj_primitives.h"
|
10
|
+
#include "fiobj_internal.h"
|
8
11
|
|
9
12
|
/* *****************************************************************************
|
10
|
-
NULL
|
13
|
+
NULL
|
11
14
|
***************************************************************************** */
|
12
15
|
|
13
|
-
static int
|
14
|
-
|
15
|
-
return 0;
|
16
|
-
return 1;
|
16
|
+
static int fiobj_primitive_is_eq(const fiobj_s *self, const fiobj_s *other) {
|
17
|
+
return self == other;
|
17
18
|
}
|
18
19
|
|
19
|
-
static
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
return (fio_cstr_s){.buffer = "null", .len = 4};
|
29
|
-
(void)obj;
|
30
|
-
}
|
31
|
-
static int64_t fio_true2i(fiobj_s *obj) {
|
32
|
-
return 1;
|
33
|
-
(void)obj;
|
34
|
-
}
|
35
|
-
static double fio_true2f(fiobj_s *obj) {
|
36
|
-
return 1;
|
37
|
-
(void)obj;
|
38
|
-
}
|
39
|
-
|
40
|
-
static struct fiobj_vtable_s FIOBJ_VTABLE_NULL = {
|
41
|
-
.free = fiobj_simple_dealloc,
|
20
|
+
static struct fiobj_vtable_s NULL_VTABLE = {
|
21
|
+
.name = "NULL",
|
22
|
+
/* deallocate an object */
|
23
|
+
.free = fiobj_noop_free,
|
24
|
+
/* object should evaluate as true/false? */
|
25
|
+
.is_true = fiobj_noop_false,
|
26
|
+
/* object value as String */
|
27
|
+
.to_str = fiobj_noop_str,
|
28
|
+
/* object value as Integer */
|
42
29
|
.to_i = fiobj_noop_i,
|
30
|
+
/* object value as Float */
|
43
31
|
.to_f = fiobj_noop_f,
|
44
|
-
.
|
45
|
-
|
32
|
+
.is_eq = fiobj_primitive_is_eq,
|
33
|
+
/* return the number of nested object */
|
46
34
|
.count = fiobj_noop_count,
|
35
|
+
/* return a wrapped object (if object wrapping exists, i.e. Hash couplet) */
|
36
|
+
.unwrap = fiobj_noop_unwrap,
|
37
|
+
/* perform a task for the object's children (-1 stops iteration)
|
38
|
+
* returns the number of items processed + `start_at`.
|
39
|
+
*/
|
47
40
|
.each1 = fiobj_noop_each1,
|
48
41
|
};
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
42
|
+
|
43
|
+
/** Identifies the NULL type. */
|
44
|
+
const uintptr_t FIOBJ_T_NULL = (uintptr_t)(&NULL_VTABLE);
|
45
|
+
|
46
|
+
/** Returns a NULL object. */
|
47
|
+
fiobj_s *fiobj_null(void) {
|
48
|
+
static struct {
|
49
|
+
fiobj_head_s head;
|
50
|
+
struct fiobj_vtable_s *vtable;
|
51
|
+
} null_obj = {.head = {.ref = 1}, .vtable = &NULL_VTABLE};
|
52
|
+
return (fiobj_s *)(&null_obj.vtable);
|
53
|
+
}
|
54
|
+
|
55
|
+
/* *****************************************************************************
|
56
|
+
True
|
57
|
+
***************************************************************************** */
|
58
|
+
|
59
|
+
static struct fiobj_vtable_s TRUE_VTABLE = {
|
60
|
+
.name = "True",
|
61
|
+
/* deallocate an object */
|
62
|
+
.free = fiobj_noop_free,
|
63
|
+
/* object should evaluate as true/false? */
|
64
|
+
.is_true = fiobj_noop_true,
|
65
|
+
/* object value as String */
|
66
|
+
.to_str = fiobj_noop_str,
|
67
|
+
/* object value as Integer */
|
60
68
|
.to_i = fiobj_noop_i,
|
69
|
+
/* object value as Float */
|
61
70
|
.to_f = fiobj_noop_f,
|
62
|
-
.
|
63
|
-
|
71
|
+
.is_eq = fiobj_primitive_is_eq,
|
72
|
+
/* return the number of nested object */
|
64
73
|
.count = fiobj_noop_count,
|
74
|
+
/* return a wrapped object (if object wrapping exists, i.e. Hash couplet) */
|
75
|
+
.unwrap = fiobj_noop_unwrap,
|
76
|
+
/* perform a task for the object's children (-1 stops iteration)
|
77
|
+
* returns the number of items processed + `start_at`.
|
78
|
+
*/
|
65
79
|
.each1 = fiobj_noop_each1,
|
66
80
|
};
|
67
81
|
|
82
|
+
/** Identifies the TRUE type. */
|
83
|
+
const uintptr_t FIOBJ_T_TRUE = (uintptr_t)(&TRUE_VTABLE);
|
84
|
+
|
85
|
+
/** Returns a TRUE object. */
|
86
|
+
fiobj_s *fiobj_true(void) {
|
87
|
+
static struct {
|
88
|
+
fiobj_head_s head;
|
89
|
+
struct fiobj_vtable_s *vtable;
|
90
|
+
} obj = {.head = {.ref = 1}, .vtable = &TRUE_VTABLE};
|
91
|
+
return (fiobj_s *)(&obj.vtable);
|
92
|
+
}
|
93
|
+
|
68
94
|
/* *****************************************************************************
|
69
|
-
|
95
|
+
False
|
70
96
|
***************************************************************************** */
|
71
97
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
98
|
+
static struct fiobj_vtable_s FALSE_VTABLE = {
|
99
|
+
.name = "False",
|
100
|
+
/* deallocate an object */
|
101
|
+
.free = fiobj_noop_free,
|
102
|
+
/* object should evaluate as true/false? */
|
103
|
+
.is_true = fiobj_noop_false,
|
104
|
+
/* object value as String */
|
105
|
+
.to_str = fiobj_noop_str,
|
106
|
+
/* object value as Integer */
|
107
|
+
.to_i = fiobj_noop_i,
|
108
|
+
/* object value as Float */
|
109
|
+
.to_f = fiobj_noop_f,
|
110
|
+
.is_eq = fiobj_primitive_is_eq,
|
111
|
+
/* return the number of nested object */
|
112
|
+
.count = fiobj_noop_count,
|
113
|
+
/* return a wrapped object (if object wrapping exists, i.e. Hash couplet) */
|
114
|
+
.unwrap = fiobj_noop_unwrap,
|
115
|
+
/* perform a task for the object's children (-1 stops iteration)
|
116
|
+
* returns the number of items processed + `start_at`.
|
117
|
+
*/
|
118
|
+
.each1 = fiobj_noop_each1,
|
119
|
+
};
|
84
120
|
|
85
|
-
/**
|
86
|
-
|
87
|
-
return fiobj_simple_alloc(FIOBJ_T_NULL, &FIOBJ_VTABLE_NULL);
|
88
|
-
}
|
121
|
+
/** Identifies the FALSE type. */
|
122
|
+
const uintptr_t FIOBJ_T_FALSE = (uintptr_t)(&FALSE_VTABLE);
|
89
123
|
|
90
|
-
/**
|
124
|
+
/** Returns a FALSE object. */
|
91
125
|
fiobj_s *fiobj_false(void) {
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
fiobj_s *
|
97
|
-
return fiobj_simple_alloc(FIOBJ_T_TRUE, &FIOBJ_VTABLE_TRUE);
|
126
|
+
static struct {
|
127
|
+
fiobj_head_s head;
|
128
|
+
struct fiobj_vtable_s *vtable;
|
129
|
+
} obj = {.head = {.ref = 1}, .vtable = &FALSE_VTABLE};
|
130
|
+
return (fiobj_s *)(&obj.vtable);
|
98
131
|
}
|