io-stream 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d85df6aecb7833dd6945292040cb635510f088df8dc0f9427b207ada1b8fcfa
4
- data.tar.gz: 07b3d70a28adc36c23286f42f92c0d9eec99a3a176efbbb839c3f4c9d34a13fd
3
+ metadata.gz: e7580fa6412067d9c5e341d3f81de6f9cd8134cc04fb1b2666bafc0a9685cc99
4
+ data.tar.gz: 76040e83616e06be4c7c0bbdfd89d019542b8d5eaa44c56af5e474acda870983
5
5
  SHA512:
6
- metadata.gz: e40a994276d5cab512b1c77213ba48c02fe7916256c0070893f37bc641baea4ecf277ee3695b76357617b6e5366ddb22fbf8ff5839f7c64698edc01b3bc2ced9
7
- data.tar.gz: 21ae83634d2c036a2c60865fdafb26de516fc8a0822c45ff018fd6c887079c73dcb63ace72f07b316d87b5973b4de5d3d673d435a89f09c755361ab0a63238ce
6
+ metadata.gz: 9ac128c5e456067d97b9477ed715fc2d4b0698b3d01e2cb6884dfa2b28128b09a860cba4480f8b0a161c2d13c4ac956c00ddafee1b949f8f63f602e7ad277185
7
+ data.tar.gz: a381be911bb16224c57ad364dc8e4e85ce74616523360cbf62ab04d84747d3b47b133291c41dbac5e346cc01485dc85f2237f82c17a6612cf5404283d2be5c2e
checksums.yaml.gz.sig CHANGED
Binary file
@@ -18,6 +18,9 @@ module IO::Stream
18
18
  # The maximum read size when appending to IO buffers. Defaults to 8MB.
19
19
  MAXIMUM_READ_SIZE = ENV.fetch("IO_STREAM_MAXIMUM_READ_SIZE", BLOCK_SIZE * 128).to_i
20
20
 
21
+ class LimitError < StandardError
22
+ end
23
+
21
24
  class Generic
22
25
  def initialize(block_size: BLOCK_SIZE, maximum_read_size: MAXIMUM_READ_SIZE)
23
26
  @eof = false
@@ -85,15 +88,10 @@ module IO::Stream
85
88
  read_partial(size) or raise EOFError, "Encountered eof while reading data!"
86
89
  end
87
90
 
88
- # Efficiently read data from the stream until encountering pattern.
89
- # @parameter pattern [String] The pattern to match.
90
- # @parameter offset [Integer] The offset to start searching from.
91
- # @parameter limit [Integer] The maximum number of bytes to read, including the pattern (even if chomped).
92
- # @returns [String | Nil] The contents of the stream up until the pattern, which is consumed but not returned.
93
- def read_until(pattern, offset = 0, limit: nil, chomp: true)
91
+ private def index_of(pattern, offset, limit)
94
92
  # We don't want to split on the pattern, so we subtract the size of the pattern.
95
93
  split_offset = pattern.bytesize - 1
96
-
94
+
97
95
  until index = @read_buffer.index(pattern, offset)
98
96
  offset = @read_buffer.bytesize - split_offset
99
97
 
@@ -103,13 +101,24 @@ module IO::Stream
103
101
  return nil unless fill_read_buffer
104
102
  end
105
103
 
106
- return nil if limit and index >= limit
107
-
108
- @read_buffer.freeze
109
- matched = @read_buffer.byteslice(0, index+(chomp ? 0 : pattern.bytesize))
110
- @read_buffer = @read_buffer.byteslice(index+pattern.bytesize, @read_buffer.bytesize)
111
-
112
- return matched
104
+ return index
105
+ end
106
+
107
+ # Efficiently read data from the stream until encountering pattern.
108
+ # @parameter pattern [String] The pattern to match.
109
+ # @parameter offset [Integer] The offset to start searching from.
110
+ # @parameter limit [Integer] The maximum number of bytes to read, including the pattern (even if chomped).
111
+ # @returns [String | Nil] The contents of the stream up until the pattern, which is consumed but not returned.
112
+ def read_until(pattern, offset = 0, limit: nil, chomp: true)
113
+ if index = index_of(pattern, offset, limit)
114
+ return nil if limit and index >= limit
115
+
116
+ @read_buffer.freeze
117
+ matched = @read_buffer.byteslice(0, index+(chomp ? 0 : pattern.bytesize))
118
+ @read_buffer = @read_buffer.byteslice(index+pattern.bytesize, @read_buffer.bytesize)
119
+
120
+ return matched
121
+ end
113
122
  end
114
123
 
115
124
  def peek(size = nil)
@@ -129,8 +138,45 @@ module IO::Stream
129
138
  return @read_buffer
130
139
  end
131
140
 
132
- def gets(separator = $/, **options)
133
- read_until(separator, **options)
141
+ def gets(separator = $/, limit = nil, chomp: false)
142
+ # Compatibility with IO#gets:
143
+ if separator.is_a?(Integer)
144
+ limit = separator
145
+ separator = $/
146
+ end
147
+
148
+ # We don't want to split in the middle of the separator, so we subtract the size of the separator from the start of the search:
149
+ split_offset = separator.bytesize - 1
150
+
151
+ offset = 0
152
+
153
+ until index = @read_buffer.index(separator, offset)
154
+ offset = @read_buffer.bytesize - split_offset
155
+ offset = 0 if offset < 0
156
+
157
+ # If a limit was given, and the offset is beyond the limit, we should return up to the limit:
158
+ if limit and offset >= limit
159
+ # As we didn't find the separator, there is nothing to chomp either.
160
+ return consume_read_buffer(limit)
161
+ end
162
+
163
+ # If we can't read any more data, we should return what we have:
164
+ return consume_read_buffer unless fill_read_buffer
165
+ end
166
+
167
+ # If the index of the separator was beyond the limit:
168
+ if limit and index >= limit
169
+ # Return up to the limit:
170
+ return consume_read_buffer(limit)
171
+ end
172
+
173
+ # Freeze the read buffer, as this enables us to use byteslice without generating a hidden copy:
174
+ @read_buffer.freeze
175
+
176
+ line = @read_buffer.byteslice(0, index+(chomp ? 0 : separator.bytesize))
177
+ @read_buffer = @read_buffer.byteslice(index+separator.bytesize, @read_buffer.bytesize)
178
+
179
+ return line
134
180
  end
135
181
 
136
182
  private def drain(buffer)
@@ -4,5 +4,5 @@
4
4
  # Copyright, 2023-2024, by Samuel Williams.
5
5
 
6
6
  module IO::Stream
7
- VERSION = "0.5.0"
7
+ VERSION = "0.6.0"
8
8
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: io-stream
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -37,7 +37,7 @@ cert_chain:
37
37
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
38
38
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
39
39
  -----END CERTIFICATE-----
40
- date: 2024-10-14 00:00:00.000000000 Z
40
+ date: 2024-10-15 00:00:00.000000000 Z
41
41
  dependencies: []
42
42
  description:
43
43
  email:
metadata.gz.sig CHANGED
Binary file