Class: RASN1::Types::Choice

Inherits:
Base
  • Object
show all
Defined in:
lib/rasn1/types/choice.rb,
lib/rasn1/tracer.rb

Overview

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 ASN1Error is raised.

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

Author:

  • Sylvain Daubert

Constant Summary

Constants inherited from Base

Base::CLASSES, Base::CLASS_MASK, Base::INDEFINITE_LENGTH, Base::MULTI_OCTETS_ID

Instance Attribute Summary collapse

Attributes inherited from Base

#asn1_class, #default, #name, #options

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#==, #can_build?, constrained?, #constructed?, #do_parse_explicit_with_tracing, #do_parse_with_tracing, encoded_type, #explicit?, #id, #implicit?, #initialize, #initialize_copy, #optional?, parse, #primitive?, #specific_initializer, #tagged?, #type, type, #value, #value=, #value?, #value_size, #void_value

Constructor Details

This class inherits a constructor from RASN1::Types::Base

Instance Attribute Details

#chosenInteger

Chosen type

Returns:

  • (Integer)

    index of type in choice value



37
38
39
# File 'lib/rasn1/types/choice.rb', line 37

def chosen
  @chosen
end

Class Method Details

.start_tracingObject

Patch #parse! to add tracing ability



103
104
105
106
# File 'lib/rasn1/tracer.rb', line 103

def start_tracing
  alias_method :parse_without_tracing, :parse!
  alias_method :parse!, :parse_with_tracing
end

.stop_tracingObject

Unpatch #parse! to remove tracing ability



110
111
112
# File 'lib/rasn1/tracer.rb', line 110

def stop_tracing
  alias_method :parse!, :parse_without_tracing
end

Instance Method Details

#chosen_valueObject

Note:

#chosen MUST be set before calling this method

Get chosen value

Returns:

  • (Object)

    value

Raises:



53
54
55
56
57
58
59
60
61
# 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) ⇒ String

Parameters:

  • level (::Integer) (defaults to: 0)

Returns:

  • (String)


96
97
98
99
100
101
102
103
# File 'lib/rasn1/types/choice.rb', line 96

def inspect(level=0)
  str = common_inspect(level)
  str << if defined?(@chosen) && value?
           "\n#{@value[@chosen].inspect(level + 1)}"
         else
           ' not chosen!'
         end
end

#parse!(der, ber: false) ⇒ Integer

Parse a DER string. This method updates object by setting #chosen and chosen value.

Parameters:

  • der (String)

    DER string

  • ber (Boolean) (defaults to: false)

    if true, accept BER encoding

Returns:

  • (Integer)

    total number of parsed bytes

Raises:



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/rasn1/types/choice.rb', line 77

def parse!(der, ber: false)
  @value.each_with_index do |element, i|
    @chosen = i
    nb_bytes = element.parse!(der, ber: ber)
    return nb_bytes
  rescue ASN1Error
    @chosen = nil
    next
  end

  @no_value = true
  @value = void_value
  raise ASN1Error, "CHOICE #{@name}: no type matching #{der.inspect}" unless optional?

  0
end

#parse_with_tracing(der, ber: false) ⇒ Object

Parse der with tracing abillity

See Also:



118
119
120
121
# File 'lib/rasn1/tracer.rb', line 118

def parse_with_tracing(der, ber: false)
  RASN1.tracer.trace(self.trace)
  parse_without_tracing(der, ber: ber)
end

#set_chosen_value(value) ⇒ Object

Note:

#chosen MUST be set before calling this method

Set chosen value.

Parameters:

  • value (Object)

Returns:

  • (Object)

    value

Raises:



44
45
46
47
# File 'lib/rasn1/types/choice.rb', line 44

def set_chosen_value(value) # rubocop:disable Naming/AccessorMethodName
  check_chosen
  @value[@chosen].value = value
end

#to_derString

Note:

#chosen MUST be set before calling this method

Returns DER-formated string.

Returns:

  • (String)

    DER-formated string

Raises:



66
67
68
69
# File 'lib/rasn1/types/choice.rb', line 66

def to_der
  check_chosen
  @value[@chosen].to_der
end

#traceString

Returns:

  • (String)


107
108
109
# File 'lib/rasn1/types/choice.rb', line 107

def trace
  msg_type(no_id: true)
end