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