blob: 2e07a219c9c5bad1bbe03661a29b4998a4b7e54d [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) {
Lev Walkin97363482016-01-24 19:23:02 -080010 (void)data;
11 (void)size;
12 (void)op_key;
Lev Walkinae1422b2013-03-24 02:08:42 -070013 assert(!"UNREACHABLE");
14 return 0;
15}
16
17static void normalize(asn_per_outp_t *po) {
18 if(po->nboff >= 8) {
19 po->buffer += (po->nboff >> 3);
20 po->nbits -= (po->nboff & ~0x07);
21 po->nboff &= 0x07;
22 }
23}
24
25static void
26check_per_encode_constrained(int lineno, int unsigned_, long value, long lbound, unsigned long ubound, int bit_range) {
27 INTEGER_t st;
28 INTEGER_t *reconstructed_st = 0;
Wim Lewisfb6344e2014-07-28 12:16:01 -070029 struct asn_INTEGER_specifics_s specs;
Wim Lewis18c2ec92014-07-29 11:30:10 -070030 struct asn_per_constraints_s cts;
Lev Walkinae1422b2013-03-24 02:08:42 -070031 asn_enc_rval_t enc_rval;
32 asn_dec_rval_t dec_rval;
33 asn_per_outp_t po;
34 asn_per_data_t pd;
Lev Walkinae1422b2013-03-24 02:08:42 -070035
Lev Walkin20a01f92013-03-28 00:22:08 -070036 if(unsigned_)
37 printf("%d: Recoding %s %lu [%ld..%lu]\n", lineno,
38 unsigned_ ? "unsigned" : "signed", value, lbound, ubound);
39 else
40 printf("%d: Recoding %s %ld [%ld..%lu]\n", lineno,
41 unsigned_ ? "unsigned" : "signed", value, lbound, ubound);
Lev Walkinae1422b2013-03-24 02:08:42 -070042
Lev Walkin6cbed3d2017-10-07 16:42:41 -070043 if(ubound > LONG_MAX) {
44 printf("Skipped test, unsupported\n");
45 return;
46 }
47
Lev Walkinae1422b2013-03-24 02:08:42 -070048 memset(&st, 0, sizeof(st));
49 memset(&po, 0, sizeof(po));
50 memset(&pd, 0, sizeof(pd));
51 memset(&cts, 0, sizeof(cts));
52 memset(&specs, 0, sizeof(specs));
53
54 cts.value.flags = APC_CONSTRAINED;
55 cts.value.range_bits = bit_range;
56 cts.value.effective_bits = bit_range;
57 cts.value.lower_bound = lbound;
58 cts.value.upper_bound = ubound;
59
Lev Walkin20a01f92013-03-28 00:22:08 -070060 if(unsigned_)
61 asn_ulong2INTEGER(&st, (unsigned long)value);
62 else
63 asn_long2INTEGER(&st, value);
Lev Walkinae1422b2013-03-24 02:08:42 -070064
65 po.buffer = po.tmpspace;
66 po.nboff = 0;
67 po.nbits = 8 * sizeof(po.tmpspace);
Lev Walkin6cd0d562017-08-25 11:57:01 -070068 po.output = FailOut;
Lev Walkinae1422b2013-03-24 02:08:42 -070069
70 specs.field_width = sizeof(long);
71 specs.field_unsigned = unsigned_;
72
73 asn_DEF_INTEGER.specifics = &specs;
74 enc_rval = INTEGER_encode_uper(&asn_DEF_INTEGER, &cts, &st, &po);
75 assert(enc_rval.encoded == 0);
76
77 normalize(&po);
78
79 assert(po.buffer == &po.tmpspace[bit_range / 8]);
Lev Walkin20a01f92013-03-28 00:22:08 -070080
81 if(unsigned_) {
82 unsigned long recovered_value =
83 ((uint32_t)po.tmpspace[0] << 24)
84 | ((uint32_t)po.tmpspace[1] << 16)
85 | ((uint32_t)po.tmpspace[2] << 8)
86 | ((uint32_t)po.tmpspace[3] << 0);
87 recovered_value >>= (32 - bit_range);
88 recovered_value += cts.value.lower_bound;
89 assert(recovered_value == (unsigned long)value);
90 } else {
91 long recovered_value =
92 ((uint32_t)po.tmpspace[0] << 24)
93 | ((uint32_t)po.tmpspace[1] << 16)
94 | ((uint32_t)po.tmpspace[2] << 8)
95 | ((uint32_t)po.tmpspace[3] << 0);
96 recovered_value = (unsigned long)recovered_value >> (32 - bit_range);
Lev Walkin6cbed3d2017-10-07 16:42:41 -070097 if(per_long_range_unrebase(recovered_value, cts.value.lower_bound,
98 cts.value.upper_bound, &recovered_value)
99 < 0) {
100 assert(!"Unreachable");
101 }
102 assert(recovered_value == value);
Lev Walkin20a01f92013-03-28 00:22:08 -0700103 }
Lev Walkin97363482016-01-24 19:23:02 -0800104 assert(po.nboff == (size_t)((bit_range == 32) ? 0 : (8 - (32 - bit_range))));
Lev Walkinae1422b2013-03-24 02:08:42 -0700105 assert(po.nbits == 8 * (sizeof(po.tmpspace) - (po.buffer-po.tmpspace)));
106 assert(po.flushed_bytes == 0);
107
108 pd.buffer = po.tmpspace;
109 pd.nboff = 0;
110 pd.nbits = 8 * (po.buffer - po.tmpspace) + po.nboff;
111 pd.moved = 0;
112 dec_rval = INTEGER_decode_uper(0, &asn_DEF_INTEGER, &cts,
113 (void **)&reconstructed_st, &pd);
Lev Walkin20a01f92013-03-28 00:22:08 -0700114 assert(dec_rval.code == RC_OK);
115 if(unsigned_) {
116 unsigned long reconstructed_value = 0;
117 asn_INTEGER2ulong(reconstructed_st, &reconstructed_value);
118 assert(reconstructed_value == (unsigned long)value);
119 } else {
120 long reconstructed_value = 0;
121 asn_INTEGER2long(reconstructed_st, &reconstructed_value);
122 assert(reconstructed_value == value);
123 }
Lev Walkin229ad002017-09-18 20:13:49 -0700124 ASN_STRUCT_RESET(asn_DEF_INTEGER, &st);
125 ASN_STRUCT_FREE(asn_DEF_INTEGER, reconstructed_st);
Lev Walkinae1422b2013-03-24 02:08:42 -0700126}
127
128#define CHECK(u, v, l, r, b) \
129 check_per_encode_constrained(__LINE__, u, v, l, r, b)
130
131int
132main() {
133 int unsigned_;
134 for(unsigned_ = 0; unsigned_ < 2; unsigned_++) {
135 int u = unsigned_;
136
137 /* Encode a signed 0x8babab into a range constrained by 0..2^29-1 */
138 CHECK(u, 0x8babab, 0, 536870911UL, 29);
139 CHECK(u, 0x8babab, 0, 1073741823UL, 30);
140 CHECK(u, 0x8babab, 0, 2147483647UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700141
142 CHECK(u, 0x8babab, 10, 536870901UL, 29);
143 CHECK(u, 0x8babab, 10, 1073741803UL, 30);
144 CHECK(u, 0x8babab, 10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700145
146 CHECK(0, 0x8babab, -10, 536870901UL, 29);
147 CHECK(0, 0x8babab, -10, 1073741803UL, 30);
148 CHECK(0, 0x8babab, -10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700149
150 CHECK(u, 11, 10, 536870901UL, 29);
151 CHECK(u, 11, 10, 1073741803UL, 30);
152 CHECK(u, 11, 10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700153
154 CHECK(0, 1, -10, 536870901UL, 29);
155 CHECK(0, 1, -10, 1073741803UL, 30);
156 CHECK(0, 1, -10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700157
158 CHECK(u, 10, 10, 536870901UL, 29);
159 CHECK(u, 10, 10, 1073741803UL, 30);
160 CHECK(u, 10, 10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700161
162 CHECK(0, 0, -10, 536870901UL, 29);
163 CHECK(0, 0, -10, 1073741803UL, 30);
164 CHECK(0, 0, -10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700165
166 CHECK(0, -1, -10, 536870901UL, 29);
167 CHECK(0, -1, -10, 1073741803UL, 30);
168 CHECK(0, -1, -10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700169
170 CHECK(0, -10, -10, 536870901UL, 29);
171 CHECK(0, -10, -10, 1073741803UL, 30);
172 CHECK(0, -10, -10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700173
174 CHECK(u, 536870901UL, 10, 536870901UL, 29);
175 CHECK(u, 1073741803UL, 10, 1073741803UL, 30);
176 CHECK(u, 2147483607UL, 10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700177
178 CHECK(0, 536870901UL, -10, 536870901UL, 29);
179 CHECK(0, 1073741803UL, -10, 1073741803UL, 30);
180 CHECK(0, 2147483607UL, -10, 2147483607UL, 31);
Lev Walkinae1422b2013-03-24 02:08:42 -0700181
Lev Walkinb1d85e32013-03-28 00:32:49 -0700182 CHECK(0, -2147483648, -2147483648, 2147483647, 32);
183 CHECK(0, -10, -2147483648, 2147483647, 32);
184 CHECK(0, -1, -2147483648, 2147483647, 32);
Lev Walkin6cbed3d2017-10-07 16:42:41 -0700185 CHECK(0, 0, INT32_MIN, INT32_MAX, 32);
Lev Walkinb1d85e32013-03-28 00:32:49 -0700186 CHECK(0, 0, -2147483648, 2147483647, 32);
187 CHECK(0, 1, -2147483648, 2147483647, 32);
188 CHECK(0, 10, -2147483648, 2147483647, 32);
189 CHECK(0, 2147483647, -2147483648, 2147483647, 32);
Lev Walkin20a01f92013-03-28 00:22:08 -0700190
Lev Walkinb1d85e32013-03-28 00:32:49 -0700191 CHECK(1, 0, 0, 4294967295UL, 32);
192 CHECK(1, 1, 0, 4294967295UL, 32);
193 CHECK(1, 10, 0, 4294967295UL, 32);
194 CHECK(1, 2000000000, 0, 4294967295UL, 32);
195 CHECK(1, 2147483647, 0, 4294967295UL, 32);
Lev Walkin6cbed3d2017-10-07 16:42:41 -0700196
197#ifdef TEST_64BIT
Lev Walkinb1d85e32013-03-28 00:32:49 -0700198 CHECK(1, 2147483648, 0, 4294967295UL, 32);
199 CHECK(1, 4000000000, 0, 4294967295UL, 32);
200 CHECK(1, 4294967295UL, 0, 4294967295UL, 32);
Lev Walkin6cbed3d2017-10-07 16:42:41 -0700201#endif
Lev Walkin20a01f92013-03-28 00:22:08 -0700202
Lev Walkinb1d85e32013-03-28 00:32:49 -0700203 CHECK(1, 10, 10, 4294967285UL, 32);
204 CHECK(1, 11, 10, 4294967285UL, 32);
205
Lev Walkin6cbed3d2017-10-07 16:42:41 -0700206#ifdef TEST_64BIT
Lev Walkinb1d85e32013-03-28 00:32:49 -0700207 if(sizeof(long) > sizeof(uint32_t)) {
208 CHECK(0, 0, -10, 4294967285UL, 32);
209 CHECK(0, 1, -10, 4294967285UL, 32);
210 CHECK(0, -1, -10, 4294967285UL, 32);
211 CHECK(0, -10, -10, 4294967285UL, 32);
212 CHECK(0, -10, -10, 4294967285UL, 32);
213 CHECK(0, 0x8babab, -10, 4294967285UL, 32);
Lev Walkin20a01f92013-03-28 00:22:08 -0700214
215 CHECK(u, 0x8babab, 0, 4294967295UL, 32);
216 CHECK(u, 11, 10, 4294967205UL, 32);
217 CHECK(u, 10, 10, 4294967205UL, 32);
Lev Walkinb1d85e32013-03-28 00:32:49 -0700218 CHECK(u, 4294967205UL, 10, 4294967285UL, 32);
Lev Walkin20a01f92013-03-28 00:22:08 -0700219
Lev Walkinb1d85e32013-03-28 00:32:49 -0700220 CHECK(0, 4294967205UL, -10, 4294967285UL, 32);
Lev Walkin20a01f92013-03-28 00:22:08 -0700221 CHECK(u, 4294967295UL, 1, 4294967295UL, 32);
222
223 CHECK(u, 2000000000, 0, 4294967295UL, 32);
224 CHECK(u, 2147483647, 0, 4294967295UL, 32);
225 CHECK(u, 2147483648, 0, 4294967295UL, 32);
226 CHECK(u, 4000000000, 0, 4294967295UL, 32);
227 }
Lev Walkin6cbed3d2017-10-07 16:42:41 -0700228#endif
Lev Walkinae1422b2013-03-24 02:08:42 -0700229 }
230
231 return 0;
232}