aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1kit/types/real.rb
blob: 3b2a108ed3cd217a37a4c6fd7f22486be0a1ac39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# coding: ASCII-8BIT

class ASN1Kit::Real < ASN1Kit::Type
  asn1_tag :IMPLICIT, :UNIVERSAL, 9
  asn1_alias "REAL"

  PLUS_INFINITY = :plus_infinity
  MINUS_INFINITY = :minus_infinity
  NOT_A_NUMBER = :not_a_number
  MINUS_ZERO = :minus_zero

  SPECIAL_VALUES = Set[
    PLUS_INFINITY, MINUS_INFINITY, NOT_A_NUMBER, MINUS_ZERO
  ]
  private_constant :SPECIAL_VALUES

  def initialize(value)
    case value
    when PLUS_INFINITY, MINUS_INFINITY, NOT_A_NUMBER, MINUS_ZERO
      @value = value
    when Integer
      # TODO: Consider constraints
      @value = { mantissa: value, base: 10, exponent: 0 }
    when Float, Rational
      raise NotImplementedError
    else
      # Assuming value is a { mantissa: M, base: B, exponent: E } value
      @value = value
    end
  end

  def cast_to(type)
    return type.new(@value) if type <= ASN1Kit::Real
    super
  end

  def plus_infinity?() @value == PLUS_INFINITY end
  def minus_infinity?() @value == MINUS_INFINITY end
  def not_a_number?() @value == NOT_A_NUMBER end
  def minus_zero?() @value == MINUS_ZERO end
  def raw_value() @value end

  def ==(other)
    other.is_a?(ASN1Kit::Real) && @value == other.raw_value
  end
end