Method: XZ::StreamReader#read
- Defined in:
- lib/facter/util/ruby-xz-1.0.0/lib/xz/stream_reader.rb
#read(length = nil, outbuf = String.new) ⇒ Object
Mostly like IO#read. The length
parameter refers to the amount of decompressed bytes to read, not the amount of bytes to read from the compressed data. That is, if you request a read of 50 bytes, you will receive a string with a maximum length of 50 bytes, regardless of how many bytes this was in compressed form.
Return values are as per IO#read.
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/facter/util/ruby-xz-1.0.0/lib/xz/stream_reader.rb', line 203 def read(length = nil, outbuf = String.new) return "".force_encoding(Encoding::BINARY) if length == 0 # Shortcut; retval as per IO#read. # Note: Querying the underlying IO as early as possible allows to # have Ruby's own IO exceptions to bubble up. if length return nil if eof? # In line with IO#read outbuf.force_encoding(Encoding::BINARY) # As per IO#read docs # The user's request is in decompressed bytes, so it doesn't matter # how much is actually read from the compressed file. if @delegate_io.eof? data = "" action = XZ::LibLZMA::LZMA_FINISH else data = @delegate_io.read(XZ::CHUNK_SIZE) action = @delegate_io.eof? ? XZ::LibLZMA::LZMA_FINISH : XZ::LibLZMA::LZMA_RUN end lzma_code(data, action) { |decompressed| @readbuf << decompressed } # If the requested amount has been read, return it. # Also return if EOF has been reached. Note that # String#slice! will clear the string to an empty one # if `length' is greater than the string length. # If EOF is not yet reached, try reading and decompresing # more data. if @readbuf.bytesize >= length || @delegate_io.eof? result = @readbuf.slice!(0, length) @pos += result.bytesize return outbuf.replace(result) else return read(length, outbuf) end else # Read the entire file and decompress it into memory, returning it. while chunk = @delegate_io.read(XZ::CHUNK_SIZE) action = @delegate_io.eof? ? XZ::LibLZMA::LZMA_FINISH : XZ::LibLZMA::LZMA_RUN lzma_code(chunk, action) { |decompressed| @readbuf << decompressed } end @pos += @readbuf.bytesize # Apply encoding conversion. # First, tag the read data with the external encoding. @readbuf.force_encoding(@external_encoding) # Now, transcode it to the internal encoding if that was requested. # Otherwise return it with the external encoding as-is. if @internal_encoding @readbuf.encode!(@internal_encoding, @transcode_options) outbuf.force_encoding(@internal_encoding) else outbuf.force_encoding(@external_encoding) end outbuf.replace(@readbuf) @readbuf.clear @readbuf.force_encoding(Encoding::BINARY) # Back to binary mode for further reading return outbuf end end |