class RASN1::Types::Choice

A ASN.1 CHOICE is a choice between different types.

Create a CHOICE

A CHOICE is defined this way:

choice = Choice.new
choice.value = [Integer.new(implicit: 0, class: :context),
                Integer.new(implicit: 1, class: :context),
                OctetString.new(implicit: 2, class: :context)]

The chosen type may be set this way:

choice.chosen = 0   # choose :int1

The chosen value may be set these ways:

choise.value[choice.chosen].value = 1
choise.set_chosen_value 1

The chosen value may be got these ways:

choise.value[choice.chosen].value # => 1
choice.chosen_value               # => 1

Encode a CHOICE

{#to_der} only encodes the chosen value:

choise.to_der   # => "\x80\x01\x01"

Parse a CHOICE

Parsing a CHOICE set {#chosen} and set value to chosen type. If parsed string does not contain a type from CHOICE, a {RASN1::ASN1Error} is raised.

str = "\x04\x03abc"
choice.parse! str
choice.chosen        # => 2
choice.chosen_value  # => "abc"

@author Sylvain Daubert

Attributes

chosen[RW]

Chosen type @return [Integer] index of type in choice value

Public Instance Methods

chosen_value() click to toggle source

Get chosen value @note {#chosen} MUST be set before calling this method @return [Object] value @raise [ChoiceError] {#chosen} not set

# File lib/rasn1/types/choice.rb, line 53
def chosen_value
  check_chosen
  case @value[@chosen]
  when Base
    @value[@chosen].value
  when Model
    @value[@chosen]
  end
end
inspect(level=0) click to toggle source
# File lib/rasn1/types/choice.rb, line 93
def inspect(level=0)
  str = common_inspect(level)
  str << if !defined? @chosen
           ' not chosen!'
         else
           "\n#{@value[@chosen].inspect(level + 1)}"
         end
end
parse!(der, ber: false) click to toggle source

Parse a DER string. This method updates object by setting {#chosen} and chosen value. @param [String] der DER string @param [Boolean] ber if true, accept BER encoding @return [Integer] total number of parsed bytes @raise [ASN1Error] error on parsing

# File lib/rasn1/types/choice.rb, line 77
def parse!(der, ber: false)
  parsed = false
  @value.each_with_index do |element, i|
    begin
      @chosen = i
      nb_bytes = element.parse!(der, ber: ber)
      parsed = true
      return nb_bytes
    rescue ASN1Error
      @chosen = nil
      next
    end
  end
  raise ASN1Error, "CHOICE #{@name}: no type matching #{der.inspect}" unless parsed
end
set_chosen_value(value) click to toggle source

Set chosen value. @note {#chosen} MUST be set before calling this method @param [Object] value @return [Object] value @raise [ChoiceError] {#chosen} not set

# File lib/rasn1/types/choice.rb, line 44
def set_chosen_value(value)
  check_chosen
  @value[@chosen].value = value
end
to_der() click to toggle source

@note {#chosen} MUST be set before calling this method @return [String] DER-formated string @raise [ChoiceError] {#chosen} not set

# File lib/rasn1/types/choice.rb, line 66
def to_der
  check_chosen
  @value[@chosen].to_der
end

Private Instance Methods

check_chosen() click to toggle source
# File lib/rasn1/types/choice.rb, line 104
def check_chosen
  raise ChoiceError if !defined?(@chosen) || @chosen.nil?
end