blob: f17243753419facb15258bedfcf50d0cdbb9c780 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001/*-
Lev Walkin523de9e2006-08-18 01:34:18 +00002 * Copyright (c) 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
3 * All rights reserved.
Lev Walkinf15320b2004-06-03 03:38:44 +00004 * Redistribution and modifications are permitted subject to BSD license.
5 */
6/*
Lev Walkin41635d32006-03-18 05:06:57 +00007 * Read the NativeInteger.h for the explanation wrt. differences between
Lev Walkinf15320b2004-06-03 03:38:44 +00008 * INTEGER and NativeInteger.
9 * Basically, both are decoders and encoders of ASN.1 INTEGER type, but this
10 * implementation deals with the standard (machine-specific) representation
11 * of them instead of using the platform-independent buffer.
12 */
Lev Walkina9cc46e2004-09-22 16:06:28 +000013#include <asn_internal.h>
Lev Walkinf15320b2004-06-03 03:38:44 +000014#include <NativeInteger.h>
Lev Walkinf15320b2004-06-03 03:38:44 +000015
16/*
17 * NativeInteger basic type description.
18 */
Wim Lewis18c2ec92014-07-29 11:30:10 -070019static const ber_tlv_tag_t asn_DEF_NativeInteger_tags[] = {
Lev Walkinf15320b2004-06-03 03:38:44 +000020 (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
21};
Bi-Ruei, Chiu1f87ac02017-08-20 01:25:45 +080022asn_TYPE_operation_t asn_OP_NativeInteger = {
Lev Walkina9cc46e2004-09-22 16:06:28 +000023 NativeInteger_free,
24 NativeInteger_print,
Lev Walkincd2f48e2017-08-10 02:14:59 -070025 NativeInteger_compare,
Lev Walkinf15320b2004-06-03 03:38:44 +000026 NativeInteger_decode_ber,
27 NativeInteger_encode_der,
Lev Walkin435cb282004-10-21 14:13:48 +000028 NativeInteger_decode_xer,
Lev Walkina9cc46e2004-09-22 16:06:28 +000029 NativeInteger_encode_xer,
Lev Walkincc159472017-07-06 08:26:36 -070030#ifdef ASN_DISABLE_OER_SUPPORT
31 0,
32 0,
33#else
Lev Walkin9ae018e2017-07-24 01:45:57 +040034 NativeInteger_decode_oer, /* OER decoder */
35 NativeInteger_encode_oer, /* Canonical OER encoder */
Lev Walkincc159472017-07-06 08:26:36 -070036#endif /* ASN_DISABLE_OER_SUPPORT */
Lev Walkinb33425f2017-07-14 14:59:52 +040037#ifdef ASN_DISABLE_PER_SUPPORT
38 0,
39 0,
40#else
41 NativeInteger_decode_uper, /* Unaligned PER decoder */
42 NativeInteger_encode_uper, /* Unaligned PER encoder */
43#endif /* ASN_DISABLE_PER_SUPPORT */
Lev Walkina5972be2017-09-29 23:15:58 -070044 NativeInteger_random_fill,
Bi-Ruei, Chiu1f87ac02017-08-20 01:25:45 +080045 0 /* Use generic outmost tag fetcher */
46};
47asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
48 "INTEGER", /* The ASN.1 type is still INTEGER */
49 "INTEGER",
50 &asn_OP_NativeInteger,
Lev Walkin5e033762004-09-29 13:26:15 +000051 asn_DEF_NativeInteger_tags,
52 sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
53 asn_DEF_NativeInteger_tags, /* Same as above */
54 sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
Lev Walkina5972be2017-09-29 23:15:58 -070055 { 0, 0, asn_generic_no_constraint },
Lev Walkin449f8322004-08-20 13:23:42 +000056 0, 0, /* No members */
Lev Walkind9bd7752004-06-05 08:17:50 +000057 0 /* No specifics */
Lev Walkinf15320b2004-06-03 03:38:44 +000058};
59
60/*
61 * Decode INTEGER type.
62 */
Lev Walkindc06f6b2004-10-20 15:50:55 +000063asn_dec_rval_t
Lev Walkinafbf2a92017-09-12 23:30:27 -070064NativeInteger_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
Lev Walkin20696a42017-10-17 21:27:33 -070065 const asn_TYPE_descriptor_t *td, void **nint_ptr,
66 const void *buf_ptr, size_t size, int tag_mode) {
Lev Walkind62a6622017-08-22 02:31:02 -070067 const asn_INTEGER_specifics_t *specs =
68 (const asn_INTEGER_specifics_t *)td->specifics;
69 long *native = (long *)*nint_ptr;
Lev Walkindc06f6b2004-10-20 15:50:55 +000070 asn_dec_rval_t rval;
Lev Walkinf15320b2004-06-03 03:38:44 +000071 ber_tlv_len_t length;
72
73 /*
74 * If the structure is not there, allocate it.
75 */
Lev Walkine0b56e02005-02-25 12:10:27 +000076 if(native == NULL) {
77 native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
78 if(native == NULL) {
Lev Walkinf15320b2004-06-03 03:38:44 +000079 rval.code = RC_FAIL;
80 rval.consumed = 0;
81 return rval;
82 }
83 }
84
85 ASN_DEBUG("Decoding %s as INTEGER (tm=%d)",
86 td->name, tag_mode);
87
88 /*
89 * Check tags.
90 */
Lev Walkin5e033762004-09-29 13:26:15 +000091 rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
92 tag_mode, 0, &length, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +000093 if(rval.code != RC_OK)
94 return rval;
95
96 ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
97
98 /*
99 * Make sure we have this length.
100 */
Lev Walkin8c3b8542005-03-10 18:52:02 +0000101 buf_ptr = ((const char *)buf_ptr) + rval.consumed;
Lev Walkinf15320b2004-06-03 03:38:44 +0000102 size -= rval.consumed;
Lev Walkind9bd7752004-06-05 08:17:50 +0000103 if(length > (ber_tlv_len_t)size) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000104 rval.code = RC_WMORE;
105 rval.consumed = 0;
106 return rval;
107 }
108
109 /*
110 * ASN.1 encoded INTEGER: buf_ptr, length
Lev Walkine0b56e02005-02-25 12:10:27 +0000111 * Fill the native, at the same time checking for overflow.
Lev Walkinf15320b2004-06-03 03:38:44 +0000112 * If overflow occured, return with RC_FAIL.
113 */
114 {
115 INTEGER_t tmp;
Lev Walkin7e033b52005-07-02 08:19:17 +0000116 union {
117 const void *constbuf;
118 void *nonconstbuf;
119 } unconst_buf;
Lev Walkinf15320b2004-06-03 03:38:44 +0000120 long l;
Lev Walkin7e033b52005-07-02 08:19:17 +0000121
122 unconst_buf.constbuf = buf_ptr;
123 tmp.buf = (uint8_t *)unconst_buf.nonconstbuf;
Lev Walkinf15320b2004-06-03 03:38:44 +0000124 tmp.size = length;
125
Lev Walkin8bb57a22007-12-03 13:41:36 +0000126 if((specs&&specs->field_unsigned)
Lev Walkinaaae9bf2010-10-24 16:56:30 -0700127 ? asn_INTEGER2ulong(&tmp, (unsigned long *)&l) /* sic */
Lev Walkin8bb57a22007-12-03 13:41:36 +0000128 : asn_INTEGER2long(&tmp, &l)) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000129 rval.code = RC_FAIL;
130 rval.consumed = 0;
131 return rval;
132 }
133
Lev Walkine0b56e02005-02-25 12:10:27 +0000134 *native = l;
Lev Walkinf15320b2004-06-03 03:38:44 +0000135 }
136
137 rval.code = RC_OK;
138 rval.consumed += length;
139
Lev Walkine0b56e02005-02-25 12:10:27 +0000140 ASN_DEBUG("Took %ld/%ld bytes to encode %s (%ld)",
141 (long)rval.consumed, (long)length, td->name, (long)*native);
Lev Walkinf15320b2004-06-03 03:38:44 +0000142
143 return rval;
144}
145
146/*
147 * Encode the NativeInteger using the standard INTEGER type DER encoder.
148 */
Lev Walkina9cc46e2004-09-22 16:06:28 +0000149asn_enc_rval_t
Lev Walkin20696a42017-10-17 21:27:33 -0700150NativeInteger_encode_der(const asn_TYPE_descriptor_t *sd, const void *ptr,
151 int tag_mode, ber_tlv_tag_t tag,
152 asn_app_consume_bytes_f *cb, void *app_key) {
153 unsigned long native = *(const unsigned long *)ptr; /* Disable sign ext. */
154 asn_enc_rval_t erval;
Lev Walkinf15320b2004-06-03 03:38:44 +0000155 INTEGER_t tmp;
156
157#ifdef WORDS_BIGENDIAN /* Opportunistic optimization */
158
Lev Walkine0b56e02005-02-25 12:10:27 +0000159 tmp.buf = (uint8_t *)&native;
160 tmp.size = sizeof(native);
Lev Walkinf15320b2004-06-03 03:38:44 +0000161
162#else /* Works even if WORDS_BIGENDIAN is not set where should've been */
Lev Walkine0b56e02005-02-25 12:10:27 +0000163 uint8_t buf[sizeof(native)];
Lev Walkinf15320b2004-06-03 03:38:44 +0000164 uint8_t *p;
165
Lev Walkind54f2552004-10-27 13:24:51 +0000166 /* Prepare a fake INTEGER */
Lev Walkine0b56e02005-02-25 12:10:27 +0000167 for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
Lev Walkinf3c089e2007-11-13 23:53:13 +0000168 *p = (uint8_t)native;
Lev Walkinf15320b2004-06-03 03:38:44 +0000169
170 tmp.buf = buf;
171 tmp.size = sizeof(buf);
172#endif /* WORDS_BIGENDIAN */
173
174 /* Encode fake INTEGER */
175 erval = INTEGER_encode_der(sd, &tmp, tag_mode, tag, cb, app_key);
Lev Walkin20696a42017-10-17 21:27:33 -0700176 if(erval.structure_ptr == &tmp) {
177 erval.structure_ptr = ptr;
178 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000179 return erval;
180}
181
Lev Walkin435cb282004-10-21 14:13:48 +0000182/*
183 * Decode the chunk of XML text encoding INTEGER.
184 */
185asn_dec_rval_t
Lev Walkinafbf2a92017-09-12 23:30:27 -0700186NativeInteger_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
Lev Walkin20696a42017-10-17 21:27:33 -0700187 const asn_TYPE_descriptor_t *td, void **sptr,
188 const char *opt_mname, const void *buf_ptr,
189 size_t size) {
Lev Walkind62a6622017-08-22 02:31:02 -0700190 const asn_INTEGER_specifics_t *specs =
191 (const asn_INTEGER_specifics_t *)td->specifics;
192 asn_dec_rval_t rval;
Lev Walkin59b176e2005-11-26 11:25:14 +0000193 INTEGER_t st;
Lev Walkinf0b7c9a2005-01-27 17:54:57 +0000194 void *st_ptr = (void *)&st;
Lev Walkine0b56e02005-02-25 12:10:27 +0000195 long *native = (long *)*sptr;
Lev Walkin435cb282004-10-21 14:13:48 +0000196
Lev Walkine0b56e02005-02-25 12:10:27 +0000197 if(!native) {
Lev Walkin59b176e2005-11-26 11:25:14 +0000198 native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
Lev Walkin7c1dc052016-03-14 03:08:15 -0700199 if(!native) ASN__DECODE_FAILED;
Lev Walkin435cb282004-10-21 14:13:48 +0000200 }
201
Lev Walkin59b176e2005-11-26 11:25:14 +0000202 memset(&st, 0, sizeof(st));
203 rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr,
Lev Walkinf0b7c9a2005-01-27 17:54:57 +0000204 opt_mname, buf_ptr, size);
Lev Walkin435cb282004-10-21 14:13:48 +0000205 if(rval.code == RC_OK) {
206 long l;
Lev Walkin8bb57a22007-12-03 13:41:36 +0000207 if((specs&&specs->field_unsigned)
Lev Walkinaaae9bf2010-10-24 16:56:30 -0700208 ? asn_INTEGER2ulong(&st, (unsigned long *)&l) /* sic */
Lev Walkin8bb57a22007-12-03 13:41:36 +0000209 : asn_INTEGER2long(&st, &l)) {
Lev Walkin435cb282004-10-21 14:13:48 +0000210 rval.code = RC_FAIL;
211 rval.consumed = 0;
212 } else {
Lev Walkine0b56e02005-02-25 12:10:27 +0000213 *native = l;
Lev Walkin435cb282004-10-21 14:13:48 +0000214 }
215 } else {
Lev Walkine0b56e02005-02-25 12:10:27 +0000216 /*
217 * Cannot restart from the middle;
218 * there is no place to save state in the native type.
219 * Request a continuation from the very beginning.
220 */
Lev Walkin435cb282004-10-21 14:13:48 +0000221 rval.consumed = 0;
222 }
Lev Walkinadcb5862006-03-17 02:11:12 +0000223 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &st);
Lev Walkin435cb282004-10-21 14:13:48 +0000224 return rval;
225}
226
227
Lev Walkina9cc46e2004-09-22 16:06:28 +0000228asn_enc_rval_t
Lev Walkin20696a42017-10-17 21:27:33 -0700229NativeInteger_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
230 int ilevel, enum xer_encoder_flags_e flags,
231 asn_app_consume_bytes_f *cb, void *app_key) {
Lev Walkind62a6622017-08-22 02:31:02 -0700232 const asn_INTEGER_specifics_t *specs =
233 (const asn_INTEGER_specifics_t *)td->specifics;
234 char scratch[32]; /* Enough for 64-bit int */
Lev Walkina9cc46e2004-09-22 16:06:28 +0000235 asn_enc_rval_t er;
Lev Walkine0b56e02005-02-25 12:10:27 +0000236 const long *native = (const long *)sptr;
Lev Walkina9cc46e2004-09-22 16:06:28 +0000237
238 (void)ilevel;
239 (void)flags;
240
Lev Walkin7c1dc052016-03-14 03:08:15 -0700241 if(!native) ASN__ENCODE_FAILED;
Lev Walkina9cc46e2004-09-22 16:06:28 +0000242
Lev Walkin8bb57a22007-12-03 13:41:36 +0000243 er.encoded = snprintf(scratch, sizeof(scratch),
244 (specs && specs->field_unsigned)
245 ? "%lu" : "%ld", *native);
Lev Walkina9cc46e2004-09-22 16:06:28 +0000246 if(er.encoded <= 0 || (size_t)er.encoded >= sizeof(scratch)
247 || cb(scratch, er.encoded, app_key) < 0)
Lev Walkin7c1dc052016-03-14 03:08:15 -0700248 ASN__ENCODE_FAILED;
Lev Walkina9cc46e2004-09-22 16:06:28 +0000249
Lev Walkin7c1dc052016-03-14 03:08:15 -0700250 ASN__ENCODED_OK(er);
Lev Walkin59b176e2005-11-26 11:25:14 +0000251}
252
Lev Walkin62d76872017-08-05 22:49:42 -0700253#ifndef ASN_DISABLE_PER_SUPPORT
254
Lev Walkin59b176e2005-11-26 11:25:14 +0000255asn_dec_rval_t
Lev Walkinafbf2a92017-09-12 23:30:27 -0700256NativeInteger_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
Lev Walkin20696a42017-10-17 21:27:33 -0700257 const asn_TYPE_descriptor_t *td,
Lev Walkin494fb702017-08-07 20:07:00 -0700258 const asn_per_constraints_t *constraints, void **sptr,
259 asn_per_data_t *pd) {
Lev Walkind62a6622017-08-22 02:31:02 -0700260 const asn_INTEGER_specifics_t *specs =
261 (const asn_INTEGER_specifics_t *)td->specifics;
262 asn_dec_rval_t rval;
Lev Walkin59b176e2005-11-26 11:25:14 +0000263 long *native = (long *)*sptr;
264 INTEGER_t tmpint;
265 void *tmpintptr = &tmpint;
266
267 (void)opt_codec_ctx;
268 ASN_DEBUG("Decoding NativeInteger %s (UPER)", td->name);
269
270 if(!native) {
271 native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
Lev Walkin7c1dc052016-03-14 03:08:15 -0700272 if(!native) ASN__DECODE_FAILED;
Lev Walkin59b176e2005-11-26 11:25:14 +0000273 }
274
275 memset(&tmpint, 0, sizeof tmpint);
276 rval = INTEGER_decode_uper(opt_codec_ctx, td, constraints,
277 &tmpintptr, pd);
Lev Walkinb2bed822005-11-27 12:40:43 +0000278 if(rval.code == RC_OK) {
Lev Walkin8bb57a22007-12-03 13:41:36 +0000279 if((specs&&specs->field_unsigned)
Lev Walkinaaae9bf2010-10-24 16:56:30 -0700280 ? asn_INTEGER2ulong(&tmpint, (unsigned long *)native)
Lev Walkin8bb57a22007-12-03 13:41:36 +0000281 : asn_INTEGER2long(&tmpint, native))
Lev Walkin59b176e2005-11-26 11:25:14 +0000282 rval.code = RC_FAIL;
283 else
284 ASN_DEBUG("NativeInteger %s got value %ld",
285 td->name, *native);
Lev Walkinb2bed822005-11-27 12:40:43 +0000286 }
Lev Walkinadcb5862006-03-17 02:11:12 +0000287 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
Lev Walkin59b176e2005-11-26 11:25:14 +0000288
289 return rval;
Lev Walkina9cc46e2004-09-22 16:06:28 +0000290}
291
Lev Walkin523de9e2006-08-18 01:34:18 +0000292asn_enc_rval_t
Lev Walkin20696a42017-10-17 21:27:33 -0700293NativeInteger_encode_uper(const asn_TYPE_descriptor_t *td,
294 const asn_per_constraints_t *constraints,
295 const void *sptr, asn_per_outp_t *po) {
Lev Walkind62a6622017-08-22 02:31:02 -0700296 const asn_INTEGER_specifics_t *specs =
297 (const asn_INTEGER_specifics_t *)td->specifics;
298 asn_enc_rval_t er;
Lev Walkin523de9e2006-08-18 01:34:18 +0000299 long native;
300 INTEGER_t tmpint;
301
Lev Walkin7c1dc052016-03-14 03:08:15 -0700302 if(!sptr) ASN__ENCODE_FAILED;
Lev Walkin523de9e2006-08-18 01:34:18 +0000303
Lev Walkin20696a42017-10-17 21:27:33 -0700304 native = *(const long *)sptr;
Lev Walkin523de9e2006-08-18 01:34:18 +0000305
Lev Walkin20696a42017-10-17 21:27:33 -0700306 ASN_DEBUG("Encoding NativeInteger %s %ld (UPER)", td->name, native);
Lev Walkin523de9e2006-08-18 01:34:18 +0000307
308 memset(&tmpint, 0, sizeof(tmpint));
Lev Walkin8bb57a22007-12-03 13:41:36 +0000309 if((specs&&specs->field_unsigned)
310 ? asn_ulong2INTEGER(&tmpint, native)
311 : asn_long2INTEGER(&tmpint, native))
Lev Walkin7c1dc052016-03-14 03:08:15 -0700312 ASN__ENCODE_FAILED;
Lev Walkin523de9e2006-08-18 01:34:18 +0000313 er = INTEGER_encode_uper(td, constraints, &tmpint, po);
314 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
315 return er;
316}
317
Lev Walkin62d76872017-08-05 22:49:42 -0700318#endif /* ASN_DISABLE_PER_SUPPORT */
319
Lev Walkinf15320b2004-06-03 03:38:44 +0000320/*
321 * INTEGER specific human-readable output.
322 */
323int
Lev Walkin20696a42017-10-17 21:27:33 -0700324NativeInteger_print(const asn_TYPE_descriptor_t *td, const void *sptr,
325 int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
Lev Walkind62a6622017-08-22 02:31:02 -0700326 const asn_INTEGER_specifics_t *specs =
327 (const asn_INTEGER_specifics_t *)td->specifics;
328 const long *native = (const long *)sptr;
Lev Walkinef8dd442017-09-18 22:38:03 -0700329 char scratch[32]; /* Enough for 64-bit int */
330 int ret;
Lev Walkinf15320b2004-06-03 03:38:44 +0000331
Lev Walkinef8dd442017-09-18 22:38:03 -0700332 (void)td; /* Unused argument */
333 (void)ilevel; /* Unused argument */
Lev Walkind9bd7752004-06-05 08:17:50 +0000334
Lev Walkinef8dd442017-09-18 22:38:03 -0700335 if(native) {
336 long value = *native;
337 ret = snprintf(scratch, sizeof(scratch),
338 (specs && specs->field_unsigned) ? "%lu" : "%ld", value);
339 assert(ret > 0 && (size_t)ret < sizeof(scratch));
340 if(cb(scratch, ret, app_key) < 0) return -1;
341 if(specs && (value >= 0 || !specs->field_unsigned)) {
342 const asn_INTEGER_enum_map_t *el =
343 INTEGER_map_value2enum(specs, value);
344 if(el) {
345 if(cb(" (", 2, app_key) < 0) return -1;
346 if(cb(el->enum_name, el->enum_len, app_key) < 0) return -1;
347 if(cb(")", 1, app_key) < 0) return -1;
348 }
349 }
350 return 0;
Lev Walkinf15320b2004-06-03 03:38:44 +0000351 } else {
Lev Walkin8e8078a2004-09-26 13:10:40 +0000352 return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
Lev Walkinf15320b2004-06-03 03:38:44 +0000353 }
354}
355
356void
Lev Walkinf6853ce2017-08-11 00:50:27 -0700357NativeInteger_free(const asn_TYPE_descriptor_t *td, void *ptr,
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700358 enum asn_struct_free_method method) {
Lev Walkinf6853ce2017-08-11 00:50:27 -0700359 if(!td || !ptr)
Lev Walkinf15320b2004-06-03 03:38:44 +0000360 return;
361
362 ASN_DEBUG("Freeing %s as INTEGER (%d, %p, Native)",
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700363 td->name, method, ptr);
Lev Walkinf15320b2004-06-03 03:38:44 +0000364
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700365 switch(method) {
366 case ASFM_FREE_EVERYTHING:
367 FREEMEM(ptr);
368 break;
369 case ASFM_FREE_UNDERLYING:
370 break;
371 case ASFM_FREE_UNDERLYING_AND_RESET:
372 memset(ptr, 0, sizeof(long));
373 break;
374 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000375}
376
Lev Walkincd2f48e2017-08-10 02:14:59 -0700377int
378NativeInteger_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const void *bptr) {
379 (void)td;
380
381 if(aptr && bptr) {
382 const asn_INTEGER_specifics_t *specs =
383 (const asn_INTEGER_specifics_t *)td->specifics;
Lev Walkinf6853ce2017-08-11 00:50:27 -0700384 if(specs && specs->field_unsigned) {
Lev Walkincd2f48e2017-08-10 02:14:59 -0700385 const unsigned long *a = aptr;
386 const unsigned long *b = bptr;
387 if(*a < *b) {
388 return -1;
389 } else if(*a > *b) {
390 return 1;
391 } else {
Lev Walkinf6853ce2017-08-11 00:50:27 -0700392 return 0;
Lev Walkincd2f48e2017-08-10 02:14:59 -0700393 }
394 } else {
395 const long *a = aptr;
396 const long *b = bptr;
397 if(*a < *b) {
398 return -1;
399 } else if(*a > *b) {
400 return 1;
401 } else {
Lev Walkinf6853ce2017-08-11 00:50:27 -0700402 return 0;
Lev Walkincd2f48e2017-08-10 02:14:59 -0700403 }
404 }
405 } else if(!aptr) {
406 return -1;
407 } else {
408 return 1;
409 }
410}
Lev Walkina5972be2017-09-29 23:15:58 -0700411
412asn_random_fill_result_t
413NativeInteger_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
414 const asn_encoding_constraints_t *constraints,
415 size_t max_length) {
416 const asn_INTEGER_specifics_t *specs =
417 (const asn_INTEGER_specifics_t *)td->specifics;
418 asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
419 asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
420 asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
421 long *st = *sptr;
422 const asn_INTEGER_enum_map_t *emap;
423 size_t emap_len;
424 intmax_t value;
425 int find_inside_map;
426
427 if(max_length == 0) return result_skipped;
428
429 if(st == NULL) {
430 st = (long *)CALLOC(1, sizeof(*st));
431 if(st == NULL) {
432 return result_failed;
433 }
434 }
435
436 if(specs) {
437 emap = specs->value2enum;
438 emap_len = specs->map_count;
439 if(specs->strict_enumeration) {
440 find_inside_map = emap_len > 0;
441 } else {
442 find_inside_map = emap_len ? asn_random_between(0, 1) : 0;
443 }
444 } else {
445 emap = 0;
446 emap_len = 0;
447 find_inside_map = 0;
448 }
449
450 if(find_inside_map) {
451 assert(emap_len > 0);
452 value = emap[asn_random_between(0, emap_len - 1)].nat_value;
453 } else {
Lev Walkin18741a92017-10-01 12:40:19 -0700454 const asn_per_constraints_t *ct;
Lev Walkina5972be2017-09-29 23:15:58 -0700455
456 static const long variants[] = {
457 -65536, -65535, -65534, -32769, -32768, -32767, -16385, -16384,
458 -16383, -257, -256, -255, -254, -129, -128, -127,
459 -126, -1, 0, 1, 126, 127, 128, 129,
460 254, 255, 256, 257, 16383, 16384, 16385, 32767,
461 32768, 32769, 65534, 65535, 65536, 65537};
462 if(specs && specs->field_unsigned) {
463 assert(variants[18] == 0);
464 value = variants[asn_random_between(
465 18, sizeof(variants) / sizeof(variants[0]) - 1)];
466 } else {
467 value = variants[asn_random_between(
468 0, sizeof(variants) / sizeof(variants[0]) - 1)];
469 }
470
471 if(!constraints) constraints = &td->encoding_constraints;
Lev Walkin18741a92017-10-01 12:40:19 -0700472 ct = constraints ? constraints->per_constraints : 0;
473 if(ct && (ct->value.flags & APC_CONSTRAINED)) {
474 if(value < ct->value.lower_bound || value > ct->value.upper_bound) {
475 value = asn_random_between(ct->value.lower_bound,
476 ct->value.upper_bound);
477 }
478 }
Lev Walkina5972be2017-09-29 23:15:58 -0700479 }
480
Lev Walkinb5186682017-09-30 19:32:13 -0700481 *sptr = st;
Lev Walkina5972be2017-09-29 23:15:58 -0700482 *st = value;
483 return result_ok;
484}