Class: IO::LikeHelpers::CharacterIO::ConverterReader Private
- Inherits:
-
BasicReader
- Object
- BasicReader
- IO::LikeHelpers::CharacterIO::ConverterReader
- Defined in:
- lib/io/like_helpers/character_io/converter_reader.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
This class is a character reader that converts bytes from one character encoding to another. It is also used when simply handling universal newline conversion.
Constant Summary collapse
- MIN_BUFFER_SIZE =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
This comes from MRI.
128 * 1024
Instance Method Summary collapse
-
#clear ⇒ nil
private
Clears the state of this reader.
-
#consume(length) ⇒ nil
private
Consumes bytes from the front of the buffer.
-
#content ⇒ String
private
Returns the bytes of the buffer as a binary encoded String.
-
#empty? ⇒ Boolean
private
Returns ‘true` if the read buffer is empty and `false` otherwise.
-
#initialize(buffered_io, buffer_size: MIN_BUFFER_SIZE, encoding_opts: {}, external_encoding: nil, internal_encoding: nil) ⇒ ConverterReader
constructor
private
Creates a new intance of this class.
-
#refill(many = true) ⇒ nil
private
Refills the buffer from the stream.
-
#unread(buffer, length: buffer.bytesize) ⇒ nil
private
Places bytes at the beginning of the read buffer.
Methods inherited from BasicReader
Constructor Details
#initialize(buffered_io, buffer_size: MIN_BUFFER_SIZE, encoding_opts: {}, external_encoding: nil, internal_encoding: nil) ⇒ ConverterReader
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Creates a new intance of this class.
Note that ‘MIN_BUFFER_SIZE` is used for the buffer size when `buffer_size` is `nil` or less than `MIN_BUFFER_SIZE`.
When ‘internal_encoding` is `nil`, character conversion is not performed, but newline conversion will still be performed if `encoding_opts` specifies such.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/io/like_helpers/character_io/converter_reader.rb', line 34 def initialize( buffered_io, buffer_size: MIN_BUFFER_SIZE, encoding_opts: {}, external_encoding: nil, internal_encoding: nil ) super(buffered_io, encoding: internal_encoding || external_encoding) if ! buffer_size || buffer_size < MIN_BUFFER_SIZE buffer_size = MIN_BUFFER_SIZE end @buffer_size = buffer_size @start_idx = @end_idx = @buffer_size @buffer = "\0".b * @buffer_size @converter = internal_encoding ? Encoding::Converter.new( external_encoding, internal_encoding, **encoding_opts ) : Encoding::Converter.new('', '', **encoding_opts) end |
Instance Method Details
#clear ⇒ nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Clears the state of this reader.
60 61 62 63 64 |
# File 'lib/io/like_helpers/character_io/converter_reader.rb', line 60 def clear super @start_idx = @end_idx = @buffer_size nil end |
#consume(length) ⇒ nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Consumes bytes from the front of the buffer.
86 87 88 89 90 91 |
# File 'lib/io/like_helpers/character_io/converter_reader.rb', line 86 def consume(length) existing_content_size = @end_idx - @start_idx length = existing_content_size if length > existing_content_size @start_idx += length nil end |
#content ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the bytes of the buffer as a binary encoded String.
The returned bytes should be encoded using the value of BasicReader#encoding and ‘String#force_encoding`. Bytes are returned rather than characters because CharacterIO#read_line works on bytes for compatibility with the MRI implementation and working with characters would be inefficient in that case.
76 77 78 |
# File 'lib/io/like_helpers/character_io/converter_reader.rb', line 76 def content @buffer[@start_idx..@end_idx-1] end |
#empty? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns ‘true` if the read buffer is empty and `false` otherwise.
97 98 99 |
# File 'lib/io/like_helpers/character_io/converter_reader.rb', line 97 def empty? @start_idx >= @end_idx end |
#refill(many = true) ⇒ nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Refills the buffer from the stream.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/io/like_helpers/character_io/converter_reader.rb', line 118 def refill(many = true) existing_content_size = @end_idx - @start_idx # Nothing to do if the character buffer is already full. return nil if existing_content_size >= @buffer_size conversion_buffer = ''.b = Encoding::Converter::PARTIAL_INPUT |= Encoding::Converter::AFTER_OUTPUT unless many begin loop do buffered_io.refill if buffered_io.read_buffer_empty? input = buffered_io.peek input_count = input.bytesize result = @converter.primitive_convert( input, conversion_buffer, 0, @buffer_size - existing_content_size, ) case result when :after_output, :source_buffer_empty, :destination_buffer_full consumed = input_count - input.bytesize buffered_io.skip(consumed) break unless conversion_buffer.empty? next when :invalid_byte_sequence putback = @converter.putback consumed = input_count - input.bytesize - putback.bytesize buffered_io.skip(consumed) end raise @converter.last_error end rescue EOFError conversion_buffer << @converter.finish # Ignore this if there is still buffered data. raise if conversion_buffer.empty? end append_to_buffer(conversion_buffer.b) nil end |
#unread(buffer, length: buffer.bytesize) ⇒ nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Places bytes at the beginning of the read buffer.
178 179 180 181 182 183 184 185 186 187 |
# File 'lib/io/like_helpers/character_io/converter_reader.rb', line 178 def unread(buffer, length: buffer.bytesize) existing_content_size = @end_idx - @start_idx if length > @buffer_size - existing_content_size raise IOError, 'insufficient buffer space for unread' end prepend_to_buffer(buffer.b[0, length]) nil end |