Commit cc6a910a authored by Lev Walkin's avatar Lev Walkin

pretty-printing

parent 06b8d7aa
...@@ -29,16 +29,15 @@ ANY_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, ...@@ -29,16 +29,15 @@ ANY_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
int ilevel, enum xer_encoder_flags_e flags, int ilevel, enum xer_encoder_flags_e flags,
asn_app_consume_bytes_f *cb, void *app_key) { asn_app_consume_bytes_f *cb, void *app_key) {
(void)ilevel; if(flags & XER_F_CANONICAL) {
(void)flags; /*
(void)cb; * Canonical XER-encoding of ANY type is not supported.
(void)app_key; */
_ASN_ENCODE_FAILED;
/* }
* XER-encoding of ANY type is not supported.
*/
_ASN_ENCODE_FAILED; /* Dump as binary */
return OCTET_STRING_encode_xer(td, sptr, ilevel, flags, cb, app_key);
} }
struct _callback_arg { struct _callback_arg {
......
...@@ -78,6 +78,7 @@ BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, ...@@ -78,6 +78,7 @@ BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
char *p = scratch; char *p = scratch;
char *scend = scratch + (sizeof(scratch) - 10); char *scend = scratch + (sizeof(scratch) - 10);
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
int xcan = (flags & XER_F_CANONICAL);
uint8_t *buf; uint8_t *buf;
uint8_t *end; uint8_t *end;
...@@ -94,8 +95,7 @@ BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, ...@@ -94,8 +95,7 @@ BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
*/ */
for(buf++; buf < end; buf++) { for(buf++; buf < end; buf++) {
int v = *buf; int v = *buf;
int nline = (flags & XER_F_CANONICAL) int nline = xcan?0:((((buf - st->buf) - 1) % 8) == 0);
?0:((((buf - st->buf) - 1) % 16) == 0);
if(p >= scend || nline) { if(p >= scend || nline) {
er.encoded += p - scratch; er.encoded += p - scratch;
_ASN_CALLBACK(scratch, p - scratch); _ASN_CALLBACK(scratch, p - scratch);
...@@ -108,7 +108,8 @@ BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, ...@@ -108,7 +108,8 @@ BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
} }
er.encoded += p - scratch; er.encoded += p - scratch;
_ASN_CALLBACK(scratch, p - scratch); if(!xcan && (((buf - st->buf) - 1) % 8) == 0)
_i_ASN_TEXT_INDENT(1, ilevel);
if(buf < end + 1) { if(buf < end + 1) {
int v = *buf; int v = *buf;
...@@ -120,6 +121,9 @@ BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, ...@@ -120,6 +121,9 @@ BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
_ASN_CALLBACK(scratch, p - scratch); _ASN_CALLBACK(scratch, p - scratch);
} }
if(!xcan && ((st->size - 1) % 8) == 0)
_i_ASN_TEXT_INDENT(1, ilevel - 1);
return er; return er;
} }
...@@ -149,7 +153,8 @@ BIT_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel, ...@@ -149,7 +153,8 @@ BIT_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
* Hexadecimal dump. * Hexadecimal dump.
*/ */
for(buf++; buf < end; buf++) { for(buf++; buf < end; buf++) {
if(((buf - st->buf) - 1) % 16 == 0 && (st->size > 16)) { if(((buf - st->buf) - 1) % 16 == 0 && (st->size > 17)
&& buf != st->buf+1) {
int i; int i;
/* Indentation */ /* Indentation */
if(cb("\n", 1, app_key)) return -1; if(cb("\n", 1, app_key)) return -1;
...@@ -162,9 +167,21 @@ BIT_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel, ...@@ -162,9 +167,21 @@ BIT_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
*p++ = h2c[*buf & 0x0F]; *p++ = h2c[*buf & 0x0F];
*p++ = 0x20; *p++ = 0x20;
} }
if(p > scratch) p--; /* Eat the tailing space */
/* Dump the incomplete 16-bytes row */ if(p > scratch) {
return cb(scratch, p - scratch, app_key); p--; /* Eat the tailing space */
if((st->size > 17)) {
int i;
if(cb("\n", 1, app_key)) return -1;
for(i = 0; i < ilevel; i++) cb(" ", 1, app_key);
}
/* Dump the incomplete 16-bytes row */
if(cb(scratch, p - scratch, app_key))
return -1;
}
return 0;
} }
...@@ -34,6 +34,9 @@ asn1_TYPE_descriptor_t asn1_DEF_OCTET_STRING = { ...@@ -34,6 +34,9 @@ asn1_TYPE_descriptor_t asn1_DEF_OCTET_STRING = {
0 /* No specifics */ 0 /* No specifics */
}; };
#undef _CH_PHASE
#undef NEXT_PHASE
#undef PREV_PHASE
#define _CH_PHASE(ctx, inc) do { \ #define _CH_PHASE(ctx, inc) do { \
if(ctx->phase == 0) \ if(ctx->phase == 0) \
ctx->step = 0; \ ctx->step = 0; \
...@@ -42,6 +45,7 @@ asn1_TYPE_descriptor_t asn1_DEF_OCTET_STRING = { ...@@ -42,6 +45,7 @@ asn1_TYPE_descriptor_t asn1_DEF_OCTET_STRING = {
#define NEXT_PHASE(ctx) _CH_PHASE(ctx, +1) #define NEXT_PHASE(ctx) _CH_PHASE(ctx, +1)
#define PREV_PHASE(ctx) _CH_PHASE(ctx, -1) #define PREV_PHASE(ctx) _CH_PHASE(ctx, -1)
#undef ADVANCE
#define ADVANCE(num_bytes) do { \ #define ADVANCE(num_bytes) do { \
size_t num = num_bytes; \ size_t num = num_bytes; \
buf_ptr = ((char *)buf_ptr) + num; \ buf_ptr = ((char *)buf_ptr) + num; \
...@@ -49,12 +53,14 @@ asn1_TYPE_descriptor_t asn1_DEF_OCTET_STRING = { ...@@ -49,12 +53,14 @@ asn1_TYPE_descriptor_t asn1_DEF_OCTET_STRING = {
consumed_myself += num; \ consumed_myself += num; \
} while(0) } while(0)
#undef RETURN
#define RETURN(_code) do { \ #define RETURN(_code) do { \
rval.code = _code; \ rval.code = _code; \
rval.consumed = consumed_myself;\ rval.consumed = consumed_myself;\
return rval; \ return rval; \
} while(0) } while(0)
#undef APPEND
#define APPEND(bufptr, bufsize) do { \ #define APPEND(bufptr, bufsize) do { \
size_t _bs = (bufsize); \ size_t _bs = (bufsize); \
size_t _ns = ctx->step; /* Allocated */ \ size_t _ns = ctx->step; /* Allocated */ \
...@@ -161,8 +167,10 @@ OCTET_STRING_decode_ber(asn1_TYPE_descriptor_t *td, ...@@ -161,8 +167,10 @@ OCTET_STRING_decode_ber(asn1_TYPE_descriptor_t *td,
} type_type } type_type
= (enum type_type_e)(int)td->specifics; /* An ugly hack */ = (enum type_type_e)(int)td->specifics; /* An ugly hack */
ASN_DEBUG("Decoding %s as %s (%ld)", ASN_DEBUG("Decoding %s as %s (frame %ld)",
td->name, "OCTET STRING", (long)size); td->name,
(type_type == _TT_GENERIC) ? "OCTET STRING" : "OS-SpecialCase",
(long)size);
/* /*
* Create the string if does not exist. * Create the string if does not exist.
...@@ -188,8 +196,8 @@ OCTET_STRING_decode_ber(asn1_TYPE_descriptor_t *td, ...@@ -188,8 +196,8 @@ OCTET_STRING_decode_ber(asn1_TYPE_descriptor_t *td,
RETURN(rval.code); RETURN(rval.code);
} }
ASN_DEBUG("OS length is %d bytes, form %d", ASN_DEBUG("OS length is %d bytes, form %d (consumed %d==0)",
(int)ctx->left, tlv_constr); (int)ctx->left, tlv_constr, rval.consumed);
if(tlv_constr) { if(tlv_constr) {
/* /*
...@@ -198,18 +206,6 @@ OCTET_STRING_decode_ber(asn1_TYPE_descriptor_t *td, ...@@ -198,18 +206,6 @@ OCTET_STRING_decode_ber(asn1_TYPE_descriptor_t *td,
ctx->ptr = _new_stack(); ctx->ptr = _new_stack();
if(ctx->ptr) { if(ctx->ptr) {
(void *)stck = ctx->ptr; (void *)stck = ctx->ptr;
#if 0
if(ctx->left < 0) {
stck->cur_ptr->want_nulls = -ctx->left;
stck->cur_ptr->left = -1;
} else {
stck->cur_ptr->want_nulls = 0;
stck->cur_ptr->left = ctx->left;
}
ASN_DEBUG("+EXPECT1 left=%d wn=%d",
stck->cur_ptr->left,
stck->cur_ptr->want_nulls);
#endif
if(type_type == _TT_BIT_STRING) { if(type_type == _TT_BIT_STRING) {
/* Number of meaningless tail bits */ /* Number of meaningless tail bits */
APPEND("\0", 1); APPEND("\0", 1);
...@@ -555,6 +551,9 @@ OCTET_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, ...@@ -555,6 +551,9 @@ OCTET_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
*p++ = h2c[(*buf >> 4) & 0x0F]; *p++ = h2c[(*buf >> 4) & 0x0F];
*p++ = h2c[*buf & 0x0F]; *p++ = h2c[*buf & 0x0F];
} }
_ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */
er.encoded += p - scratch;
} else { } else {
for(i = 0; buf < end; buf++, i++) { for(i = 0; buf < end; buf++, i++) {
if(!(i % 16) && (i || st->size > 16)) { if(!(i % 16) && (i || st->size > 16)) {
...@@ -567,12 +566,15 @@ OCTET_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, ...@@ -567,12 +566,15 @@ OCTET_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
*p++ = h2c[*buf & 0x0F]; *p++ = h2c[*buf & 0x0F];
*p++ = 0x20; *p++ = 0x20;
} }
if(i) p--; /* Remove the tail space */ if(p - scratch) {
p--; /* Remove the tail space */
_ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */
er.encoded += p - scratch;
if(st->size > 16)
_i_ASN_TEXT_INDENT(1, ilevel-1);
}
} }
_ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */
er.encoded += p - scratch;
return er; return er;
} }
...@@ -629,9 +631,14 @@ OCTET_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel, ...@@ -629,9 +631,14 @@ OCTET_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
*p++ = h2c[*buf & 0x0F]; *p++ = h2c[*buf & 0x0F];
*p++ = 0x20; *p++ = 0x20;
} }
if(i) p--; /* Remove the tail space */
return cb(scratch, p - scratch, app_key); if(p > scratch) {
p--; /* Remove the tail space */
if(cb(scratch, p - scratch, app_key))
return -1;
}
return 0;
} }
int int
......
...@@ -6,13 +6,16 @@ ...@@ -6,13 +6,16 @@
#include <constr_TYPE.h> #include <constr_TYPE.h>
#include <assert.h> #include <assert.h>
#undef ADVANCE
#define ADVANCE(num_bytes) do { \ #define ADVANCE(num_bytes) do { \
size_t num = num_bytes; \ size_t num = num_bytes; \
ptr = ((char *)ptr) + num; \ ptr = ((char *)ptr) + num; \
size -= num; \ size -= num; \
consumed_myself += num; \ consumed_myself += num; \
} while(0) } while(0)
#undef RETURN
#define RETURN(_code) do { \ #define RETURN(_code) do { \
fprintf(stderr, "-----%d", __LINE__); \
ber_dec_rval_t rval; \ ber_dec_rval_t rval; \
rval.code = _code; \ rval.code = _code; \
rval.consumed = consumed_myself; \ rval.consumed = consumed_myself; \
...@@ -100,6 +103,7 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx, ...@@ -100,6 +103,7 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx,
case -1: RETURN(RC_FAIL); case -1: RETURN(RC_FAIL);
case 0: RETURN(RC_WMORE); case 0: RETURN(RC_WMORE);
} }
ADVANCE(tag_len + len_len);
} else { } else {
assert(tagno < td->tags_count); /* At least one loop */ assert(tagno < td->tags_count); /* At least one loop */
} }
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
* This macro "eats" the part of the buffer which is definitely "consumed", * This macro "eats" the part of the buffer which is definitely "consumed",
* i.e. was correctly converted into local representation or rightfully skipped. * i.e. was correctly converted into local representation or rightfully skipped.
*/ */
#undef ADVANCE
#define ADVANCE(num_bytes) do { \ #define ADVANCE(num_bytes) do { \
size_t num = num_bytes; \ size_t num = num_bytes; \
ptr = ((char *)ptr) + num; \ ptr = ((char *)ptr) + num; \
...@@ -42,6 +43,7 @@ ...@@ -42,6 +43,7 @@
/* /*
* Switch to the next phase of parsing. * Switch to the next phase of parsing.
*/ */
#undef NEXT_PHASE
#define NEXT_PHASE(ctx) do { \ #define NEXT_PHASE(ctx) do { \
ctx->phase++; \ ctx->phase++; \
ctx->step = 0; \ ctx->step = 0; \
...@@ -50,6 +52,7 @@ ...@@ -50,6 +52,7 @@
/* /*
* Return a standardized complex structure. * Return a standardized complex structure.
*/ */
#undef RETURN
#define RETURN(_code) do { \ #define RETURN(_code) do { \
rval.code = _code; \ rval.code = _code; \
rval.consumed = consumed_myself;\ rval.consumed = consumed_myself;\
...@@ -616,9 +619,11 @@ CHOICE_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel, ...@@ -616,9 +619,11 @@ CHOICE_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
} }
/* Print member's name and stuff */ /* Print member's name and stuff */
if(cb(elm->name, strlen(elm->name), app_key) if(0) {
|| cb(": ", 2, app_key)) if(cb(elm->name, strlen(elm->name), app_key)
return -1; || cb(": ", 2, app_key))
return -1;
}
return elm->type->print_struct(elm->type, memb_ptr, ilevel, return elm->type->print_struct(elm->type, memb_ptr, ilevel,
cb, app_key); cb, app_key);
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
* This macro "eats" the part of the buffer which is definitely "consumed", * This macro "eats" the part of the buffer which is definitely "consumed",
* i.e. was correctly converted into local representation or rightfully skipped. * i.e. was correctly converted into local representation or rightfully skipped.
*/ */
#undef ADVANCE
#define ADVANCE(num_bytes) do { \ #define ADVANCE(num_bytes) do { \
size_t num = num_bytes; \ size_t num = num_bytes; \
ptr = ((char *)ptr) + num; \ ptr = ((char *)ptr) + num; \
...@@ -42,6 +43,8 @@ ...@@ -42,6 +43,8 @@
/* /*
* Switch to the next phase of parsing. * Switch to the next phase of parsing.
*/ */
#undef NEXT_PHASE
#undef PHASE_OUT
#define NEXT_PHASE(ctx) do { \ #define NEXT_PHASE(ctx) do { \
ctx->phase++; \ ctx->phase++; \
ctx->step = 0; \ ctx->step = 0; \
...@@ -51,6 +54,7 @@ ...@@ -51,6 +54,7 @@
/* /*
* Return a standardized complex structure. * Return a standardized complex structure.
*/ */
#undef RETURN
#define RETURN(_code) do { \ #define RETURN(_code) do { \
rval.code = _code; \ rval.code = _code; \
rval.consumed = consumed_myself;\ rval.consumed = consumed_myself;\
...@@ -228,7 +232,7 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *td, ...@@ -228,7 +232,7 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *td,
*/ */
tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag); tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
ASN_DEBUG("Current tag in %s SEQUENCE for element %d " ASN_DEBUG("Current tag in %s SEQUENCE for element %d "
"(%s) is %s encoded in %d bytes, left %ld", "(%s) is %s encoded in %d bytes, of frame %ld",
td->name, edx, elements[edx].name, td->name, edx, elements[edx].name,
ber_tlv_tag_string(tlv_tag), (int)tag_len, (long)LEFT); ber_tlv_tag_string(tlv_tag), (int)tag_len, (long)LEFT);
switch(tag_len) { switch(tag_len) {
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
* This macro "eats" the part of the buffer which is definitely "consumed", * This macro "eats" the part of the buffer which is definitely "consumed",
* i.e. was correctly converted into local representation or rightfully skipped. * i.e. was correctly converted into local representation or rightfully skipped.
*/ */
#undef ADVANCE
#define ADVANCE(num_bytes) do { \ #define ADVANCE(num_bytes) do { \
size_t num = num_bytes; \ size_t num = num_bytes; \
ptr = ((char *)ptr) + num; \ ptr = ((char *)ptr) + num; \
...@@ -48,6 +49,7 @@ ...@@ -48,6 +49,7 @@
/* /*
* Switch to the next phase of parsing. * Switch to the next phase of parsing.
*/ */
#undef NEXT_PHASE
#define NEXT_PHASE(ctx) do { \ #define NEXT_PHASE(ctx) do { \
ctx->phase++; \ ctx->phase++; \
ctx->step = 0; \ ctx->step = 0; \
...@@ -56,6 +58,7 @@ ...@@ -56,6 +58,7 @@
/* /*
* Return a standardized complex structure. * Return a standardized complex structure.
*/ */
#undef RETURN
#define RETURN(_code) do { \ #define RETURN(_code) do { \
rval.code = _code; \ rval.code = _code; \
rval.consumed = consumed_myself;\ rval.consumed = consumed_myself;\
......
...@@ -24,12 +24,13 @@ ...@@ -24,12 +24,13 @@
* if the V processor returns with "want more data" even if the buffer * if the V processor returns with "want more data" even if the buffer
* contains way more data than the V processor have seen. * contains way more data than the V processor have seen.
*/ */
#define SIZE_VIOLATION (ctx->left != -1 && (size_t)ctx->left <= size) #define SIZE_VIOLATION (ctx->left >= 0 && (size_t)ctx->left <= size)
/* /*
* This macro "eats" the part of the buffer which is definitely "consumed", * This macro "eats" the part of the buffer which is definitely "consumed",
* i.e. was correctly converted into local representation or rightfully skipped. * i.e. was correctly converted into local representation or rightfully skipped.
*/ */
#undef ADVANCE
#define ADVANCE(num_bytes) do { \ #define ADVANCE(num_bytes) do { \
size_t num = num_bytes; \ size_t num = num_bytes; \
ptr = ((char *)ptr) + num; \ ptr = ((char *)ptr) + num; \
...@@ -42,6 +43,8 @@ ...@@ -42,6 +43,8 @@
/* /*
* Switch to the next phase of parsing. * Switch to the next phase of parsing.
*/ */
#undef NEXT_PHASE
#undef PHASE_OUT
#define NEXT_PHASE(ctx) do { \ #define NEXT_PHASE(ctx) do { \
ctx->phase++; \ ctx->phase++; \
ctx->step = 0; \ ctx->step = 0; \
...@@ -51,6 +54,7 @@ ...@@ -51,6 +54,7 @@
/* /*
* Return a standardized complex structure. * Return a standardized complex structure.
*/ */
#undef RETURN
#define RETURN(_code) do { \ #define RETURN(_code) do { \
rval.code = _code; \ rval.code = _code; \
rval.consumed = consumed_myself;\ rval.consumed = consumed_myself;\
......
...@@ -42,7 +42,19 @@ xer_encode(asn1_TYPE_descriptor_t *td, void *sptr, ...@@ -42,7 +42,19 @@ xer_encode(asn1_TYPE_descriptor_t *td, void *sptr,
return er; return er;
} }
static int _print2fp(const void *buffer, size_t size, void *app_key); /*
* This is a helper function for xer_fprint, which directs all the incoming data
* into the provided file descriptor.
*/
static int
xer__print2fp(const void *buffer, size_t size, void *app_key) {
FILE *stream = (FILE *)app_key;
if(fwrite(buffer, 1, size, stream) != size)
return -1;
return 0;
}
int int
xer_fprint(FILE *stream, asn1_TYPE_descriptor_t *td, void *sptr) { xer_fprint(FILE *stream, asn1_TYPE_descriptor_t *td, void *sptr) {
...@@ -52,20 +64,9 @@ xer_fprint(FILE *stream, asn1_TYPE_descriptor_t *td, void *sptr) { ...@@ -52,20 +64,9 @@ xer_fprint(FILE *stream, asn1_TYPE_descriptor_t *td, void *sptr) {
if(!td || !sptr) if(!td || !sptr)
return -1; return -1;
er = xer_encode(td, sptr, XER_F_BASIC, _print2fp, stream); er = xer_encode(td, sptr, XER_F_BASIC, xer__print2fp, stream);
if(er.encoded == -1) if(er.encoded == -1)
return -1; return -1;
return fflush(stream); return fflush(stream);
} }
static int
_print2fp(const void *buffer, size_t size, void *app_key) {
FILE *stream = (FILE *)app_key;
if(fwrite(buffer, 1, size, stream) != size)
return -1;
return 0;
}
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