Class: AudioTag::ID3::StreamReader
- Inherits:
-
Object
- Object
- AudioTag::ID3::StreamReader
- Defined in:
- lib/audio_tag/id3/stream_reader.rb
Overview
Wrapper for native IO stream objects that defines a consistent reading interface.
Bang methods indicate that the read operation is not idempotent, as calling them will result in the stream position being advanced. Non-bang methods are idempotent, as they reset the stream position after reading meaning the net effect on the stream position is 0.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#stream ⇒ Object
readonly
Returns the value of attribute stream.
Instance Method Summary collapse
-
#initialize(stream) ⇒ StreamReader
constructor
A new instance of StreamReader.
- #read(length) ⇒ Object
- #read!(length) ⇒ Object
- #read_byte ⇒ Object
- #read_byte! ⇒ Object
- #read_bytes(length) ⇒ Object
- #read_bytes!(length) ⇒ Object
- #read_bytes_until(byte) ⇒ Object
-
#read_bytes_until!(byte, consume_delimiter: true) ⇒ Object
Uses instance method rather than stream.eof? directly as this can be overridden in child classes to prevent read*_until methods extending past the end of a settable limit.
- #read_until(byte) ⇒ Object
-
#read_until!(byte, consume_delimiter: true) ⇒ Object
Reads the stream up to the specified byte, for example a null delimiter.
Constructor Details
#initialize(stream) ⇒ StreamReader
Returns a new instance of StreamReader.
13 14 15 |
# File 'lib/audio_tag/id3/stream_reader.rb', line 13 def initialize(stream) @stream = stream end |
Instance Attribute Details
#stream ⇒ Object (readonly)
Returns the value of attribute stream.
11 12 13 |
# File 'lib/audio_tag/id3/stream_reader.rb', line 11 def stream @stream end |
Instance Method Details
#read(length) ⇒ Object
21 22 23 24 25 26 27 |
# File 'lib/audio_tag/id3/stream_reader.rb', line 21 def read(length) pos = stream.pos read!(length) ensure stream.seek(pos) end |
#read!(length) ⇒ Object
17 18 19 |
# File 'lib/audio_tag/id3/stream_reader.rb', line 17 def read!(length) stream.read(length) || raise end |
#read_byte ⇒ Object
45 46 47 |
# File 'lib/audio_tag/id3/stream_reader.rb', line 45 def read_byte read_bytes(1).first || raise end |
#read_byte! ⇒ Object
41 42 43 |
# File 'lib/audio_tag/id3/stream_reader.rb', line 41 def read_byte! read_bytes!(1).first || raise end |
#read_bytes(length) ⇒ Object
33 34 35 36 37 38 39 |
# File 'lib/audio_tag/id3/stream_reader.rb', line 33 def read_bytes(length) pos = stream.pos read_bytes!(length) ensure stream.seek(pos) end |
#read_bytes!(length) ⇒ Object
29 30 31 |
# File 'lib/audio_tag/id3/stream_reader.rb', line 29 def read_bytes!(length) stream.read(length)&.bytes || raise end |
#read_bytes_until(byte) ⇒ Object
83 84 85 86 87 88 89 |
# File 'lib/audio_tag/id3/stream_reader.rb', line 83 def read_bytes_until(byte) pos = stream.pos read_bytes_until!(byte) ensure stream.seek(pos) end |
#read_bytes_until!(byte, consume_delimiter: true) ⇒ Object
Uses instance method rather than stream.eof? directly as this can be overridden in child classes to prevent read*_until methods extending past the end of a settable limit.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/audio_tag/id3/stream_reader.rb', line 68 def read_bytes_until!(byte, consume_delimiter: true) [].tap do |bytes| until end_of_stream? next_byte = stream.getbyte if next_byte == byte stream.ungetbyte(1) unless consume_delimiter break end bytes << next_byte end end end |
#read_until(byte) ⇒ Object
61 62 63 |
# File 'lib/audio_tag/id3/stream_reader.rb', line 61 def read_until(byte) read_bytes_until(byte).pack("c*") end |
#read_until!(byte, consume_delimiter: true) ⇒ Object
Reads the stream up to the specified byte, for example a null delimiter. The given byte is not included in the output, but the stream is advanced to the position after it unless the consume_delimiter flag is false.
This is useful for extracting string fragments until a delimiter without including it in the extracted fragment nor the start of the next.
57 58 59 |
# File 'lib/audio_tag/id3/stream_reader.rb', line 57 def read_until!(byte, consume_delimiter: true) read_bytes_until!(byte, consume_delimiter:).pack("c*") end |