Class: Cabriolet::CAB::Extractor::BlockReader

Inherits:
Object
  • Object
show all
Defined in:
lib/cabriolet/cab/extractor.rb

Overview

BlockReader wraps cabinet file handles and reads CFDATA blocks Handles multi-part cabinets by following the FolderData chain

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io_system, folder_data, num_blocks, salvage) ⇒ BlockReader

Returns a new instance of BlockReader.



222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/cabriolet/cab/extractor.rb', line 222

def initialize(io_system, folder_data, num_blocks, salvage)
  @io_system = io_system
  @current_data = folder_data
  @num_blocks = num_blocks
  @salvage = salvage
  @current_block = 0
  @buffer = ""
  @buffer_pos = 0
  @cab_handle = nil

  # Open first cabinet and seek to data offset
  open_current_cabinet
end

Instance Attribute Details

#current_blockObject (readonly)

Returns the value of attribute current_block.



219
220
221
# File 'lib/cabriolet/cab/extractor.rb', line 219

def current_block
  @current_block
end

#current_dataObject (readonly)

Returns the value of attribute current_data.



219
220
221
# File 'lib/cabriolet/cab/extractor.rb', line 219

def current_data
  @current_data
end

#io_systemObject (readonly)

Returns the value of attribute io_system.



219
220
221
# File 'lib/cabriolet/cab/extractor.rb', line 219

def io_system
  @io_system
end

#num_blocksObject (readonly)

Returns the value of attribute num_blocks.



219
220
221
# File 'lib/cabriolet/cab/extractor.rb', line 219

def num_blocks
  @num_blocks
end

#salvageObject (readonly)

Returns the value of attribute salvage.



219
220
221
# File 'lib/cabriolet/cab/extractor.rb', line 219

def salvage
  @salvage
end

Instance Method Details

#closeObject



284
285
286
287
# File 'lib/cabriolet/cab/extractor.rb', line 284

def close
  @cab_handle&.close
  @cab_handle = nil
end

#read(bytes) ⇒ Object



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
266
267
268
269
270
271
272
273
# File 'lib/cabriolet/cab/extractor.rb', line 236

def read(bytes)
  # Early return if we've already exhausted all blocks and buffer
  if @current_block >= @num_blocks && @buffer_pos >= @buffer.bytesize
    if ENV["DEBUG_BLOCK"]
      warn "DEBUG BlockReader.read(#{bytes}): Already exhausted, returning empty"
    end
    return +""
  end

  result = +""

  if ENV["DEBUG_BLOCK"]
    warn "DEBUG BlockReader.read(#{bytes}): buffer_size=#{@buffer.bytesize} buffer_pos=#{@buffer_pos} block=#{@current_block}/#{@num_blocks}"
  end

  while result.bytesize < bytes
    # Read more data if buffer is empty
    if (@buffer_pos >= @buffer.bytesize) && !read_next_block
      if ENV["DEBUG_BLOCK"]
        warn "DEBUG BlockReader.read: EXHAUSTED at result.bytesize=#{result.bytesize} (wanted #{bytes})"
      end
      break
    end

    # Copy from buffer
    available = @buffer.bytesize - @buffer_pos
    to_copy = [available, bytes - result.bytesize].min

    result << @buffer[@buffer_pos, to_copy]
    @buffer_pos += to_copy
  end

  if ENV["DEBUG_BLOCK"]
    warn "DEBUG BlockReader.read: returning #{result.bytesize} bytes"
  end

  result
end

#seek(_offset, _whence) ⇒ Object



275
276
277
278
# File 'lib/cabriolet/cab/extractor.rb', line 275

def seek(_offset, _whence)
  # Not implemented for block reader
  0
end

#tellObject



280
281
282
# File 'lib/cabriolet/cab/extractor.rb', line 280

def tell
  0
end