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.
250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/bin_struct/abstract_tlv.rb', line 250 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 155
|
.type ⇒ Integer
Type attribute for real TLV class
|
# File 'lib/bin_struct/abstract_tlv.rb', line 155
|
.value ⇒ Object
Value attribute for real TLV class
|
# File 'lib/bin_struct/abstract_tlv.rb', line 155
|
Instance Attribute Details
#length ⇒ Integer
Length attribute
|
# File 'lib/bin_struct/abstract_tlv.rb', line 231
|
#type ⇒ Integer
Type attribute
|
# File 'lib/bin_struct/abstract_tlv.rb', line 231
|
#value ⇒ Object
Value attribute
|
# File 'lib/bin_struct/abstract_tlv.rb', line 231
|
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
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/bin_struct/abstract_tlv.rb', line 85 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
181 182 183 |
# File 'lib/bin_struct/abstract_tlv.rb', line 181 def define_type_default(default) attr_defs[:type][:default] = default end |
.define_type_enum(hsh) ⇒ void
172 173 174 175 |
# File 'lib/bin_struct/abstract_tlv.rb', line 172 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
141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/bin_struct/abstract_tlv.rb', line 141 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
116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/bin_struct/abstract_tlv.rb', line 116 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
311 312 313 314 315 316 317 318 319 |
# File 'lib/bin_struct/abstract_tlv.rb', line 311 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
298 299 300 |
# File 'lib/bin_struct/abstract_tlv.rb', line 298 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
266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/bin_struct/abstract_tlv.rb', line 266 def read(str) return self if str.nil? idx = 0 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.
304 305 306 307 |
# File 'lib/bin_struct/abstract_tlv.rb', line 304 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 |