2e07a219c9c5bad1bbe03661a29b4998a4b7e54d
[com/asn1c.git] / tests / tests-skeletons / check-PER-INTEGER.c
1 #include <stdio.h>
2 #include <assert.h>
3
4 #include <INTEGER.h>
5 #include <INTEGER.c>
6 #include <per_support.c>
7 #include <per_support.h>
8
9 static int FailOut(const void *data, size_t size, void *op_key) {
10     (void)data;
11     (void)size;
12     (void)op_key;
13         assert(!"UNREACHABLE");
14         return 0;
15 }
16
17 static 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
25 static void
26 check_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;
29         struct asn_INTEGER_specifics_s specs;
30         struct asn_per_constraints_s cts;
31         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;
35
36         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);
42
43     if(ubound > LONG_MAX) {
44         printf("Skipped test, unsupported\n");
45         return;
46     }
47
48         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
60         if(unsigned_)
61                 asn_ulong2INTEGER(&st, (unsigned long)value);
62         else
63                 asn_long2INTEGER(&st, value);
64
65         po.buffer = po.tmpspace;
66         po.nboff = 0;
67         po.nbits = 8 * sizeof(po.tmpspace);
68         po.output = FailOut;
69
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]);
80
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);
97         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);
103         }
104         assert(po.nboff == (size_t)((bit_range == 32) ? 0 : (8 - (32 - bit_range))));
105         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);
114         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         }
124         ASN_STRUCT_RESET(asn_DEF_INTEGER, &st);
125         ASN_STRUCT_FREE(asn_DEF_INTEGER, reconstructed_st);
126 }
127
128 #define CHECK(u, v, l, r, b)    \
129         check_per_encode_constrained(__LINE__, u, v, l, r, b)
130
131 int
132 main() {
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);
141
142         CHECK(u, 0x8babab, 10, 536870901UL, 29);
143         CHECK(u, 0x8babab, 10, 1073741803UL, 30);
144         CHECK(u, 0x8babab, 10, 2147483607UL, 31);
145
146         CHECK(0, 0x8babab, -10, 536870901UL, 29);
147         CHECK(0, 0x8babab, -10, 1073741803UL, 30);
148         CHECK(0, 0x8babab, -10, 2147483607UL, 31);
149
150         CHECK(u, 11, 10, 536870901UL, 29);
151         CHECK(u, 11, 10, 1073741803UL, 30);
152         CHECK(u, 11, 10, 2147483607UL, 31);
153
154         CHECK(0, 1, -10, 536870901UL, 29);
155         CHECK(0, 1, -10, 1073741803UL, 30);
156         CHECK(0, 1, -10, 2147483607UL, 31);
157
158         CHECK(u, 10, 10, 536870901UL, 29);
159         CHECK(u, 10, 10, 1073741803UL, 30);
160         CHECK(u, 10, 10, 2147483607UL, 31);
161
162         CHECK(0, 0, -10, 536870901UL, 29);
163         CHECK(0, 0, -10, 1073741803UL, 30);
164         CHECK(0, 0, -10, 2147483607UL, 31);
165
166         CHECK(0, -1, -10, 536870901UL, 29);
167         CHECK(0, -1, -10, 1073741803UL, 30);
168         CHECK(0, -1, -10, 2147483607UL, 31);
169
170         CHECK(0, -10, -10, 536870901UL, 29);
171         CHECK(0, -10, -10, 1073741803UL, 30);
172         CHECK(0, -10, -10, 2147483607UL, 31);
173
174         CHECK(u, 536870901UL, 10, 536870901UL, 29);
175         CHECK(u, 1073741803UL, 10, 1073741803UL, 30);
176         CHECK(u, 2147483607UL, 10, 2147483607UL, 31);
177
178         CHECK(0, 536870901UL, -10, 536870901UL, 29);
179         CHECK(0, 1073741803UL, -10, 1073741803UL, 30);
180         CHECK(0, 2147483607UL, -10, 2147483607UL, 31);
181
182         CHECK(0, -2147483648, -2147483648, 2147483647, 32);
183         CHECK(0, -10, -2147483648, 2147483647, 32);
184         CHECK(0,  -1, -2147483648, 2147483647, 32);
185         CHECK(0,   0, INT32_MIN, INT32_MAX, 32);
186         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);
190
191         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);
196
197 #ifdef  TEST_64BIT
198         CHECK(1, 2147483648, 0, 4294967295UL, 32);
199         CHECK(1, 4000000000, 0, 4294967295UL, 32);
200         CHECK(1, 4294967295UL, 0, 4294967295UL, 32);
201 #endif
202
203         CHECK(1, 10, 10, 4294967285UL, 32);
204         CHECK(1, 11, 10, 4294967285UL, 32);
205
206 #ifdef  TEST_64BIT
207         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);
214
215                 CHECK(u, 0x8babab, 0, 4294967295UL, 32);
216                 CHECK(u, 11, 10, 4294967205UL, 32);
217                 CHECK(u, 10, 10, 4294967205UL, 32);
218                 CHECK(u, 4294967205UL, 10, 4294967285UL, 32);
219
220                 CHECK(0, 4294967205UL, -10, 4294967285UL, 32);
221                 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         }
228 #endif
229  }
230
231   return 0;
232 }