Commit 4fe28822 authored by Lev Walkin's avatar Lev Walkin

ensure xer encode yields the same number of bytes as it sends to the callback

parent 7489807a
......@@ -117,7 +117,6 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
int v = *buf;
int nline = xcan?0:(((buf - st->buf) % 8) == 0);
if(p >= scend || nline) {
er.encoded += p - scratch;
ASN__CALLBACK(scratch, p - scratch);
p = scratch;
if(nline) ASN__TEXT_INDENT(1, ilevel);
......@@ -129,7 +128,6 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
if(!xcan && ((buf - st->buf) % 8) == 0)
ASN__TEXT_INDENT(1, ilevel);
er.encoded += p - scratch;
ASN__CALLBACK(scratch, p - scratch);
p = scratch;
......@@ -139,7 +137,6 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
int i;
for(i = 7; i >= ubits; i--)
*p++ = (v & (1 << i)) ? 0x31 : 0x30;
er.encoded += p - scratch;
ASN__CALLBACK(scratch, p - scratch);
}
......
......@@ -198,7 +198,7 @@ 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;
asn_enc_rval_t er = {0, 0, 0};
(void)ilevel;
(void)flags;
......@@ -207,10 +207,8 @@ BOOLEAN_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
if(*st) {
ASN__CALLBACK("<true/>", 7);
er.encoded = 7;
} else {
ASN__CALLBACK("<false/>", 8);
er.encoded = 8;
}
ASN__ENCODED_OK(er);
......
......@@ -578,7 +578,6 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
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 */
......@@ -590,7 +589,6 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
ASN__CALLBACK(&b, 1);
}
er.encoded += st->size;
ASN__ENCODED_OK(er);
cb_failed:
ASN__ENCODE_FAILED;
......@@ -624,7 +622,6 @@ OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
for(; buf < end; buf++) {
if(p >= scend) {
ASN__CALLBACK(scratch, p - scratch);
er.encoded += p - scratch;
p = scratch;
}
*p++ = h2c[(*buf >> 4) & 0x0F];
......@@ -632,12 +629,10 @@ OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
}
ASN__CALLBACK(scratch, p-scratch); /* Dump the rest */
er.encoded += p - scratch;
} else {
for(i = 0; buf < end; buf++, i++) {
if(!(i % 16) && (i || st->size > 16)) {
ASN__CALLBACK(scratch, p-scratch);
er.encoded += (p-scratch);
p = scratch;
ASN__TEXT_INDENT(1, ilevel);
}
......@@ -648,7 +643,6 @@ OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
if(p - scratch) {
p--; /* Remove the tail space */
ASN__CALLBACK(scratch, p-scratch); /* Dump the rest */
er.encoded += p - scratch;
if(st->size > 16)
ASN__TEXT_INDENT(1, ilevel-1);
}
......
......@@ -70,28 +70,29 @@ static void ASN_DEBUG(const char *fmt, ...) { (void)fmt; }
/*
* Invoke the application-supplied callback and fail, if something is wrong.
*/
#define ASN__E_cbc(buf, size) (cb((buf), (size), app_key) < 0)
#define ASN__E_CALLBACK(foo) do { \
if(foo) goto cb_failed; \
} while(0)
#define ASN__CALLBACK(buf, size) \
ASN__E_CALLBACK(ASN__E_cbc(buf, size))
#define ASN__CALLBACK2(buf1, size1, buf2, size2) \
ASN__E_CALLBACK(ASN__E_cbc(buf1, size1) || ASN__E_cbc(buf2, size2))
#define ASN__CALLBACK3(buf1, size1, buf2, size2, buf3, size3) \
ASN__E_CALLBACK(ASN__E_cbc(buf1, size1) \
|| ASN__E_cbc(buf2, size2) \
|| ASN__E_cbc(buf3, size3))
#define ASN__E_cbc(buf, size) (cb((buf), (size), app_key) < 0)
#define ASN__E_CALLBACK(size, foo) \
do { \
if(foo) goto cb_failed; \
er.encoded += (size); \
} while(0)
#define ASN__CALLBACK(buf, size) ASN__E_CALLBACK(size, ASN__E_cbc(buf, size))
#define ASN__CALLBACK2(buf1, size1, buf2, size2) \
ASN__E_CALLBACK((size1) + (size2), \
ASN__E_cbc(buf1, size1) || ASN__E_cbc(buf2, size2))
#define ASN__CALLBACK3(buf1, size1, buf2, size2, buf3, size3) \
ASN__E_CALLBACK((size1) + (size2) + (size3), \
ASN__E_cbc(buf1, size1) || ASN__E_cbc(buf2, size2) \
|| ASN__E_cbc(buf3, size3))
#define ASN__TEXT_INDENT(nl, level) do { \
int tmp_level = (level); \
int tmp_nl = ((nl) != 0); \
int tmp_i; \
if(tmp_nl) ASN__CALLBACK("\n", 1); \
if(tmp_level < 0) tmp_level = 0; \
for(tmp_i = 0; tmp_i < tmp_level; tmp_i++) \
ASN__CALLBACK(" ", 4); \
er.encoded += tmp_nl + 4 * tmp_level; \
#define ASN__TEXT_INDENT(nl, level) \
do { \
int tmp_level = (level); \
int tmp_nl = ((nl) != 0); \
int tmp_i; \
if(tmp_nl) ASN__CALLBACK("\n", 1); \
if(tmp_level < 0) tmp_level = 0; \
for(tmp_i = 0; tmp_i < tmp_level; tmp_i++) ASN__CALLBACK(" ", 4); \
} while(0)
#define _i_INDENT(nl) do { \
......
......@@ -810,16 +810,15 @@ CHOICE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = 0;
if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel);
if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel);
ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
tmper = elm->type->op->xer_encoder(elm->type, memb_ptr,
ilevel + 1, flags, cb, app_key);
if(tmper.encoded == -1) return tmper;
er.encoded += tmper.encoded;
ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
er.encoded += 5 + (2 * mlen) + tmper.encoded;
}
if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel - 1);
......
......@@ -929,9 +929,9 @@ SEQUENCE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel,
tmp_def_val = 0;
}
if(tmper.encoded == -1) return tmper;
er.encoded += tmper.encoded;
ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
er.encoded += 5 + (2 * mlen) + tmper.encoded;
}
if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
......
......@@ -88,56 +88,55 @@ SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
}
asn_enc_rval_t
SEQUENCE_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_sequence_ *list = _A_SEQUENCE_FROM_VOID(sptr);
const char *mname = specs->as_XMLValueList
? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag);
unsigned int mlen = mname ? strlen(mname) : 0;
int xcan = (flags & XER_F_CANONICAL);
int i;
if(!sptr) ASN__ENCODE_FAILED;
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(mname) {
if(!xcan) ASN__TEXT_INDENT(1, ilevel);
ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
}
tmper = elm->type->op->xer_encoder(elm->type, memb_ptr,
ilevel + 1, flags, cb, app_key);
if(tmper.encoded == -1) return tmper;
if(tmper.encoded == 0 && specs->as_XMLValueList) {
const char *name = elm->type->xml_tag;
size_t len = strlen(name);
if(!xcan) ASN__TEXT_INDENT(1, ilevel + 1);
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) ASN__TEXT_INDENT(1, ilevel - 1);
ASN__ENCODED_OK(er);
SEQUENCE_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_sequence_ *list = _A_SEQUENCE_FROM_VOID(sptr);
const char *mname = specs->as_XMLValueList
? 0
: ((*elm->name) ? elm->name : elm->type->xml_tag);
unsigned int mlen = mname ? strlen(mname) : 0;
int xcan = (flags & XER_F_CANONICAL);
int i;
if(!sptr) ASN__ENCODE_FAILED;
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(mname) {
if(!xcan) ASN__TEXT_INDENT(1, ilevel);
ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
}
tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + 1,
flags, cb, app_key);
if(tmper.encoded == -1) return tmper;
er.encoded += tmper.encoded;
if(tmper.encoded == 0 && specs->as_XMLValueList) {
const char *name = elm->type->xml_tag;
size_t len = strlen(name);
if(!xcan) ASN__TEXT_INDENT(1, ilevel + 1);
ASN__CALLBACK3("<", 1, name, len, "/>", 2);
}
if(mname) {
ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
}
}
if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
ASN__ENCODED_OK(er);
cb_failed:
ASN__ENCODE_FAILED;
ASN__ENCODE_FAILED;
}
asn_enc_rval_t
......
......@@ -869,10 +869,9 @@ SET_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
tmper = elm->type->op->xer_encoder(elm->type, memb_ptr,
ilevel + 1, flags, cb, app_key);
if(tmper.encoded == -1) return tmper;
er.encoded += tmper.encoded;
ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
er.encoded += 5 + (2 * mlen) + tmper.encoded;
}
if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
......
......@@ -700,11 +700,8 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
tmper = elm->type->op->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 == -1) return tmper;
er.encoded += tmper.encoded;
if(tmper.encoded == 0 && specs->as_XMLValueList) {
const char *name = elm->type->xml_tag;
size_t len = strlen(name);
......@@ -713,10 +710,8 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
if(mname) {
ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
er.encoded += 5;
}
er.encoded += (2 * mlen) + tmper.encoded;
}
if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
......@@ -726,6 +721,7 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
xer_tmp_enc_t *end = encs + encs_count;
ssize_t control_size = 0;
er.encoded = 0;
cb = original_cb;
app_key = original_app_key;
qsort(encs, encs_count, sizeof(encs[0]), SET_OF_xer_order);
......@@ -741,9 +737,7 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
goto cleanup;
cb_failed:
er.encoded = -1;
er.failed_type = td;
er.structure_ptr = sptr;
ASN__ENCODE_FAILED;
cleanup:
if(encs) {
size_t n;
......
......@@ -13,7 +13,8 @@ asn_enc_rval_t
xer_encode(asn_TYPE_descriptor_t *td, void *sptr,
enum xer_encoder_flags_e xer_flags,
asn_app_consume_bytes_f *cb, void *app_key) {
asn_enc_rval_t er, tmper;
asn_enc_rval_t er = {0, 0, 0};
asn_enc_rval_t tmper;
const char *mname;
size_t mlen;
int xcan = (xer_flags & XER_F_CANONICAL) ? 1 : 2;
......@@ -27,11 +28,10 @@ xer_encode(asn_TYPE_descriptor_t *td, void *sptr,
tmper = td->op->xer_encoder(td, sptr, 1, xer_flags, cb, app_key);
if(tmper.encoded == -1) return tmper;
er.encoded += tmper.encoded;
ASN__CALLBACK3("</", 2, mname, mlen, ">\n", xcan);
er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded;
ASN__ENCODED_OK(er);
cb_failed:
ASN__ENCODE_FAILED;
......
......@@ -74,7 +74,7 @@ save_object_as(PDU_t *st, enum asn_transfer_syntax syntax) {
fprintf(stderr, "SAVED OBJECT IN SIZE %d/%zd\n", buf_offset, rval.encoded);
// assert(buf_offset == rval.encoded);
assert(buf_offset == rval.encoded);
}
static PDU_t *
......
......@@ -66,9 +66,9 @@ save_object_as(PDU_t *st, enum asn_transfer_syntax syntax) {
return;
}
fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset);
fprintf(stderr, "SAVED OBJECT IN SIZE %d/%zu\n", buf_offset, rval.encoded);
// assert(buf_offset == rval.encoded);
assert(buf_offset == rval.encoded);
}
static PDU_t *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment