Module: GPS_PVT::PER::Basic_Unaligned::Decoder

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

Class Method Summary collapse

Class Method Details

.constrainted_whole_number(str, v_range) ⇒ Object

10.5.6



119
120
121
# File 'lib/gps_pvt/asn1/per.rb', line 119

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

.constrainted_whole_number2(str, v_min, v_max) ⇒ Object

10.5.6



114
115
116
117
118
# File 'lib/gps_pvt/asn1/per.rb', line 114

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

.length_constrained_whole_number(str, len_range) ⇒ Object



142
143
144
145
146
147
148
149
150
# File 'lib/gps_pvt/asn1/per.rb', line 142

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

.length_normally_small_length(str) ⇒ Object

10.9.4.2 -> 10.9.3.4



151
152
153
154
155
156
# File 'lib/gps_pvt/asn1/per.rb', line 151

def length_normally_small_length(str) # 10.9.4.2 -> 10.9.3.4
  case str.slice!(0)
  when '0'; str.slice!(0, 6).to_i(2) + 1
  when '1'; length_otherwise(str)
  end
end

.length_otherwise(str) ⇒ Object

10.9.4.2 -> 10.9.3.5-8



157
158
159
160
161
162
163
164
165
166
# File 'lib/gps_pvt/asn1/per.rb', line 157

def length_otherwise(str) # 10.9.4.2 -> 10.9.3.5-8
  case str.slice!(0)
  when '0'; non_negative_binary_integer(str, 7) # 10.9.3.6
  when '1';
    case str.slice!(0)
    when '0'; non_negative_binary_integer(str, 14) # 10.9.3.7
    when '1'; [non_negative_binary_integer(str, 6) * (1 << 14), true] # 10.9.3.8
    end
  end
end

.non_negative_binary_integer(str, bits) ⇒ Object

10.3



104
105
106
# File 'lib/gps_pvt/asn1/per.rb', line 104

def non_negative_binary_integer(str, bits) # 10.3
  str.slice!(0, bits).to_i(2)
end

.normally_small_non_negative_whole_number(str, *len_dec) ⇒ Object

10.6



122
123
124
125
126
127
# File 'lib/gps_pvt/asn1/per.rb', line 122

def normally_small_non_negative_whole_number(str, *len_dec) # 10.6
  case str.slice!(0)
  when '0'; str.slice!(0, 6).to_i(2) # 10.6.1
  when '1'; semi_constrained_whole_number(str, 0, *len_dec) # 10.6.2
  end
end

.semi_constrained_whole_number(str, v_min, *len_dec) ⇒ Object

10.7



128
129
130
131
132
133
134
# File 'lib/gps_pvt/asn1/per.rb', line 128

def semi_constrained_whole_number(str, v_min, *len_dec) # 10.7
  len_dec = :length_otherwise if len_dec.empty?
  v_str = with_length(str, *len_dec).collect{|len_oct|
    str.slice!(0, len_oct * 8)
  }.join
  non_negative_binary_integer(v_str, v_str.size) + v_min
end

.twos_complement_binary_integer(str, bits) ⇒ Object

10.4



107
108
109
110
111
112
113
# File 'lib/gps_pvt/asn1/per.rb', line 107

def twos_complement_binary_integer(str, bits) # 10.4
  bits -= 1
  case str.slice!(0)
  when '0'; 0 
  when '1'; -(1 << bits) 
  end + non_negative_binary_integer(str, bits)
end

.unconstrained_whole_number(str, *len_dec) ⇒ Object

10.8



135
136
137
138
139
140
141
# File 'lib/gps_pvt/asn1/per.rb', line 135

def unconstrained_whole_number(str, *len_dec) # 10.8
  len_dec = :length_otherwise if len_dec.empty?
  v_str = with_length(str, *len_dec).collect{|len_oct|
    str.slice!(0, len_oct * 8)
  }.join
  twos_complement_binary_integer(v_str, v_str.size)
end

.with_length(str, *len_dec) ⇒ Object



167
168
169
170
171
172
173
174
175
176
# File 'lib/gps_pvt/asn1/per.rb', line 167

def with_length(str, *len_dec)
  Enumerator::new{|y|
    len, cnt = len_dec[0].kind_of?(Symbol) ? send(len_dec[0], str, *len_dec[1..-1]) : len_dec
    loop{
      y << len
      break unless cnt
      len, cnt = length_otherwise(str) # fragmentation
    }
  }
end