53c7dddc246196bee2fd24219735cae05a224298
[com/asn1c.git] / tests / tests-skeletons / check-OER-INTEGER.c
1 #include <stdio.h>
2 #include <assert.h>
3
4 #include <asn_application.h>
5 #include <INTEGER.h>
6
7 #define CHECK_DECODE(code, a, b, c, d, e, f)    check_decode(__LINE__, code, a, b, c, d, e, f)
8 #define CHECK_ROUNDTRIP(a, b, c) check_roundtrip(__LINE__, a, b, c);
9 #define CHECK_ENCODE_OK(a, b, c) check_encode(__LINE__, 0, a, b, c)
10 #define CHECK_ENCODE_BAD(a, b, c) check_encode(__LINE__, 1, a, b, c);
11
12 static asn_oer_constraints_t *
13 setup_constraints(unsigned width, unsigned positive) {
14     static struct asn_oer_constraints_s empty_constraints;
15     asn_oer_constraints_t *constraints = &empty_constraints;
16     asn_oer_constraint_number_t *ct_value = &constraints->value;
17
18     memset(&empty_constraints, 0, sizeof(empty_constraints));
19
20     /* Setup integer constraints as requested */
21     ct_value->width = width;
22     ct_value->positive = positive;
23
24     return constraints;
25 }
26
27 static void
28 check_decode(int lineno, enum asn_dec_rval_code_e code, intmax_t control, const char *buf, size_t size, const char *dummy, unsigned width, unsigned positive) {
29     static char *code_s[] = { "RC_OK", "RC_WMORE", "RC_FAIL", "<error>" };
30
31     fprintf(stderr, "\n%d: OER decode (control %" PRIdMAX ")\n", lineno, control);
32
33     INTEGER_t *st = NULL;
34     asn_dec_rval_t ret;
35     asn_oer_constraints_t *constraints = setup_constraints(width, positive);
36
37     fprintf(stderr, "%d: buf[%zu]={%d, %d, ...}\n", lineno, size,
38             size <= 0 ? -1 : ((const uint8_t *)buf)[0],
39             size <= 1 ? -1 : ((const uint8_t *)buf)[1]);
40
41     (void)dummy;
42
43     ret = asn_DEF_INTEGER.op->oer_decoder(0, &asn_DEF_INTEGER, constraints,
44                                       (void **)&st, buf, size);
45     if(ret.code != RC_OK) {
46         /* Basic OER decode does not work */
47         fprintf(stderr, "%d: Failed oer_decode(ctl=%" PRIdMAX ", size=%zu)\n",
48                 lineno, control, size);
49         if(ret.code == code) {
50             fprintf(stderr, "  (That was expected)\n");
51             ASN_STRUCT_FREE(asn_DEF_INTEGER, st);
52             return;
53         } else {
54             fprintf(
55                 stderr, "  Unexpected return code %s (%d) expected %s\n",
56                 code_s[(unsigned)ret.code <= RC_FAIL ? RC_FAIL : (RC_FAIL + 1)],
57                 (int)ret.code, code_s[code]);
58             assert(ret.code == code);
59         }
60     } else {
61         intmax_t outcome;
62         if(asn_INTEGER2imax(st, &outcome) != 0) {
63             /* Result of decode is structurally incorrect */
64             fprintf(stderr,
65                     "%d: Failed to convert INTEGER 2 imax; structurally "
66                     "incorrect INTEGER\n",
67                     lineno);
68             assert(!"Unreachable");
69         } else if(outcome != control) {
70             /* Decoded value is wrong */
71             fprintf(stderr,
72                     "%d: Decode result %" PRIdMAX " is not expected %" PRIdMAX
73                     "\n",
74                     lineno, outcome, control);
75             assert(outcome == control);
76         }
77     }
78
79     fprintf(stderr, "%d: Decode result %" PRIdMAX "\n", lineno, control);
80     ASN_STRUCT_FREE(asn_DEF_INTEGER, st);
81 }
82
83 static void
84 dump_data(int lineno, const uint8_t *buf, size_t size) {
85     const uint8_t *p = buf;
86     const uint8_t *end = buf + size;
87
88     fprintf(stderr, "%d: Encoded: [", lineno);
89
90     for(; p < end; p++) {
91         fprintf(stderr, "\\x%02x", *(const unsigned char *)p);
92     }
93     fprintf(stderr, "] (%zu bytes)\n", size);
94 }
95
96 static void
97 check_roundtrip(int lineno, intmax_t value, intmax_t lower_bound, intmax_t upper_bound) {
98     uint8_t tmpbuf[32];
99     size_t tmpbuf_size;
100
101     fprintf(stderr, "\n%d: OER round-trip value %" PRIdMAX "\n", lineno, value);
102
103     INTEGER_t *stOut = (INTEGER_t *)calloc(1, sizeof(*stOut));
104     INTEGER_t *stIn = NULL;
105     asn_enc_rval_t er;
106     asn_dec_rval_t ret;
107     asn_oer_constraints_t *constraints =
108         setup_constraints(lower_bound, upper_bound);
109
110     if(asn_imax2INTEGER(stOut, value) == -1) {
111         assert(!"Unreachable imax2INTEGER failure");
112     } else {
113         assert(stOut->buf != NULL);
114         assert(stOut->size != 0);
115     }
116
117     er = oer_encode_to_buffer(&asn_DEF_INTEGER, constraints, stOut, tmpbuf,
118                               sizeof(tmpbuf));
119     if(er.encoded == -1) {
120         fprintf(stderr, "%d: OER encode failed for %s\n", lineno,
121                 er.failed_type ? er.failed_type->name : "<none>");
122         assert(er.encoded != -1);
123     }
124     tmpbuf_size = er.encoded;
125     ASN_STRUCT_FREE(asn_DEF_INTEGER, stOut);
126
127     dump_data(lineno, tmpbuf, tmpbuf_size);
128
129     ret = asn_DEF_INTEGER.op->oer_decoder(0, &asn_DEF_INTEGER, constraints,
130                                       (void **)&stIn, tmpbuf, tmpbuf_size);
131     if(ret.code != RC_OK) {
132         /* Basic OER decode does not work */
133         fprintf(stderr, "%d: Failed oer_decode(value=%" PRIdMAX ", size=%zu)\n",
134                 lineno, value, tmpbuf_size);
135         assert(ret.code == 0);
136     } else {
137         intmax_t outcome;
138         if(asn_INTEGER2imax(stIn, &outcome) != 0) {
139             /* Result of decode is structurally incorrect */
140             fprintf(stderr,
141                     "%d: Failed to convert INTEGER 2 imax; structurally "
142                     "incorrect INTEGER\n",
143                     lineno);
144             assert(!"Unreachable");
145         } else if(outcome != value) {
146             /* Decoded value is wrong */
147             fprintf(stderr,
148                     "%d: Decode result %" PRIdMAX " is not expected %" PRIdMAX
149                     "\n",
150                     lineno, outcome, value);
151             assert(outcome == value);
152         }
153     }
154
155     ASN_STRUCT_FREE(asn_DEF_INTEGER, stIn);
156     fprintf(stderr, "%d: Decode result %" PRIdMAX "\n", lineno, value);
157 }
158
159 static void
160 check_encode(int lineno, int bad, intmax_t value, unsigned width, unsigned positive) {
161     uint8_t tmpbuf[32];
162
163     fprintf(stderr, "\n%d: OER encode value %" PRIdMAX "\n", lineno, value);
164
165     INTEGER_t *stOut = (INTEGER_t *)calloc(1, sizeof(*stOut));
166     asn_enc_rval_t er;
167     asn_oer_constraints_t *constraints = setup_constraints(width, positive);
168
169     if(asn_imax2INTEGER(stOut, value) == -1) {
170         assert(!"Unreachable imax2INTEGER failure");
171     } else {
172         assert(stOut->buf != NULL);
173         assert(stOut->size != 0);
174     }
175
176     er = oer_encode_to_buffer(&asn_DEF_INTEGER, constraints, stOut, tmpbuf,
177                               sizeof(tmpbuf));
178     if(er.encoded == -1) {
179         fprintf(stderr, "%d: OER encode failed for %s%s\n", lineno,
180                 er.failed_type ? er.failed_type->name : "<none>",
181                 bad ? " (expected)" : "");
182         if(!bad) {
183             assert(er.encoded != -1);
184         }
185     } else {
186         dump_data(lineno, tmpbuf, er.encoded);
187         if(bad) {
188             assert(er.encoded == -1);
189         }
190     }
191     ASN_STRUCT_FREE(asn_DEF_INTEGER, stOut);
192 }
193
194 int
195 main() {
196         CHECK_DECODE(RC_WMORE, 0, "", 0, "bounds=", 0, 0);
197         CHECK_DECODE(RC_FAIL, 0, "\x00", 1, "bounds=", 0, 0);
198         CHECK_DECODE(RC_WMORE, 0, "", 0, "bounds=", 1, 0);
199         CHECK_DECODE(RC_WMORE, 0, "", 0, "bounds=", 1, 1);
200         CHECK_DECODE(RC_OK, 0, "\x00", 1, "bounds=", 1, 1);
201         CHECK_DECODE(RC_OK, 0, "\x00", 1, "bounds=", 1, 0);
202
203         CHECK_DECODE(RC_OK, 0, "\x00", 1, "bounds=", 1, 0);
204         CHECK_DECODE(RC_OK, 1, "\x01", 1, "bounds=", 1, 0);
205         CHECK_DECODE(RC_OK, -1, "\xff", 1, "bounds=", 1, 0);
206         CHECK_DECODE(RC_OK, -1, "\xff", 1, "bounds=", 1, 0);
207         CHECK_DECODE(RC_OK, 127, "\x7f", 1, "bounds=", 1, 1);
208         CHECK_DECODE(RC_OK, 255, "\xff", 1, "bounds=", 1, 1);
209         CHECK_DECODE(RC_OK, 255, "\xff", 1, "bounds=", 1, 1);
210         CHECK_DECODE(RC_WMORE, 0, "\xff", 1, "bounds=", 2, 1);
211         CHECK_DECODE(RC_OK, 65535, "\xff\xff", 2, "bounds=", 2, 1);
212
213         CHECK_DECODE(RC_OK, 0, "\x01\x00", 2, "bounds=", 0, 0);
214         CHECK_DECODE(RC_OK, 1, "\x01\x01", 2, "bounds=", 0, 0);
215         CHECK_DECODE(RC_OK, -1, "\x1\xff", 2, "bounds=", 0, 0);
216         CHECK_DECODE(RC_OK, -1, "\x1\xff", 2, "bounds=", 0, 0);
217         CHECK_DECODE(RC_OK, -1, "\x1\xff", 2, "bounds=", 0, 0);
218         CHECK_DECODE(RC_OK, 255, "\x1\xff", 2, "bounds=", 0, 1);
219         CHECK_DECODE(RC_WMORE, -1, "\x02\x00\xff", 2, "bounds=", 0, 0);
220         CHECK_DECODE(RC_OK, 255, "\x02\x00\xff", 3, "bounds=", 0, 0);
221
222     CHECK_ROUNDTRIP(0, 0, 0);
223     CHECK_ROUNDTRIP(1, 0, 0);
224     CHECK_ROUNDTRIP(-1, 0, 0);
225     CHECK_ROUNDTRIP(-65000, 0, 0);
226     CHECK_ROUNDTRIP(65000, 0, 0);
227     CHECK_ROUNDTRIP(65535, 0, 0);
228     CHECK_ROUNDTRIP(-65535, 0, 0);
229     CHECK_ROUNDTRIP(-65536, 0, 0);
230     CHECK_ROUNDTRIP(65536, 0, 0);
231     CHECK_ROUNDTRIP(0, 1, 0);
232     CHECK_ROUNDTRIP(1, 1, 0);
233     CHECK_ROUNDTRIP(-1, 1, 0);
234     CHECK_ROUNDTRIP(-127, 1, 0);
235     CHECK_ROUNDTRIP(-128, 1, 0);
236     CHECK_ROUNDTRIP(127, 1, 0);
237     CHECK_ROUNDTRIP(1, 2, 1);
238     CHECK_ROUNDTRIP(32000, 2, 1);
239     CHECK_ROUNDTRIP(32000, 2, 0);
240     CHECK_ROUNDTRIP(1, 2, 1);
241     CHECK_ROUNDTRIP(65535, 2, 1);
242     CHECK_ROUNDTRIP(65535, 4, 0);
243
244     CHECK_ENCODE_OK(0, 1, 1);
245     CHECK_ENCODE_OK(255, 1, 1);
246     CHECK_ENCODE_BAD(256, 1, 1);
247     CHECK_ENCODE_OK(0, 1, 0);
248     CHECK_ENCODE_OK(127, 1, 0);
249     CHECK_ENCODE_OK(-128, 1, 0);
250     CHECK_ENCODE_BAD(-129, 1, 0);
251     CHECK_ENCODE_BAD(128, 1, 0);
252     CHECK_ENCODE_OK(-4900000000, 8, 0);
253     CHECK_ENCODE_OK(4900000000, 8, 0);
254     CHECK_ENCODE_OK(-2000000000, 8, 0);
255     CHECK_ENCODE_OK(-4000000000, 8, 0);
256     CHECK_ENCODE_BAD(-4900000000, 4, 1);
257     CHECK_ENCODE_BAD(-1, 0, 4000000000);
258     CHECK_ENCODE_BAD(4900000000, 4, 1);
259     CHECK_ENCODE_OK(4100000000, 4, 1);
260
261     for(size_t i = 0; i < 7 ; i++) {
262         intmax_t value = (intmax_t)1 << i;
263         CHECK_ROUNDTRIP(value, 1, 1);
264         value = -value;
265         CHECK_ROUNDTRIP(value, 1, 0);
266     }
267
268     for(size_t i = 0; i < 16 ; i++) {
269         intmax_t value = (intmax_t)1 << i;
270         CHECK_ROUNDTRIP(value, 2, 1);
271         value = -value;
272         CHECK_ROUNDTRIP(value, 2, 0);
273     }
274
275     for(size_t i = 0; i < 32 ; i++) {
276         intmax_t value = (intmax_t)1 << i;
277         CHECK_ROUNDTRIP(value, 4, 1);
278         value = -value;
279         CHECK_ROUNDTRIP(value, 4, 0);
280     }
281
282     for(size_t i = 0; i < 8 * sizeof(intmax_t) - 1; i++) {
283         intmax_t value = (intmax_t)1 << i;
284         CHECK_ROUNDTRIP(value, 8, 0);
285         value = -value;
286         CHECK_ROUNDTRIP(value, 8, 0);
287     }
288
289     for(size_t i = 0; i < 8 * sizeof(intmax_t) - 1; i++) {
290         intmax_t value = (intmax_t)1 << i;
291         CHECK_ROUNDTRIP(value, 0, 0);
292         value = -value;
293         CHECK_ROUNDTRIP(value, 0, 0);
294     }
295
296 }