rage-iodine 1.7.58

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
  3. data/.github/workflows/ruby.yml +42 -0
  4. data/.gitignore +20 -0
  5. data/.rspec +2 -0
  6. data/.yardopts +8 -0
  7. data/CHANGELOG.md +1098 -0
  8. data/Gemfile +11 -0
  9. data/LICENSE.txt +21 -0
  10. data/LIMITS.md +41 -0
  11. data/README.md +782 -0
  12. data/Rakefile +23 -0
  13. data/SPEC-PubSub-Draft.md +159 -0
  14. data/SPEC-WebSocket-Draft.md +239 -0
  15. data/bin/console +22 -0
  16. data/bin/info.md +353 -0
  17. data/bin/mustache_bench.rb +100 -0
  18. data/bin/poc/Gemfile.lock +23 -0
  19. data/bin/poc/README.md +37 -0
  20. data/bin/poc/config.ru +66 -0
  21. data/bin/poc/gemfile +1 -0
  22. data/bin/poc/www/index.html +57 -0
  23. data/examples/async_task.ru +92 -0
  24. data/examples/bates/README.md +3 -0
  25. data/examples/bates/config.ru +342 -0
  26. data/examples/bates/david+bold.pdf +0 -0
  27. data/examples/bates/public/drop-pdf.png +0 -0
  28. data/examples/bates/public/index.html +600 -0
  29. data/examples/config.ru +59 -0
  30. data/examples/echo.ru +59 -0
  31. data/examples/etag.ru +16 -0
  32. data/examples/hello.ru +29 -0
  33. data/examples/pubsub_engine.ru +81 -0
  34. data/examples/rack3.ru +12 -0
  35. data/examples/redis.ru +70 -0
  36. data/examples/shootout.ru +73 -0
  37. data/examples/sub-protocols.ru +90 -0
  38. data/examples/tcp_client.rb +66 -0
  39. data/examples/x-sendfile.ru +14 -0
  40. data/exe/iodine +280 -0
  41. data/ext/iodine/extconf.rb +110 -0
  42. data/ext/iodine/fio.c +12096 -0
  43. data/ext/iodine/fio.h +6390 -0
  44. data/ext/iodine/fio_cli.c +431 -0
  45. data/ext/iodine/fio_cli.h +189 -0
  46. data/ext/iodine/fio_json_parser.h +687 -0
  47. data/ext/iodine/fio_siphash.c +157 -0
  48. data/ext/iodine/fio_siphash.h +37 -0
  49. data/ext/iodine/fio_tls.h +129 -0
  50. data/ext/iodine/fio_tls_missing.c +649 -0
  51. data/ext/iodine/fio_tls_openssl.c +1056 -0
  52. data/ext/iodine/fio_tmpfile.h +50 -0
  53. data/ext/iodine/fiobj.h +44 -0
  54. data/ext/iodine/fiobj4fio.h +21 -0
  55. data/ext/iodine/fiobj_ary.c +333 -0
  56. data/ext/iodine/fiobj_ary.h +139 -0
  57. data/ext/iodine/fiobj_data.c +1185 -0
  58. data/ext/iodine/fiobj_data.h +167 -0
  59. data/ext/iodine/fiobj_hash.c +409 -0
  60. data/ext/iodine/fiobj_hash.h +176 -0
  61. data/ext/iodine/fiobj_json.c +622 -0
  62. data/ext/iodine/fiobj_json.h +68 -0
  63. data/ext/iodine/fiobj_mem.h +71 -0
  64. data/ext/iodine/fiobj_mustache.c +317 -0
  65. data/ext/iodine/fiobj_mustache.h +62 -0
  66. data/ext/iodine/fiobj_numbers.c +344 -0
  67. data/ext/iodine/fiobj_numbers.h +127 -0
  68. data/ext/iodine/fiobj_str.c +433 -0
  69. data/ext/iodine/fiobj_str.h +172 -0
  70. data/ext/iodine/fiobject.c +620 -0
  71. data/ext/iodine/fiobject.h +654 -0
  72. data/ext/iodine/hpack.h +1923 -0
  73. data/ext/iodine/http.c +2736 -0
  74. data/ext/iodine/http.h +1019 -0
  75. data/ext/iodine/http1.c +825 -0
  76. data/ext/iodine/http1.h +29 -0
  77. data/ext/iodine/http1_parser.h +1835 -0
  78. data/ext/iodine/http_internal.c +1279 -0
  79. data/ext/iodine/http_internal.h +248 -0
  80. data/ext/iodine/http_mime_parser.h +350 -0
  81. data/ext/iodine/iodine.c +1433 -0
  82. data/ext/iodine/iodine.h +64 -0
  83. data/ext/iodine/iodine_caller.c +218 -0
  84. data/ext/iodine/iodine_caller.h +27 -0
  85. data/ext/iodine/iodine_connection.c +941 -0
  86. data/ext/iodine/iodine_connection.h +55 -0
  87. data/ext/iodine/iodine_defer.c +420 -0
  88. data/ext/iodine/iodine_defer.h +6 -0
  89. data/ext/iodine/iodine_fiobj2rb.h +120 -0
  90. data/ext/iodine/iodine_helpers.c +282 -0
  91. data/ext/iodine/iodine_helpers.h +12 -0
  92. data/ext/iodine/iodine_http.c +1280 -0
  93. data/ext/iodine/iodine_http.h +23 -0
  94. data/ext/iodine/iodine_json.c +302 -0
  95. data/ext/iodine/iodine_json.h +6 -0
  96. data/ext/iodine/iodine_mustache.c +567 -0
  97. data/ext/iodine/iodine_mustache.h +6 -0
  98. data/ext/iodine/iodine_pubsub.c +580 -0
  99. data/ext/iodine/iodine_pubsub.h +26 -0
  100. data/ext/iodine/iodine_rack_io.c +273 -0
  101. data/ext/iodine/iodine_rack_io.h +20 -0
  102. data/ext/iodine/iodine_store.c +142 -0
  103. data/ext/iodine/iodine_store.h +20 -0
  104. data/ext/iodine/iodine_tcp.c +346 -0
  105. data/ext/iodine/iodine_tcp.h +13 -0
  106. data/ext/iodine/iodine_tls.c +261 -0
  107. data/ext/iodine/iodine_tls.h +13 -0
  108. data/ext/iodine/mustache_parser.h +1546 -0
  109. data/ext/iodine/redis_engine.c +957 -0
  110. data/ext/iodine/redis_engine.h +79 -0
  111. data/ext/iodine/resp_parser.h +317 -0
  112. data/ext/iodine/scheduler.c +173 -0
  113. data/ext/iodine/scheduler.h +6 -0
  114. data/ext/iodine/websocket_parser.h +506 -0
  115. data/ext/iodine/websockets.c +752 -0
  116. data/ext/iodine/websockets.h +185 -0
  117. data/iodine.gemspec +50 -0
  118. data/lib/iodine/connection.rb +61 -0
  119. data/lib/iodine/json.rb +42 -0
  120. data/lib/iodine/mustache.rb +113 -0
  121. data/lib/iodine/pubsub.rb +55 -0
  122. data/lib/iodine/rack_utils.rb +43 -0
  123. data/lib/iodine/tls.rb +16 -0
  124. data/lib/iodine/version.rb +3 -0
  125. data/lib/iodine.rb +274 -0
  126. data/lib/rack/handler/iodine.rb +33 -0
  127. data/logo.png +0 -0
  128. metadata +284 -0
@@ -0,0 +1,71 @@
1
+ /*
2
+ Copyright: Boaz Segev, 2018
3
+ License: MIT
4
+
5
+ Feel free to copy, use and enjoy according to the license provided.
6
+ */
7
+ #ifndef H_FIOBJ_MEM_H
8
+
9
+ /**
10
+ * This is a placeholder for facil.io memory allocator functions in fio.h.
11
+ *
12
+ * In cases where the FIOBJ library is extracted from facil.io, these functions
13
+ * will call the system's memory allocator (`malloc`, `free`, etc').
14
+ */
15
+ #define H_FIOBJ_MEM_H
16
+
17
+ #include <stdlib.h>
18
+
19
+ /**
20
+ * Allocates memory using a per-CPU core block memory pool.
21
+ * Memory is zeroed out.
22
+ *
23
+ * Allocations above FIO_MEMORY_BLOCK_ALLOC_LIMIT (12,288 bytes when using 32Kb
24
+ * blocks) will be redirected to `mmap`, as if `fio_mmap` was called.
25
+ */
26
+ void *fio_malloc(size_t size);
27
+
28
+ /**
29
+ * same as calling `fio_malloc(size_per_unit * unit_count)`;
30
+ *
31
+ * Allocations above FIO_MEMORY_BLOCK_ALLOC_LIMIT (12,288 bytes when using 32Kb
32
+ * blocks) will be redirected to `mmap`, as if `fio_mmap` was called.
33
+ */
34
+ void *fio_calloc(size_t size_per_unit, size_t unit_count);
35
+
36
+ /** Frees memory that was allocated using this library. */
37
+ void fio_free(void *ptr);
38
+
39
+ /**
40
+ * Re-allocates memory. An attept to avoid copying the data is made only for big
41
+ * memory allocations (larger than FIO_MEMORY_BLOCK_ALLOC_LIMIT).
42
+ */
43
+ void *fio_realloc(void *ptr, size_t new_size);
44
+
45
+ /**
46
+ * Re-allocates memory. An attept to avoid copying the data is made only for big
47
+ * memory allocations (larger than FIO_MEMORY_BLOCK_ALLOC_LIMIT).
48
+ *
49
+ * This variation is slightly faster as it might copy less data.
50
+ */
51
+ void *fio_realloc2(void *ptr, size_t new_size, size_t copy_length);
52
+
53
+ /**
54
+ * Allocates memory directly using `mmap`, this is prefered for objects that
55
+ * both require almost a page of memory (or more) and expect a long lifetime.
56
+ *
57
+ * However, since this allocation will invoke the system call (`mmap`), it will
58
+ * be inherently slower.
59
+ *
60
+ * `fio_free` can be used for deallocating the memory.
61
+ */
62
+ void *fio_mmap(size_t size);
63
+
64
+ #if FIO_OVERRIDE_MALLOC
65
+ #define malloc fio_malloc
66
+ #define free fio_free
67
+ #define realloc fio_realloc
68
+ #define calloc fio_calloc
69
+ #endif
70
+
71
+ #endif /* H_FIOBJ_MEM_H */
@@ -0,0 +1,317 @@
1
+ /*
2
+ Copyright: Boaz Segev, 2018-2019
3
+ License: MIT
4
+ */
5
+ #define INCLUDE_MUSTACHE_IMPLEMENTATION 1
6
+ #include <mustache_parser.h>
7
+
8
+ #include <fiobj_ary.h>
9
+ #include <fiobj_hash.h>
10
+ #include <fiobj_mustache.h>
11
+ #include <fiobj_str.h>
12
+
13
+ #ifndef FIO_IGNORE_MACRO
14
+ /**
15
+ * This is used internally to ignore macros that shadow functions (avoiding
16
+ * named arguments when required).
17
+ */
18
+ #define FIO_IGNORE_MACRO
19
+ #endif
20
+
21
+ /**
22
+ * Loads a mustache template, converting it into an opaque instruction array.
23
+ *
24
+ * Returns a pointer to the instruction array.
25
+ *
26
+ * The `folder` argument should contain the template's root folder which would
27
+ * also be used to search for any required partial templates.
28
+ *
29
+ * The `filename` argument should contain the template's file name.
30
+ */
31
+ mustache_s *fiobj_mustache_load(fio_str_info_s filename) {
32
+ return mustache_load(.filename = filename.data, .filename_len = filename.len);
33
+ }
34
+
35
+ /**
36
+ * Loads a mustache template, converting it into an opaque instruction array.
37
+ *
38
+ * Returns a pointer to the instruction array.
39
+ *
40
+ * The `folder` argument should contain the template's root folder which would
41
+ * also be used to search for any required partial templates.
42
+ *
43
+ * The `filename` argument should contain the template's file name.
44
+ */
45
+ mustache_s *fiobj_mustache_new FIO_IGNORE_MACRO(mustache_load_args_s args) {
46
+ return mustache_load FIO_IGNORE_MACRO(args);
47
+ }
48
+
49
+ /** Free the mustache template */
50
+ void fiobj_mustache_free(mustache_s *mustache) { mustache_free(mustache); }
51
+
52
+ /**
53
+ * Renders a template into an existing FIOBJ String (`dest`'s end), using the
54
+ * information in the `data` object.
55
+ *
56
+ * Returns FIOBJ_INVALID if an error occured and a FIOBJ String on success.
57
+ */
58
+ FIOBJ fiobj_mustache_build2(FIOBJ dest, mustache_s *mustache, FIOBJ data) {
59
+ mustache_build(mustache, .udata1 = (void *)dest, .udata2 = (void *)data);
60
+ return dest;
61
+ }
62
+
63
+ /**
64
+ * Creates a FIOBJ String containing the rendered template using the information
65
+ * in the `data` object.
66
+ *
67
+ * Returns FIOBJ_INVALID if an error occured and a FIOBJ String on success.
68
+ */
69
+ FIOBJ fiobj_mustache_build(mustache_s *mustache, FIOBJ data) {
70
+ if (!mustache)
71
+ return FIOBJ_INVALID;
72
+ return fiobj_mustache_build2(fiobj_str_buf(mustache->u.read_only.data_length),
73
+ mustache, data);
74
+ }
75
+
76
+ /* *****************************************************************************
77
+ Mustache Callbacks
78
+ ***************************************************************************** */
79
+
80
+ static inline FIOBJ fiobj_mustache_find_obj_absolute(FIOBJ parent, FIOBJ key) {
81
+ if (!FIOBJ_TYPE_IS(parent, FIOBJ_T_HASH))
82
+ return FIOBJ_INVALID;
83
+ FIOBJ o = FIOBJ_INVALID;
84
+ o = fiobj_hash_get(parent, key);
85
+ return o;
86
+ }
87
+
88
+ static inline FIOBJ fiobj_mustache_find_obj_tree(mustache_section_s *section,
89
+ const char *name,
90
+ uint32_t name_len) {
91
+ FIOBJ key = fiobj_str_tmp();
92
+ fiobj_str_write(key, name, name_len);
93
+ do {
94
+ FIOBJ tmp = fiobj_mustache_find_obj_absolute((FIOBJ)section->udata2, key);
95
+ if (tmp != FIOBJ_INVALID) {
96
+ return tmp;
97
+ }
98
+ } while ((section = mustache_section_parent(section)));
99
+ return FIOBJ_INVALID;
100
+ }
101
+
102
+ static inline FIOBJ fiobj_mustache_find_obj(mustache_section_s *section,
103
+ const char *name,
104
+ uint32_t name_len) {
105
+ FIOBJ tmp = fiobj_mustache_find_obj_tree(section, name, name_len);
106
+ if (tmp != FIOBJ_INVALID)
107
+ return tmp;
108
+ /* interpolate sections... */
109
+ uint32_t dot = 0;
110
+ while (dot < name_len && name[dot] != '.')
111
+ ++dot;
112
+ if (dot == name_len)
113
+ return FIOBJ_INVALID;
114
+ tmp = fiobj_mustache_find_obj_tree(section, name, dot);
115
+ if (!tmp) {
116
+ return FIOBJ_INVALID;
117
+ }
118
+ ++dot;
119
+ for (;;) {
120
+ FIOBJ key = fiobj_str_tmp();
121
+ fiobj_str_write(key, name + dot, name_len - dot);
122
+ FIOBJ obj = fiobj_mustache_find_obj_absolute(tmp, key);
123
+ if (obj != FIOBJ_INVALID)
124
+ return obj;
125
+ name += dot;
126
+ name_len -= dot;
127
+ dot = 0;
128
+ while (dot < name_len && name[dot] != '.')
129
+ ++dot;
130
+ if (dot == name_len) {
131
+ return FIOBJ_INVALID;
132
+ }
133
+ key = fiobj_str_tmp();
134
+ fiobj_str_write(key, name, dot);
135
+ tmp = fiobj_mustache_find_obj_absolute(tmp, key);
136
+ if (tmp == FIOBJ_INVALID)
137
+ return FIOBJ_INVALID;
138
+ ++dot;
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Called when an argument name was detected in the current section.
144
+ *
145
+ * A conforming implementation will search for the named argument both in the
146
+ * existing section and all of it's parents (walking backwards towards the root)
147
+ * until a value is detected.
148
+ *
149
+ * A missing value should be treated the same as an empty string.
150
+ *
151
+ * A conforming implementation will output the named argument's value (either
152
+ * HTML escaped or not, depending on the `escape` flag) as a string.
153
+ */
154
+ static int mustache_on_arg(mustache_section_s *section, const char *name,
155
+ uint32_t name_len, unsigned char escape) {
156
+ FIOBJ o = fiobj_mustache_find_obj(section, name, name_len);
157
+ if (!o)
158
+ return 0;
159
+ fio_str_info_s i = fiobj_obj2cstr(o);
160
+ if (!i.len)
161
+ return 0;
162
+ return mustache_write_text(section, i.data, i.len, escape);
163
+ }
164
+
165
+ /**
166
+ * Called when simple template text (string) is detected.
167
+ *
168
+ * A conforming implementation will output data as a string (no escaping).
169
+ */
170
+ static int mustache_on_text(mustache_section_s *section, const char *data,
171
+ uint32_t data_len) {
172
+ FIOBJ dest = (FIOBJ)section->udata1;
173
+ fiobj_str_write(dest, data, data_len);
174
+ return 0;
175
+ }
176
+
177
+ /**
178
+ * Called for nested sections, must return the number of objects in the new
179
+ * subsection (depending on the argument's name).
180
+ *
181
+ * Arrays should return the number of objects in the array.
182
+ *
183
+ * `true` values should return 1.
184
+ *
185
+ * `false` values should return 0.
186
+ *
187
+ * A return value of -1 will stop processing with an error.
188
+ *
189
+ * Please note, this will handle both normal and inverted sections.
190
+ */
191
+ static int32_t mustache_on_section_test(mustache_section_s *section,
192
+ const char *name, uint32_t name_len,
193
+ uint8_t callable) {
194
+ FIOBJ o = fiobj_mustache_find_obj(section, name, name_len);
195
+ if (!o || FIOBJ_TYPE_IS(o, FIOBJ_T_FALSE))
196
+ return 0;
197
+ if (FIOBJ_TYPE_IS(o, FIOBJ_T_ARRAY))
198
+ return fiobj_ary_count(o);
199
+ return 1;
200
+ (void)callable; /* FIOBJ doesn't support lambdas */
201
+ }
202
+
203
+ /**
204
+ * Called when entering a nested section.
205
+ *
206
+ * `index` is a zero based index indicating the number of repetitions that
207
+ * occurred so far (same as the array index for arrays).
208
+ *
209
+ * A return value of -1 will stop processing with an error.
210
+ *
211
+ * Note: this is a good time to update the subsection's `udata` with the value
212
+ * of the array index. The `udata` will always contain the value or the parent's
213
+ * `udata`.
214
+ */
215
+ static int mustache_on_section_start(mustache_section_s *section,
216
+ char const *name, uint32_t name_len,
217
+ uint32_t index) {
218
+ FIOBJ o = fiobj_mustache_find_obj(section, name, name_len);
219
+ if (!o)
220
+ return -1;
221
+ if (FIOBJ_TYPE_IS(o, FIOBJ_T_ARRAY))
222
+ section->udata2 = (void *)fiobj_ary_index(o, index);
223
+ else
224
+ section->udata2 = (void *)o;
225
+ return 0;
226
+ }
227
+
228
+ /**
229
+ * Called for cleanup in case of error.
230
+ */
231
+ static void mustache_on_formatting_error(void *udata1, void *udata2) {
232
+ (void)udata1;
233
+ (void)udata2;
234
+ }
235
+
236
+ /* *****************************************************************************
237
+ Testing
238
+ ***************************************************************************** */
239
+
240
+ #if DEBUG
241
+ static inline void mustache_save2file(char const *filename, char const *data,
242
+ size_t length) {
243
+ #ifdef __MINGW32__
244
+ int fd = _open(filename, _O_CREAT | _O_RDWR);
245
+ #else
246
+ int fd = open(filename, O_CREAT | O_RDWR, 0);
247
+ #endif
248
+ if (fd == -1) {
249
+ perror("Couldn't open / create file for template testing");
250
+ exit(-1);
251
+ }
252
+ #ifdef __MINGW32__
253
+ _chmod(filename, _S_IREAD | _S_IWRITE);
254
+ #else
255
+ fchmod(fd, 0777);
256
+ #endif
257
+ if (pwrite(fd, data, length, 0) != (ssize_t)length) {
258
+ perror("Mustache template write error");
259
+ exit(-1);
260
+ }
261
+ close(fd);
262
+ }
263
+
264
+ void fiobj_mustache_test(void) {
265
+ #define TEST_ASSERT(cond, ...) \
266
+ if (!(cond)) { \
267
+ fprintf(stderr, "* " __VA_ARGS__); \
268
+ fprintf(stderr, "\n !!! Testing failed !!!\n"); \
269
+ exit(-1); \
270
+ }
271
+
272
+ char const *template =
273
+ "{{=<< >>=}}* Users:\r\n<<#users>><<id>>. <<& name>> "
274
+ "(<<name>>)\r\n<</users>>\r\nNested: <<& nested.item >>.";
275
+ char const *template_name = "mustache_test_template.mustache";
276
+ fprintf(stderr, "mustache test saving template %s\n", template_name);
277
+ mustache_save2file(template_name, template, strlen(template));
278
+ mustache_s *m =
279
+ fiobj_mustache_load((fio_str_info_s){.data = (char *)template_name});
280
+ unlink(template_name);
281
+ TEST_ASSERT(m, "fiobj_mustache_load failed.\n");
282
+ FIOBJ data = fiobj_hash_new();
283
+ FIOBJ key = fiobj_str_new("users", 5);
284
+ FIOBJ ary = fiobj_ary_new2(4);
285
+ fiobj_hash_set(data, key, ary);
286
+ fiobj_free(key);
287
+ for (int i = 0; i < 4; ++i) {
288
+ FIOBJ id = fiobj_str_buf(4);
289
+ fiobj_str_write_i(id, i);
290
+ FIOBJ name = fiobj_str_buf(4);
291
+ fiobj_str_write(name, "User ", 5);
292
+ fiobj_str_write_i(name, i);
293
+ FIOBJ usr = fiobj_hash_new2(2);
294
+ key = fiobj_str_new("id", 2);
295
+ fiobj_hash_set(usr, key, id);
296
+ fiobj_free(key);
297
+ key = fiobj_str_new("name", 4);
298
+ fiobj_hash_set(usr, key, name);
299
+ fiobj_free(key);
300
+ fiobj_ary_push(ary, usr);
301
+ }
302
+ key = fiobj_str_new("nested", 6);
303
+ ary = fiobj_hash_new2(2);
304
+ fiobj_hash_set(data, key, ary);
305
+ fiobj_free(key);
306
+ key = fiobj_str_new("item", 4);
307
+ fiobj_hash_set(ary, key, fiobj_str_new("dot notation success", 20));
308
+ fiobj_free(key);
309
+ key = fiobj_mustache_build(m, data);
310
+ fiobj_free(data);
311
+ TEST_ASSERT(key, "fiobj_mustache_build failed!\n");
312
+ fprintf(stderr, "%s\n", fiobj_obj2cstr(key).data);
313
+ fiobj_free(key);
314
+ fiobj_mustache_free(m);
315
+ }
316
+
317
+ #endif
@@ -0,0 +1,62 @@
1
+ /*
2
+ Copyright: Boaz Segev, 2018-2019
3
+ License: MIT
4
+ */
5
+ #ifndef H_FIOBJ_MUSTACHE_H
6
+ #define H_FIOBJ_MUSTACHE_H
7
+
8
+ #include <fiobject.h>
9
+
10
+ #include <mustache_parser.h>
11
+
12
+ /**
13
+ * Loads a mustache template, converting it into an opaque instruction array.
14
+ *
15
+ * Returns a pointer to the instruction array or NULL (on error).
16
+ *
17
+ * The `filename` argument should contain the template's file name.
18
+ */
19
+ mustache_s *fiobj_mustache_load(fio_str_info_s filename);
20
+
21
+ /**
22
+ * Loads a mustache template, either from memory of a file, converting it into
23
+ * an opaque instruction array.
24
+ *
25
+ * Returns a pointer to the instruction array or NULL (on error).
26
+ *
27
+ * Accepts any of the following named arguments:
28
+ * * `char const *filename` - The root template's file name.
29
+ * * `size_t filename_len` - The file name's length.
30
+ * * `char const *data` - If set, will be used as the file's contents.
31
+ * * `size_t data_len` - If set, `data` will be used as the file's contents.
32
+ * * `mustache_error_en *err` - A container for any template load errors (see
33
+ * mustache_parser.h).
34
+ */
35
+ mustache_s *fiobj_mustache_new(mustache_load_args_s args);
36
+ #define fiobj_mustache_new(...) \
37
+ fiobj_mustache_new((mustache_load_args_s){__VA_ARGS__})
38
+
39
+ /** Free the mustache template */
40
+ void fiobj_mustache_free(mustache_s *mustache);
41
+
42
+ /**
43
+ * Creates a FIOBJ String containing the rendered template using the information
44
+ * in the `data` object.
45
+ *
46
+ * Returns FIOBJ_INVALID if an error occurred and a FIOBJ String on success.
47
+ */
48
+ FIOBJ fiobj_mustache_build(mustache_s *mustache, FIOBJ data);
49
+
50
+ /**
51
+ * Renders a template into an existing FIOBJ String (`dest`'s end), using the
52
+ * information in the `data` object.
53
+ *
54
+ * Returns FIOBJ_INVALID if an error occurred and a FIOBJ String on success.
55
+ */
56
+ FIOBJ fiobj_mustache_build2(FIOBJ dest, mustache_s *mustache, FIOBJ data);
57
+
58
+ #if DEBUG
59
+ void fiobj_mustache_test(void);
60
+ #endif
61
+
62
+ #endif /* H_FIOBJ_MUSTACHE_H */