class Bindef

The primary namespace for {Bindef}.

Constants

VERSION

The current {Bindef} version.

Attributes

pragmas[R]

@return [Hash] the map of current pragma settings

Public Class Methods

new(output = STDOUT, error = STDERR, verbose: false, warnings: true) click to toggle source

@api private

# File lib/bindef.rb, line 15
def initialize(output = STDOUT, error = STDERR, verbose: false, warnings: true)
  @output = output
  @error = error
  @pragmas = DEFAULT_PRAGMAS.dup.update(verbose: verbose, warnings: warnings)
end

Public Instance Methods

blobify(value, fmt) click to toggle source

Builds a string containing the given value packed into the given format. @param value [Object] the value to emit @param fmt [String] the `Array#pack` format to emit it in @api private

# File lib/bindef.rb, line 52
def blobify(value, fmt)
  [value].pack(fmt)
end
emit(blob) click to toggle source

Emits the given blob of data. @param blob [String] the data to emit @return [void] @api private

# File lib/bindef.rb, line 60
def emit(blob)
  @output << blob
end
f32(num) { |blob| ... } click to toggle source

Emits a `float`. @param num [Numeric] the number to emit @return [void]

# File lib/bindef.rb, line 115
def f32(num)
  # NOTE: All floats are double-precision in Ruby, so I don't have a good
  # (read: simple) way to validate single-precision floats yet.

  fmt = pragmas[:endian] == :big ? "g" : "e"
  blob = blobify num, fmt

  yield blob if block_given?

  emit blob
end
f64(num) { |blob| ... } click to toggle source

Emits a `double`. @param num [Numeric] the number to emit @return [void]

# File lib/bindef.rb, line 130
def f64(num)
  raise CommandError, "#{num} is an invalid double-precision float" if num.to_f.nan?

  fmt = pragmas[:endian] == :big ? "G" : "E"

  blob = blobify num, fmt

  yield blob if block_given?

  emit blob
end
i8(num) { |blob| ... } click to toggle source

Emits a `int8_t`. @param num [Integer] the number to emit @return [void]

# File lib/bindef.rb, line 159
def i8(num)
  validate_int_width! num, 8

  blob = blobify num, "c"

  yield blob if block_given?

  emit blob
end
method_missing(*args) click to toggle source

Captures unknown commands and raises an appropriate error. @api private

# File lib/bindef.rb, line 66
def method_missing(*args)
  raise CommandError, "unknown command: #{args.join(" ")}"
end
pragma(**hsh) { || ... } click to toggle source

Changes the values of the given pragma keys. @see PRAGMA_SCHEMA @param hsh [Hash] the keys and values to update the pragma state with @yield [void] A temporary scope for the pragma changes, if a block is given @return [void] @example

pragma verbose: true # changes the `:verbose` pragma to `true` for the remainder of the script
pragma encoding: "utf-16" { str "foobar" } # changes the `:encoding` pragma for the block only
# File lib/bindef.rb, line 83
def pragma(**hsh)
  old_pragmas = pragmas.dup

  hsh.each do |key, value|
    raise PragmaError, "unknown pragma: #{key}" unless @pragmas.key? key
    raise PragmaError, "bad pragma value: #{value}" unless PRAGMA_SCHEMA[key].include?(value)

    pragmas[key] = value
  end

  return unless block_given?

  yield
  pragmas.replace old_pragmas
end
respond_to_missing?(*_args) click to toggle source

@api private

# File lib/bindef.rb, line 71
def respond_to_missing?(*_args)
  true
end
str(string) { |blob| ... } click to toggle source

Emits a string. @note Uses the `:encoding` {#pragma} @param string [String] the string to emit @return [void]

# File lib/bindef.rb, line 103
def str(string)
  enc_string = string.encode pragmas[:encoding]
  blob = blobify enc_string, "a#{enc_string.bytesize}"

  yield blob if block_given?

  emit blob
end
u8(num) { |blob| ... } click to toggle source

Emits a `uint8_t`. @param num [Integer] the number to emit @return [void]

# File lib/bindef.rb, line 145
def u8(num)
  warning "#{num} in u8 command is negative" if num.negative?
  validate_int_width! num, 8

  blob = blobify num, "C"

  yield blob if block_given?

  emit blob
end
validate_int_width!(num, width) click to toggle source

Ensures that the given integer number can be represented within the given width of bits. @param num [Integer] the number to test @param width [Integer] the bit width to test against @return [void] @raise [CommandError] if the number is wider than `width` bits @api private

# File lib/bindef.rb, line 44
def validate_int_width!(num, width)
  raise CommandError, "width of #{num} exceeds #{width} bits" if num.bit_length > width
end
verbose(msg) click to toggle source

Writes a message to the error I/O if verbose mode is enabled. @note Uses the `:verbose` {#pragma} @param msg [String] the message to write @return [void] @api private

# File lib/bindef.rb, line 26
def verbose(msg)
  @error.puts "V: #{msg}" if @pragmas[:verbose]
end
warning(msg) click to toggle source

Writes a warning message to the error I/O. @param msg [String] the warning message to write @return [void] @api private

# File lib/bindef.rb, line 34
def warning(msg)
  @error.puts "W: #{msg}" if @pragmas[:warnings]
end