class GrizzlyBerElement

Attributes

tag[R]
value[R]

Public Class Methods

new(byte_array = []) click to toggle source
# File lib/grizzly_ber.rb, line 6
def initialize(byte_array = [])
  raise ArgumentError, "byte_array must be of type Array" unless byte_array.is_a?(Array)
  @tag = "" # is an uppercase hex string
  @value = nil # is a byte array if this is a data element or a GrizzlyBer if it's a sequence element
  decode_value decode_length decode_tag byte_array
end

Public Instance Methods

tag=(tag) click to toggle source
# File lib/grizzly_ber.rb, line 13
def tag=(tag)
  raise ArgumentError, "tag must be a valid hex string" unless tag.is_a? String and tag.size.even? and tag =~ /^[0-9A-F]*$/
  raise ArgumentError, "tag #{tag} must be a valid BER tag" unless tag_is_valid? tag
  @tag = tag
end
to_ber() click to toggle source
# File lib/grizzly_ber.rb, line 24
def to_ber
  ber_array = ""
  ber_array += @tag.upcase
  value_hex_string = @value.pack("C*").unpack("H*").first.upcase if @value.is_a? Array
  value_hex_string = @value.to_ber if @value.is_a? GrizzlyBer
  value_byte_count = value_hex_string.size/2
  if value_byte_count < 0x7F # if the length of the value array is only one byte long and does not have its upper bit set
    ber_array << byte_to_hex(value_byte_count)
  else
    #pack("w") was meant to do this length calc but doesn't work right...
    number_of_bytes_in_byte_count = ((value_byte_count).to_s(16).size/2.0).ceil
    ber_array << byte_to_hex(number_of_bytes_in_byte_count | 0x80)
    ber_array += (value_byte_count).to_s(16).rjust(number_of_bytes_in_byte_count*2,'0').upcase
  end
  ber_array += value_hex_string
end
value=(value) click to toggle source
# File lib/grizzly_ber.rb, line 19
def value=(value)
  raise ArgumentError, "value must be of type Array or GrizzlyBer" unless value.is_a?(Array) || value.is_a?(GrizzlyBer)
  @value = value 
end

Private Instance Methods

byte_to_hex(byte) click to toggle source
# File lib/grizzly_ber.rb, line 58
def byte_to_hex(byte)
  byte.to_s(16).rjust(2,'0').upcase
end
decode_length(byte_array) click to toggle source
# File lib/grizzly_ber.rb, line 79
def decode_length(byte_array)
  return [] if byte_array.size < 1

  first_byte = byte_array.shift
  if (first_byte & 0x80) == 0x80
    decoded_length_of_length = first_byte & 0x7F

    return [] if byte_array.size < decoded_length_of_length
    @length = 0
    decoded_length_of_length.times { @length = (@length << 8) | byte_array.shift }
  else
    @length = first_byte
  end

  byte_array
end
decode_tag(byte_array) click to toggle source
# File lib/grizzly_ber.rb, line 62
def decode_tag(byte_array)
  return [] if byte_array.size < 1

  first_byte = byte_array.shift
  @tag << byte_to_hex(first_byte)
  return byte_array if (first_byte & 0x1F) != 0x1F

  while byte_array.size > 0
    next_byte = byte_array.shift
    @tag << byte_to_hex(next_byte)
    return byte_array if (next_byte & 0x80) != 0x80
  end

  @tag = nil
  []
end
decode_value(byte_array) click to toggle source
# File lib/grizzly_ber.rb, line 96
def decode_value(byte_array)
  return [] if byte_array.size < 1 or byte_array.size < @length
  return @value = byte_array.shift(@length) if [@tag].pack("H*").unpack("C*").first & 0x20 == 0
  @value = GrizzlyBer.new.from_ber byte_array.shift(@length)
end
tag_is_valid?(tag_string) click to toggle source
# File lib/grizzly_ber.rb, line 43
def tag_is_valid?(tag_string)
  tag_byte_array = [tag_string].pack("H*").unpack("C*")
  return false if tag_byte_array.size < 1

  first_byte = tag_byte_array.shift
  return false if tag_byte_array.size == 0 and (first_byte & 0x1F) == 0x1F
  return false if tag_byte_array.size > 0  and (first_byte & 0x1F) != 0x1F

  last_byte = tag_byte_array.pop || 0x00
  return false if (last_byte & 0x80) != 0x00

  tag_byte_array.each {|byte| return false if (byte & 0x80) != 0x80 }
  true
end