Class: BinStruct::AbstractTLV Abstract
- Includes:
- Structable
- Defined in:
- lib/bin_struct/abstract_tlv.rb
Overview
Base class to define type-length-value data.
You have to define a concrete class from AbstractTLV
MyTLV = BinStruct::AbstractTLV.create
MyTLV.define_type_enum 'one' => 1, 'two' => 2
This will define a new MyTLV class, subclass of AbstractTLV. This class will define 3 attributes:
.define_type_enum is, here, necessary to define enum hash to be used for #type accessor, as this one is defined as an Enum.
Constant Summary collapse
- ATTR_TYPES =
{ 'T' => :type, 'L' => :length, 'V' => :value }.freeze
Constants inherited from Struct
Class Attribute Summary collapse
-
.aliases ⇒ Hash
Aliases defined in AbstractTLV.create.
- .attr_in_length ⇒ Object
-
.length ⇒ Integer
abstract
Length attribute for real TLV class.
-
.type ⇒ Integer
abstract
Type attribute for real TLV class.
-
.value ⇒ Object
abstract
Value attribute for real TLV class.
Instance Attribute Summary collapse
-
#length ⇒ Integer
abstract
Length attribute.
-
#type ⇒ Integer
abstract
Type attribute.
-
#value ⇒ Object
abstract
Value attribute.
Class Method Summary collapse
-
.create(type_class: Int8Enum, length_class: Int8, value_class: String, aliases: {}, attr_order: 'TLV', attr_in_length: 'V') ⇒ Class
Generate a TLV class.
-
.define_type_default(default) ⇒ void
abstract
Set default value for #type attribute.
-
.define_type_enum(hsh) ⇒ void
abstract
Set enum hash for #type attribute.
-
.derive(type_class: nil, length_class: nil, value_class: nil, aliases: {}) ⇒ Class
Derive a new TLV class from an existing one.
-
.inherited(klass) ⇒ void
On inheritage, copy aliases and attr_in_length.
Instance Method Summary collapse
-
#calc_length ⇒ Integer
Calculate length.
-
#human_type ⇒ ::String
abstract
Get human-readable type.
-
#initialize(options = {}) ⇒ AbstractTLV
constructor
abstract
Return a new instance of a real TLV class.
-
#read(str) ⇒ AbstractTLV
abstract
Populate object from a binary string.
- #to_human ⇒ ::String abstract
Methods included from Structable
#format_inspect, #sz, #to_s, #type_name
Methods inherited from Struct
#[], #[]=, #attribute?, #attributes, attributes, #bits_on, define_attr, define_attr_after, define_attr_before, define_bit_attr, define_bit_attr_after, define_bit_attr_before, #inspect, #offset_of, #optional?, #optional_attributes, #present?, remove_attr, #sz, #to_h, #to_s, update_attr
Constructor Details
#initialize(options = {}) ⇒ AbstractTLV
Should only be called on real TLV classes, created by create.
Return a new instance of a real TLV class.
270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/bin_struct/abstract_tlv.rb', line 270 def initialize( = {}) @attr_in_length = self.class.attr_in_length self.class.aliases.each do |al, orig| [orig] = [al] if .key?(al) end super # used #value= defined below, which set length if needed self.value = [:value] if [:value] calc_length unless .key?(:length) end |
Class Attribute Details
.aliases ⇒ Hash
Aliases defined in create
70 71 72 |
# File 'lib/bin_struct/abstract_tlv.rb', line 70 def aliases @aliases end |
.attr_in_length ⇒ Object
72 73 74 |
# File 'lib/bin_struct/abstract_tlv.rb', line 72 def attr_in_length @attr_in_length end |
.length ⇒ Integer
Length attribute for real TLV class
|
|
# File 'lib/bin_struct/abstract_tlv.rb', line 157
|
.type ⇒ Integer
Type attribute for real TLV class
|
|
# File 'lib/bin_struct/abstract_tlv.rb', line 157
|
.value ⇒ Object
Value attribute for real TLV class
|
|
# File 'lib/bin_struct/abstract_tlv.rb', line 157
|
Instance Attribute Details
#length ⇒ Integer
Length attribute
|
|
# File 'lib/bin_struct/abstract_tlv.rb', line 251
|
#type ⇒ Integer
Type attribute
|
|
# File 'lib/bin_struct/abstract_tlv.rb', line 251
|
#value ⇒ Object
Value attribute
|
|
# File 'lib/bin_struct/abstract_tlv.rb', line 251
|
Class Method Details
.create(type_class: Int8Enum, length_class: Int8, value_class: String, aliases: {}, attr_order: 'TLV', attr_in_length: 'V') ⇒ Class
Generate a TLV class
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/bin_struct/abstract_tlv.rb', line 86 def create(type_class: Int8Enum, length_class: Int8, value_class: String, aliases: {}, attr_order: 'TLV', attr_in_length: 'V') unless equal?(AbstractTLV) raise Error, '.create cannot be called on a subclass of BinStruct::AbstractTLV' end klass = Class.new(self) klass.aliases = aliases klass.attr_in_length = attr_in_length check_attr_in_length(attr_in_length) check_attr_order(attr_order) generate_attributes(klass, attr_order, type_class, length_class, value_class) generate_aliases_for(klass, aliases) aliases.each do |al, orig| klass.instance_eval do alias_method al, orig if klass.method_defined?(orig) alias_method :"#{al}=", :"#{orig}=" if klass.method_defined?(:"#{orig}=") end end klass end |
.define_type_default(default) ⇒ void
183 184 185 |
# File 'lib/bin_struct/abstract_tlv.rb', line 183 def define_type_default(default) attr_defs[:type][:default] = default end |
.define_type_enum(hsh) ⇒ void
174 175 176 177 |
# File 'lib/bin_struct/abstract_tlv.rb', line 174 def define_type_enum(hsh) attr_defs[:type][:options][:enum].clear attr_defs[:type][:options][:enum].merge!(hsh) end |
.derive(type_class: nil, length_class: nil, value_class: nil, aliases: {}) ⇒ Class
Derive a new TLV class from an existing one
143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/bin_struct/abstract_tlv.rb', line 143 def derive(type_class: nil, length_class: nil, value_class: nil, aliases: {}) raise Error, ".derive cannot be called on #{name}" if equal?(AbstractTLV) klass = Class.new(self) klass.aliases.merge!(aliases) generate_aliases_for(klass, aliases) klass.attr_defs[:type].type = type_class unless type_class.nil? klass.attr_defs[:length].type = length_class unless length_class.nil? klass.attr_defs[:value].type = value_class unless value_class.nil? klass end |
.inherited(klass) ⇒ void
This method returns an undefined value.
On inheritage, copy aliases and attr_in_length
117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/bin_struct/abstract_tlv.rb', line 117 def inherited(klass) super aliases = @aliases.clone attr_in_length = @attr_in_length.clone klass.class_eval do @aliases = aliases @attr_in_length = attr_in_length end end |
Instance Method Details
#calc_length ⇒ Integer
Calculate length
332 333 334 335 336 337 338 339 340 |
# File 'lib/bin_struct/abstract_tlv.rb', line 332 def calc_length ail = @attr_in_length length = 0 ail.each_char do |attr_type| length += self[ATTR_TYPES[attr_type]].sz end self.length = length end |
#human_type ⇒ ::String
Should only be called on real TLV class instances.
Get human-readable type
319 320 321 |
# File 'lib/bin_struct/abstract_tlv.rb', line 319 def human_type self[:type].to_human.to_s end |
#read(str) ⇒ AbstractTLV
Should only be called on real TLV class instances.
Populate object from a binary string
286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
# File 'lib/bin_struct/abstract_tlv.rb', line 286 def read(str) return self if str.nil? idx = 0 str = str.b attributes.each do |attr_name| attr = self[attr_name] length = attr_name == :value ? real_length : attr.sz attr.read(str[idx, length]) idx += attr.sz end self end |
#to_human ⇒ ::String
Should only be called on real TLV class instances.
325 326 327 328 |
# File 'lib/bin_struct/abstract_tlv.rb', line 325 def to_human my_value = self[:value].is_a?(String) ? self[:value].inspect : self[:value].to_human 'type:%s,length:%u,value:%s' % [human_type, length, my_value] end |