Commit dc06f6b0 authored by Lev Walkin's avatar Lev Walkin
Browse files

XER support

parent 87534e07
......@@ -944,7 +944,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
OUT("\n");
p = MKID(expr->Identifier);
OUT("ber_dec_rval_t\n");
OUT("asn_dec_rval_t\n");
OUT("%s_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n", p);
INDENTED(
OUT("\tvoid **structure, void *bufptr, size_t size, int tag_mode) {\n");
......@@ -1472,6 +1472,9 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) {
return 0;
}
/*
* Generate "asn_DEF_XXX" type definition.
*/
static int
emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_count, int all_tags_count, int elements_count, enum etd_spec spec) {
char *p;
......@@ -1482,6 +1485,7 @@ emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_
OUT("asn_TYPE_descriptor_t asn_DEF_%s = {\n", p);
INDENT(+1);
OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
if(expr->expr_type & ASN_CONSTR_MASK) {
p = asn1c_type_name(arg, arg->expr, TNF_SAFE);
......
......@@ -13,13 +13,14 @@ static asn_OCTET_STRING_specifics_t asn_DEF_ANY_specs = {
2 /* Special indicator that this is an ANY type */
};
asn_TYPE_descriptor_t asn_DEF_ANY = {
"ANY",
"ANY",
OCTET_STRING_free,
OCTET_STRING_print,
asn_generic_no_constraint,
OCTET_STRING_decode_ber,
OCTET_STRING_encode_der,
0, /* Not implemented yet */
OCTET_STRING_decode_xer_hex,
ANY_encode_xer,
0, /* Use generic outmost tag fetcher */
0, 0, 0, 0,
......@@ -111,7 +112,7 @@ ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) {
int
ANY_to_type(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
ber_dec_rval_t rval;
asn_dec_rval_t rval;
void *newst = 0;
if(!st || !td || !struct_ptr) {
......
......@@ -19,12 +19,13 @@ static asn_OCTET_STRING_specifics_t asn_DEF_BIT_STRING_specs = {
};
asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
"BIT STRING",
"BIT_STRING",
OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
BIT_STRING_print,
BIT_STRING_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
0, /* Not implemented yet */
OCTET_STRING_decode_xer_binary,
BIT_STRING_encode_xer,
0, /* Use generic outmost tag fetcher */
asn_DEF_BIT_STRING_tags,
......
......@@ -13,6 +13,7 @@ static ber_tlv_tag_t asn_DEF_BMPString_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
asn_TYPE_descriptor_t asn_DEF_BMPString = {
"BMPString",
"BMPString",
OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
BMPString_print,
......@@ -20,7 +21,7 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = {
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
0, /* Not implemented yet */
BMPString_encode_xer, /* Conver to UTF8 */
BMPString_encode_xer, /* Convert to UTF8 */
0, /* Use generic outmost tag fetcher */
asn_DEF_BMPString_tags,
sizeof(asn_DEF_BMPString_tags)
......
......@@ -12,6 +12,7 @@ static ber_tlv_tag_t asn_DEF_BOOLEAN_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (1 << 2))
};
asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
"BOOLEAN",
"BOOLEAN",
BOOLEAN_free,
BOOLEAN_print,
......@@ -32,13 +33,13 @@ asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
/*
* Decode BOOLEAN type.
*/
ber_dec_rval_t
asn_dec_rval_t
BOOLEAN_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td,
void **bool_value, void *buf_ptr, size_t size,
int tag_mode) {
BOOLEAN_t *st = (BOOLEAN_t *)*bool_value;
ber_dec_rval_t rval;
asn_dec_rval_t rval;
ber_tlv_len_t length;
ber_tlv_len_t lidx;
......
......@@ -13,6 +13,7 @@ static ber_tlv_tag_t asn_DEF_ENUMERATED_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
};
asn_TYPE_descriptor_t asn_DEF_ENUMERATED = {
"ENUMERATED",
"ENUMERATED",
ASN__PRIMITIVE_TYPE_free,
INTEGER_print, /* Implemented in terms of INTEGER */
......
......@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_GeneralString_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
asn_TYPE_descriptor_t asn_DEF_GeneralString = {
"GeneralString",
"GeneralString",
OCTET_STRING_free,
OCTET_STRING_print, /* non-ascii string */
asn_generic_unknown_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
0, /* Not implemented yet */
OCTET_STRING_encode_xer, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer,
0, /* Use generic outmost tag fetcher */
asn_DEF_GeneralString_tags,
sizeof(asn_DEF_GeneralString_tags)
......
......@@ -122,13 +122,14 @@ static ber_tlv_tag_t asn_DEF_GeneralizedTime_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
"GeneralizedTime",
"GeneralizedTime",
OCTET_STRING_free,
GeneralizedTime_print,
GeneralizedTime_constraint, /* Check validity of time */
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
GeneralizedTime_encode_der, /* Implemented in terms of OCTET STRING */
0, /* Not implemented yet */
GeneralizedTime_encode_der,
OCTET_STRING_decode_xer_utf8,
GeneralizedTime_encode_xer,
0, /* Use generic outmost tag fetcher */
asn_DEF_GeneralizedTime_tags,
......@@ -231,7 +232,7 @@ GeneralizedTime_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
sptr = &st;
}
return OCTET_STRING_encode_xer_ascii(td, sptr, ilevel, flags,
return OCTET_STRING_encode_xer_utf8(td, sptr, ilevel, flags,
cb, app_key);
}
......
......@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_GraphicString_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
asn_TYPE_descriptor_t asn_DEF_GraphicString = {
"GraphicString",
"GraphicString",
OCTET_STRING_free,
OCTET_STRING_print, /* non-ascii string */
asn_generic_unknown_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
0, /* Not implemented yet */
OCTET_STRING_encode_xer, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */
0, /* Use generic outmost tag fetcher */
asn_DEF_GraphicString_tags,
sizeof(asn_DEF_GraphicString_tags)
......
......@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_IA5String_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
asn_TYPE_descriptor_t asn_DEF_IA5String = {
"IA5String",
"IA5String",
OCTET_STRING_free,
OCTET_STRING_print_ascii, /* ASCII subset */
OCTET_STRING_print_utf8, /* ASCII subset */
IA5String_constraint, /* Constraint on the alphabet */
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
0, /* Not implemented yet */
OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
0, /* Use generic outmost tag fetcher */
asn_DEF_IA5String_tags,
sizeof(asn_DEF_IA5String_tags)
......
......@@ -15,6 +15,7 @@ static ber_tlv_tag_t asn_DEF_INTEGER_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_INTEGER = {
"INTEGER",
"INTEGER",
ASN__PRIMITIVE_TYPE_free,
INTEGER_print,
......
......@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_ISO646String_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
asn_TYPE_descriptor_t asn_DEF_ISO646String = {
"ISO646String",
"ISO646String",
OCTET_STRING_free,
OCTET_STRING_print_ascii, /* ASCII subset */
OCTET_STRING_print_utf8, /* ASCII subset */
VisibleString_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
0, /* Not implemented yet */
OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
0, /* Use generic outmost tag fetcher */
asn_DEF_ISO646String_tags,
sizeof(asn_DEF_ISO646String_tags)
......
......@@ -13,6 +13,7 @@ static ber_tlv_tag_t asn_DEF_NULL_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (5 << 2))
};
asn_TYPE_descriptor_t asn_DEF_NULL = {
"NULL",
"NULL",
BOOLEAN_free,
NULL_print,
......
......@@ -20,6 +20,7 @@ static ber_tlv_tag_t asn_DEF_NativeEnumerated_tags[] = {
};
asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = {
"ENUMERATED", /* The ASN.1 type is still ENUMERATED */
"ENUMERATED",
NativeInteger_free,
NativeInteger_print,
asn_generic_no_constraint,
......
......@@ -22,6 +22,7 @@ static ber_tlv_tag_t asn_DEF_NativeInteger_tags[] = {
};
asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
"INTEGER", /* The ASN.1 type is still INTEGER */
"INTEGER",
NativeInteger_free,
NativeInteger_print,
asn_generic_no_constraint,
......@@ -41,12 +42,12 @@ asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
/*
* Decode INTEGER type.
*/
ber_dec_rval_t
asn_dec_rval_t
NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td,
void **int_ptr, void *buf_ptr, size_t size, int tag_mode) {
int *Int = (int *)*int_ptr;
ber_dec_rval_t rval;
asn_dec_rval_t rval;
ber_tlv_len_t length;
/*
......
......@@ -22,6 +22,7 @@ static ber_tlv_tag_t asn_DEF_NativeReal_tags[] = {
};
asn_TYPE_descriptor_t asn_DEF_NativeReal = {
"REAL", /* The ASN.1 type is still REAL */
"REAL",
NativeReal_free,
NativeReal_print,
asn_generic_no_constraint,
......@@ -41,12 +42,12 @@ asn_TYPE_descriptor_t asn_DEF_NativeReal = {
/*
* Decode REAL type.
*/
ber_dec_rval_t
asn_dec_rval_t
NativeReal_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td,
void **dbl_ptr, void *buf_ptr, size_t size, int tag_mode) {
double *Dbl = (double *)*dbl_ptr;
ber_dec_rval_t rval;
asn_dec_rval_t rval;
ber_tlv_len_t length;
/*
......
......@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_NumericString_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
asn_TYPE_descriptor_t asn_DEF_NumericString = {
"NumericString",
"NumericString",
OCTET_STRING_free,
OCTET_STRING_print_ascii, /* ASCII subset */
OCTET_STRING_print_utf8, /* ASCII subset */
NumericString_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
0, /* Not implemented yet */
OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
0, /* Use generic outmost tag fetcher */
asn_DEF_NumericString_tags,
sizeof(asn_DEF_NumericString_tags)
......
......@@ -16,6 +16,7 @@ static ber_tlv_tag_t asn_DEF_OBJECT_IDENTIFIER_tags[] = {
};
asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
"OBJECT IDENTIFIER",
"OBJECT_IDENTIFIER",
ASN__PRIMITIVE_TYPE_free,
OBJECT_IDENTIFIER_print,
OBJECT_IDENTIFIER_constraint,
......
......@@ -20,13 +20,14 @@ static asn_OCTET_STRING_specifics_t asn_DEF_OCTET_STRING_specs = {
0
};
asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
"OCTET STRING",
"OCTET STRING", /* Canonical name */
"OCTET_STRING", /* XML tag name */
OCTET_STRING_free,
OCTET_STRING_print, /* non-ascii stuff, generally */
asn_generic_no_constraint,
OCTET_STRING_decode_ber,
OCTET_STRING_encode_der,
0, /* Not implemented yet */
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer,
0, /* Use generic outmost tag fetcher */
asn_DEF_OCTET_STRING_tags,
......@@ -160,14 +161,15 @@ _new_stack() {
/*
* Decode OCTET STRING type.
*/
ber_dec_rval_t
asn_dec_rval_t
OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td,
void **os_structure, void *buf_ptr, size_t size, int tag_mode) {
asn_OCTET_STRING_specifics_t *specs = td->specifics
? td->specifics : &asn_DEF_OCTET_STRING_specs;
? (asn_OCTET_STRING_specifics_t *)td->specifics
: &asn_DEF_OCTET_STRING_specs;
BIT_STRING_t *st = (BIT_STRING_t *)*os_structure;
ber_dec_rval_t rval;
asn_dec_rval_t rval;
asn_struct_ctx_t *ctx;
ssize_t consumed_myself = 0;
struct _stack *stck; /* Expectations stack structure */
......@@ -511,7 +513,8 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
asn_app_consume_bytes_f *cb, void *app_key) {
asn_enc_rval_t er;
asn_OCTET_STRING_specifics_t *specs = td->specifics
? td->specifics : &asn_DEF_OCTET_STRING_specs;
? (asn_OCTET_STRING_specifics_t *)td->specifics
: &asn_DEF_OCTET_STRING_specs;
BIT_STRING_t *st = (BIT_STRING_t *)sptr;
OS_type_e type_variant = (OS_type_e)specs->subvariant;
int fix_last_byte = 0;
......@@ -683,8 +686,48 @@ static struct OCTET_STRING__xer_escape_table_s {
OSXET("\046\147\164\073"), /* &gt; */
};
static int
OS__check_escaped_control_char(void *buf, int size) {
size_t i;
/*
* Inefficient algorithm which translates the escape sequences
* defined above into characters. Returns -1 if not found.
* TODO: 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++) {
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, 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_ascii(asn_TYPE_descriptor_t *td, void *sptr,
OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *sptr,
int ilevel, enum xer_encoder_flags_e flags,
asn_app_consume_bytes_f *cb, void *app_key) {
const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
......@@ -728,6 +771,396 @@ OCTET_STRING_encode_xer_ascii(asn_TYPE_descriptor_t *td, void *sptr,
return er;
}
/*
* Convert from hexadecimal format (cstring): "AB CD EF"
*/
static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, void *chunk_buf, size_t chunk_size, int have_more) {
OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
char *chunk_stop = (char *)chunk_buf;
char *p = chunk_stop;
char *pend = p + chunk_size;
unsigned int clv = 0;
int half = 0; /* Half bit */
uint8_t *buf;
/* Reallocate buffer according to high cap estimation */
ssize_t _ns = st->size + (chunk_size + 1) / 2;
void *nptr = REALLOC(st->buf, _ns + 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 = *(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 <= _ns);
st->buf[st->size] = 0; /* Courtesy termination */
return (chunk_stop - (char *)chunk_buf); /* Converted size */
}
/*
* Convert from binary format: "00101011101"
*/
static ssize_t OCTET_STRING__convert_binary(void *sptr, void *chunk_buf, size_t chunk_size, int have_more) {
BIT_STRING_t *st = (BIT_STRING_t *)sptr;
char *p = (char *)chunk_buf;
char *pend = p + chunk_size;
int bits_unused = st->bits_unused & 0x7;
uint8_t *buf;
/* Reallocate buffer according to high cap estimation */
ssize_t _ns = st->size + (chunk_size + 7) / 8;
void *nptr = REALLOC(st->buf, _ns + 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 = *(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 <= _ns);
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, char *buf, char *end, long *return_value) {
long val = 0;
char *p;
for(p = buf; p < end; p++) {
int ch = *p;
if((val * base + base) < 0) return -1; /* Strange huge value */
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: /* ';' */
*return_value = val;
return (p - buf) + 1;
default:
return -1; /* Character set error */
}
}
/* Do not return value. It's an error we're talking about here. */
return (p - buf);
}
/*
* Convert from the plain UTF-8 format, expanding entity references: "2 &lt; 3"
*/
static ssize_t OCTET_STRING__convert_entrefs(void *sptr, void *chunk_buf, size_t chunk_size, int have_more) {
OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
char *p = (char *)chunk_buf;
char *pend = p + chunk_size;
uint8_t *buf;
/* Reallocate buffer */
ssize_t _ns = st->size + chunk_size;
void *nptr = REALLOC(st->buf, _ns + 1);
if(!nptr) return -1;