yeptris 0.6.18.2-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 +7 -0
- data/README.adoc +141 -0
- data/ext/build_windows_native.rb +41 -0
- data/ext/libyeptris/extconf.rb +57 -0
- data/ext/yeptris_native/cbor_ruby.c +193 -0
- data/ext/yeptris_native/extconf.rb +47 -0
- data/ext/yeptris_native/json_ruby.c +354 -0
- data/ext/yeptris_native/yeptris_native.c +497 -0
- data/lib/yeptris/cbor.rb +130 -0
- data/lib/yeptris/document.rb +255 -0
- data/lib/yeptris/ffi.rb +426 -0
- data/lib/yeptris/json/descriptor.rb +266 -0
- data/lib/yeptris/json.rb +394 -0
- data/lib/yeptris/materializer.rb +354 -0
- data/lib/yeptris/native-3.4.so +0 -0
- data/lib/yeptris/node.rb +453 -0
- data/lib/yeptris/psych/class_loader.rb +24 -0
- data/lib/yeptris/psych/coder_shim.rb +55 -0
- data/lib/yeptris/psych/drop_in.rb +63 -0
- data/lib/yeptris/psych/encodable.rb +14 -0
- data/lib/yeptris/psych/handler.rb +90 -0
- data/lib/yeptris/psych/parser.rb +105 -0
- data/lib/yeptris/psych/scalar_scanner.rb +149 -0
- data/lib/yeptris/psych/visitors.rb +545 -0
- data/lib/yeptris/psych.rb +622 -0
- data/lib/yeptris/schema.rb +253 -0
- data/lib/yeptris/valueml.rb +455 -0
- data/lib/yeptris/yaml/descriptor.rb +56 -0
- data/lib/yeptris/yaml.rb +422 -0
- data/lib/yeptris.rb +113 -0
- data/libyeptris.so +0 -0
- data/vendor/libyeptris/CMakeLists.txt +254 -0
- data/vendor/libyeptris/cmake/yeptris-config.cmake.in +5 -0
- data/vendor/libyeptris/cmake/yeptris.pc.in +11 -0
- data/vendor/libyeptris/src/CMakeLists.txt +167 -0
- data/vendor/libyeptris/src/include/yeptris/api.h +32 -0
- data/vendor/libyeptris/src/include/yeptris/cbor.h +101 -0
- data/vendor/libyeptris/src/include/yeptris/dom.h +190 -0
- data/vendor/libyeptris/src/include/yeptris/emit.h +81 -0
- data/vendor/libyeptris/src/include/yeptris/error.h +41 -0
- data/vendor/libyeptris/src/include/yeptris/events.h +157 -0
- data/vendor/libyeptris/src/include/yeptris/json.h +45 -0
- data/vendor/libyeptris/src/include/yeptris/json.hpp +258 -0
- data/vendor/libyeptris/src/include/yeptris/jsonc_compat.h +115 -0
- data/vendor/libyeptris/src/include/yeptris/marshal.h +52 -0
- data/vendor/libyeptris/src/include/yeptris/parse.h +48 -0
- data/vendor/libyeptris/src/include/yeptris/plan.h +100 -0
- data/vendor/libyeptris/src/include/yeptris/resolve.h +71 -0
- data/vendor/libyeptris/src/include/yeptris/schema.h +121 -0
- data/vendor/libyeptris/src/include/yeptris/tape.h +123 -0
- data/vendor/libyeptris/src/include/yeptris/types.h +38 -0
- data/vendor/libyeptris/src/include/yeptris/values.h +102 -0
- data/vendor/libyeptris/src/include/yeptris/version.h.in +29 -0
- data/vendor/libyeptris/src/include/yeptris/visit.h +77 -0
- data/vendor/libyeptris/src/include/yeptris/yajl_compat.h +135 -0
- data/vendor/libyeptris/src/include/yeptris.h +23 -0
- data/vendor/libyeptris/src/yeptris/build.c +376 -0
- data/vendor/libyeptris/src/yeptris/cbor/cbor.h +25 -0
- data/vendor/libyeptris/src/yeptris/cbor/decode.c +981 -0
- data/vendor/libyeptris/src/yeptris/cbor/encode.c +835 -0
- data/vendor/libyeptris/src/yeptris/cbor/sink.h +58 -0
- data/vendor/libyeptris/src/yeptris/common/chartype.c +41 -0
- data/vendor/libyeptris/src/yeptris/common/chartype.h +77 -0
- data/vendor/libyeptris/src/yeptris/common/cpu.c +81 -0
- data/vendor/libyeptris/src/yeptris/common/cpu.h +40 -0
- data/vendor/libyeptris/src/yeptris/common/error.c +65 -0
- data/vendor/libyeptris/src/yeptris/common/error.h +79 -0
- data/vendor/libyeptris/src/yeptris/common/mutex.h +45 -0
- data/vendor/libyeptris/src/yeptris/common/nametab.c +275 -0
- data/vendor/libyeptris/src/yeptris/common/nametab.h +68 -0
- data/vendor/libyeptris/src/yeptris/common/port.h +74 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text.c +49 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text.h +295 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text_avx2.c +534 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text_neon.c +662 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text_scalar.c +298 -0
- data/vendor/libyeptris/src/yeptris/common/string_view.c +34 -0
- data/vendor/libyeptris/src/yeptris/common/string_view.h +93 -0
- data/vendor/libyeptris/src/yeptris/doc.h +56 -0
- data/vendor/libyeptris/src/yeptris/dom/dom.c +1192 -0
- data/vendor/libyeptris/src/yeptris/dom/dom.h +312 -0
- data/vendor/libyeptris/src/yeptris/dom/hpool.c +107 -0
- data/vendor/libyeptris/src/yeptris/dom/mapindex.c +173 -0
- data/vendor/libyeptris/src/yeptris/dom/mapindex.h +61 -0
- data/vendor/libyeptris/src/yeptris/dom/mutate.c +431 -0
- data/vendor/libyeptris/src/yeptris/emit/emit.c +434 -0
- data/vendor/libyeptris/src/yeptris/emit/float/api.h +38 -0
- data/vendor/libyeptris/src/yeptris/emit/float/dragon.c +405 -0
- data/vendor/libyeptris/src/yeptris/emit/float/floatint.h +231 -0
- data/vendor/libyeptris/src/yeptris/emit/float/print.c +396 -0
- data/vendor/libyeptris/src/yeptris/emit/style.c +81 -0
- data/vendor/libyeptris/src/yeptris/emit/style.h +24 -0
- data/vendor/libyeptris/src/yeptris/emit/writer.c +816 -0
- data/vendor/libyeptris/src/yeptris/emit/writer.h +76 -0
- data/vendor/libyeptris/src/yeptris/encoding/bom.c +31 -0
- data/vendor/libyeptris/src/yeptris/encoding/encoding.h +63 -0
- data/vendor/libyeptris/src/yeptris/encoding/transcode.c +148 -0
- data/vendor/libyeptris/src/yeptris/encoding/utf8_validate.c +178 -0
- data/vendor/libyeptris/src/yeptris/events/capture.c +150 -0
- data/vendor/libyeptris/src/yeptris/events/capture.h +39 -0
- data/vendor/libyeptris/src/yeptris/events/iterparse.c +208 -0
- data/vendor/libyeptris/src/yeptris/events/pull.c +97 -0
- data/vendor/libyeptris/src/yeptris/events/push.c +104 -0
- data/vendor/libyeptris/src/yeptris/events/recorder.c +107 -0
- data/vendor/libyeptris/src/yeptris/events/values.c +527 -0
- data/vendor/libyeptris/src/yeptris/events/values_priv.h +51 -0
- data/vendor/libyeptris/src/yeptris/events/yaml_compat.c +86 -0
- data/vendor/libyeptris/src/yeptris/events/yaml_compat.h +90 -0
- data/vendor/libyeptris/src/yeptris/jsonapi/jsonc_compat.c +687 -0
- data/vendor/libyeptris/src/yeptris/jsonapi/yajl_compat.c +728 -0
- data/vendor/libyeptris/src/yeptris/marshal.c +782 -0
- data/vendor/libyeptris/src/yeptris/memory/allocator.c +20 -0
- data/vendor/libyeptris/src/yeptris/memory/allocator.h +43 -0
- data/vendor/libyeptris/src/yeptris/memory/arena.c +134 -0
- data/vendor/libyeptris/src/yeptris/memory/arena.h +52 -0
- data/vendor/libyeptris/src/yeptris/memory/pool.c +122 -0
- data/vendor/libyeptris/src/yeptris/memory/pool.h +36 -0
- data/vendor/libyeptris/src/yeptris/parse/engine.c +3698 -0
- data/vendor/libyeptris/src/yeptris/parse/engine.h +65 -0
- data/vendor/libyeptris/src/yeptris/parse/events.h +124 -0
- data/vendor/libyeptris/src/yeptris/parse/numbers.c +349 -0
- data/vendor/libyeptris/src/yeptris/parse/numbers.h +33 -0
- data/vendor/libyeptris/src/yeptris/parse/scalars.c +416 -0
- data/vendor/libyeptris/src/yeptris/parse/scalars.h +75 -0
- data/vendor/libyeptris/src/yeptris/parse.c +737 -0
- data/vendor/libyeptris/src/yeptris/plan.c +824 -0
- data/vendor/libyeptris/src/yeptris/resolve/compat11.c +334 -0
- data/vendor/libyeptris/src/yeptris/resolve/core12.c +143 -0
- data/vendor/libyeptris/src/yeptris/resolve/resolver.h +56 -0
- data/vendor/libyeptris/src/yeptris/resolve/tags.c +58 -0
- data/vendor/libyeptris/src/yeptris/scan/json.c +792 -0
- data/vendor/libyeptris/src/yeptris/scan/json.h +109 -0
- data/vendor/libyeptris/src/yeptris/scan/scan.c +463 -0
- data/vendor/libyeptris/src/yeptris/scan/scan.h +150 -0
- data/vendor/libyeptris/src/yeptris/schema.c +308 -0
- data/vendor/libyeptris/src/yeptris/tape.c +1308 -0
- data/vendor/libyeptris/src/yeptris/tape_in.h +19 -0
- data/vendor/libyeptris/src/yeptris/version.c +7 -0
- data/vendor/libyeptris/src/yeptris/visit/dom_visit.c +115 -0
- data/vendor/libyeptris/src/yeptris/visit/json_visit.c +293 -0
- data/vendor/libyeptris/src/yeptris/visit/yaml_visit.c +127 -0
- metadata +199 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/* scan.h — structure facts from bytes (TODO.impl/06).
|
|
2
|
+
*
|
|
3
|
+
* MECE law: scan answers "where does this line's content start and where
|
|
4
|
+
* do spans end" — never grammar decisions, never allocation. The engine
|
|
5
|
+
* (07) owns grammar. Line facts are produced lazily, one line at a time;
|
|
6
|
+
* no whole-document table (streaming-friendly).
|
|
7
|
+
*/
|
|
8
|
+
#ifndef YEP_SCAN_H
|
|
9
|
+
#define YEP_SCAN_H
|
|
10
|
+
|
|
11
|
+
#include <stddef.h>
|
|
12
|
+
#include <stdint.h>
|
|
13
|
+
|
|
14
|
+
#include "common/simd_text.h" /* yep_stopset (the stop-class form) */
|
|
15
|
+
|
|
16
|
+
#ifdef __cplusplus
|
|
17
|
+
extern "C" {
|
|
18
|
+
#endif
|
|
19
|
+
|
|
20
|
+
typedef struct yep_line_info {
|
|
21
|
+
uint32_t offset; /* byte offset of the line start */
|
|
22
|
+
uint32_t end; /* byte offset of the line break (exclusive content end) */
|
|
23
|
+
uint16_t indent; /* column of the first non-space (== end - offset when blank) */
|
|
24
|
+
uint16_t flags;
|
|
25
|
+
unsigned char first; /* first content byte ('\0' for blank lines) */
|
|
26
|
+
} yep_line_info;
|
|
27
|
+
|
|
28
|
+
enum {
|
|
29
|
+
YEP_LF_BLANK = 1u << 0, /* only spaces */
|
|
30
|
+
YEP_LF_COMMENT = 1u << 1, /* first content char is '#' */
|
|
31
|
+
YEP_LF_DOC_START = 1u << 2, /* "---" (then EOL / space / comment) */
|
|
32
|
+
YEP_LF_DOC_END = 1u << 3, /* "..." (then EOL / space / comment) */
|
|
33
|
+
YEP_LF_DIRECTIVE = 1u << 4, /* '%' at column 0 */
|
|
34
|
+
YEP_LF_TAB = 1u << 5, /* tab within the indentation (error) */
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/* Facts for the line starting at pos. Handles \n, \r\n, lone \r breaks. */
|
|
38
|
+
yep_line_info yep_scan_line(const char* p, size_t len, size_t pos);
|
|
39
|
+
|
|
40
|
+
/* What terminated a plain-scalar span. */
|
|
41
|
+
typedef enum {
|
|
42
|
+
YEP_TERM_EOF = 0,
|
|
43
|
+
YEP_TERM_EOL,
|
|
44
|
+
YEP_TERM_COMMENT, /* " #" — span excludes the preceding space */
|
|
45
|
+
YEP_TERM_COLON, /* ':' followed by blank/EOL — span ends before ':' */
|
|
46
|
+
YEP_TERM_FLOW, /* flow indicator (flow context only) */
|
|
47
|
+
YEP_TERM_BAD_COLON /* ':' in a position YAML forbids (error context) */
|
|
48
|
+
} yep_span_term;
|
|
49
|
+
|
|
50
|
+
typedef struct yep_span {
|
|
51
|
+
uint32_t start;
|
|
52
|
+
uint32_t end; /* trimmed span end (exclusive) */
|
|
53
|
+
yep_span_term term;
|
|
54
|
+
} yep_span;
|
|
55
|
+
|
|
56
|
+
/* Line-shape classification (TODO.restructure/49): byte-class FACTS for
|
|
57
|
+
* the engine's one-per-line dispatch decision — scan walks, the engine
|
|
58
|
+
* decides. A shape is only produced for the dominant block line forms;
|
|
59
|
+
* every other line classifies NONE and keeps the general paths. */
|
|
60
|
+
typedef enum {
|
|
61
|
+
YEP_LSHAPE_NONE = 0, /* not classified: use the general chain */
|
|
62
|
+
YEP_LSHAPE_DASH, /* "- " entry at the content start */
|
|
63
|
+
YEP_LSHAPE_KEY, /* plain key + terminating ':' */
|
|
64
|
+
} yep_line_kind;
|
|
65
|
+
|
|
66
|
+
typedef enum {
|
|
67
|
+
YEP_LVAL_NONE = 0, /* value not classified (bail) */
|
|
68
|
+
YEP_LVAL_EMPTY, /* EOL or comment after the ':' / '-' */
|
|
69
|
+
YEP_LVAL_PLAIN, /* plain scalar (val_span + term) */
|
|
70
|
+
YEP_LVAL_ALIAS, /* '*name' at val_start */
|
|
71
|
+
YEP_LVAL_ANCHOR_PLAIN, /* '&name' then a plain scalar */
|
|
72
|
+
YEP_LVAL_FLOW, /* '[' / '{' at val_start: the flow kernel owns it */
|
|
73
|
+
} yep_line_val;
|
|
74
|
+
|
|
75
|
+
typedef struct yep_line_shape {
|
|
76
|
+
yep_line_kind kind;
|
|
77
|
+
yep_line_val val;
|
|
78
|
+
uint32_t dash; /* '-' offset (DASH) */
|
|
79
|
+
uint32_t key_start; /* trimmed plain key span (KEY) */
|
|
80
|
+
uint32_t key_end;
|
|
81
|
+
uint32_t colon; /* the terminating ':' offset (KEY) */
|
|
82
|
+
uint32_t val_start; /* first value byte (all non-EMPTY vals) */
|
|
83
|
+
uint32_t anchor_end; /* ANCHOR_PLAIN: end of the anchor name */
|
|
84
|
+
yep_span val_span; /* PLAIN / ANCHOR_PLAIN: the scalar span + term */
|
|
85
|
+
} yep_line_shape;
|
|
86
|
+
|
|
87
|
+
/* Classifies the content line described by li (its own line; flags must
|
|
88
|
+
* be clear). Zero-initializes *out, then fills the facts. */
|
|
89
|
+
void yep_scan_shape(const char* p, size_t len, const yep_line_info* li, yep_line_shape* out);
|
|
90
|
+
void yep_scan_shape_f(const char* p, size_t len, const yep_line_info* li, const yep_line_facts* f,
|
|
91
|
+
yep_line_shape* out);
|
|
92
|
+
void yep_scan_line_f(const char* p, size_t len, size_t pos, const yep_line_facts* f,
|
|
93
|
+
yep_line_info* out);
|
|
94
|
+
|
|
95
|
+
/* ns-anchor-name byte: not blank/break/flow-indicator, not ',' or '#'. */
|
|
96
|
+
int yep_scan_prop_char(unsigned char c);
|
|
97
|
+
|
|
98
|
+
/* First offset at/after pos that cannot continue an anchor/alias name. */
|
|
99
|
+
size_t yep_scan_prop_end(const char* p, size_t len, size_t pos);
|
|
100
|
+
|
|
101
|
+
/* Scans a plain scalar starting at pos (must be content, not a comment).
|
|
102
|
+
* flow != 0 adds flow stop characters; in flow, ':' terminates when
|
|
103
|
+
* followed by blank/EOL/flow indicator. Leading whitespace is NOT
|
|
104
|
+
* consumed. Trailing spaces are trimmed from the span. */
|
|
105
|
+
yep_span yep_scan_plain(const char* p, size_t len, size_t pos, int flow);
|
|
106
|
+
|
|
107
|
+
/* ns-plain-first truth: whether c may START a plain scalar. ','
|
|
108
|
+
* ']' '}' are c-flow-indicators, excluded in every context ('[' '{'
|
|
109
|
+
* never reach a plain start: the engine dispatches flow first). */
|
|
110
|
+
int yep_plain_first_ok(unsigned char c);
|
|
111
|
+
|
|
112
|
+
/* The stop classes (scan.c's SSOT; prebuilt nibble-class tables —
|
|
113
|
+
* '\n','\r',':','#' and, in flow, ',','[',']','{','}').
|
|
114
|
+
* Externally linked so the unit suite can pin them against
|
|
115
|
+
* yep_stopset_init — a hand-written literal drift here would silently
|
|
116
|
+
* end every plain scalar early. */
|
|
117
|
+
extern const yep_stopset yep_break_stopset;
|
|
118
|
+
extern const yep_stopset yep_plain_stop_block;
|
|
119
|
+
extern const yep_stopset yep_plain_stop_flow;
|
|
120
|
+
|
|
121
|
+
/* The fused line-facts sweep (kernel-dispatched): end/indent/stop in
|
|
122
|
+
* one pass — scan_line and scan_shape both consume these. */
|
|
123
|
+
void yep_scan_facts(const char* p, size_t len, size_t pos, yep_line_facts* out);
|
|
124
|
+
|
|
125
|
+
/* Scans a quoted scalar whose opening quote is at pos. Returns span of
|
|
126
|
+
* the CONTENT (between quotes) and sets *term (EOL on unterminated → the
|
|
127
|
+
* caller errors). q is '\'' or '"'. */
|
|
128
|
+
yep_span yep_scan_quoted(const char* p, size_t len, size_t pos, int* has_escape);
|
|
129
|
+
|
|
130
|
+
/* True if a simple key may start at p[pos] (ns-plain-first approximation
|
|
131
|
+
* plus quote/flow openers). Exposed for the engine's dispatch. */
|
|
132
|
+
int yep_scan_is_key_start(unsigned char c);
|
|
133
|
+
|
|
134
|
+
/* Consumed length of the line break at pos (0 if none): \n -> 1,
|
|
135
|
+
* \r\n -> 2, lone \r -> 1. */
|
|
136
|
+
size_t yep_scan_break_len(const char* p, size_t len, size_t pos);
|
|
137
|
+
|
|
138
|
+
/* Line/col bookkeeping across a scanned gap: advances *line and
|
|
139
|
+
* *line_start over the bytes in [*from, to) (only the unscanned region
|
|
140
|
+
* is walked — scanning from the line start is quadratic on long
|
|
141
|
+
* lines). *from becomes `to`. Shared by the flow kernel's event pass
|
|
142
|
+
* and the DOM direct builder so their line/col facts cannot drift. */
|
|
143
|
+
void yep_scan_advance_line(const char* p, size_t* from, size_t to, uint32_t* line,
|
|
144
|
+
size_t* line_start);
|
|
145
|
+
|
|
146
|
+
#ifdef __cplusplus
|
|
147
|
+
}
|
|
148
|
+
#endif
|
|
149
|
+
|
|
150
|
+
#endif /* YEP_SCAN_H */
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/* schema.c — the fused schema-descriptor materialization
|
|
2
|
+
* (issue #238, TODO.restructure/83).
|
|
3
|
+
*
|
|
4
|
+
* One parse (the same engine every surface uses) + one fused walk of
|
|
5
|
+
* the DOM against the caller's descriptor: typed columns come out,
|
|
6
|
+
* the intermediate generic document never exists. The DOM side runs
|
|
7
|
+
* first because it is the cheapest complete-materialization engine;
|
|
8
|
+
* when the recorder path learns descriptor projection it can drop in
|
|
9
|
+
* under the same ABI (the columns are the contract, not the walk).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
#include <stdlib.h>
|
|
13
|
+
#include <string.h>
|
|
14
|
+
|
|
15
|
+
#include <yeptris/schema.h>
|
|
16
|
+
#include <yeptris/values.h> /* YeptrisValue: ST_ANY records (#238) */
|
|
17
|
+
|
|
18
|
+
#include "dom/dom.h"
|
|
19
|
+
#include "memory/allocator.h"
|
|
20
|
+
#include "parse/engine.h"
|
|
21
|
+
#include "resolve/resolver.h"
|
|
22
|
+
#include "scan/json.h"
|
|
23
|
+
|
|
24
|
+
typedef struct {
|
|
25
|
+
const yeptris_desc_node* desc;
|
|
26
|
+
uint32_t desc_len;
|
|
27
|
+
yeptris_schema_column* cols;
|
|
28
|
+
const yep_dom* dom;
|
|
29
|
+
int oom;
|
|
30
|
+
int overflow;
|
|
31
|
+
int type_mismatch; /* node index */
|
|
32
|
+
uint32_t* seen_map; /* per-node: the mapping instance that last
|
|
33
|
+
* emitted — YEP_SF_FIRST_WINS skips a repeat */
|
|
34
|
+
} yep_schema_ctx;
|
|
35
|
+
|
|
36
|
+
static int col_put(yep_schema_ctx* c, uint32_t node, const void* rec, size_t size) {
|
|
37
|
+
yeptris_schema_column* col = &c->cols[node];
|
|
38
|
+
if (col->count >= col->capacity) {
|
|
39
|
+
c->overflow = 1;
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
42
|
+
memcpy((char*)col->data + (size_t)col->count * size, rec, size);
|
|
43
|
+
col->count++;
|
|
44
|
+
return 1;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static void put_error_schema(uint32_t node) {
|
|
48
|
+
yep_error_set(yep_error_tls(), YEP_ERR_SCHEMA, 0, 0, node,
|
|
49
|
+
"required descriptor node %u missing", node);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* Materializes the DOM node under plan `node` into its column. */
|
|
53
|
+
static int emit(yep_schema_ctx* c, uint32_t node, uint32_t at);
|
|
54
|
+
|
|
55
|
+
static int emit_scalar(yep_schema_ctx* c, uint32_t node, uint32_t at) {
|
|
56
|
+
const yeptris_desc_node* d = &c->desc[node];
|
|
57
|
+
const yep_dnode* n = yep_dom_node(c->dom, at);
|
|
58
|
+
yep_view v = yep_dom_view(c->dom, n->value);
|
|
59
|
+
switch (d->type_tag) {
|
|
60
|
+
case YEP_ST_STR: {
|
|
61
|
+
yeptris_span2 s = {(uint32_t)((const char*)v.p - c->dom->input_base), v.len, 0, 0};
|
|
62
|
+
return col_put(c, node, &s, sizeof(s));
|
|
63
|
+
}
|
|
64
|
+
case YEP_ST_INT:
|
|
65
|
+
case YEP_ST_FLOAT: {
|
|
66
|
+
int64_t iv = 0;
|
|
67
|
+
double dv = 0;
|
|
68
|
+
int shape = 0;
|
|
69
|
+
size_t end = 0;
|
|
70
|
+
if (v.len == 0 || v.p == NULL ||
|
|
71
|
+
yep_json_number_scan(v.p, v.len, &end, &shape, &iv, &dv) == 0 || end != v.len) {
|
|
72
|
+
c->type_mismatch = (int)node;
|
|
73
|
+
return -1;
|
|
74
|
+
}
|
|
75
|
+
if (d->type_tag == YEP_ST_INT) {
|
|
76
|
+
int64_t out = shape == 0 ? iv : (int64_t)dv;
|
|
77
|
+
return col_put(c, node, &out, sizeof(out));
|
|
78
|
+
}
|
|
79
|
+
double fd = shape == 0 ? (double)iv : dv;
|
|
80
|
+
return col_put(c, node, &fd, sizeof(fd));
|
|
81
|
+
}
|
|
82
|
+
case YEP_ST_BOOL: {
|
|
83
|
+
uint8_t b = (uint8_t)(v.len > 0 && (v.p[0] == 't' || v.p[0] == 'T' || v.p[0] == 'y' ||
|
|
84
|
+
v.p[0] == 'Y' || v.p[0] == 'o' || v.p[0] == '1'));
|
|
85
|
+
return col_put(c, node, &b, sizeof(b));
|
|
86
|
+
}
|
|
87
|
+
case YEP_ST_NULL:
|
|
88
|
+
col_put(c, node, &(uint8_t){0}, 0);
|
|
89
|
+
return 1;
|
|
90
|
+
case YEP_ST_ANY: {
|
|
91
|
+
/* the resolver's verdict, verbatim: a YeptrisValue record
|
|
92
|
+
* (#238's headroom) — kind/tag_id from the node, the span
|
|
93
|
+
* borrowed, and the numeric payload converted when the
|
|
94
|
+
* verdict says so (the values-drain's conversion, DOM-side) */
|
|
95
|
+
YeptrisValue r = {0, 0, 0, 0, 0, 0, 0};
|
|
96
|
+
r.tag_id = n->tag_id;
|
|
97
|
+
r.off = (uint32_t)((const char*)v.p - c->dom->input_base);
|
|
98
|
+
r.len = v.len;
|
|
99
|
+
switch (n->tag_id) {
|
|
100
|
+
case YEPTRIS_TAG_NULL:
|
|
101
|
+
r.kind = YEP_V_NULL;
|
|
102
|
+
break;
|
|
103
|
+
case YEPTRIS_TAG_BOOL: {
|
|
104
|
+
r.kind = YEP_V_BOOL;
|
|
105
|
+
r.b = (uint8_t)(v.len > 0 && (v.p[0] == 't' || v.p[0] == 'T' || v.p[0] == 'y' ||
|
|
106
|
+
v.p[0] == 'Y' || v.p[0] == 'o' || v.p[0] == '1'));
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
case YEPTRIS_TAG_INT:
|
|
110
|
+
case YEPTRIS_TAG_FLOAT: {
|
|
111
|
+
int64_t iv = 0;
|
|
112
|
+
double dv = 0;
|
|
113
|
+
int shape = 0;
|
|
114
|
+
size_t end = 0;
|
|
115
|
+
if (v.len != 0 && v.p != NULL &&
|
|
116
|
+
yep_json_number_scan(v.p, v.len, &end, &shape, &iv, &dv) != 0 && end == v.len) {
|
|
117
|
+
if (n->tag_id == YEPTRIS_TAG_INT) {
|
|
118
|
+
r.kind = YEP_V_INT;
|
|
119
|
+
r.p = (uint64_t)iv;
|
|
120
|
+
} else {
|
|
121
|
+
r.kind = YEP_V_FLOAT;
|
|
122
|
+
double fd = shape == 0 ? (double)iv : dv;
|
|
123
|
+
memcpy(&r.p, &fd, sizeof(fd));
|
|
124
|
+
}
|
|
125
|
+
} else {
|
|
126
|
+
r.kind = YEP_V_STR; /* the resolver said number, the
|
|
127
|
+
bytes disagree: keep the span */
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
case YEPTRIS_TAG_TIMESTAMP:
|
|
132
|
+
r.kind = YEP_V_TIMESTAMP;
|
|
133
|
+
break;
|
|
134
|
+
default:
|
|
135
|
+
r.kind = YEP_V_STR;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
return col_put(c, node, &r, sizeof(r));
|
|
139
|
+
}
|
|
140
|
+
default:
|
|
141
|
+
return -1;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
static int emit(yep_schema_ctx* c, uint32_t node, uint32_t at) {
|
|
146
|
+
const yeptris_desc_node* d = &c->desc[node];
|
|
147
|
+
const yep_dnode* n = yep_dom_node(c->dom, at);
|
|
148
|
+
switch (d->kind) {
|
|
149
|
+
case YEP_SK_SCALAR:
|
|
150
|
+
return emit_scalar(c, node, at);
|
|
151
|
+
case YEP_SK_CALLBACK: {
|
|
152
|
+
/* the escape hatch: raw span + the node's first byte —
|
|
153
|
+
* scalar content by span, collections by their extent (the
|
|
154
|
+
* caller that needs the tree takes the generic surface) */
|
|
155
|
+
yep_view v = yep_dom_view(c->dom, n->value);
|
|
156
|
+
yeptris_span2 s = {(uint32_t)((const char*)v.p - c->dom->input_base), v.len,
|
|
157
|
+
(uint32_t)((const char*)v.p - c->dom->input_base), 0};
|
|
158
|
+
if (n->kind == YEP_DOM_MAPPING || n->kind == YEP_DOM_SEQUENCE) {
|
|
159
|
+
s.off = 0; /* collections have no span: position only */
|
|
160
|
+
s.len = 0;
|
|
161
|
+
}
|
|
162
|
+
return col_put(c, node, &s, sizeof(s));
|
|
163
|
+
}
|
|
164
|
+
case YEP_SK_SEQUENCE: {
|
|
165
|
+
if (n->kind != YEP_DOM_SEQUENCE) {
|
|
166
|
+
return 0; /* not this shape: the column stays empty */
|
|
167
|
+
}
|
|
168
|
+
uint32_t ch = d->child_index;
|
|
169
|
+
if (ch >= c->desc_len) {
|
|
170
|
+
return -1;
|
|
171
|
+
}
|
|
172
|
+
uint32_t e = n->first_child;
|
|
173
|
+
while (e != UINT32_MAX) {
|
|
174
|
+
int rc = emit(c, ch, e);
|
|
175
|
+
if (rc != 1) {
|
|
176
|
+
return rc;
|
|
177
|
+
}
|
|
178
|
+
e = c->dom->nodes[e].next_sibling;
|
|
179
|
+
}
|
|
180
|
+
return 1;
|
|
181
|
+
}
|
|
182
|
+
case YEP_SK_MAPPING: {
|
|
183
|
+
if (n->kind != YEP_DOM_MAPPING) {
|
|
184
|
+
return 0;
|
|
185
|
+
}
|
|
186
|
+
uint32_t k = n->first_child;
|
|
187
|
+
while (k != UINT32_MAX) {
|
|
188
|
+
uint32_t val = c->dom->nodes[k].next_sibling;
|
|
189
|
+
yep_view key = yep_dom_view(c->dom, c->dom->nodes[k].value);
|
|
190
|
+
for (uint32_t ci = d->child_index;
|
|
191
|
+
ci < d->child_index + d->child_count && ci < c->desc_len; ci++) {
|
|
192
|
+
const yeptris_desc_node* cd = &c->desc[ci];
|
|
193
|
+
size_t wl = strlen(cd->wire_name ? cd->wire_name : "");
|
|
194
|
+
if (cd->wire_name != NULL && key.len == wl &&
|
|
195
|
+
memcmp(key.p, cd->wire_name, wl) == 0) {
|
|
196
|
+
if ((cd->flags & YEP_SF_FIRST_WINS) && c->seen_map != NULL &&
|
|
197
|
+
c->seen_map[ci] == at + 1) {
|
|
198
|
+
break; /* a repeat within THIS mapping: first wins */
|
|
199
|
+
}
|
|
200
|
+
int rc = emit(c, ci, val);
|
|
201
|
+
if (rc != 1) {
|
|
202
|
+
return rc;
|
|
203
|
+
}
|
|
204
|
+
if ((cd->flags & YEP_SF_FIRST_WINS) && c->seen_map != NULL) {
|
|
205
|
+
c->seen_map[ci] = at + 1;
|
|
206
|
+
}
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
k = c->dom->nodes[val].next_sibling;
|
|
211
|
+
}
|
|
212
|
+
return 1;
|
|
213
|
+
}
|
|
214
|
+
default:
|
|
215
|
+
return -1;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
YEPTRIS_API YeptrisStatus yeptris_schema_load(const char* source, size_t len, YeptrisSchema schema,
|
|
220
|
+
const yeptris_desc_node* desc, uint32_t desc_len,
|
|
221
|
+
uint32_t desc_abi, yeptris_schema_column* cols) {
|
|
222
|
+
if ((source == NULL && len != 0) || desc == NULL || desc_len == 0 || cols == NULL) {
|
|
223
|
+
return YEPTRIS_ERROR_ARG;
|
|
224
|
+
}
|
|
225
|
+
if (desc_abi != YEPTRIS_DESC_ABI) {
|
|
226
|
+
yep_error_set(yep_error_tls(), YEP_ERR_UNEXPECTED, 0, 0, desc_abi,
|
|
227
|
+
"descriptor ABI %u != %u (recompile the descriptor)", desc_abi,
|
|
228
|
+
YEPTRIS_DESC_ABI);
|
|
229
|
+
return YEPTRIS_ERROR_ARG;
|
|
230
|
+
}
|
|
231
|
+
for (uint32_t i = 0; i < desc_len; i++) {
|
|
232
|
+
if (desc[i].reserved != 0) {
|
|
233
|
+
return YEPTRIS_ERROR_ARG;
|
|
234
|
+
}
|
|
235
|
+
cols[i].count = 0;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const yep_allocator* sys = yep_system_allocator();
|
|
239
|
+
yep_engine* eng = yep_engine_create(sys);
|
|
240
|
+
yep_dom* dom = yep_dom_create(sys);
|
|
241
|
+
uint32_t* seen_map_ptr = NULL;
|
|
242
|
+
YeptrisStatus st = YEPTRIS_OK;
|
|
243
|
+
yep_sink sink = {.on_event = yep_dom_on_event,
|
|
244
|
+
.ctx = dom,
|
|
245
|
+
.on_flow_build = dom_on_flow_build,
|
|
246
|
+
.on_flow_commit = dom_on_flow_commit,
|
|
247
|
+
.on_flow_rollback = dom_on_flow_rollback,
|
|
248
|
+
.on_block_pair = dom_on_block_pair,
|
|
249
|
+
.on_scalar = dom_on_scalar,
|
|
250
|
+
.on_block_open = dom_on_block_open,
|
|
251
|
+
.on_block_item = dom_on_block_item};
|
|
252
|
+
if (eng == NULL || dom == NULL) {
|
|
253
|
+
st = YEPTRIS_ERROR_MEMORY;
|
|
254
|
+
goto out;
|
|
255
|
+
}
|
|
256
|
+
if (schema == YEPTRIS_SCHEMA_11_COMPAT) {
|
|
257
|
+
yep_engine_set_resolver(eng, yep_resolver_compat11());
|
|
258
|
+
dom->resolver = yep_resolver_compat11(); /* the DOM's direct
|
|
259
|
+
builders resolve their own tag_ids —
|
|
260
|
+
ST_ANY reads the NODE's verdict */
|
|
261
|
+
}
|
|
262
|
+
dom->input_base = source;
|
|
263
|
+
dom->input_len = len;
|
|
264
|
+
yep_dom_prepare_len(dom, len);
|
|
265
|
+
if (yep_engine_run(eng, source, len, &sink) != 0 || dom->dcount == 0) {
|
|
266
|
+
st = YEPTRIS_ERROR_PARSE;
|
|
267
|
+
goto out;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
{
|
|
271
|
+
uint32_t* seen = seen_map_ptr = calloc(desc_len, sizeof(uint32_t));
|
|
272
|
+
if (seen == NULL) {
|
|
273
|
+
st = YEPTRIS_ERROR_MEMORY;
|
|
274
|
+
goto out;
|
|
275
|
+
}
|
|
276
|
+
yep_schema_ctx c = {desc, desc_len, cols, dom, 0, 0, -1, seen};
|
|
277
|
+
int rc = emit(&c, 0, dom->docs[0]);
|
|
278
|
+
if (rc < 0 && c.type_mismatch >= 0) {
|
|
279
|
+
yep_error_set(yep_error_tls(), YEP_ERR_UNEXPECTED, 0, 0, (uint32_t)c.type_mismatch,
|
|
280
|
+
"node %d: value is not a number", c.type_mismatch);
|
|
281
|
+
st = YEPTRIS_ERROR_PARSE;
|
|
282
|
+
goto out;
|
|
283
|
+
}
|
|
284
|
+
if (rc < 0) {
|
|
285
|
+
st = YEPTRIS_ERROR_ARG;
|
|
286
|
+
goto out;
|
|
287
|
+
}
|
|
288
|
+
for (uint32_t i = 0; i < desc_len; i++) {
|
|
289
|
+
if ((desc[i].flags & YEP_SF_REQUIRED) && cols[i].count == 0 &&
|
|
290
|
+
desc[i].wire_name != NULL) {
|
|
291
|
+
put_error_schema(i);
|
|
292
|
+
st = YEPTRIS_ERROR_SCHEMA;
|
|
293
|
+
goto out;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (c.overflow) {
|
|
297
|
+
st = YEPTRIS_ERROR_MEMORY; /* caller buffers too small */
|
|
298
|
+
yep_error_set(yep_error_tls(), YEP_ERR_MEMORY, 0, 0, 0,
|
|
299
|
+
"output column capacity exceeded");
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
out:
|
|
304
|
+
free(seen_map_ptr);
|
|
305
|
+
yep_dom_destroy(dom);
|
|
306
|
+
yep_engine_destroy(eng);
|
|
307
|
+
return st;
|
|
308
|
+
}
|