Class: Bindef
- Inherits:
-
Object
- Object
- Bindef
- Includes:
- Extras::Ctrl, Extras::Int128, Extras::String, Extras::TLV, Schemas
- Defined in:
- lib/bindef.rb,
lib/bindef/extras.rb,
lib/bindef/schemas.rb,
lib/bindef/version.rb,
lib/bindef/exceptions.rb,
lib/bindef/extras/tlv.rb,
lib/bindef/extras/ctrl.rb,
lib/bindef/extras/int128.rb,
lib/bindef/extras/string.rb
Overview
The primary namespace for Bindef.
Defined Under Namespace
Modules: Extras, Schemas Classes: BindefError, CommandError, EvaluationError, PragmaError
Constant Summary collapse
- VERSION =
The current Bindef version.
"0.0.5"
Constants included from Schemas
Schemas::DEFAULT_PRAGMAS, Schemas::ENDIANDED_INTEGER_COMMAND_MAP, Schemas::PRAGMA_SCHEMA
Instance Attribute Summary collapse
-
#pragmas ⇒ Hash
readonly
The map of current pragma settings.
Instance Method Summary collapse
-
#blobify(value, fmt) ⇒ Object
private
Builds a string containing the given value packed into the given format.
-
#emit(blob) ⇒ void
private
Emits the given blob of data.
-
#f32(num) {|blob| ... } ⇒ void
Emits a
float
. -
#f64(num) {|blob| ... } ⇒ void
Emits a
double
. -
#i16(num) ⇒ void
Emits a
int16_t
. -
#i32(num) ⇒ void
Emits a
int32_t
. -
#i64(num) ⇒ void
Emits a
int64_t
. -
#i8(num) {|blob| ... } ⇒ void
Emits a
int8_t
. -
#initialize(output = STDOUT, error = STDERR, verbose: false, warnings: true) ⇒ Bindef
constructor
private
A new instance of Bindef.
-
#method_missing(*args) ⇒ Object
private
Captures unknown commands and raises an appropriate error.
-
#pragma(**hsh) {|void| ... } ⇒ void
Changes the values of the given pragma keys.
-
#str(string) {|blob| ... } ⇒ void
Emits a string.
-
#u16(num) ⇒ void
Emits a
uint16_t
. -
#u32(num) ⇒ void
Emits a
uint32_t
. -
#u64(num) ⇒ void
Emits a
uint64_t
. -
#u8(num) {|blob| ... } ⇒ void
Emits a
uint8_t
. -
#validate_int_width!(num, width) ⇒ void
private
Ensures that the given integer number can be represented within the given width of bits.
-
#verbose(msg) ⇒ void
private
Writes a message to the error I/O if verbose mode is enabled.
-
#warning(msg) ⇒ void
private
Writes a warning message to the error I/O.
Methods included from Extras::String
Methods included from Extras::Int128
Methods included from Extras::TLV
Constructor Details
#initialize(output = STDOUT, error = STDERR, verbose: false, warnings: true) ⇒ Bindef
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of Bindef.
15 16 17 18 19 |
# 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 |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(*args) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Captures unknown commands and raises an appropriate error.
66 67 68 |
# File 'lib/bindef.rb', line 66 def method_missing(*args) raise CommandError, "unknown command: #{args.join(" ")}" end |
Instance Attribute Details
#pragmas ⇒ Hash (readonly)
Returns the map of current pragma settings.
12 13 14 |
# File 'lib/bindef.rb', line 12 def pragmas @pragmas end |
Instance Method Details
#blobify(value, fmt) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Builds a string containing the given value packed into the given format.
52 53 54 |
# File 'lib/bindef.rb', line 52 def blobify(value, fmt) [value].pack(fmt) end |
#emit(blob) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Emits the given blob of data.
60 61 62 |
# File 'lib/bindef.rb', line 60 def emit(blob) @output << blob end |
#f32(num) {|blob| ... } ⇒ void
This method returns an undefined value.
Emits a float
.
110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/bindef.rb', line 110 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| ... } ⇒ void
This method returns an undefined value.
Emits a double
.
125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/bindef.rb', line 125 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 |
#i16(num) ⇒ void
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/bindef.rb', line 194 ENDIANDED_INTEGER_COMMAND_MAP.each do |cmd, fmt| define_method cmd do |num, &block| warning "#{num} in #{cmd} command is negative" if num.negative? && cmd[0] == "u" validate_int_width! num, cmd[1..-1].to_i end_fmt = pragmas[:endian] == :big ? "#{fmt}>" : "#{fmt}<" blob = blobify num, end_fmt # Fun fact: You can't use `yield` in `define_method`. block&.call(blob) emit blob end end |
#i32(num) ⇒ void
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/bindef.rb', line 194 ENDIANDED_INTEGER_COMMAND_MAP.each do |cmd, fmt| define_method cmd do |num, &block| warning "#{num} in #{cmd} command is negative" if num.negative? && cmd[0] == "u" validate_int_width! num, cmd[1..-1].to_i end_fmt = pragmas[:endian] == :big ? "#{fmt}>" : "#{fmt}<" blob = blobify num, end_fmt # Fun fact: You can't use `yield` in `define_method`. block&.call(blob) emit blob end end |
#i64(num) ⇒ void
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/bindef.rb', line 194 ENDIANDED_INTEGER_COMMAND_MAP.each do |cmd, fmt| define_method cmd do |num, &block| warning "#{num} in #{cmd} command is negative" if num.negative? && cmd[0] == "u" validate_int_width! num, cmd[1..-1].to_i end_fmt = pragmas[:endian] == :big ? "#{fmt}>" : "#{fmt}<" blob = blobify num, end_fmt # Fun fact: You can't use `yield` in `define_method`. block&.call(blob) emit blob end end |
#i8(num) {|blob| ... } ⇒ void
This method returns an undefined value.
Emits a int8_t
.
154 155 156 157 158 159 160 161 162 |
# File 'lib/bindef.rb', line 154 def i8(num) validate_int_width! num, 8 blob = blobify num, "c" yield blob if block_given? emit blob end |
#pragma(**hsh) {|void| ... } ⇒ void
This method returns an undefined value.
Changes the values of the given pragma keys.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/bindef.rb', line 78 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 if block_given? yield pragmas.replace old_pragmas end end |
#str(string) {|blob| ... } ⇒ void
98 99 100 101 102 103 104 105 |
# File 'lib/bindef.rb', line 98 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 |
#u16(num) ⇒ void
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/bindef.rb', line 194 ENDIANDED_INTEGER_COMMAND_MAP.each do |cmd, fmt| define_method cmd do |num, &block| warning "#{num} in #{cmd} command is negative" if num.negative? && cmd[0] == "u" validate_int_width! num, cmd[1..-1].to_i end_fmt = pragmas[:endian] == :big ? "#{fmt}>" : "#{fmt}<" blob = blobify num, end_fmt # Fun fact: You can't use `yield` in `define_method`. block&.call(blob) emit blob end end |
#u32(num) ⇒ void
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/bindef.rb', line 194 ENDIANDED_INTEGER_COMMAND_MAP.each do |cmd, fmt| define_method cmd do |num, &block| warning "#{num} in #{cmd} command is negative" if num.negative? && cmd[0] == "u" validate_int_width! num, cmd[1..-1].to_i end_fmt = pragmas[:endian] == :big ? "#{fmt}>" : "#{fmt}<" blob = blobify num, end_fmt # Fun fact: You can't use `yield` in `define_method`. block&.call(blob) emit blob end end |
#u64(num) ⇒ void
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/bindef.rb', line 194 ENDIANDED_INTEGER_COMMAND_MAP.each do |cmd, fmt| define_method cmd do |num, &block| warning "#{num} in #{cmd} command is negative" if num.negative? && cmd[0] == "u" validate_int_width! num, cmd[1..-1].to_i end_fmt = pragmas[:endian] == :big ? "#{fmt}>" : "#{fmt}<" blob = blobify num, end_fmt # Fun fact: You can't use `yield` in `define_method`. block&.call(blob) emit blob end end |
#u8(num) {|blob| ... } ⇒ void
This method returns an undefined value.
Emits a uint8_t
.
140 141 142 143 144 145 146 147 148 149 |
# File 'lib/bindef.rb', line 140 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) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Ensures that the given integer number can be represented within the given width of bits.
44 45 46 |
# 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) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Uses the :verbose
#pragma
This method returns an undefined value.
Writes a message to the error I/O if verbose mode is enabled.
26 27 28 |
# File 'lib/bindef.rb', line 26 def verbose(msg) @error.puts "V: #{msg}" if @pragmas[:verbose] end |
#warning(msg) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Writes a warning message to the error I/O.
34 35 36 |
# File 'lib/bindef.rb', line 34 def warning(msg) @error.puts "W: #{msg}" if @pragmas[:warnings] end |