asn_enc_rval_t BIT_STRING_encode_xer(Allocator * allocator, asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { asn_enc_rval_t er; char scratch[128]; char *p = scratch; char *scend = scratch + (sizeof(scratch) - 10); const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; int xcan = (flags & XER_F_CANONICAL); uint8_t *buf; uint8_t *end; if(!st || !st->buf) _ASN_ENCODE_FAILED; er.encoded = 0; buf = st->buf; end = buf + st->size - 1; /* Last byte is special */ /* * Binary dump */ for(; buf < end; buf++) { int v = *buf; int nline = xcan?0:(((buf - st->buf) % 8) == 0); if(p >= scend || nline) { er.encoded += p - scratch; _ASN_CALLBACK(allocator, scratch, p - scratch); p = scratch; if(nline) _i_ASN_TEXT_INDENT(allocator, 1, ilevel); } memcpy(p + 0, _bit_pattern[v >> 4], 4); memcpy(p + 4, _bit_pattern[v & 0x0f], 4); p += 8; } if(!xcan && ((buf - st->buf) % 8) == 0) _i_ASN_TEXT_INDENT(allocator,1, ilevel); er.encoded += p - scratch; _ASN_CALLBACK(allocator, scratch, p - scratch); p = scratch; if(buf == end) { int v = *buf; int ubits = st->bits_unused; int i; for(i = 7; i >= ubits; i--) *p++ = (v & (1 << i)) ? 0x31 : 0x30; er.encoded += p - scratch; _ASN_CALLBACK(allocator, scratch, p - scratch); } if(!xcan) _i_ASN_TEXT_INDENT(allocator, 1, ilevel - 1); _ASN_ENCODED_OK(er); cb_failed: _ASN_ENCODE_FAILED; }
asn_enc_rval_t OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { static const char *h2c = "0123456789ABCDEF"; const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; asn_enc_rval_t er; char scratch[16 * 3 + 4]; char *p = scratch; uint8_t *buf; uint8_t *end; size_t i; if(!st || (!st->buf && st->size)) _ASN_ENCODE_FAILED; er.encoded = 0; /* * Dump the contents of the buffer in hexadecimal. */ buf = st->buf; end = buf + st->size; if(flags & XER_F_CANONICAL) { char *scend = scratch + (sizeof(scratch) - 2); for(; buf < end; buf++) { if(p >= scend) { _ASN_CALLBACK(scratch, p - scratch); er.encoded += p - scratch; p = scratch; } *p++ = h2c[(*buf >> 4) & 0x0F]; *p++ = h2c[*buf & 0x0F]; } _ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */ er.encoded += p - scratch; } else {
asn_enc_rval_t BOOLEAN_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { const BOOLEAN_t *st = (const BOOLEAN_t *)sptr; asn_enc_rval_t er; (void)ilevel; (void)flags; if(!st) _ASN_ENCODE_FAILED; if(*st) { _ASN_CALLBACK("<true/>", 7); er.encoded = 7; } else { _ASN_CALLBACK("<false/>", 8); er.encoded = 8; } _ASN_ENCODED_OK(er); cb_failed: _ASN_ENCODE_FAILED; }
asn_enc_rval_t SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { asn_enc_rval_t er; asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics; asn_TYPE_member_t *elm = td->elements; asn_anonymous_set_ *list = _A_SET_FROM_VOID(sptr); const char *mname = specs->as_XMLValueList ? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag); size_t mlen = mname ? strlen(mname) : 0; int xcan = (flags & XER_F_CANONICAL); xer_tmp_enc_t *encs = 0; size_t encs_count = 0; void *original_app_key = app_key; asn_app_consume_bytes_f *original_cb = cb; int i; if(!sptr) _ASN_ENCODE_FAILED; if(xcan) { encs = (xer_tmp_enc_t *)MALLOC(list->count * sizeof(encs[0])); if(!encs) _ASN_ENCODE_FAILED; cb = SET_OF_encode_xer_callback; } er.encoded = 0; for(i = 0; i < list->count; i++) { asn_enc_rval_t tmper; void *memb_ptr = list->array[i]; if(!memb_ptr) continue; if(encs) { memset(&encs[encs_count], 0, sizeof(encs[0])); app_key = &encs[encs_count]; encs_count++; } if(mname) { if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel); _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1); } if(!xcan && specs->as_XMLValueList == 1) _i_ASN_TEXT_INDENT(1, ilevel + 1); tmper = elm->type->xer_encoder(elm->type, memb_ptr, ilevel + (specs->as_XMLValueList != 2), flags, cb, app_key); if(tmper.encoded == -1) { td = tmper.failed_type; sptr = tmper.structure_ptr; goto cb_failed; } if(tmper.encoded == 0 && specs->as_XMLValueList) { const char *name = elm->type->xml_tag; size_t len = strlen(name); _ASN_CALLBACK3("<", 1, name, len, "/>", 2); } if(mname) { _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1); er.encoded += 5; } er.encoded += (2 * mlen) + tmper.encoded; } if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1); if(encs) { xer_tmp_enc_t *enc = encs; xer_tmp_enc_t *end = encs + encs_count; ssize_t control_size = 0; cb = original_cb; app_key = original_app_key; qsort(encs, encs_count, sizeof(encs[0]), SET_OF_xer_order); for(; enc < end; enc++) { _ASN_CALLBACK(enc->buffer, enc->offset); FREEMEM(enc->buffer); enc->buffer = 0; control_size += enc->offset; } assert(control_size == er.encoded); } goto cleanup; cb_failed: er.encoded = -1; er.failed_type = td; er.structure_ptr = sptr; cleanup: if(encs) { while(encs_count-- > 0) { if(encs[encs_count].buffer) FREEMEM(encs[encs_count].buffer); } FREEMEM(encs); } _ASN_ENCODED_OK(er); }
/* * Encode OCTET STRING type using DER. */ asn_enc_rval_t OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr, int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) { asn_enc_rval_t er; asn_OCTET_STRING_specifics_t *specs = td->specifics ? (asn_OCTET_STRING_specifics_t *)td->specifics : &asn_DEF_OCTET_STRING_specs; BIT_STRING_t *st = (BIT_STRING_t *)sptr; enum asn_OS_Subvariant type_variant = specs->subvariant; int fix_last_byte = 0; ASN_DEBUG("%s %s as OCTET STRING", cb?"Estimating":"Encoding", td->name); /* * Write tags. */ if(type_variant != ASN_OSUBV_ANY || tag_mode == 1) { er.encoded = der_write_tags(td, (type_variant == ASN_OSUBV_BIT) + st->size, tag_mode, type_variant == ASN_OSUBV_ANY, tag, cb, app_key); if(er.encoded == -1) { er.failed_type = td; er.structure_ptr = sptr; return er; } } else { /* Disallow: [<tag>] IMPLICIT ANY */ assert(type_variant != ASN_OSUBV_ANY || tag_mode != -1); er.encoded = 0; } if(!cb) { er.encoded += (type_variant == ASN_OSUBV_BIT) + st->size; _ASN_ENCODED_OK(er); } /* * Prepare to deal with the last octet of BIT STRING. */ if(type_variant == ASN_OSUBV_BIT) { uint8_t b = st->bits_unused & 0x07; if(b && st->size) fix_last_byte = 1; _ASN_CALLBACK(&b, 1); er.encoded++; } /* Invoke callback for the main part of the buffer */ _ASN_CALLBACK(st->buf, st->size - fix_last_byte); /* The last octet should be stripped off the unused bits */ if(fix_last_byte) { uint8_t b = st->buf[st->size-1] & (0xff << st->bits_unused); _ASN_CALLBACK(&b, 1); } er.encoded += st->size; _ASN_ENCODED_OK(er); cb_failed: _ASN_ENCODE_FAILED; }