Class: BinStruct::BitAttr Abstract
- Inherits:
-
Object
- Object
- BinStruct::BitAttr
- Includes:
- Structable
- Defined in:
- lib/bin_struct/bit_attr.rb
Overview
This class is abstract.
Subclasses must de derived using BitAttr.create.
Define a bitfield attribute to embed in a Struct. Use it through Struct.define_bit_attr
Defined Under Namespace
Classes: Parameters
Class Attribute Summary collapse
- .parameters ⇒ Parameters readonly
Instance Attribute Summary collapse
- #bit_methods ⇒ ::Array[Symbol] readonly
-
#width ⇒ Integer
readonly
Width in bits of bit attribute.
Class Method Summary collapse
-
.create(width:, endian: :big, **fields) ⇒ Class
Create a new BitAttr subclass with specified parameters.
Instance Method Summary collapse
- #format_inspect ⇒ Object
-
#from_human(value) ⇒ self
Set fields from associated integer.
-
#initialize(opts = {}) ⇒ self
constructor
Initialize bit attribute.
-
#read(str) ⇒ self
Populate bit attribute from
str
. -
#to_i ⇒ Integer
(also: #to_human)
Give integer associated to this attribute.
-
#to_s ⇒ ::String
Return binary string.
-
#type_name ⇒ ::String
Get type name.
Methods included from Structable
Constructor Details
#initialize(opts = {}) ⇒ self
Initialize bit attribute
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/bin_struct/bit_attr.rb', line 94 def initialize(opts = {}) parameters = self.class.parameters raise NotImplementedError, "#initialize may only be called on subclass of #{self.class}" if parameters.nil? @width = parameters.width @fields = parameters.fields @int = parameters.int.dup @data = {} @bit_methods = [] parameters.fields.each do |name, size| @data[name] = opts[name] || 0 define_methods(name, size) end @bit_methods.freeze end |
Class Attribute Details
.parameters ⇒ Parameters (readonly)
46 47 48 |
# File 'lib/bin_struct/bit_attr.rb', line 46 def parameters @parameters end |
Instance Attribute Details
#bit_methods ⇒ ::Array[Symbol] (readonly)
36 37 38 |
# File 'lib/bin_struct/bit_attr.rb', line 36 def bit_methods @bit_methods end |
#width ⇒ Integer (readonly)
Returns width in bits of bit attribute.
34 35 36 |
# File 'lib/bin_struct/bit_attr.rb', line 34 def width @width end |
Class Method Details
.create(width:, endian: :big, **fields) ⇒ Class
Create a new BinStruct::BitAttr subclass with specified parameters
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/bin_struct/bit_attr.rb', line 57 def create(width:, endian: :big, **fields) raise ArgumentError, 'with must be 8, 16, 24, 32 or 64' unless [8, 16, 24, 32, 64].include?(width) hsh = compute_hash(width, endian, fields) cached = cache[hsh] return cached if cached total_size = fields.reduce(0) { |acc, ary| acc + ary.last } raise ArgumentError, "sum of bitfield sizes is not equal to #{width}" unless total_size == width cache[hsh] = Class.new(self) do int_klass = BinStruct.const_get("Int#{width}") @parameters = Parameters.new(width, fields, int_klass.new(endian: endian)).freeze end end |
Instance Method Details
#format_inspect ⇒ Object
161 162 163 164 |
# File 'lib/bin_struct/bit_attr.rb', line 161 def format_inspect str = @int.format_inspect << "\n" str << @data.map { |name, value| "#{name}:#{value}" }.join(' ') end |
#from_human(value) ⇒ self
Set fields from associated integer
157 158 159 |
# File 'lib/bin_struct/bit_attr.rb', line 157 def from_human(value) compute_data(value.to_i) end |
#read(str) ⇒ self
Populate bit attribute from str
127 128 129 130 131 132 |
# File 'lib/bin_struct/bit_attr.rb', line 127 def read(str) return self if str.nil? @int.read(str) compute_data(@int.to_i) end |
#to_i ⇒ Integer Also known as: to_human
Give integer associated to this attribute
136 137 138 139 140 141 142 143 144 |
# File 'lib/bin_struct/bit_attr.rb', line 136 def to_i v = 0 @fields.each do |name, size| v <<= size v |= @data[name] end v end |
#to_s ⇒ ::String
Return binary string
149 150 151 152 |
# File 'lib/bin_struct/bit_attr.rb', line 149 def to_s @int.value = to_i @int.to_s end |
#type_name ⇒ ::String
Get type name
113 114 115 116 117 118 119 120 121 122 |
# File 'lib/bin_struct/bit_attr.rb', line 113 def type_name return @type_name if defined? @type_name endian_suffix = case @int.endian when :big then '' when :little then 'le' when :native then 'n' end @type_name = "BitAttr#{@width}#{endian_suffix}" end |