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,105 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yeptris
|
|
4
|
+
module Psych
|
|
5
|
+
# The event parser (TODO.impl/15 phase E): drives a Handler with
|
|
6
|
+
# Psych's exact event shapes over the yeptris recorder — one bulk
|
|
7
|
+
# record drain (the Materializer's seam), then a pure-Ruby
|
|
8
|
+
# dispatch loop. No callback marshaling, no per-event FFI calls.
|
|
9
|
+
class Parser
|
|
10
|
+
attr_accessor :handler
|
|
11
|
+
attr_reader :filename
|
|
12
|
+
|
|
13
|
+
ANY = 0
|
|
14
|
+
UTF8 = 1
|
|
15
|
+
UTF16LE = 2
|
|
16
|
+
UTF16BE = 3
|
|
17
|
+
|
|
18
|
+
def initialize(handler = Handler.new)
|
|
19
|
+
@handler = handler
|
|
20
|
+
@filename = nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def parse(yaml, filename = nil)
|
|
24
|
+
yaml = Yeptris.read_input(yaml)
|
|
25
|
+
yaml = yaml.to_s
|
|
26
|
+
@filename = filename
|
|
27
|
+
flat, arena = Materializer.drain(yaml, schema: :compat_11)
|
|
28
|
+
dispatch(flat, arena)
|
|
29
|
+
self
|
|
30
|
+
rescue ParseError => e
|
|
31
|
+
raise SyntaxError.from_parse_error(e)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
STREAM_START = Materializer::STREAM_START
|
|
37
|
+
STREAM_END = Materializer::STREAM_END
|
|
38
|
+
DOCUMENT_START = Materializer::DOCUMENT_START
|
|
39
|
+
DOCUMENT_END = Materializer::DOCUMENT_END
|
|
40
|
+
SEQUENCE_START = Materializer::SEQUENCE_START
|
|
41
|
+
MAPPING_START = Materializer::MAPPING_START
|
|
42
|
+
SCALAR = Materializer::SCALAR
|
|
43
|
+
ALIAS = Materializer::ALIAS
|
|
44
|
+
|
|
45
|
+
EF_FLOW = 1 << 0
|
|
46
|
+
EF_EXPLICIT = 1 << 1
|
|
47
|
+
STYLE_PLAIN = 1
|
|
48
|
+
STYLE_SINGLE_QUOTED = 2
|
|
49
|
+
STYLE_DOUBLE_QUOTED = 3
|
|
50
|
+
|
|
51
|
+
def dispatch(flat, arena)
|
|
52
|
+
h = @handler
|
|
53
|
+
i = 0
|
|
54
|
+
while i < flat.length
|
|
55
|
+
type = flat[i]
|
|
56
|
+
style = flat[i + 1]
|
|
57
|
+
flags = flat[i + 2]
|
|
58
|
+
value = field(flat, arena, i + 6)
|
|
59
|
+
anchor = field(flat, arena, i + 8)
|
|
60
|
+
tag = field(flat, arena, i + 10)
|
|
61
|
+
case type
|
|
62
|
+
when STREAM_START then h.start_stream(UTF8)
|
|
63
|
+
when STREAM_END then h.end_stream
|
|
64
|
+
# version: [] when no %YAML directive (Psych's own shape);
|
|
65
|
+
# a declared directive's [major, minor] is not carried by
|
|
66
|
+
# the record — the one documented divergence
|
|
67
|
+
when DOCUMENT_START then h.start_document([], [], (flags & EF_EXPLICIT).zero?)
|
|
68
|
+
when DOCUMENT_END then h.end_document((flags & EF_EXPLICIT).zero?)
|
|
69
|
+
when SEQUENCE_START
|
|
70
|
+
h.start_sequence(anchor, tag, tag.nil?, (flags & EF_FLOW).zero? ? Handler::BLOCK : Handler::FLOW)
|
|
71
|
+
when Materializer::SEQUENCE_END then h.end_sequence
|
|
72
|
+
when MAPPING_START
|
|
73
|
+
h.start_mapping(anchor, tag, tag.nil?, (flags & EF_FLOW).zero? ? Handler::BLOCK : Handler::FLOW)
|
|
74
|
+
when Materializer::MAPPING_END then h.end_mapping
|
|
75
|
+
when SCALAR
|
|
76
|
+
# A synthesized empty scalar (empty document, '?' empty
|
|
77
|
+
# key) carries style ANY(0); Psych's C emits plain(1)
|
|
78
|
+
# with an empty String value — normalized here, at the
|
|
79
|
+
# boundary, so the emitter's style chooser is untouched
|
|
80
|
+
if style.zero?
|
|
81
|
+
style = STYLE_PLAIN
|
|
82
|
+
end
|
|
83
|
+
value = +"" if value.nil?
|
|
84
|
+
# libyaml's plain_implicit: a plain scalar that carried
|
|
85
|
+
# no explicit tag (an explicit tag kills implicit typing)
|
|
86
|
+
plain = style == STYLE_PLAIN && tag.nil?
|
|
87
|
+
# quoted_implicit covers every explicit style — single,
|
|
88
|
+
# double, literal, folded — when the tag was absent
|
|
89
|
+
quoted = !plain && tag.nil? && style > STYLE_PLAIN
|
|
90
|
+
h.scalar(value, anchor, tag, plain, quoted, style)
|
|
91
|
+
when ALIAS then h.alias(value)
|
|
92
|
+
end
|
|
93
|
+
i += Materializer::FIELDS
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def field(flat, arena, at)
|
|
98
|
+
len = flat[at + 1]
|
|
99
|
+
return nil if len.zero?
|
|
100
|
+
|
|
101
|
+
arena.byteslice(flat[at], len)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
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
|