proc{
unum_gen = proc{|n, sf|
next [n, proc{|v| v}] unless sf
[n, sf.kind_of?(Rational) ? proc{|v| (sf * v).to_f} : proc{|v| sf * v}]
}
num_gen = proc{|n, sf|
lim = 1 << (n - 1)
lim2 = lim << 1
next [n, proc{|v| v >= lim ? v - lim2 : v}] unless sf
[n, sf.kind_of?(Rational) ?
proc{|v| v -= lim2 if v >= lim; (sf * v).to_f} :
proc{|v| v -= lim2 if v >= lim; sf * v}]
}
num_sign_gen = proc{|n, sf|
lim = 1 << (n - 1)
next [n, proc{|v| v >= lim ? lim - v : v}] unless sf
[n, sf.kind_of?(Rational) ?
proc{|v| v = lim - v if v >= lim; (sf * v).to_f} :
proc{|v| v = lim - v if v >= lim; sf * v}]
}
invalidate = proc{|orig, err|
[orig[0], proc{|v| v == err ? nil : orig[1].call(v)}]
}
idx_list_gen = proc{|n, start|
start ||= 0
idx_list = (start...(start+n)).to_a.reverse
[n, proc{|v| idx_list.inject([]){|res, idx|
res.unshift(idx) if (v & 0x1) > 0
break res unless (v >>= 1) > 0
res
} }]
}
sc2rad = 3.1415926535898
df = { 1 => proc{|n| n},
2 => 12,
3 => 12,
4 => unum_gen.call(30, Rational(1, 1000)), 5 => 1,
6 => 5,
7 => 1,
8 => 3,
9 => 6,
10 => 1,
11 => invalidate.call(unum_gen.call(24, Rational(2, 100)), 0x800000), 12 => invalidate.call(num_gen.call(20, Rational(5, 10000)), 0x80000), 13 => 7,
14 => unum_gen.call(8, 299_792.458), 15 => invalidate.call(unum_gen.call(8, Rational(1, 4)), 0), 16 => 2,
17 => invalidate.call(num_gen.call(14, Rational(2, 100)), 0x2000), 18 => num_gen.call(20, Rational(5, 10000)), 19 => 7,
20 => invalidate.call(unum_gen.call(8, Rational(1, 4)), 0), 21 => 6,
22 => 1,
23 => 1,
24 => 1,
25 => num_gen.call(38, Rational(1, 10000)), 34 => unum_gen.call(27, Rational(1, 1000)), 35 => 5,
36 => 1,
37 => 3,
38 => 6,
39 => 1,
40 => [5, proc{|v| v - 7}],
41 => invalidate.call(unum_gen.call(25, Rational(2, 100)), 0x1000000), 42 => invalidate.call(num_gen.call(20, Rational(5, 10000)), 0x80000), 43 => 7,
44 => unum_gen.call(7, 599_584.916), 45 => invalidate.call(unum_gen.call(8, Rational(1, 4)), 0), 46 => 2,
47 => invalidate.call(num_gen.call(14, Rational(2, 100)), 0x2000), 48 => invalidate.call(num_gen.call(20, Rational(5, 10000)), 0x80000), 49 => 7,
50 => invalidate.call(unum_gen.call(8, Rational(1, 4)), 0), 51 => 16,
52 => 17,
53 => 5,
54 => 8,
55 => 12,
56 => 1,
57 => 16,
71 => 8,
76 => 10,
77 => 4,
78 => 2,
79 => num_gen.call(14, Rational(sc2rad, 1 << 43)), 81 => unum_gen.call(16, 1 << 4), 82 => num_gen.call(8, Rational(1, 1 << 55)), 83 => num_gen.call(16, Rational(1, 1 << 43)), 84 => num_gen.call(22, Rational(1, 1 << 31)), 85 => 10,
86 => num_gen.call(16, Rational(1, 1 << 5)), 87 => num_gen.call(16, Rational(sc2rad, 1 << 43)), 88 => num_gen.call(32, Rational(sc2rad, 1 << 31)), 89 => num_gen.call(16, Rational(1, 1 << 29)), 90 => unum_gen.call(32, Rational(1, 1 << 33)),
91 => num_gen.call(16, Rational(1, 1 << 29)), 92 => unum_gen.call(32, Rational(1, 1 << 19)), 93 => unum_gen.call(16, 1 << 4), 94 => num_gen.call(16, Rational(1, 1 << 29)), 95 => num_gen.call(32, Rational(sc2rad, 1 << 31)), 96 => num_gen.call(16, Rational(1, 1 << 29)), 97 => num_gen.call(32, Rational(sc2rad, 1 << 31)), 98 => num_gen.call(16, Rational(1, 1 << 5)), 99 => num_gen.call(32, Rational(sc2rad, 1 << 31)), 100 => num_gen.call(24, Rational(sc2rad, 1 << 43)), 101 => num_gen.call(8, Rational(1, 1 << 31)), 102 => 6,
103 => 1,
104 => 1,
105 => 1,
106 => 2,
107 => [12, proc{|v|
hh, mm, ss = [v >> 7, (v & 0x7E) >> 1, (v & 0x1) > 0 ? 30 : 0]
hh * 3600 + mm * 60 + ss }],
108 => 1,
109 => 1,
110 => unum_gen.call(7, 15 * 60), 111 => num_sign_gen.call(24, Rational(1000, 1 << 20)), 112 => num_sign_gen.call(27, Rational(1000, 1 << 11)), 113 => num_sign_gen.call(5, Rational(1000, 1 << 30)), 120 => 1,
121 => num_sign_gen.call(11, Rational(1, 1 << 40)),
122 => 2, 123 => 1, 124 => num_sign_gen.call(22, Rational(1, 1 << 30)), 125 => num_sign_gen.call(5, Rational(1, 1 << 30)), 126 => 5, 127 => 1, 128 => 4, 129 => invalidate.call(unum_gen.call(11), 0), 130 => 2, 131 => 1,
132 => invalidate.call(unum_gen.call(11), 0), 133 => num_sign_gen.call(32, Rational(1, 1 << 31)), 134 => invalidate.call(unum_gen.call(5), 0), 135 => num_sign_gen.call(22, Rational(1, 1 << 30)), 136 => 1, 137 => 1,
141 => 1,
142 => 1,
248 => 30,
364 => 2,
393 => 1,
394 => idx_list_gen.call(64, 1),
395 => idx_list_gen.call(32, 1),
396 => proc{|df394, df395|
x_list = df394.product(df395)
idx_list = idx_list_gen.call(x_list.size)[1]
[x_list.size, proc{|v| x_list.values_at(*idx_list.call(v))}]
},
397 => invalidate.call(unum_gen.call(8, Rational(1, 1000)), 0xFF), 398 => unum_gen.call(10, Rational(1, 1000 << 10)), 399 => invalidate.call(num_gen.call(14), 0x2000), 400 => invalidate.call(num_gen.call(15, Rational(1, 1000 << 24)), 0x4000), 401 => invalidate.call(num_gen.call(22, Rational(1, 1000 << 29)), 0x200000), 402 => 4,
403 => invalidate.call(unum_gen.call(6), 0), 404 => invalidate.call(num_gen.call(15, Rational(1, 10000)), 0x4000), 405 => invalidate.call(num_gen.call(20, Rational(1, 1000 << 29)), 0x80000), 406 => invalidate.call(num_gen.call(24, Rational(1, 1000 << 31)), 0x800000), 407 => 10,
408 => invalidate.call(unum_gen.call(10, Rational(1, 1 << 4)), 0), 409 => 3,
411 => 2,
412 => 2,
416 => 3,
417 => 1,
418 => 3,
420 => 1,
429 => 4,
:uint => proc{|n| n},
}
df[27] = df[26] = df[25]
df[117] = df[114] = df[111]
df[118] = df[115] = df[112]
df[119] = df[116] = df[113]
{430..433 => 81..84, 434 => 71, 435..449 => 86..100, 450 => 79, 451 => 78,
452 => 76, 453 => 77, 454 => 102, 455 => 101, 456 => 85, 457 => 137}.each{|dst, src|
src = (src.to_a rescue [src]).flatten
(dst.to_a rescue ([dst] * src.size)).flatten.zip(src).each{|i, j| df[i] = df[j]}
}
df.merge!({
:SBAS_prn => [6, proc{|v| v + 120}],
:SBAS_iodn => 8,
:SBAS_tod => num_gen.call(13, 1 << 4),
:SBAS_ura => df[77],
:SBAS_xy => num_gen.call(30, Rational(8, 100)),
:SBAS_z => num_gen.call(25, Rational(4, 10)),
:SBAS_dxy => num_gen.call(17, Rational(1, 1600)),
:SBAS_dz => num_gen.call(18, Rational(1, 250)),
:SBAS_ddxy => num_gen.call(10, Rational(1, 80000)),
:SBAS_ddz => num_gen.call(10, Rational(1, 16000)),
:SBAS_agf0 => num_gen.call(12, Rational(1, 1 << 31)),
:SBAS_agf1 => num_gen.call(8, Rational(1, 1 << 40)),
})
df.define_singleton_method(:generate_prop){|idx_list|
hash = Hash[*([:bits, :op].collect.with_index{|k, i|
[k, idx_list.collect{|idx, *args|
case prop = self[idx]
when Proc; prop = prop.call(*args)
end
[prop].flatten(1)[i]
}]
}.flatten(1))].merge({:df => idx_list})
hash[:bits_total] = hash[:bits].inject{|a, b| a + b} || 0
hash
}
df
}.call