Module: GPS_PVT::PER::Basic_Unaligned::Encoder

Defined in:
lib/gps_pvt/asn1/per.rb

Class Method Summary collapse

Class Method Details

.constrainted_whole_number(v, v_range) ⇒ Object

10.5.6



32
33
34
# File 'lib/gps_pvt/asn1/per.rb', line 32

def constrainted_whole_number(v, v_range) # 10.5.6
  constrainted_whole_number2(v, *v_range.minmax)
end

.constrainted_whole_number2(v, v_min, v_max) ⇒ Object

10.5.6



27
28
29
30
31
# File 'lib/gps_pvt/asn1/per.rb', line 27

def constrainted_whole_number2(v, v_min, v_max) # 10.5.6
  non_negative_binary_integer2(
      v - v_min,
      Math::log2(v_max - v_min + 1).ceil)
end

.length_constrained_whole_number(len, len_range) ⇒ Object



56
57
58
59
60
61
62
63
64
# File 'lib/gps_pvt/asn1/per.rb', line 56

def length_constrained_whole_number(len, len_range)
  if len_range.max < 65536 then # 10.9.4.1
    (len_range.min == len_range.max) ?
        "" : 
        constrainted_whole_number(len, len_range)
  else
    length_otherwise(len)
  end
end

.length_normally_small_length(len) ⇒ Object

10.9.4.2 -> 10.9.3.4



65
66
67
68
69
70
71
72
73
# File 'lib/gps_pvt/asn1/per.rb', line 65

def length_normally_small_length(len) # 10.9.4.2 -> 10.9.3.4
  if len <= 64 then
    normally_small_non_negative_whole_number(len - 1)
  else
    len_enc, len_remain = length_otherwise(len)
    len_enc = "1#{len_enc}"
    len_remain ? [len_enc, len_remain] : len_enc
  end
end

.length_otherwise(len) ⇒ Object

10.9.4.2 -> 10.9.3.5-8



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/gps_pvt/asn1/per.rb', line 74

def length_otherwise(len) # 10.9.4.2 -> 10.9.3.5-8
  if len <= 127 then # 10.9.3.6
    non_negative_binary_integer2(len, 8)
  elsif len < 16384 then # 10.9.3.7
    "10#{non_negative_binary_integer2(len, 14)}"
  else # 10.9.3.8
    q, r = len.divmod(16384)
    q2 = [q, 4].min
    res = "11#{non_negative_binary_integer2(q2, 6)}"
    ((r == 0) && (q <= 4)) ? res : [res, len - (q2 * 16384)]
  end
end

.non_negative_binary_integer(v, align = 1) ⇒ Object

10.3



14
15
16
17
# File 'lib/gps_pvt/asn1/per.rb', line 14

def non_negative_binary_integer(v, align = 1) # 10.3
  non_negative_binary_integer2(
      v, (Math::log2(v + 1) / align).ceil * align)
end

.non_negative_binary_integer2(v, bits) ⇒ Object

10.3



11
12
13
# File 'lib/gps_pvt/asn1/per.rb', line 11

def non_negative_binary_integer2(v, bits) # 10.3
  "%0#{bits}b" % v
end

.normally_small_non_negative_whole_number(v, *len_enc) ⇒ Object

10.6



35
36
37
38
39
40
41
# File 'lib/gps_pvt/asn1/per.rb', line 35

def normally_small_non_negative_whole_number(v, *len_enc) # 10.6
  if v <= 63 then
    "0%06b" % v # 10.6.1
  else
    "1#{semi_constrained_whole_number(v, 0, *len_enc)}" # 10.6.2
  end
end

.semi_constrained_whole_number(v, v_min, *len_enc) ⇒ Object

10.7



42
43
44
45
46
47
48
# File 'lib/gps_pvt/asn1/per.rb', line 42

def semi_constrained_whole_number(v, v_min, *len_enc) # 10.7
  len_enc = :length_otherwise if len_enc.empty?
  bf = non_negative_binary_integer(v - v_min, 8).scan(/.{8}/)
  with_length(bf.size, *len_enc).collect{|len_str, range|
    len_str + bf[range].join
  }.join
end

.twos_complement_binary_integer(v) ⇒ Object

10.4



18
19
20
21
22
23
24
25
26
# File 'lib/gps_pvt/asn1/per.rb', line 18

def twos_complement_binary_integer(v) # 10.4
  if v >= 0 then
    bits = ((Math::log2(v + 1) + 1) / 8).ceil * 8
    "%0#{bits}b" % v
  else
    bits = ((Math::log2(-v) + 1) / 8).ceil * 8 - 1
    "1%0#{bits}b" % (v + (1 << bits))
  end
end

.unconstrained_whole_number(v, *len_enc) ⇒ Object

10.8



49
50
51
52
53
54
55
# File 'lib/gps_pvt/asn1/per.rb', line 49

def unconstrained_whole_number(v, *len_enc) # 10.8
  len_enc = :length_otherwise if len_enc.empty?
  bf = twos_complement_binary_integer(v).scan(/.{8}/)
  with_length(bf.size, *len_enc).collect{|len_str, range|
    len_str + bf[range].join
  }.join
end

.with_length(len, *len_enc) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/gps_pvt/asn1/per.rb', line 86

def with_length(len, *len_enc)
  Enumerator::new{|y|
    len_str, len_remain = len_enc[0].kind_of?(Symbol) ? send(len_enc[0], len, *len_enc[1..-1]) : len_enc
    loop{
      if len_remain then
        y << [len_str, -len..-(len_remain+1)]
      else
        y << [len_str, -len..-1]
        break
      end
      len_str, len_remain = length_otherwise(len = len_remain) # fragmentation
    }
  }
end