yeptris 0.6.59.1-arm-linux-eabihf → 0.6.61.1-arm-linux-eabihf
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.
- checksums.yaml +4 -4
- data/ext/yeptris_native/version.h +2 -2
- data/lib/yeptris/3.4/native.so +0 -0
- data/lib/yeptris/ffi.rb +19 -0
- data/lib/yeptris/yaml.rb +71 -0
- data/lib/yeptris.rb +1 -1
- data/libyeptris.so +0 -0
- data/vendor/libyeptris/CMakeLists.txt +1 -1
- data/vendor/libyeptris/src/CMakeLists.txt +7 -0
- data/vendor/libyeptris/src/include/yeptris/emit.h +30 -2
- data/vendor/libyeptris/src/include/yeptris/parse.h +73 -0
- data/vendor/libyeptris/src/include/yeptris/resolve.h +8 -0
- data/vendor/libyeptris/src/include/yeptris/validate.h +222 -21
- data/vendor/libyeptris/src/include/yeptris/values.h +8 -2
- data/vendor/libyeptris/src/yeptris/cbor/cbor.h +10 -0
- data/vendor/libyeptris/src/yeptris/cbor/decode.c +5 -7
- data/vendor/libyeptris/src/yeptris/cbor/encode.c +9 -9
- data/vendor/libyeptris/src/yeptris/cbor/from_marshal.c +1 -1
- data/vendor/libyeptris/src/yeptris/common/error.h +2 -0
- data/vendor/libyeptris/src/yeptris/doc.h +20 -0
- data/vendor/libyeptris/src/yeptris/dom/dom.c +12 -1
- data/vendor/libyeptris/src/yeptris/dom/ytape.c +56 -7
- data/vendor/libyeptris/src/yeptris/emit/emit.c +93 -13
- data/vendor/libyeptris/src/yeptris/emit/writer.c +243 -652
- data/vendor/libyeptris/src/yeptris/emit/writer.h +25 -8
- data/vendor/libyeptris/src/yeptris/events/push.c +28 -3
- data/vendor/libyeptris/src/yeptris/events/values.c +46 -0
- data/vendor/libyeptris/src/yeptris/marshal/to_json.c +650 -0
- data/vendor/libyeptris/src/yeptris/parse/engine.c +611 -130
- data/vendor/libyeptris/src/yeptris/parse/engine.h +5 -0
- data/vendor/libyeptris/src/yeptris/parse/stream_iter.c +358 -0
- data/vendor/libyeptris/src/yeptris/parse.c +216 -44
- data/vendor/libyeptris/src/yeptris/resolve/compat11.c +3 -6
- data/vendor/libyeptris/src/yeptris/resolve/core12.c +11 -3
- data/vendor/libyeptris/src/yeptris/resolve/full12.c +201 -0
- data/vendor/libyeptris/src/yeptris/resolve/json12.c +12 -6
- data/vendor/libyeptris/src/yeptris/resolve/resolver.h +38 -0
- data/vendor/libyeptris/src/yeptris/resolve/tags.c +192 -0
- data/vendor/libyeptris/src/yeptris/scan/scan.c +22 -7
- data/vendor/libyeptris/src/yeptris/tape.c +24 -5
- data/vendor/libyeptris/src/yeptris/validate/compile.c +39 -3
- data/vendor/libyeptris/src/yeptris/validate/internal.h +223 -7
- data/vendor/libyeptris/src/yeptris/validate/jsonschema.c +645 -115
- data/vendor/libyeptris/src/yeptris/validate/output.c +246 -0
- data/vendor/libyeptris/src/yeptris/validate/regexp.c +623 -157
- data/vendor/libyeptris/src/yeptris/validate/registry.c +118 -0
- data/vendor/libyeptris/src/yeptris/validate/resources.c +601 -0
- data/vendor/libyeptris/src/yeptris/validate/stream.c +1155 -0
- data/vendor/libyeptris/src/yeptris/validate/validate.c +288 -145
- metadata +8 -1
|
@@ -53,6 +53,11 @@ int yep_engine_step(yep_engine* e, const char* chunk, size_t len, int final, con
|
|
|
53
53
|
* allocates a fresh one if reused). Returns NULL when absent. */
|
|
54
54
|
yep_pool* yep_engine_detach_pool(yep_engine* e);
|
|
55
55
|
|
|
56
|
+
/* Detaches the run's break-normalizer copy (ownership moves to the
|
|
57
|
+
* caller; the caller owns the returned buffer once detached). Returns
|
|
58
|
+
* NULL when the run kept the input zero-copy. */
|
|
59
|
+
char* yep_engine_detach_norm_buf(yep_engine* e, size_t* len_out);
|
|
60
|
+
|
|
56
61
|
/* Implicit-typing schema for the next run (NULL: 1.2 core), and the
|
|
57
62
|
* runtime nesting limit. */
|
|
58
63
|
struct yep_resolver;
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
/* stream_iter.c — tolerant per-document stream iteration (#921).
|
|
2
|
+
*
|
|
3
|
+
* The load_stream contract parses the whole stream and returns nothing
|
|
4
|
+
* when any document fails; consumers that must keep the valid
|
|
5
|
+
* documents of a stream cannot use the engine for recovery. This
|
|
6
|
+
* iterator frames documents ENGINE-SIDE (the abort-at-DOCUMENT_END
|
|
7
|
+
* run iterparse uses — scanner-accurate: a quoted scalar spanning a
|
|
8
|
+
* line that looks like a marker never splits) and reports failures
|
|
9
|
+
* per document: on a parse-class error the iterator records that
|
|
10
|
+
* document's verdict (the engine's line/col, which ARE the failed
|
|
11
|
+
* document's own — each run starts at the frame) and resyncs to the
|
|
12
|
+
* next line-start marker, so the host keeps the valid documents.
|
|
13
|
+
*
|
|
14
|
+
* The resync after a FAILURE is a raw marker scan: the failed
|
|
15
|
+
* document's tail is ill-formed by definition, so the scanner-grade
|
|
16
|
+
* framing above no longer has a well-defined subject; the raw scan is
|
|
17
|
+
* the libyaml-familiar best effort and only ever runs on the recovery
|
|
18
|
+
* path (valid documents never hit it).
|
|
19
|
+
*
|
|
20
|
+
* Cost note: each document parses twice (the boundary run + the slice
|
|
21
|
+
* parse). The tolerance contract is the point; a single-pass upgrade
|
|
22
|
+
* rides on the same sink seam when a workload demands it. */
|
|
23
|
+
|
|
24
|
+
#include <stdlib.h>
|
|
25
|
+
#include <string.h>
|
|
26
|
+
|
|
27
|
+
#include "../../include/yeptris/dom.h"
|
|
28
|
+
#include "../../include/yeptris/parse.h"
|
|
29
|
+
#include "../common/error.h"
|
|
30
|
+
#include "../common/simd_text.h"
|
|
31
|
+
#include "../encoding/encoding.h"
|
|
32
|
+
#include "../memory/allocator.h"
|
|
33
|
+
#include "../resolve/resolver.h"
|
|
34
|
+
#include "doc.h"
|
|
35
|
+
#include "engine.h"
|
|
36
|
+
|
|
37
|
+
/* The boundary finder: a sink that aborts the run at the first
|
|
38
|
+
* DOCUMENT_END (iterparse's law — the marker line stays unconsumed
|
|
39
|
+
* and doubles as the next document's start). Events are discarded;
|
|
40
|
+
* the run's pos IS the document's end offset. */
|
|
41
|
+
typedef struct {
|
|
42
|
+
int doc_ends;
|
|
43
|
+
} frame_sink;
|
|
44
|
+
|
|
45
|
+
static int frame_on_event(void* ctx, const yep_event* ev) {
|
|
46
|
+
frame_sink* s = (frame_sink*)ctx;
|
|
47
|
+
if (ev->type == YEP_EV_DOCUMENT_END) {
|
|
48
|
+
s->doc_ends++;
|
|
49
|
+
return 1; /* abort: the document is complete */
|
|
50
|
+
}
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
struct yeptris_stream_iter {
|
|
55
|
+
const char* buf;
|
|
56
|
+
size_t len;
|
|
57
|
+
size_t cursor;
|
|
58
|
+
int done;
|
|
59
|
+
int gated; /* the encoding front-end ran once (iterparse's
|
|
60
|
+
* law: after it, cursor and engine pos live in
|
|
61
|
+
* the same buffer space) */
|
|
62
|
+
unsigned char* owned; /* UTF-16/32 transcode output */
|
|
63
|
+
char* norm; /* NEL/LS/PS-normalized copy */
|
|
64
|
+
const YeptrisParseOptions* opts; /* borrowed */
|
|
65
|
+
size_t index; /* 0-based stream document index (errors consume
|
|
66
|
+
* one too — the host's yield order is the stream's) */
|
|
67
|
+
YeptrisStatus last_status; /* the LAST next()'s per-document verdict */
|
|
68
|
+
uint32_t last_line;
|
|
69
|
+
uint32_t last_col;
|
|
70
|
+
size_t last_off; /* the last SUCCESSFUL document's slice
|
|
71
|
+
* in the (post-gate) buffer space */
|
|
72
|
+
size_t last_len;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
yeptris_stream_iter* yeptris_stream_iter_new(const char* buf, size_t len,
|
|
76
|
+
const YeptrisParseOptions* opts) {
|
|
77
|
+
if (buf == NULL && len != 0) {
|
|
78
|
+
return NULL;
|
|
79
|
+
}
|
|
80
|
+
struct yeptris_stream_iter* it = calloc(1, sizeof(*it));
|
|
81
|
+
if (it == NULL) {
|
|
82
|
+
return NULL;
|
|
83
|
+
}
|
|
84
|
+
it->buf = buf;
|
|
85
|
+
it->len = len;
|
|
86
|
+
it->opts = opts;
|
|
87
|
+
return it;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* The resync: the next line-start marker (--- / ...) followed by
|
|
91
|
+
* space, break, or EOF — the c-forbidden lookahead. Raw bytes: the
|
|
92
|
+
* recovery path's best effort (see the file comment). The scan starts
|
|
93
|
+
* AFTER the failed frame's first line: the frame opened at `from`'s
|
|
94
|
+
* line, and the engine's failure pos can sit at EOF (the run scans to
|
|
95
|
+
* the end before reporting), so anchoring on `from` itself is the only
|
|
96
|
+
* stable reference. */
|
|
97
|
+
static size_t next_marker(const char* p, size_t len, size_t from) {
|
|
98
|
+
size_t i = from;
|
|
99
|
+
while (i < len && p[i] != '\n' && p[i] != '\r') {
|
|
100
|
+
i++;
|
|
101
|
+
}
|
|
102
|
+
if (i < len) {
|
|
103
|
+
i++;
|
|
104
|
+
}
|
|
105
|
+
int line_start = 1;
|
|
106
|
+
while (i < len) {
|
|
107
|
+
char ch = p[i];
|
|
108
|
+
if (ch == '\n' || ch == '\r') {
|
|
109
|
+
line_start = 1;
|
|
110
|
+
i++;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (line_start && ch == '-' && i + 2 < len && p[i + 1] == '-' && p[i + 2] == '-' &&
|
|
114
|
+
(i + 3 == len || p[i + 3] == ' ' || p[i + 3] == '\n' || p[i + 3] == '\r' ||
|
|
115
|
+
p[i + 3] == '\t')) {
|
|
116
|
+
return i;
|
|
117
|
+
}
|
|
118
|
+
if (line_start && ch == '.' && i + 2 < len && p[i + 1] == '.' && p[i + 2] == '.' &&
|
|
119
|
+
(i + 3 == len || p[i + 3] == ' ' || p[i + 3] == '\n' || p[i + 3] == '\r' ||
|
|
120
|
+
p[i + 3] == '\t')) {
|
|
121
|
+
return i;
|
|
122
|
+
}
|
|
123
|
+
line_start = 0;
|
|
124
|
+
i++;
|
|
125
|
+
}
|
|
126
|
+
return len; /* no marker: the tail is unrecoverable */
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
static void it_fail(struct yeptris_stream_iter* it, YeptrisStatus st, uint32_t line, uint32_t col) {
|
|
130
|
+
it->last_status = st;
|
|
131
|
+
it->last_line = line;
|
|
132
|
+
it->last_col = col;
|
|
133
|
+
it->last_len = 0; /* the slice accessor must not serve a stale frame
|
|
134
|
+
* (the success path sets off/len right after) */
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static int engine_opts(yep_engine* eng, const YeptrisParseOptions* opts) {
|
|
138
|
+
/* the typing SSOT: one switch (parse.c owns it) */
|
|
139
|
+
YeptrisSchema schema = opts != NULL ? opts->schema : YEPTRIS_SCHEMA_12_CORE;
|
|
140
|
+
yep_engine_set_resolver(eng, resolver_for_schema(schema));
|
|
141
|
+
if (opts != NULL && opts->schema == YEPTRIS_SCHEMA_11_COMPAT) {
|
|
142
|
+
/* the compat grammar is the psych/libyaml surface (parse_impl's
|
|
143
|
+
* law) */
|
|
144
|
+
yep_engine_set_compat_grammar(eng, 1);
|
|
145
|
+
}
|
|
146
|
+
if (opts != NULL && opts->max_depth > 0) {
|
|
147
|
+
yep_engine_set_max_depth(eng, opts->max_depth);
|
|
148
|
+
}
|
|
149
|
+
return 0;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
YeptrisStatus yeptris_stream_iter_next(struct yeptris_stream_iter* it, YeptrisDocument* out,
|
|
153
|
+
size_t* index) {
|
|
154
|
+
if (it == NULL || out == NULL) {
|
|
155
|
+
return YEPTRIS_ERROR_ARG;
|
|
156
|
+
}
|
|
157
|
+
*out = NULL;
|
|
158
|
+
if (index != NULL) {
|
|
159
|
+
*index = it->index;
|
|
160
|
+
}
|
|
161
|
+
for (;;) {
|
|
162
|
+
/* the encoding front-end, ONCE (iterparse's gate law: BOM
|
|
163
|
+
* strip, UTF-16/32 transcode, NEL/LS/PS normalization — cursor
|
|
164
|
+
* and engine pos must live in one buffer space or the resume
|
|
165
|
+
* arithmetic corrupts slices) */
|
|
166
|
+
if (!it->gated) {
|
|
167
|
+
it->gated = 1;
|
|
168
|
+
const yep_allocator* sys = yep_system_allocator();
|
|
169
|
+
yep_encoding enc = YEP_ENC_UNKNOWN;
|
|
170
|
+
size_t bom = yep_bom_sniff((const unsigned char*)it->buf, it->len, &enc);
|
|
171
|
+
if (enc == YEP_ENC_UTF16LE || enc == YEP_ENC_UTF16BE || enc == YEP_ENC_UTF32LE ||
|
|
172
|
+
enc == YEP_ENC_UTF32BE) {
|
|
173
|
+
size_t tlen = 0;
|
|
174
|
+
size_t terr = 0;
|
|
175
|
+
unsigned char* owned = NULL;
|
|
176
|
+
int rc = yep_transcode_to_utf8(sys, enc, (const unsigned char*)it->buf + bom,
|
|
177
|
+
it->len - bom, &owned, &tlen, &terr);
|
|
178
|
+
if (rc != 0) {
|
|
179
|
+
it->done = 1;
|
|
180
|
+
it_fail(it, YEPTRIS_ERROR_ENCODING, 1, 1);
|
|
181
|
+
return YEPTRIS_ERROR_ENCODING;
|
|
182
|
+
}
|
|
183
|
+
it->owned = owned;
|
|
184
|
+
it->buf = (const char*)owned;
|
|
185
|
+
it->len = tlen;
|
|
186
|
+
it->cursor = 0;
|
|
187
|
+
} else {
|
|
188
|
+
it->cursor = bom;
|
|
189
|
+
}
|
|
190
|
+
size_t nlen = 0;
|
|
191
|
+
int kept_raw = 0;
|
|
192
|
+
char* norm = yep_engine_normalize_breaks(sys, it->buf + it->cursor,
|
|
193
|
+
it->len - it->cursor, &nlen, &kept_raw);
|
|
194
|
+
if (norm != NULL) {
|
|
195
|
+
it->norm = norm;
|
|
196
|
+
it->buf = norm;
|
|
197
|
+
it->len = nlen;
|
|
198
|
+
it->cursor = 0;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (it->done) {
|
|
202
|
+
it_fail(it, YEPTRIS_OK, 0, 0);
|
|
203
|
+
return YEPTRIS_OK; /* *out stays NULL: the stream is over */
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/* one boundary run: abort at DOCUMENT_END, learn the extent */
|
|
207
|
+
frame_sink fs = {0};
|
|
208
|
+
yep_engine* eng = yep_engine_create(yep_system_allocator());
|
|
209
|
+
if (eng == NULL) {
|
|
210
|
+
it->done = 1;
|
|
211
|
+
it_fail(it, YEPTRIS_ERROR_MEMORY, 0, 0);
|
|
212
|
+
return YEPTRIS_ERROR_MEMORY;
|
|
213
|
+
}
|
|
214
|
+
engine_opts(eng, it->opts);
|
|
215
|
+
yep_sink sink = {.on_event = frame_on_event,
|
|
216
|
+
.ctx = &fs,
|
|
217
|
+
.on_flow_build = NULL,
|
|
218
|
+
.on_flow_commit = NULL,
|
|
219
|
+
.on_flow_rollback = NULL,
|
|
220
|
+
.on_block_pair = NULL,
|
|
221
|
+
.on_block_open = NULL,
|
|
222
|
+
.on_block_item = NULL};
|
|
223
|
+
yep_text_stats pst;
|
|
224
|
+
yep_text_active()->scan_stats(it->buf + it->cursor, it->len - it->cursor, &pst);
|
|
225
|
+
yep_engine_prepare(eng, &pst);
|
|
226
|
+
int rc = yep_engine_run(eng, it->buf + it->cursor, it->len - it->cursor, &sink);
|
|
227
|
+
size_t pos = yep_engine_pos(eng);
|
|
228
|
+
yep_err_code err_code = YEP_ERR_NONE;
|
|
229
|
+
uint32_t err_line = 0, err_col = 0;
|
|
230
|
+
{
|
|
231
|
+
const yep_error* err = yep_engine_error(eng);
|
|
232
|
+
if (err != NULL) {
|
|
233
|
+
err_code = err->code;
|
|
234
|
+
err_line = err->line;
|
|
235
|
+
err_col = err->col;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
yep_engine_destroy(eng);
|
|
239
|
+
|
|
240
|
+
if (rc == -1 && (err_code == YEP_ERR_MEMORY || err_code == YEP_ERR_ENCODING)) {
|
|
241
|
+
/* the stream-fatal classes: the arena state is unknown
|
|
242
|
+
* (memory) or the front-end's space is broken (encoding —
|
|
243
|
+
* it gated once, so this cannot be a per-document miss) */
|
|
244
|
+
it->done = 1;
|
|
245
|
+
it_fail(it, err_code == YEP_ERR_MEMORY ? YEPTRIS_ERROR_MEMORY : YEPTRIS_ERROR_ENCODING,
|
|
246
|
+
err_line, err_col);
|
|
247
|
+
return it->last_status;
|
|
248
|
+
}
|
|
249
|
+
if (rc == -1 || (rc != 0 && fs.doc_ends == 0)) {
|
|
250
|
+
/* THIS document failed (parse-class or the run died before
|
|
251
|
+
* any document completed): report the per-document verdict
|
|
252
|
+
* — the run started at the frame, so the engine's line/col
|
|
253
|
+
* ARE the failed document's own — then resync to the next
|
|
254
|
+
* marker and keep going */
|
|
255
|
+
it_fail(it, err_code == YEP_ERR_DEPTH ? YEPTRIS_ERROR_DEPTH : YEPTRIS_ERROR_PARSE,
|
|
256
|
+
err_line, err_col);
|
|
257
|
+
size_t at = next_marker(it->buf, it->len, it->cursor);
|
|
258
|
+
if (at >= it->len) {
|
|
259
|
+
it->done = 1; /* the tail is unrecoverable */
|
|
260
|
+
} else {
|
|
261
|
+
it->cursor = at;
|
|
262
|
+
}
|
|
263
|
+
it->index++;
|
|
264
|
+
if (index != NULL) {
|
|
265
|
+
*index = it->index - 1;
|
|
266
|
+
}
|
|
267
|
+
return it->last_status; /* *out stays NULL: the failed slot */
|
|
268
|
+
}
|
|
269
|
+
if (fs.doc_ends == 0) {
|
|
270
|
+
/* natural end or a blank tail: the stream is over */
|
|
271
|
+
it->done = 1;
|
|
272
|
+
it_fail(it, YEPTRIS_OK, 0, 0);
|
|
273
|
+
return YEPTRIS_OK;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/* the frame is [cursor, cursor+pos): parse it as ONE document
|
|
277
|
+
* (the slice's own marker or bare content rides parse_ex's
|
|
278
|
+
* contract; the default tape route is what load uses) */
|
|
279
|
+
YeptrisStatus st = YEPTRIS_OK;
|
|
280
|
+
YeptrisDocument doc = yeptris_parse_ex(it->buf + it->cursor, pos, it->opts, &st);
|
|
281
|
+
if (doc == NULL || st != YEPTRIS_OK) {
|
|
282
|
+
/* the boundary run accepted what the slice parse refused:
|
|
283
|
+
* report as a failed document and resync the same way */
|
|
284
|
+
it_fail(it, st == YEPTRIS_OK ? YEPTRIS_ERROR_PARSE : st, 0, 0);
|
|
285
|
+
yeptris_document_free(doc);
|
|
286
|
+
size_t at = next_marker(it->buf, it->len, it->cursor);
|
|
287
|
+
if (at >= it->len) {
|
|
288
|
+
it->done = 1;
|
|
289
|
+
} else {
|
|
290
|
+
it->cursor = at;
|
|
291
|
+
}
|
|
292
|
+
it->index++;
|
|
293
|
+
if (index != NULL) {
|
|
294
|
+
*index = it->index - 1;
|
|
295
|
+
}
|
|
296
|
+
return it->last_status;
|
|
297
|
+
}
|
|
298
|
+
it_fail(it, YEPTRIS_OK, 0, 0);
|
|
299
|
+
it->last_off = it->cursor;
|
|
300
|
+
it->last_len = pos;
|
|
301
|
+
it->cursor += pos;
|
|
302
|
+
it->index++;
|
|
303
|
+
if (index != NULL) {
|
|
304
|
+
*index = it->index - 1;
|
|
305
|
+
}
|
|
306
|
+
*out = doc;
|
|
307
|
+
return YEPTRIS_OK;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
YeptrisStatus yeptris_stream_iter_status(const struct yeptris_stream_iter* it, uint32_t* line,
|
|
312
|
+
uint32_t* col) {
|
|
313
|
+
if (it == NULL) {
|
|
314
|
+
return YEPTRIS_ERROR_ARG;
|
|
315
|
+
}
|
|
316
|
+
if (line != NULL) {
|
|
317
|
+
*line = it->last_line;
|
|
318
|
+
}
|
|
319
|
+
if (col != NULL) {
|
|
320
|
+
*col = it->last_col;
|
|
321
|
+
}
|
|
322
|
+
return it->last_status;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/* The last successful document's slice (parse.h): the host's value
|
|
326
|
+
* route re-parses exactly these bytes — one typing SSOT. */
|
|
327
|
+
YeptrisStatus yeptris_stream_iter_slice(const struct yeptris_stream_iter* it, size_t* off,
|
|
328
|
+
size_t* len) {
|
|
329
|
+
if (it == NULL || off == NULL || len == NULL) {
|
|
330
|
+
return YEPTRIS_ERROR_ARG;
|
|
331
|
+
}
|
|
332
|
+
if (it->last_status != YEPTRIS_OK || it->last_len == 0) {
|
|
333
|
+
return YEPTRIS_ERROR_ARG; /* a failure or the stream end was the last step */
|
|
334
|
+
}
|
|
335
|
+
*off = it->last_off;
|
|
336
|
+
*len = it->last_len;
|
|
337
|
+
return YEPTRIS_OK;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
YeptrisStatus yeptris_stream_iter_buffer(const struct yeptris_stream_iter* it, const char** buf,
|
|
341
|
+
size_t* len) {
|
|
342
|
+
if (it == NULL || buf == NULL || len == NULL) {
|
|
343
|
+
return YEPTRIS_ERROR_ARG;
|
|
344
|
+
}
|
|
345
|
+
*buf = it->buf;
|
|
346
|
+
*len = it->len;
|
|
347
|
+
return YEPTRIS_OK;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
void yeptris_stream_iter_free(struct yeptris_stream_iter* it) {
|
|
351
|
+
if (it == NULL) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const yep_allocator* sys = yep_system_allocator();
|
|
355
|
+
yep_free(sys, it->owned);
|
|
356
|
+
yep_free(sys, it->norm);
|
|
357
|
+
free(it);
|
|
358
|
+
}
|