module PacketGen::Inspect

{Inspect} module provides methods to help writing inspect @api private @author Sylvain Daubert

Constants

FMT_ATTR

Format to inspect attribute

MAX_WIDTH

Maximum number of characters on a line for INSPECT

Public Class Methods

dashed_line(name, level=1) click to toggle source

Create a dashed line with obj class writing in it @param [String] name @param [Integer] level @return [String]

# File lib/packetgen/inspect.rb, line 23
def self.dashed_line(name, level=1)
  str = '--' * level << " #{name} "
  str << '-' * (MAX_WIDTH - str.length) << "\n"
end
enum_human_hex(str, int, hexsize) click to toggle source

@param [String] str @param [Integer] int @param [Integer] hexsize @return [String]

# File lib/packetgen/inspect.rb, line 44
def self.enum_human_hex(str, int, hexsize)
  "%-16s (0x%0#{hexsize}x)" % [str, int]
end
format(type, attr, value, level=1) click to toggle source

Simple formatter to inspect an attribute @param [String] type attribute type @param [String] attr attribute name @param [String] value @param [Integer] level @return [String]

# File lib/packetgen/inspect.rb, line 54
def self.format(type, attr, value, level=1)
  str = Inspect.shift_level(level)
  str << Inspect::FMT_ATTR % [type, attr, value]
end
inspect_asn1_attribute(name, attr, level=1) click to toggle source

Format a ASN.1 attribute for #inspect. 4 cases are handled:

  • attribute value is a =RANS1::Types::Enumerated+: show named value and its integer value as hexdecimal format,

  • attribute value is a RASN1::Types::Integer: show value as integer and in hexdecimal format,

  • attribute value is a RASN1::Model: only show its root type,

  • else, #to_s is used to format attribute value.

@param [Symbol] name attribute name @param [RASN1::Types::Base,RASN1::Model] attr attribute @param [Integer] level @return [String]

# File lib/packetgen/inspect.rb, line 86
def self.inspect_asn1_attribute(name, attr, level=1)
  str = shift_level(level)
  val = case attr
        when RASN1::Types::Enumerated
          hexsize = attr.value_size * 2
          "%-16s (0x%0#{hexsize}x)" % [attr.value, attr.to_i]
        when RASN1::Types::Integer
          int_dec_hex(attr.value, attr.value_size * 2)
        when RASN1::Model
          attr.root.type
        else
          attr.value.to_s.inspect
        end
  str << FMT_ATTR % [attr.type, name, val]
end
inspect_attribute(attr, value, level=1) click to toggle source

Format an attribute for #inspect. 3 cases are handled:

  • attribute value is a {Types::Int}: show value as integer and in hexdecimal format,

  • attribute value responds to #to_human: call it,

  • else, #to_s is used to format attribute value.

@param [Symbol] attr attribute name @param [Object] value attribute value @param [Integer] level @return [String]

# File lib/packetgen/inspect.rb, line 69
def self.inspect_attribute(attr, value, level=1)
  type = value.class.to_s.sub(/.*::/, '')
  self.format(type, attr, value.format_inspect, level)
end
inspect_body(body, name='Body') click to toggle source

@param [#to_s] body @return [String]

# File lib/packetgen/inspect.rb, line 104
def self.inspect_body(body, name='Body')
  return '' if body.nil? || body.empty?

  str = dashed_line(name, 2)
  str << (0..15).to_a.map { |v| ' %02d' % v }.join << "\n"
  str << '-' * MAX_WIDTH << "\n"
  unless body.empty?
    (body.size / 16 + 1).times do |i|
      octets = body.to_s[i * 16, 16].unpack('C*')
      o_str = octets.map { |v| ' %02x' % v }.join
      str << o_str
      str << ' ' * (3 * 16 - o_str.size) unless o_str.size >= 3 * 16
      str << '  ' << octets.map { |v| v < 128 && v > 31 ? v.chr : '.' }.join
      str << "\n"
    end
  end
  str << '-' * MAX_WIDTH << "\n"
end
int_dec_hex(value, hexsize) click to toggle source

@param [#to_i] value @param [Integer] hexsize @return [String]

# File lib/packetgen/inspect.rb, line 36
def self.int_dec_hex(value, hexsize)
  "%-16s (0x%0#{hexsize}x)" % [value.to_i, value.to_i]
end
shift_level(level=1) click to toggle source

@return [String]

# File lib/packetgen/inspect.rb, line 29
def self.shift_level(level=1)
  '  ' * (level + 1)
end