http-2 0.12.0 → 1.0.2
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/README.md +10 -7
- data/lib/http/2/base64.rb +45 -0
- data/lib/http/2/client.rb +14 -5
- data/lib/http/2/connection.rb +184 -90
- data/lib/http/2/emitter.rb +4 -5
- data/lib/http/2/error.rb +22 -1
- data/lib/http/2/extensions.rb +51 -0
- data/lib/http/2/flow_buffer.rb +88 -35
- data/lib/http/2/framer.rb +145 -108
- data/lib/http/2/header/compressor.rb +157 -0
- data/lib/http/2/header/decompressor.rb +144 -0
- data/lib/http/2/header/encoding_context.rb +339 -0
- data/lib/http/2/{huffman.rb → header/huffman.rb} +9 -7
- data/lib/http/2/{huffman_statemachine.rb → header/huffman_statemachine.rb} +3 -1
- data/lib/http/2/header.rb +35 -0
- data/lib/http/2/server.rb +39 -14
- data/lib/http/2/stream.rb +86 -17
- data/lib/http/2/version.rb +1 -1
- data/lib/http/2.rb +12 -13
- data/sig/client.rbs +9 -0
- data/sig/connection.rbs +94 -0
- data/sig/emitter.rbs +13 -0
- data/sig/error.rbs +35 -0
- data/sig/extensions.rbs +13 -0
- data/sig/flow_buffer.rbs +21 -0
- data/sig/frame_buffer.rbs +13 -0
- data/sig/framer.rbs +55 -0
- data/sig/header/compressor.rbs +27 -0
- data/sig/header/decompressor.rbs +24 -0
- data/sig/header/encoding_context.rbs +34 -0
- data/sig/header/huffman.rbs +9 -0
- data/sig/header.rbs +27 -0
- data/sig/next.rbs +101 -0
- data/sig/server.rbs +12 -0
- data/sig/stream.rbs +91 -0
- metadata +37 -25
- data/LICENSE +0 -21
- data/lib/http/2/buffer.rb +0 -78
- data/lib/http/2/compressor.rb +0 -580
@@ -0,0 +1,27 @@
|
|
1
|
+
module HTTP2
|
2
|
+
module Header
|
3
|
+
class Compressor
|
4
|
+
include PackingExtensions
|
5
|
+
|
6
|
+
@cc: EncodingContext
|
7
|
+
|
8
|
+
def table_size=: (Integer) -> void
|
9
|
+
|
10
|
+
def integer: (Integer, Integer, buffer: String, ?offset: Integer) -> String
|
11
|
+
|
12
|
+
def string: (String) -> String
|
13
|
+
|
14
|
+
def header: (header_command, ?String) -> String
|
15
|
+
|
16
|
+
def encode: (Enumerable[header_pair]) -> String
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def initialize: (?context_hash options) -> void
|
21
|
+
|
22
|
+
def huffman_string: (String str) -> String
|
23
|
+
|
24
|
+
def plain_string: (String str) -> String
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module HTTP2
|
2
|
+
module Header
|
3
|
+
class Decompressor
|
4
|
+
include BufferUtils
|
5
|
+
|
6
|
+
@cc: EncodingContext
|
7
|
+
|
8
|
+
def table_size=: (Integer) -> void
|
9
|
+
|
10
|
+
def integer: (String, Integer) -> Integer
|
11
|
+
|
12
|
+
def string: (String) -> String
|
13
|
+
|
14
|
+
def header: (String) -> header_command
|
15
|
+
|
16
|
+
def decode: (String, frame?) -> Array[header_pair]
|
17
|
+
| (String) -> Array[header_pair]
|
18
|
+
private
|
19
|
+
|
20
|
+
def initialize: (context_hash options) -> untyped
|
21
|
+
| () -> untyped
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module HTTP2
|
2
|
+
module Header
|
3
|
+
class EncodingContext
|
4
|
+
STATIC_TABLE: Array[header_pair]
|
5
|
+
|
6
|
+
attr_reader table: Array[header_pair]
|
7
|
+
|
8
|
+
attr_reader options: context_hash
|
9
|
+
|
10
|
+
def dup: () -> EncodingContext
|
11
|
+
|
12
|
+
def dereference: (Integer) -> header_pair
|
13
|
+
|
14
|
+
def process: (header_command cmd) -> header_pair?
|
15
|
+
|
16
|
+
def encode: (_Each[header_pair]) -> Array[header_command]
|
17
|
+
|
18
|
+
def addcmd: (String name, String value) -> header_command
|
19
|
+
|
20
|
+
def table_size=: (Integer) -> void
|
21
|
+
|
22
|
+
def current_table_size: () -> Integer
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def initialize: (context_hash options) -> untyped
|
27
|
+
| () -> untyped
|
28
|
+
|
29
|
+
def add_to_table: (header_pair) -> void
|
30
|
+
|
31
|
+
def size_check: (header_pair?) -> bool
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/sig/header.rbs
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module HTTP2
|
2
|
+
module Header
|
3
|
+
type header_key = :type | :name | :value | :index
|
4
|
+
type header_value = Integer | String | :indexed | :changetablesize | :incremental | :noindex | :neverindexed
|
5
|
+
|
6
|
+
#type context_hash = {
|
7
|
+
# huffman?: (:always | :never | :shorter),
|
8
|
+
# index?: (:all | :static | :never),
|
9
|
+
# table_size?: Integer
|
10
|
+
#}
|
11
|
+
type context_hash = Hash[Symbol, Symbol | Integer]
|
12
|
+
|
13
|
+
type header_command = Hash[header_key, header_value]
|
14
|
+
|
15
|
+
HEADREP: Hash[Symbol, Hash[Symbol, Integer]]
|
16
|
+
|
17
|
+
NAIVE: Hash[Symbol, Symbol]
|
18
|
+
LINEAR: Hash[Symbol, Symbol]
|
19
|
+
STATIC: Hash[Symbol, Symbol]
|
20
|
+
SHORTER: Hash[Symbol, Symbol]
|
21
|
+
NAIVEH: Hash[Symbol, Symbol]
|
22
|
+
LINEARH: Hash[Symbol, Symbol]
|
23
|
+
STATICH: Hash[Symbol, Symbol]
|
24
|
+
SHORTERH: Hash[Symbol, Symbol]
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/sig/next.rbs
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
module HTTP2
|
2
|
+
VERSION: String
|
3
|
+
|
4
|
+
DEFAULT_FLOW_WINDOW: Integer
|
5
|
+
|
6
|
+
DEFAULT_HEADER_SIZE: Integer
|
7
|
+
|
8
|
+
DEFAULT_MAX_CONCURRENT_STREAMS: Integer
|
9
|
+
|
10
|
+
type settings_hash = Hash[Symbol, Integer]
|
11
|
+
|
12
|
+
type settings_ary = Array[settings_enum]
|
13
|
+
|
14
|
+
type settings_enum = Enumerable[[Symbol, Integer]]
|
15
|
+
|
16
|
+
SPEC_DEFAULT_CONNECTION_SETTINGS: settings_hash
|
17
|
+
|
18
|
+
DEFAULT_CONNECTION_SETTINGS: settings_hash
|
19
|
+
|
20
|
+
DEFAULT_WEIGHT: Integer
|
21
|
+
|
22
|
+
CONNECTION_PREFACE_MAGIC: String
|
23
|
+
|
24
|
+
REQUEST_MANDATORY_HEADERS: Array[String]
|
25
|
+
|
26
|
+
RESPONSE_MANDATORY_HEADERS: Array[String]
|
27
|
+
|
28
|
+
type header_pair = [string, string]
|
29
|
+
|
30
|
+
# # FRAMES
|
31
|
+
type frame_control_flags = Array[:end_headers | :end_stream]
|
32
|
+
|
33
|
+
# # HEADERS
|
34
|
+
# type headers_frame = {
|
35
|
+
# type: :headers, flags: frame_control_flags, stream: Integer, payload: Enumerable[header_pair],
|
36
|
+
# ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, ?padding: Integer
|
37
|
+
# }
|
38
|
+
|
39
|
+
# # DATA
|
40
|
+
type data_frame = { type: :data, flags: frame_control_flags, stream: Integer, length: Integer, payload: String, padding: Integer }
|
41
|
+
| { type: :data, flags: frame_control_flags, stream: Integer, length: Integer, payload: String }
|
42
|
+
| { type: :data, flags: frame_control_flags, payload: String }
|
43
|
+
|
44
|
+
# # PUSH_PROMISE
|
45
|
+
# type push_promise_frame = { type: :push_promise, promise_stream: Integer, flags: frame_control_flags, stream: Integer, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair], ?padding: Integer }
|
46
|
+
|
47
|
+
# # SETTINGS
|
48
|
+
# type settings_frame = { type: :settings, stream: 0, payload: Array[[Symbol | Integer, Integer]] }
|
49
|
+
|
50
|
+
# # WINDOW_UPDATE
|
51
|
+
# type window_update_frame = { type: :window_update, stream: Integer, increment: Integer }
|
52
|
+
|
53
|
+
# # PRIORITY
|
54
|
+
type priority_frame = { type: :priority, stream: Integer, dependency: Integer, exclusive: bool, weight: Integer }
|
55
|
+
|
56
|
+
# # ALTSVC
|
57
|
+
# type altsvc_frame = { type: :altsvc, stream: 0, max_age: Integer, port: Integer, proto: "String", host: String }
|
58
|
+
|
59
|
+
# # ORIGIN
|
60
|
+
# type origin_frame = { type: :origin, stream: 0, origin: Array[String] }
|
61
|
+
|
62
|
+
# # PING
|
63
|
+
# type ping_frame = { type: :ping, payload: String, length: Integer }
|
64
|
+
|
65
|
+
# # GOAWAY
|
66
|
+
# type goaway_frame = { type: :goaway, stream: 0, last_stream: Integer, error: Symbol? }
|
67
|
+
|
68
|
+
# type frame = headers_frame | data_frame | push_promise_frame |
|
69
|
+
# settings_frame | window_update_frame | priority_frame | altsvc_frame |
|
70
|
+
# origin_frame | ping_frame | goaway_frame
|
71
|
+
|
72
|
+
type frame_key = :type | :flags | :stream | :padding | :ignore |
|
73
|
+
# headers
|
74
|
+
:method | :trailer | :content_length | :status |
|
75
|
+
# data, settings, ping
|
76
|
+
:payload | :length |
|
77
|
+
# promise
|
78
|
+
:promise_stream |
|
79
|
+
# window_update
|
80
|
+
:increment |
|
81
|
+
# priority
|
82
|
+
:dependency | :exclusive | :weight |
|
83
|
+
# altsvc
|
84
|
+
:max_age | :port | :proto | :host |
|
85
|
+
# origin
|
86
|
+
:origin |
|
87
|
+
# goaway
|
88
|
+
:last_stream | :error
|
89
|
+
|
90
|
+
type frame_value = Integer |
|
91
|
+
Symbol | # type (:data, :headers)
|
92
|
+
Array[Symbol] |
|
93
|
+
String |
|
94
|
+
bool |
|
95
|
+
Array[String] |
|
96
|
+
Array[[Symbol | Integer, Integer]] |
|
97
|
+
Enumerable[header_pair] |
|
98
|
+
nil
|
99
|
+
|
100
|
+
type frame = Hash[frame_key, frame_value]
|
101
|
+
end
|
data/sig/server.rbs
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module HTTP2
|
2
|
+
class Server < Connection
|
3
|
+
|
4
|
+
def upgrade: (String settings, Enumerable[header_pair] headers, String body) -> void
|
5
|
+
|
6
|
+
def origin_set=: (Array[_ToS]) -> void
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def promise: (Stream parent, Enumerable[header_pair] headers, Array[Symbol] flags) { (Stream) -> void } -> void
|
11
|
+
end
|
12
|
+
end
|
data/sig/stream.rbs
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
module HTTP2
|
2
|
+
class Stream
|
3
|
+
include FlowBuffer
|
4
|
+
include Emitter
|
5
|
+
|
6
|
+
attr_reader id: Integer
|
7
|
+
attr_reader state: Symbol
|
8
|
+
attr_reader parent: Stream?
|
9
|
+
attr_reader weight: Integer
|
10
|
+
attr_reader dependency: Integer
|
11
|
+
attr_reader remote_window: Integer
|
12
|
+
attr_reader local_window: Integer
|
13
|
+
attr_reader closed: Symbol?
|
14
|
+
|
15
|
+
@connection: Connection
|
16
|
+
@local_window_max_size: Integer
|
17
|
+
@error: bool
|
18
|
+
@_method: String?
|
19
|
+
@_content_length: Integer?
|
20
|
+
@_status_code: Integer?
|
21
|
+
@_waiting_on_trailers: bool
|
22
|
+
@received_data: bool
|
23
|
+
@activated: bool
|
24
|
+
|
25
|
+
alias window local_window
|
26
|
+
|
27
|
+
def closed?: () -> bool
|
28
|
+
|
29
|
+
def receive: (frame) -> void
|
30
|
+
|
31
|
+
alias << receive
|
32
|
+
|
33
|
+
def verify_trailers: (frame) -> void
|
34
|
+
|
35
|
+
def calculate_content_length: (Integer?) -> void
|
36
|
+
|
37
|
+
def send: (frame) -> void
|
38
|
+
|
39
|
+
def headers: (Enumerable[header_pair] headers, ?end_headers: bool, ?end_stream: bool) -> void
|
40
|
+
|
41
|
+
def promise: (Enumerable[header_pair] headers, ?end_headers: bool) { (Stream) -> void } -> void
|
42
|
+
|
43
|
+
def reprioritize: (?weight: Integer, ?dependency: Integer, ?exclusive: bool) -> void
|
44
|
+
|
45
|
+
def data: (String payload, ?end_stream: bool) -> void
|
46
|
+
|
47
|
+
def chunk_data: (String payload, Integer max_size) { (String) -> void } -> String
|
48
|
+
|
49
|
+
def close: (Symbol error) -> void
|
50
|
+
| () -> void
|
51
|
+
|
52
|
+
def cancel: () -> void
|
53
|
+
|
54
|
+
def refuse: () -> void
|
55
|
+
|
56
|
+
def window_update: (Integer increment) -> void
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def initialize: (
|
61
|
+
connection: Connection,
|
62
|
+
id: Integer,
|
63
|
+
?weight: Integer,
|
64
|
+
?dependency: Integer,
|
65
|
+
?exclusive: bool,
|
66
|
+
?parent: Stream?,
|
67
|
+
?state: Symbol
|
68
|
+
) -> untyped
|
69
|
+
|
70
|
+
def transition: (frame, bool sending) -> void
|
71
|
+
|
72
|
+
def event: (Symbol newstate) -> void
|
73
|
+
|
74
|
+
def activate_stream_in_conn: () -> void
|
75
|
+
|
76
|
+
def close_stream_in_conn: (*untyped) -> void
|
77
|
+
|
78
|
+
def complete_transition: (frame) -> void
|
79
|
+
|
80
|
+
def process_priority: ({weight: Integer, dependency: Integer, exclusive: bool}) -> void
|
81
|
+
|
82
|
+
def end_frame?: () -> bool
|
83
|
+
|
84
|
+
def stream_error: (Symbol error, ?msg: String?) -> void
|
85
|
+
| () -> void
|
86
|
+
|
87
|
+
alias error stream_error
|
88
|
+
|
89
|
+
def manage_state: (frame) { () -> void } -> void
|
90
|
+
end
|
91
|
+
end
|
metadata
CHANGED
@@ -1,57 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http-2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
+
- Tiago Cardoso
|
7
8
|
- Ilya Grigorik
|
8
9
|
- Kaoru Maeda
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2024-
|
13
|
-
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: base64
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
requirements:
|
18
|
-
- - ">="
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: '0'
|
21
|
-
type: :runtime
|
22
|
-
prerelease: false
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
requirements:
|
25
|
-
- - ">="
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
version: '0'
|
13
|
+
date: 2024-11-05 00:00:00.000000000 Z
|
14
|
+
dependencies: []
|
28
15
|
description: Pure-ruby HTTP 2.0 protocol implementation
|
29
16
|
email:
|
17
|
+
- cardoso_tiago@hotmail.com
|
30
18
|
- ilya@igvita.com
|
31
19
|
executables: []
|
32
20
|
extensions: []
|
33
21
|
extra_rdoc_files: []
|
34
22
|
files:
|
35
|
-
- LICENSE
|
36
23
|
- README.md
|
37
24
|
- lib/http/2.rb
|
38
|
-
- lib/http/2/
|
25
|
+
- lib/http/2/base64.rb
|
39
26
|
- lib/http/2/client.rb
|
40
|
-
- lib/http/2/compressor.rb
|
41
27
|
- lib/http/2/connection.rb
|
42
28
|
- lib/http/2/emitter.rb
|
43
29
|
- lib/http/2/error.rb
|
30
|
+
- lib/http/2/extensions.rb
|
44
31
|
- lib/http/2/flow_buffer.rb
|
45
32
|
- lib/http/2/framer.rb
|
46
|
-
- lib/http/2/
|
47
|
-
- lib/http/2/
|
33
|
+
- lib/http/2/header.rb
|
34
|
+
- lib/http/2/header/compressor.rb
|
35
|
+
- lib/http/2/header/decompressor.rb
|
36
|
+
- lib/http/2/header/encoding_context.rb
|
37
|
+
- lib/http/2/header/huffman.rb
|
38
|
+
- lib/http/2/header/huffman_statemachine.rb
|
48
39
|
- lib/http/2/server.rb
|
49
40
|
- lib/http/2/stream.rb
|
50
41
|
- lib/http/2/version.rb
|
42
|
+
- sig/client.rbs
|
43
|
+
- sig/connection.rbs
|
44
|
+
- sig/emitter.rbs
|
45
|
+
- sig/error.rbs
|
46
|
+
- sig/extensions.rbs
|
47
|
+
- sig/flow_buffer.rbs
|
48
|
+
- sig/frame_buffer.rbs
|
49
|
+
- sig/framer.rbs
|
50
|
+
- sig/header.rbs
|
51
|
+
- sig/header/compressor.rbs
|
52
|
+
- sig/header/decompressor.rbs
|
53
|
+
- sig/header/encoding_context.rbs
|
54
|
+
- sig/header/huffman.rbs
|
55
|
+
- sig/next.rbs
|
56
|
+
- sig/server.rbs
|
57
|
+
- sig/stream.rbs
|
51
58
|
homepage: https://github.com/igrigorik/http-2
|
52
59
|
licenses:
|
53
60
|
- MIT
|
54
|
-
metadata:
|
61
|
+
metadata:
|
62
|
+
bug_tracker_uri: https://github.com/igrigorik/http-2/issues
|
63
|
+
changelog_uri: https://github.com/igrigorik/http-2/blob/main/CHANGELOG.md
|
64
|
+
source_code_uri: https://github.com/igrigorik/http-2
|
65
|
+
homepage_uri: https://github.com/igrigorik/http-2
|
66
|
+
rubygems_mfa_required: 'true'
|
55
67
|
post_install_message:
|
56
68
|
rdoc_options: []
|
57
69
|
require_paths:
|
@@ -60,14 +72,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
60
72
|
requirements:
|
61
73
|
- - ">="
|
62
74
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
75
|
+
version: 2.7.0
|
64
76
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
77
|
requirements:
|
66
78
|
- - ">="
|
67
79
|
- !ruby/object:Gem::Version
|
68
80
|
version: '0'
|
69
81
|
requirements: []
|
70
|
-
rubygems_version: 3.3
|
82
|
+
rubygems_version: 3.5.3
|
71
83
|
signing_key:
|
72
84
|
specification_version: 4
|
73
85
|
summary: Pure-ruby HTTP 2.0 protocol implementation
|
data/LICENSE
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
MIT License
|
2
|
-
|
3
|
-
Copyright (c) 2013 Ilya Grigorik
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
7
|
-
in the Software without restriction, including without limitation the rights
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
10
|
-
furnished to do so, subject to the following conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
13
|
-
copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
-
SOFTWARE.
|
data/lib/http/2/buffer.rb
DELETED
@@ -1,78 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'forwardable'
|
4
|
-
|
5
|
-
module HTTP2
|
6
|
-
# Binary buffer wraps String.
|
7
|
-
#
|
8
|
-
class Buffer
|
9
|
-
extend Forwardable
|
10
|
-
|
11
|
-
def_delegators :@buffer, :ord, :encoding, :setbyte, :unpack, :unpack1,
|
12
|
-
:size, :each_byte, :to_str, :to_s, :length, :inspect,
|
13
|
-
:[], :[]=, :empty?, :bytesize, :include?
|
14
|
-
|
15
|
-
UINT32 = 'N'
|
16
|
-
private_constant :UINT32
|
17
|
-
|
18
|
-
# Forces binary encoding on the string
|
19
|
-
def initialize(str = '')
|
20
|
-
str = str.dup if str.frozen?
|
21
|
-
@buffer = str.force_encoding(Encoding::BINARY)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Emulate StringIO#read: slice first n bytes from the buffer.
|
25
|
-
#
|
26
|
-
# @param n [Integer] number of bytes to slice from the buffer
|
27
|
-
def read(n)
|
28
|
-
Buffer.new(@buffer.slice!(0, n))
|
29
|
-
end
|
30
|
-
|
31
|
-
# Emulate StringIO#getbyte: slice first byte from buffer.
|
32
|
-
def getbyte
|
33
|
-
read(1).ord
|
34
|
-
end
|
35
|
-
|
36
|
-
def slice!(*args)
|
37
|
-
Buffer.new(@buffer.slice!(*args))
|
38
|
-
end
|
39
|
-
|
40
|
-
def slice(*args)
|
41
|
-
Buffer.new(@buffer.slice(*args))
|
42
|
-
end
|
43
|
-
|
44
|
-
def force_encoding(*args)
|
45
|
-
@buffer = @buffer.force_encoding(*args)
|
46
|
-
end
|
47
|
-
|
48
|
-
def ==(other)
|
49
|
-
@buffer == other
|
50
|
-
end
|
51
|
-
|
52
|
-
def +(other)
|
53
|
-
@buffer += other
|
54
|
-
end
|
55
|
-
|
56
|
-
# Emulate String#getbyte: return nth byte from buffer.
|
57
|
-
def readbyte(n)
|
58
|
-
@buffer[n].ord
|
59
|
-
end
|
60
|
-
|
61
|
-
# Slice unsigned 32-bit integer from buffer.
|
62
|
-
# @return [Integer]
|
63
|
-
def read_uint32
|
64
|
-
read(4).unpack1(UINT32)
|
65
|
-
end
|
66
|
-
|
67
|
-
# Ensures that data that is added is binary encoded as well,
|
68
|
-
# otherwise this could lead to the Buffer instance changing its encoding.
|
69
|
-
%i[<< prepend].each do |mutating_method|
|
70
|
-
define_method(mutating_method) do |string|
|
71
|
-
string = string.dup if string.frozen?
|
72
|
-
@buffer.send mutating_method, string.force_encoding(Encoding::BINARY)
|
73
|
-
|
74
|
-
self
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|