blob: 94f8280a31a008727b1c50841afcd5fff4fbd932 [file] [log] [blame]
Lev Walkinae1422b2013-03-24 02:08:42 -07001#include <stdio.h>
2#include <assert.h>
3
Lev Walkinae1422b2013-03-24 02:08:42 -07004#include <INTEGER.h>
5#include <INTEGER.c>
6#include <per_support.c>
7#include <per_support.h>
8
9static int FailOut(const void *data, size_t size, void *op_key) {
10 assert(!"UNREACHABLE");
11 return 0;
12}
13
14static void normalize(asn_per_outp_t *po) {
15 if(po->nboff >= 8) {
16 po->buffer += (po->nboff >> 3);
17 po->nbits -= (po->nboff & ~0x07);
18 po->nboff &= 0x07;
19 }
20}
21
22static void
23check_per_encode_constrained(int lineno, int unsigned_, long value, long lbound, unsigned long ubound, int bit_range) {
24 INTEGER_t st;
25 INTEGER_t *reconstructed_st = 0;
26 asn_INTEGER_specifics_t specs;
27 asn_per_constraints_t cts;
28 asn_enc_rval_t enc_rval;
29 asn_dec_rval_t dec_rval;
30 asn_per_outp_t po;
31 asn_per_data_t pd;
Lev Walkinae1422b2013-03-24 02:08:42 -070032
Lev Walkin20a01f92013-03-28 00:22:08 -070033 if(unsigned_)
34 printf("%d: Recoding %s %lu [%ld..%lu]\n", lineno,
35 unsigned_ ? "unsigned" : "signed", value, lbound, ubound);
36 else
37 printf("%d: Recoding %s %ld [%ld..%lu]\n", lineno,
38 unsigned_ ? "unsigned" : "signed", value, lbound, ubound);
Lev Walkinae1422b2013-03-24 02:08:42 -070039
40 memset(&st, 0, sizeof(st));
41 memset(&po, 0, sizeof(po));
42 memset(&pd, 0, sizeof(pd));
43 memset(&cts, 0, sizeof(cts));
44 memset(&specs, 0, sizeof(specs));
45
46 cts.value.flags = APC_CONSTRAINED;
47 cts.value.range_bits = bit_range;
48 cts.value.effective_bits = bit_range;
49 cts.value.lower_bound = lbound;
50 cts.value.upper_bound = ubound;
51
Lev Walkin20a01f92013-03-28 00:22:08 -070052 if(unsigned_)
53 asn_ulong2INTEGER(&st, (unsigned long)value);
54 else
55 asn_long2INTEGER(&st, value);
Lev Walkinae1422b2013-03-24 02:08:42 -070056
57 po.buffer = po.tmpspace;
58 po.nboff = 0;
59 po.nbits = 8 * sizeof(po.tmpspace);
60 po.outper = FailOut;
61
62 specs.field_width = sizeof(long);
63 specs.field_unsigned = unsigned_;
64
65 asn_DEF_INTEGER.specifics = &specs;
66 enc_rval = INTEGER_encode_uper(&asn_DEF_INTEGER, &cts, &st, &po);
67 assert(enc_rval.encoded == 0);
68
69 normalize(&po);
70
71 assert(po.buffer == &po.tmpspace[bit_range / 8]);
Lev Walkin20a01f92013-03-28 00:22:08 -070072
73 if(unsigned_) {
74 unsigned long recovered_value =
75 ((uint32_t)po.tmpspace[0] << 24)
76 | ((uint32_t)po.tmpspace[1] << 16)
77 | ((uint32_t)po.tmpspace[2] << 8)
78 | ((uint32_t)po.tmpspace[3] << 0);
79 recovered_value >>= (32 - bit_range);
80 recovered_value += cts.value.lower_bound;
81 assert(recovered_value == (unsigned long)value);
82 } else {
83 long recovered_value =
84 ((uint32_t)po.tmpspace[0] << 24)
85 | ((uint32_t)po.tmpspace[1] << 16)
86 | ((uint32_t)po.tmpspace[2] << 8)
87 | ((uint32_t)po.tmpspace[3] << 0);
88 recovered_value = (unsigned long)recovered_value >> (32 - bit_range);
89 recovered_value += cts.value.lower_bound;
90 assert((long)recovered_value == value);
91 }
Lev Walkinae1422b2013-03-24 02:08:42 -070092 assert(po.nboff == ((bit_range == 32) ? 0 : (8 - (32 - bit_range))));
93 assert(po.nbits == 8 * (sizeof(po.tmpspace) - (po.buffer-po.tmpspace)));
94 assert(po.flushed_bytes == 0);
95
96 pd.buffer = po.tmpspace;
97 pd.nboff = 0;
98 pd.nbits = 8 * (po.buffer - po.tmpspace) + po.nboff;
99 pd.moved = 0;
100 dec_rval = INTEGER_decode_uper(0, &asn_DEF_INTEGER, &cts,
101 (void **)&reconstructed_st, &pd);
Lev Walkin20a01f92013-03-28 00:22:08 -0700102 assert(dec_rval.code == RC_OK);
103 if(unsigned_) {
104 unsigned long reconstructed_value = 0;
105 asn_INTEGER2ulong(reconstructed_st, &reconstructed_value);
106 assert(reconstructed_value == (unsigned long)value);
107 } else {
108 long reconstructed_value = 0;
109 asn_INTEGER2long(reconstructed_st, &reconstructed_value);
110 assert(reconstructed_value == value);
111 }
Lev Walkinae1422b2013-03-24 02:08:42 -0700112}
113
114#define CHECK(u, v, l, r, b) \
115 check_per_encode_constrained(__LINE__, u, v, l, r, b)
116
117int
118main() {
119 int unsigned_;
120 for(unsigned_ = 0; unsigned_ < 2; unsigned_++) {
121 int u = unsigned_;
122
123 /* Encode a signed 0x8babab into a range constrained by 0..2^29-1 */
124 CHECK(u, 0x8babab, 0, 536870911UL, 29);
125 CHECK(u, 0x8babab, 0, 1073741823UL, 30);
126 CHECK(u, 0x8babab, 0, 2147483647UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700127
128 CHECK(u, 0x8babab, 10, 536870901UL, 29);
129 CHECK(u, 0x8babab, 10, 1073741803UL, 30);
130 CHECK(u, 0x8babab, 10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700131
132 CHECK(0, 0x8babab, -10, 536870901UL, 29);
133 CHECK(0, 0x8babab, -10, 1073741803UL, 30);
134 CHECK(0, 0x8babab, -10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700135
136 CHECK(u, 11, 10, 536870901UL, 29);
137 CHECK(u, 11, 10, 1073741803UL, 30);
138 CHECK(u, 11, 10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700139
140 CHECK(0, 1, -10, 536870901UL, 29);
141 CHECK(0, 1, -10, 1073741803UL, 30);
142 CHECK(0, 1, -10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700143
144 CHECK(u, 10, 10, 536870901UL, 29);
145 CHECK(u, 10, 10, 1073741803UL, 30);
146 CHECK(u, 10, 10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700147
148 CHECK(0, 0, -10, 536870901UL, 29);
149 CHECK(0, 0, -10, 1073741803UL, 30);
150 CHECK(0, 0, -10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700151
152 CHECK(0, -1, -10, 536870901UL, 29);
153 CHECK(0, -1, -10, 1073741803UL, 30);
154 CHECK(0, -1, -10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700155
156 CHECK(0, -10, -10, 536870901UL, 29);
157 CHECK(0, -10, -10, 1073741803UL, 30);
158 CHECK(0, -10, -10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700159
160 CHECK(u, 536870901UL, 10, 536870901UL, 29);
161 CHECK(u, 1073741803UL, 10, 1073741803UL, 30);
162 CHECK(u, 2147483607UL, 10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700163
164 CHECK(0, 536870901UL, -10, 536870901UL, 29);
165 CHECK(0, 1073741803UL, -10, 1073741803UL, 30);
166 CHECK(0, 2147483607UL, -10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700167
Lev Walkinb1d85e32013-03-28 00:32:49 -0700168 CHECK(0, -2147483648, -2147483648, 2147483647, 32);
169 CHECK(0, -10, -2147483648, 2147483647, 32);
170 CHECK(0, -1, -2147483648, 2147483647, 32);
171 CHECK(0, 0, -2147483648, 2147483647, 32);
172 CHECK(0, 1, -2147483648, 2147483647, 32);
173 CHECK(0, 10, -2147483648, 2147483647, 32);
174 CHECK(0, 2147483647, -2147483648, 2147483647, 32);
Lev Walkin20a01f92013-03-28 00:22:08 -0700175
Lev Walkinb1d85e32013-03-28 00:32:49 -0700176 CHECK(1, 0, 0, 4294967295UL, 32);
177 CHECK(1, 1, 0, 4294967295UL, 32);
178 CHECK(1, 10, 0, 4294967295UL, 32);
179 CHECK(1, 2000000000, 0, 4294967295UL, 32);
180 CHECK(1, 2147483647, 0, 4294967295UL, 32);
181 CHECK(1, 2147483648, 0, 4294967295UL, 32);
182 CHECK(1, 4000000000, 0, 4294967295UL, 32);
183 CHECK(1, 4294967295UL, 0, 4294967295UL, 32);
Lev Walkin20a01f92013-03-28 00:22:08 -0700184
Lev Walkinb1d85e32013-03-28 00:32:49 -0700185 CHECK(1, 10, 10, 4294967285UL, 32);
186 CHECK(1, 11, 10, 4294967285UL, 32);
187
188 if(sizeof(long) > sizeof(uint32_t)) {
189 CHECK(0, 0, -10, 4294967285UL, 32);
190 CHECK(0, 1, -10, 4294967285UL, 32);
191 CHECK(0, -1, -10, 4294967285UL, 32);
192 CHECK(0, -10, -10, 4294967285UL, 32);
193 CHECK(0, -10, -10, 4294967285UL, 32);
194 CHECK(0, 0x8babab, -10, 4294967285UL, 32);
Lev Walkin20a01f92013-03-28 00:22:08 -0700195
196 CHECK(u, 0x8babab, 0, 4294967295UL, 32);
197 CHECK(u, 11, 10, 4294967205UL, 32);
198 CHECK(u, 10, 10, 4294967205UL, 32);
Lev Walkinb1d85e32013-03-28 00:32:49 -0700199 CHECK(u, 4294967205UL, 10, 4294967285UL, 32);
Lev Walkin20a01f92013-03-28 00:22:08 -0700200
Lev Walkinb1d85e32013-03-28 00:32:49 -0700201 CHECK(0, 4294967205UL, -10, 4294967285UL, 32);
Lev Walkin20a01f92013-03-28 00:22:08 -0700202 CHECK(u, 4294967295UL, 1, 4294967295UL, 32);
203
204 CHECK(u, 2000000000, 0, 4294967295UL, 32);
205 CHECK(u, 2147483647, 0, 4294967295UL, 32);
206 CHECK(u, 2147483648, 0, 4294967295UL, 32);
207 CHECK(u, 4000000000, 0, 4294967295UL, 32);
208 }
Lev Walkinae1422b2013-03-24 02:08:42 -0700209 }
210
211 return 0;
212}