Unused code. Been wanting to do this for years.
OCTET_STRING_compare,
OCTET_STRING_decode_ber,
OCTET_STRING_encode_der,
- OCTET_STRING_decode_xer_hex,
ANY_encode_xer,
0, /* Random fill is not defined for ANY type */
0 /* Use generic outmost tag fetcher */
#define ANY_constraint asn_generic_no_constraint
#define ANY_decode_ber OCTET_STRING_decode_ber
#define ANY_encode_der OCTET_STRING_encode_der
-#define ANY_decode_xer OCTET_STRING_decode_xer_hex
/******************************
* Handy conversion routines. *
asn_constr_check_f ASId_constraint;
ber_type_decoder_f ASId_decode_ber;
der_type_encoder_f ASId_encode_der;
-xer_type_decoder_f ASId_decode_xer;
xer_type_encoder_f ASId_encode_xer;
#ifdef __cplusplus
asn_constr_check_f AttributeType_constraint;
ber_type_decoder_f AttributeType_decode_ber;
der_type_encoder_f AttributeType_encode_der;
-xer_type_decoder_f AttributeType_decode_xer;
xer_type_encoder_f AttributeType_encode_xer;
#ifdef __cplusplus
asn_constr_check_f AttributeValue_constraint;
ber_type_decoder_f AttributeValue_decode_ber;
der_type_encoder_f AttributeValue_encode_der;
-xer_type_decoder_f AttributeValue_decode_xer;
xer_type_encoder_f AttributeValue_encode_xer;
#ifdef __cplusplus
BIT_STRING_compare,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_decode_xer_binary,
BIT_STRING_encode_xer,
BIT_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
#define BIT_STRING_free OCTET_STRING_free
#define BIT_STRING_decode_ber OCTET_STRING_decode_ber
#define BIT_STRING_encode_der OCTET_STRING_encode_der
-#define BIT_STRING_decode_xer OCTET_STRING_decode_xer_binary
#ifdef __cplusplus
}
BOOLEAN_compare,
BOOLEAN_decode_ber,
BOOLEAN_encode_der,
- BOOLEAN_decode_xer,
BOOLEAN_encode_xer,
BOOLEAN_random_fill,
0 /* Use generic outmost tag fetcher */
ASN__ENCODED_OK(erval);
}
-
-/*
- * Decode the chunk of XML text encoding INTEGER.
- */
-static enum xer_pbd_rval
-BOOLEAN__xer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr,
- const void *chunk_buf, size_t chunk_size) {
- BOOLEAN_t *st = (BOOLEAN_t *)sptr;
- const char *p = (const char *)chunk_buf;
-
- (void)td;
-
- if(chunk_size && p[0] == 0x3c /* '<' */) {
- switch(xer_check_tag(chunk_buf, chunk_size, "false")) {
- case XCT_BOTH:
- /* "<false/>" */
- *st = 0;
- break;
- case XCT_UNKNOWN_BO:
- if(xer_check_tag(chunk_buf, chunk_size, "true")
- != XCT_BOTH)
- return XPBD_BROKEN_ENCODING;
- /* "<true/>" */
- *st = 1; /* Or 0xff as in DER?.. */
- break;
- default:
- return XPBD_BROKEN_ENCODING;
- }
- return XPBD_BODY_CONSUMED;
- } else {
- return XPBD_BROKEN_ENCODING;
- }
-}
-
-
-asn_dec_rval_t
-BOOLEAN_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *td, void **sptr,
- const char *opt_mname, const void *buf_ptr, size_t size) {
- return xer_decode_primitive(opt_codec_ctx, td,
- sptr, sizeof(BOOLEAN_t), opt_mname, buf_ptr, size,
- BOOLEAN__xer_body_decode);
-}
-
asn_enc_rval_t
BOOLEAN_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
int ilevel, enum xer_encoder_flags_e flags,
asn_struct_compare_f BOOLEAN_compare;
ber_type_decoder_f BOOLEAN_decode_ber;
der_type_encoder_f BOOLEAN_encode_der;
-xer_type_decoder_f BOOLEAN_decode_xer;
xer_type_encoder_f BOOLEAN_encode_xer;
asn_random_fill_f BOOLEAN_random_fill;
asn_constr_check_f BinarySigningTime_constraint;
ber_type_decoder_f BinarySigningTime_decode_ber;
der_type_encoder_f BinarySigningTime_encode_der;
-xer_type_decoder_f BinarySigningTime_decode_xer;
xer_type_encoder_f BinarySigningTime_encode_xer;
#ifdef __cplusplus
asn_constr_check_f BinaryTime_constraint;
ber_type_decoder_f BinaryTime_decode_ber;
der_type_encoder_f BinaryTime_encode_der;
-xer_type_decoder_f BinaryTime_decode_xer;
xer_type_encoder_f BinaryTime_encode_xer;
#ifdef __cplusplus
asn_constr_check_f CMSAttributeValue_constraint;
ber_type_decoder_f CMSAttributeValue_decode_ber;
der_type_encoder_f CMSAttributeValue_encode_der;
-xer_type_decoder_f CMSAttributeValue_decode_xer;
xer_type_encoder_f CMSAttributeValue_encode_xer;
#ifdef __cplusplus
asn_constr_check_f CMSSubjectKeyIdentifier_constraint;
ber_type_decoder_f CMSSubjectKeyIdentifier_decode_ber;
der_type_encoder_f CMSSubjectKeyIdentifier_encode_der;
-xer_type_decoder_f CMSSubjectKeyIdentifier_decode_xer;
xer_type_encoder_f CMSSubjectKeyIdentifier_encode_xer;
#ifdef __cplusplus
asn_constr_check_f CMSVersion_constraint;
ber_type_decoder_f CMSVersion_decode_ber;
der_type_encoder_f CMSVersion_encode_der;
-xer_type_decoder_f CMSVersion_decode_xer;
xer_type_encoder_f CMSVersion_encode_xer;
#ifdef __cplusplus
asn_constr_check_f CertificateSerialNumber_constraint;
ber_type_decoder_f CertificateSerialNumber_decode_ber;
der_type_encoder_f CertificateSerialNumber_encode_der;
-xer_type_decoder_f CertificateSerialNumber_decode_xer;
xer_type_encoder_f CertificateSerialNumber_encode_xer;
#ifdef __cplusplus
asn_constr_check_f ContentType_constraint;
ber_type_decoder_f ContentType_decode_ber;
der_type_encoder_f ContentType_encode_der;
-xer_type_decoder_f ContentType_decode_xer;
xer_type_encoder_f ContentType_encode_xer;
#ifdef __cplusplus
asn_constr_check_f ContentTypePKCS7_constraint;
ber_type_decoder_f ContentTypePKCS7_decode_ber;
der_type_encoder_f ContentTypePKCS7_encode_der;
-xer_type_decoder_f ContentTypePKCS7_decode_xer;
xer_type_encoder_f ContentTypePKCS7_encode_xer;
#ifdef __cplusplus
asn_constr_check_f Countersignature_constraint;
ber_type_decoder_f Countersignature_decode_ber;
der_type_encoder_f Countersignature_encode_der;
-xer_type_decoder_f Countersignature_decode_xer;
xer_type_encoder_f Countersignature_encode_xer;
#ifdef __cplusplus
asn_constr_check_f DigestAlgorithmIdentifier_constraint;
ber_type_decoder_f DigestAlgorithmIdentifier_decode_ber;
der_type_encoder_f DigestAlgorithmIdentifier_encode_der;
-xer_type_decoder_f DigestAlgorithmIdentifier_decode_xer;
xer_type_encoder_f DigestAlgorithmIdentifier_encode_xer;
#ifdef __cplusplus
asn_constr_check_f DistinguishedName_constraint;
ber_type_decoder_f DistinguishedName_decode_ber;
der_type_encoder_f DistinguishedName_encode_der;
-xer_type_decoder_f DistinguishedName_decode_xer;
xer_type_encoder_f DistinguishedName_encode_xer;
#ifdef __cplusplus
GeneralizedTime_compare,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
GeneralizedTime_encode_der,
- OCTET_STRING_decode_xer_utf8,
GeneralizedTime_encode_xer,
GeneralizedTime_random_fill,
0 /* Use generic outmost tag fetcher */
#define GeneralizedTime_free OCTET_STRING_free
#define GeneralizedTime_decode_ber OCTET_STRING_decode_ber
-#define GeneralizedTime_decode_xer OCTET_STRING_decode_xer_utf8
/***********************
* Some handy helpers. *
OCTET_STRING_compare,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der,
- OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
#define IA5String_compare OCTET_STRING_compare
#define IA5String_decode_ber OCTET_STRING_decode_ber
#define IA5String_encode_der OCTET_STRING_encode_der
-#define IA5String_decode_xer OCTET_STRING_decode_xer_utf8
#define IA5String_encode_xer OCTET_STRING_encode_xer_utf8
#ifdef __cplusplus
INTEGER_compare,
ber_decode_primitive,
INTEGER_encode_der,
- INTEGER_decode_xer,
INTEGER_encode_xer,
INTEGER_random_fill,
0 /* Use generic outmost tag fetcher */
return rval;
}
-static const asn_INTEGER_enum_map_t *INTEGER_map_enum2value(
- const asn_INTEGER_specifics_t *specs, const char *lstart,
- const char *lstop);
-
/*
* INTEGER specific human-readable output.
*/
return (ret < 0) ? -1 : 0;
}
-struct e2v_key {
- const char *start;
- const char *stop;
- const asn_INTEGER_enum_map_t *vemap;
- const unsigned int *evmap;
-};
-static int
-INTEGER__compar_enum2value(const void *kp, const void *am) {
- const struct e2v_key *key = (const struct e2v_key *)kp;
- const asn_INTEGER_enum_map_t *el = (const asn_INTEGER_enum_map_t *)am;
- const char *ptr, *end, *name;
-
- /* Remap the element (sort by different criterion) */
- el = key->vemap + key->evmap[el - key->vemap];
-
- /* Compare strings */
- for(ptr = key->start, end = key->stop, name = el->enum_name;
- ptr < end; ptr++, name++) {
- if(*ptr != *name || !*name)
- return *(const unsigned char *)ptr
- - *(const unsigned char *)name;
- }
- return name[0] ? -1 : 0;
-}
-
-static const asn_INTEGER_enum_map_t *
-INTEGER_map_enum2value(const asn_INTEGER_specifics_t *specs, const char *lstart,
- const char *lstop) {
- const asn_INTEGER_enum_map_t *el_found;
- int count = specs ? specs->map_count : 0;
- struct e2v_key key;
- const char *lp;
-
- if(!count) return NULL;
-
- /* Guaranteed: assert(lstart < lstop); */
- /* Figure out the tag name */
- for(lstart++, lp = lstart; lp < lstop; lp++) {
- switch(*lp) {
- case 9: case 10: case 11: case 12: case 13: case 32: /* WSP */
- case 0x2f: /* '/' */ case 0x3e: /* '>' */
- break;
- default:
- continue;
- }
- break;
- }
- if(lp == lstop) return NULL; /* No tag found */
- lstop = lp;
-
- key.start = lstart;
- key.stop = lstop;
- key.vemap = specs->value2enum;
- key.evmap = specs->enum2value;
- el_found = (asn_INTEGER_enum_map_t *)bsearch(&key,
- specs->value2enum, count, sizeof(specs->value2enum[0]),
- INTEGER__compar_enum2value);
- if(el_found) {
- /* Remap enum2value into value2enum */
- el_found = key.vemap + key.evmap[el_found - key.vemap];
- }
- return el_found;
-}
-
static int
INTEGER__compar_value2enum(const void *kp, const void *am) {
long a = *(const long *)kp;
INTEGER__compar_value2enum);
}
-static int
-INTEGER_st_prealloc(INTEGER_t *st, int min_size) {
- void *p = MALLOC(min_size + 1);
- if(p) {
- void *b = st->buf;
- st->size = 0;
- st->buf = p;
- FREEMEM(b);
- return 0;
- } else {
- return -1;
- }
-}
-
-/*
- * Decode the chunk of XML text encoding INTEGER.
- */
-static enum xer_pbd_rval
-INTEGER__xer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr,
- const void *chunk_buf, size_t chunk_size) {
- INTEGER_t *st = (INTEGER_t *)sptr;
- intmax_t dec_value;
- intmax_t hex_value = 0;
- const char *lp;
- const char *lstart = (const char *)chunk_buf;
- const char *lstop = lstart + chunk_size;
- enum {
- ST_LEADSPACE,
- ST_SKIPSPHEX,
- ST_WAITDIGITS,
- ST_DIGITS,
- ST_DIGITS_TRAILSPACE,
- ST_HEXDIGIT1,
- ST_HEXDIGIT2,
- ST_HEXDIGITS_TRAILSPACE,
- ST_HEXCOLON,
- ST_END_ENUM,
- ST_UNEXPECTED
- } state = ST_LEADSPACE;
- const char *dec_value_start = 0; /* INVARIANT: always !0 in ST_DIGITS */
- const char *dec_value_end = 0;
-
- if(chunk_size)
- ASN_DEBUG("INTEGER body %ld 0x%2x..0x%2x",
- (long)chunk_size, *lstart, lstop[-1]);
-
- if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
- return XPBD_SYSTEM_FAILURE;
-
- /*
- * We may have received a tag here. It will be processed inline.
- * Use strtoul()-like code and serialize the result.
- */
- for(lp = lstart; lp < lstop; lp++) {
- int lv = *lp;
- switch(lv) {
- case 0x09: case 0x0a: case 0x0d: case 0x20:
- switch(state) {
- case ST_LEADSPACE:
- case ST_DIGITS_TRAILSPACE:
- case ST_HEXDIGITS_TRAILSPACE:
- case ST_SKIPSPHEX:
- continue;
- case ST_DIGITS:
- dec_value_end = lp;
- state = ST_DIGITS_TRAILSPACE;
- continue;
- case ST_HEXCOLON:
- state = ST_HEXDIGITS_TRAILSPACE;
- continue;
- default:
- break;
- }
- break;
- case 0x2d: /* '-' */
- if(state == ST_LEADSPACE) {
- dec_value = 0;
- dec_value_start = lp;
- state = ST_WAITDIGITS;
- continue;
- }
- break;
- case 0x2b: /* '+' */
- if(state == ST_LEADSPACE) {
- dec_value = 0;
- dec_value_start = lp;
- state = ST_WAITDIGITS;
- continue;
- }
- break;
- case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
- case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
- switch(state) {
- case ST_DIGITS: continue;
- case ST_SKIPSPHEX: /* Fall through */
- case ST_HEXDIGIT1:
- hex_value = (lv - 0x30) << 4;
- state = ST_HEXDIGIT2;
- continue;
- case ST_HEXDIGIT2:
- hex_value += (lv - 0x30);
- state = ST_HEXCOLON;
- st->buf[st->size++] = (uint8_t)hex_value;
- continue;
- case ST_HEXCOLON:
- return XPBD_BROKEN_ENCODING;
- case ST_LEADSPACE:
- dec_value = 0;
- dec_value_start = lp;
- /* FALL THROUGH */
- case ST_WAITDIGITS:
- state = ST_DIGITS;
- continue;
- default:
- break;
- }
- break;
- case 0x3c: /* '<', start of XML encoded enumeration */
- if(state == ST_LEADSPACE) {
- const asn_INTEGER_enum_map_t *el;
- el = INTEGER_map_enum2value(
- (const asn_INTEGER_specifics_t *)
- td->specifics, lstart, lstop);
- if(el) {
- ASN_DEBUG("Found \"%s\" => %ld",
- el->enum_name, el->nat_value);
- dec_value = el->nat_value;
- state = ST_END_ENUM;
- lp = lstop - 1;
- continue;
- }
- ASN_DEBUG("Unknown identifier for INTEGER");
- }
- return XPBD_BROKEN_ENCODING;
- case 0x3a: /* ':' */
- if(state == ST_HEXCOLON) {
- /* This colon is expected */
- state = ST_HEXDIGIT1;
- continue;
- } else if(state == ST_DIGITS) {
- /* The colon here means that we have
- * decoded the first two hexadecimal
- * places as a decimal value.
- * Switch decoding mode. */
- ASN_DEBUG("INTEGER re-evaluate as hex form");
- state = ST_SKIPSPHEX;
- dec_value_start = 0;
- lp = lstart - 1;
- continue;
- } else {
- ASN_DEBUG("state %d at %ld", state, (long)(lp - lstart));
- break;
- }
- /* [A-Fa-f] */
- case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:
- case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:
- switch(state) {
- case ST_SKIPSPHEX:
- case ST_LEADSPACE: /* Fall through */
- case ST_HEXDIGIT1:
- hex_value = lv - ((lv < 0x61) ? 0x41 : 0x61);
- hex_value += 10;
- hex_value <<= 4;
- state = ST_HEXDIGIT2;
- continue;
- case ST_HEXDIGIT2:
- hex_value += lv - ((lv < 0x61) ? 0x41 : 0x61);
- hex_value += 10;
- st->buf[st->size++] = (uint8_t)hex_value;
- state = ST_HEXCOLON;
- continue;
- case ST_DIGITS:
- ASN_DEBUG("INTEGER re-evaluate as hex form");
- state = ST_SKIPSPHEX;
- dec_value_start = 0;
- lp = lstart - 1;
- continue;
- default:
- break;
- }
- break;
- }
-
- /* Found extra non-numeric stuff */
- ASN_DEBUG("INTEGER :: Found non-numeric 0x%2x at %ld",
- lv, (long)(lp - lstart));
- state = ST_UNEXPECTED;
- break;
- }
-
- switch(state) {
- case ST_END_ENUM:
- /* Got a complete and valid enumeration encoded as a tag. */
- break;
- case ST_DIGITS:
- dec_value_end = lstop;
- /* FALL THROUGH */
- case ST_DIGITS_TRAILSPACE:
- /* The last symbol encountered was a digit. */
- switch(asn_strtoimax_lim(dec_value_start, &dec_value_end, &dec_value)) {
- case ASN_STRTOX_OK:
- if(dec_value >= LONG_MIN && dec_value <= LONG_MAX) {
- break;
- } else {
- /*
- * We model INTEGER on long for XER,
- * to avoid rewriting all the tests at once.
- */
- ASN_DEBUG("INTEGER exceeds long range");
- }
- /* Fall through */
- case ASN_STRTOX_ERROR_RANGE:
- ASN_DEBUG("INTEGER decode %s hit range limit", td->name);
- return XPBD_DECODER_LIMIT;
- case ASN_STRTOX_ERROR_INVAL:
- case ASN_STRTOX_EXPECT_MORE:
- case ASN_STRTOX_EXTRA_DATA:
- return XPBD_BROKEN_ENCODING;
- }
- break;
- case ST_HEXCOLON:
- case ST_HEXDIGITS_TRAILSPACE:
- st->buf[st->size] = 0; /* Just in case termination */
- return XPBD_BODY_CONSUMED;
- case ST_HEXDIGIT1:
- case ST_HEXDIGIT2:
- case ST_SKIPSPHEX:
- return XPBD_BROKEN_ENCODING;
- case ST_LEADSPACE:
- /* Content not found */
- return XPBD_NOT_BODY_IGNORE;
- case ST_WAITDIGITS:
- case ST_UNEXPECTED:
- ASN_DEBUG("INTEGER: No useful digits (state %d)", state);
- return XPBD_BROKEN_ENCODING; /* No digits */
- }
-
- /*
- * Convert the result of parsing of enumeration or a straight
- * decimal value into a BER representation.
- */
- if(asn_imax2INTEGER(st, dec_value)) {
- ASN_DEBUG("INTEGER decode %s conversion failed", td->name);
- return XPBD_SYSTEM_FAILURE;
- }
-
- return XPBD_BODY_CONSUMED;
-}
-
-asn_dec_rval_t
-INTEGER_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *td, void **sptr,
- const char *opt_mname, const void *buf_ptr, size_t size) {
- return xer_decode_primitive(opt_codec_ctx, td,
- sptr, sizeof(INTEGER_t), opt_mname,
- buf_ptr, size, INTEGER__xer_body_decode);
-}
-
asn_enc_rval_t
INTEGER_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
int ilevel, enum xer_encoder_flags_e flags,
asn_struct_print_f INTEGER_print;
asn_struct_compare_f INTEGER_compare;
der_type_encoder_f INTEGER_encode_der;
-xer_type_decoder_f INTEGER_decode_xer;
xer_type_encoder_f INTEGER_encode_xer;
asn_random_fill_f INTEGER_random_fill;
asn_constr_check_f IPAddress_constraint;
ber_type_decoder_f IPAddress_decode_ber;
der_type_encoder_f IPAddress_encode_der;
-xer_type_decoder_f IPAddress_decode_xer;
xer_type_encoder_f IPAddress_encode_xer;
#ifdef __cplusplus
ASN_MODULE_SRCS+=asn1/asn1c/constr_TYPE.c
ASN_MODULE_HDRS+=asn1/asn1c/constraints.h
ASN_MODULE_SRCS+=asn1/asn1c/constraints.c
-ASN_MODULE_HDRS+=asn1/asn1c/xer_support.h
-ASN_MODULE_SRCS+=asn1/asn1c/xer_support.c
-ASN_MODULE_HDRS+=asn1/asn1c/xer_decoder.h
-ASN_MODULE_SRCS+=asn1/asn1c/xer_decoder.c
ASN_MODULE_HDRS+=asn1/asn1c/xer_encoder.h
ASN_MODULE_SRCS+=asn1/asn1c/xer_encoder.c
\ No newline at end of file
asn_constr_check_f MessageDigest_constraint;
ber_type_decoder_f MessageDigest_decode_ber;
der_type_encoder_f MessageDigest_encode_der;
-xer_type_decoder_f MessageDigest_decode_xer;
xer_type_encoder_f MessageDigest_encode_xer;
#ifdef __cplusplus
NULL_compare,
NULL_decode_ber,
NULL_encode_der, /* Special handling of DER encoding */
- NULL_decode_xer,
NULL_encode_xer,
NULL_random_fill,
0 /* Use generic outmost tag fetcher */
ASN__ENCODED_OK(er);
}
-
-static enum xer_pbd_rval
-NULL__xer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr,
- const void *chunk_buf, size_t chunk_size) {
- (void)td;
- (void)sptr;
- (void)chunk_buf; /* Going to be empty according to the rules below. */
-
- /*
- * There must be no content in self-terminating <NULL/> tag.
- */
- if(chunk_size)
- return XPBD_BROKEN_ENCODING;
- else
- return XPBD_BODY_CONSUMED;
-}
-
-asn_dec_rval_t
-NULL_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *td, void **sptr,
- const char *opt_mname, const void *buf_ptr, size_t size) {
- return xer_decode_primitive(opt_codec_ctx, td,
- sptr, sizeof(NULL_t), opt_mname, buf_ptr, size,
- NULL__xer_body_decode);
-}
-
int
NULL_compare(const asn_TYPE_descriptor_t *td, const void *a, const void *b) {
(void)td;
asn_struct_compare_f NULL_compare;
ber_type_decoder_f NULL_decode_ber;
der_type_encoder_f NULL_encode_der;
-xer_type_decoder_f NULL_decode_xer;
xer_type_encoder_f NULL_encode_xer;
asn_random_fill_f NULL_random_fill;
OCTET_STRING_compare, /* Implemented in terms of a string comparison */
ber_decode_primitive,
der_encode_primitive,
- OBJECT_IDENTIFIER_decode_xer,
OBJECT_IDENTIFIER_encode_xer,
OBJECT_IDENTIFIER_random_fill,
0 /* Use generic outmost tag fetcher */
return produced;
}
-static enum xer_pbd_rval
-OBJECT_IDENTIFIER__xer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr,
- const void *chunk_buf, size_t chunk_size) {
- OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr;
- const char *chunk_end = (const char *)chunk_buf + chunk_size;
- const char *endptr;
- asn_oid_arc_t s_arcs[10];
- asn_oid_arc_t *arcs = s_arcs;
- ssize_t num_arcs;
- ssize_t ret;
-
- (void)td;
-
- num_arcs = OBJECT_IDENTIFIER_parse_arcs(
- (const char *)chunk_buf, chunk_size, arcs,
- sizeof(s_arcs) / sizeof(s_arcs[0]), &endptr);
- if(num_arcs < 0) {
- /* Expecting more than zero arcs */
- return XPBD_BROKEN_ENCODING;
- } else if(num_arcs == 0) {
- return XPBD_NOT_BODY_IGNORE;
- }
- assert(endptr == chunk_end);
-
- if((size_t)num_arcs > sizeof(s_arcs)/sizeof(s_arcs[0])) {
- arcs = (asn_oid_arc_t *)MALLOC(num_arcs * sizeof(asn_oid_arc_t));
- if(!arcs) return XPBD_SYSTEM_FAILURE;
- ret = OBJECT_IDENTIFIER_parse_arcs((const char *)chunk_buf, chunk_size,
- arcs, num_arcs, &endptr);
- if(ret != num_arcs)
- return XPBD_SYSTEM_FAILURE; /* assert?.. */
- }
-
- /*
- * Convert arcs into BER representation.
- */
- ret = OBJECT_IDENTIFIER_set_arcs(st, arcs, num_arcs);
- if(arcs != s_arcs) FREEMEM(arcs);
-
- return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED;
-}
-
-asn_dec_rval_t
-OBJECT_IDENTIFIER_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *td, void **sptr,
- const char *opt_mname, const void *buf_ptr,
- size_t size) {
- return xer_decode_primitive(opt_codec_ctx, td,
- sptr, sizeof(OBJECT_IDENTIFIER_t), opt_mname,
- buf_ptr, size, OBJECT_IDENTIFIER__xer_body_decode);
-}
-
asn_enc_rval_t
OBJECT_IDENTIFIER_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
int ilevel, enum xer_encoder_flags_e flags,
asn_struct_print_f OBJECT_IDENTIFIER_print;
asn_constr_check_f OBJECT_IDENTIFIER_constraint;
der_type_encoder_f OBJECT_IDENTIFIER_encode_der;
-xer_type_decoder_f OBJECT_IDENTIFIER_decode_xer;
xer_type_encoder_f OBJECT_IDENTIFIER_encode_xer;
asn_random_fill_f OBJECT_IDENTIFIER_random_fill;
OCTET_STRING_compare,
OCTET_STRING_decode_ber,
OCTET_STRING_encode_der,
- OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer,
OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
OSXET("\046\147\164\073"), /* > */
};
-static int
-OS__check_escaped_control_char(const void *buf, int size) {
- size_t i;
- /*
- * Inefficient algorithm which translates the escape sequences
- * defined above into characters. Returns -1 if not found.
- * TODO (asn1c) replace by a faster algorithm (bsearch(), hash or
- * nested table lookups).
- */
- for(i = 0; i < 32 /* Don't spend time on the bottom half */; i++) {
- const struct OCTET_STRING__xer_escape_table_s *el;
- el = &OCTET_STRING__xer_escape_table[i];
- if(el->size == size && memcmp(buf, el->string, size) == 0)
- return i;
- }
- return -1;
-}
-
-static int
-OCTET_STRING__handle_control_chars(void *struct_ptr, const void *chunk_buf, size_t chunk_size) {
- /*
- * This might be one of the escape sequences
- * for control characters. Check it out.
- * #11.15.5
- */
- int control_char = OS__check_escaped_control_char(chunk_buf,chunk_size);
- if(control_char >= 0) {
- OCTET_STRING_t *st = (OCTET_STRING_t *)struct_ptr;
- void *p = REALLOC(st->buf, st->size + 2);
- if(p) {
- st->buf = (uint8_t *)p;
- st->buf[st->size++] = control_char;
- st->buf[st->size] = '\0'; /* nul-termination */
- return 0;
- }
- }
-
- return -1; /* No, it's not */
-}
-
asn_enc_rval_t
OCTET_STRING_encode_xer_utf8(const asn_TYPE_descriptor_t *td, const void *sptr,
int ilevel, enum xer_encoder_flags_e flags,
ASN__ENCODED_OK(er);
}
-/*
- * Convert from hexadecimal format (cstring): "AB CD EF"
- */
-static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) {
- OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
- const char *chunk_stop = (const char *)chunk_buf;
- const char *p = chunk_stop;
- const char *pend = p + chunk_size;
- unsigned int clv = 0;
- int half = 0; /* Half bit */
- uint8_t *buf;
-
- /* Reallocate buffer according to high cap estimation */
- size_t new_size = st->size + (chunk_size + 1) / 2;
- void *nptr = REALLOC(st->buf, new_size + 1);
- if(!nptr) return -1;
- st->buf = (uint8_t *)nptr;
- buf = st->buf + st->size;
-
- /*
- * If something like " a b c " appears here, the " a b":3 will be
- * converted, and the rest skipped. That is, unless buf_size is greater
- * than chunk_size, then it'll be equivalent to "ABC0".
- */
- for(; p < pend; p++) {
- int ch = *(const unsigned char *)p;
- switch(ch) {
- case 0x09: case 0x0a: case 0x0c: case 0x0d:
- case 0x20:
- /* Ignore whitespace */
- continue;
- case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/
- case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/
- clv = (clv << 4) + (ch - 0x30);
- break;
- case 0x41: case 0x42: case 0x43: /* ABC */
- case 0x44: case 0x45: case 0x46: /* DEF */
- clv = (clv << 4) + (ch - 0x41 + 10);
- break;
- case 0x61: case 0x62: case 0x63: /* abc */
- case 0x64: case 0x65: case 0x66: /* def */
- clv = (clv << 4) + (ch - 0x61 + 10);
- break;
- default:
- *buf = 0; /* JIC */
- return -1;
- }
- if(half++) {
- half = 0;
- *buf++ = clv;
- chunk_stop = p + 1;
- }
- }
-
- /*
- * Check partial decoding.
- */
- if(half) {
- if(have_more) {
- /*
- * Partial specification is fine,
- * because no more more PXER_TEXT data is available.
- */
- *buf++ = clv << 4;
- chunk_stop = p;
- }
- } else {
- chunk_stop = p;
- }
-
- st->size = buf - st->buf; /* Adjust the buffer size */
- assert(st->size <= new_size);
- st->buf[st->size] = 0; /* Courtesy termination */
-
- return (chunk_stop - (const char *)chunk_buf); /* Converted size */
-}
-
-/*
- * Convert from binary format: "00101011101"
- */
-static ssize_t OCTET_STRING__convert_binary(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) {
- BIT_STRING_t *st = (BIT_STRING_t *)sptr;
- const char *p = (const char *)chunk_buf;
- const char *pend = p + chunk_size;
- int bits_unused = st->bits_unused & 0x7;
- uint8_t *buf;
-
- /* Reallocate buffer according to high cap estimation */
- size_t new_size = st->size + (chunk_size + 7) / 8;
- void *nptr = REALLOC(st->buf, new_size + 1);
- if(!nptr) return -1;
- st->buf = (uint8_t *)nptr;
- buf = st->buf + st->size;
-
- (void)have_more;
-
- if(bits_unused == 0)
- bits_unused = 8;
- else if(st->size)
- buf--;
-
- /*
- * Convert series of 0 and 1 into the octet string.
- */
- for(; p < pend; p++) {
- int ch = *(const unsigned char *)p;
- switch(ch) {
- case 0x09: case 0x0a: case 0x0c: case 0x0d:
- case 0x20:
- /* Ignore whitespace */
- break;
- case 0x30:
- case 0x31:
- if(bits_unused-- <= 0) {
- *++buf = 0; /* Clean the cell */
- bits_unused = 7;
- }
- *buf |= (ch&1) << bits_unused;
- break;
- default:
- st->bits_unused = bits_unused;
- return -1;
- }
- }
-
- if(bits_unused == 8) {
- st->size = buf - st->buf;
- st->bits_unused = 0;
- } else {
- st->size = buf - st->buf + 1;
- st->bits_unused = bits_unused;
- }
-
- assert(st->size <= new_size);
- st->buf[st->size] = 0; /* Courtesy termination */
-
- return chunk_size; /* Converted in full */
-}
-
-/*
- * Something like strtod(), but with stricter rules.
- */
-static int
-OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) {
- const int32_t last_unicode_codepoint = 0x10ffff;
- int32_t val = 0;
- const char *p;
-
- for(p = buf; p < end; p++) {
- int ch = *p;
-
- switch(ch) {
- case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/
- case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/
- val = val * base + (ch - 0x30);
- break;
- case 0x41: case 0x42: case 0x43: /* ABC */
- case 0x44: case 0x45: case 0x46: /* DEF */
- val = val * base + (ch - 0x41 + 10);
- break;
- case 0x61: case 0x62: case 0x63: /* abc */
- case 0x64: case 0x65: case 0x66: /* def */
- val = val * base + (ch - 0x61 + 10);
- break;
- case 0x3b: /* ';' */
- *ret_value = val;
- return (p - buf) + 1;
- default:
- return -1; /* Character set error */
- }
-
- /* Value exceeds the Unicode range. */
- if(val > last_unicode_codepoint) {
- return -1;
- }
- }
-
- *ret_value = -1;
- return (p - buf);
-}
-
-/*
- * Convert from the plain UTF-8 format, expanding entity references: "2 < 3"
- */
-static ssize_t
-OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf,
- size_t chunk_size, int have_more) {
- OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
- const char *p = (const char *)chunk_buf;
- const char *pend = p + chunk_size;
- uint8_t *buf;
-
- /* Reallocate buffer */
- size_t new_size = st->size + chunk_size;
- void *nptr = REALLOC(st->buf, new_size + 1);
- if(!nptr) return -1;
- st->buf = (uint8_t *)nptr;
- buf = st->buf + st->size;
-
- /*
- * Convert series of 0 and 1 into the octet string.
- */
- for(; p < pend; p++) {
- int ch = *(const unsigned char *)p;
- int len; /* Length of the rest of the chunk */
-
- if(ch != 0x26 /* '&' */) {
- *buf++ = ch;
- continue; /* That was easy... */
- }
-
- /*
- * Process entity reference.
- */
- len = chunk_size - (p - (const char *)chunk_buf);
- if(len == 1 /* "&" */) goto want_more;
- if(p[1] == 0x23 /* '#' */) {
- const char *pval; /* Pointer to start of digits */
- int32_t val = 0; /* Entity reference value */
- int base;
-
- if(len == 2 /* "&#" */) goto want_more;
- if(p[2] == 0x78 /* 'x' */)
- pval = p + 3, base = 16;
- else
- pval = p + 2, base = 10;
- len = OS__strtoent(base, pval, p + len, &val);
- if(len == -1) {
- /* Invalid charset. Just copy verbatim. */
- *buf++ = ch;
- continue;
- }
- if(!len || pval[len-1] != 0x3b) goto want_more;
- assert(val > 0);
- p += (pval - p) + len - 1; /* Advance past entref */
-
- if(val < 0x80) {
- *buf++ = (char)val;
- } else if(val < 0x800) {
- *buf++ = 0xc0 | ((val >> 6));
- *buf++ = 0x80 | ((val & 0x3f));
- } else if(val < 0x10000) {
- *buf++ = 0xe0 | ((val >> 12));
- *buf++ = 0x80 | ((val >> 6) & 0x3f);
- *buf++ = 0x80 | ((val & 0x3f));
- } else if(val < 0x200000) {
- *buf++ = 0xf0 | ((val >> 18));
- *buf++ = 0x80 | ((val >> 12) & 0x3f);
- *buf++ = 0x80 | ((val >> 6) & 0x3f);
- *buf++ = 0x80 | ((val & 0x3f));
- } else if(val < 0x4000000) {
- *buf++ = 0xf8 | ((val >> 24));
- *buf++ = 0x80 | ((val >> 18) & 0x3f);
- *buf++ = 0x80 | ((val >> 12) & 0x3f);
- *buf++ = 0x80 | ((val >> 6) & 0x3f);
- *buf++ = 0x80 | ((val & 0x3f));
- } else {
- *buf++ = 0xfc | ((val >> 30) & 0x1);
- *buf++ = 0x80 | ((val >> 24) & 0x3f);
- *buf++ = 0x80 | ((val >> 18) & 0x3f);
- *buf++ = 0x80 | ((val >> 12) & 0x3f);
- *buf++ = 0x80 | ((val >> 6) & 0x3f);
- *buf++ = 0x80 | ((val & 0x3f));
- }
- } else {
- /*
- * Ugly, limited parsing of & > <
- */
- char *sc = (char *)memchr(p, 0x3b, len > 5 ? 5 : len);
- if(!sc) goto want_more;
- if((sc - p) == 4
- && p[1] == 0x61 /* 'a' */
- && p[2] == 0x6d /* 'm' */
- && p[3] == 0x70 /* 'p' */) {
- *buf++ = 0x26;
- p = sc;
- continue;
- }
- if((sc - p) == 3) {
- if(p[1] == 0x6c) {
- *buf = 0x3c; /* '<' */
- } else if(p[1] == 0x67) {
- *buf = 0x3e; /* '>' */
- } else {
- /* Unsupported entity reference */
- *buf++ = ch;
- continue;
- }
- if(p[2] != 0x74) {
- /* Unsupported entity reference */
- *buf++ = ch;
- continue;
- }
- buf++;
- p = sc;
- continue;
- }
- /* Unsupported entity reference */
- *buf++ = ch;
- }
-
- continue;
- want_more:
- if(have_more) {
- /*
- * We know that no more data (of the same type)
- * is coming. Copy the rest verbatim.
- */
- *buf++ = ch;
- continue;
- }
- chunk_size = (p - (const char *)chunk_buf);
- /* Processing stalled: need more data */
- break;
- }
-
- st->size = buf - st->buf;
- assert(st->size <= new_size);
- st->buf[st->size] = 0; /* Courtesy termination */
-
- return chunk_size; /* Converted in full */
-}
-
-/*
- * Decode OCTET STRING from the XML element's body.
- */
-static asn_dec_rval_t
-OCTET_STRING__decode_xer(
- const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *td,
- void **sptr, const char *opt_mname, const void *buf_ptr, size_t size,
- int (*opt_unexpected_tag_decoder)(void *struct_ptr, const void *chunk_buf,
- size_t chunk_size),
- ssize_t (*body_receiver)(void *struct_ptr, const void *chunk_buf,
- size_t chunk_size, int have_more)) {
- OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr;
- const asn_OCTET_STRING_specifics_t *specs = td->specifics
- ? (const asn_OCTET_STRING_specifics_t *)td->specifics
- : &asn_SPC_OCTET_STRING_specs;
- const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
- asn_struct_ctx_t *ctx; /* Per-structure parser context */
- asn_dec_rval_t rval; /* Return value from the decoder */
- int st_allocated;
-
- /*
- * Create the string if does not exist.
- */
- if(!st) {
- st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
- *sptr = (void *)st;
- if(!st) goto sta_failed;
- st_allocated = 1;
- } else {
- st_allocated = 0;
- }
- if(!st->buf) {
- /* This is separate from above section */
- st->buf = (uint8_t *)CALLOC(1, 1);
- if(!st->buf) {
- if(st_allocated) {
- *sptr = 0;
- goto stb_failed;
- } else {
- goto sta_failed;
- }
- }
- }
-
- /* Restore parsing context */
- ctx = (asn_struct_ctx_t *)(((char *)*sptr) + specs->ctx_offset);
-
- return xer_decode_general(opt_codec_ctx, ctx, *sptr, xml_tag,
- buf_ptr, size, opt_unexpected_tag_decoder, body_receiver);
-
-stb_failed:
- FREEMEM(st);
-sta_failed:
- rval.code = RC_FAIL;
- rval.consumed = 0;
- return rval;
-}
-
-/*
- * Decode OCTET STRING from the hexadecimal data.
- */
-asn_dec_rval_t
-OCTET_STRING_decode_xer_hex(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *td, void **sptr,
- const char *opt_mname, const void *buf_ptr,
- size_t size) {
- return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
- buf_ptr, size, 0, OCTET_STRING__convert_hexadecimal);
-}
-
-/*
- * Decode OCTET STRING from the binary (0/1) data.
- */
-asn_dec_rval_t
-OCTET_STRING_decode_xer_binary(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *td, void **sptr,
- const char *opt_mname, const void *buf_ptr,
- size_t size) {
- return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
- buf_ptr, size, 0, OCTET_STRING__convert_binary);
-}
-
-/*
- * Decode OCTET STRING from the string (ASCII/UTF-8) data.
- */
-asn_dec_rval_t
-OCTET_STRING_decode_xer_utf8(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *td, void **sptr,
- const char *opt_mname, const void *buf_ptr,
- size_t size) {
- return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
- buf_ptr, size,
- OCTET_STRING__handle_control_chars,
- OCTET_STRING__convert_entrefs);
-}
-
int
OCTET_STRING_print(const asn_TYPE_descriptor_t *td, const void *sptr,
int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
asn_struct_compare_f OCTET_STRING_compare;
ber_type_decoder_f OCTET_STRING_decode_ber;
der_type_encoder_f OCTET_STRING_encode_der;
-xer_type_decoder_f OCTET_STRING_decode_xer_hex; /* Hexadecimal */
-xer_type_decoder_f OCTET_STRING_decode_xer_binary; /* 01010111010 */
-xer_type_decoder_f OCTET_STRING_decode_xer_utf8; /* ASCII/UTF-8 */
xer_type_encoder_f OCTET_STRING_encode_xer;
xer_type_encoder_f OCTET_STRING_encode_xer_utf8;
asn_random_fill_f OCTET_STRING_random_fill;
#define OCTET_STRING_constraint asn_generic_no_constraint
-#define OCTET_STRING_decode_xer OCTET_STRING_decode_xer_hex
/******************************
* Handy conversion routines. *
OPEN_TYPE_compare,
OPEN_TYPE_decode_ber,
OPEN_TYPE_encode_der,
- OPEN_TYPE_decode_xer,
OPEN_TYPE_encode_xer,
0, /* Random fill is not supported for open type */
0, /* Use generic outmost tag fetcher */
}
return rv;
}
-
-asn_dec_rval_t
-OPEN_TYPE_xer_get(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *td, void *sptr,
- const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
- size_t consumed_myself = 0;
- asn_type_selector_result_t selected;
- void *memb_ptr; /* Pointer to the member */
- void **memb_ptr2; /* Pointer to that pointer */
- void *inner_value;
- asn_dec_rval_t rv;
-
- int xer_context = 0;
- ssize_t ch_size;
- pxer_chunk_type_e ch_type;
-
- if(!(elm->flags & ATF_OPEN_TYPE)) {
- ASN__DECODE_FAILED;
- }
-
- if(!elm->type_selector) {
- ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
- td->name, elm->name, elm->type->name);
- ASN__DECODE_FAILED;
- }
-
- selected = elm->type_selector(td, sptr);
- if(!selected.presence_index) {
- ASN__DECODE_FAILED;
- }
-
- /* Fetch the pointer to this member */
- assert(elm->flags == ATF_OPEN_TYPE);
- if(elm->flags & ATF_POINTER) {
- memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
- } else {
- memb_ptr = (char *)sptr + elm->memb_offset;
- memb_ptr2 = &memb_ptr;
- }
- if(*memb_ptr2 != NULL) {
- /* Make sure we reset the structure first before encoding */
- if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
- != 0) {
- ASN__DECODE_FAILED;
- }
- }
-
- /*
- * Confirm wrapper.
- */
- for(;;) {
- ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
- if(ch_size < 0) {
- ASN__DECODE_FAILED;
- } else {
- switch(ch_type) {
- case PXER_WMORE:
- ASN__DECODE_STARVED;
- case PXER_COMMENT:
- case PXER_TEXT:
- ADVANCE(ch_size);
- continue;
- case PXER_TAG:
- break;
- }
- break;
- }
- }
-
- /*
- * Wrapper value confirmed.
- */
- switch(xer_check_tag(ptr, ch_size, elm->name)) {
- case XCT_OPENING:
- ADVANCE(ch_size);
- break;
- case XCT_BROKEN:
- default:
- ASN__DECODE_FAILED;
- }
-
- inner_value =
- (char *)*memb_ptr2
- + elm->type->elements[selected.presence_index - 1].memb_offset;
-
- rv = selected.type_descriptor->op->xer_decoder(
- opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size);
- ADVANCE(rv.consumed);
- rv.consumed = 0;
- switch(rv.code) {
- case RC_OK:
- if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
- selected.presence_index)
- == 0) {
- break;
- } else {
- rv.code = RC_FAIL;
- }
- /* Fall through */
- case RC_FAIL:
- /* Point to a best position where failure occurred */
- rv.consumed = consumed_myself;
- /* Fall through */
- case RC_WMORE:
- /* Wrt. rv.consumed==0:
- * In case a genuine RC_WMORE, the whole Open Type decoding
- * will have to be restarted.
- */
- if(*memb_ptr2) {
- const asn_CHOICE_specifics_t *specs =
- selected.type_descriptor->specifics;
- if(elm->flags & ATF_POINTER) {
- ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
- *memb_ptr2 = NULL;
- } else {
- ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
- inner_value);
- memset(*memb_ptr2, 0, specs->struct_size);
- }
- }
- return rv;
- }
-
- /*
- * Finalize wrapper.
- */
- for(;;) {
- ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
- if(ch_size < 0) {
- ASN__DECODE_FAILED;
- } else {
- switch(ch_type) {
- case PXER_WMORE:
- ASN__DECODE_STARVED;
- case PXER_COMMENT:
- case PXER_TEXT:
- ADVANCE(ch_size);
- continue;
- case PXER_TAG:
- break;
- }
- break;
- }
- }
-
- /*
- * Wrapper value confirmed.
- */
- switch(xer_check_tag(ptr, ch_size, elm->name)) {
- case XCT_CLOSING:
- ADVANCE(ch_size);
- break;
- case XCT_BROKEN:
- default:
- ASN__DECODE_FAILED;
- }
-
- rv.consumed += consumed_myself;
-
- return rv;
-}
#define OPEN_TYPE_constraint CHOICE_constraint
#define OPEN_TYPE_decode_ber NULL
#define OPEN_TYPE_encode_der CHOICE_encode_der
-#define OPEN_TYPE_decode_xer NULL
#define OPEN_TYPE_encode_xer CHOICE_encode_xer
extern asn_TYPE_operation_t asn_OP_OPEN_TYPE;
const asn_TYPE_member_t *element,
const void *ptr, size_t size);
-asn_dec_rval_t OPEN_TYPE_xer_get(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *parent_type,
- void *parent_structure,
- const asn_TYPE_member_t *element,
- const void *ptr, size_t size);
-
#ifdef __cplusplus
}
#endif
asn_constr_check_f SignatureAlgorithmIdentifier_constraint;
ber_type_decoder_f SignatureAlgorithmIdentifier_decode_ber;
der_type_encoder_f SignatureAlgorithmIdentifier_encode_der;
-xer_type_decoder_f SignatureAlgorithmIdentifier_decode_xer;
xer_type_encoder_f SignatureAlgorithmIdentifier_encode_xer;
#ifdef __cplusplus
asn_constr_check_f SignatureValue_constraint;
ber_type_decoder_f SignatureValue_decode_ber;
der_type_encoder_f SignatureValue_encode_der;
-xer_type_decoder_f SignatureValue_decode_xer;
xer_type_encoder_f SignatureValue_encode_xer;
#ifdef __cplusplus
asn_constr_check_f SigningTime_constraint;
ber_type_decoder_f SigningTime_decode_ber;
der_type_encoder_f SigningTime_encode_der;
-xer_type_decoder_f SigningTime_decode_xer;
xer_type_encoder_f SigningTime_encode_xer;
#ifdef __cplusplus
UTCTime_compare,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_decode_xer_utf8,
UTCTime_encode_xer,
UTCTime_random_fill,
0 /* Use generic outmost tag fetcher */
#define UTCTime_free OCTET_STRING_free
#define UTCTime_decode_ber OCTET_STRING_decode_ber
#define UTCTime_encode_der OCTET_STRING_encode_der
-#define UTCTime_decode_xer OCTET_STRING_decode_xer_utf8
/***********************
* Some handy helpers. *
asn_constr_check_f Version_constraint;
ber_type_decoder_f Version_decode_ber;
der_type_encoder_f Version_encode_der;
-xer_type_decoder_f Version_decode_xer;
xer_type_encoder_f Version_encode_xer;
#ifdef __cplusplus
const asn_TYPE_descriptor_t *td, const void *sptr,
asn_app_consume_bytes_f *callback, void *callback_key) {
asn_enc_rval_t er;
- enum xer_encoder_flags_e xer_flags = XER_F_CANONICAL;
(void)opt_codec_ctx; /* Parameters are not checked on encode yet. */
errno = ENOENT; /* Transfer syntax is not defined for any type. */
ASN__ENCODE_FAILED;
- case ATS_BASIC_XER:
- /* CANONICAL-XER is a superset of BASIC-XER. */
- xer_flags &= ~XER_F_CANONICAL;
- xer_flags |= XER_F_BASIC;
- /* Fall through. */
- case ATS_CANONICAL_XER:
- if(td->op->xer_encoder) {
- er = xer_encode(td, sptr, xer_flags, callback, callback_key);
- if(er.encoded == -1) {
- if(er.failed_type && er.failed_type->op->xer_encoder) {
- errno = EBADF; /* Structure has incorrect form. */
- } else {
- errno = ENOENT; /* XER is not defined for this type. */
- }
- }
- } else {
- errno = ENOENT; /* Transfer syntax is not defined for this type. */
- ASN__ENCODE_FAILED;
- }
- break;
-
default:
errno = ENOENT;
ASN__ENCODE_FAILED;
case ATS_DER:
case ATS_BER:
return ber_decode(opt_codec_ctx, td, sptr, buffer, size);
-
- case ATS_BASIC_XER:
- case ATS_CANONICAL_XER:
- return xer_decode(opt_codec_ctx, td, sptr, buffer, size);
}
}
ATS_BER,
ATS_DER,
ATS_CER, /* Only decoding is supported */
- /*
- * X.693:
- * XER: XML Encoding Rules.
- * CANONICAL-XER is a more strict variant of BASIC-XER.
- */
- ATS_BASIC_XER,
- ATS_CANONICAL_XER
};
/*
* function pointers of the asn_TYPE_descriptor_t directly,
* this structure must be ALLOCATED ON THE STACK!
* If you can't always satisfy this requirement, use ber_decode()
- * and xer_decode() functions instead.
+ * instead.
*/
typedef struct asn_codec_ctx_s {
/*
} while(0)
/*
- * Type of the return value of the decoding functions (ber_decode, xer_decode)
+ * Type of the return value of the decoding functions (ber_decode, <deleted>)
*
* Please note that the number of consumed bytes is ALWAYS meaningful,
* even if code==RC_FAIL. This is to indicate the number of successfully
break;
}
}
-
-
-/*
- * Local internal type passed around as an argument.
- */
-struct xdp_arg_s {
- const asn_TYPE_descriptor_t *type_descriptor;
- void *struct_key;
- xer_primitive_body_decoder_f *prim_body_decoder;
- int decoded_something;
- int want_more;
-};
-
-/*
- * Since some kinds of primitive values can be encoded using value-specific
- * tags (<MINUS-INFINITY>, <enum-element>, etc), the primitive decoder must
- * be supplied with such tags to parse them as needed.
- */
-static int
-xer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size) {
- struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
- enum xer_pbd_rval bret;
-
- /*
- * The chunk_buf is guaranteed to start at '<'.
- */
- assert(chunk_size && ((const char *)chunk_buf)[0] == 0x3c);
-
- /*
- * Decoding was performed once already. Prohibit doing it again.
- */
- if(arg->decoded_something)
- return -1;
-
- bret = arg->prim_body_decoder(arg->type_descriptor,
- arg->struct_key, chunk_buf, chunk_size);
- switch(bret) {
- case XPBD_SYSTEM_FAILURE:
- case XPBD_DECODER_LIMIT:
- case XPBD_BROKEN_ENCODING:
- break;
- case XPBD_BODY_CONSUMED:
- /* Tag decoded successfully */
- arg->decoded_something = 1;
- /* Fall through */
- case XPBD_NOT_BODY_IGNORE: /* Safe to proceed further */
- return 0;
- }
-
- return -1;
-}
-
-static ssize_t
-xer_decode__primitive_body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {
- struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
- enum xer_pbd_rval bret;
- size_t lead_wsp_size;
-
- if(arg->decoded_something) {
- if(xer_whitespace_span(chunk_buf, chunk_size) == chunk_size) {
- /*
- * Example:
- * "<INTEGER>123<!--/--> </INTEGER>"
- * ^- chunk_buf position.
- */
- return chunk_size;
- }
- /*
- * Decoding was done once already. Prohibit doing it again.
- */
- return -1;
- }
-
- if(!have_more) {
- /*
- * If we've received something like "1", we can't really
- * tell whether it is really `1` or `123`, until we know
- * that there is no more data coming.
- * The have_more argument will be set to 1 once something
- * like this is available to the caller of this callback:
- * "1<tag_start..."
- */
- arg->want_more = 1;
- return -1;
- }
-
- lead_wsp_size = xer_whitespace_span(chunk_buf, chunk_size);
- chunk_buf = (const char *)chunk_buf + lead_wsp_size;
- chunk_size -= lead_wsp_size;
-
- bret = arg->prim_body_decoder(arg->type_descriptor,
- arg->struct_key, chunk_buf, chunk_size);
- switch(bret) {
- case XPBD_SYSTEM_FAILURE:
- case XPBD_DECODER_LIMIT:
- case XPBD_BROKEN_ENCODING:
- break;
- case XPBD_BODY_CONSUMED:
- /* Tag decoded successfully */
- arg->decoded_something = 1;
- /* Fall through */
- case XPBD_NOT_BODY_IGNORE: /* Safe to proceed further */
- return lead_wsp_size + chunk_size;
- }
-
- return -1;
-}
-
-
-asn_dec_rval_t
-xer_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *td, void **sptr,
- size_t struct_size, const char *opt_mname,
- const void *buf_ptr, size_t size,
- xer_primitive_body_decoder_f *prim_body_decoder) {
- const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
- asn_struct_ctx_t s_ctx;
- struct xdp_arg_s s_arg;
- asn_dec_rval_t rc;
-
- /*
- * Create the structure if does not exist.
- */
- if(!*sptr) {
- *sptr = CALLOC(1, struct_size);
- if(!*sptr) ASN__DECODE_FAILED;
- }
-
- memset(&s_ctx, 0, sizeof(s_ctx));
- s_arg.type_descriptor = td;
- s_arg.struct_key = *sptr;
- s_arg.prim_body_decoder = prim_body_decoder;
- s_arg.decoded_something = 0;
- s_arg.want_more = 0;
-
- rc = xer_decode_general(opt_codec_ctx, &s_ctx, &s_arg,
- xml_tag, buf_ptr, size,
- xer_decode__unexpected_tag, xer_decode__primitive_body);
- switch(rc.code) {
- case RC_OK:
- if(!s_arg.decoded_something) {
- char ch;
- ASN_DEBUG("Primitive body is not recognized, "
- "supplying empty one");
- /*
- * Decoding opportunity has come and gone.
- * Where's the result?
- * Try to feed with empty body, see if it eats it.
- */
- if(prim_body_decoder(s_arg.type_descriptor,
- s_arg.struct_key, &ch, 0)
- != XPBD_BODY_CONSUMED) {
- /*
- * This decoder does not like empty stuff.
- */
- ASN__DECODE_FAILED;
- }
- }
- break;
- case RC_WMORE:
- /*
- * Redo the whole thing later.
- * We don't have a context to save intermediate parsing state.
- */
- rc.consumed = 0;
- break;
- case RC_FAIL:
- rc.consumed = 0;
- if(s_arg.want_more)
- rc.code = RC_WMORE;
- else
- ASN__DECODE_FAILED;
- break;
- }
- return rc;
-}
ber_type_decoder_f ber_decode_primitive;
der_type_encoder_f der_encode_primitive;
-/*
- * A callback specification for the xer_decode_primitive() function below.
- */
-enum xer_pbd_rval {
- XPBD_SYSTEM_FAILURE, /* System failure (memory shortage, etc) */
- XPBD_DECODER_LIMIT, /* Hit some decoder limitation or deficiency */
- XPBD_BROKEN_ENCODING, /* Encoding of a primitive body is broken */
- XPBD_NOT_BODY_IGNORE, /* Not a body format, but safe to ignore */
- XPBD_BODY_CONSUMED /* Body is recognized and consumed */
-};
-typedef enum xer_pbd_rval(xer_primitive_body_decoder_f)(
- const asn_TYPE_descriptor_t *td, void *struct_ptr, const void *chunk_buf,
- size_t chunk_size);
-
-/*
- * Specific function to decode simple primitive types.
- * Also see xer_decode_general() in xer_decoder.h
- */
-asn_dec_rval_t xer_decode_primitive(
- const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *type_descriptor, void **struct_ptr,
- size_t struct_size, const char *opt_mname, const void *buf_ptr, size_t size,
- xer_primitive_body_decoder_f *prim_body_decoder);
-
#ifdef __cplusplus
}
#endif
}
}
-#undef XER_ADVANCE
-#define XER_ADVANCE(num_bytes) do { \
- size_t num = num_bytes; \
- buf_ptr = (const void *)(((const char *)buf_ptr) + num); \
- size -= num; \
- consumed_myself += num; \
- } while(0)
-
-/*
- * Decode the XER (XML) data.
- */
-asn_dec_rval_t
-CHOICE_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *td, void **struct_ptr,
- const char *opt_mname, const void *buf_ptr, size_t size) {
- /*
- * Bring closer parts of structure description.
- */
- const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics;
- const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
-
- /*
- * Parts of the structure being constructed.
- */
- void *st = *struct_ptr; /* Target structure. */
- asn_struct_ctx_t *ctx; /* Decoder context */
-
- asn_dec_rval_t rval; /* Return value of a decoder */
- ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
- size_t edx; /* Element index */
-
- /*
- * Create the target structure if it is not present already.
- */
- if(st == 0) {
- st = *struct_ptr = CALLOC(1, specs->struct_size);
- if(st == 0) RETURN(RC_FAIL);
- }
-
- /*
- * Restore parsing context.
- */
- ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
- if(ctx->phase == 0 && !*xml_tag)
- ctx->phase = 1; /* Skip the outer tag checking phase */
-
- /*
- * Phases of XER/XML processing:
- * Phase 0: Check that the opening tag matches our expectations.
- * Phase 1: Processing body and reacting on closing tag.
- * Phase 2: Processing inner type.
- * Phase 3: Only waiting for closing tag.
- * Phase 4: Skipping unknown extensions.
- * Phase 5: PHASED OUT
- */
- for(edx = ctx->step; ctx->phase <= 4;) {
- pxer_chunk_type_e ch_type; /* XER chunk type */
- ssize_t ch_size; /* Chunk size */
- xer_check_tag_e tcv; /* Tag check value */
- asn_TYPE_member_t *elm;
-
- /*
- * Go inside the member.
- */
- if(ctx->phase == 2) {
- asn_dec_rval_t tmprval;
- void *memb_ptr; /* Pointer to the member */
- void **memb_ptr2; /* Pointer to that pointer */
- unsigned old_present;
-
- elm = &td->elements[edx];
-
- if(elm->flags & ATF_POINTER) {
- /* Member is a pointer to another structure */
- memb_ptr2 = (void **)((char *)st
- + elm->memb_offset);
- } else {
- memb_ptr = (char *)st + elm->memb_offset;
- memb_ptr2 = &memb_ptr;
- }
-
- /* Start/Continue decoding the inner member */
- tmprval = elm->type->op->xer_decoder(opt_codec_ctx,
- elm->type, memb_ptr2, elm->name,
- buf_ptr, size);
- XER_ADVANCE(tmprval.consumed);
- ASN_DEBUG("XER/CHOICE: itdf: [%s] code=%d",
- elm->type->name, tmprval.code);
- old_present = _fetch_present_idx(st,
- specs->pres_offset, specs->pres_size);
- assert(old_present == 0 || old_present == edx + 1);
- /* Record what we've got */
- _set_present_idx(st,
- specs->pres_offset, specs->pres_size, edx + 1);
- if(tmprval.code != RC_OK)
- RETURN(tmprval.code);
- ctx->phase = 3;
- /* Fall through */
- }
-
- /* No need to wait for closing tag; special mode. */
- if(ctx->phase == 3 && !*xml_tag) {
- ctx->phase = 5; /* Phase out */
- RETURN(RC_OK);
- }
-
- /*
- * Get the next part of the XML stream.
- */
- ch_size = xer_next_token(&ctx->context, buf_ptr, size, &ch_type);
- if(ch_size == -1) {
- RETURN(RC_FAIL);
- } else {
- switch(ch_type) {
- case PXER_WMORE:
- RETURN(RC_WMORE);
- case PXER_COMMENT: /* Got XML comment */
- case PXER_TEXT: /* Ignore free-standing text */
- XER_ADVANCE(ch_size); /* Skip silently */
- continue;
- case PXER_TAG:
- break; /* Check the rest down there */
- }
- }
-
- tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
- ASN_DEBUG("XER/CHOICE checked [%c%c%c%c] vs [%s], tcv=%d",
- ch_size>0?((const uint8_t *)buf_ptr)[0]:'?',
- ch_size>1?((const uint8_t *)buf_ptr)[1]:'?',
- ch_size>2?((const uint8_t *)buf_ptr)[2]:'?',
- ch_size>3?((const uint8_t *)buf_ptr)[3]:'?',
- xml_tag, tcv);
-
- /* Skip the extensions section */
- if(ctx->phase == 4) {
- ASN_DEBUG("skip_unknown(%d, %ld)",
- tcv, (long)ctx->left);
- switch(xer_skip_unknown(tcv, &ctx->left)) {
- case -1:
- ctx->phase = 5;
- RETURN(RC_FAIL);
- case 1:
- ctx->phase = 3;
- /* Fall through */
- case 0:
- XER_ADVANCE(ch_size);
- continue;
- case 2:
- ctx->phase = 3;
- break;
- }
- }
-
- switch(tcv) {
- case XCT_BOTH:
- break; /* No CHOICE? */
- case XCT_CLOSING:
- if(ctx->phase != 3)
- break;
- XER_ADVANCE(ch_size);
- ctx->phase = 5; /* Phase out */
- RETURN(RC_OK);
- case XCT_OPENING:
- if(ctx->phase == 0) {
- XER_ADVANCE(ch_size);
- ctx->phase = 1; /* Processing body phase */
- continue;
- }
- /* Fall through */
- case XCT_UNKNOWN_OP:
- case XCT_UNKNOWN_BO:
-
- if(ctx->phase != 1)
- break; /* Really unexpected */
-
- /*
- * Search which inner member corresponds to this tag.
- */
- for(edx = 0; edx < td->elements_count; edx++) {
- elm = &td->elements[edx];
- tcv = xer_check_tag(buf_ptr,ch_size,elm->name);
- switch(tcv) {
- case XCT_BOTH:
- case XCT_OPENING:
- /*
- * Process this member.
- */
- ctx->step = edx;
- ctx->phase = 2;
- break;
- case XCT_UNKNOWN_OP:
- case XCT_UNKNOWN_BO:
- continue;
- default:
- edx = td->elements_count;
- break; /* Phase out */
- }
- break;
- }
- if(edx != td->elements_count)
- continue;
-
- /* It is expected extension */
- if(specs->ext_start != -1) {
- ASN_DEBUG("Got anticipated extension");
- /*
- * Check for (XCT_BOTH or XCT_UNKNOWN_BO)
- * By using a mask. Only record a pure
- * <opening> tags.
- */
- if(tcv & XCT_CLOSING) {
- /* Found </extension> without body */
- ctx->phase = 3; /* Terminating */
- } else {
- ctx->left = 1;
- ctx->phase = 4; /* Skip ...'s */
- }
- XER_ADVANCE(ch_size);
- continue;
- }
-
- /* Fall through */
- default:
- break;
- }
-
- ASN_DEBUG("Unexpected XML tag [%c%c%c%c] in CHOICE [%s]"
- " (ph=%d, tag=%s)",
- ch_size>0?((const uint8_t *)buf_ptr)[0]:'?',
- ch_size>1?((const uint8_t *)buf_ptr)[1]:'?',
- ch_size>2?((const uint8_t *)buf_ptr)[2]:'?',
- ch_size>3?((const uint8_t *)buf_ptr)[3]:'?',
- td->name, ctx->phase, xml_tag);
- break;
- }
-
- ctx->phase = 5; /* Phase out, just in case */
- RETURN(RC_FAIL);
-}
-
-
asn_enc_rval_t
CHOICE_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb,
CHOICE_compare,
CHOICE_decode_ber,
CHOICE_encode_der,
- CHOICE_decode_xer,
CHOICE_encode_xer,
CHOICE_random_fill,
CHOICE_outmost_tag
asn_constr_check_f CHOICE_constraint;
ber_type_decoder_f CHOICE_decode_ber;
der_type_encoder_f CHOICE_encode_der;
-xer_type_decoder_f CHOICE_decode_xer;
xer_type_encoder_f CHOICE_encode_xer;
asn_outmost_tag_f CHOICE_outmost_tag;
asn_random_fill_f CHOICE_random_fill;
ASN__ENCODED_OK(erval);
}
-
-#undef XER_ADVANCE
-#define XER_ADVANCE(num_bytes) \
- do { \
- size_t num = (num_bytes); \
- ptr = ((const char *)ptr) + num; \
- size -= num; \
- consumed_myself += num; \
- } while(0)
-
-/*
- * Decode the XER (XML) data.
- */
-asn_dec_rval_t
-SEQUENCE_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *td, void **struct_ptr,
- const char *opt_mname, const void *ptr, size_t size) {
- /*
- * Bring closer parts of structure description.
- */
- const asn_SEQUENCE_specifics_t *specs
- = (const asn_SEQUENCE_specifics_t *)td->specifics;
- asn_TYPE_member_t *elements = td->elements;
- const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
-
- /*
- * ... and parts of the structure being constructed.
- */
- void *st = *struct_ptr; /* Target structure. */
- asn_struct_ctx_t *ctx; /* Decoder context */
-
- asn_dec_rval_t rval; /* Return value from a decoder */
- ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
- size_t edx; /* Element index */
-
- /*
- * Create the target structure if it is not present already.
- */
- if(st == 0) {
- st = *struct_ptr = CALLOC(1, specs->struct_size);
- if(st == 0) RETURN(RC_FAIL);
- }
-
- /*
- * Restore parsing context.
- */
- ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
-
-
- /*
- * Phases of XER/XML processing:
- * Phase 0: Check that the opening tag matches our expectations.
- * Phase 1: Processing body and reacting on closing tag.
- * Phase 2: Processing inner type.
- * Phase 3: Skipping unknown extensions.
- * Phase 4: PHASED OUT
- */
- for(edx = ctx->step; ctx->phase <= 3;) {
- pxer_chunk_type_e ch_type; /* XER chunk type */
- ssize_t ch_size; /* Chunk size */
- xer_check_tag_e tcv; /* Tag check value */
- asn_TYPE_member_t *elm;
-
- /*
- * Go inside the inner member of a sequence.
- */
- if(ctx->phase == 2) {
- asn_dec_rval_t tmprval;
- void *memb_ptr_dontuse; /* Pointer to the member */
- void **memb_ptr2; /* Pointer to that pointer */
-
- elm = &td->elements[edx];
-
- if(elm->flags & ATF_POINTER) {
- /* Member is a pointer to another structure */
- memb_ptr2 = (void **)((char *)st + elm->memb_offset);
- } else {
- memb_ptr_dontuse = (char *)st + elm->memb_offset;
- memb_ptr2 = &memb_ptr_dontuse; /* Only use of memb_ptr_dontuse */
- }
-
- if(elm->flags & ATF_OPEN_TYPE) {
- tmprval = OPEN_TYPE_xer_get(opt_codec_ctx, td, st, elm, ptr, size);
- } else {
- /* Invoke the inner type decoder, m.b. multiple times */
- tmprval = elm->type->op->xer_decoder(opt_codec_ctx,
- elm->type, memb_ptr2, elm->name,
- ptr, size);
- }
- XER_ADVANCE(tmprval.consumed);
- if(tmprval.code != RC_OK)
- RETURN(tmprval.code);
- ctx->phase = 1; /* Back to body processing */
- ctx->step = ++edx;
- ASN_DEBUG("XER/SEQUENCE phase => %d, step => %d",
- ctx->phase, ctx->step);
- /* Fall through */
- }
-
- /*
- * Get the next part of the XML stream.
- */
- ch_size = xer_next_token(&ctx->context, ptr, size,
- &ch_type);
- if(ch_size == -1) {
- RETURN(RC_FAIL);
- } else {
- switch(ch_type) {
- case PXER_WMORE:
- RETURN(RC_WMORE);
- case PXER_COMMENT: /* Got XML comment */
- case PXER_TEXT: /* Ignore free-standing text */
- XER_ADVANCE(ch_size); /* Skip silently */
- continue;
- case PXER_TAG:
- break; /* Check the rest down there */
- }
- }
-
- tcv = xer_check_tag(ptr, ch_size, xml_tag);
- ASN_DEBUG("XER/SEQUENCE: tcv = %d, ph=%d [%s]",
- tcv, ctx->phase, xml_tag);
-
- /* Skip the extensions section */
- if(ctx->phase == 3) {
- switch(xer_skip_unknown(tcv, &ctx->left)) {
- case -1:
- ctx->phase = 4;
- RETURN(RC_FAIL);
- case 0:
- XER_ADVANCE(ch_size);
- continue;
- case 1:
- XER_ADVANCE(ch_size);
- ctx->phase = 1;
- continue;
- case 2:
- ctx->phase = 1;
- break;
- }
- }
-
- switch(tcv) {
- case XCT_CLOSING:
- if(ctx->phase == 0) break;
- ctx->phase = 0;
- /* Fall through */
- case XCT_BOTH:
- if(ctx->phase == 0) {
- if(edx >= td->elements_count ||
- /* Explicit OPTIONAL specs reaches the end */
- (edx + elements[edx].optional == td->elements_count) ||
- /* All extensions are optional */
- IN_EXTENSION_GROUP(specs, edx)) {
- XER_ADVANCE(ch_size);
- ctx->phase = 4; /* Phase out */
- RETURN(RC_OK);
- } else {
- ASN_DEBUG("Premature end of XER SEQUENCE");
- RETURN(RC_FAIL);
- }
- }
- /* Fall through */
- case XCT_OPENING:
- if(ctx->phase == 0) {
- XER_ADVANCE(ch_size);
- ctx->phase = 1; /* Processing body phase */
- continue;
- }
- /* Fall through */
- case XCT_UNKNOWN_OP:
- case XCT_UNKNOWN_BO:
-
- ASN_DEBUG("XER/SEQUENCE: tcv=%d, ph=%d, edx=%" ASN_PRI_SIZE "",
- tcv, ctx->phase, edx);
- if(ctx->phase != 1) {
- break; /* Really unexpected */
- }
-
- if(edx < td->elements_count) {
- /*
- * Search which member corresponds to this tag.
- */
- size_t n;
- size_t edx_end = edx + elements[edx].optional + 1;
- if(edx_end > td->elements_count)
- edx_end = td->elements_count;
- for(n = edx; n < edx_end; n++) {
- elm = &td->elements[n];
- tcv = xer_check_tag(ptr, ch_size, elm->name);
- switch(tcv) {
- case XCT_BOTH:
- case XCT_OPENING:
- /*
- * Process this member.
- */
- ctx->step = edx = n;
- ctx->phase = 2;
- break;
- case XCT_UNKNOWN_OP:
- case XCT_UNKNOWN_BO:
- continue;
- default:
- n = edx_end;
- break; /* Phase out */
- }
- break;
- }
- if(n != edx_end)
- continue;
- } else {
- ASN_DEBUG("Out of defined members: %" ASN_PRI_SIZE "/%u",
- edx, td->elements_count);
- }
-
- /* It is expected extension */
- if(IN_EXTENSION_GROUP(specs,
- edx + (edx < td->elements_count
- ? elements[edx].optional : 0))) {
- ASN_DEBUG("Got anticipated extension at %" ASN_PRI_SIZE "",
- edx);
- /*
- * Check for (XCT_BOTH or XCT_UNKNOWN_BO)
- * By using a mask. Only record a pure
- * <opening> tags.
- */
- if(tcv & XCT_CLOSING) {
- /* Found </extension> without body */
- } else {
- ctx->left = 1;
- ctx->phase = 3; /* Skip ...'s */
- }
- XER_ADVANCE(ch_size);
- continue;
- }
-
- /* Fall through */
- default:
- break;
- }
-
- ASN_DEBUG("Unexpected XML tag in SEQUENCE [%c%c%c%c%c%c]",
- size>0?((const char *)ptr)[0]:'.',
- size>1?((const char *)ptr)[1]:'.',
- size>2?((const char *)ptr)[2]:'.',
- size>3?((const char *)ptr)[3]:'.',
- size>4?((const char *)ptr)[4]:'.',
- size>5?((const char *)ptr)[5]:'.');
- break;
- }
-
- ctx->phase = 4; /* "Phase out" on hard failure */
- RETURN(RC_FAIL);
-}
-
asn_enc_rval_t
SEQUENCE_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
int ilevel, enum xer_encoder_flags_e flags,
SEQUENCE_compare,
SEQUENCE_decode_ber,
SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
SEQUENCE_encode_xer,
SEQUENCE_random_fill,
0 /* Use generic outmost tag fetcher */
asn_constr_check_f SEQUENCE_constraint;
ber_type_decoder_f SEQUENCE_decode_ber;
der_type_encoder_f SEQUENCE_encode_der;
-xer_type_decoder_f SEQUENCE_decode_xer;
xer_type_encoder_f SEQUENCE_encode_xer;
asn_random_fill_f SEQUENCE_random_fill;
extern asn_TYPE_operation_t asn_OP_SEQUENCE;
SEQUENCE_OF_compare,
SEQUENCE_OF_decode_ber,
SEQUENCE_OF_encode_der,
- SEQUENCE_OF_decode_xer,
SEQUENCE_OF_encode_xer,
SEQUENCE_OF_random_fill,
0 /* Use generic outmost tag fetcher */
#define SEQUENCE_OF_print SET_OF_print
#define SEQUENCE_OF_constraint SET_OF_constraint
#define SEQUENCE_OF_decode_ber SET_OF_decode_ber
-#define SEQUENCE_OF_decode_xer SET_OF_decode_xer
#define SEQUENCE_OF_random_fill SET_OF_random_fill
#ifdef __cplusplus
}
}
-#undef XER_ADVANCE
-#define XER_ADVANCE(num_bytes) do { \
- size_t num = num_bytes; \
- buf_ptr = ((const char *)buf_ptr) + num;\
- size -= num; \
- consumed_myself += num; \
- } while(0)
-
-/*
- * Decode the XER (XML) data.
- */
-asn_dec_rval_t
-SET_OF_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *td, void **struct_ptr,
- const char *opt_mname, const void *buf_ptr, size_t size) {
- /*
- * Bring closer parts of structure description.
- */
- const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics;
- const asn_TYPE_member_t *element = td->elements;
- const char *elm_tag;
- const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
-
- /*
- * ... and parts of the structure being constructed.
- */
- void *st = *struct_ptr; /* Target structure. */
- asn_struct_ctx_t *ctx; /* Decoder context */
-
- asn_dec_rval_t rval; /* Return value from a decoder */
- ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
-
- /*
- * Create the target structure if it is not present already.
- */
- if(st == 0) {
- st = *struct_ptr = CALLOC(1, specs->struct_size);
- if(st == 0) RETURN(RC_FAIL);
- }
-
- /* Which tag is expected for the downstream */
- if(specs->as_XMLValueList) {
- elm_tag = (specs->as_XMLValueList == 1) ? 0 : "";
- } else {
- elm_tag = (*element->name)
- ? element->name : element->type->xml_tag;
- }
-
- /*
- * Restore parsing context.
- */
- ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
-
- /*
- * Phases of XER/XML processing:
- * Phase 0: Check that the opening tag matches our expectations.
- * Phase 1: Processing body and reacting on closing tag.
- * Phase 2: Processing inner type.
- */
- for(; ctx->phase <= 2;) {
- pxer_chunk_type_e ch_type; /* XER chunk type */
- ssize_t ch_size; /* Chunk size */
- xer_check_tag_e tcv; /* Tag check value */
-
- /*
- * Go inside the inner member of a set.
- */
- if(ctx->phase == 2) {
- asn_dec_rval_t tmprval;
-
- /* Invoke the inner type decoder, m.b. multiple times */
- ASN_DEBUG("XER/SET OF element [%s]", elm_tag);
- tmprval = element->type->op->xer_decoder(opt_codec_ctx,
- element->type, &ctx->ptr, elm_tag,
- buf_ptr, size);
- if(tmprval.code == RC_OK) {
- asn_anonymous_set_ *list = _A_SET_FROM_VOID(st);
- if(ASN_SET_ADD(list, ctx->ptr) != 0)
- RETURN(RC_FAIL);
- ctx->ptr = 0;
- XER_ADVANCE(tmprval.consumed);
- } else {
- XER_ADVANCE(tmprval.consumed);
- RETURN(tmprval.code);
- }
- ctx->phase = 1; /* Back to body processing */
- ASN_DEBUG("XER/SET OF phase => %d", ctx->phase);
- /* Fall through */
- }
-
- /*
- * Get the next part of the XML stream.
- */
- ch_size = xer_next_token(&ctx->context,
- buf_ptr, size, &ch_type);
- if(ch_size == -1) {
- RETURN(RC_FAIL);
- } else {
- switch(ch_type) {
- case PXER_WMORE:
- RETURN(RC_WMORE);
- case PXER_COMMENT: /* Got XML comment */
- case PXER_TEXT: /* Ignore free-standing text */
- XER_ADVANCE(ch_size); /* Skip silently */
- continue;
- case PXER_TAG:
- break; /* Check the rest down there */
- }
- }
-
- tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
- ASN_DEBUG("XER/SET OF: tcv = %d, ph=%d t=%s",
- tcv, ctx->phase, xml_tag);
- switch(tcv) {
- case XCT_CLOSING:
- if(ctx->phase == 0) break;
- ctx->phase = 0;
- /* Fall through */
- case XCT_BOTH:
- if(ctx->phase == 0) {
- /* No more things to decode */
- XER_ADVANCE(ch_size);
- ctx->phase = 3; /* Phase out */
- RETURN(RC_OK);
- }
- /* Fall through */
- case XCT_OPENING:
- if(ctx->phase == 0) {
- XER_ADVANCE(ch_size);
- ctx->phase = 1; /* Processing body phase */
- continue;
- }
- /* Fall through */
- case XCT_UNKNOWN_OP:
- case XCT_UNKNOWN_BO:
-
- ASN_DEBUG("XER/SET OF: tcv=%d, ph=%d", tcv, ctx->phase);
- if(ctx->phase == 1) {
- /*
- * Process a single possible member.
- */
- ctx->phase = 2;
- continue;
- }
- /* Fall through */
- default:
- break;
- }
-
- ASN_DEBUG("Unexpected XML tag in SET OF");
- break;
- }
-
- ctx->phase = 3; /* "Phase out" on hard failure */
- RETURN(RC_FAIL);
-}
-
-
-
typedef struct xer_tmp_enc_s {
void *buffer;
size_t offset;
SET_OF_compare,
SET_OF_decode_ber,
SET_OF_encode_der,
- SET_OF_decode_xer,
SET_OF_encode_xer,
SET_OF_random_fill,
0 /* Use generic outmost tag fetcher */
asn_constr_check_f SET_OF_constraint;
ber_type_decoder_f SET_OF_decode_ber;
der_type_encoder_f SET_OF_encode_der;
-xer_type_decoder_f SET_OF_decode_xer;
xer_type_encoder_f SET_OF_encode_xer;
asn_random_fill_f SET_OF_random_fill;
extern asn_TYPE_operation_t asn_OP_SET_OF;
#include "asn1/asn1c/ber_decoder.h" /* Basic Encoding Rules decoder */
#include "asn1/asn1c/der_encoder.h" /* Distinguished Encoding Rules encoder */
-#include "asn1/asn1c/xer_decoder.h" /* Decoder of XER (XML, text) */
#include "asn1/asn1c/xer_encoder.h" /* Encoder into XER (XML, text) */
#include "asn1/asn1c/constraints.h" /* Subtype constraints support */
#include "asn1/asn1c/asn_random_fill.h" /* Random structures support */
asn_struct_compare_f *compare_struct; /* Compare two structures */
ber_type_decoder_f *ber_decoder; /* Generic BER decoder */
der_type_encoder_f *der_encoder; /* Canonical DER encoder */
- xer_type_decoder_f *xer_decoder; /* Generic XER decoder */
xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */
asn_random_fill_f *random_fill; /* Initialize with a random value */
asn_outmost_tag_f *outmost_tag; /* <optional, internal> */
+++ /dev/null
-/*
- * Copyright (c) 2004-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-
-#include <assert.h>
-
-#include "asn1/asn1c/asn_application.h"
-#include "asn1/asn1c/asn_internal.h"
-#include "asn1/asn1c/xer_support.h" /* XER/XML parsing support */
-
-
-/*
- * Decode the XER encoding of a given type.
- */
-asn_dec_rval_t
-xer_decode(const asn_codec_ctx_t *opt_codec_ctx,
- const asn_TYPE_descriptor_t *td, void **struct_ptr,
- const void *buffer, size_t size) {
- asn_codec_ctx_t s_codec_ctx;
-
- /*
- * Stack checker requires that the codec context
- * must be allocated on the stack.
- */
- if(opt_codec_ctx) {
- if(opt_codec_ctx->max_stack_size) {
- s_codec_ctx = *opt_codec_ctx;
- opt_codec_ctx = &s_codec_ctx;
- }
- } else {
- /* If context is not given, be security-conscious anyway */
- memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
- s_codec_ctx.max_stack_size = ASN__DEFAULT_STACK_MAX;
- opt_codec_ctx = &s_codec_ctx;
- }
-
- /*
- * Invoke type-specific decoder.
- */
- return td->op->xer_decoder(opt_codec_ctx, td, struct_ptr, 0, buffer, size);
-}
-
-
-
-struct xer__cb_arg {
- pxml_chunk_type_e chunk_type;
- size_t chunk_size;
- const void *chunk_buf;
- int callback_not_invoked;
-};
-
-static int
-xer__token_cb(pxml_chunk_type_e type, const void *_chunk_data, size_t _chunk_size, void *key) {
- struct xer__cb_arg *arg = (struct xer__cb_arg *)key;
- arg->chunk_type = type;
- arg->chunk_size = _chunk_size;
- arg->chunk_buf = _chunk_data;
- arg->callback_not_invoked = 0;
- return -1; /* Terminate the XML parsing */
-}
-
-/*
- * Fetch the next token from the XER/XML stream.
- */
-ssize_t
-xer_next_token(int *stateContext, const void *buffer, size_t size, pxer_chunk_type_e *ch_type) {
- struct xer__cb_arg arg;
- int new_stateContext = *stateContext;
- ssize_t ret;
-
- arg.callback_not_invoked = 1;
- ret = pxml_parse(&new_stateContext, buffer, size, xer__token_cb, &arg);
- if(ret < 0) return -1;
- if(arg.callback_not_invoked) {
- assert(ret == 0); /* No data was consumed */
- *ch_type = PXER_WMORE;
- return 0; /* Try again with more data */
- } else {
- assert(arg.chunk_size);
- assert(arg.chunk_buf == buffer);
- }
-
- /*
- * Translate the XML chunk types into more convenient ones.
- */
- switch(arg.chunk_type) {
- case PXML_TEXT:
- *ch_type = PXER_TEXT;
- break;
- case PXML_TAG:
- *ch_type = PXER_WMORE;
- return 0; /* Want more */
- case PXML_TAG_END:
- *ch_type = PXER_TAG;
- break;
- case PXML_COMMENT:
- case PXML_COMMENT_END:
- *ch_type = PXER_COMMENT;
- break;
- }
-
- *stateContext = new_stateContext;
- return arg.chunk_size;
-}
-
-#define CSLASH 0x2f /* '/' */
-#define LANGLE 0x3c /* '<' */
-#define RANGLE 0x3e /* '>' */
-
-xer_check_tag_e
-xer_check_tag(const void *buf_ptr, int size, const char *need_tag) {
- const char *buf = (const char *)buf_ptr;
- const char *end;
- xer_check_tag_e ct = XCT_OPENING;
-
- if(size < 2 || buf[0] != LANGLE || buf[size-1] != RANGLE) {
- if(size >= 2)
- ASN_DEBUG("Broken XML tag: \"%c...%c\"",
- buf[0], buf[size - 1]);
- return XCT_BROKEN;
- }
-
- /*
- * Determine the tag class.
- */
- if(buf[1] == CSLASH) {
- buf += 2; /* advance past "</" */
- size -= 3; /* strip "</" and ">" */
- ct = XCT_CLOSING;
- if(size > 0 && buf[size-1] == CSLASH)
- return XCT_BROKEN; /* </abc/> */
- } else {
- buf++; /* advance past "<" */
- size -= 2; /* strip "<" and ">" */
- if(size > 0 && buf[size-1] == CSLASH) {
- ct = XCT_BOTH;
- size--; /* One more, for "/" */
- }
- }
-
- /* Sometimes we don't care about the tag */
- if(!need_tag || !*need_tag)
- return (xer_check_tag_e)(XCT__UNK__MASK | ct);
-
- /*
- * Determine the tag name.
- */
- for(end = buf + size; buf < end; buf++, need_tag++) {
- int b = *buf, n = *need_tag;
- if(b != n) {
- if(n == 0) {
- switch(b) {
- case 0x09: case 0x0a: case 0x0c: case 0x0d:
- case 0x20:
- /* "<abc def/>": whitespace is normal */
- return ct;
- }
- }
- return (xer_check_tag_e)(XCT__UNK__MASK | ct);
- }
- if(b == 0)
- return XCT_BROKEN; /* Embedded 0 in buf?! */
- }
- if(*need_tag)
- return (xer_check_tag_e)(XCT__UNK__MASK | ct);
-
- return ct;
-}
-
-
-#undef ADVANCE
-#define ADVANCE(num_bytes) do { \
- size_t num = (num_bytes); \
- buf_ptr = ((const char *)buf_ptr) + num; \
- size -= num; \
- consumed_myself += num; \
- } while(0)
-
-#undef RETURN
-#define RETURN(_code) do { \
- rval.code = _code; \
- rval.consumed = consumed_myself; \
- if(rval.code != RC_OK) \
- ASN_DEBUG("Failed with %d", rval.code); \
- return rval; \
- } while(0)
-
-#define XER_GOT_BODY(chunk_buf, chunk_size, size) do { \
- ssize_t converted_size = body_receiver \
- (struct_key, chunk_buf, chunk_size, \
- (size_t)chunk_size < size); \
- if(converted_size == -1) RETURN(RC_FAIL); \
- if(converted_size == 0 \
- && size == (size_t)chunk_size) \
- RETURN(RC_WMORE); \
- chunk_size = converted_size; \
- } while(0)
-#define XER_GOT_EMPTY() do { \
- if(body_receiver(struct_key, 0, 0, size > 0) == -1) \
- RETURN(RC_FAIL); \
- } while(0)
-
-/*
- * Generalized function for decoding the primitive values.
- */
-asn_dec_rval_t
-xer_decode_general(const asn_codec_ctx_t *opt_codec_ctx,
- asn_struct_ctx_t *ctx, /* Type decoder context */
- void *struct_key,
- const char *xml_tag, /* Expected XML tag */
- const void *buf_ptr, size_t size,
- int (*opt_unexpected_tag_decoder)
- (void *struct_key, const void *chunk_buf, size_t chunk_size),
- ssize_t (*body_receiver)
- (void *struct_key, const void *chunk_buf, size_t chunk_size,
- int have_more)
- ) {
-
- asn_dec_rval_t rval;
- ssize_t consumed_myself = 0;
-
- (void)opt_codec_ctx;
-
- /*
- * Phases of XER/XML processing:
- * Phase 0: Check that the opening tag matches our expectations.
- * Phase 1: Processing body and reacting on closing tag.
- */
- if(ctx->phase > 1) RETURN(RC_FAIL);
- for(;;) {
- pxer_chunk_type_e ch_type; /* XER chunk type */
- ssize_t ch_size; /* Chunk size */
- xer_check_tag_e tcv; /* Tag check value */
-
- /*
- * Get the next part of the XML stream.
- */
- ch_size = xer_next_token(&ctx->context, buf_ptr, size,
- &ch_type);
- if(ch_size == -1) {
- RETURN(RC_FAIL);
- } else {
- switch(ch_type) {
- case PXER_WMORE:
- RETURN(RC_WMORE);
- case PXER_COMMENT: /* Got XML comment */
- ADVANCE(ch_size); /* Skip silently */
- continue;
- case PXER_TEXT:
- if(ctx->phase == 0) {
- /*
- * We have to ignore whitespace here,
- * but in order to be forward compatible
- * with EXTENDED-XER (EMBED-VALUES, #25)
- * any text is just ignored here.
- */
- } else {
- XER_GOT_BODY(buf_ptr, ch_size, size);
- }
- ADVANCE(ch_size);
- continue;
- case PXER_TAG:
- break; /* Check the rest down there */
- }
- }
-
- assert(ch_type == PXER_TAG && size);
-
- tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
- /*
- * Phase 0:
- * Expecting the opening tag
- * for the type being processed.
- * Phase 1:
- * Waiting for the closing XML tag.
- */
- switch(tcv) {
- case XCT_BOTH:
- if(ctx->phase) break;
- /* Finished decoding of an empty element */
- XER_GOT_EMPTY();
- ADVANCE(ch_size);
- ctx->phase = 2; /* Phase out */
- RETURN(RC_OK);
- case XCT_OPENING:
- if(ctx->phase) break;
- ADVANCE(ch_size);
- ctx->phase = 1; /* Processing body phase */
- continue;
- case XCT_CLOSING:
- if(!ctx->phase) break;
- ADVANCE(ch_size);
- ctx->phase = 2; /* Phase out */
- RETURN(RC_OK);
- case XCT_UNKNOWN_BO:
- /*
- * Certain tags in the body may be expected.
- */
- if(opt_unexpected_tag_decoder
- && opt_unexpected_tag_decoder(struct_key,
- buf_ptr, ch_size) >= 0) {
- /* Tag's processed fine */
- ADVANCE(ch_size);
- if(!ctx->phase) {
- /* We are not expecting
- * the closing tag anymore. */
- ctx->phase = 2; /* Phase out */
- RETURN(RC_OK);
- }
- continue;
- }
- /* Fall through */
- default:
- break; /* Unexpected tag */
- }
-
- ASN_DEBUG("Unexpected XML tag (expected \"%s\")", xml_tag);
- break; /* Dark and mysterious things have just happened */
- }
-
- RETURN(RC_FAIL);
-}
-
-
-size_t
-xer_whitespace_span(const void *chunk_buf, size_t chunk_size) {
- const char *p = (const char *)chunk_buf;
- const char *pend = p + chunk_size;
-
- for(; p < pend; p++) {
- switch(*p) {
- /* X.693, #8.1.4
- * HORISONTAL TAB (9)
- * LINE FEED (10)
- * CARRIAGE RETURN (13)
- * SPACE (32)
- */
- case 0x09: case 0x0a: case 0x0d: case 0x20:
- continue;
- default:
- break;
- }
- break;
- }
- return (p - (const char *)chunk_buf);
-}
-
-/*
- * This is a vastly simplified, non-validating XML tree skipper.
- */
-int
-xer_skip_unknown(xer_check_tag_e tcv, ber_tlv_len_t *depth) {
- assert(*depth > 0);
- switch(tcv) {
- case XCT_BOTH:
- case XCT_UNKNOWN_BO:
- /* These negate each other. */
- return 0;
- case XCT_OPENING:
- case XCT_UNKNOWN_OP:
- ++(*depth);
- return 0;
- case XCT_CLOSING:
- case XCT_UNKNOWN_CL:
- if(--(*depth) == 0)
- return (tcv == XCT_CLOSING) ? 2 : 1;
- return 0;
- default:
- return -1;
- }
-}
+++ /dev/null
-/*-
- * Copyright (c) 2004-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _XER_DECODER_H_
-#define _XER_DECODER_H_
-
-#include "asn1/asn1c/asn_application.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct asn_TYPE_descriptor_s; /* Forward declaration */
-
-/*
- * The XER decoder of any ASN.1 type. May be invoked by the application.
- * Decodes CANONICAL-XER and BASIC-XER.
- */
-asn_dec_rval_t xer_decode(
- const struct asn_codec_ctx_s *opt_codec_ctx,
- const struct asn_TYPE_descriptor_s *type_descriptor,
- void **struct_ptr, /* Pointer to a target structure's pointer */
- const void *buffer, /* Data to be decoded */
- size_t size /* Size of data buffer */
-);
-
-/*
- * Type of the type-specific XER decoder function.
- */
-typedef asn_dec_rval_t(xer_type_decoder_f)(
- const asn_codec_ctx_t *opt_codec_ctx,
- const struct asn_TYPE_descriptor_s *type_descriptor, void **struct_ptr,
- const char *opt_mname, /* Member name */
- const void *buf_ptr, size_t size);
-
-/*******************************
- * INTERNALLY USEFUL FUNCTIONS *
- *******************************/
-
-/*
- * Generalized function for decoding the primitive values.
- * Used by more specialized functions, such as OCTET_STRING_decode_xer_utf8
- * and others. This function should not be used by applications, as its API
- * is subject to changes.
- */
-asn_dec_rval_t xer_decode_general(
- const asn_codec_ctx_t *opt_codec_ctx,
- asn_struct_ctx_t *ctx, /* Type decoder context */
- void *struct_key, /* Treated as opaque pointer */
- const char *xml_tag, /* Expected XML tag name */
- const void *buf_ptr, size_t size,
- int (*opt_unexpected_tag_decoder)(void *struct_key, const void *chunk_buf,
- size_t chunk_size),
- ssize_t (*body_receiver)(void *struct_key, const void *chunk_buf,
- size_t chunk_size, int have_more));
-
-
-/*
- * Fetch the next XER (XML) token from the stream.
- * The function returns the number of bytes occupied by the chunk type,
- * returned in the _ch_type. The _ch_type is only set (and valid) when
- * the return value is >= 0.
- */
- typedef enum pxer_chunk_type {
- PXER_WMORE, /* Chunk type is not clear, more data expected. */
- PXER_TAG, /* Complete XER tag */
- PXER_TEXT, /* Plain text between XER tags */
- PXER_COMMENT /* A comment, may be part of */
- } pxer_chunk_type_e;
-ssize_t xer_next_token(int *stateContext,
- const void *buffer, size_t size, pxer_chunk_type_e *_ch_type);
-
-/*
- * This function checks the buffer against the tag name is expected to occur.
- */
- typedef enum xer_check_tag {
- XCT_BROKEN = 0, /* The tag is broken */
- XCT_OPENING = 1, /* This is the <opening> tag */
- XCT_CLOSING = 2, /* This is the </closing> tag */
- XCT_BOTH = 3, /* This is the <modified/> tag */
- XCT__UNK__MASK = 4, /* Mask of everything unexpected */
- XCT_UNKNOWN_OP = 5, /* Unexpected <opening> tag */
- XCT_UNKNOWN_CL = 6, /* Unexpected </closing> tag */
- XCT_UNKNOWN_BO = 7 /* Unexpected <modified/> tag */
- } xer_check_tag_e;
-xer_check_tag_e xer_check_tag(const void *buf_ptr, int size,
- const char *need_tag);
-
-/*
- * Get the number of bytes consisting entirely of XER whitespace characters.
- * RETURN VALUES:
- * >=0: Number of whitespace characters in the string.
- */
-size_t xer_whitespace_span(const void *chunk_buf, size_t chunk_size);
-
-/*
- * Skip the series of anticipated extensions.
- */
-int xer_skip_unknown(xer_check_tag_e tcv, ber_tlv_len_t *depth);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _XER_DECODER_H_ */
return fflush(stream);
}
-
-struct xer_buffer {
- char *buffer;
- size_t buffer_size;
- size_t allocated_size;
-};
-
-static int
-xer__buffer_append(const void *buffer, size_t size, void *app_key) {
- struct xer_buffer *xb = app_key;
-
- while(xb->buffer_size + size + 1 > xb->allocated_size) {
- size_t new_size = 2 * (xb->allocated_size ? xb->allocated_size : 64);
- char *new_buf = MALLOC(new_size);
- if(!new_buf) return -1;
- if (xb->buffer) {
- memcpy(new_buf, xb->buffer, xb->buffer_size);
- }
- FREEMEM(xb->buffer);
- xb->buffer = new_buf;
- xb->allocated_size = new_size;
- }
-
- memcpy(xb->buffer + xb->buffer_size, buffer, size);
- xb->buffer_size += size;
- xb->buffer[xb->buffer_size] = '\0';
- return 0;
-}
-
-enum xer_equivalence_e
-xer_equivalent(const struct asn_TYPE_descriptor_s *td, const void *struct1,
- const void *struct2, FILE *opt_debug_stream) {
- struct xer_buffer xb1 = {0, 0, 0};
- struct xer_buffer xb2 = {0, 0, 0};
- asn_enc_rval_t e1, e2;
- asn_dec_rval_t rval;
- void *sptr = NULL;
-
- if(!td || !struct1 || !struct2) {
- if(opt_debug_stream) {
- if(!td) fprintf(opt_debug_stream, "Type descriptor missing\n");
- if(!struct1) fprintf(opt_debug_stream, "Structure 1 missing\n");
- if(!struct2) fprintf(opt_debug_stream, "Structure 2 missing\n");
- }
- return XEQ_FAILURE;
- }
-
- e1 = xer_encode(td, struct1, XER_F_BASIC, xer__buffer_append, &xb1);
- if(e1.encoded == -1) {
- if(opt_debug_stream) {
- fprintf(stderr, "XER Encoding of %s failed\n", td->name);
- }
- FREEMEM(xb1.buffer);
- return XEQ_ENCODE1_FAILED;
- }
-
- e2 = xer_encode(td, struct2, XER_F_BASIC, xer__buffer_append, &xb2);
- if(e2.encoded == -1) {
- if(opt_debug_stream) {
- fprintf(stderr, "XER Encoding of %s failed\n", td->name);
- }
- FREEMEM(xb1.buffer);
- FREEMEM(xb2.buffer);
- return XEQ_ENCODE1_FAILED;
- }
-
- if(xb1.buffer_size != xb2.buffer_size
- || memcmp(xb1.buffer, xb2.buffer, xb1.buffer_size) != 0) {
- if(opt_debug_stream) {
- fprintf(opt_debug_stream,
- "Structures XER-encoded into different byte streams:\n=== "
- "Structure 1 ===\n%s\n=== Structure 2 ===\n%s\n",
- xb1.buffer, xb2.buffer);
- }
- FREEMEM(xb1.buffer);
- FREEMEM(xb2.buffer);
- return XEQ_DIFFERENT;
- } else {
- if(opt_debug_stream) {
- fprintf(opt_debug_stream,
- "Both structures encoded into the same XER byte stream "
- "of size %" ASN_PRI_SIZE ":\n%s",
- xb1.buffer_size, xb1.buffer);
- }
- }
-
- rval = xer_decode(NULL, td, (void **)&sptr, xb1.buffer,
- xb1.buffer_size);
- switch(rval.code) {
- case RC_OK:
- break;
- case RC_WMORE:
- if(opt_debug_stream) {
- fprintf(opt_debug_stream,
- "Structure %s XER decode unexpectedly requires "
- "more data:\n%s\n",
- td->name, xb1.buffer);
- }
- /* Fall through */
- case RC_FAIL:
- default:
- if(opt_debug_stream) {
- fprintf(opt_debug_stream,
- "Structure %s XER decoding resulted in failure.\n",
- td->name);
- }
- ASN_STRUCT_FREE(*td, sptr);
- FREEMEM(xb1.buffer);
- FREEMEM(xb2.buffer);
- return XEQ_DECODE_FAILED;
- }
-
- if(rval.consumed != xb1.buffer_size
- && ((rval.consumed > xb1.buffer_size)
- || xer_whitespace_span(xb1.buffer + rval.consumed,
- xb1.buffer_size - rval.consumed)
- != (xb1.buffer_size - rval.consumed))) {
- if(opt_debug_stream) {
- fprintf(opt_debug_stream,
- "Round-trip decode of %s required less bytes (%" ASN_PRI_SIZE ") than "
- "encoded (%" ASN_PRI_SIZE ")\n",
- td->name, rval.consumed, xb1.buffer_size);
- }
- ASN_STRUCT_FREE(*td, sptr);
- FREEMEM(xb1.buffer);
- FREEMEM(xb2.buffer);
- return XEQ_ROUND_TRIP_FAILED;
- }
-
- /*
- * Reuse xb2 to encode newly decoded structure.
- */
- FREEMEM(xb2.buffer);
- memset(&xb2, 0, sizeof(xb2));
-
- e2 = xer_encode(td, sptr, XER_F_BASIC, xer__buffer_append, &xb2);
- if(e2.encoded == -1) {
- if(opt_debug_stream) {
- fprintf(stderr, "XER Encoding of round-trip decode of %s failed\n",
- td->name);
- }
- ASN_STRUCT_FREE(*td, sptr);
- FREEMEM(xb1.buffer);
- FREEMEM(xb2.buffer);
- return XEQ_ROUND_TRIP_FAILED;
- }
-
- ASN_STRUCT_FREE(*td, sptr);
- sptr = 0;
-
- if(xb1.buffer_size != xb2.buffer_size
- || memcmp(xb1.buffer, xb2.buffer, xb1.buffer_size) != 0) {
- if(opt_debug_stream) {
- fprintf(opt_debug_stream,
- "XER Encoding of round-trip decode of %s resulted in "
- "different byte stream:\n"
- "=== Original ===\n%s\n"
- "=== Round-tripped ===\n%s\n",
- xb1.buffer, xb2.buffer, td->name);
- }
- FREEMEM(xb1.buffer);
- FREEMEM(xb2.buffer);
- return XEQ_ROUND_TRIP_FAILED;
- }
-
- FREEMEM(xb1.buffer);
- FREEMEM(xb2.buffer);
- return XEQ_SUCCESS;
-}
int xer_fprint(FILE *stream, const struct asn_TYPE_descriptor_s *td,
const void *struct_ptr);
-/*
- * A helper function that uses XER encoding/decoding to verify that:
- * - Both structures encode into the same BASIC XER.
- * - Both resulting XER byte streams can be decoded back.
- * - Both decoded structures encode into the same BASIC XER (round-trip).
- * All of this verifies equivalence between structures and a round-trip.
- * ARGUMENTS:
- * (opt_debug_stream) - If specified, prints ongoing details.
- */
-enum xer_equivalence_e {
- XEQ_SUCCESS, /* The only completely positive return value */
- XEQ_FAILURE, /* General failure */
- XEQ_ENCODE1_FAILED, /* First sructure XER encoding failed */
- XEQ_ENCODE2_FAILED, /* Second structure XER encoding failed */
- XEQ_DIFFERENT, /* Structures encoded into different XER */
- XEQ_DECODE_FAILED, /* Decode of the XER data failed */
- XEQ_ROUND_TRIP_FAILED /* Bad round-trip */
-};
-enum xer_equivalence_e xer_equivalent(
- const struct asn_TYPE_descriptor_s *type_descriptor, const void *struct1,
- const void *struct2, FILE *opt_debug_stream);
-
/*
* Type of the generic XER encoder.
*/
+++ /dev/null
-/*
- * Copyright (c) 2003, 2004 X/IO Labs, xiolabs.com.
- * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include "asn1/asn1c/asn_system.h"
-#include "asn1/asn1c/xer_support.h"
-
-/* Parser states */
-typedef enum {
- ST_TEXT,
- ST_TAG_START,
- ST_TAG_BODY,
- ST_TAG_QUOTE_WAIT,
- ST_TAG_QUOTED_STRING,
- ST_TAG_UNQUOTED_STRING,
- ST_COMMENT_WAIT_DASH1, /* "<!--"[1] */
- ST_COMMENT_WAIT_DASH2, /* "<!--"[2] */
- ST_COMMENT,
- ST_COMMENT_CLO_DASH2, /* "-->"[0] */
- ST_COMMENT_CLO_RT /* "-->"[1] */
-} pstate_e;
-
-static const int
-_charclass[256] = {
- 0,0,0,0,0,0,0,0, 0,1,1,0,1,1,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 2,2,2,2,2,2,2,2, 2,2,0,0,0,0,0,0, /* 01234567 89 */
- 0,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, /* ABCDEFG HIJKLMNO */
- 3,3,3,3,3,3,3,3, 3,3,3,0,0,0,0,0, /* PQRSTUVW XYZ */
- 0,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, /* abcdefg hijklmno */
- 3,3,3,3,3,3,3,3, 3,3,3,0,0,0,0,0 /* pqrstuvw xyz */
-};
-#define WHITESPACE(c) (_charclass[(unsigned char)(c)] == 1)
-#define ALNUM(c) (_charclass[(unsigned char)(c)] >= 2)
-#define ALPHA(c) (_charclass[(unsigned char)(c)] == 3)
-
-/* Aliases for characters, ASCII/UTF-8 */
-#define EXCLAM 0x21 /* '!' */
-#define CQUOTE 0x22 /* '"' */
-#define CDASH 0x2d /* '-' */
-#define CSLASH 0x2f /* '/' */
-#define LANGLE 0x3c /* '<' */
-#define CEQUAL 0x3d /* '=' */
-#define RANGLE 0x3e /* '>' */
-#define CQUEST 0x3f /* '?' */
-
-/* Invoke token callback */
-#define TOKEN_CB_CALL(type, _ns, _current_too, _final) do { \
- int _ret; \
- pstate_e ns = _ns; \
- ssize_t _sz = (p - chunk_start) + _current_too; \
- if (!_sz) { \
- /* Shortcut */ \
- state = _ns; \
- break; \
- } \
- _ret = cb(type, chunk_start, _sz, key); \
- if(_ret < _sz) { \
- if(_current_too && _ret == -1) \
- state = ns; \
- goto finish; \
- } \
- chunk_start = p + _current_too; \
- state = ns; \
- } while(0)
-
-#define TOKEN_CB(_type, _ns, _current_too) \
- TOKEN_CB_CALL(_type, _ns, _current_too, 0)
-
-#define PXML_TAG_FINAL_CHUNK_TYPE PXML_TAG_END
-#define PXML_COMMENT_FINAL_CHUNK_TYPE PXML_COMMENT_END
-
-#define TOKEN_CB_FINAL(_type, _ns, _current_too) \
- TOKEN_CB_CALL( _type ## _FINAL_CHUNK_TYPE , _ns, _current_too, 1)
-
-/*
- * Parser itself
- */
-ssize_t pxml_parse(int *stateContext, const void *xmlbuf, size_t size, pxml_callback_f *cb, void *key) {
- pstate_e state = (pstate_e)*stateContext;
- const char *chunk_start = (const char *)xmlbuf;
- const char *p = chunk_start;
- const char *end = p + size;
-
- for(; p < end; p++) {
- int C = *(const unsigned char *)p;
- switch(state) {
- case ST_TEXT:
- /*
- * Initial state: we're in the middle of some text,
- * or just have started.
- */
- if (C == LANGLE)
- /* We're now in the tag, probably */
- TOKEN_CB(PXML_TEXT, ST_TAG_START, 0);
- break;
- case ST_TAG_START:
- if (ALPHA(C) || (C == CSLASH))
- state = ST_TAG_BODY;
- else if (C == EXCLAM)
- state = ST_COMMENT_WAIT_DASH1;
- else
- /*
- * Not characters and not whitespace.
- * Must be something like "3 < 4".
- */
- TOKEN_CB(PXML_TEXT, ST_TEXT, 1);/* Flush as data */
- break;
- case ST_TAG_BODY:
- switch(C) {
- case RANGLE:
- /* End of the tag */
- TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
- break;
- case LANGLE:
- /*
- * The previous tag wasn't completed, but still
- * recognized as valid. (Mozilla-compatible)
- */
- TOKEN_CB_FINAL(PXML_TAG, ST_TAG_START, 0);
- break;
- case CEQUAL:
- state = ST_TAG_QUOTE_WAIT;
- break;
- }
- break;
- case ST_TAG_QUOTE_WAIT:
- /*
- * State after the equal sign ("=") in the tag.
- */
- switch(C) {
- case CQUOTE:
- state = ST_TAG_QUOTED_STRING;
- break;
- case RANGLE:
- /* End of the tag */
- TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
- break;
- default:
- if(!WHITESPACE(C))
- /* Unquoted string value */
- state = ST_TAG_UNQUOTED_STRING;
- }
- break;
- case ST_TAG_QUOTED_STRING:
- /*
- * Tag attribute's string value in quotes.
- */
- if(C == CQUOTE) {
- /* Return back to the tag state */
- state = ST_TAG_BODY;
- }
- break;
- case ST_TAG_UNQUOTED_STRING:
- if(C == RANGLE) {
- /* End of the tag */
- TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
- } else if(WHITESPACE(C)) {
- /* Return back to the tag state */
- state = ST_TAG_BODY;
- }
- break;
- case ST_COMMENT_WAIT_DASH1:
- if(C == CDASH) {
- state = ST_COMMENT_WAIT_DASH2;
- } else {
- /* Some ordinary tag. */
- state = ST_TAG_BODY;
- }
- break;
- case ST_COMMENT_WAIT_DASH2:
- if(C == CDASH) {
- /* Seen "<--" */
- state = ST_COMMENT;
- } else {
- /* Some ordinary tag */
- state = ST_TAG_BODY;
- }
- break;
- case ST_COMMENT:
- if(C == CDASH) {
- state = ST_COMMENT_CLO_DASH2;
- }
- break;
- case ST_COMMENT_CLO_DASH2:
- if(C == CDASH) {
- state = ST_COMMENT_CLO_RT;
- } else {
- /* This is not an end of a comment */
- state = ST_COMMENT;
- }
- break;
- case ST_COMMENT_CLO_RT:
- if(C == RANGLE) {
- TOKEN_CB_FINAL(PXML_COMMENT, ST_TEXT, 1);
- } else if(C == CDASH) {
- /* Maintain current state, still waiting for '>' */
- } else {
- state = ST_COMMENT;
- }
- break;
- } /* switch(*ptr) */
- } /* for() */
-
- /*
- * Flush the partially processed chunk, state permitting.
- */
- if(p - chunk_start) {
- switch (state) {
- case ST_COMMENT:
- TOKEN_CB(PXML_COMMENT, state, 0);
- break;
- case ST_TEXT:
- TOKEN_CB(PXML_TEXT, state, 0);
- break;
- default: break; /* a no-op */
- }
- }
-
-finish:
- *stateContext = (int)state;
- return chunk_start - (const char *)xmlbuf;
-}
+++ /dev/null
-/*
- * Copyright (c) 2003, 2004 X/IO Labs, xiolabs.com.
- * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _XER_SUPPORT_H_
-#define _XER_SUPPORT_H_
-
-#include "asn1/asn1c/asn_system.h" /* Platform-specific types */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Types of data transferred to the application.
- */
-typedef enum {
- PXML_TEXT, /* Plain text between XML tags. */
- PXML_TAG, /* A tag, starting with '<'. */
- PXML_COMMENT, /* An XML comment, including "<!--" and "-->". */
- /*
- * The following chunk types are reported if the chunk
- * terminates the specified XML element.
- */
- PXML_TAG_END, /* Tag ended */
- PXML_COMMENT_END /* Comment ended */
-} pxml_chunk_type_e;
-
-/*
- * Callback function that is called by the parser when parsed data is
- * available. The _opaque is the pointer to a field containing opaque user
- * data specified in pxml_create() call. The chunk type is _type and the text
- * data is the piece of buffer identified by _bufid (as supplied to
- * pxml_feed() call) starting at offset _offset and of _size bytes size.
- * The chunk is NOT '\0'-terminated.
- */
-typedef int (pxml_callback_f)(pxml_chunk_type_e _type,
- const void *_chunk_data, size_t _chunk_size, void *_key);
-
-/*
- * Parse the given buffer as it were a chunk of XML data.
- * Invoke the specified callback each time the meaninful data is found.
- * This function returns number of bytes consumed from the bufer.
- * It will always be lesser than or equal to the specified _size.
- * The next invocation of this function must account the difference.
- */
-ssize_t pxml_parse(int *_stateContext, const void *_buf, size_t _size,
- pxml_callback_f *cb, void *_key);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _XER_SUPPORT_H_ */