2 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
4 * Redistribution and modifications are permitted subject to BSD license.
6 #include <asn_internal.h>
7 #include <NativeInteger.h>
11 * Decode INTEGER type.
14 NativeInteger_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
15 const asn_TYPE_descriptor_t *td, void **nint_ptr,
16 const void *buf_ptr, size_t size, int tag_mode) {
17 const asn_INTEGER_specifics_t *specs =
18 (const asn_INTEGER_specifics_t *)td->specifics;
19 long *native = (long *)*nint_ptr;
24 * If the structure is not there, allocate it.
27 native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
35 ASN_DEBUG("Decoding %s as INTEGER (tm=%d)",
41 rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
42 tag_mode, 0, &length, 0);
43 if(rval.code != RC_OK)
46 ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
49 * Make sure we have this length.
51 buf_ptr = ((const char *)buf_ptr) + rval.consumed;
52 size -= rval.consumed;
53 if(length > (ber_tlv_len_t)size) {
60 * ASN.1 encoded INTEGER: buf_ptr, length
61 * Fill the native, at the same time checking for overflow.
62 * If overflow occurred, return with RC_FAIL.
72 unconst_buf.constbuf = buf_ptr;
73 tmp.buf = (uint8_t *)unconst_buf.nonconstbuf;
76 if((specs&&specs->field_unsigned)
77 ? asn_INTEGER2ulong(&tmp, (unsigned long *)&l) /* sic */
78 : asn_INTEGER2long(&tmp, &l)) {
88 rval.consumed += length;
90 ASN_DEBUG("Took %ld/%ld bytes to encode %s (%ld)",
91 (long)rval.consumed, (long)length, td->name, (long)*native);
97 * Encode the NativeInteger using the standard INTEGER type DER encoder.
100 NativeInteger_encode_der(const asn_TYPE_descriptor_t *sd, const void *ptr,
101 int tag_mode, ber_tlv_tag_t tag,
102 asn_app_consume_bytes_f *cb, void *app_key) {
103 unsigned long native = *(const unsigned long *)ptr; /* Disable sign ext. */
104 asn_enc_rval_t erval = {0,0,0};
107 #ifdef WORDS_BIGENDIAN /* Opportunistic optimization */
109 tmp.buf = (uint8_t *)&native;
110 tmp.size = sizeof(native);
112 #else /* Works even if WORDS_BIGENDIAN is not set where should've been */
113 uint8_t buf[sizeof(native)];
116 /* Prepare a fake INTEGER */
117 for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
118 *p = (uint8_t)native;
121 tmp.size = sizeof(buf);
122 #endif /* WORDS_BIGENDIAN */
124 /* Encode fake INTEGER */
125 erval = INTEGER_encode_der(sd, &tmp, tag_mode, tag, cb, app_key);
126 if(erval.structure_ptr == &tmp) {
127 erval.structure_ptr = ptr;