blob: f30ea3860359783bc6c54d3b2d89edf504867c96 [file] [log] [blame]
Lev Walkined3a4ae2017-07-07 10:09:51 -07001#include <stdio.h>
2#include <assert.h>
3
Lev Walkine4d8c922017-07-10 20:29:33 -07004#include <asn_codecs.h>
Lev Walkined3a4ae2017-07-07 10:09:51 -07005#include <INTEGER.h>
Lev Walkined3a4ae2017-07-07 10:09:51 -07006
Lev Walkine4d8c922017-07-10 20:29:33 -07007#define CHECK_DECODE(code, a, b, c, d, e, f) check_decode(__LINE__, code, a, b, c, d, e, f)
Lev Walkincc9b3ae2017-07-14 08:57:02 +04008#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);
Lev Walkin54f34512017-07-10 05:27:46 -070011
Lev Walkincc9b3ae2017-07-14 08:57:02 +040012static asn_oer_constraints_t *
Lev Walkin494fb702017-08-07 20:07:00 -070013setup_constraints(unsigned width, unsigned positive) {
Lev Walkincc9b3ae2017-07-14 08:57:02 +040014 static struct asn_oer_constraints_s empty_constraints;
Lev Walkin494fb702017-08-07 20:07:00 -070015 asn_oer_constraints_t *constraints = &empty_constraints;
16 asn_oer_constraint_number_t *ct_value = &constraints->value;
Lev Walkin54f34512017-07-10 05:27:46 -070017
Lev Walkincc9b3ae2017-07-14 08:57:02 +040018 memset(&empty_constraints, 0, sizeof(empty_constraints));
19
Lev Walkine4d8c922017-07-10 20:29:33 -070020 /* Setup integer constraints as requested */
Lev Walkin4118ccf2017-08-02 10:37:31 -070021 ct_value->width = width;
22 ct_value->positive = positive;
Lev Walkine4d8c922017-07-10 20:29:33 -070023
Lev Walkincc9b3ae2017-07-14 08:57:02 +040024 return constraints;
25}
26
27static void
Lev Walkin4118ccf2017-08-02 10:37:31 -070028check_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) {
Lev Walkincc9b3ae2017-07-14 08:57:02 +040029 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;
Lev Walkin494fb702017-08-07 20:07:00 -070035 asn_oer_constraints_t *constraints = setup_constraints(width, positive);
Lev Walkincc9b3ae2017-07-14 08:57:02 +040036
37 fprintf(stderr, "%d: buf[%zu]={%d, %d, ...}\n", lineno, size,
38 ((const uint8_t *)buf)[0],
39 ((const uint8_t *)buf)[1]);
40
Lev Walkine4d8c922017-07-10 20:29:33 -070041 (void)dummy;
42
43 ret = asn_DEF_INTEGER.oer_decoder(0, &asn_DEF_INTEGER, constraints,
44 (void **)&st, buf, size);
Lev Walkin54f34512017-07-10 05:27:46 -070045 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);
Lev Walkine4d8c922017-07-10 20:29:33 -070049 if(ret.code == code) {
50 fprintf(stderr, " (That was expected)\n");
51 return;
52 } else {
53 fprintf(
54 stderr, " Unexpected return code %s (%d) expected %s\n",
55 code_s[(unsigned)ret.code <= RC_FAIL ? RC_FAIL : (RC_FAIL + 1)],
56 (int)ret.code, code_s[code]);
57 assert(ret.code == code);
58 }
Lev Walkin54f34512017-07-10 05:27:46 -070059 } else {
60 intmax_t outcome;
61 if(asn_INTEGER2imax(st, &outcome) != 0) {
62 /* Result of decode is structurally incorrect */
Lev Walkine4d8c922017-07-10 20:29:33 -070063 fprintf(stderr,
64 "%d: Failed to convert INTEGER 2 imax; structurally "
65 "incorrect INTEGER\n",
Lev Walkin54f34512017-07-10 05:27:46 -070066 lineno);
67 assert(!"Unreachable");
68 } else if(outcome != control) {
69 /* Decoded value is wrong */
70 fprintf(stderr,
71 "%d: Decode result %" PRIdMAX " is not expected %" PRIdMAX
72 "\n",
73 lineno, outcome, control);
74 assert(outcome == control);
75 }
76 }
77
78 fprintf(stderr, "%d: Decode result %" PRIdMAX "\n", lineno, control);
Lev Walkined3a4ae2017-07-07 10:09:51 -070079}
80
Lev Walkincc9b3ae2017-07-14 08:57:02 +040081static void
82dump_data(int lineno, const uint8_t *buf, size_t size) {
83 const uint8_t *p = buf;
84 const uint8_t *end = buf + size;
85
86 fprintf(stderr, "%d: Encoded: [", lineno);
87
88 for(; p < end; p++) {
89 fprintf(stderr, "\\x%02x", *(const unsigned char *)p);
90 }
91 fprintf(stderr, "] (%zu bytes)\n", size);
92}
Lev Walkin486fd5c2017-07-10 22:08:14 -070093
94static void
95check_roundtrip(int lineno, intmax_t value, intmax_t lower_bound, intmax_t upper_bound) {
96 uint8_t tmpbuf[32];
97 size_t tmpbuf_size;
98
Lev Walkincc9b3ae2017-07-14 08:57:02 +040099 fprintf(stderr, "\n%d: OER round-trip value %" PRIdMAX "\n", lineno, value);
100
Lev Walkin486fd5c2017-07-10 22:08:14 -0700101 INTEGER_t *stOut = (INTEGER_t *)calloc(1, sizeof(*stOut));
102 INTEGER_t *stIn = NULL;
103 asn_enc_rval_t er;
104 asn_dec_rval_t ret;
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400105 asn_oer_constraints_t *constraints =
Lev Walkin494fb702017-08-07 20:07:00 -0700106 setup_constraints(lower_bound, upper_bound);
Lev Walkin486fd5c2017-07-10 22:08:14 -0700107
108 if(asn_imax2INTEGER(stOut, value) == -1) {
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400109 assert(!"Unreachable imax2INTEGER failure");
110 } else {
111 assert(stOut->buf != NULL);
112 assert(stOut->size != 0);
Lev Walkin486fd5c2017-07-10 22:08:14 -0700113 }
114
115 er = oer_encode_to_buffer(&asn_DEF_INTEGER, constraints, stOut, tmpbuf,
116 sizeof(tmpbuf));
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400117 if(er.encoded == -1) {
118 fprintf(stderr, "%d: OER encode failed for %s\n", lineno,
Lev Walkin486fd5c2017-07-10 22:08:14 -0700119 er.failed_type ? er.failed_type->name : "<none>");
120 assert(er.encoded != -1);
121 }
122 tmpbuf_size = er.encoded;
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400123 ASN_STRUCT_FREE(asn_DEF_INTEGER, stOut);
124
125 dump_data(lineno, tmpbuf, tmpbuf_size);
Lev Walkin486fd5c2017-07-10 22:08:14 -0700126
127 ret = asn_DEF_INTEGER.oer_decoder(0, &asn_DEF_INTEGER, constraints,
128 (void **)&stIn, tmpbuf, tmpbuf_size);
129 if(ret.code != RC_OK) {
130 /* Basic OER decode does not work */
131 fprintf(stderr, "%d: Failed oer_decode(value=%" PRIdMAX ", size=%zu)\n",
132 lineno, value, tmpbuf_size);
133 assert(ret.code == 0);
134 } else {
135 intmax_t outcome;
136 if(asn_INTEGER2imax(stIn, &outcome) != 0) {
137 /* Result of decode is structurally incorrect */
138 fprintf(stderr,
139 "%d: Failed to convert INTEGER 2 imax; structurally "
140 "incorrect INTEGER\n",
141 lineno);
142 assert(!"Unreachable");
143 } else if(outcome != value) {
144 /* Decoded value is wrong */
145 fprintf(stderr,
146 "%d: Decode result %" PRIdMAX " is not expected %" PRIdMAX
147 "\n",
148 lineno, outcome, value);
149 assert(outcome == value);
150 }
151 }
152
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400153 ASN_STRUCT_FREE(asn_DEF_INTEGER, stIn);
Lev Walkin486fd5c2017-07-10 22:08:14 -0700154 fprintf(stderr, "%d: Decode result %" PRIdMAX "\n", lineno, value);
155}
156
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400157static void
Lev Walkin4118ccf2017-08-02 10:37:31 -0700158check_encode(int lineno, int bad, intmax_t value, unsigned width, unsigned positive) {
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400159 uint8_t tmpbuf[32];
160
161 fprintf(stderr, "\n%d: OER encode value %" PRIdMAX "\n", lineno, value);
162
163 INTEGER_t *stOut = (INTEGER_t *)calloc(1, sizeof(*stOut));
164 asn_enc_rval_t er;
Lev Walkin494fb702017-08-07 20:07:00 -0700165 asn_oer_constraints_t *constraints = setup_constraints(width, positive);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400166
167 if(asn_imax2INTEGER(stOut, value) == -1) {
168 assert(!"Unreachable imax2INTEGER failure");
169 } else {
170 assert(stOut->buf != NULL);
171 assert(stOut->size != 0);
172 }
173
174 er = oer_encode_to_buffer(&asn_DEF_INTEGER, constraints, stOut, tmpbuf,
175 sizeof(tmpbuf));
176 if(er.encoded == -1) {
177 fprintf(stderr, "%d: OER encode failed for %s%s\n", lineno,
178 er.failed_type ? er.failed_type->name : "<none>",
179 bad ? " (expected)" : "");
180 if(!bad) {
181 assert(er.encoded != -1);
182 }
183 } else {
184 dump_data(lineno, tmpbuf, er.encoded);
185 if(bad) {
186 assert(er.encoded == -1);
187 }
188 }
189 ASN_STRUCT_FREE(asn_DEF_INTEGER, stOut);
190}
191
Lev Walkined3a4ae2017-07-07 10:09:51 -0700192int
193main() {
Lev Walkine4d8c922017-07-10 20:29:33 -0700194 CHECK_DECODE(RC_WMORE, 0, "", 0, "bounds=", 0, 0);
Lev Walkin4118ccf2017-08-02 10:37:31 -0700195 CHECK_DECODE(RC_FAIL, 0, "\x00", 1, "bounds=", 0, 0);
196 CHECK_DECODE(RC_WMORE, 0, "", 0, "bounds=", 1, 0);
197 CHECK_DECODE(RC_WMORE, 0, "", 0, "bounds=", 1, 1);
198 CHECK_DECODE(RC_OK, 0, "\x00", 1, "bounds=", 1, 1);
199 CHECK_DECODE(RC_OK, 0, "\x00", 1, "bounds=", 1, 0);
Lev Walkine4d8c922017-07-10 20:29:33 -0700200
Lev Walkin4118ccf2017-08-02 10:37:31 -0700201 CHECK_DECODE(RC_OK, 0, "\x00", 1, "bounds=", 1, 0);
202 CHECK_DECODE(RC_OK, 1, "\x01", 1, "bounds=", 1, 0);
203 CHECK_DECODE(RC_OK, -1, "\xff", 1, "bounds=", 1, 0);
204 CHECK_DECODE(RC_OK, -1, "\xff", 1, "bounds=", 1, 0);
205 CHECK_DECODE(RC_OK, 127, "\x7f", 1, "bounds=", 1, 1);
206 CHECK_DECODE(RC_OK, 255, "\xff", 1, "bounds=", 1, 1);
207 CHECK_DECODE(RC_OK, 255, "\xff", 1, "bounds=", 1, 1);
208 CHECK_DECODE(RC_WMORE, 0, "\xff", 1, "bounds=", 2, 1);
209 CHECK_DECODE(RC_OK, 65535, "\xff\xff", 2, "bounds=", 2, 1);
Lev Walkine4d8c922017-07-10 20:29:33 -0700210
Lev Walkin4118ccf2017-08-02 10:37:31 -0700211 CHECK_DECODE(RC_OK, 0, "\x01\x00", 2, "bounds=", 0, 0);
212 CHECK_DECODE(RC_OK, 1, "\x01\x01", 2, "bounds=", 0, 0);
213 CHECK_DECODE(RC_OK, -1, "\x1\xff", 2, "bounds=", 0, 0);
214 CHECK_DECODE(RC_OK, -1, "\x1\xff", 2, "bounds=", 0, 0);
215 CHECK_DECODE(RC_OK, -1, "\x1\xff", 2, "bounds=", 0, 0);
216 CHECK_DECODE(RC_OK, 255, "\x1\xff", 2, "bounds=", 0, 1);
217 CHECK_DECODE(RC_WMORE, -1, "\x02\x00\xff", 2, "bounds=", 0, 0);
218 CHECK_DECODE(RC_OK, 255, "\x02\x00\xff", 3, "bounds=", 0, 0);
Lev Walkin486fd5c2017-07-10 22:08:14 -0700219
Lev Walkin4118ccf2017-08-02 10:37:31 -0700220 CHECK_ROUNDTRIP(0, 0, 0);
221 CHECK_ROUNDTRIP(1, 0, 0);
222 CHECK_ROUNDTRIP(-1, 0, 0);
223 CHECK_ROUNDTRIP(-65000, 0, 0);
224 CHECK_ROUNDTRIP(65000, 0, 0);
225 CHECK_ROUNDTRIP(65535, 0, 0);
226 CHECK_ROUNDTRIP(-65535, 0, 0);
227 CHECK_ROUNDTRIP(-65536, 0, 0);
228 CHECK_ROUNDTRIP(65536, 0, 0);
229 CHECK_ROUNDTRIP(0, 1, 0);
230 CHECK_ROUNDTRIP(1, 1, 0);
231 CHECK_ROUNDTRIP(-1, 1, 0);
232 CHECK_ROUNDTRIP(-127, 1, 0);
233 CHECK_ROUNDTRIP(-128, 1, 0);
234 CHECK_ROUNDTRIP(127, 1, 0);
235 CHECK_ROUNDTRIP(1, 2, 1);
236 CHECK_ROUNDTRIP(32000, 2, 1);
237 CHECK_ROUNDTRIP(32000, 2, 0);
238 CHECK_ROUNDTRIP(1, 2, 1);
239 CHECK_ROUNDTRIP(65535, 2, 1);
240 CHECK_ROUNDTRIP(65535, 4, 0);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400241
Lev Walkin4118ccf2017-08-02 10:37:31 -0700242 CHECK_ENCODE_OK(0, 1, 1);
243 CHECK_ENCODE_OK(255, 1, 1);
244 CHECK_ENCODE_BAD(256, 1, 1);
245 CHECK_ENCODE_OK(0, 1, 0);
246 CHECK_ENCODE_OK(127, 1, 0);
247 CHECK_ENCODE_OK(-128, 1, 0);
248 CHECK_ENCODE_BAD(-129, 1, 0);
249 CHECK_ENCODE_BAD(128, 1, 0);
250 CHECK_ENCODE_OK(-4900000000, 8, 0);
251 CHECK_ENCODE_OK(4900000000, 8, 0);
252 CHECK_ENCODE_OK(-2000000000, 8, 0);
253 CHECK_ENCODE_OK(-4000000000, 8, 0);
254 CHECK_ENCODE_BAD(-4900000000, 4, 1);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400255 CHECK_ENCODE_BAD(-1, 0, 4000000000);
Lev Walkin4118ccf2017-08-02 10:37:31 -0700256 CHECK_ENCODE_BAD(4900000000, 4, 1);
257 CHECK_ENCODE_OK(4100000000, 4, 1);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400258
259 for(size_t i = 0; i < 7 ; i++) {
260 intmax_t value = (intmax_t)1 << i;
Lev Walkin4118ccf2017-08-02 10:37:31 -0700261 CHECK_ROUNDTRIP(value, 1, 1);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400262 value = -value;
Lev Walkin4118ccf2017-08-02 10:37:31 -0700263 CHECK_ROUNDTRIP(value, 1, 0);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400264 }
265
266 for(size_t i = 0; i < 16 ; i++) {
267 intmax_t value = (intmax_t)1 << i;
Lev Walkin4118ccf2017-08-02 10:37:31 -0700268 CHECK_ROUNDTRIP(value, 2, 1);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400269 value = -value;
Lev Walkin4118ccf2017-08-02 10:37:31 -0700270 CHECK_ROUNDTRIP(value, 2, 0);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400271 }
272
273 for(size_t i = 0; i < 32 ; i++) {
274 intmax_t value = (intmax_t)1 << i;
Lev Walkin4118ccf2017-08-02 10:37:31 -0700275 CHECK_ROUNDTRIP(value, 4, 1);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400276 value = -value;
Lev Walkin4118ccf2017-08-02 10:37:31 -0700277 CHECK_ROUNDTRIP(value, 4, 0);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400278 }
279
280 for(size_t i = 0; i < 8 * sizeof(intmax_t) ; i++) {
281 intmax_t value = (intmax_t)1 << i;
Lev Walkin4118ccf2017-08-02 10:37:31 -0700282 CHECK_ROUNDTRIP(value, 8, 0);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400283 value = -value;
Lev Walkin4118ccf2017-08-02 10:37:31 -0700284 CHECK_ROUNDTRIP(value, 8, 0);
285 }
286
287 for(size_t i = 0; i < 8 * sizeof(intmax_t) ; i++) {
288 intmax_t value = (intmax_t)1 << i;
289 CHECK_ROUNDTRIP(value, 0, 0);
290 value = -value;
291 CHECK_ROUNDTRIP(value, 0, 0);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400292 }
Lev Walkin486fd5c2017-07-10 22:08:14 -0700293
Lev Walkined3a4ae2017-07-07 10:09:51 -0700294}