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 <asn_codecs_prim.h>
10 * Decode an always-primitive type.
13 ber_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx,
14 const asn_TYPE_descriptor_t *td, void **sptr,
15 const void *buf_ptr, size_t size, int tag_mode) {
16 ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr;
18 ber_tlv_len_t length = 0; /* =0 to avoid [incorrect] warning. */
21 * If the structure is not there, allocate it.
24 st = (ASN__PRIMITIVE_TYPE_t *)CALLOC(1, sizeof(*st));
25 if(st == NULL) ASN__DECODE_FAILED;
29 ASN_DEBUG("Decoding %s as plain primitive (tm=%d)",
33 * Check tags and extract value length.
35 rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
36 tag_mode, 0, &length, 0);
37 if(rval.code != RC_OK)
40 ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
43 * Make sure we have this length.
45 buf_ptr = ((const char *)buf_ptr) + rval.consumed;
46 size -= rval.consumed;
47 if(length > (ber_tlv_len_t)size) {
53 st->size = (int)length;
54 /* The following better be optimized away. */
55 if(sizeof(st->size) != sizeof(length)
56 && (ber_tlv_len_t)st->size != length) {
61 st->buf = (uint8_t *)MALLOC(length + 1);
67 memcpy(st->buf, buf_ptr, length);
68 st->buf[length] = '\0'; /* Just in case */
71 rval.consumed += length;
73 ASN_DEBUG("Took %ld/%ld bytes to encode %s",
75 (long)length, td->name);
81 * Encode an always-primitive type using DER.
84 der_encode_primitive(const asn_TYPE_descriptor_t *td, const void *sptr,
85 int tag_mode, ber_tlv_tag_t tag,
86 asn_app_consume_bytes_f *cb, void *app_key) {
87 asn_enc_rval_t erval = {0,0,0};
88 const ASN__PRIMITIVE_TYPE_t *st = (const ASN__PRIMITIVE_TYPE_t *)sptr;
90 ASN_DEBUG("%s %s as a primitive type (tm=%d)",
91 cb?"Encoding":"Estimating", td->name, tag_mode);
93 erval.encoded = der_write_tags(td, st->size, tag_mode, 0, tag,
95 ASN_DEBUG("%s wrote tags %d", td->name, (int)erval.encoded);
96 if(erval.encoded == -1) {
97 erval.failed_type = td;
98 erval.structure_ptr = sptr;
103 if(cb(st->buf, st->size, app_key) < 0) {
105 erval.failed_type = td;
106 erval.structure_ptr = sptr;
110 assert(st->buf || st->size == 0);
113 erval.encoded += st->size;
114 ASN__ENCODED_OK(erval);