iodine 0.4.19 → 0.5.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/.travis.yml +1 -2
- data/CHANGELOG.md +22 -0
- data/LIMITS.md +19 -9
- data/README.md +92 -77
- data/SPEC-PubSub-Draft.md +113 -0
- data/SPEC-Websocket-Draft.md +127 -143
- data/bin/http-hello +0 -1
- data/bin/raw-rbhttp +1 -1
- data/bin/raw_broadcast +8 -10
- data/bin/updated api +2 -2
- data/bin/ws-broadcast +2 -4
- data/bin/ws-echo +2 -2
- data/examples/config.ru +13 -13
- data/examples/echo.ru +5 -6
- data/examples/hello.ru +2 -3
- data/examples/info.md +316 -0
- data/examples/pubsub_engine.ru +81 -0
- data/examples/redis.ru +9 -9
- data/examples/shootout.ru +45 -11
- data/ext/iodine/defer.c +194 -297
- data/ext/iodine/defer.h +61 -53
- data/ext/iodine/evio.c +0 -260
- data/ext/iodine/evio.h +50 -22
- data/ext/iodine/evio_callbacks.c +26 -0
- data/ext/iodine/evio_epoll.c +251 -0
- data/ext/iodine/evio_kqueue.c +193 -0
- data/ext/iodine/extconf.rb +1 -1
- data/ext/iodine/facil.c +1420 -542
- data/ext/iodine/facil.h +151 -64
- data/ext/iodine/fio_ary.h +418 -0
- data/ext/iodine/{base64.c → fio_base64.c} +33 -24
- data/ext/iodine/{base64.h → fio_base64.h} +6 -7
- data/ext/iodine/{fio_cli_helper.c → fio_cli.c} +77 -58
- data/ext/iodine/{fio_cli_helper.h → fio_cli.h} +9 -4
- data/ext/iodine/fio_hashmap.h +759 -0
- data/ext/iodine/fio_json_parser.h +651 -0
- data/ext/iodine/fio_llist.h +257 -0
- data/ext/iodine/fio_mem.c +672 -0
- data/ext/iodine/fio_mem.h +140 -0
- data/ext/iodine/fio_random.c +248 -0
- data/ext/iodine/{random.h → fio_random.h} +11 -14
- data/ext/iodine/{sha1.c → fio_sha1.c} +28 -24
- data/ext/iodine/{sha1.h → fio_sha1.h} +38 -16
- data/ext/iodine/{sha2.c → fio_sha2.c} +66 -49
- data/ext/iodine/{sha2.h → fio_sha2.h} +57 -26
- data/ext/iodine/{fiobj_internal.c → fio_siphash.c} +9 -90
- data/ext/iodine/fio_siphash.h +18 -0
- data/ext/iodine/fio_tmpfile.h +38 -0
- data/ext/iodine/fiobj.h +24 -7
- data/ext/iodine/fiobj4sock.h +23 -0
- data/ext/iodine/fiobj_ary.c +143 -226
- data/ext/iodine/fiobj_ary.h +17 -16
- data/ext/iodine/fiobj_data.c +1160 -0
- data/ext/iodine/fiobj_data.h +164 -0
- data/ext/iodine/fiobj_hash.c +298 -406
- data/ext/iodine/fiobj_hash.h +101 -54
- data/ext/iodine/fiobj_json.c +478 -601
- data/ext/iodine/fiobj_json.h +34 -9
- data/ext/iodine/fiobj_numbers.c +383 -51
- data/ext/iodine/fiobj_numbers.h +87 -11
- data/ext/iodine/fiobj_str.c +423 -184
- data/ext/iodine/fiobj_str.h +81 -32
- data/ext/iodine/fiobject.c +273 -522
- data/ext/iodine/fiobject.h +477 -112
- data/ext/iodine/http.c +2243 -83
- data/ext/iodine/http.h +842 -121
- data/ext/iodine/http1.c +810 -385
- data/ext/iodine/http1.h +16 -39
- data/ext/iodine/http1_parser.c +146 -74
- data/ext/iodine/http1_parser.h +15 -4
- data/ext/iodine/http_internal.c +1258 -0
- data/ext/iodine/http_internal.h +226 -0
- data/ext/iodine/http_mime_parser.h +341 -0
- data/ext/iodine/iodine.c +86 -68
- data/ext/iodine/iodine.h +26 -11
- data/ext/iodine/iodine_helpers.c +8 -7
- data/ext/iodine/iodine_http.c +487 -324
- data/ext/iodine/iodine_json.c +304 -0
- data/ext/iodine/iodine_json.h +6 -0
- data/ext/iodine/iodine_protocol.c +107 -45
- data/ext/iodine/iodine_pubsub.c +526 -225
- data/ext/iodine/iodine_pubsub.h +10 -0
- data/ext/iodine/iodine_websockets.c +268 -510
- data/ext/iodine/iodine_websockets.h +2 -4
- data/ext/iodine/pubsub.c +726 -432
- data/ext/iodine/pubsub.h +85 -103
- data/ext/iodine/rb-call.c +4 -4
- data/ext/iodine/rb-defer.c +46 -22
- data/ext/iodine/rb-fiobj2rb.h +117 -0
- data/ext/iodine/rb-rack-io.c +73 -238
- data/ext/iodine/rb-rack-io.h +2 -2
- data/ext/iodine/rb-registry.c +35 -93
- data/ext/iodine/rb-registry.h +1 -0
- data/ext/iodine/redis_engine.c +742 -304
- data/ext/iodine/redis_engine.h +42 -39
- data/ext/iodine/resp_parser.h +311 -0
- data/ext/iodine/sock.c +627 -490
- data/ext/iodine/sock.h +345 -297
- data/ext/iodine/spnlock.inc +15 -4
- data/ext/iodine/websocket_parser.h +16 -20
- data/ext/iodine/websockets.c +188 -257
- data/ext/iodine/websockets.h +24 -133
- data/lib/iodine.rb +52 -7
- data/lib/iodine/cli.rb +6 -24
- data/lib/iodine/json.rb +40 -0
- data/lib/iodine/version.rb +1 -1
- data/lib/iodine/websocket.rb +5 -3
- data/lib/rack/handler/iodine.rb +58 -13
- metadata +38 -48
- data/bin/ws-shootout +0 -107
- data/examples/broadcast.ru +0 -56
- data/ext/iodine/bscrypt-common.h +0 -116
- data/ext/iodine/bscrypt.h +0 -49
- data/ext/iodine/fio2resp.c +0 -60
- data/ext/iodine/fio2resp.h +0 -51
- data/ext/iodine/fio_dict.c +0 -446
- data/ext/iodine/fio_dict.h +0 -99
- data/ext/iodine/fio_hash_table.h +0 -370
- data/ext/iodine/fio_list.h +0 -111
- data/ext/iodine/fiobj_internal.h +0 -280
- data/ext/iodine/fiobj_primitives.c +0 -131
- data/ext/iodine/fiobj_primitives.h +0 -55
- data/ext/iodine/fiobj_sym.c +0 -135
- data/ext/iodine/fiobj_sym.h +0 -60
- data/ext/iodine/hex.c +0 -124
- data/ext/iodine/hex.h +0 -70
- data/ext/iodine/http1_request.c +0 -81
- data/ext/iodine/http1_request.h +0 -58
- data/ext/iodine/http1_response.c +0 -417
- data/ext/iodine/http1_response.h +0 -95
- data/ext/iodine/http_request.c +0 -111
- data/ext/iodine/http_request.h +0 -102
- data/ext/iodine/http_response.c +0 -1703
- data/ext/iodine/http_response.h +0 -250
- data/ext/iodine/misc.c +0 -182
- data/ext/iodine/misc.h +0 -74
- data/ext/iodine/random.c +0 -208
- data/ext/iodine/redis_connection.c +0 -278
- data/ext/iodine/redis_connection.h +0 -86
- data/ext/iodine/resp.c +0 -842
- data/ext/iodine/resp.h +0 -261
- data/ext/iodine/siphash.c +0 -154
- data/ext/iodine/siphash.h +0 -22
- data/ext/iodine/xor-crypt.c +0 -193
- data/ext/iodine/xor-crypt.h +0 -107
data/ext/iodine/fio_list.h
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
Copyright: Boaz segev, 2016-2017
|
3
|
-
License: MIT
|
4
|
-
|
5
|
-
Feel free to copy, use and enjoy according to the license provided.
|
6
|
-
*/
|
7
|
-
#ifndef H_FACIL_IO_LIST_H
|
8
|
-
/**
|
9
|
-
A simple doubly linked list implementation... Doesn't do much, but does it well.
|
10
|
-
*/
|
11
|
-
#define H_FACIL_IO_LIST_H
|
12
|
-
|
13
|
-
/** The data structure for a doubly linked list. */
|
14
|
-
typedef struct fio_list_s {
|
15
|
-
struct fio_list_s *prev;
|
16
|
-
struct fio_list_s *next;
|
17
|
-
} fio_list_s;
|
18
|
-
|
19
|
-
/** An inline function that initializes a list's head. */
|
20
|
-
static inline __attribute__((unused)) void fio_list_init(fio_list_s *list) {
|
21
|
-
*list = (fio_list_s){.next = list, .prev = list};
|
22
|
-
}
|
23
|
-
|
24
|
-
/** A macro that evaluates to an initialized list head. */
|
25
|
-
#define FIO_LIST_INIT(name) \
|
26
|
-
(fio_list_s) { .next = &(name), .prev = &(name) }
|
27
|
-
/** A macro that evaluates to an initialized list head. */
|
28
|
-
#define FIO_LIST_INIT_STATIC(name) \
|
29
|
-
{ .next = &(name), .prev = &(name) }
|
30
|
-
|
31
|
-
/** Adds a list reference to the list at the specified position. */
|
32
|
-
static inline __attribute__((unused)) void fio_list_add(fio_list_s *pos,
|
33
|
-
fio_list_s *item) {
|
34
|
-
/* prepare item */
|
35
|
-
item->next = pos->next;
|
36
|
-
item->prev = pos;
|
37
|
-
/* inject item only after preperation (in case of misuse or memory tearing) */
|
38
|
-
pos->next = item;
|
39
|
-
item->next->prev = item;
|
40
|
-
}
|
41
|
-
|
42
|
-
/** Removes a list reference from the list. Returns the same reference. */
|
43
|
-
static inline __attribute__((unused)) fio_list_s *
|
44
|
-
fio_list_remove(fio_list_s *item) {
|
45
|
-
item->next->prev = item->prev;
|
46
|
-
item->prev->next = item->next;
|
47
|
-
*item = (fio_list_s){.next = item, .prev = item};
|
48
|
-
return item;
|
49
|
-
}
|
50
|
-
/** Switches two list items. */
|
51
|
-
static inline __attribute__((unused)) void fio_list_switch(fio_list_s *item1,
|
52
|
-
fio_list_s *item2) {
|
53
|
-
if (item1 == item2)
|
54
|
-
return;
|
55
|
-
fio_list_s tmp = *item1;
|
56
|
-
*item1 = *item2;
|
57
|
-
*item2 = tmp;
|
58
|
-
if (item1->next == item2)
|
59
|
-
item1->next = item1;
|
60
|
-
else
|
61
|
-
item1->next->prev = item1;
|
62
|
-
if (item1->prev == item2)
|
63
|
-
item1->prev = item1;
|
64
|
-
else
|
65
|
-
item1->prev->next = item1;
|
66
|
-
}
|
67
|
-
|
68
|
-
#ifndef fio_node2obj
|
69
|
-
/** Takes a node pointer (list/hash/dict, etc') and returns it's container. */
|
70
|
-
#define fio_node2obj(type, member, ptr) \
|
71
|
-
((type *)((uintptr_t)(ptr) - (uintptr_t)(&(((type *)0)->member))))
|
72
|
-
#endif
|
73
|
-
|
74
|
-
/** Takes a list pointer and returns a pointer to it's container. */
|
75
|
-
#define fio_list_object(type, member, plist) fio_node2obj(type, member, (plist))
|
76
|
-
|
77
|
-
/** iterates the whole list. */
|
78
|
-
#define fio_list_for_each(type, member, var, head) \
|
79
|
-
for (fio_list_s *pos = (head).next->next; \
|
80
|
-
(&((var) = fio_list_object(type, member, pos->prev))->member != \
|
81
|
-
&(head)) || \
|
82
|
-
((var) = NULL); \
|
83
|
-
(var) = fio_list_object(type, member, pos), pos = pos->next)
|
84
|
-
|
85
|
-
/** Removes a member from the end of the list. */
|
86
|
-
#define fio_list_pop(type, member, head) \
|
87
|
-
(((head).prev == &(head)) \
|
88
|
-
? ((type *)(0x0)) \
|
89
|
-
: (fio_list_object(type, member, fio_list_remove((head).prev))))
|
90
|
-
|
91
|
-
/** Adds a member to the end of the list. */
|
92
|
-
#define fio_list_push(type, member, head, pitem) \
|
93
|
-
fio_list_add((head).prev, &(pitem)->member)
|
94
|
-
|
95
|
-
/** Removes a member from the beginning of the list. */
|
96
|
-
#define fio_list_shift(type, member, head) \
|
97
|
-
(((head).next == &(head)) \
|
98
|
-
? ((type *)(0x0)) \
|
99
|
-
: (fio_list_object(type, member, fio_list_remove((head).next))))
|
100
|
-
|
101
|
-
/** Adds a member to the beginning of the list. */
|
102
|
-
#define fio_list_unshift(type, member, head, pitem) \
|
103
|
-
fio_list_add((head).next, &(pitem)->member)
|
104
|
-
|
105
|
-
/** Tests if the list is empty. */
|
106
|
-
#define fio_list_is_empty(head) ((head).next == &(head))
|
107
|
-
|
108
|
-
/** Tests if the list is NOT empty. */
|
109
|
-
#define fio_list_any(head) ((head).next != &(head))
|
110
|
-
|
111
|
-
#endif
|
data/ext/iodine/fiobj_internal.h
DELETED
@@ -1,280 +0,0 @@
|
|
1
|
-
#ifndef FIOBJECT_INTERNAL_H
|
2
|
-
/*
|
3
|
-
Copyright: Boaz Segev, 2017
|
4
|
-
License: MIT
|
5
|
-
*/
|
6
|
-
|
7
|
-
/**
|
8
|
-
This header includes all the internal rescources / data and types required to
|
9
|
-
create object types.
|
10
|
-
*/
|
11
|
-
#define FIOBJECT_INTERNAL_H
|
12
|
-
|
13
|
-
#ifndef _GNU_SOURCE
|
14
|
-
#define _GNU_SOURCE
|
15
|
-
#endif
|
16
|
-
|
17
|
-
#include "fiobject.h"
|
18
|
-
|
19
|
-
#include <errno.h>
|
20
|
-
#include <math.h>
|
21
|
-
#include <signal.h>
|
22
|
-
#include <stdarg.h>
|
23
|
-
#include <stdio.h>
|
24
|
-
#include <stdlib.h>
|
25
|
-
#include <string.h>
|
26
|
-
#include <sys/types.h>
|
27
|
-
|
28
|
-
/* *****************************************************************************
|
29
|
-
Atomic add / subtract
|
30
|
-
***************************************************************************** */
|
31
|
-
|
32
|
-
/* C11 Atomics are defined? */
|
33
|
-
#if defined(__ATOMIC_RELAXED)
|
34
|
-
#define SPN_LOCK_BUILTIN(...) __atomic_exchange_n(__VA_ARGS__, __ATOMIC_ACQ_REL)
|
35
|
-
/** An atomic addition operation */
|
36
|
-
#define spn_add(...) __atomic_add_fetch(__VA_ARGS__, __ATOMIC_ACQ_REL)
|
37
|
-
/** An atomic subtraction operation */
|
38
|
-
#define spn_sub(...) __atomic_sub_fetch(__VA_ARGS__, __ATOMIC_ACQ_REL)
|
39
|
-
|
40
|
-
/* Select the correct compiler builtin method. */
|
41
|
-
#elif defined(__has_builtin)
|
42
|
-
|
43
|
-
#if __has_builtin(__sync_fetch_and_or)
|
44
|
-
#define SPN_LOCK_BUILTIN(...) __sync_fetch_and_or(__VA_ARGS__)
|
45
|
-
/** An atomic addition operation */
|
46
|
-
#define spn_add(...) __sync_add_and_fetch(__VA_ARGS__)
|
47
|
-
/** An atomic subtraction operation */
|
48
|
-
#define spn_sub(...) __sync_sub_and_fetch(__VA_ARGS__)
|
49
|
-
|
50
|
-
#else
|
51
|
-
#error Required builtin "__sync_swap" or "__sync_fetch_and_or" missing from compiler.
|
52
|
-
#endif /* defined(__has_builtin) */
|
53
|
-
|
54
|
-
#elif __GNUC__ > 3
|
55
|
-
#define SPN_LOCK_BUILTIN(...) __sync_fetch_and_or(__VA_ARGS__)
|
56
|
-
/** An atomic addition operation */
|
57
|
-
#define spn_add(...) __sync_add_and_fetch(__VA_ARGS__)
|
58
|
-
/** An atomic subtraction operation */
|
59
|
-
#define spn_sub(...) __sync_sub_and_fetch(__VA_ARGS__)
|
60
|
-
|
61
|
-
#else
|
62
|
-
#error Required builtin "__sync_swap" or "__sync_fetch_and_or" not found.
|
63
|
-
#endif
|
64
|
-
|
65
|
-
/* *****************************************************************************
|
66
|
-
Simple List - Used for fiobj_s * objects, but can be used for anything really.
|
67
|
-
***************************************************************************** */
|
68
|
-
|
69
|
-
typedef struct fio_ls_s {
|
70
|
-
struct fio_ls_s *prev;
|
71
|
-
struct fio_ls_s *next;
|
72
|
-
const fiobj_s *obj;
|
73
|
-
} fio_ls_s;
|
74
|
-
|
75
|
-
#define FIO_LS_INIT(name) \
|
76
|
-
{ .next = &(name), .prev = &(name) }
|
77
|
-
|
78
|
-
/** Adds an object to the list's head. */
|
79
|
-
static inline __attribute__((unused)) void fio_ls_push(fio_ls_s *pos,
|
80
|
-
const fiobj_s *obj) {
|
81
|
-
/* prepare item */
|
82
|
-
fio_ls_s *item = (fio_ls_s *)malloc(sizeof(*item));
|
83
|
-
if (!item)
|
84
|
-
perror("ERROR: fiobj list couldn't allocate memory"), exit(errno);
|
85
|
-
*item = (fio_ls_s){.prev = pos, .next = pos->next, .obj = obj};
|
86
|
-
/* inject item */
|
87
|
-
pos->next->prev = item;
|
88
|
-
pos->next = item;
|
89
|
-
}
|
90
|
-
|
91
|
-
/** Adds an object to the list's tail. */
|
92
|
-
static inline __attribute__((unused)) void fio_ls_unshift(fio_ls_s *pos,
|
93
|
-
const fiobj_s *obj) {
|
94
|
-
pos = pos->prev;
|
95
|
-
fio_ls_push(pos, obj);
|
96
|
-
}
|
97
|
-
|
98
|
-
/** Removes an object from the list's head. */
|
99
|
-
static inline __attribute__((unused)) fiobj_s *fio_ls_pop(fio_ls_s *list) {
|
100
|
-
if (list->next == list)
|
101
|
-
return NULL;
|
102
|
-
fio_ls_s *item = list->next;
|
103
|
-
const fiobj_s *ret = item->obj;
|
104
|
-
list->next = item->next;
|
105
|
-
list->next->prev = list;
|
106
|
-
free(item);
|
107
|
-
return (fiobj_s *)ret;
|
108
|
-
}
|
109
|
-
|
110
|
-
/** Removes an object from the list's tail. */
|
111
|
-
static inline __attribute__((unused)) fiobj_s *fio_ls_shift(fio_ls_s *list) {
|
112
|
-
if (list->prev == list)
|
113
|
-
return NULL;
|
114
|
-
fio_ls_s *item = list->prev;
|
115
|
-
const fiobj_s *ret = item->obj;
|
116
|
-
list->prev = item->prev;
|
117
|
-
list->prev->next = list;
|
118
|
-
free(item);
|
119
|
-
return (fiobj_s *)ret;
|
120
|
-
}
|
121
|
-
|
122
|
-
/** Removes an object from the containing node. */
|
123
|
-
static inline __attribute__((unused)) fiobj_s *fio_ls_remove(fio_ls_s *node) {
|
124
|
-
const fiobj_s *ret = node->obj;
|
125
|
-
node->next->prev = node->prev->next;
|
126
|
-
node->prev->next = node->next->prev;
|
127
|
-
free(node);
|
128
|
-
return (fiobj_s *)ret;
|
129
|
-
}
|
130
|
-
|
131
|
-
/* *****************************************************************************
|
132
|
-
Memory Page Size
|
133
|
-
***************************************************************************** */
|
134
|
-
|
135
|
-
#if defined(__unix__) || defined(__APPLE__) || defined(__linux__)
|
136
|
-
#include <unistd.h>
|
137
|
-
|
138
|
-
size_t __attribute__((weak)) fiobj_memory_page_size(void) {
|
139
|
-
static size_t page_size = 0;
|
140
|
-
if (page_size)
|
141
|
-
return page_size;
|
142
|
-
page_size = sysconf(_SC_PAGESIZE);
|
143
|
-
if (!page_size)
|
144
|
-
page_size = 4096;
|
145
|
-
return page_size;
|
146
|
-
}
|
147
|
-
#pragma weak fiobj_memory_page_size
|
148
|
-
|
149
|
-
#else
|
150
|
-
#define fiobj_memory_page_size() 4096
|
151
|
-
|
152
|
-
#endif
|
153
|
-
|
154
|
-
/* *****************************************************************************
|
155
|
-
Type VTable (virtual function table)
|
156
|
-
***************************************************************************** */
|
157
|
-
|
158
|
-
/**
|
159
|
-
* Each type must define a complete virtual function table and point to the
|
160
|
-
* table from it's topmost element in it's `struct`.
|
161
|
-
*/
|
162
|
-
struct fiobj_vtable_s {
|
163
|
-
/** class name as a C string */
|
164
|
-
const char *name;
|
165
|
-
/** deallocate an object - should deallocate parent only
|
166
|
-
*
|
167
|
-
* Note that nested objects, such as contained by Arrays and Hash maps, are
|
168
|
-
* handled using `each1` and handled accoring to their reference count.
|
169
|
-
*/
|
170
|
-
void (*const free)(fiobj_s *);
|
171
|
-
/** object should evaluate as true/false? */
|
172
|
-
int (*const is_true)(const fiobj_s *);
|
173
|
-
/** object value as String */
|
174
|
-
fio_cstr_s (*const to_str)(const fiobj_s *);
|
175
|
-
/** object value as Integer */
|
176
|
-
int64_t (*const to_i)(const fiobj_s *);
|
177
|
-
/** object value as Float */
|
178
|
-
double (*const to_f)(const fiobj_s *);
|
179
|
-
/**
|
180
|
-
* returns 1 if objects are equal, 0 if unequal.
|
181
|
-
*
|
182
|
-
* `self` and `other` are never NULL.
|
183
|
-
*
|
184
|
-
* objects that enumerate (`count > 0`) should only test
|
185
|
-
* themselves (not their children). any nested objects will be tested
|
186
|
-
* seperately.
|
187
|
-
*
|
188
|
-
* wrapping objects should forward the function call to the wrapped objectd
|
189
|
-
* (similar to `count` and `each1`) after completing any internal testing.
|
190
|
-
*/
|
191
|
-
int (*const is_eq)(const fiobj_s *self, const fiobj_s *other);
|
192
|
-
/**
|
193
|
-
* return the number of nested object
|
194
|
-
*
|
195
|
-
* wrapping objects should forward the function call to the wrapped objectd
|
196
|
-
* (similar to `each1`).
|
197
|
-
*/
|
198
|
-
size_t (*const count)(const fiobj_s *o);
|
199
|
-
/**
|
200
|
-
* return either `self` or a wrapped object.
|
201
|
-
* (if object wrapping exists, i.e. Hash couplet, return nested object)
|
202
|
-
*/
|
203
|
-
fiobj_s *(*const unwrap)(const fiobj_s *obj);
|
204
|
-
/**
|
205
|
-
* perform a task for the object's children (-1 stops iteration)
|
206
|
-
* returns the number of items processed + `start_at`.
|
207
|
-
*
|
208
|
-
* wrapping objects should forward the function call to the wrapped objectd
|
209
|
-
* (similar to `count`).
|
210
|
-
*/
|
211
|
-
size_t (*const each1)(fiobj_s *, size_t start_at,
|
212
|
-
int (*task)(fiobj_s *obj, void *arg), void *arg);
|
213
|
-
};
|
214
|
-
|
215
|
-
// extern struct fiobj_vtable_s FIOBJ_VTABLE_INVALID; // unused just yet
|
216
|
-
/* *****************************************************************************
|
217
|
-
VTable (virtual function table) common implememntations
|
218
|
-
***************************************************************************** */
|
219
|
-
|
220
|
-
/** simple deallocation (`free`). */
|
221
|
-
void fiobj_simple_dealloc(fiobj_s *o);
|
222
|
-
/** no deallocation (eternal objects). */
|
223
|
-
void fiobj_noop_free(fiobj_s *obj);
|
224
|
-
/** always true. */
|
225
|
-
int fiobj_noop_true(const fiobj_s *obj);
|
226
|
-
/** always false. */
|
227
|
-
int fiobj_noop_false(const fiobj_s *obj);
|
228
|
-
/** NULL C string. */
|
229
|
-
fio_cstr_s fiobj_noop_str(const fiobj_s *obj);
|
230
|
-
/** always 0. */
|
231
|
-
int64_t fiobj_noop_i(const fiobj_s *obj);
|
232
|
-
/** always 0. */
|
233
|
-
double fiobj_noop_f(const fiobj_s *obj);
|
234
|
-
/** always 0. */
|
235
|
-
size_t fiobj_noop_count(const fiobj_s *obj);
|
236
|
-
/** always 0. */
|
237
|
-
int fiobj_noop_is_eq(const fiobj_s *self, const fiobj_s *other);
|
238
|
-
/** always self. */
|
239
|
-
fiobj_s *fiobj_noop_unwrap(const fiobj_s *obj);
|
240
|
-
/** always 0. */
|
241
|
-
size_t fiobj_noop_each1(fiobj_s *obj, size_t start_at,
|
242
|
-
int (*task)(fiobj_s *obj, void *arg), void *arg);
|
243
|
-
|
244
|
-
/* *****************************************************************************
|
245
|
-
The Object type head and management
|
246
|
-
***************************************************************************** */
|
247
|
-
|
248
|
-
typedef struct { uintptr_t ref; } fiobj_head_s;
|
249
|
-
|
250
|
-
#define OBJ2HEAD(o) (((fiobj_head_s *)(o)) - 1)
|
251
|
-
#define HEAD2OBJ(o) ((fiobj_s *)(((fiobj_head_s *)(o)) + 1))
|
252
|
-
|
253
|
-
#define OBJREF_ADD(o) spn_add(&(OBJ2HEAD((o))->ref), 1)
|
254
|
-
#define OBJREF_REM(o) spn_sub(&(OBJ2HEAD((o))->ref), 1)
|
255
|
-
|
256
|
-
#define OBJVTBL(o) ((struct fiobj_vtable_s *)(((fiobj_s *)(o))->type))
|
257
|
-
|
258
|
-
// #define PTR2OBJ(o) (((o) << 1) | 1)
|
259
|
-
// #define OBJ2PTR(o) (((o)&1) ? ((o) >> 1) : (o))
|
260
|
-
|
261
|
-
/* *****************************************************************************
|
262
|
-
Internal API required across the board
|
263
|
-
***************************************************************************** */
|
264
|
-
|
265
|
-
/** Allocates memory for the fiobj_s's data structure */
|
266
|
-
static inline fiobj_s *fiobj_alloc(size_t size) {
|
267
|
-
fiobj_head_s *head = (fiobj_head_s *)malloc(size + sizeof(head));
|
268
|
-
if (!head)
|
269
|
-
return NULL;
|
270
|
-
*head = (fiobj_head_s){.ref = 1};
|
271
|
-
return HEAD2OBJ(head);
|
272
|
-
};
|
273
|
-
|
274
|
-
/** Deallocates the fiobj_s's data structure. */
|
275
|
-
static inline void fiobj_dealloc(fiobj_s *obj) { free(OBJ2HEAD(obj)); }
|
276
|
-
|
277
|
-
/** The Hashing function used by dynamic facil.io objects. */
|
278
|
-
uint64_t fiobj_sym_hash(const void *data, size_t len);
|
279
|
-
|
280
|
-
#endif
|
@@ -1,131 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
Copyright: Boaz Segev, 2017
|
3
|
-
License: MIT
|
4
|
-
*/
|
5
|
-
|
6
|
-
/**
|
7
|
-
Herein are defined some primitive types for the facil.io dynamic object system.
|
8
|
-
*/
|
9
|
-
#include "fiobj_primitives.h"
|
10
|
-
#include "fiobj_internal.h"
|
11
|
-
|
12
|
-
/* *****************************************************************************
|
13
|
-
NULL
|
14
|
-
***************************************************************************** */
|
15
|
-
|
16
|
-
static int fiobj_primitive_is_eq(const fiobj_s *self, const fiobj_s *other) {
|
17
|
-
return self == other;
|
18
|
-
}
|
19
|
-
|
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 */
|
29
|
-
.to_i = fiobj_noop_i,
|
30
|
-
/* object value as Float */
|
31
|
-
.to_f = fiobj_noop_f,
|
32
|
-
.is_eq = fiobj_primitive_is_eq,
|
33
|
-
/* return the number of nested object */
|
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
|
-
*/
|
40
|
-
.each1 = fiobj_noop_each1,
|
41
|
-
};
|
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 */
|
68
|
-
.to_i = fiobj_noop_i,
|
69
|
-
/* object value as Float */
|
70
|
-
.to_f = fiobj_noop_f,
|
71
|
-
.is_eq = fiobj_primitive_is_eq,
|
72
|
-
/* return the number of nested object */
|
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
|
-
*/
|
79
|
-
.each1 = fiobj_noop_each1,
|
80
|
-
};
|
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
|
-
|
94
|
-
/* *****************************************************************************
|
95
|
-
False
|
96
|
-
***************************************************************************** */
|
97
|
-
|
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
|
-
};
|
120
|
-
|
121
|
-
/** Identifies the FALSE type. */
|
122
|
-
const uintptr_t FIOBJ_T_FALSE = (uintptr_t)(&FALSE_VTABLE);
|
123
|
-
|
124
|
-
/** Returns a FALSE object. */
|
125
|
-
fiobj_s *fiobj_false(void) {
|
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);
|
131
|
-
}
|