dissect.util.stream#

Module Contents#

Classes#

AlignedStream

Basic buffered stream that provides easy aligned reads.

RangeStream

Create a stream with a specific range from another file-like object.

RelativeStream

Create a relative stream from another file-like object.

BufferedStream

Create a buffered stream from another file-like object.

MappingStream

Create a stream from multiple mapped file-like objects.

RunlistStream

Create a stream from multiple runs on another file-like object.

OverlayStream

Create a stream from another file-like object with the ability to overlay other streams or bytes.

ZlibStream

Create a zlib stream from another file-like object.

Attributes#

dissect.util.stream.STREAM_BUFFER_SIZE#
class dissect.util.stream.AlignedStream(size: int | None = None, align: int = STREAM_BUFFER_SIZE)#

Bases: io.RawIOBase

Basic buffered stream that provides easy aligned reads.

Must be subclassed for various stream implementations. Subclasses can implement:
  • _read(offset, length)

  • _seek(pos, whence=io.SEEK_SET)

The offset and length for _read are guaranteed to be aligned. The only time that overriding _seek would make sense is if there’s no known size of your stream, but still want to provide SEEK_END functionality.

Most subclasses of AlignedStream take one or more file-like objects as source. Operations on these subclasses, like reading, will modify the source file-like object as a side effect.

Parameters:
  • size – The size of the stream. This is used in read and seek operations. None if unknown.

  • align – The alignment size. Read operations are aligned on this boundary. Also determines buffer size.

seek(pos: int, whence: int = io.SEEK_SET) int#

Seek the stream to the specified position.

read(n: int = -1) bytes#

Read and return up to n bytes, or read to the end of the stream if n is -1.

Returns an empty bytes object on EOF.

readinto(b: bytearray) int#

Read bytes into a pre-allocated bytes-like object b.

Returns an int representing the number of bytes read (0 for EOF).

readall() bytes#

Read until end of stream.

readoffset(offset: int, length: int) bytes#

Convenience method to read from a certain offset with 1 call.

tell() int#

Return current stream position.

close() None#

Flush and close the IO object.

This method has no effect if the file is already closed.

readable() bool#

Return whether object was opened for reading.

If False, read() will raise OSError.

seekable() bool#

Return whether object supports random access.

If False, seek(), tell() and truncate() will raise OSError. This method may need to do a test seek().

class dissect.util.stream.RangeStream(fh: BinaryIO, offset: int, size: int, align: int = STREAM_BUFFER_SIZE)#

Bases: AlignedStream

Create a stream with a specific range from another file-like object.

ASCII representation:

Source file-like object
|................................................|
        RangeStream with offset and size
        |............................|
Parameters:
  • fh – The source file-like object.

  • offset – The offset the stream should start from on the source file-like object.

  • size – The size the stream should be.

  • align – The alignment size.

class dissect.util.stream.RelativeStream(fh: BinaryIO, offset: int, size: int | None = None, align: int = STREAM_BUFFER_SIZE)#

Bases: AlignedStream

Create a relative stream from another file-like object.

ASCII representation:

Source file-like object
|................................................|
        RelativeStream with offset
        |........................................|
Parameters:
  • fh – The source file-like object.

  • offset – The offset the stream should start from on the source file-like object.

  • size – The size the stream should be.

  • align – The alignment size.

class dissect.util.stream.BufferedStream(fh: BinaryIO, offset: int = 0, size: int | None = None, align: int = STREAM_BUFFER_SIZE)#

Bases: RelativeStream

Create a buffered stream from another file-like object.

Optionally start from a specific offset.

Parameters:
  • fh – The source file-like object.

  • offset – The offset the stream should start from.

  • size – The size the stream should be.

  • align – The alignment size.

class dissect.util.stream.MappingStream(size: int | None = None, align: int = STREAM_BUFFER_SIZE)#

Bases: AlignedStream

Create a stream from multiple mapped file-like objects.

Parameters:
  • size – The size the stream should be.

  • align – The alignment size.

add(offset: int, size: int, fh: BinaryIO, file_offset: int = 0) None#

Add a file-like object to the stream.

Parameters:
  • offset – The offset in the stream this fh maps to.

  • size – The size that this mapped fh spans in the stream.

  • fh – The file-like object to map.

  • file_offset – The offset in the fh to start from.

class dissect.util.stream.RunlistStream(fh: BinaryIO, runlist: list[tuple[int, int]], size: int, block_size: int, align: int | None = None)#

Bases: AlignedStream

Create a stream from multiple runs on another file-like object.

This is common in filesystems, where file data information is stored in “runs”. A run is a (block_offset, block_count) tuple, meaning the amount of consecutive blocks from a specific starting block. A block_offset of None represents a sparse run, meaning it must simply return all \x00 bytes.

Parameters:
  • fh – The source file-like object.

  • runlist – The runlist for this stream in block units.

  • size – The size of the stream. This can be smaller than the total sum of blocks (to account for slack space).

  • block_size – The block size in bytes.

  • align – Optional alignment that differs from the block size, otherwise block_size is used as alignment.

property runlist: list[tuple[int, int]]#
class dissect.util.stream.OverlayStream(fh: BinaryIO, size: int | None = None, align: int = STREAM_BUFFER_SIZE)#

Bases: AlignedStream

Create a stream from another file-like object with the ability to overlay other streams or bytes.

Useful for patching large file-like objects without having to cache the entire contents. First wrap the original stream in this class, and then call add() with the offset and data to overlay.

Parameters:
  • fh – The source file-like object.

  • size – The size the stream should be.

  • align – The alignment size.

add(offset: int, data: bytes | BinaryIO, size: int | None = None) None#

Add an overlay at the given offset.

Parameters:
  • offset – The offset in bytes to add an overlay at.

  • data – The bytes or file-like object to overlay

  • size – Optional size specification of the overlay, if it can’t be inferred.

class dissect.util.stream.ZlibStream(fh: BinaryIO, size: int | None = None, align: int = STREAM_BUFFER_SIZE, **kwargs)#

Bases: AlignedStream

Create a zlib stream from another file-like object.

Basically the same as gzip.GzipFile but for raw zlib streams. Due to the nature of zlib streams, seeking backwards requires resetting the decompression context.

Parameters:
  • fh – The source file-like object.

  • size – The size the stream should be.

readall() bytes#

Read until end of stream.