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.

Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/README.md +4 -4
  4. data/SPEC-Websocket-Draft.md +3 -6
  5. data/bin/mustache.rb +128 -0
  6. data/examples/test_template.mustache +16 -0
  7. data/ext/iodine/fio.c +9397 -0
  8. data/ext/iodine/fio.h +4723 -0
  9. data/ext/iodine/fio_ary.h +353 -54
  10. data/ext/iodine/fio_cli.c +351 -361
  11. data/ext/iodine/fio_cli.h +84 -105
  12. data/ext/iodine/fio_hashmap.h +70 -16
  13. data/ext/iodine/fio_json_parser.h +35 -24
  14. data/ext/iodine/fio_siphash.c +104 -4
  15. data/ext/iodine/fio_siphash.h +18 -2
  16. data/ext/iodine/fio_str.h +1218 -0
  17. data/ext/iodine/fio_tmpfile.h +1 -1
  18. data/ext/iodine/fiobj.h +13 -8
  19. data/ext/iodine/fiobj4sock.h +6 -8
  20. data/ext/iodine/fiobj_ary.c +107 -17
  21. data/ext/iodine/fiobj_ary.h +36 -4
  22. data/ext/iodine/fiobj_data.c +146 -127
  23. data/ext/iodine/fiobj_data.h +25 -23
  24. data/ext/iodine/fiobj_hash.c +7 -7
  25. data/ext/iodine/fiobj_hash.h +6 -5
  26. data/ext/iodine/fiobj_json.c +20 -17
  27. data/ext/iodine/fiobj_json.h +5 -5
  28. data/ext/iodine/fiobj_mem.h +71 -0
  29. data/ext/iodine/fiobj_mustache.c +310 -0
  30. data/ext/iodine/fiobj_mustache.h +40 -0
  31. data/ext/iodine/fiobj_numbers.c +199 -94
  32. data/ext/iodine/fiobj_numbers.h +7 -7
  33. data/ext/iodine/fiobj_str.c +142 -333
  34. data/ext/iodine/fiobj_str.h +65 -55
  35. data/ext/iodine/fiobject.c +49 -11
  36. data/ext/iodine/fiobject.h +40 -39
  37. data/ext/iodine/http.c +382 -190
  38. data/ext/iodine/http.h +124 -80
  39. data/ext/iodine/http1.c +99 -127
  40. data/ext/iodine/http1.h +5 -5
  41. data/ext/iodine/http1_parser.c +3 -2
  42. data/ext/iodine/http1_parser.h +2 -2
  43. data/ext/iodine/http_internal.c +14 -12
  44. data/ext/iodine/http_internal.h +25 -19
  45. data/ext/iodine/iodine.c +37 -18
  46. data/ext/iodine/iodine.h +4 -0
  47. data/ext/iodine/iodine_caller.c +9 -2
  48. data/ext/iodine/iodine_caller.h +2 -0
  49. data/ext/iodine/iodine_connection.c +82 -117
  50. data/ext/iodine/iodine_defer.c +57 -50
  51. data/ext/iodine/iodine_defer.h +0 -1
  52. data/ext/iodine/iodine_fiobj2rb.h +4 -2
  53. data/ext/iodine/iodine_helpers.c +4 -4
  54. data/ext/iodine/iodine_http.c +25 -32
  55. data/ext/iodine/iodine_json.c +2 -1
  56. data/ext/iodine/iodine_mustache.c +423 -0
  57. data/ext/iodine/iodine_mustache.h +6 -0
  58. data/ext/iodine/iodine_pubsub.c +48 -153
  59. data/ext/iodine/iodine_pubsub.h +5 -4
  60. data/ext/iodine/iodine_rack_io.c +7 -5
  61. data/ext/iodine/iodine_store.c +16 -13
  62. data/ext/iodine/iodine_tcp.c +26 -34
  63. data/ext/iodine/mustache_parser.h +1085 -0
  64. data/ext/iodine/redis_engine.c +740 -646
  65. data/ext/iodine/redis_engine.h +13 -15
  66. data/ext/iodine/resp_parser.h +11 -5
  67. data/ext/iodine/websocket_parser.h +13 -13
  68. data/ext/iodine/websockets.c +240 -393
  69. data/ext/iodine/websockets.h +52 -113
  70. data/lib/iodine.rb +1 -1
  71. data/lib/iodine/mustache.rb +140 -0
  72. data/lib/iodine/version.rb +1 -1
  73. metadata +15 -28
  74. data/ext/iodine/defer.c +0 -566
  75. data/ext/iodine/defer.h +0 -148
  76. data/ext/iodine/evio.c +0 -26
  77. data/ext/iodine/evio.h +0 -161
  78. data/ext/iodine/evio_callbacks.c +0 -26
  79. data/ext/iodine/evio_epoll.c +0 -251
  80. data/ext/iodine/evio_kqueue.c +0 -194
  81. data/ext/iodine/facil.c +0 -2325
  82. data/ext/iodine/facil.h +0 -616
  83. data/ext/iodine/fio_base64.c +0 -277
  84. data/ext/iodine/fio_base64.h +0 -71
  85. data/ext/iodine/fio_llist.h +0 -257
  86. data/ext/iodine/fio_mem.c +0 -675
  87. data/ext/iodine/fio_mem.h +0 -143
  88. data/ext/iodine/fio_random.c +0 -248
  89. data/ext/iodine/fio_random.h +0 -45
  90. data/ext/iodine/fio_sha1.c +0 -362
  91. data/ext/iodine/fio_sha1.h +0 -107
  92. data/ext/iodine/fio_sha2.c +0 -842
  93. data/ext/iodine/fio_sha2.h +0 -169
  94. data/ext/iodine/pubsub.c +0 -867
  95. data/ext/iodine/pubsub.h +0 -221
  96. data/ext/iodine/sock.c +0 -1366
  97. data/ext/iodine/sock.h +0 -566
  98. data/ext/iodine/spnlock.inc +0 -111
@@ -18,7 +18,7 @@ License: MIT
18
18
  #include <sys/types.h>
19
19
  #include <unistd.h>
20
20
 
21
- int fio_tmpfile(void) {
21
+ static inline int fio_tmpfile(void) {
22
22
  // create a temporary file to contain the data.
23
23
  int fd = 0;
24
24
  #ifdef P_tmpdir
@@ -5,18 +5,20 @@ License: MIT
5
5
  #ifndef H_FIOBJ_H
6
6
  #define H_FIOBJ_H
7
7
 
8
- #include "fiobj_ary.h"
9
- #include "fiobj_data.h"
10
- #include "fiobj_hash.h"
11
- #include "fiobj_json.h"
12
- #include "fiobj_numbers.h"
13
- #include "fiobj_str.h"
14
- #include "fiobject.h"
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 "fio_siphash.h"
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) {
@@ -4,20 +4,18 @@
4
4
  * Defines a helper for using fiobj with the sock library.
5
5
  */
6
6
 
7
- #include "fiobj.h"
8
- #include "sock.h"
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
- fio_cstr_s s = fiobj_obj2cstr(o);
16
- return sock_write2(.uuid = uuid, .buffer = (void *)(o),
17
- .offset = (((intptr_t)s.data) - ((intptr_t)(o))),
18
- .length = s.length,
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
@@ -3,12 +3,16 @@ Copyright: Boaz Segev, 2017-2018
3
3
  License: MIT
4
4
  */
5
5
 
6
- #include "fiobject.h"
6
+ #include <fiobject.h>
7
7
 
8
8
  #define FIO_OVERRIDE_MALLOC 1
9
- #include "fio_mem.h"
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((FIOBJ)i.obj, arg); }
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, (int (*)(void *, void *))task,
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
- fio_cstr_s fiobject___noop_to_str(const FIOBJ o);
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, .type = FIOBJ_T_ARRAY,
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 begining of the array.
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 retrived from the end of the array. i.e., `-1`
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 (FIOBJ)fio_ary_index(&obj2ary(ary)->ary, pos);
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 = (FIOBJ)fio_ary_set(&obj2ary(ary)->ary, (void *)obj, pos);
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, (void *)obj);
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 (FIOBJ)fio_ary_pop(&obj2ary(ary)->ary);
170
+ return fio_ary_pop(&obj2ary(ary)->ary);
167
171
  }
168
172
 
169
173
  /**
170
- * Unshifts an object to the begining of the Array. This could be
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, (void *)obj);
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 (FIOBJ)fio_ary_shift(&obj2ary(ary)->ary);
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
  }
@@ -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 "fiobject.h"
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 begining of the array.
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 retrived from the end of the array. i.e., `-1`
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 begining of the Array. This could be
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
  ***************************************************************************** */
@@ -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 "fiobj_data.h"
21
- #include "fio_tmpfile.h"
22
- #include "fiobj_str.h"
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 "fio_mem.h"
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, obj2io(o)->len);
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
- fio_cstr_s data;
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, 4096);
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.buffer, data.len);
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}, .buffer = buffer, .fd = fd,
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 fio_cstr_s fio_io2str(const FIOBJ o) {
199
+ static fio_str_info_s fio_io2str(const FIOBJ o) {
196
200
  switch (obj2io(o)->fd) {
197
201
  case -1:
198
- return (fio_cstr_s){.buffer = obj2io(o)->buffer, .len = obj2io(o)->len};
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, obj2io(o)->len);
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 (fio_cstr_s){.buffer = obj2io(o)->buffer, .len = obj2io(o)->len};
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 (fio_cstr_s){.buffer = NULL, .len = 0};
218
+ return (fio_str_info_s){.data = NULL, .len = 0};
212
219
  obj2io(o)->buffer[i] = 0;
213
- return (fio_cstr_s){.buffer = obj2io(o)->buffer, .len = i};
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
- (len = fiobj_data_i(self)) == fiobj_data_i(other) &&
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
- fio_cstr_s tmp;
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, 4096);
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 fio_cstr_s fiobj_data_read_str(FIOBJ io, intptr_t length) {
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 (fio_cstr_s){.buffer = NULL, .len = 0};
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 (fio_cstr_s){.buffer = NULL, .len = 0};
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 (fio_cstr_s){
509
- .buffer = (obj2io(io)->buffer + pos), .length = (obj2io(io)->pos - pos),
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 fio_cstr_s fiobj_data_read_slice(FIOBJ io, intptr_t length) {
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 (fio_cstr_s){.buffer = NULL, .len = 0};
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 (fio_cstr_s){.buffer = NULL, .len = 0};
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 fio_cstr_s fiobj_data_read_file(FIOBJ io, intptr_t length) {
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 (fio_cstr_s){.buffer = NULL, .len = 0};
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
- fio_cstr_s data = {.buffer = (obj2io(io)->buffer + obj2io(io)->pos),
556
- .length = (uintptr_t)length};
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, obj2io(io)->fpos);
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 (fio_cstr_s){.buffer = NULL, .len = 0};
573
- obj2io(io)->fpos += l;
574
- return (fio_cstr_s){.buffer = obj2io(io)->buffer, .len = l};
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
- fio_cstr_s fiobj_data_read(FIOBJ io, intptr_t length) {
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 (fio_cstr_s){.buffer = NULL, .len = 0};
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 fio_cstr_s fiobj_data_read2ch_str(FIOBJ io, uint8_t token) {
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 (fio_cstr_s){.buffer = NULL, .len = 0};
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
- fio_cstr_s ret = (fio_cstr_s){
614
- .buffer = obj2io(io)->buffer + obj2io(io)->pos,
615
- .length = (uintptr_t)(pos - obj2io(io)->buffer) - obj2io(io)->pos,
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 fio_cstr_s fiobj_data_read2ch_slice(FIOBJ io, uint8_t token) {
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 (fio_cstr_s){.buffer = NULL, .len = 0};
624
- size_t old_pos = obj2io(obj2io(io)->parent)->pos;
625
- obj2io(obj2io(io)->parent)->pos = obj2io(io)->capa + obj2io(io)->pos;
626
- fio_cstr_s tmp = fiobj_data_read2ch(obj2io(io)->parent, token);
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 fio_cstr_s fiobj_data_read2ch_file(FIOBJ io, uint8_t token) {
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 (fio_cstr_s){
647
- .buffer =
648
- (delta ? ((obj2io(io)->buffer + obj2io(io)->pos) - delta) : NULL),
649
- .length = delta,
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 (fio_cstr_s){.buffer = NULL, .len = 0};
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 (fio_cstr_s){.buffer = obj2io(io)->buffer, .len = obj2io(io)->len};
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 (fio_cstr_s){
680
- .buffer = obj2io(io)->buffer, .length = delta,
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
- fio_cstr_s fiobj_data_read2ch(FIOBJ io, uint8_t token) {
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 (fio_cstr_s){.buffer = NULL, .len = 0};
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 fio_cstr_s fiobj_data_pread_str(FIOBJ io, intptr_t start_at,
812
- uintptr_t length) {
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 (fio_cstr_s){
823
- .buffer = NULL, .length = 0,
835
+ return (fio_str_info_s){
836
+ .data = NULL,
837
+ .len = 0,
824
838
  };
825
- return (fio_cstr_s){
826
- .buffer = obj2io(io)->buffer + start_at, .length = length,
839
+ return (fio_str_info_s){
840
+ .data = (char *)obj2io(io)->buffer + start_at,
841
+ .len = length,
827
842
  };
828
843
  }
829
- static fio_cstr_s fiobj_data_pread_slice(FIOBJ io, intptr_t start_at,
830
- uintptr_t length) {
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 (fio_cstr_s){
841
- .buffer = NULL, .length = 0,
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 fio_cstr_s fiobj_data_pread_file(FIOBJ io, intptr_t start_at,
847
- uintptr_t length) {
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 (fio_cstr_s){
857
- .buffer = NULL, .length = 0,
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 (fio_cstr_s){
865
- .buffer = NULL, .length = 0,
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 (fio_cstr_s){
870
- .buffer = obj2io(io)->buffer, .length = tmp,
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
- fio_cstr_s fiobj_data_pread(FIOBJ io, intptr_t start_at, uintptr_t length) {
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 (fio_cstr_s){
885
- .buffer = NULL, .length = 0,
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
- fio_cstr_s s1, s2;
1018
+ fio_str_info_s s1, s2;
999
1019
  fprintf(stderr, "=== testing fiobj_data\n");
1000
- if (filename)
1001
- text = fiobj_str_readfile(filename, 0, 0);
1002
- else
1003
- text = fiobj_str_static("Line 1\r\nLine 2\nLine 3 unended", 29);
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).buffer,
1009
- fiobj_obj2cstr(text).length);
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).length != fiobj_obj2cstr(text).length ||
1028
- fiobj_obj2cstr(fdio).length != fiobj_obj2cstr(text).length) {
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.length != s2.length || memcmp(s1.data, s2.data, s1.length)) {
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.length != s2.length || memcmp(s1.data, s2.data, s1.length)) {
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.length != s2.length || memcmp(s1.data, s2.data, s1.length)) {
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.length != s2.length || memcmp(s1.data, s2.data, s1.length)) {
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 "fiobj_data.h"
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; }