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.
Files changed (142) hide show
  1. checksums.yaml +7 -0
  2. data/README.adoc +141 -0
  3. data/ext/build_windows_native.rb +41 -0
  4. data/ext/libyeptris/extconf.rb +57 -0
  5. data/ext/yeptris_native/cbor_ruby.c +193 -0
  6. data/ext/yeptris_native/extconf.rb +47 -0
  7. data/ext/yeptris_native/json_ruby.c +354 -0
  8. data/ext/yeptris_native/yeptris_native.c +497 -0
  9. data/lib/yeptris/cbor.rb +130 -0
  10. data/lib/yeptris/document.rb +255 -0
  11. data/lib/yeptris/ffi.rb +426 -0
  12. data/lib/yeptris/json/descriptor.rb +266 -0
  13. data/lib/yeptris/json.rb +394 -0
  14. data/lib/yeptris/materializer.rb +354 -0
  15. data/lib/yeptris/native-3.4.so +0 -0
  16. data/lib/yeptris/node.rb +453 -0
  17. data/lib/yeptris/psych/class_loader.rb +24 -0
  18. data/lib/yeptris/psych/coder_shim.rb +55 -0
  19. data/lib/yeptris/psych/drop_in.rb +63 -0
  20. data/lib/yeptris/psych/encodable.rb +14 -0
  21. data/lib/yeptris/psych/handler.rb +90 -0
  22. data/lib/yeptris/psych/parser.rb +105 -0
  23. data/lib/yeptris/psych/scalar_scanner.rb +149 -0
  24. data/lib/yeptris/psych/visitors.rb +545 -0
  25. data/lib/yeptris/psych.rb +622 -0
  26. data/lib/yeptris/schema.rb +253 -0
  27. data/lib/yeptris/valueml.rb +455 -0
  28. data/lib/yeptris/yaml/descriptor.rb +56 -0
  29. data/lib/yeptris/yaml.rb +422 -0
  30. data/lib/yeptris.rb +113 -0
  31. data/libyeptris.so +0 -0
  32. data/vendor/libyeptris/CMakeLists.txt +254 -0
  33. data/vendor/libyeptris/cmake/yeptris-config.cmake.in +5 -0
  34. data/vendor/libyeptris/cmake/yeptris.pc.in +11 -0
  35. data/vendor/libyeptris/src/CMakeLists.txt +167 -0
  36. data/vendor/libyeptris/src/include/yeptris/api.h +32 -0
  37. data/vendor/libyeptris/src/include/yeptris/cbor.h +101 -0
  38. data/vendor/libyeptris/src/include/yeptris/dom.h +190 -0
  39. data/vendor/libyeptris/src/include/yeptris/emit.h +81 -0
  40. data/vendor/libyeptris/src/include/yeptris/error.h +41 -0
  41. data/vendor/libyeptris/src/include/yeptris/events.h +157 -0
  42. data/vendor/libyeptris/src/include/yeptris/json.h +45 -0
  43. data/vendor/libyeptris/src/include/yeptris/json.hpp +258 -0
  44. data/vendor/libyeptris/src/include/yeptris/jsonc_compat.h +115 -0
  45. data/vendor/libyeptris/src/include/yeptris/marshal.h +52 -0
  46. data/vendor/libyeptris/src/include/yeptris/parse.h +48 -0
  47. data/vendor/libyeptris/src/include/yeptris/plan.h +100 -0
  48. data/vendor/libyeptris/src/include/yeptris/resolve.h +71 -0
  49. data/vendor/libyeptris/src/include/yeptris/schema.h +121 -0
  50. data/vendor/libyeptris/src/include/yeptris/tape.h +123 -0
  51. data/vendor/libyeptris/src/include/yeptris/types.h +38 -0
  52. data/vendor/libyeptris/src/include/yeptris/values.h +102 -0
  53. data/vendor/libyeptris/src/include/yeptris/version.h.in +29 -0
  54. data/vendor/libyeptris/src/include/yeptris/visit.h +77 -0
  55. data/vendor/libyeptris/src/include/yeptris/yajl_compat.h +135 -0
  56. data/vendor/libyeptris/src/include/yeptris.h +23 -0
  57. data/vendor/libyeptris/src/yeptris/build.c +376 -0
  58. data/vendor/libyeptris/src/yeptris/cbor/cbor.h +25 -0
  59. data/vendor/libyeptris/src/yeptris/cbor/decode.c +981 -0
  60. data/vendor/libyeptris/src/yeptris/cbor/encode.c +835 -0
  61. data/vendor/libyeptris/src/yeptris/cbor/sink.h +58 -0
  62. data/vendor/libyeptris/src/yeptris/common/chartype.c +41 -0
  63. data/vendor/libyeptris/src/yeptris/common/chartype.h +77 -0
  64. data/vendor/libyeptris/src/yeptris/common/cpu.c +81 -0
  65. data/vendor/libyeptris/src/yeptris/common/cpu.h +40 -0
  66. data/vendor/libyeptris/src/yeptris/common/error.c +65 -0
  67. data/vendor/libyeptris/src/yeptris/common/error.h +79 -0
  68. data/vendor/libyeptris/src/yeptris/common/mutex.h +45 -0
  69. data/vendor/libyeptris/src/yeptris/common/nametab.c +275 -0
  70. data/vendor/libyeptris/src/yeptris/common/nametab.h +68 -0
  71. data/vendor/libyeptris/src/yeptris/common/port.h +74 -0
  72. data/vendor/libyeptris/src/yeptris/common/simd_text.c +49 -0
  73. data/vendor/libyeptris/src/yeptris/common/simd_text.h +295 -0
  74. data/vendor/libyeptris/src/yeptris/common/simd_text_avx2.c +534 -0
  75. data/vendor/libyeptris/src/yeptris/common/simd_text_neon.c +662 -0
  76. data/vendor/libyeptris/src/yeptris/common/simd_text_scalar.c +298 -0
  77. data/vendor/libyeptris/src/yeptris/common/string_view.c +34 -0
  78. data/vendor/libyeptris/src/yeptris/common/string_view.h +93 -0
  79. data/vendor/libyeptris/src/yeptris/doc.h +56 -0
  80. data/vendor/libyeptris/src/yeptris/dom/dom.c +1192 -0
  81. data/vendor/libyeptris/src/yeptris/dom/dom.h +312 -0
  82. data/vendor/libyeptris/src/yeptris/dom/hpool.c +107 -0
  83. data/vendor/libyeptris/src/yeptris/dom/mapindex.c +173 -0
  84. data/vendor/libyeptris/src/yeptris/dom/mapindex.h +61 -0
  85. data/vendor/libyeptris/src/yeptris/dom/mutate.c +431 -0
  86. data/vendor/libyeptris/src/yeptris/emit/emit.c +434 -0
  87. data/vendor/libyeptris/src/yeptris/emit/float/api.h +38 -0
  88. data/vendor/libyeptris/src/yeptris/emit/float/dragon.c +405 -0
  89. data/vendor/libyeptris/src/yeptris/emit/float/floatint.h +231 -0
  90. data/vendor/libyeptris/src/yeptris/emit/float/print.c +396 -0
  91. data/vendor/libyeptris/src/yeptris/emit/style.c +81 -0
  92. data/vendor/libyeptris/src/yeptris/emit/style.h +24 -0
  93. data/vendor/libyeptris/src/yeptris/emit/writer.c +816 -0
  94. data/vendor/libyeptris/src/yeptris/emit/writer.h +76 -0
  95. data/vendor/libyeptris/src/yeptris/encoding/bom.c +31 -0
  96. data/vendor/libyeptris/src/yeptris/encoding/encoding.h +63 -0
  97. data/vendor/libyeptris/src/yeptris/encoding/transcode.c +148 -0
  98. data/vendor/libyeptris/src/yeptris/encoding/utf8_validate.c +178 -0
  99. data/vendor/libyeptris/src/yeptris/events/capture.c +150 -0
  100. data/vendor/libyeptris/src/yeptris/events/capture.h +39 -0
  101. data/vendor/libyeptris/src/yeptris/events/iterparse.c +208 -0
  102. data/vendor/libyeptris/src/yeptris/events/pull.c +97 -0
  103. data/vendor/libyeptris/src/yeptris/events/push.c +104 -0
  104. data/vendor/libyeptris/src/yeptris/events/recorder.c +107 -0
  105. data/vendor/libyeptris/src/yeptris/events/values.c +527 -0
  106. data/vendor/libyeptris/src/yeptris/events/values_priv.h +51 -0
  107. data/vendor/libyeptris/src/yeptris/events/yaml_compat.c +86 -0
  108. data/vendor/libyeptris/src/yeptris/events/yaml_compat.h +90 -0
  109. data/vendor/libyeptris/src/yeptris/jsonapi/jsonc_compat.c +687 -0
  110. data/vendor/libyeptris/src/yeptris/jsonapi/yajl_compat.c +728 -0
  111. data/vendor/libyeptris/src/yeptris/marshal.c +782 -0
  112. data/vendor/libyeptris/src/yeptris/memory/allocator.c +20 -0
  113. data/vendor/libyeptris/src/yeptris/memory/allocator.h +43 -0
  114. data/vendor/libyeptris/src/yeptris/memory/arena.c +134 -0
  115. data/vendor/libyeptris/src/yeptris/memory/arena.h +52 -0
  116. data/vendor/libyeptris/src/yeptris/memory/pool.c +122 -0
  117. data/vendor/libyeptris/src/yeptris/memory/pool.h +36 -0
  118. data/vendor/libyeptris/src/yeptris/parse/engine.c +3698 -0
  119. data/vendor/libyeptris/src/yeptris/parse/engine.h +65 -0
  120. data/vendor/libyeptris/src/yeptris/parse/events.h +124 -0
  121. data/vendor/libyeptris/src/yeptris/parse/numbers.c +349 -0
  122. data/vendor/libyeptris/src/yeptris/parse/numbers.h +33 -0
  123. data/vendor/libyeptris/src/yeptris/parse/scalars.c +416 -0
  124. data/vendor/libyeptris/src/yeptris/parse/scalars.h +75 -0
  125. data/vendor/libyeptris/src/yeptris/parse.c +737 -0
  126. data/vendor/libyeptris/src/yeptris/plan.c +824 -0
  127. data/vendor/libyeptris/src/yeptris/resolve/compat11.c +334 -0
  128. data/vendor/libyeptris/src/yeptris/resolve/core12.c +143 -0
  129. data/vendor/libyeptris/src/yeptris/resolve/resolver.h +56 -0
  130. data/vendor/libyeptris/src/yeptris/resolve/tags.c +58 -0
  131. data/vendor/libyeptris/src/yeptris/scan/json.c +792 -0
  132. data/vendor/libyeptris/src/yeptris/scan/json.h +109 -0
  133. data/vendor/libyeptris/src/yeptris/scan/scan.c +463 -0
  134. data/vendor/libyeptris/src/yeptris/scan/scan.h +150 -0
  135. data/vendor/libyeptris/src/yeptris/schema.c +308 -0
  136. data/vendor/libyeptris/src/yeptris/tape.c +1308 -0
  137. data/vendor/libyeptris/src/yeptris/tape_in.h +19 -0
  138. data/vendor/libyeptris/src/yeptris/version.c +7 -0
  139. data/vendor/libyeptris/src/yeptris/visit/dom_visit.c +115 -0
  140. data/vendor/libyeptris/src/yeptris/visit/json_visit.c +293 -0
  141. data/vendor/libyeptris/src/yeptris/visit/yaml_visit.c +127 -0
  142. metadata +199 -0
@@ -0,0 +1,76 @@
1
+ /* writer.h — internal emitter engine (TODO.impl/13). */
2
+ #ifndef YEP_EMIT_WRITER_H
3
+ #define YEP_EMIT_WRITER_H
4
+
5
+ #include <stdint.h>
6
+
7
+ #include "../common/nametab.h"
8
+ #include "../doc.h"
9
+ #include "../dom/dom.h"
10
+
11
+ /* Streaming high-water mark: the writer flushes when len crosses it
12
+ * (append-only output makes any point safe; 13C). */
13
+ #define YEP_EMIT_WATERMARK (1u << 16)
14
+
15
+ typedef int (*yep_emit_flush)(void* ctx, const char* bytes, size_t len);
16
+
17
+ typedef struct yep_writer {
18
+ char* p; /* output (wet) */
19
+ size_t len; /* bytes written (or counted, dry) */
20
+ int dry; /* 1: size only */
21
+ char last; /* last byte written ('\0' at start) — dry-safe */
22
+ int force_flow; /* complex-key emission: collections render flow */
23
+ yep_emit_flush sink; /* 13C: streaming flush (NULL = buffered) */
24
+ void* sink_ctx;
25
+ size_t watermark;
26
+ size_t flushed; /* total bytes handed to the sink */
27
+ int sink_aborted; /* a sink returned nonzero: stop, report 0 */
28
+ int canonical;
29
+ int explicit_doc_start;
30
+ /* every document carries the --- marker */ /* 13B: fixed canonical form — flow collections,
31
+ * quoted strings, typed words, shortest floats
32
+ */
33
+ int json; /* 21: JSON output — canonical minus YAML words:
34
+ * null (not ~), no document markers, JSON escapes */
35
+ int json_compact; /* json-c to_json_string: no padding spaces */
36
+ int json_pretty; /* json-c PRETTY: 2-space indent, per-entry lines */
37
+ int pretty_depth; /* json_pretty nesting level (indent = 2*depth) */
38
+ int best_width; /* 13B: 0 = default 80; flow lines wrap after a
39
+ * value past this width */
40
+ int col; /* current output column (wr_* maintains) */
41
+ const char* sv_input; /* compact-view decode bases (dom regions) */
42
+ const char* sv_arena;
43
+ /* #352: per-scalar route decisions, derived once in the dry
44
+ * sizing pass and consumed by the wet write pass (one byte per
45
+ * scalar, indexed by consumption order; NULL = derive per pass) */
46
+ uint8_t* sc_dec;
47
+ uint32_t sc_i;
48
+ /* #352 slice 2: the growable single-pass route — the exact-sizing
49
+ * dry pass measured 0.54-0.73x of the one-pass stream route on
50
+ * CI-fresh runners, so serialize_ex writes wet into a buffer that
51
+ * doubles on demand (cap/grow), like the streaming window. The
52
+ * fixed-buffer routes keep grow=0 and today's trust-the-count
53
+ * behavior. oom marks a failed growth: writes stop touching memory
54
+ * but the byte count keeps running so callers can fail cleanly. */
55
+ size_t cap;
56
+ int grow;
57
+ int oom;
58
+ } yep_writer;
59
+
60
+ typedef struct yep_emitter {
61
+ const yeptris_document* doc;
62
+ yep_writer w;
63
+ yep_nametab canon_names; /* canonical anchor renaming: view -> index */
64
+ } yep_emitter;
65
+
66
+ /* One pass over the document set. dry=1 counts exactly. */
67
+ size_t yep_emit_run(yep_emitter* em, int dry);
68
+
69
+ /* Compact single-line JSON (internal entries for the json-c compat
70
+ * layer's to_json_string forms). pretty selects json-c's
71
+ * JSON_C_TO_STRING_PRETTY layout: newline + 2-space indent per
72
+ * nesting level, one entry per line. */
73
+ char* yep_serialize_json_compact(const yeptris_document* doc, size_t* len);
74
+ char* yep_serialize_json_pretty(const yeptris_document* doc, size_t* len);
75
+
76
+ #endif /* YEP_EMIT_WRITER_H */
@@ -0,0 +1,31 @@
1
+ /* bom.c — byte-order-mark sniffing (TODO.impl/05). */
2
+
3
+ #include "encoding.h"
4
+
5
+ size_t yep_bom_sniff(const unsigned char* p, size_t len, yep_encoding* out) {
6
+ yep_encoding enc = YEP_ENC_UNKNOWN;
7
+ size_t consumed = 0;
8
+
9
+ /* UTF-32LE (FF FE 00 00) must be tested before UTF-16LE (FF FE). */
10
+ if (len >= 4 && p[0] == 0xFF && p[1] == 0xFE && p[2] == 0x00 && p[3] == 0x00) {
11
+ enc = YEP_ENC_UTF32LE;
12
+ consumed = 4;
13
+ } else if (len >= 3 && p[0] == 0xEF && p[1] == 0xBB && p[2] == 0xBF) {
14
+ enc = YEP_ENC_UTF8;
15
+ consumed = 3;
16
+ } else if (len >= 4 && p[0] == 0x00 && p[1] == 0x00 && p[2] == 0xFE && p[3] == 0xFF) {
17
+ enc = YEP_ENC_UTF32BE;
18
+ consumed = 4;
19
+ } else if (len >= 2 && p[0] == 0xFF && p[1] == 0xFE) {
20
+ enc = YEP_ENC_UTF16LE;
21
+ consumed = 2;
22
+ } else if (len >= 2 && p[0] == 0xFE && p[1] == 0xFF) {
23
+ enc = YEP_ENC_UTF16BE;
24
+ consumed = 2;
25
+ }
26
+
27
+ if (out != NULL) {
28
+ *out = enc;
29
+ }
30
+ return consumed;
31
+ }
@@ -0,0 +1,63 @@
1
+ /* encoding.h — the encoding front-end (TODO.impl/05).
2
+ *
3
+ * MECE law: charset truth lives ONLY here. The scan layer receives a
4
+ * buffer guaranteed valid UTF-8 and never re-validates; output is always
5
+ * UTF-8 (the libleptris serialization guarantee).
6
+ *
7
+ * Zero-copy policy: UTF-8 input is validated in place and borrowed;
8
+ * non-UTF-8 input is transcoded once (into a buffer allocated via the
9
+ * caller's allocator — item 07/11 re-home it into the document arena).
10
+ *
11
+ * v1 scope decisions (recorded in TODO.impl/05): validation is scalar
12
+ * with a SWAR ASCII fast path — the SIMD kernel lands only if item 06's
13
+ * profiles demand it; transcoding rejects ill-formed input (strict) —
14
+ * compat replacement policy arrives with the parse-options item (10).
15
+ */
16
+ #ifndef YEP_ENCODING_H
17
+ #define YEP_ENCODING_H
18
+
19
+ #include <stddef.h>
20
+
21
+ #include "memory/allocator.h"
22
+
23
+ #ifdef __cplusplus
24
+ extern "C" {
25
+ #endif
26
+
27
+ typedef enum {
28
+ YEP_ENC_UNKNOWN = 0,
29
+ YEP_ENC_UTF8,
30
+ YEP_ENC_UTF16LE,
31
+ YEP_ENC_UTF16BE,
32
+ YEP_ENC_UTF32LE,
33
+ YEP_ENC_UTF32BE,
34
+ } yep_encoding;
35
+
36
+ /* Sniffs a byte-order mark. Sets *out (UNKNOWN when none) and returns the
37
+ * BOM length in bytes (0 when none). Partial BOMs at end-of-input match
38
+ * nothing. UTF-32LE is checked before UTF-16LE (FF FE 00 00 is both).
39
+ * out may be NULL. */
40
+ size_t yep_bom_sniff(const unsigned char* p, size_t len, yep_encoding* out);
41
+
42
+ /* Validates UTF-8: 1 when [p, p+len) is well-formed (no overlongs, no
43
+ * surrogates, no > U+10FFFF, no truncation), else 0 with *err_pos set to
44
+ * the offset of the first offending byte (err_pos may be NULL). */
45
+ int yep_utf8_validate(const unsigned char* p, size_t len, size_t* err_pos);
46
+
47
+ /* Well-formed UTF-8 AND the YAML 1.2 c-printable charset: raw C0
48
+ * controls except TAB/LF/CR, DEL, C1 except NEL, U+FFFE/U+FFFF are
49
+ * rejected (charset SSOT — encoding/ is the only place that decides). */
50
+ int yep_printable_validate(const unsigned char* p, size_t len, size_t* err_pos);
51
+
52
+ /* Transcodes UTF-16/32 (any endianness) into freshly allocated UTF-8.
53
+ * On success returns 0, stores the buffer (owned by the caller, freed
54
+ * with the allocator) and its length. Errors: -1 allocation failure,
55
+ * -2 ill-formed input with *err_pos at the offending unit offset. */
56
+ int yep_transcode_to_utf8(const yep_allocator* sys, yep_encoding enc, const unsigned char* src,
57
+ size_t len, unsigned char** out, size_t* out_len, size_t* err_pos);
58
+
59
+ #ifdef __cplusplus
60
+ }
61
+ #endif
62
+
63
+ #endif /* YEP_ENCODING_H */
@@ -0,0 +1,148 @@
1
+ /* transcode.c — UTF-16/UTF-32 (either endianness) → UTF-8 (TODO.impl/05).
2
+ *
3
+ * Strict v1: ill-formed input (unpaired surrogates, values above
4
+ * U+10FFFF, truncated units) is an error at the offending unit; the
5
+ * compat replacement policy arrives with parse options (10).
6
+ * Worst-case sizing: UTF-16 unit 2 bytes → 3 UTF-8 bytes (1.5x);
7
+ * UTF-32 unit 4 → 4 bytes (1x).
8
+ */
9
+
10
+ #include <stdint.h>
11
+
12
+ #include "encoding.h"
13
+
14
+ static unsigned char* yep_emit_utf8(unsigned char* o, uint32_t cp) {
15
+ if (cp < 0x80) {
16
+ *o++ = (unsigned char)cp;
17
+ } else if (cp < 0x800) {
18
+ *o++ = (unsigned char)(0xC0 | (cp >> 6));
19
+ *o++ = (unsigned char)(0x80 | (cp & 0x3F));
20
+ } else if (cp < 0x10000) {
21
+ *o++ = (unsigned char)(0xE0 | (cp >> 12));
22
+ *o++ = (unsigned char)(0x80 | ((cp >> 6) & 0x3F));
23
+ *o++ = (unsigned char)(0x80 | (cp & 0x3F));
24
+ } else {
25
+ *o++ = (unsigned char)(0xF0 | (cp >> 18));
26
+ *o++ = (unsigned char)(0x80 | ((cp >> 12) & 0x3F));
27
+ *o++ = (unsigned char)(0x80 | ((cp >> 6) & 0x3F));
28
+ *o++ = (unsigned char)(0x80 | (cp & 0x3F));
29
+ }
30
+ return o;
31
+ }
32
+
33
+ static uint16_t rd16(const unsigned char* p, int big_endian) {
34
+ return big_endian ? (uint16_t)((p[0] << 8) | p[1]) : (uint16_t)((p[1] << 8) | p[0]);
35
+ }
36
+
37
+ static int yep_is_surrogate(uint32_t cp) {
38
+ return cp >= 0xD800 && cp <= 0xDFFF;
39
+ }
40
+
41
+ static int yep_transcode_utf16(const yep_allocator* sys, int big_endian, const unsigned char* src,
42
+ size_t len, unsigned char** out, size_t* out_len, size_t* err_pos) {
43
+ if (len % 2 != 0) { /* trailing partial unit */
44
+ if (err_pos != NULL) {
45
+ *err_pos = len - 1;
46
+ }
47
+ return -2;
48
+ }
49
+
50
+ size_t units = len / 2;
51
+ size_t max_out = units * 3;
52
+ unsigned char* dst = yep_alloc(sys, max_out ? max_out : 1);
53
+ if (dst == NULL) {
54
+ return -1;
55
+ }
56
+
57
+ unsigned char* o = dst;
58
+ for (size_t i = 0; i < units; i++) {
59
+ uint16_t u = rd16(src + i * 2, big_endian);
60
+ if (u >= 0xD800 && u <= 0xDBFF) {
61
+ if (i + 1 >= units) {
62
+ if (err_pos != NULL) {
63
+ *err_pos = i * 2;
64
+ }
65
+ yep_free(sys, dst);
66
+ return -2; /* lone high surrogate */
67
+ }
68
+ uint16_t v = rd16(src + (i + 1) * 2, big_endian);
69
+ if (v < 0xDC00 || v > 0xDFFF) {
70
+ if (err_pos != NULL) {
71
+ *err_pos = (i + 1) * 2;
72
+ }
73
+ yep_free(sys, dst);
74
+ return -2; /* high surrogate not followed by low */
75
+ }
76
+ uint32_t cp = 0x10000 + (((uint32_t)(u - 0xD800)) << 10) + (uint32_t)(v - 0xDC00);
77
+ o = yep_emit_utf8(o, cp);
78
+ i++;
79
+ } else if (u >= 0xDC00 && u <= 0xDFFF) {
80
+ if (err_pos != NULL) {
81
+ *err_pos = i * 2;
82
+ }
83
+ yep_free(sys, dst);
84
+ return -2; /* lone low surrogate */
85
+ } else {
86
+ o = yep_emit_utf8(o, u);
87
+ }
88
+ }
89
+
90
+ *out = dst;
91
+ *out_len = (size_t)(o - dst);
92
+ return 0;
93
+ }
94
+
95
+ static int yep_transcode_utf32(const yep_allocator* sys, int big_endian, const unsigned char* src,
96
+ size_t len, unsigned char** out, size_t* out_len, size_t* err_pos) {
97
+ size_t units = len / 4;
98
+ unsigned char* dst = yep_alloc(sys, len ? len : 1);
99
+ if (dst == NULL) {
100
+ return -1;
101
+ }
102
+
103
+ unsigned char* o = dst;
104
+ for (size_t i = 0; i < units; i++) {
105
+ const unsigned char* p = src + i * 4;
106
+ uint32_t cp = big_endian ? ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) |
107
+ ((uint32_t)p[2] << 8) | (uint32_t)p[3]
108
+ : ((uint32_t)p[3] << 24) | ((uint32_t)p[2] << 16) |
109
+ ((uint32_t)p[1] << 8) | (uint32_t)p[0];
110
+ if (cp > 0x10FFFF || yep_is_surrogate(cp)) {
111
+ if (err_pos != NULL) {
112
+ *err_pos = i * 4;
113
+ }
114
+ yep_free(sys, dst);
115
+ return -2;
116
+ }
117
+ o = yep_emit_utf8(o, cp);
118
+ }
119
+
120
+ *out = dst;
121
+ *out_len = (size_t)(o - dst);
122
+ return 0;
123
+ }
124
+
125
+ int yep_transcode_to_utf8(const yep_allocator* sys, yep_encoding enc, const unsigned char* src,
126
+ size_t len, unsigned char** out, size_t* out_len, size_t* err_pos) {
127
+ if (sys == NULL || out == NULL || out_len == NULL || (src == NULL && len != 0)) {
128
+ return -1;
129
+ }
130
+ if (len == 0) {
131
+ *out = NULL;
132
+ *out_len = 0;
133
+ return 0;
134
+ }
135
+
136
+ switch (enc) {
137
+ case YEP_ENC_UTF16LE:
138
+ return yep_transcode_utf16(sys, 0, src, len, out, out_len, err_pos);
139
+ case YEP_ENC_UTF16BE:
140
+ return yep_transcode_utf16(sys, 1, src, len, out, out_len, err_pos);
141
+ case YEP_ENC_UTF32LE:
142
+ return yep_transcode_utf32(sys, 0, src, len, out, out_len, err_pos);
143
+ case YEP_ENC_UTF32BE:
144
+ return yep_transcode_utf32(sys, 1, src, len, out, out_len, err_pos);
145
+ default:
146
+ return -2; /* not a transcoding source */
147
+ }
148
+ }
@@ -0,0 +1,178 @@
1
+ /* utf8_validate.c — well-formedness check with a SIMD-gated fast path
2
+ * (TODO.impl/05; TODO.restructure/69). Clean 32-byte chunks ride the
3
+ * gate_scan kernel (0 = every byte printable ASCII — validated in one
4
+ * pass); dirty chunks fall to the exact per-byte walk, which resumes
5
+ * the kernel at the next sequence boundary. The original SWAR path
6
+ * broke at the first non-ASCII byte and never recovered.
7
+ *
8
+ * Rules enforced (Unicode 15 well-formedness): no overlong encodings, no
9
+ * UTF-16 surrogate code points (U+D800..U+DFFF), nothing above U+10FFFF,
10
+ * continuation bytes only where a sequence expects them.
11
+ *
12
+ * yep_printable_validate additionally enforces the YAML 1.2 c-printable
13
+ * charset on the stream (the charset SSOT lives here): raw C0 controls
14
+ * except TAB/LF/CR, DEL, C1 except NEL (U+0085), and U+FFFE/U+FFFF are
15
+ * rejected wherever they appear. Escape sequences are decoded later —
16
+ * printable applies to source bytes only.
17
+ */
18
+
19
+ #include <stdint.h>
20
+ #include <string.h>
21
+
22
+ #include "../common/simd_text.h"
23
+ #include "encoding.h"
24
+
25
+ static int ascii_ok(unsigned char b, int printable) {
26
+ if (!printable) {
27
+ return 1;
28
+ }
29
+ /* c-printable ASCII: TAB, LF, CR, 0x20..0x7E */
30
+ if (b == '\t' || b == '\n' || b == '\r') {
31
+ return 1;
32
+ }
33
+ return b >= 0x20 && b <= 0x7E;
34
+ }
35
+
36
+ /* Code point >= 0x80 allowed by c-printable? (surrogates are already
37
+ * rejected by the well-formedness rules above). */
38
+ static int cp_printable(uint32_t cp) {
39
+ return cp == 0x85 || (cp >= 0xA0 && cp <= 0xFFFD) || cp >= 0x10000;
40
+ }
41
+
42
+ /* The exact per-byte walk: ASCII gate check plus the multibyte DFA.
43
+ * Advances *i by one byte or one whole sequence; returns 0 on error
44
+ * (with *err_pos set), 1 to continue. */
45
+ static int step(const unsigned char* p, size_t len, size_t* i, size_t* err_pos, int printable) {
46
+ size_t at = *i;
47
+ unsigned char b = p[at];
48
+ if (b < 0x80) {
49
+ if (!ascii_ok(b, printable)) {
50
+ if (err_pos != NULL) {
51
+ *err_pos = at;
52
+ }
53
+ return 0;
54
+ }
55
+ *i = at + 1;
56
+ return 1;
57
+ }
58
+
59
+ size_t need; /* continuation bytes expected */
60
+ unsigned char lo, hi; /* allowed range of the first continuation */
61
+ if (b >= 0xC2 && b <= 0xDF) {
62
+ need = 1;
63
+ lo = 0x80;
64
+ hi = 0xBF;
65
+ } else if (b == 0xE0) {
66
+ need = 2;
67
+ lo = 0xA0; /* no overlong two-byte */
68
+ hi = 0xBF;
69
+ } else if ((b >= 0xE1 && b <= 0xEC) || b == 0xEE || b == 0xEF) {
70
+ need = 2;
71
+ lo = 0x80;
72
+ hi = 0xBF;
73
+ } else if (b == 0xED) {
74
+ need = 2;
75
+ lo = 0x80;
76
+ hi = 0x9F; /* no surrogates */
77
+ } else if (b == 0xF0) {
78
+ need = 3;
79
+ lo = 0x90; /* no overlong three-byte */
80
+ hi = 0xBF;
81
+ } else if (b >= 0xF1 && b <= 0xF3) {
82
+ need = 3;
83
+ lo = 0x80;
84
+ hi = 0xBF;
85
+ } else if (b == 0xF4) {
86
+ need = 3;
87
+ lo = 0x80;
88
+ hi = 0x8F; /* no > U+10FFFF */
89
+ } else {
90
+ if (err_pos != NULL) {
91
+ *err_pos = at;
92
+ }
93
+ return 0;
94
+ }
95
+
96
+ /* The sequence spans [at, at + need]; all those bytes must exist. */
97
+ if (at + need >= len) {
98
+ if (err_pos != NULL) {
99
+ *err_pos = at;
100
+ }
101
+ return 0;
102
+ }
103
+
104
+ unsigned char c1 = p[at + 1];
105
+ if (c1 < lo || c1 > hi) {
106
+ if (err_pos != NULL) {
107
+ *err_pos = at + 1;
108
+ }
109
+ return 0;
110
+ }
111
+ for (size_t k = 2; k <= need; k++) {
112
+ if (p[at + k] < 0x80 || p[at + k] > 0xBF) {
113
+ if (err_pos != NULL) {
114
+ *err_pos = at + k;
115
+ }
116
+ return 0;
117
+ }
118
+ }
119
+ if (printable) {
120
+ uint32_t cp;
121
+ if (need == 1) {
122
+ cp = ((uint32_t)(b & 0x1F) << 6) | (uint32_t)(c1 & 0x3F);
123
+ } else if (need == 2) {
124
+ cp = ((uint32_t)(b & 0x0F) << 12) | ((uint32_t)(c1 & 0x3F) << 6) |
125
+ (uint32_t)(p[at + 2] & 0x3F);
126
+ } else {
127
+ cp = ((uint32_t)(b & 0x07) << 18) | ((uint32_t)(c1 & 0x3F) << 12) |
128
+ ((uint32_t)(p[at + 2] & 0x3F) << 6) | (uint32_t)(p[at + 3] & 0x3F);
129
+ }
130
+ if (!cp_printable(cp)) {
131
+ if (err_pos != NULL) {
132
+ *err_pos = at;
133
+ }
134
+ return 0;
135
+ }
136
+ }
137
+ *i = at + 1 + need;
138
+ return 1;
139
+ }
140
+
141
+ static int validate(const unsigned char* p, size_t len, size_t* err_pos, int printable) {
142
+ if (err_pos != NULL) {
143
+ *err_pos = 0;
144
+ }
145
+ if (p == NULL && len != 0) {
146
+ return 0;
147
+ }
148
+
149
+ size_t i = 0;
150
+
151
+ while (i + 32 <= len) {
152
+ if (yep_text_active()->gate_scan((const char*)p + i, 32) == 0) {
153
+ i += 32;
154
+ continue;
155
+ }
156
+ size_t edge = i + 32;
157
+ while (i < edge) {
158
+ if (!step(p, len, &i, err_pos, printable)) {
159
+ return 0;
160
+ }
161
+ }
162
+ }
163
+
164
+ while (i < len) {
165
+ if (!step(p, len, &i, err_pos, printable)) {
166
+ return 0;
167
+ }
168
+ }
169
+ return 1;
170
+ }
171
+
172
+ int yep_utf8_validate(const unsigned char* p, size_t len, size_t* err_pos) {
173
+ return validate(p, len, err_pos, 0);
174
+ }
175
+
176
+ int yep_printable_validate(const unsigned char* p, size_t len, size_t* err_pos) {
177
+ return validate(p, len, err_pos, 1);
178
+ }
@@ -0,0 +1,150 @@
1
+ /* capture.c — the shared capture sink (TODO.impl/12). */
2
+
3
+ #include "capture.h"
4
+
5
+ #include <string.h>
6
+
7
+ #include "../../include/yeptris/events.h"
8
+
9
+ /* The record IS the public ABI shape (events.h pins it). */
10
+ YEPTRIS_CT_ASSERT(sizeof(YeptrisEventRecord) == 36);
11
+
12
+ void yep_rec_init(yep_rec_store* s) {
13
+ s->recs = NULL;
14
+ s->n = 0;
15
+ s->cap = 0;
16
+ s->arena = NULL;
17
+ s->arena_len = 0;
18
+ s->arena_cap = 0;
19
+ }
20
+
21
+ void yep_rec_reset(yep_rec_store* s) {
22
+ s->n = 0;
23
+ s->arena_len = 0;
24
+ }
25
+
26
+ void yep_rec_free(yep_rec_store* s) {
27
+ free(s->recs);
28
+ free(s->arena);
29
+ yep_rec_init(s);
30
+ }
31
+
32
+ static uint32_t arena_put(yep_rec_store* s, const char* p, uint32_t len) {
33
+ if (len == 0 || p == NULL) {
34
+ return 0;
35
+ }
36
+ if (s->arena_len + len > s->arena_cap) {
37
+ size_t cap = s->arena_cap ? s->arena_cap : 256;
38
+ while (s->arena_len + len > cap) {
39
+ cap *= 2;
40
+ }
41
+ char* na = realloc(s->arena, cap);
42
+ if (na == NULL) {
43
+ return 0; /* OOM: the string is dropped, not fatal */
44
+ }
45
+ s->arena = na;
46
+ s->arena_cap = cap;
47
+ }
48
+ memcpy(s->arena + s->arena_len, p, len);
49
+ uint32_t off = (uint32_t)s->arena_len;
50
+ s->arena_len += len;
51
+ return off;
52
+ }
53
+
54
+ int yep_rec_on_event(void* ctx, const yep_event* ev) {
55
+ yep_rec_store* s = (yep_rec_store*)ctx;
56
+ if (s->n == s->cap) {
57
+ size_t cap = s->cap ? s->cap * 2 : 64;
58
+ YeptrisEventRecord* nr = realloc(s->recs, cap * sizeof(*nr));
59
+ if (nr == NULL) {
60
+ return -1;
61
+ }
62
+ s->recs = nr;
63
+ s->cap = cap;
64
+ }
65
+ YeptrisEventRecord* r = &s->recs[s->n];
66
+ memset(r, 0, sizeof(*r));
67
+ switch (ev->type) {
68
+ case YEP_EV_STREAM_START:
69
+ r->type = YEPTRIS_EV_STREAM_START;
70
+ break;
71
+ case YEP_EV_STREAM_END:
72
+ r->type = YEPTRIS_EV_STREAM_END;
73
+ break;
74
+ case YEP_EV_DOCUMENT_START:
75
+ r->type = YEPTRIS_EV_DOCUMENT_START;
76
+ if (ev->style == 1) {
77
+ r->flags |= YEPTRIS_EF_EXPLICIT;
78
+ }
79
+ break;
80
+ case YEP_EV_DOCUMENT_END:
81
+ r->type = YEPTRIS_EV_DOCUMENT_END;
82
+ if (ev->style == 1) {
83
+ r->flags |= YEPTRIS_EF_EXPLICIT;
84
+ }
85
+ break;
86
+ case YEP_EV_SEQ_START:
87
+ r->type = YEPTRIS_EV_SEQUENCE_START;
88
+ break;
89
+ case YEP_EV_SEQ_END:
90
+ r->type = YEPTRIS_EV_SEQUENCE_END;
91
+ break;
92
+ case YEP_EV_MAP_START:
93
+ r->type = YEPTRIS_EV_MAPPING_START;
94
+ break;
95
+ case YEP_EV_MAP_END:
96
+ r->type = YEPTRIS_EV_MAPPING_END;
97
+ break;
98
+ case YEP_EV_SCALAR:
99
+ r->type = YEPTRIS_EV_SCALAR;
100
+ r->style = ev->style;
101
+ r->tag_id = ev->tag_id; /* the resolver's verdict, once */
102
+ if (ev->implicit) {
103
+ r->flags |= YEPTRIS_EF_IMPLICIT;
104
+ }
105
+ break;
106
+ case YEP_EV_ALIAS:
107
+ r->type = YEPTRIS_EV_ALIAS;
108
+ break;
109
+ default:
110
+ return 0;
111
+ }
112
+ if (ev->flow) {
113
+ r->flags |= YEPTRIS_EF_FLOW;
114
+ }
115
+ r->line = ev->line;
116
+ r->col = ev->col;
117
+ r->value_off = arena_put(s, (const char*)ev->value.p, (uint32_t)ev->value.len);
118
+ r->value_len = (uint32_t)ev->value.len;
119
+ r->anchor_off = arena_put(s, (const char*)ev->anchor.p, (uint32_t)ev->anchor.len);
120
+ r->anchor_len = (uint32_t)ev->anchor.len;
121
+ r->tag_off = arena_put(s, (const char*)ev->tag.p, (uint32_t)ev->tag.len);
122
+ r->tag_len = (uint32_t)ev->tag.len;
123
+ s->n++;
124
+ return 0;
125
+ }
126
+
127
+ void yep_rec_materialize(const yep_rec_store* s, size_t i, void* out) {
128
+ const YeptrisEventRecord* r = &s->recs[i];
129
+ YeptrisEvent* e = (YeptrisEvent*)out;
130
+ memset(e, 0, sizeof(*e));
131
+ e->type = (YeptrisEventType)r->type;
132
+ e->style = r->style;
133
+ e->flow = (r->flags & YEPTRIS_EF_FLOW) != 0;
134
+ e->explicit_marker = (r->flags & YEPTRIS_EF_EXPLICIT) != 0;
135
+ e->implicit = (r->flags & YEPTRIS_EF_IMPLICIT) != 0;
136
+ e->line = r->line;
137
+ e->col = r->col;
138
+ if (r->value_len > 0) {
139
+ e->value = s->arena + r->value_off;
140
+ e->value_len = r->value_len;
141
+ }
142
+ if (r->anchor_len > 0) {
143
+ e->anchor = s->arena + r->anchor_off;
144
+ e->anchor_len = r->anchor_len;
145
+ }
146
+ if (r->tag_len > 0) {
147
+ e->tag = s->arena + r->tag_off;
148
+ e->tag_len = r->tag_len;
149
+ }
150
+ }
@@ -0,0 +1,39 @@
1
+ /* capture.h — shared event capture (TODO.impl/12).
2
+ *
3
+ * One sink that appends fixed-size records plus copied strings into an
4
+ * arena. Pull, recorder and iterparse are storage policies over this
5
+ * machinery; push converts directly (no storage). The engine knows
6
+ * nothing about any of them (OCP).
7
+ */
8
+ #ifndef YEP_EVENTS_CAPTURE_H
9
+ #define YEP_EVENTS_CAPTURE_H
10
+
11
+ #include <stdint.h>
12
+ #include <stdlib.h>
13
+
14
+ #include "../../include/yeptris/events.h"
15
+ #include "parse/engine.h"
16
+ #include "parse/events.h"
17
+
18
+ /* Growable records array + string arena; records are the public
19
+ * YeptrisEventRecord layout (the storage SSOT for pull/recorder/
20
+ * iterparse). */
21
+ typedef struct {
22
+ YeptrisEventRecord* recs;
23
+ size_t n, cap;
24
+ char* arena;
25
+ size_t arena_len, arena_cap;
26
+ } yep_rec_store;
27
+
28
+ void yep_rec_init(yep_rec_store* s);
29
+ void yep_rec_reset(yep_rec_store* s);
30
+ void yep_rec_free(yep_rec_store* s);
31
+
32
+ /* The sink: appends one record per event, strings copied to the arena. */
33
+ int yep_rec_on_event(void* ctx, const yep_event* ev);
34
+
35
+ /* Materializes record i into the public event shape; string pointers
36
+ * reference this store's arena. */
37
+ void yep_rec_materialize(const yep_rec_store* s, size_t i, void* out /* YeptrisEvent* */);
38
+
39
+ #endif /* YEP_EVENTS_CAPTURE_H */