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_tmpfile.h
CHANGED
data/ext/iodine/fiobj.h
CHANGED
@@ -5,18 +5,20 @@ License: MIT
|
|
5
5
|
#ifndef H_FIOBJ_H
|
6
6
|
#define H_FIOBJ_H
|
7
7
|
|
8
|
-
#include
|
9
|
-
#include
|
10
|
-
#include
|
11
|
-
#include
|
12
|
-
#include
|
13
|
-
#include
|
14
|
-
#include
|
8
|
+
#include <fiobj_ary.h>
|
9
|
+
#include <fiobj_data.h>
|
10
|
+
#include <fiobj_hash.h>
|
11
|
+
#include <fiobj_json.h>
|
12
|
+
#include <fiobj_mustache.h>
|
13
|
+
#include <fiobj_numbers.h>
|
14
|
+
#include <fiobj_str.h>
|
15
|
+
#include <fiobject.h>
|
15
16
|
|
16
|
-
#include
|
17
|
+
#include <fio_siphash.h>
|
17
18
|
|
18
19
|
#if DEBUG
|
19
20
|
FIO_INLINE void fiobj_test(void) {
|
21
|
+
fprintf(stderr, "\n=== FIOBJ Tests ===\n\n");
|
20
22
|
fiobj_test_string();
|
21
23
|
fiobj_test_numbers();
|
22
24
|
fiobj_test_array();
|
@@ -24,6 +26,9 @@ FIO_INLINE void fiobj_test(void) {
|
|
24
26
|
fiobj_test_core();
|
25
27
|
fiobj_data_test();
|
26
28
|
fiobj_test_json();
|
29
|
+
fiobj_mustache_test();
|
30
|
+
fiobj_siphash_test();
|
31
|
+
fprintf(stderr, "=== FIOBJ Done ===\n\n");
|
27
32
|
}
|
28
33
|
#else
|
29
34
|
FIO_INLINE void fiobj_test(void) {
|
data/ext/iodine/fiobj4sock.h
CHANGED
@@ -4,20 +4,18 @@
|
|
4
4
|
* Defines a helper for using fiobj with the sock library.
|
5
5
|
*/
|
6
6
|
|
7
|
-
#include
|
8
|
-
#include
|
7
|
+
#include <fio.h>
|
8
|
+
#include <fiobj.h>
|
9
9
|
|
10
10
|
static void fiobj4sock_dealloc(void *o) { fiobj_free((FIOBJ)o); }
|
11
11
|
|
12
12
|
/** send a FIOBJ object through a socket. */
|
13
13
|
static inline __attribute__((unused)) ssize_t fiobj_send_free(intptr_t uuid,
|
14
14
|
FIOBJ o) {
|
15
|
-
|
16
|
-
return
|
17
|
-
|
18
|
-
|
19
|
-
.dealloc =
|
20
|
-
fiobj4sock_dealloc); // (void (*)(void *))fiobj_free
|
15
|
+
fio_str_info_s s = fiobj_obj2cstr(o);
|
16
|
+
return fio_write2(uuid, .data.buffer = (void *)(o),
|
17
|
+
.offset = (((intptr_t)s.data) - ((intptr_t)(o))),
|
18
|
+
.length = s.len, .after.dealloc = fiobj4sock_dealloc);
|
21
19
|
}
|
22
20
|
|
23
21
|
#endif
|
data/ext/iodine/fiobj_ary.c
CHANGED
@@ -3,12 +3,16 @@ Copyright: Boaz Segev, 2017-2018
|
|
3
3
|
License: MIT
|
4
4
|
*/
|
5
5
|
|
6
|
-
#include
|
6
|
+
#include <fiobject.h>
|
7
7
|
|
8
8
|
#define FIO_OVERRIDE_MALLOC 1
|
9
|
-
#include
|
9
|
+
#include <fiobj_mem.h>
|
10
|
+
|
11
|
+
#define FIO_ARY_TYPE FIOBJ
|
12
|
+
#define FIO_ARY_TYPE_INVALID FIOBJ_INVALID
|
13
|
+
#define FIO_ARY_TYPE_COMPARE(a, b) (fiobj_iseq((a), (b)))
|
14
|
+
#include <fio_ary.h>
|
10
15
|
|
11
|
-
#include "fio_ary.h"
|
12
16
|
#include <assert.h>
|
13
17
|
|
14
18
|
#ifndef FIOBJ_ARRAY_DEFAULT_CAPA
|
@@ -34,15 +38,14 @@ VTable
|
|
34
38
|
***************************************************************************** */
|
35
39
|
|
36
40
|
static void fiobj_ary_dealloc(FIOBJ o, void (*task)(FIOBJ, void *), void *arg) {
|
37
|
-
FIO_ARY_FOR(&obj2ary(o)->ary, i) { task(
|
41
|
+
FIO_ARY_FOR(&obj2ary(o)->ary, i) { task(i.obj, arg); }
|
38
42
|
fio_ary_free(&obj2ary(o)->ary);
|
39
43
|
free(FIOBJ2PTR(o));
|
40
44
|
}
|
41
45
|
|
42
46
|
static size_t fiobj_ary_each1(FIOBJ o, size_t start_at,
|
43
47
|
int (*task)(FIOBJ obj, void *arg), void *arg) {
|
44
|
-
return fio_ary_each(&obj2ary(o)->ary, start_at,
|
45
|
-
arg);
|
48
|
+
return fio_ary_each(&obj2ary(o)->ary, start_at, task, arg);
|
46
49
|
}
|
47
50
|
|
48
51
|
static size_t fiobj_ary_is_eq(const FIOBJ self, const FIOBJ other) {
|
@@ -63,7 +66,7 @@ static size_t fiobj_ary_is_true(const FIOBJ ary) {
|
|
63
66
|
return fiobj_ary_count(ary) > 0;
|
64
67
|
}
|
65
68
|
|
66
|
-
|
69
|
+
fio_str_info_s fiobject___noop_to_str(const FIOBJ o);
|
67
70
|
intptr_t fiobject___noop_to_i(const FIOBJ o);
|
68
71
|
double fiobject___noop_to_f(const FIOBJ o);
|
69
72
|
|
@@ -92,7 +95,8 @@ static FIOBJ fiobj_ary_alloc(size_t capa, size_t start_at) {
|
|
92
95
|
*ary = (fiobj_ary_s){
|
93
96
|
.head =
|
94
97
|
{
|
95
|
-
.ref = 1,
|
98
|
+
.ref = 1,
|
99
|
+
.type = FIOBJ_T_ARRAY,
|
96
100
|
},
|
97
101
|
};
|
98
102
|
fio_ary_new(&ary->ary, capa);
|
@@ -118,7 +122,7 @@ size_t fiobj_ary_capa(FIOBJ ary) {
|
|
118
122
|
}
|
119
123
|
|
120
124
|
/**
|
121
|
-
* Returns a TEMPORARY pointer to the
|
125
|
+
* Returns a TEMPORARY pointer to the beginning of the array.
|
122
126
|
*
|
123
127
|
* This pointer can be used for sorting and other direct access operations as
|
124
128
|
* long as no other actions (insertion/deletion) are performed on the array.
|
@@ -131,12 +135,12 @@ FIOBJ *fiobj_ary2ptr(FIOBJ ary) {
|
|
131
135
|
/**
|
132
136
|
* Returns a temporary object owned by the Array.
|
133
137
|
*
|
134
|
-
* Negative values are
|
138
|
+
* Negative values are retrieved from the end of the array. i.e., `-1`
|
135
139
|
* is the last item.
|
136
140
|
*/
|
137
141
|
FIOBJ fiobj_ary_index(FIOBJ ary, int64_t pos) {
|
138
142
|
assert(ary && FIOBJ_TYPE_IS(ary, FIOBJ_T_ARRAY));
|
139
|
-
return
|
143
|
+
return fio_ary_index(&obj2ary(ary)->ary, pos);
|
140
144
|
}
|
141
145
|
|
142
146
|
/**
|
@@ -144,7 +148,7 @@ FIOBJ fiobj_ary_index(FIOBJ ary, int64_t pos) {
|
|
144
148
|
*/
|
145
149
|
void fiobj_ary_set(FIOBJ ary, FIOBJ obj, int64_t pos) {
|
146
150
|
assert(ary && FIOBJ_TYPE_IS(ary, FIOBJ_T_ARRAY));
|
147
|
-
FIOBJ old =
|
151
|
+
FIOBJ old = fio_ary_set(&obj2ary(ary)->ary, obj, pos);
|
148
152
|
fiobj_free(old);
|
149
153
|
}
|
150
154
|
|
@@ -157,28 +161,84 @@ Array push / shift API
|
|
157
161
|
*/
|
158
162
|
void fiobj_ary_push(FIOBJ ary, FIOBJ obj) {
|
159
163
|
assert(ary && FIOBJ_TYPE_IS(ary, FIOBJ_T_ARRAY));
|
160
|
-
fio_ary_push(&obj2ary(ary)->ary,
|
164
|
+
fio_ary_push(&obj2ary(ary)->ary, obj);
|
161
165
|
}
|
162
166
|
|
163
167
|
/** Pops an object from the end of the Array. */
|
164
168
|
FIOBJ fiobj_ary_pop(FIOBJ ary) {
|
165
169
|
assert(ary && FIOBJ_TYPE_IS(ary, FIOBJ_T_ARRAY));
|
166
|
-
return
|
170
|
+
return fio_ary_pop(&obj2ary(ary)->ary);
|
167
171
|
}
|
168
172
|
|
169
173
|
/**
|
170
|
-
* Unshifts an object to the
|
174
|
+
* Unshifts an object to the beginning of the Array. This could be
|
171
175
|
* expensive.
|
172
176
|
*/
|
173
177
|
void fiobj_ary_unshift(FIOBJ ary, FIOBJ obj) {
|
174
178
|
assert(ary && FIOBJ_TYPE_IS(ary, FIOBJ_T_ARRAY));
|
175
|
-
fio_ary_unshift(&obj2ary(ary)->ary,
|
179
|
+
fio_ary_unshift(&obj2ary(ary)->ary, obj);
|
176
180
|
}
|
177
181
|
|
178
182
|
/** Shifts an object from the beginning of the Array. */
|
179
183
|
FIOBJ fiobj_ary_shift(FIOBJ ary) {
|
180
184
|
assert(ary && FIOBJ_TYPE_IS(ary, FIOBJ_T_ARRAY));
|
181
|
-
return
|
185
|
+
return fio_ary_shift(&obj2ary(ary)->ary);
|
186
|
+
}
|
187
|
+
|
188
|
+
/* *****************************************************************************
|
189
|
+
Array Find / Remove / Replace
|
190
|
+
***************************************************************************** */
|
191
|
+
|
192
|
+
/**
|
193
|
+
* Replaces the object at a specific position, returning the old object -
|
194
|
+
* remember to `fiobj_free` the old object.
|
195
|
+
*/
|
196
|
+
FIOBJ fiobj_ary_replace(FIOBJ ary, FIOBJ obj, int64_t pos) {
|
197
|
+
assert(ary && FIOBJ_TYPE_IS(ary, FIOBJ_T_ARRAY));
|
198
|
+
FIOBJ old = fiobj_ary_index(ary, pos);
|
199
|
+
fiobj_ary_set(ary, obj, pos);
|
200
|
+
return old;
|
201
|
+
}
|
202
|
+
|
203
|
+
/**
|
204
|
+
* Finds the index of a specifide object (if any). Returns -1 if the object
|
205
|
+
* isn't found.
|
206
|
+
*/
|
207
|
+
int64_t fiobj_ary_find(FIOBJ ary, FIOBJ data) {
|
208
|
+
assert(ary && FIOBJ_TYPE_IS(ary, FIOBJ_T_ARRAY));
|
209
|
+
return (int64_t)fio_ary_find(&obj2ary(ary)->ary, data);
|
210
|
+
}
|
211
|
+
|
212
|
+
/**
|
213
|
+
* Removes the object at the index (if valid), changing the index of any
|
214
|
+
* following objects.
|
215
|
+
*
|
216
|
+
* Returns 0 on success or -1 (if no object or out of bounds).
|
217
|
+
*/
|
218
|
+
int fiobj_ary_remove(FIOBJ ary, int64_t pos) {
|
219
|
+
assert(ary && FIOBJ_TYPE_IS(ary, FIOBJ_T_ARRAY));
|
220
|
+
FIOBJ old = fio_ary_remove(&obj2ary(ary)->ary, (intptr_t)pos);
|
221
|
+
if (!old) {
|
222
|
+
return -1;
|
223
|
+
}
|
224
|
+
fiobj_free(old);
|
225
|
+
return 0;
|
226
|
+
}
|
227
|
+
|
228
|
+
/**
|
229
|
+
* Removes the first instance of an object from the Array (if any), changing the
|
230
|
+
* index of any following objects.
|
231
|
+
*
|
232
|
+
* Returns 0 on success or -1 (if the object wasn't found).
|
233
|
+
*/
|
234
|
+
int fiobj_ary_remove2(FIOBJ ary, FIOBJ data) {
|
235
|
+
assert(ary && FIOBJ_TYPE_IS(ary, FIOBJ_T_ARRAY));
|
236
|
+
int found = fio_ary_remove2(&obj2ary(ary)->ary, data);
|
237
|
+
if (found == -1) {
|
238
|
+
return -1;
|
239
|
+
}
|
240
|
+
fiobj_free(data);
|
241
|
+
return 0;
|
182
242
|
}
|
183
243
|
|
184
244
|
/* *****************************************************************************
|
@@ -240,6 +300,36 @@ void fiobj_test_array(void) {
|
|
240
300
|
fiobj_ary_unshift(a, fiobj_false());
|
241
301
|
TEST_ASSERT(fiobj_ary_count(a) == 5, "Array unshift error\n");
|
242
302
|
TEST_ASSERT(fiobj_ary_shift(a) == fiobj_false(), "Array shift value error\n");
|
303
|
+
TEST_ASSERT(fiobj_ary_replace(a, fiobj_true(), -2) == fiobj_false(),
|
304
|
+
"Array replace didn't return correct value\n");
|
305
|
+
|
306
|
+
FIO_ARY_FOR(&obj2ary(a)->ary, pos) {
|
307
|
+
if (pos.obj) {
|
308
|
+
fprintf(stderr, "%lu) %s\n", pos.i, fiobj_obj2cstr(pos.obj).data);
|
309
|
+
}
|
310
|
+
}
|
311
|
+
|
312
|
+
TEST_ASSERT(fiobj_ary_index(a, -2) == fiobj_true(),
|
313
|
+
"Array index retrival error for index -2 (should be true)\n");
|
314
|
+
TEST_ASSERT(fiobj_ary_count(a) == 4, "Array size error\n");
|
315
|
+
fiobj_ary_remove(a, -2);
|
316
|
+
TEST_ASSERT(fiobj_ary_count(a) == 3, "Array remove error\n");
|
317
|
+
|
318
|
+
FIO_ARY_FOR(&obj2ary(a)->ary, pos) {
|
319
|
+
if (pos.obj) {
|
320
|
+
fprintf(stderr, "%lu) %s\n", pos.i, fiobj_obj2cstr(pos.obj).data);
|
321
|
+
}
|
322
|
+
}
|
323
|
+
|
324
|
+
fiobj_ary_remove2(a, fiobj_true());
|
325
|
+
TEST_ASSERT(fiobj_ary_count(a) == 2, "Array remove2 error\n");
|
326
|
+
TEST_ASSERT(fiobj_ary_index(a, 0) == fiobj_null(),
|
327
|
+
"Array index 0 should be null - %s\n",
|
328
|
+
fiobj_obj2cstr(fiobj_ary_index(a, 0)).data);
|
329
|
+
TEST_ASSERT(fiobj_ary_index(a, 1) == fiobj_true(),
|
330
|
+
"Array index 0 should be true - %s\n",
|
331
|
+
fiobj_obj2cstr(fiobj_ary_index(a, 0)).data);
|
332
|
+
|
243
333
|
fiobj_free(a);
|
244
334
|
fprintf(stderr, "* passed.\n");
|
245
335
|
}
|
data/ext/iodine/fiobj_ary.h
CHANGED
@@ -9,7 +9,7 @@ A dynamic Array type for the fiobj_s dynamic type system.
|
|
9
9
|
*/
|
10
10
|
#define FIOBJ_ARRAY_H
|
11
11
|
|
12
|
-
#include
|
12
|
+
#include <fiobject.h>
|
13
13
|
|
14
14
|
#ifdef __cplusplus
|
15
15
|
extern "C" {
|
@@ -36,7 +36,7 @@ size_t fiobj_ary_count(FIOBJ ary);
|
|
36
36
|
size_t fiobj_ary_capa(FIOBJ ary);
|
37
37
|
|
38
38
|
/**
|
39
|
-
* Returns a TEMPORARY pointer to the
|
39
|
+
* Returns a TEMPORARY pointer to the beginning of the array.
|
40
40
|
*
|
41
41
|
* This pointer can be used for sorting and other direct access operations as
|
42
42
|
* long as no other actions (insertion/deletion) are performed on the array.
|
@@ -50,7 +50,7 @@ FIOBJ *fiobj_ary2ptr(FIOBJ ary);
|
|
50
50
|
*
|
51
51
|
* fiobj_dup(fiobj_ary_index(array, 0));
|
52
52
|
*
|
53
|
-
* Negative values are
|
53
|
+
* Negative values are retrieved from the end of the array. i.e., `-1`
|
54
54
|
* is the last item.
|
55
55
|
*/
|
56
56
|
FIOBJ fiobj_ary_index(FIOBJ ary, int64_t pos);
|
@@ -75,7 +75,7 @@ void fiobj_ary_push(FIOBJ ary, FIOBJ obj);
|
|
75
75
|
FIOBJ fiobj_ary_pop(FIOBJ ary);
|
76
76
|
|
77
77
|
/**
|
78
|
-
* Unshifts an object to the
|
78
|
+
* Unshifts an object to the beginning of the Array. This could be
|
79
79
|
* expensive.
|
80
80
|
*/
|
81
81
|
void fiobj_ary_unshift(FIOBJ ary, FIOBJ obj);
|
@@ -83,6 +83,38 @@ void fiobj_ary_unshift(FIOBJ ary, FIOBJ obj);
|
|
83
83
|
/** Shifts an object from the beginning of the Array. */
|
84
84
|
FIOBJ fiobj_ary_shift(FIOBJ ary);
|
85
85
|
|
86
|
+
/* *****************************************************************************
|
87
|
+
Array Find / Remove / Replace
|
88
|
+
***************************************************************************** */
|
89
|
+
|
90
|
+
/**
|
91
|
+
* Replaces the object at a specific position, returning the old object -
|
92
|
+
* remember to `fiobj_free` the old object.
|
93
|
+
*/
|
94
|
+
FIOBJ fiobj_ary_replace(FIOBJ ary, FIOBJ obj, int64_t pos);
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Finds the index of a specifide object (if any). Returns -1 if the object
|
98
|
+
* isn't found.
|
99
|
+
*/
|
100
|
+
int64_t fiobj_ary_find(FIOBJ ary, FIOBJ data);
|
101
|
+
|
102
|
+
/**
|
103
|
+
* Removes the object at the index (if valid), changing the index of any
|
104
|
+
* following objects.
|
105
|
+
*
|
106
|
+
* Returns 0 on success or -1 (if no object or out of bounds).
|
107
|
+
*/
|
108
|
+
int fiobj_ary_remove(FIOBJ ary, int64_t pos);
|
109
|
+
|
110
|
+
/**
|
111
|
+
* Removes the first instance of an object from the Array (if any), changing the
|
112
|
+
* index of any following objects.
|
113
|
+
*
|
114
|
+
* Returns 0 on success or -1 (if the object wasn't found).
|
115
|
+
*/
|
116
|
+
int fiobj_ary_remove2(FIOBJ ary, FIOBJ data);
|
117
|
+
|
86
118
|
/* *****************************************************************************
|
87
119
|
Array compacting (untested)
|
88
120
|
***************************************************************************** */
|
data/ext/iodine/fiobj_data.c
CHANGED
@@ -17,9 +17,9 @@ License: MIT
|
|
17
17
|
* Writing is always performed at the end of the stream / memory buffer,
|
18
18
|
* ignoring the current seek position.
|
19
19
|
*/
|
20
|
-
#include
|
21
|
-
#include
|
22
|
-
#include
|
20
|
+
#include <fio_tmpfile.h>
|
21
|
+
#include <fiobj_data.h>
|
22
|
+
#include <fiobj_str.h>
|
23
23
|
|
24
24
|
#include <assert.h>
|
25
25
|
#include <errno.h>
|
@@ -30,7 +30,7 @@ License: MIT
|
|
30
30
|
#include <unistd.h>
|
31
31
|
|
32
32
|
#define FIO_OVERRIDE_MALLOC 1
|
33
|
-
#include
|
33
|
+
#include <fiobj_mem.h>
|
34
34
|
|
35
35
|
/* *****************************************************************************
|
36
36
|
Numbers Type
|
@@ -43,7 +43,7 @@ typedef struct {
|
|
43
43
|
FIOBJ parent;
|
44
44
|
void (*dealloc)(void *); /* buffer deallocation function */
|
45
45
|
size_t fpos; /* the file reader's position */
|
46
|
-
};
|
46
|
+
} source;
|
47
47
|
size_t capa; /* total buffer capacity / slice offset */
|
48
48
|
size_t len; /* length of valid data in buffer */
|
49
49
|
size_t pos; /* position of reader */
|
@@ -69,23 +69,24 @@ static void fiobj_data_copy_buffer(FIOBJ o) {
|
|
69
69
|
void *tmp = malloc(obj2io(o)->capa);
|
70
70
|
REQUIRE_MEM(tmp);
|
71
71
|
memcpy(tmp, obj2io(o)->buffer, obj2io(o)->len);
|
72
|
-
if (obj2io(o)->dealloc)
|
73
|
-
obj2io(o)->dealloc(obj2io(o)->buffer);
|
74
|
-
obj2io(o)->dealloc = free;
|
72
|
+
if (obj2io(o)->source.dealloc)
|
73
|
+
obj2io(o)->source.dealloc(obj2io(o)->buffer);
|
74
|
+
obj2io(o)->source.dealloc = free;
|
75
75
|
obj2io(o)->buffer = tmp;
|
76
76
|
}
|
77
77
|
|
78
78
|
static void fiobj_data_copy_parent(FIOBJ o) {
|
79
|
-
switch (obj2io(obj2io(o)->parent)->fd) {
|
79
|
+
switch (obj2io(obj2io(o)->source.parent)->fd) {
|
80
80
|
case -1:
|
81
81
|
obj2io(o)->buffer = malloc(obj2io(o)->len + 1);
|
82
82
|
memcpy(obj2io(o)->buffer,
|
83
|
-
obj2io(obj2io(o)->parent)->buffer + obj2io(o)->capa,
|
83
|
+
obj2io(obj2io(o)->source.parent)->buffer + obj2io(o)->capa,
|
84
|
+
obj2io(o)->len);
|
84
85
|
obj2io(o)->buffer[obj2io(o)->len] = 0;
|
85
86
|
obj2io(o)->capa = obj2io(o)->len;
|
86
87
|
obj2io(o)->fd = -1;
|
87
|
-
fiobj_free(obj2io(o)->parent);
|
88
|
-
obj2io(o)->dealloc = free;
|
88
|
+
fiobj_free(obj2io(o)->source.parent);
|
89
|
+
obj2io(o)->source.dealloc = free;
|
89
90
|
return;
|
90
91
|
default:
|
91
92
|
obj2io(o)->fd = fio_tmpfile();
|
@@ -93,15 +94,16 @@ static void fiobj_data_copy_parent(FIOBJ o) {
|
|
93
94
|
perror("FATAL ERROR: (fiobj_data) can't create temporary file");
|
94
95
|
exit(errno);
|
95
96
|
}
|
96
|
-
|
97
|
+
fio_str_info_s data;
|
97
98
|
size_t pos = 0;
|
98
99
|
do {
|
99
100
|
ssize_t written;
|
100
|
-
data = fiobj_data_pread(obj2io(o)->parent, pos + obj2io(o)->capa,
|
101
|
+
data = fiobj_data_pread(obj2io(o)->source.parent, pos + obj2io(o)->capa,
|
102
|
+
4096);
|
101
103
|
if (data.len + pos > obj2io(o)->len)
|
102
104
|
data.len = obj2io(o)->len - pos;
|
103
105
|
retry_int:
|
104
|
-
written = write(obj2io(o)->fd, data.
|
106
|
+
written = write(obj2io(o)->fd, data.data, data.len);
|
105
107
|
if (written < 0) {
|
106
108
|
if (errno == EINTR)
|
107
109
|
goto retry_int;
|
@@ -110,10 +112,10 @@ static void fiobj_data_copy_parent(FIOBJ o) {
|
|
110
112
|
}
|
111
113
|
pos += written;
|
112
114
|
} while (data.len == 4096);
|
113
|
-
fiobj_free(obj2io(o)->parent);
|
115
|
+
fiobj_free(obj2io(o)->source.parent);
|
114
116
|
obj2io(o)->capa = 0;
|
115
117
|
obj2io(o)->len = pos;
|
116
|
-
obj2io(o)->fpos = obj2io(o)->pos;
|
118
|
+
obj2io(o)->source.fpos = obj2io(o)->pos;
|
117
119
|
obj2io(o)->pos = 0;
|
118
120
|
obj2io(o)->buffer = NULL;
|
119
121
|
break;
|
@@ -123,7 +125,7 @@ static void fiobj_data_copy_parent(FIOBJ o) {
|
|
123
125
|
static inline void fiobj_data_pre_write(FIOBJ o, uintptr_t length) {
|
124
126
|
switch (obj2io(o)->fd) {
|
125
127
|
case -1:
|
126
|
-
if (obj2io(o)->dealloc != free) {
|
128
|
+
if (obj2io(o)->source.dealloc != free) {
|
127
129
|
fiobj_data_copy_buffer(o);
|
128
130
|
}
|
129
131
|
break;
|
@@ -154,7 +156,9 @@ static FIOBJ fiobj_data_alloc(void *buffer, int fd) {
|
|
154
156
|
fiobj_data_s *io = malloc(sizeof(*io));
|
155
157
|
REQUIRE_MEM(io);
|
156
158
|
*io = (fiobj_data_s){
|
157
|
-
.head = {.ref = 1, .type = FIOBJ_T_DATA},
|
159
|
+
.head = {.ref = 1, .type = FIOBJ_T_DATA},
|
160
|
+
.buffer = buffer,
|
161
|
+
.fd = fd,
|
158
162
|
};
|
159
163
|
return (FIOBJ)io;
|
160
164
|
}
|
@@ -163,11 +167,11 @@ static void fiobj_data_dealloc(FIOBJ o, void (*task)(FIOBJ, void *),
|
|
163
167
|
void *arg) {
|
164
168
|
switch (obj2io(o)->fd) {
|
165
169
|
case -1:
|
166
|
-
if (obj2io(o)->dealloc && obj2io(o)->buffer)
|
167
|
-
obj2io(o)->dealloc(obj2io(o)->buffer);
|
170
|
+
if (obj2io(o)->source.dealloc && obj2io(o)->buffer)
|
171
|
+
obj2io(o)->source.dealloc(obj2io(o)->buffer);
|
168
172
|
break;
|
169
173
|
case -2:
|
170
|
-
fiobj_free(obj2io(o)->parent);
|
174
|
+
fiobj_free(obj2io(o)->source.parent);
|
171
175
|
break;
|
172
176
|
default:
|
173
177
|
close(obj2io(o)->fd);
|
@@ -192,32 +196,34 @@ static intptr_t fiobj_data_i(const FIOBJ o) {
|
|
192
196
|
|
193
197
|
static size_t fiobj_data_is_true(const FIOBJ o) { return fiobj_data_i(o) > 0; }
|
194
198
|
|
195
|
-
static
|
199
|
+
static fio_str_info_s fio_io2str(const FIOBJ o) {
|
196
200
|
switch (obj2io(o)->fd) {
|
197
201
|
case -1:
|
198
|
-
return (
|
202
|
+
return (fio_str_info_s){.data = (char *)obj2io(o)->buffer,
|
203
|
+
.len = obj2io(o)->len};
|
199
204
|
break;
|
200
205
|
case -2:
|
201
|
-
return fiobj_data_pread(obj2io(o)->parent, obj2io(o)->capa,
|
206
|
+
return fiobj_data_pread(obj2io(o)->source.parent, obj2io(o)->capa,
|
207
|
+
obj2io(o)->len);
|
202
208
|
break;
|
203
209
|
}
|
204
210
|
int64_t i = fiobj_data_get_fd_size(o);
|
205
211
|
if (i <= 0)
|
206
|
-
return (
|
212
|
+
return (fio_str_info_s){.data = (char *)obj2io(o)->buffer,
|
213
|
+
.len = obj2io(o)->len};
|
207
214
|
obj2io(o)->len = 0;
|
208
215
|
obj2io(o)->pos = 0;
|
209
216
|
fiobj_data_pre_write((FIOBJ)o, i + 1);
|
210
217
|
if (pread(obj2io(o)->fd, obj2io(o)->buffer, i, 0) != i)
|
211
|
-
return (
|
218
|
+
return (fio_str_info_s){.data = NULL, .len = 0};
|
212
219
|
obj2io(o)->buffer[i] = 0;
|
213
|
-
return (
|
220
|
+
return (fio_str_info_s){.data = (char *)obj2io(o)->buffer, .len = i};
|
214
221
|
}
|
215
222
|
|
216
223
|
static size_t fiobj_data_iseq(const FIOBJ self, const FIOBJ other) {
|
217
224
|
int64_t len;
|
218
|
-
return (
|
219
|
-
|
220
|
-
!memcmp(fio_io2str(self).buffer, fio_io2str(other).buffer, (size_t)len));
|
225
|
+
return ((len = fiobj_data_i(self)) == fiobj_data_i(other) &&
|
226
|
+
!memcmp(fio_io2str(self).data, fio_io2str(other).data, (size_t)len));
|
221
227
|
}
|
222
228
|
|
223
229
|
uintptr_t fiobject___noop_count(FIOBJ o);
|
@@ -322,7 +328,7 @@ FIOBJ fiobj_data_newstr(void) {
|
|
322
328
|
FIOBJ o = fiobj_data_alloc(malloc(4096), -1);
|
323
329
|
REQUIRE_MEM(obj2io(o)->buffer);
|
324
330
|
obj2io(o)->capa = 4096;
|
325
|
-
obj2io(o)->dealloc = free;
|
331
|
+
obj2io(o)->source.dealloc = free;
|
326
332
|
return o;
|
327
333
|
}
|
328
334
|
|
@@ -336,7 +342,7 @@ FIOBJ fiobj_data_newstr2(void *buffer, uintptr_t length,
|
|
336
342
|
FIOBJ o = fiobj_data_alloc(buffer, -1);
|
337
343
|
obj2io(o)->capa = length;
|
338
344
|
obj2io(o)->len = length;
|
339
|
-
obj2io(o)->dealloc = dealloc;
|
345
|
+
obj2io(o)->source.dealloc = dealloc;
|
340
346
|
return o;
|
341
347
|
}
|
342
348
|
|
@@ -344,7 +350,7 @@ FIOBJ fiobj_data_newstr2(void *buffer, uintptr_t length,
|
|
344
350
|
FIOBJ fiobj_data_newfd(int fd) {
|
345
351
|
FIOBJ o = fiobj_data_alloc(malloc(4096), fd);
|
346
352
|
REQUIRE_MEM(obj2io(o)->buffer);
|
347
|
-
obj2io(o)->fpos = 0;
|
353
|
+
obj2io(o)->source.fpos = 0;
|
348
354
|
return o;
|
349
355
|
}
|
350
356
|
|
@@ -369,7 +375,7 @@ FIOBJ fiobj_data_slice(FIOBJ parent, intptr_t offset, uintptr_t length) {
|
|
369
375
|
while (obj2io(parent)->fd == -2) {
|
370
376
|
/* don't slice a slice... climb the parent chain. */
|
371
377
|
offset += obj2io(parent)->capa;
|
372
|
-
parent = obj2io(parent)->parent;
|
378
|
+
parent = obj2io(parent)->source.parent;
|
373
379
|
}
|
374
380
|
size_t parent_len = fiobj_data_len(parent);
|
375
381
|
if (parent_len <= (size_t)offset) {
|
@@ -382,7 +388,7 @@ FIOBJ fiobj_data_slice(FIOBJ parent, intptr_t offset, uintptr_t length) {
|
|
382
388
|
FIOBJ o = fiobj_data_alloc(NULL, -2);
|
383
389
|
obj2io(o)->capa = offset;
|
384
390
|
obj2io(o)->len = length;
|
385
|
-
obj2io(o)->parent = fiobj_dup(parent);
|
391
|
+
obj2io(o)->source.parent = fiobj_dup(parent);
|
386
392
|
return o;
|
387
393
|
}
|
388
394
|
|
@@ -442,10 +448,11 @@ static int fiobj_data_save_slice(FIOBJ o, const char *filename) {
|
|
442
448
|
if (target == -1)
|
443
449
|
return -1;
|
444
450
|
errno = 0;
|
445
|
-
|
451
|
+
fio_str_info_s tmp;
|
446
452
|
size_t total = 0;
|
447
453
|
do {
|
448
|
-
tmp = fiobj_data_pread(obj2io(o)->parent, obj2io(o)->capa + total,
|
454
|
+
tmp = fiobj_data_pread(obj2io(o)->source.parent, obj2io(o)->capa + total,
|
455
|
+
4096);
|
449
456
|
if (tmp.len == 0)
|
450
457
|
break;
|
451
458
|
if (total + tmp.len > obj2io(o)->len)
|
@@ -484,10 +491,10 @@ Reading API
|
|
484
491
|
***************************************************************************** */
|
485
492
|
|
486
493
|
/** Reads up to `length` bytes */
|
487
|
-
static
|
494
|
+
static fio_str_info_s fiobj_data_read_str(FIOBJ io, intptr_t length) {
|
488
495
|
if (obj2io(io)->pos == obj2io(io)->len) {
|
489
496
|
/* EOF */
|
490
|
-
return (
|
497
|
+
return (fio_str_info_s){.data = NULL, .len = 0};
|
491
498
|
}
|
492
499
|
|
493
500
|
if (length <= 0) {
|
@@ -497,7 +504,7 @@ static fio_cstr_s fiobj_data_read_str(FIOBJ io, intptr_t length) {
|
|
497
504
|
|
498
505
|
if (length <= 0) {
|
499
506
|
/* We are at EOF - length or beyond */
|
500
|
-
return (
|
507
|
+
return (fio_str_info_s){.data = NULL, .len = 0};
|
501
508
|
}
|
502
509
|
|
503
510
|
/* reading length bytes */
|
@@ -505,16 +512,17 @@ static fio_cstr_s fiobj_data_read_str(FIOBJ io, intptr_t length) {
|
|
505
512
|
obj2io(io)->pos = pos + length;
|
506
513
|
if (obj2io(io)->pos > obj2io(io)->len)
|
507
514
|
obj2io(io)->pos = obj2io(io)->len;
|
508
|
-
return (
|
509
|
-
.
|
515
|
+
return (fio_str_info_s){
|
516
|
+
.data = (char *)(obj2io(io)->buffer + pos),
|
517
|
+
.len = (obj2io(io)->pos - pos),
|
510
518
|
};
|
511
519
|
}
|
512
520
|
|
513
521
|
/** Reads up to `length` bytes */
|
514
|
-
static
|
522
|
+
static fio_str_info_s fiobj_data_read_slice(FIOBJ io, intptr_t length) {
|
515
523
|
if (obj2io(io)->pos == obj2io(io)->len) {
|
516
524
|
/* EOF */
|
517
|
-
return (
|
525
|
+
return (fio_str_info_s){.data = NULL, .len = 0};
|
518
526
|
}
|
519
527
|
if (length <= 0) {
|
520
528
|
/* read to EOF - length */
|
@@ -523,39 +531,40 @@ static fio_cstr_s fiobj_data_read_slice(FIOBJ io, intptr_t length) {
|
|
523
531
|
|
524
532
|
if (length <= 0) {
|
525
533
|
/* We are at EOF - length or beyond */
|
526
|
-
return (
|
534
|
+
return (fio_str_info_s){.data = NULL, .len = 0};
|
527
535
|
}
|
528
536
|
register size_t pos = obj2io(io)->pos;
|
529
537
|
obj2io(io)->pos = pos + length;
|
530
538
|
if (obj2io(io)->pos > obj2io(io)->len)
|
531
539
|
obj2io(io)->pos = obj2io(io)->len;
|
532
|
-
return fiobj_data_pread(obj2io(io)->parent, pos + obj2io(io)->capa,
|
540
|
+
return fiobj_data_pread(obj2io(io)->source.parent, pos + obj2io(io)->capa,
|
533
541
|
(obj2io(io)->pos - pos));
|
534
542
|
}
|
535
543
|
|
536
544
|
/** Reads up to `length` bytes */
|
537
|
-
static
|
545
|
+
static fio_str_info_s fiobj_data_read_file(FIOBJ io, intptr_t length) {
|
538
546
|
uintptr_t fsize = fiobj_data_get_fd_size(io);
|
539
547
|
|
540
548
|
if (length <= 0) {
|
541
549
|
/* read to EOF - length */
|
542
|
-
length = (fsize - obj2io(io)->fpos) + length;
|
550
|
+
length = (fsize - obj2io(io)->source.fpos) + length;
|
543
551
|
}
|
544
552
|
|
545
553
|
if (length <= 0) {
|
546
554
|
/* We are at EOF - length or beyond */
|
547
555
|
errno = 0;
|
548
|
-
return (
|
556
|
+
return (fio_str_info_s){.data = NULL, .len = 0};
|
549
557
|
}
|
550
558
|
|
551
559
|
/* reading length bytes */
|
552
560
|
if (length + obj2io(io)->pos <= obj2io(io)->len) {
|
553
561
|
/* the data already exists in the buffer */
|
554
562
|
// fprintf(stderr, "in_buffer...\n");
|
555
|
-
|
556
|
-
|
563
|
+
fio_str_info_s data = {.data =
|
564
|
+
(char *)(obj2io(io)->buffer + obj2io(io)->pos),
|
565
|
+
.len = (uintptr_t)length};
|
557
566
|
obj2io(io)->pos += length;
|
558
|
-
obj2io(io)->fpos += length;
|
567
|
+
obj2io(io)->source.fpos += length;
|
559
568
|
return data;
|
560
569
|
} else {
|
561
570
|
/* read the data into the buffer - internal counting gets invalidated */
|
@@ -565,13 +574,14 @@ static fio_cstr_s fiobj_data_read_file(FIOBJ io, intptr_t length) {
|
|
565
574
|
fiobj_data_pre_write(io, length);
|
566
575
|
ssize_t l;
|
567
576
|
retry_int:
|
568
|
-
l = pread(obj2io(io)->fd, obj2io(io)->buffer, length,
|
577
|
+
l = pread(obj2io(io)->fd, obj2io(io)->buffer, length,
|
578
|
+
obj2io(io)->source.fpos);
|
569
579
|
if (l == -1 && errno == EINTR)
|
570
580
|
goto retry_int;
|
571
581
|
if (l == -1 || l == 0)
|
572
|
-
return (
|
573
|
-
obj2io(io)->fpos += l;
|
574
|
-
return (
|
582
|
+
return (fio_str_info_s){.data = NULL, .len = 0};
|
583
|
+
obj2io(io)->source.fpos += l;
|
584
|
+
return (fio_str_info_s){.data = (char *)obj2io(io)->buffer, .len = l};
|
575
585
|
}
|
576
586
|
}
|
577
587
|
|
@@ -581,10 +591,10 @@ static fio_cstr_s fiobj_data_read_file(FIOBJ io, intptr_t length) {
|
|
581
591
|
* The C string object will be invalidate the next time a function call to the
|
582
592
|
* IO object is made.
|
583
593
|
*/
|
584
|
-
|
594
|
+
fio_str_info_s fiobj_data_read(FIOBJ io, intptr_t length) {
|
585
595
|
if (!io || !FIOBJ_TYPE_IS(io, FIOBJ_T_DATA)) {
|
586
596
|
errno = EFAULT;
|
587
|
-
return (
|
597
|
+
return (fio_str_info_s){.data = NULL, .len = 0};
|
588
598
|
}
|
589
599
|
errno = 0;
|
590
600
|
switch (obj2io(io)->fd) {
|
@@ -603,28 +613,28 @@ fio_cstr_s fiobj_data_read(FIOBJ io, intptr_t length) {
|
|
603
613
|
Tokenize (read2ch)
|
604
614
|
***************************************************************************** */
|
605
615
|
|
606
|
-
static
|
616
|
+
static fio_str_info_s fiobj_data_read2ch_str(FIOBJ io, uint8_t token) {
|
607
617
|
if (obj2io(io)->pos == obj2io(io)->len) /* EOF */
|
608
|
-
return (
|
618
|
+
return (fio_str_info_s){.data = NULL, .len = 0};
|
609
619
|
|
610
620
|
uint8_t *pos = obj2io(io)->buffer + obj2io(io)->pos;
|
611
621
|
uint8_t *lim = obj2io(io)->buffer + obj2io(io)->len;
|
612
622
|
swallow_ch(&pos, lim, token);
|
613
|
-
|
614
|
-
.
|
615
|
-
.
|
623
|
+
fio_str_info_s ret = (fio_str_info_s){
|
624
|
+
.data = (char *)obj2io(io)->buffer + obj2io(io)->pos,
|
625
|
+
.len = (uintptr_t)(pos - obj2io(io)->buffer) - obj2io(io)->pos,
|
616
626
|
};
|
617
627
|
obj2io(io)->pos = (uintptr_t)(pos - obj2io(io)->buffer);
|
618
628
|
return ret;
|
619
629
|
}
|
620
630
|
|
621
|
-
static
|
631
|
+
static fio_str_info_s fiobj_data_read2ch_slice(FIOBJ io, uint8_t token) {
|
622
632
|
if (obj2io(io)->pos == obj2io(io)->len) /* EOF */
|
623
|
-
return (
|
624
|
-
size_t old_pos = obj2io(obj2io(io)->parent)->pos;
|
625
|
-
obj2io(obj2io(io)->parent)->pos = obj2io(io)->capa + obj2io(io)->pos;
|
626
|
-
|
627
|
-
obj2io(obj2io(io)->parent)->pos = old_pos;
|
633
|
+
return (fio_str_info_s){.data = NULL, .len = 0};
|
634
|
+
size_t old_pos = obj2io(obj2io(io)->source.parent)->pos;
|
635
|
+
obj2io(obj2io(io)->source.parent)->pos = obj2io(io)->capa + obj2io(io)->pos;
|
636
|
+
fio_str_info_s tmp = fiobj_data_read2ch(obj2io(io)->source.parent, token);
|
637
|
+
obj2io(obj2io(io)->source.parent)->pos = old_pos;
|
628
638
|
if (tmp.len + obj2io(io)->pos > obj2io(io)->len) {
|
629
639
|
/* EOF */
|
630
640
|
tmp.len = obj2io(io)->len - obj2io(io)->pos;
|
@@ -634,7 +644,7 @@ static fio_cstr_s fiobj_data_read2ch_slice(FIOBJ io, uint8_t token) {
|
|
634
644
|
return tmp;
|
635
645
|
}
|
636
646
|
|
637
|
-
static
|
647
|
+
static fio_str_info_s fiobj_data_read2ch_file(FIOBJ io, uint8_t token) {
|
638
648
|
uint8_t *pos = obj2io(io)->buffer + obj2io(io)->pos;
|
639
649
|
uint8_t *lim = obj2io(io)->buffer + obj2io(io)->len;
|
640
650
|
if (pos != lim && swallow_ch(&pos, lim, token)) {
|
@@ -642,11 +652,12 @@ static fio_cstr_s fiobj_data_read2ch_file(FIOBJ io, uint8_t token) {
|
|
642
652
|
const uintptr_t delta =
|
643
653
|
(uintptr_t)(pos - (obj2io(io)->buffer + obj2io(io)->pos));
|
644
654
|
obj2io(io)->pos += delta;
|
645
|
-
obj2io(io)->fpos += delta;
|
646
|
-
return (
|
647
|
-
.
|
648
|
-
(delta ? ((obj2io(io)->buffer + obj2io(io)->pos) - delta)
|
649
|
-
|
655
|
+
obj2io(io)->source.fpos += delta;
|
656
|
+
return (fio_str_info_s){
|
657
|
+
.data =
|
658
|
+
(char *)(delta ? ((obj2io(io)->buffer + obj2io(io)->pos) - delta)
|
659
|
+
: NULL),
|
660
|
+
.len = delta,
|
650
661
|
};
|
651
662
|
}
|
652
663
|
|
@@ -658,15 +669,16 @@ static fio_cstr_s fiobj_data_read2ch_file(FIOBJ io, uint8_t token) {
|
|
658
669
|
fiobj_data_pre_write(io, 4096); /* read a page at a time */
|
659
670
|
retry_int:
|
660
671
|
tmp = pread(obj2io(io)->fd, obj2io(io)->buffer + obj2io(io)->len, 4096,
|
661
|
-
obj2io(io)->fpos + obj2io(io)->len);
|
672
|
+
obj2io(io)->source.fpos + obj2io(io)->len);
|
662
673
|
if (tmp < 0 && errno == EINTR)
|
663
674
|
goto retry_int;
|
664
675
|
if (tmp < 0 || (tmp == 0 && obj2io(io)->len == 0)) {
|
665
|
-
return (
|
676
|
+
return (fio_str_info_s){.data = NULL, .len = 0};
|
666
677
|
}
|
667
678
|
if (tmp == 0) {
|
668
|
-
obj2io(io)->fpos += obj2io(io)->len;
|
669
|
-
return (
|
679
|
+
obj2io(io)->source.fpos += obj2io(io)->len;
|
680
|
+
return (fio_str_info_s){.data = (char *)obj2io(io)->buffer,
|
681
|
+
.len = obj2io(io)->len};
|
670
682
|
}
|
671
683
|
obj2io(io)->len += tmp;
|
672
684
|
pos = obj2io(io)->buffer;
|
@@ -675,9 +687,10 @@ static fio_cstr_s fiobj_data_read2ch_file(FIOBJ io, uint8_t token) {
|
|
675
687
|
const uintptr_t delta =
|
676
688
|
(uintptr_t)(pos - (obj2io(io)->buffer + obj2io(io)->pos));
|
677
689
|
obj2io(io)->pos = delta;
|
678
|
-
obj2io(io)->fpos += delta;
|
679
|
-
return (
|
680
|
-
.
|
690
|
+
obj2io(io)->source.fpos += delta;
|
691
|
+
return (fio_str_info_s){
|
692
|
+
.data = (char *)obj2io(io)->buffer,
|
693
|
+
.len = delta,
|
681
694
|
};
|
682
695
|
}
|
683
696
|
}
|
@@ -694,10 +707,10 @@ static fio_cstr_s fiobj_data_read2ch_file(FIOBJ io, uint8_t token) {
|
|
694
707
|
* The C string object will be invalidate the next time a function call to the
|
695
708
|
* IO object is made.
|
696
709
|
*/
|
697
|
-
|
710
|
+
fio_str_info_s fiobj_data_read2ch(FIOBJ io, uint8_t token) {
|
698
711
|
if (!io || !FIOBJ_TYPE_IS(io, FIOBJ_T_DATA)) {
|
699
712
|
errno = EFAULT;
|
700
|
-
return (
|
713
|
+
return (fio_str_info_s){.data = NULL, .len = 0};
|
701
714
|
}
|
702
715
|
switch (obj2io(io)->fd) {
|
703
716
|
case -1:
|
@@ -727,7 +740,7 @@ intptr_t fiobj_data_pos(FIOBJ io) {
|
|
727
740
|
return obj2io(io)->pos;
|
728
741
|
break;
|
729
742
|
default:
|
730
|
-
return obj2io(io)->fpos;
|
743
|
+
return obj2io(io)->source.fpos;
|
731
744
|
}
|
732
745
|
}
|
733
746
|
|
@@ -774,7 +787,7 @@ void fiobj_data_seek(FIOBJ io, intptr_t position) {
|
|
774
787
|
obj2io(io)->len = 0;
|
775
788
|
|
776
789
|
if (position == 0) {
|
777
|
-
obj2io(io)->fpos = 0;
|
790
|
+
obj2io(io)->source.fpos = 0;
|
778
791
|
return;
|
779
792
|
}
|
780
793
|
int64_t len = fiobj_data_get_fd_size(io);
|
@@ -784,7 +797,7 @@ void fiobj_data_seek(FIOBJ io, intptr_t position) {
|
|
784
797
|
if (position > len)
|
785
798
|
position = len;
|
786
799
|
|
787
|
-
obj2io(io)->fpos = position;
|
800
|
+
obj2io(io)->source.fpos = position;
|
788
801
|
return;
|
789
802
|
}
|
790
803
|
position = (0 - position);
|
@@ -792,7 +805,7 @@ void fiobj_data_seek(FIOBJ io, intptr_t position) {
|
|
792
805
|
position = 0;
|
793
806
|
else
|
794
807
|
position = len - position;
|
795
|
-
obj2io(io)->fpos = position;
|
808
|
+
obj2io(io)->source.fpos = position;
|
796
809
|
return;
|
797
810
|
}
|
798
811
|
}
|
@@ -808,8 +821,8 @@ void fiobj_data_seek(FIOBJ io, intptr_t position) {
|
|
808
821
|
// default:
|
809
822
|
// }
|
810
823
|
|
811
|
-
static
|
812
|
-
|
824
|
+
static fio_str_info_s fiobj_data_pread_str(FIOBJ io, intptr_t start_at,
|
825
|
+
uintptr_t length) {
|
813
826
|
if (start_at < 0)
|
814
827
|
start_at = obj2io(io)->len + start_at;
|
815
828
|
if (start_at < 0)
|
@@ -819,15 +832,17 @@ static fio_cstr_s fiobj_data_pread_str(FIOBJ io, intptr_t start_at,
|
|
819
832
|
if (length + start_at > obj2io(io)->len)
|
820
833
|
length = obj2io(io)->len - start_at;
|
821
834
|
if (length == 0)
|
822
|
-
return (
|
823
|
-
.
|
835
|
+
return (fio_str_info_s){
|
836
|
+
.data = NULL,
|
837
|
+
.len = 0,
|
824
838
|
};
|
825
|
-
return (
|
826
|
-
.
|
839
|
+
return (fio_str_info_s){
|
840
|
+
.data = (char *)obj2io(io)->buffer + start_at,
|
841
|
+
.len = length,
|
827
842
|
};
|
828
843
|
}
|
829
|
-
static
|
830
|
-
|
844
|
+
static fio_str_info_s fiobj_data_pread_slice(FIOBJ io, intptr_t start_at,
|
845
|
+
uintptr_t length) {
|
831
846
|
if (start_at < 0)
|
832
847
|
start_at = obj2io(io)->len + start_at;
|
833
848
|
if (start_at < 0)
|
@@ -837,14 +852,15 @@ static fio_cstr_s fiobj_data_pread_slice(FIOBJ io, intptr_t start_at,
|
|
837
852
|
if (length + start_at > obj2io(io)->len)
|
838
853
|
length = obj2io(io)->len - start_at;
|
839
854
|
if (length == 0)
|
840
|
-
return (
|
841
|
-
.
|
855
|
+
return (fio_str_info_s){
|
856
|
+
.data = NULL,
|
857
|
+
.len = 0,
|
842
858
|
};
|
843
|
-
return fiobj_data_pread(obj2io(io)->parent, start_at, length);
|
859
|
+
return fiobj_data_pread(obj2io(io)->source.parent, start_at, length);
|
844
860
|
}
|
845
861
|
|
846
|
-
static
|
847
|
-
|
862
|
+
static fio_str_info_s fiobj_data_pread_file(FIOBJ io, intptr_t start_at,
|
863
|
+
uintptr_t length) {
|
848
864
|
const int64_t size = fiobj_data_get_fd_size(io);
|
849
865
|
if (start_at < 0)
|
850
866
|
start_at = size + start_at;
|
@@ -853,21 +869,24 @@ static fio_cstr_s fiobj_data_pread_file(FIOBJ io, intptr_t start_at,
|
|
853
869
|
if (length + start_at > (uint64_t)size)
|
854
870
|
length = size - start_at;
|
855
871
|
if (length == 0)
|
856
|
-
return (
|
857
|
-
.
|
872
|
+
return (fio_str_info_s){
|
873
|
+
.data = NULL,
|
874
|
+
.len = 0,
|
858
875
|
};
|
859
876
|
obj2io(io)->len = 0;
|
860
877
|
obj2io(io)->pos = 0;
|
861
878
|
fiobj_data_pre_write(io, length + 1);
|
862
879
|
ssize_t tmp = pread(obj2io(io)->fd, obj2io(io)->buffer, length, start_at);
|
863
880
|
if (tmp <= 0) {
|
864
|
-
return (
|
865
|
-
.
|
881
|
+
return (fio_str_info_s){
|
882
|
+
.data = NULL,
|
883
|
+
.len = 0,
|
866
884
|
};
|
867
885
|
}
|
868
886
|
obj2io(io)->buffer[tmp] = 0;
|
869
|
-
return (
|
870
|
-
.
|
887
|
+
return (fio_str_info_s){
|
888
|
+
.data = (char *)obj2io(io)->buffer,
|
889
|
+
.len = tmp,
|
871
890
|
};
|
872
891
|
}
|
873
892
|
/**
|
@@ -878,11 +897,12 @@ static fio_cstr_s fiobj_data_pread_file(FIOBJ io, intptr_t start_at,
|
|
878
897
|
* The C string object will be invalidate the next time a function call to the
|
879
898
|
* IO object is made.
|
880
899
|
*/
|
881
|
-
|
900
|
+
fio_str_info_s fiobj_data_pread(FIOBJ io, intptr_t start_at, uintptr_t length) {
|
882
901
|
if (!io || !FIOBJ_TYPE_IS(io, FIOBJ_T_DATA)) {
|
883
902
|
errno = EFAULT;
|
884
|
-
return (
|
885
|
-
.
|
903
|
+
return (fio_str_info_s){
|
904
|
+
.data = NULL,
|
905
|
+
.len = 0,
|
886
906
|
};
|
887
907
|
}
|
888
908
|
|
@@ -995,20 +1015,19 @@ intptr_t fiobj_data_puts(FIOBJ io, void *buffer, uintptr_t length) {
|
|
995
1015
|
void fiobj_data_test(void) {
|
996
1016
|
char *filename = NULL;
|
997
1017
|
FIOBJ text;
|
998
|
-
|
1018
|
+
fio_str_info_s s1, s2;
|
999
1019
|
fprintf(stderr, "=== testing fiobj_data\n");
|
1000
|
-
if (filename)
|
1001
|
-
text =
|
1002
|
-
|
1003
|
-
|
1020
|
+
if (filename) {
|
1021
|
+
text = fiobj_str_buf(0);
|
1022
|
+
fiobj_str_readfile(text, filename, 0, 0);
|
1023
|
+
} else
|
1024
|
+
text = fiobj_str_new("Line 1\r\nLine 2\nLine 3 unended", 29);
|
1004
1025
|
FIOBJ strio = fiobj_data_newstr();
|
1005
1026
|
fprintf(stderr, "* `newstr` passed.\n");
|
1006
1027
|
FIOBJ fdio = fiobj_data_newtmpfile();
|
1007
1028
|
fprintf(stderr, "* `newtmpfile` passed.\n");
|
1008
|
-
fiobj_data_write(fdio, fiobj_obj2cstr(text).
|
1009
|
-
|
1010
|
-
fiobj_data_write(strio, fiobj_obj2cstr(text).buffer,
|
1011
|
-
fiobj_obj2cstr(text).length);
|
1029
|
+
fiobj_data_write(fdio, fiobj_obj2cstr(text).data, fiobj_obj2cstr(text).len);
|
1030
|
+
fiobj_data_write(strio, fiobj_obj2cstr(text).data, fiobj_obj2cstr(text).len);
|
1012
1031
|
FIOBJ sliceio = fiobj_data_slice(fdio, 8, 7);
|
1013
1032
|
|
1014
1033
|
s1 = fiobj_data_read(sliceio, 4096);
|
@@ -1024,8 +1043,8 @@ void fiobj_data_test(void) {
|
|
1024
1043
|
exit(-1);
|
1025
1044
|
}
|
1026
1045
|
|
1027
|
-
if (fiobj_obj2cstr(strio).
|
1028
|
-
fiobj_obj2cstr(fdio).
|
1046
|
+
if (fiobj_obj2cstr(strio).len != fiobj_obj2cstr(text).len ||
|
1047
|
+
fiobj_obj2cstr(fdio).len != fiobj_obj2cstr(text).len) {
|
1029
1048
|
fprintf(stderr, "* `write` operation FAILED!\n");
|
1030
1049
|
exit(-1);
|
1031
1050
|
}
|
@@ -1033,7 +1052,7 @@ void fiobj_data_test(void) {
|
|
1033
1052
|
s2 = fiobj_data_gets(fdio);
|
1034
1053
|
fprintf(stderr, "str(%d): %.*s", (int)s1.len, (int)s1.len, s1.data);
|
1035
1054
|
fprintf(stderr, "fd(%d): %.*s", (int)s2.len, (int)s2.len, s2.data);
|
1036
|
-
if (s1.
|
1055
|
+
if (s1.len != s2.len || memcmp(s1.data, s2.data, s1.len)) {
|
1037
1056
|
fprintf(stderr,
|
1038
1057
|
"* `gets` operation FAILED! (non equal data):\n"
|
1039
1058
|
"%d bytes vs. %d bytes\n"
|
@@ -1050,7 +1069,7 @@ void fiobj_data_test(void) {
|
|
1050
1069
|
s1 = fiobj_data_gets(sliceio);
|
1051
1070
|
s2 = fiobj_data_gets(fdio);
|
1052
1071
|
fiobj_data_seek(fdio, last_pos);
|
1053
|
-
if (s1.
|
1072
|
+
if (s1.len != s2.len || memcmp(s1.data, s2.data, s1.len)) {
|
1054
1073
|
fprintf(stderr,
|
1055
1074
|
"* slice `gets` operation FAILED! (non equal data):\n"
|
1056
1075
|
"%d bytes vs. %d bytes\n"
|
@@ -1063,7 +1082,7 @@ void fiobj_data_test(void) {
|
|
1063
1082
|
|
1064
1083
|
s1 = fiobj_data_read(strio, 3);
|
1065
1084
|
s2 = fiobj_data_read(fdio, 3);
|
1066
|
-
if (s1.
|
1085
|
+
if (s1.len != s2.len || memcmp(s1.data, s2.data, s1.len)) {
|
1067
1086
|
fprintf(stderr,
|
1068
1087
|
"* `read` operation FAILED! (non equal data):\n"
|
1069
1088
|
"%d bytes vs. %d bytes\n"
|
@@ -1078,7 +1097,7 @@ void fiobj_data_test(void) {
|
|
1078
1097
|
s2 = fiobj_data_gets(fdio);
|
1079
1098
|
s1 = fiobj_data_gets(strio);
|
1080
1099
|
s2 = fiobj_data_gets(fdio);
|
1081
|
-
if (s1.
|
1100
|
+
if (s1.len != s2.len || memcmp(s1.data, s2.data, s1.len)) {
|
1082
1101
|
fprintf(stderr,
|
1083
1102
|
"* EOF `gets` operation FAILED! (non equal data):\n"
|
1084
1103
|
"%d bytes vs. %d bytes\n"
|
@@ -1134,7 +1153,7 @@ void fiobj_data_test(void) {
|
|
1134
1153
|
#endif
|
1135
1154
|
|
1136
1155
|
#else /* require POSIX */
|
1137
|
-
#include
|
1156
|
+
#include <fiobj_data.h>
|
1138
1157
|
|
1139
1158
|
/** Creates a new local in-memory IO object */
|
1140
1159
|
FIOBJ fiobj_data_newstr(void) { return FIOBJ_INVALID; }
|