yeptris 0.6.16.1-aarch64-linux → 0.6.16.2-aarch64-linux
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/yeptris_native.c +43 -0
- data/lib/yeptris/json.rb +8 -4
- data/lib/yeptris/native-3.3.so +0 -0
- data/lib/yeptris/psych/class_loader.rb +24 -0
- data/lib/yeptris/psych/scalar_scanner.rb +149 -0
- data/lib/yeptris/psych.rb +23 -5
- data/lib/yeptris.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9505473e51a840dbf7c50d8ed7ae56b7e3a9b3592e26787ba0a0b231320bfe86
|
|
4
|
+
data.tar.gz: 78fbfa73c88cc29e5376cde241e310b1b4d65b878e96198faf733640bc695454
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 88c4aaa0e2b48a7b5ce25da76e0035e0cd2d83f2901bde878c6114cdf046ade9c9e7ae74ff70ebc3fe403ea98a5dce86504de060cec35a5fb2e4e6a58a4c83b6
|
|
7
|
+
data.tar.gz: ed0b241f30ae93ea79f8d4deae9ca1f33dd14c124698484c79ea9905e42149564487bbad18234f704125185b0583f7a740c76817eaa2c522b28fa2f3dce20240
|
|
@@ -423,8 +423,51 @@ static VALUE native_gc_mode_set(VALUE self, VALUE mode) {
|
|
|
423
423
|
return mode;
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
+
/* ABI-drift self-check (the #157-audit silent-nil class): the bundle
|
|
427
|
+
* is compiled against a specific yep_dom layout; engine drift makes
|
|
428
|
+
* the walkers read fields at stale offsets — cbor_load returned NIL
|
|
429
|
+
* on valid CBOR in the dev-checkout audit, with no error anywhere.
|
|
430
|
+
* Both walkers must round-trip a known document at load, or Init
|
|
431
|
+
* raises LoadError: lib/yeptris.rb's existing rescue falls back to
|
|
432
|
+
* the FFI ladder (loudly), and the stale bundle never answers with
|
|
433
|
+
* garbage. Runs inside rb_protect so a drifted walk raises instead of
|
|
434
|
+
* crashing the load. */
|
|
435
|
+
static VALUE native_self_check_body(VALUE unused) {
|
|
436
|
+
/* JSON: {"a"=>[1, 2.5, "x", true, nil]} */
|
|
437
|
+
const char* json = "{\"a\":[1,2.5,\"x\",true,null]}";
|
|
438
|
+
VALUE j = yep_rb_parse_json(json, strlen(json), 0);
|
|
439
|
+
if (j == Qundef || !RB_TYPE_P(j, T_HASH)) return Qfalse;
|
|
440
|
+
VALUE a = rb_hash_lookup(j, rb_str_new_cstr("a"));
|
|
441
|
+
if (!RB_TYPE_P(a, T_ARRAY) || RARRAY_LEN(a) != 5) return Qfalse;
|
|
442
|
+
if (!RB_INTEGER_TYPE_P(rb_ary_entry(a, 0))) return Qfalse;
|
|
443
|
+
if (!RB_FLOAT_TYPE_P(rb_ary_entry(a, 1))) return Qfalse;
|
|
444
|
+
if (!RB_TYPE_P(rb_ary_entry(a, 2), T_STRING)) return Qfalse;
|
|
445
|
+
if (rb_ary_entry(a, 3) != Qtrue || !NIL_P(rb_ary_entry(a, 4))) return Qfalse;
|
|
446
|
+
|
|
447
|
+
/* CBOR: A1 61 6B 01 = {"k" => 1} (canonical, hand-encoded) */
|
|
448
|
+
const char cbor[] = "\xA1\x61\x6B\x01";
|
|
449
|
+
VALUE c = yep_rb_cbor_load(cbor, sizeof(cbor) - 1, 0);
|
|
450
|
+
if (c == Qundef || !RB_TYPE_P(c, T_HASH)) return Qfalse;
|
|
451
|
+
VALUE one = rb_hash_lookup(c, rb_str_new_cstr("k"));
|
|
452
|
+
if (!RB_INTEGER_TYPE_P(one) || !rb_eql(one, INT2FIX(1))) return Qfalse;
|
|
453
|
+
return Qtrue;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
static void native_self_check(void) {
|
|
457
|
+
int state = 0;
|
|
458
|
+
VALUE ok = rb_protect(native_self_check_body, Qnil, &state);
|
|
459
|
+
if (state != 0 || ok != Qtrue) {
|
|
460
|
+
if (state != 0) rb_set_errinfo(Qnil);
|
|
461
|
+
rb_raise(rb_eLoadError,
|
|
462
|
+
"yeptris: native materializer failed its ABI self-check "
|
|
463
|
+
"(stale build against a drifted engine?) — refusing to "
|
|
464
|
+
"register; the FFI ladder will carry the load");
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
426
468
|
RUBY_FUNC_EXPORTED void Init_native(void) {
|
|
427
469
|
utf8_enc = rb_utf8_encoding();
|
|
470
|
+
native_self_check();
|
|
428
471
|
VALUE mYep = rb_define_module("Yeptris");
|
|
429
472
|
VALUE mNat = rb_define_module_under(mYep, "Native");
|
|
430
473
|
rb_define_singleton_method(mNat, "load_json", native_load_json, -1);
|
data/lib/yeptris/json.rb
CHANGED
|
@@ -119,7 +119,7 @@ module Yeptris
|
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
-
def walk_tape(src, tape)
|
|
122
|
+
def walk_tape(src, tape, strict_dup = STRICT_DUPLICATE_KEYS)
|
|
123
123
|
n = tape[:count]
|
|
124
124
|
kinds = tape[:kinds].read_bytes(n).unpack("C*")
|
|
125
125
|
offs = tape[:offs].read_bytes(n * 4).unpack("V*")
|
|
@@ -139,7 +139,7 @@ module Yeptris
|
|
|
139
139
|
|
|
140
140
|
docs = [nil] # record 0 (DOC) pre-consumed — the root's slot
|
|
141
141
|
stack = []
|
|
142
|
-
key_sets =
|
|
142
|
+
key_sets = strict_dup ? [{}] : nil
|
|
143
143
|
pending_key = nil
|
|
144
144
|
i = 1
|
|
145
145
|
while i < n
|
|
@@ -152,8 +152,12 @@ module Yeptris
|
|
|
152
152
|
place(docs, stack, pending_key) { {} }
|
|
153
153
|
pending_key = nil
|
|
154
154
|
when T_CLOSE
|
|
155
|
+
# Key frames are pushed per MAP_OPEN — an ARRAY close must
|
|
156
|
+
# not pop the enclosing map's frame (issue found by ea's CI:
|
|
157
|
+
# {"a":[1],"b":[2],"c":[3]} exhausted the frames and the next
|
|
158
|
+
# map key hit key_sets.last.key? on nil under strict mode).
|
|
159
|
+
key_sets&.pop if stack.last.is_a?(Hash)
|
|
155
160
|
stack.pop
|
|
156
|
-
key_sets&.pop
|
|
157
161
|
when T_STR
|
|
158
162
|
# empty-string literals are frozen+shared since Ruby 3.4
|
|
159
163
|
# (and `+""` binds after the method chain anyway), so the
|
|
@@ -256,8 +260,8 @@ module Yeptris
|
|
|
256
260
|
place(docs, stack, pending_key) { {} }
|
|
257
261
|
pending_key = nil
|
|
258
262
|
when ValueML::CLOSE
|
|
263
|
+
key_sets&.pop if stack.last.is_a?(Hash)
|
|
259
264
|
stack.pop
|
|
260
|
-
key_sets&.pop
|
|
261
265
|
when ValueML::V_STR
|
|
262
266
|
text = arena.byteslice(offs[i], lens[i])
|
|
263
267
|
if ikeys[i] == 1 && !stack.empty? && stack.last.is_a?(Hash)
|
data/lib/yeptris/native-3.3.so
CHANGED
|
Binary file
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "date"
|
|
4
|
+
|
|
5
|
+
module Yeptris
|
|
6
|
+
module Psych
|
|
7
|
+
# The minimal ClassLoader face the ScalarScanner port drives
|
|
8
|
+
# (stdlib's loader resolves through the class hierarchy; the
|
|
9
|
+
# scanner only needs the date class and symbolize).
|
|
10
|
+
class ClassLoader
|
|
11
|
+
def date
|
|
12
|
+
Date
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def symbolize str
|
|
16
|
+
str.to_sym
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def load name
|
|
20
|
+
Object.const_get(name)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "date"
|
|
4
|
+
|
|
5
|
+
module Yeptris
|
|
6
|
+
module Psych
|
|
7
|
+
###
|
|
8
|
+
# Scan scalars for built in types — the stdlib Psych::ScalarScanner
|
|
9
|
+
# port (#179): same regexes, same precedence, same edge verdicts.
|
|
10
|
+
# The load path types through the C resolver; this class is the
|
|
11
|
+
# standalone API stdlib code (and Psych's own tests) drive directly.
|
|
12
|
+
class ScalarScanner
|
|
13
|
+
# Taken from http://yaml.org/type/timestamp.html
|
|
14
|
+
TIME = /^-?\d{4}-\d{1,2}-\d{1,2}(?:[Tt]|\s+)\d{1,2}:\d\d:\d\d(?:\.\d*)?(?:\s*(?:Z|[-+]\d{1,2}:?(?:\d\d)?))?$/
|
|
15
|
+
|
|
16
|
+
# Taken from http://yaml.org/type/float.html
|
|
17
|
+
# Base 60, [-+]inf and NaN are handled separately
|
|
18
|
+
FLOAT = /^(?:[-+]?([0-9][0-9_,]*)?\.[0-9]*([eE][-+][0-9]+)?(?# base 10))$/x
|
|
19
|
+
|
|
20
|
+
# Taken from http://yaml.org/type/int.html and modified to ensure at least one numerical symbol exists
|
|
21
|
+
INTEGER_STRICT = /^(?:[-+]?0b[_]*[0-1][0-1_]* (?# base 2)
|
|
22
|
+
|[-+]?0[_]*[0-7][0-7_]* (?# base 8)
|
|
23
|
+
|[-+]?(0|[1-9][0-9_]*) (?# base 10)
|
|
24
|
+
|[-+]?0x[_]*[0-9a-fA-F][0-9a-fA-F_]* (?# base 16))$/x
|
|
25
|
+
|
|
26
|
+
# Same as above, but allows commas.
|
|
27
|
+
# Not to YML spec, but kept for backwards compatibility
|
|
28
|
+
INTEGER_LEGACY = /^(?:[-+]?0b[_,]*[0-1][0-1_,]* (?# base 2)
|
|
29
|
+
|[-+]?0[_,]*[0-7][0-7_,]* (?# base 8)
|
|
30
|
+
|[-+]?(?:0|[1-9](?:[0-9]|,[0-9]|_[0-9])*) (?# base 10)
|
|
31
|
+
|[-+]?0x[_,]*[0-9a-fA-F][0-9a-fA-F_,]* (?# base 16))$/x
|
|
32
|
+
|
|
33
|
+
BOOLEAN_TRUE = /^(yes|true|on)$/i
|
|
34
|
+
BOOLEAN_FALSE = /^(no|false|off)$/i
|
|
35
|
+
|
|
36
|
+
attr_reader :class_loader
|
|
37
|
+
|
|
38
|
+
# Create a new scanner
|
|
39
|
+
def initialize class_loader = ClassLoader, strict_integer: false, parse_symbols: true
|
|
40
|
+
@symbol_cache = {}
|
|
41
|
+
@class_loader = class_loader
|
|
42
|
+
@strict_integer = strict_integer
|
|
43
|
+
@parse_symbols = parse_symbols
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Tokenize +string+ returning the Ruby object
|
|
47
|
+
def tokenize string
|
|
48
|
+
return nil if string.empty?
|
|
49
|
+
return @symbol_cache[string] if @symbol_cache.key?(string)
|
|
50
|
+
integer_regex = @strict_integer ? INTEGER_STRICT : INTEGER_LEGACY
|
|
51
|
+
# Check for a String type, being careful not to get caught by hash keys, hex values, and
|
|
52
|
+
# special floats (e.g., -.inf).
|
|
53
|
+
if string.match?(%r{^[^\d.:-]?[[:alpha:]_\s!@#$%\^&*(){}<>|/\\~;=]+}) || string.match?(/\n/)
|
|
54
|
+
return string if string.length > 5
|
|
55
|
+
|
|
56
|
+
if string.match?(/^[^ytonf~]/i)
|
|
57
|
+
string
|
|
58
|
+
elsif string == '~' || string.match?(/^null$/i)
|
|
59
|
+
nil
|
|
60
|
+
elsif string.match?(BOOLEAN_TRUE)
|
|
61
|
+
true
|
|
62
|
+
elsif string.match?(BOOLEAN_FALSE)
|
|
63
|
+
false
|
|
64
|
+
else
|
|
65
|
+
string
|
|
66
|
+
end
|
|
67
|
+
elsif string.match?(TIME)
|
|
68
|
+
begin
|
|
69
|
+
parse_time string
|
|
70
|
+
rescue ArgumentError
|
|
71
|
+
string
|
|
72
|
+
end
|
|
73
|
+
elsif string.match?(/^\d{4}-(?:1[012]|0\d|\d)-(?:[12]\d|3[01]|0\d|\d)$/)
|
|
74
|
+
begin
|
|
75
|
+
class_loader.date.strptime(string, '%F', Date::GREGORIAN)
|
|
76
|
+
rescue ArgumentError
|
|
77
|
+
string
|
|
78
|
+
end
|
|
79
|
+
elsif string.match?(/^\+?\.inf$/i)
|
|
80
|
+
Float::INFINITY
|
|
81
|
+
elsif string.match?(/^-\.inf$/i)
|
|
82
|
+
-Float::INFINITY
|
|
83
|
+
elsif string.match?(/^\.nan$/i)
|
|
84
|
+
Float::NAN
|
|
85
|
+
elsif @parse_symbols && string.match?(/^:./)
|
|
86
|
+
if string =~ /^:(["'])(.*)\1/
|
|
87
|
+
@symbol_cache[string] = class_loader.symbolize($2.sub(/^:/, ''))
|
|
88
|
+
else
|
|
89
|
+
@symbol_cache[string] = class_loader.symbolize(string.sub(/^:/, ''))
|
|
90
|
+
end
|
|
91
|
+
elsif string.match?(/^[-+]?[0-9][0-9_]*(:[0-5]?[0-9]){1,2}$/)
|
|
92
|
+
i = 0
|
|
93
|
+
string.split(':').each_with_index do |n, e|
|
|
94
|
+
i += (n.to_i * 60**(e - 2).abs)
|
|
95
|
+
end
|
|
96
|
+
i
|
|
97
|
+
elsif string.match?(/^[-+]?[0-9][0-9_]*(:[0-5]?[0-9]){1,2}\.[0-9_]*$/)
|
|
98
|
+
i = 0
|
|
99
|
+
string.split(':').each_with_index do |n, e|
|
|
100
|
+
i += (n.to_f * 60**(e - 2).abs)
|
|
101
|
+
end
|
|
102
|
+
i
|
|
103
|
+
elsif string.match?(FLOAT)
|
|
104
|
+
if string.match?(/\A[-+]?\.\Z/)
|
|
105
|
+
string
|
|
106
|
+
else
|
|
107
|
+
Float(string.delete(',_').gsub(/\.([Ee]|$)/, '\1'))
|
|
108
|
+
end
|
|
109
|
+
elsif string.match?(integer_regex)
|
|
110
|
+
parse_int string
|
|
111
|
+
else
|
|
112
|
+
string
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Parse and return an int from +string+
|
|
117
|
+
def parse_int string
|
|
118
|
+
Integer(string.delete(',_'))
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
###
|
|
122
|
+
# Parse and return a Time from +string+
|
|
123
|
+
def parse_time string
|
|
124
|
+
date, time = *(string.split(/[Tt]|\s+/, 2))
|
|
125
|
+
(yy, m, dd) = date.match(/^(-?\d{4})-(\d{1,2})-(\d{1,2})/).captures.map { |x| x.to_i }
|
|
126
|
+
md = time.match(/(\d+:\d+:\d+)(?:\.(\d*))?\s*(Z|[-+]\d+(:\d\d)?)?/)
|
|
127
|
+
|
|
128
|
+
(hh, mm, ss) = md[1].split(':').map { |x| x.to_i }
|
|
129
|
+
us = (md[2] ? Rational("0.#{md[2]}") : 0) * 1_000_000
|
|
130
|
+
|
|
131
|
+
time = Time.utc(yy, m, dd, hh, mm, ss, us)
|
|
132
|
+
|
|
133
|
+
return time if 'Z' == md[3]
|
|
134
|
+
return Time.at(time.to_i, us) unless md[3]
|
|
135
|
+
|
|
136
|
+
tz = md[3].match(/^([+\-]?\d{1,2})\:?(\d{1,2})?$/)[1..-1].compact.map { |digit| Integer(digit, 10) }
|
|
137
|
+
offset = tz.first * 3600
|
|
138
|
+
|
|
139
|
+
if offset < 0
|
|
140
|
+
offset -= ((tz[1] || 0) * 60)
|
|
141
|
+
else
|
|
142
|
+
offset += ((tz[1] || 0) * 60)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
Time.new(yy, m, dd, hh, mm, ss + us / 1_000_000r, offset)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
data/lib/yeptris/psych.rb
CHANGED
|
@@ -22,6 +22,9 @@ require "yeptris"
|
|
|
22
22
|
# document without materializing.
|
|
23
23
|
module Yeptris
|
|
24
24
|
module Psych
|
|
25
|
+
autoload :ClassLoader, "yeptris/psych/class_loader"
|
|
26
|
+
autoload :ScalarScanner, "yeptris/psych/scalar_scanner"
|
|
27
|
+
|
|
25
28
|
# The tag registries (Psych's class-level API, #95 bug 4):
|
|
26
29
|
# load_tags maps a serialized tag to the Class that revives it;
|
|
27
30
|
# dump_tags overrides the emitted tag for a Class. Consulted by
|
|
@@ -258,18 +261,28 @@ module Yeptris
|
|
|
258
261
|
::Yeptris::Psych.dump(obj, io, options)
|
|
259
262
|
end
|
|
260
263
|
|
|
261
|
-
def load_stream(yaml, **kwargs)
|
|
264
|
+
def load_stream(yaml, **kwargs, &block)
|
|
262
265
|
# materialize each document's root directly — the stream
|
|
263
266
|
# children share one C document, so their handles would all
|
|
264
|
-
# resolve to the first document's tree
|
|
267
|
+
# resolve to the first document's tree. stdlib's block form
|
|
268
|
+
# yields each loaded document's object (#179 round 4).
|
|
265
269
|
doc = Yeptris::Document.parse(yaml, schema: :compat_11)
|
|
266
270
|
return nil if doc.nil? # the legal empty stream
|
|
267
271
|
|
|
268
272
|
begin
|
|
269
|
-
(0...doc.document_count).map { |i| doc.root(i).to_ruby }
|
|
273
|
+
docs = (0...doc.document_count).map { |i| doc.root(i).to_ruby }
|
|
270
274
|
ensure
|
|
271
275
|
doc.free
|
|
272
276
|
end
|
|
277
|
+
docs.each { |d| block.call(d) } if block
|
|
278
|
+
docs
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# safe_load_stream: stdlib's surface — the stream form of
|
|
282
|
+
# safe_load. Our load_stream is already safe-by-default
|
|
283
|
+
# (Psych 5 semantics), so this is the yielding wrapper.
|
|
284
|
+
def safe_load_stream(yaml, **kwargs, &block)
|
|
285
|
+
load_stream(yaml, **kwargs, &block)
|
|
273
286
|
end
|
|
274
287
|
|
|
275
288
|
# The first document's node tree (no Ruby materialization).
|
|
@@ -299,13 +312,14 @@ module Yeptris
|
|
|
299
312
|
# handles GC-free. (The block-yielding form is tracked under
|
|
300
313
|
# #179: the current implementation materializes eagerly; the
|
|
301
314
|
# block is only honored as a no-op convenience.)
|
|
302
|
-
_ = block # reserved for the future yielding form (#179)
|
|
303
315
|
doc = Yeptris::Document.parse(yaml, schema: :compat_11)
|
|
304
316
|
return nil if doc.nil? || doc.document_count.zero?
|
|
305
317
|
|
|
306
318
|
stream = Nodes::Stream.new
|
|
307
319
|
(0...doc.document_count).each do |i|
|
|
308
|
-
|
|
320
|
+
child = Nodes::Builder.document_stream_child(doc, i)
|
|
321
|
+
stream.children << child
|
|
322
|
+
block.call(child) if block # stdlib's yielding form (#179 round 4)
|
|
309
323
|
end
|
|
310
324
|
# ownership: the DOCUMENT wrapper is the sole owner — its own
|
|
311
325
|
# finalizer (pointer-only closure) frees the C memory; the
|
|
@@ -450,6 +464,10 @@ module Yeptris
|
|
|
450
464
|
# tree stay valid while the tree is reachable; a GC finalizer
|
|
451
465
|
# releases the C memory when it is not.
|
|
452
466
|
class Document < Node
|
|
467
|
+
# The document's root as a Ruby object (the stream-yield face).
|
|
468
|
+
def to_ruby
|
|
469
|
+
children.first&.to_ruby
|
|
470
|
+
end
|
|
453
471
|
attr_reader :version, :tags
|
|
454
472
|
|
|
455
473
|
def initialize(version = [], tags = {})
|
data/lib/yeptris.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Yeptris
|
|
4
4
|
# The gem's version lives in the parent namespace's file — the last
|
|
5
5
|
# internal require (yeptris/version) retired with it.
|
|
6
|
-
VERSION = "0.6.16.
|
|
6
|
+
VERSION = "0.6.16.2".freeze
|
|
7
7
|
# The error hierarchy lives in THIS file (the parent namespace's
|
|
8
8
|
# own file): nested constants do not trigger a parent-constant
|
|
9
9
|
# autoload, and the law forbids internal requires — defining the
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yeptris
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.16.
|
|
4
|
+
version: 0.6.16.2
|
|
5
5
|
platform: aarch64-linux
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ffi
|
|
@@ -50,11 +50,13 @@ files:
|
|
|
50
50
|
- lib/yeptris/native-3.3.so
|
|
51
51
|
- lib/yeptris/node.rb
|
|
52
52
|
- lib/yeptris/psych.rb
|
|
53
|
+
- lib/yeptris/psych/class_loader.rb
|
|
53
54
|
- lib/yeptris/psych/coder_shim.rb
|
|
54
55
|
- lib/yeptris/psych/drop_in.rb
|
|
55
56
|
- lib/yeptris/psych/encodable.rb
|
|
56
57
|
- lib/yeptris/psych/handler.rb
|
|
57
58
|
- lib/yeptris/psych/parser.rb
|
|
59
|
+
- lib/yeptris/psych/scalar_scanner.rb
|
|
58
60
|
- lib/yeptris/psych/visitors.rb
|
|
59
61
|
- lib/yeptris/schema.rb
|
|
60
62
|
- lib/yeptris/valueml.rb
|