Module: FormatParser::IOUtils

Defined Under Namespace

Classes: InvalidRead, MalformedFile

Constant Summary collapse

INTEGER_DIRECTIVES =
{
  1 => 'C',
  2 => 'S',
  4 => 'L',
  8 => 'Q'
}

Instance Method Summary collapse

Instance Method Details

#read_bytes(n) ⇒ Object Also known as: read_string

ā€˜nā€™ is the number of bytes to read



52
53
54
# File 'lib/io_utils.rb', line 52

def read_bytes(n)
  safe_read(@buf, n)
end

#read_fixed_point(fractional_digits: 16, **kwargs) ⇒ Object



47
48
49
# File 'lib/io_utils.rb', line 47

def read_fixed_point(fractional_digits: 16, **kwargs)
  read_int(**kwargs) / 2.0**fractional_digits
end

#read_int(n: 4, signed: false, big_endian: true) ⇒ Object

Read an integer.

Parameters:

  • n (Integer) (defaults to: 4)

    Number of bytes. Defaults to 4 (32-bit).

  • signed (Boolean) (defaults to: false)

    Signed if true, Unsigned if false. Defaults to false. (unsigned)

  • big_endian (Boolean) (defaults to: true)

    Big-endian if true, little-endian if false. Defaults to true (big-endian).



40
41
42
43
44
45
# File 'lib/io_utils.rb', line 40

def read_int(n: 4, signed: false, big_endian: true)
  directive = INTEGER_DIRECTIVES[n]
  directive.downcase! if signed
  directive += (big_endian ? ">" : "<") if n > 1
  read_bytes(n).unpack(directive).first
end

#safe_read(io, n) ⇒ Object

Raises:

  • (ArgumentError)


15
16
17
18
19
20
21
22
23
# File 'lib/io_utils.rb', line 15

def safe_read(io, n)
  raise ArgumentError, 'Unbounded reads are not supported' if n.nil?
  buf = io.read(n)

  raise InvalidRead, "We wanted to read #{n} bytes from the IO, but the IO is at EOF" unless buf
  raise InvalidRead, "We wanted to read #{n} bytes from the IO, but we got #{buf.bytesize} instead" if buf.bytesize != n

  buf
end

#safe_skip(io, n) ⇒ Object

Raises:

  • (ArgumentError)


25
26
27
28
29
30
31
32
33
34
# File 'lib/io_utils.rb', line 25

def safe_skip(io, n)
  raise ArgumentError, 'Unbounded skips are not supported' if n.nil?

  return if n == 0

  raise InvalidRead, 'Negative skips are not supported' if n < 0

  io.seek(io.pos + n)
  nil
end

#skip_bytes(n) ⇒ Object



58
59
60
61
# File 'lib/io_utils.rb', line 58

def skip_bytes(n)
  safe_skip(@buf, n)
  yield if block_given?
end