ciborium 0.1.0
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/CHANGELOG.md +9 -0
- data/LICENSE.txt +21 -0
- data/NOTICE.md +26 -0
- data/README.md +221 -0
- data/Rakefile +46 -0
- data/ext/ciborium/Cargo.lock +339 -0
- data/ext/ciborium/Cargo.toml +26 -0
- data/ext/ciborium/build.rs +4 -0
- data/ext/ciborium/extconf.rb +8 -0
- data/ext/ciborium/src/canonical.rs +60 -0
- data/ext/ciborium/src/cursor.rs +106 -0
- data/ext/ciborium/src/decode.rs +325 -0
- data/ext/ciborium/src/encode.rs +330 -0
- data/ext/ciborium/src/error.rs +53 -0
- data/ext/ciborium/src/lib.rs +153 -0
- data/ext/ciborium/src/scan.rs +223 -0
- data/lib/ciborium/compat/buffer.rb +190 -0
- data/lib/ciborium/compat/errors.rb +30 -0
- data/lib/ciborium/compat/packer.rb +90 -0
- data/lib/ciborium/compat/unpacker.rb +111 -0
- data/lib/ciborium/compat.rb +110 -0
- data/lib/ciborium/decode_options.rb +61 -0
- data/lib/ciborium/decoder.rb +141 -0
- data/lib/ciborium/encode_options.rb +41 -0
- data/lib/ciborium/encoded.rb +10 -0
- data/lib/ciborium/encoder.rb +80 -0
- data/lib/ciborium/errors.rb +25 -0
- data/lib/ciborium/extensions/bignum.rb +35 -0
- data/lib/ciborium/extensions/regexp.rb +41 -0
- data/lib/ciborium/extensions/time.rb +39 -0
- data/lib/ciborium/extensions/uri.rb +29 -0
- data/lib/ciborium/extensions.rb +92 -0
- data/lib/ciborium/native.rb +25 -0
- data/lib/ciborium/replace.rb +105 -0
- data/lib/ciborium/simple.rb +21 -0
- data/lib/ciborium/tagged.rb +18 -0
- data/lib/ciborium/version.rb +6 -0
- data/lib/ciborium.rb +65 -0
- data/sig/generated/ciborium/compat/buffer.rbs +95 -0
- data/sig/generated/ciborium/compat/errors.rbs +23 -0
- data/sig/generated/ciborium/compat/packer.rbs +53 -0
- data/sig/generated/ciborium/compat/unpacker.rbs +59 -0
- data/sig/generated/ciborium/compat.rbs +57 -0
- data/sig/generated/ciborium/decode_options.rbs +41 -0
- data/sig/generated/ciborium/decoder.rbs +85 -0
- data/sig/generated/ciborium/encode_options.rbs +33 -0
- data/sig/generated/ciborium/encoded.rbs +16 -0
- data/sig/generated/ciborium/encoder.rbs +50 -0
- data/sig/generated/ciborium/errors.rbs +32 -0
- data/sig/generated/ciborium/extensions/bignum.rbs +20 -0
- data/sig/generated/ciborium/extensions/regexp.rbs +30 -0
- data/sig/generated/ciborium/extensions/time.rbs +22 -0
- data/sig/generated/ciborium/extensions/uri.rbs +20 -0
- data/sig/generated/ciborium/extensions.rbs +35 -0
- data/sig/generated/ciborium/native.rbs +10 -0
- data/sig/generated/ciborium/replace.rbs +37 -0
- data/sig/generated/ciborium/version.rbs +5 -0
- data/sig/generated/ciborium.rbs +30 -0
- data/sig/manual/ciborium/extensions.rbs +12 -0
- data/sig/manual/ciborium/native.rbs +23 -0
- data/sig/manual/ciborium/tagged.rbs +25 -0
- metadata +123 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
4
|
+
module Ciborium
|
|
5
|
+
# Tag handling beyond Tagged, enabled per call through the extensions: option.
|
|
6
|
+
#
|
|
7
|
+
# An extension is any object that responds to:
|
|
8
|
+
#
|
|
9
|
+
# - tags: the tag numbers it decodes
|
|
10
|
+
# - classes: the classes whose instances it encodes
|
|
11
|
+
# - decode(tag, value): the object for a tag's decoded content
|
|
12
|
+
# - encode(object): an object to encode in place of object, typically a Tagged
|
|
13
|
+
#
|
|
14
|
+
# Symbols name the built-in extensions.
|
|
15
|
+
module Extensions
|
|
16
|
+
BUILTIN = {
|
|
17
|
+
bignum: "BigInteger",
|
|
18
|
+
time: "Time",
|
|
19
|
+
uri: "URI",
|
|
20
|
+
regexp: "Regexp",
|
|
21
|
+
}.freeze #: Hash[Symbol, String]
|
|
22
|
+
|
|
23
|
+
# Resolves Symbols to the built-in extensions and checks every entry is an extension.
|
|
24
|
+
#
|
|
25
|
+
#: (untyped extensions) -> Array[_Extension]
|
|
26
|
+
def self.resolve(extensions)
|
|
27
|
+
unless extensions.is_a?(Array)
|
|
28
|
+
raise ArgumentError, "extensions must be an Array, got #{extensions.inspect}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
extensions.map do |extension|
|
|
32
|
+
next builtin(extension) if extension.is_a?(Symbol)
|
|
33
|
+
|
|
34
|
+
unless [:tags, :classes, :decode, :encode].all? { |m| extension.respond_to?(m) }
|
|
35
|
+
raise ArgumentError, "#{extension.inspect} does not implement tags, classes, decode and encode"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
extension
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Maps each tag to a callable that wraps the extension's failures in ExtensionError.
|
|
43
|
+
#
|
|
44
|
+
#: (Array[_Extension] extensions) -> Hash[Integer, ^(Integer, untyped) -> untyped]?
|
|
45
|
+
def self.tag_handlers(extensions)
|
|
46
|
+
return if extensions.empty?
|
|
47
|
+
|
|
48
|
+
handlers = {} #: Hash[Integer, ^(Integer, untyped) -> untyped]
|
|
49
|
+
extensions.each do |extension|
|
|
50
|
+
extension.tags.each do |tag|
|
|
51
|
+
raise ArgumentError, "more than one extension decodes tag #{tag}" if handlers.key?(tag)
|
|
52
|
+
|
|
53
|
+
handlers[tag] = ->(t, value) do
|
|
54
|
+
extension.decode(t, value)
|
|
55
|
+
rescue StandardError
|
|
56
|
+
raise ExtensionError, "#{extension.inspect} failed to decode tag #{t}"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
handlers.freeze
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Pairs each class with a callable that wraps the extension's failures in EncodeError.
|
|
64
|
+
#
|
|
65
|
+
#: (Array[_Extension] extensions) -> Array[[Module, ^(untyped) -> untyped]]?
|
|
66
|
+
def self.class_handlers(extensions)
|
|
67
|
+
return if extensions.empty?
|
|
68
|
+
|
|
69
|
+
extensions.flat_map do |extension|
|
|
70
|
+
handler = ->(object) do
|
|
71
|
+
extension.encode(object)
|
|
72
|
+
rescue StandardError
|
|
73
|
+
raise EncodeError, "#{extension.inspect} failed to encode an instance of #{object.class}"
|
|
74
|
+
end
|
|
75
|
+
extension.classes.map do |klass|
|
|
76
|
+
raise ArgumentError, "#{extension.inspect} lists #{klass.inspect}, which is not a Module" unless klass.is_a?(Module)
|
|
77
|
+
|
|
78
|
+
[klass, handler] #: [Module, ^(untyped) -> untyped]
|
|
79
|
+
end
|
|
80
|
+
end.freeze
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#: (Symbol name) -> _Extension
|
|
84
|
+
private_class_method def self.builtin(name)
|
|
85
|
+
class_name = BUILTIN.fetch(name) do
|
|
86
|
+
raise ArgumentError, "unknown extension #{name.inspect}; built-in ones are #{BUILTIN.keys.inspect}"
|
|
87
|
+
end
|
|
88
|
+
require_relative "extensions/#{name}"
|
|
89
|
+
const_get(class_name).new
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
4
|
+
require "rbconfig"
|
|
5
|
+
|
|
6
|
+
# Precompiled gems carry one extension per Ruby minor under lib/ciborium/<X.Y>/.
|
|
7
|
+
fat = File.expand_path("#{RUBY_VERSION[/\A\d+\.\d+/]}/ciborium_native", __dir__.to_s)
|
|
8
|
+
if File.exist?("#{fat}.#{RbConfig::CONFIG.fetch("DLEXT")}")
|
|
9
|
+
require fat
|
|
10
|
+
else
|
|
11
|
+
require_relative "ciborium_native"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module Ciborium
|
|
15
|
+
module Native
|
|
16
|
+
# Called by the encoder for text in an encoding other than UTF-8 or US-ASCII.
|
|
17
|
+
#
|
|
18
|
+
#: (String string) -> String
|
|
19
|
+
def self.transcode(string)
|
|
20
|
+
string.encode(Encoding::UTF_8)
|
|
21
|
+
rescue EncodingError
|
|
22
|
+
raise EncodeError, "cannot transcode a #{string.encoding} string to UTF-8"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
4
|
+
# Installs Ciborium::Compat as CBOR, the constant of the cbor gem, in the manner of resolv-replace.
|
|
5
|
+
# Require it before anything requires "cbor": with Bundler, after bundler/setup and before
|
|
6
|
+
# Bundler.require.
|
|
7
|
+
|
|
8
|
+
require_relative "compat"
|
|
9
|
+
|
|
10
|
+
module Ciborium
|
|
11
|
+
module Compat
|
|
12
|
+
# Classes the cbor gem gives to_cbor. URI::Generic is included when URI is loaded.
|
|
13
|
+
CORE_EXT_CLASSES = [
|
|
14
|
+
NilClass,
|
|
15
|
+
TrueClass,
|
|
16
|
+
FalseClass,
|
|
17
|
+
Integer,
|
|
18
|
+
Float,
|
|
19
|
+
String,
|
|
20
|
+
Array,
|
|
21
|
+
Hash,
|
|
22
|
+
Symbol,
|
|
23
|
+
Time,
|
|
24
|
+
Regexp,
|
|
25
|
+
Ciborium::Tagged,
|
|
26
|
+
Ciborium::Simple,
|
|
27
|
+
].freeze #: Array[Module]
|
|
28
|
+
|
|
29
|
+
# Constants of the cbor gem that CBOR carries.
|
|
30
|
+
CBOR_CONSTANTS = [
|
|
31
|
+
:Packer, :Unpacker, :Buffer, :Tagged, :Simple, :UnpackError, :MalformedFormatError, :StackError, :TypeError,
|
|
32
|
+
].freeze #: Array[Symbol]
|
|
33
|
+
|
|
34
|
+
# Module functions of the cbor gem that CBOR carries.
|
|
35
|
+
CBOR_FUNCTIONS = [:encode, :pack, :dump, :decode, :unpack, :load].freeze #: Array[Symbol]
|
|
36
|
+
|
|
37
|
+
# @rbs self.@facade: Module?
|
|
38
|
+
|
|
39
|
+
# The frozen module installed as CBOR. It delegates to Compat rather than being Compat, so the
|
|
40
|
+
# cbor gem's extension, should it load anyway, fails on reopening it instead of replacing
|
|
41
|
+
# Compat's methods with its own.
|
|
42
|
+
#
|
|
43
|
+
#: () -> Module
|
|
44
|
+
def self.facade
|
|
45
|
+
@facade ||= begin
|
|
46
|
+
compat = self
|
|
47
|
+
facade = Module.new
|
|
48
|
+
CBOR_CONSTANTS.each { |name| facade.const_set(name, const_get(name)) }
|
|
49
|
+
CBOR_FUNCTIONS.each do |name|
|
|
50
|
+
facade.define_singleton_method(name) { |*args| compat.public_send(name, *args) }
|
|
51
|
+
end
|
|
52
|
+
[Packer, Unpacker, Buffer].each(&:freeze)
|
|
53
|
+
facade.freeze
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Marks every file of the installed cbor gems that require "cbor" could load as loaded.
|
|
58
|
+
#
|
|
59
|
+
#: () -> void
|
|
60
|
+
def self.block_cbor_gem
|
|
61
|
+
$LOADED_FEATURES.concat(cbor_gem_features - $LOADED_FEATURES)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# The cbor gem's entry point and extension: as found on the load path, and in every
|
|
65
|
+
# installed version, since RubyGems may activate any of them later.
|
|
66
|
+
#
|
|
67
|
+
#: () -> Array[String]
|
|
68
|
+
def self.cbor_gem_features
|
|
69
|
+
paths = ["cbor", "cbor/cbor"].filter_map do |feature|
|
|
70
|
+
_type, path = $LOAD_PATH.resolve_feature_path(feature)
|
|
71
|
+
path
|
|
72
|
+
rescue LoadError
|
|
73
|
+
nil
|
|
74
|
+
end
|
|
75
|
+
if defined?(Gem::Specification)
|
|
76
|
+
Gem::Specification.find_all_by_name("cbor").each do |spec|
|
|
77
|
+
spec.full_require_paths.each do |dir|
|
|
78
|
+
paths.concat(Dir[File.join(dir, "cbor.rb"), File.join(dir, "cbor", "{,*/}cbor.{so,bundle}")])
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
paths.uniq
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
#: () -> void
|
|
86
|
+
def self.install
|
|
87
|
+
block_cbor_gem
|
|
88
|
+
if Object.const_defined?(:CBOR, false) && !Object.const_get(:CBOR, false).equal?(facade)
|
|
89
|
+
warn(
|
|
90
|
+
"ciborium/replace: CBOR was already defined, likely by the cbor gem, and is now replaced. " \
|
|
91
|
+
"Require ciborium/replace before Bundler.require so the cbor gem is never loaded.",
|
|
92
|
+
)
|
|
93
|
+
Object.send(:remove_const, :CBOR)
|
|
94
|
+
end
|
|
95
|
+
Object.const_set(:CBOR, facade) unless Object.const_defined?(:CBOR, false)
|
|
96
|
+
|
|
97
|
+
classes = CORE_EXT_CLASSES.dup
|
|
98
|
+
classes << ::URI::Generic if defined?(::URI::Generic)
|
|
99
|
+
# prepend rather than include, so these replace to_cbor the cbor gem defined on the class.
|
|
100
|
+
classes.each { |klass| klass.prepend(CoreExt) }
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
Ciborium::Compat.install
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: disabled
|
|
3
|
+
|
|
4
|
+
module Ciborium
|
|
5
|
+
# A simple value (RFC 8949 section 3.3) other than false, true and null.
|
|
6
|
+
Simple = Data.define(:value)
|
|
7
|
+
|
|
8
|
+
class Simple
|
|
9
|
+
def initialize(value:)
|
|
10
|
+
raise ::TypeError, "simple value must be an Integer, got #{value.inspect}" unless value.is_a?(Integer)
|
|
11
|
+
# 24 to 31 are reserved, so no well-formed encoding exists for them.
|
|
12
|
+
unless value.between?(0, 23) || value.between?(32, 255)
|
|
13
|
+
raise ::RangeError, "simple value must be in 0..23 or 32..255, got #{value}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
super
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
UNDEFINED = Simple.new(23)
|
|
21
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: disabled
|
|
3
|
+
|
|
4
|
+
module Ciborium
|
|
5
|
+
# A tagged data item (RFC 8949 section 3.4) that no allowlisted extension interprets.
|
|
6
|
+
Tagged = Data.define(:tag, :value)
|
|
7
|
+
|
|
8
|
+
class Tagged
|
|
9
|
+
MAX_TAG = 2**64 - 1
|
|
10
|
+
|
|
11
|
+
def initialize(tag:, value:)
|
|
12
|
+
raise ::TypeError, "tag must be an Integer, got #{tag.inspect}" unless tag.is_a?(Integer)
|
|
13
|
+
raise ::RangeError, "tag must be between 0 and 2**64-1, got #{tag}" unless tag.between?(0, MAX_TAG)
|
|
14
|
+
|
|
15
|
+
super
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/ciborium.rb
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
4
|
+
require_relative "ciborium/version"
|
|
5
|
+
require_relative "ciborium/errors"
|
|
6
|
+
require_relative "ciborium/tagged"
|
|
7
|
+
require_relative "ciborium/simple"
|
|
8
|
+
require_relative "ciborium/encoded"
|
|
9
|
+
require_relative "ciborium/native"
|
|
10
|
+
require_relative "ciborium/extensions"
|
|
11
|
+
require_relative "ciborium/decode_options"
|
|
12
|
+
require_relative "ciborium/encode_options"
|
|
13
|
+
require_relative "ciborium/encoder"
|
|
14
|
+
require_relative "ciborium/decoder"
|
|
15
|
+
|
|
16
|
+
# A CBOR (RFC 8949) encoder and decoder. Tags carry no meaning unless an extension for them is
|
|
17
|
+
# allowlisted.
|
|
18
|
+
module Ciborium
|
|
19
|
+
# Encodes object into a binary String.
|
|
20
|
+
#
|
|
21
|
+
# Options are those of EncodeOptions.build.
|
|
22
|
+
#
|
|
23
|
+
#: (untyped object, **untyped options) -> String
|
|
24
|
+
def self.encode(object, **options)
|
|
25
|
+
opts = EncodeOptions.build(**options)
|
|
26
|
+
Native.encode(object, opts.max_depth, opts.flags, opts.fallback, opts.class_handlers)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Decodes a single data item. Raises MalformedError when bytes follow it.
|
|
30
|
+
#
|
|
31
|
+
# Options are those of DecodeOptions.build.
|
|
32
|
+
#
|
|
33
|
+
#: (String bytes, **untyped options) -> untyped
|
|
34
|
+
def self.decode(bytes, **options)
|
|
35
|
+
value, pos = decode_prefix(bytes, **options)
|
|
36
|
+
unless pos == bytes.bytesize
|
|
37
|
+
raise MalformedError, "#{bytes.bytesize - pos} bytes follow the decoded item"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
value
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Decodes the data item at the start of bytes and returns it with the number of bytes it took,
|
|
44
|
+
# leaving whatever follows unread.
|
|
45
|
+
#
|
|
46
|
+
#: (String bytes, **untyped options) -> [untyped, Integer]
|
|
47
|
+
def self.decode_prefix(bytes, **options)
|
|
48
|
+
opts = DecodeOptions.build(**options)
|
|
49
|
+
Native.decode(bytes, 0, opts.max_depth, opts.flags, opts.handlers)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Decodes a CBOR sequence (RFC 8742), a concatenation of zero or more data items.
|
|
53
|
+
#
|
|
54
|
+
#: (String bytes, **untyped options) -> Array[untyped]
|
|
55
|
+
def self.decode_sequence(bytes, **options)
|
|
56
|
+
opts = DecodeOptions.build(**options)
|
|
57
|
+
items = [] #: Array[untyped]
|
|
58
|
+
pos = 0
|
|
59
|
+
while pos < bytes.bytesize
|
|
60
|
+
item, pos = Native.decode(bytes, pos, opts.max_depth, opts.flags, opts.handlers)
|
|
61
|
+
items << item
|
|
62
|
+
end
|
|
63
|
+
items
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Generated from lib/ciborium/compat/buffer.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module Ciborium
|
|
4
|
+
module Compat
|
|
5
|
+
# A byte queue in front of an optional IO, as CBOR::Buffer of the cbor gem: reads refill from
|
|
6
|
+
# the IO when the queue runs dry, and writes go out to it once the queue fills.
|
|
7
|
+
class Buffer
|
|
8
|
+
DEFAULT_IO_BUFFER_SIZE: Integer
|
|
9
|
+
|
|
10
|
+
@pos: Integer
|
|
11
|
+
|
|
12
|
+
@data: String
|
|
13
|
+
|
|
14
|
+
@io_buffer_size: Integer
|
|
15
|
+
|
|
16
|
+
@io: untyped
|
|
17
|
+
|
|
18
|
+
attr_reader io: untyped
|
|
19
|
+
|
|
20
|
+
# The cbor gem's read_reference_threshold and write_reference_threshold tune its chunk
|
|
21
|
+
# sharing, which this buffer does not do, so they are accepted and ignored.
|
|
22
|
+
#
|
|
23
|
+
# : (?untyped io, ?Hash[Symbol, untyped]? options) -> void
|
|
24
|
+
def initialize: (?untyped io, ?Hash[Symbol, untyped]? options) -> void
|
|
25
|
+
|
|
26
|
+
# : () -> nil
|
|
27
|
+
def clear: () -> nil
|
|
28
|
+
|
|
29
|
+
# : () -> Integer
|
|
30
|
+
def size: () -> Integer
|
|
31
|
+
|
|
32
|
+
# : () -> bool
|
|
33
|
+
def empty?: () -> bool
|
|
34
|
+
|
|
35
|
+
# : (String data) -> Integer
|
|
36
|
+
def write: (String data) -> Integer
|
|
37
|
+
|
|
38
|
+
# : (String data) -> self
|
|
39
|
+
def <<: (String data) -> self
|
|
40
|
+
|
|
41
|
+
# Consumes up to n bytes, or everything without n, refilling from the IO until it ends.
|
|
42
|
+
# Returns nil when n is positive and nothing is left.
|
|
43
|
+
#
|
|
44
|
+
# : (?Integer? n, ?String? out) -> String?
|
|
45
|
+
def read: (?Integer? n, ?String? out) -> String?
|
|
46
|
+
|
|
47
|
+
# Consumes exactly n bytes, or everything without n. Raises EOFError, consuming nothing,
|
|
48
|
+
# when fewer than n bytes are left.
|
|
49
|
+
#
|
|
50
|
+
# : (?Integer? n, ?String? out) -> String
|
|
51
|
+
def read_all: (?Integer? n, ?String? out) -> String
|
|
52
|
+
|
|
53
|
+
# Consumes up to n bytes and returns how many it consumed.
|
|
54
|
+
#
|
|
55
|
+
# : (Integer n) -> Integer
|
|
56
|
+
def skip: (Integer n) -> Integer
|
|
57
|
+
|
|
58
|
+
# Consumes exactly n bytes, or raises EOFError consuming nothing.
|
|
59
|
+
#
|
|
60
|
+
# : (Integer n) -> self
|
|
61
|
+
def skip_all: (Integer n) -> self
|
|
62
|
+
|
|
63
|
+
# : () -> String
|
|
64
|
+
def to_str: () -> String
|
|
65
|
+
|
|
66
|
+
# : () -> Array[String]
|
|
67
|
+
def to_a: () -> Array[String]
|
|
68
|
+
|
|
69
|
+
# Writes the queued bytes to the IO, if there is one.
|
|
70
|
+
#
|
|
71
|
+
# : () -> self
|
|
72
|
+
def flush: () -> self
|
|
73
|
+
|
|
74
|
+
# : () -> nil
|
|
75
|
+
def close: () -> nil
|
|
76
|
+
|
|
77
|
+
# Writes the queued bytes to io and consumes them.
|
|
78
|
+
#
|
|
79
|
+
# : (untyped io) -> Integer
|
|
80
|
+
def write_to: (untyped io) -> Integer
|
|
81
|
+
|
|
82
|
+
# : (Integer? n) -> void
|
|
83
|
+
private def fill: (Integer? n) -> void
|
|
84
|
+
|
|
85
|
+
# : () -> String?
|
|
86
|
+
private def read_io: () -> String?
|
|
87
|
+
|
|
88
|
+
# : (Integer n) -> String
|
|
89
|
+
private def take: (Integer n) -> String
|
|
90
|
+
|
|
91
|
+
# : (String? out, String data) -> String
|
|
92
|
+
private def replace: (String? out, String data) -> String
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Generated from lib/ciborium/compat/errors.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module Ciborium
|
|
4
|
+
module Compat
|
|
5
|
+
class UnpackError < StandardError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class MalformedFormatError < UnpackError
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class StackError < UnpackError
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Raised by Unpacker#read_array_header and #read_map_header on an item of another type.
|
|
15
|
+
class TypeError < StandardError
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Raises the cbor gem's exception for a Ciborium decoding failure, keeping it as the cause.
|
|
19
|
+
#
|
|
20
|
+
# : [T] () { () -> T } -> T
|
|
21
|
+
def self.translate_errors: [T] () { () -> T } -> T
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Generated from lib/ciborium/compat/packer.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module Ciborium
|
|
4
|
+
module Compat
|
|
5
|
+
# CBOR::Packer of the cbor gem, writing through Ciborium::Encoder.
|
|
6
|
+
class Packer
|
|
7
|
+
@buffer: Buffer
|
|
8
|
+
|
|
9
|
+
@encoder: Ciborium::Encoder
|
|
10
|
+
|
|
11
|
+
attr_reader buffer: Buffer
|
|
12
|
+
|
|
13
|
+
# : (?untyped io, ?Hash[Symbol, untyped]? options) -> void
|
|
14
|
+
def initialize: (?untyped io, ?Hash[Symbol, untyped]? options) -> void
|
|
15
|
+
|
|
16
|
+
# : (untyped object) -> self
|
|
17
|
+
def write: (untyped object) -> self
|
|
18
|
+
|
|
19
|
+
# : () -> self
|
|
20
|
+
def write_nil: () -> self
|
|
21
|
+
|
|
22
|
+
# : (Integer length) -> self
|
|
23
|
+
def write_array_header: (Integer length) -> self
|
|
24
|
+
|
|
25
|
+
# : (Integer length) -> self
|
|
26
|
+
def write_map_header: (Integer length) -> self
|
|
27
|
+
|
|
28
|
+
# : () -> self
|
|
29
|
+
def flush: () -> self
|
|
30
|
+
|
|
31
|
+
# : () -> nil
|
|
32
|
+
def clear: () -> nil
|
|
33
|
+
|
|
34
|
+
# : () -> Integer
|
|
35
|
+
def size: () -> Integer
|
|
36
|
+
|
|
37
|
+
# : () -> bool
|
|
38
|
+
def empty?: () -> bool
|
|
39
|
+
|
|
40
|
+
# : (untyped io) -> Integer
|
|
41
|
+
def write_to: (untyped io) -> Integer
|
|
42
|
+
|
|
43
|
+
# : () -> String
|
|
44
|
+
def to_str: () -> String
|
|
45
|
+
|
|
46
|
+
# : () -> Array[String]
|
|
47
|
+
def to_a: () -> Array[String]
|
|
48
|
+
|
|
49
|
+
# : () -> self
|
|
50
|
+
private def drain: () -> self
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Generated from lib/ciborium/compat/unpacker.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module Ciborium
|
|
4
|
+
module Compat
|
|
5
|
+
# CBOR::Unpacker of the cbor gem, reading through Ciborium::Decoder. Input passes through
|
|
6
|
+
# buffer, which also reads from io when more is needed.
|
|
7
|
+
class Unpacker
|
|
8
|
+
@buffer: Buffer
|
|
9
|
+
|
|
10
|
+
@decoder: Ciborium::Decoder
|
|
11
|
+
|
|
12
|
+
attr_reader buffer: Buffer
|
|
13
|
+
|
|
14
|
+
# options takes symbolize_keys, and the Buffer options.
|
|
15
|
+
#
|
|
16
|
+
# : (?untyped io, ?Hash[Symbol, untyped]? options) -> void
|
|
17
|
+
def initialize: (?untyped io, ?Hash[Symbol, untyped]? options) -> void
|
|
18
|
+
|
|
19
|
+
# : (String data) -> self
|
|
20
|
+
def feed: (String data) -> self
|
|
21
|
+
|
|
22
|
+
# : () -> untyped
|
|
23
|
+
def read: () -> untyped
|
|
24
|
+
|
|
25
|
+
# : () -> nil
|
|
26
|
+
def skip: () -> nil
|
|
27
|
+
|
|
28
|
+
# Whether the next item is null. Consumes nothing.
|
|
29
|
+
#
|
|
30
|
+
# : () -> bool
|
|
31
|
+
def skip_nil: () -> bool
|
|
32
|
+
|
|
33
|
+
# : () -> Integer
|
|
34
|
+
def read_array_header: () -> Integer
|
|
35
|
+
|
|
36
|
+
# : () -> Integer
|
|
37
|
+
def read_map_header: () -> Integer
|
|
38
|
+
|
|
39
|
+
# Yields each item until the input runs out, leaving a partial item buffered.
|
|
40
|
+
#
|
|
41
|
+
# : () { (untyped) -> void } -> nil
|
|
42
|
+
# : () -> Enumerator[untyped, nil]
|
|
43
|
+
def each: () { (untyped) -> void } -> nil
|
|
44
|
+
| () -> Enumerator[untyped, nil]
|
|
45
|
+
|
|
46
|
+
# : (String data) { (untyped) -> void } -> nil
|
|
47
|
+
def feed_each: (String data) { (untyped) -> void } -> nil
|
|
48
|
+
|
|
49
|
+
# : () -> nil
|
|
50
|
+
def reset: () -> nil
|
|
51
|
+
|
|
52
|
+
# Runs the block on the decoder, moving more input into it until the block stops raising
|
|
53
|
+
# IncompleteError or the input ends.
|
|
54
|
+
#
|
|
55
|
+
# : [T] () { () -> T } -> T
|
|
56
|
+
private def with_input: [T] () { () -> T } -> T
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Generated from lib/ciborium/compat.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module Ciborium
|
|
4
|
+
# The interface of the cbor gem (CBOR), implemented on top of Ciborium. Tag extensions follow
|
|
5
|
+
# Compat.extensions, so a tag that is not allowlisted decodes to Tagged. require
|
|
6
|
+
# "ciborium/replace" to install it as CBOR.
|
|
7
|
+
module Compat
|
|
8
|
+
Tagged: untyped
|
|
9
|
+
|
|
10
|
+
Simple: untyped
|
|
11
|
+
|
|
12
|
+
# Nothing is allowlisted until the application opts in, as with Ciborium itself.
|
|
13
|
+
DEFAULT_EXTENSIONS: Array[extension]
|
|
14
|
+
|
|
15
|
+
self.@extensions: Array[extension]
|
|
16
|
+
|
|
17
|
+
# The extensions every Compat entry point uses, process-wide.
|
|
18
|
+
#
|
|
19
|
+
# : () -> Array[extension]
|
|
20
|
+
def self.extensions: () -> Array[extension]
|
|
21
|
+
|
|
22
|
+
# : (Array[extension] extensions) -> void
|
|
23
|
+
def self.extensions=: (Array[extension] extensions) -> void
|
|
24
|
+
|
|
25
|
+
# Options for Ciborium::Encoder that reproduce the cbor gem's encoding.
|
|
26
|
+
#
|
|
27
|
+
# : () -> Hash[Symbol, untyped]
|
|
28
|
+
def self.encode_options: () -> Hash[Symbol, untyped]
|
|
29
|
+
|
|
30
|
+
# Options for Ciborium::Decoder that reproduce the cbor gem's decoding.
|
|
31
|
+
#
|
|
32
|
+
# : () -> Hash[Symbol, untyped]
|
|
33
|
+
def self.decode_options: () -> Hash[Symbol, untyped]
|
|
34
|
+
|
|
35
|
+
# Encodes object, or writes it to io and returns nil when io is given.
|
|
36
|
+
#
|
|
37
|
+
# : (untyped object, ?untyped io) -> String?
|
|
38
|
+
def self.encode: (untyped object, ?untyped io) -> String?
|
|
39
|
+
|
|
40
|
+
# Decodes a single item from a String, or from all that an IO holds.
|
|
41
|
+
#
|
|
42
|
+
# options is {symbolize_keys: true}, or :keys_as_symbols.
|
|
43
|
+
#
|
|
44
|
+
# : (untyped source, ?(Hash[Symbol, untyped] | Symbol)? options) -> untyped
|
|
45
|
+
def self.decode: (untyped source, ?(Hash[Symbol, untyped] | Symbol)? options) -> untyped
|
|
46
|
+
|
|
47
|
+
# Encodes an object Ciborium cannot represent through its own to_cbor(packer), as the cbor
|
|
48
|
+
# gem does.
|
|
49
|
+
FALLBACK: ^(untyped) -> untyped
|
|
50
|
+
|
|
51
|
+
# to_cbor for the classes the cbor gem extends. Installed by ciborium/replace.
|
|
52
|
+
module CoreExt
|
|
53
|
+
# : (?untyped packer_or_io) -> untyped
|
|
54
|
+
def to_cbor: (?untyped packer_or_io) -> untyped
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Generated from lib/ciborium/decode_options.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module Ciborium
|
|
4
|
+
DEFAULT_MAX_DEPTH: Integer
|
|
5
|
+
|
|
6
|
+
MAX_DEPTH_LIMIT: Integer
|
|
7
|
+
|
|
8
|
+
# Encoding rules a profile enforces beyond well-formedness. :ctap2 is the CTAP2 canonical CBOR
|
|
9
|
+
# encoding form that WebAuthn requires: no tags, no indefinite lengths, arguments in their
|
|
10
|
+
# shortest form, and map keys ordered without duplicates.
|
|
11
|
+
PROFILES: Array[Symbol]
|
|
12
|
+
|
|
13
|
+
# Decoding options, validated and packed into the arguments the native decoder takes.
|
|
14
|
+
class DecodeOptions < Data
|
|
15
|
+
attr_reader max_depth(): Integer
|
|
16
|
+
|
|
17
|
+
attr_reader flags(): Integer
|
|
18
|
+
|
|
19
|
+
attr_reader handlers(): Hash[Integer, ^(Integer, untyped) -> untyped]?
|
|
20
|
+
|
|
21
|
+
def self.new: (Integer max_depth, Integer flags, Hash[Integer, ^(Integer, untyped) -> untyped]? handlers) -> instance
|
|
22
|
+
| (max_depth: Integer, flags: Integer, handlers: Hash[Integer, ^(Integer, untyped) -> untyped]?) -> instance
|
|
23
|
+
|
|
24
|
+
def self.members: () -> [ :max_depth, :flags, :handlers ]
|
|
25
|
+
|
|
26
|
+
def members: () -> [ :max_depth, :flags, :handlers ]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class DecodeOptions
|
|
30
|
+
# extensions lists the allowlisted extensions (see Extensions); every other tag decodes to
|
|
31
|
+
# Tagged. profile rejects input that breaks one of PROFILES.
|
|
32
|
+
#
|
|
33
|
+
# : (?extensions: Array[extension], ?symbolize_keys: bool, ?max_depth: Integer, ?duplicate_keys: Symbol, ?profile: Symbol?) -> DecodeOptions
|
|
34
|
+
def self.build: (?extensions: Array[extension], ?symbolize_keys: bool, ?max_depth: Integer, ?duplicate_keys: Symbol, ?profile: Symbol?) -> DecodeOptions
|
|
35
|
+
|
|
36
|
+
# Returns whether profile is :ctap2.
|
|
37
|
+
#
|
|
38
|
+
# : (Symbol? profile, untyped extensions) -> bool
|
|
39
|
+
def self.check_profile: (Symbol? profile, untyped extensions) -> bool
|
|
40
|
+
end
|
|
41
|
+
end
|