Skip to content
Snippets Groups Projects
Commit 9a6f65b2 authored by Lev Walkin's avatar Lev Walkin
Browse files

XER decoding support

parent 36b8b827
No related branches found
No related tags found
No related merge requests found
/*- /*-
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved. * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license. * Redistribution and modifications are permitted subject to BSD license.
*/ */
#include <asn_internal.h> #include <asn_internal.h>
#include <BMPString.h> #include <BMPString.h>
#include <UTF8String.h>
#include <assert.h>
/* /*
* BMPString basic type description. * BMPString basic type description.
...@@ -18,10 +20,10 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = { ...@@ -18,10 +20,10 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = {
OCTET_STRING_free, /* Implemented in terms of OCTET STRING */ OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
BMPString_print, BMPString_print,
asn_generic_no_constraint, /* No constraint by default */ asn_generic_no_constraint, /* No constraint by default */
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_decode_ber,
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der,
0, /* Not implemented yet */ BMPString_decode_xer, /* Convert from UTF-8 */
BMPString_encode_xer, /* Convert to UTF8 */ BMPString_encode_xer, /* Convert to UTF-8 */
0, /* Use generic outmost tag fetcher */ 0, /* Use generic outmost tag fetcher */
asn_DEF_BMPString_tags, asn_DEF_BMPString_tags,
sizeof(asn_DEF_BMPString_tags) sizeof(asn_DEF_BMPString_tags)
...@@ -74,6 +76,71 @@ BMPString__dump(const BMPString_t *st, ...@@ -74,6 +76,71 @@ BMPString__dump(const BMPString_t *st,
return wrote; return wrote;
} }
asn_dec_rval_t
BMPString_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td, void **sptr,
const char *opt_mname, void *buf_ptr, size_t size) {
asn_dec_rval_t rc;
rc = OCTET_STRING_decode_xer_utf8(opt_codec_ctx, td, sptr, opt_mname,
buf_ptr, size);
if(rc.code == RC_OK) {
/*
* Now we have a whole string in UTF-8 format.
* Convert it into UCS-2.
*/
uint32_t *wcs;
size_t wcs_len;
UTF8String_t *st;
assert(*sptr);
st = (UTF8String_t *)*sptr;
assert(st->buf);
wcs_len = UTF8String_to_wcs(st, 0, 0);
wcs = (uint32_t *)MALLOC(4 * (wcs_len + 1));
if(wcs == 0 || UTF8String_to_wcs(st, wcs, wcs_len) != wcs_len) {
rc.code = RC_FAIL;
rc.consumed = 0;
return rc;
} else {
wcs[wcs_len] = 0; /* nul-terminate */
}
if(1) {
/* Swap byte order and trim encoding to 2 bytes */
uint32_t *wc = wcs;
uint32_t *wc_end = wcs + wcs_len + 1;
uint16_t *dstwc = (uint16_t *)wcs;
for(; wc < wc_end; wc++, dstwc++) {
uint32_t wch = *wc;
if(wch > 0xffff) {
FREEMEM(wcs);
rc.code = RC_FAIL;
rc.consumed = 0;
return rc;
}
*((uint8_t *)dstwc + 0) = wch >> 8;
*((uint8_t *)dstwc + 1) = wch;
}
dstwc = (uint16_t)REALLOC(wcs, 2 * (wcs_len + 1));
if(!dstwc) {
FREEMEM(wcs);
rc.code = RC_FAIL;
rc.consumed = 0;
return rc;
} else {
wcs = (uint32_t *)dstwc;
}
}
FREEMEM(st->buf);
st->buf = (uint8_t *)wcs;
st->size = 2 * wcs_len;
}
return rc;
}
asn_enc_rval_t asn_enc_rval_t
BMPString_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, BMPString_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
int ilevel, enum xer_encoder_flags_e flags, int ilevel, enum xer_encoder_flags_e flags,
......
...@@ -12,6 +12,7 @@ typedef OCTET_STRING_t BMPString_t; /* Implemented via OCTET STRING */ ...@@ -12,6 +12,7 @@ typedef OCTET_STRING_t BMPString_t; /* Implemented via OCTET STRING */
extern asn_TYPE_descriptor_t asn_DEF_BMPString; extern asn_TYPE_descriptor_t asn_DEF_BMPString;
asn_struct_print_f BMPString_print; /* Human-readable output */ asn_struct_print_f BMPString_print; /* Human-readable output */
xer_type_decoder_f BMPString_decode_xer;
xer_type_encoder_f BMPString_encode_xer; xer_type_encoder_f BMPString_encode_xer;
#endif /* _BMPString_H_ */ #endif /* _BMPString_H_ */
...@@ -96,54 +96,72 @@ UTF8String_constraint(asn_TYPE_descriptor_t *td, const void *sptr, ...@@ -96,54 +96,72 @@ UTF8String_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
return (len < 0) ? -1 : 0; return (len < 0) ? -1 : 0;
} }
ssize_t static ssize_t
UTF8String_length(const UTF8String_t *st) { UTF8String__process(const UTF8String_t *st, uint32_t *dst, size_t dstlen) {
size_t length;
uint8_t *buf = st->buf;
uint8_t *end = buf + st->size;
if(st && st->buf) { for(length = 0; buf < end; length++) {
size_t length; int ch = *buf;
uint8_t *buf = st->buf; uint8_t *cend;
uint8_t *end = buf + st->size; int32_t value;
int want;
for(length = 0; buf < end; length++) {
int ch = *buf; /* Compute the sequence length */
uint8_t *cend; want = UTF8String_ht[0][ch >> 4];
int32_t value; switch(want) {
int want; case -1:
/* Second half of the table, long sequence */
/* Compute the sequence length */ want = UTF8String_ht[1][ch & 0x0F];
want = UTF8String_ht[0][ch >> 4]; if(want != -1) break;
switch(want) { /* Fall through */
case -1: case 0:
/* Second half of the table, long sequence */ return U8E_ILLSTART;
want = UTF8String_ht[1][ch & 0x0F];
if(want != -1) break;
/* Fall through */
case 0:
return U8E_ILLSTART;
}
/* assert(want >= 1 && want <= 6) */
/* Check character sequence length */
if(buf + want > end) return U8E_TRUNC;
value = ch & (0xff >> (want + 1));
cend = buf + want;
for(buf++; buf < cend; buf++) {
ch = *buf;
if(ch < 0x80 || ch > 0xbf) return U8E_NOTCONT;
value = (value << 6) | (ch & 0x3F);
}
if(value < UTF8String_mv[want])
return U8E_NOTMIN;
} }
return length; /* assert(want >= 1 && want <= 6) */
/* Check character sequence length */
if(buf + want > end) return U8E_TRUNC;
value = ch & (0xff >> (want + 1));
cend = buf + want;
for(buf++; buf < cend; buf++) {
ch = *buf;
if(ch < 0x80 || ch > 0xbf) return U8E_NOTCONT;
value = (value << 6) | (ch & 0x3F);
}
if(value < UTF8String_mv[want])
return U8E_NOTMIN;
if(dstlen) *dst++ = value; /* Record value */
}
if(dstlen) *dst = 0; /* zero-terminate */
return length;
}
ssize_t
UTF8String_length(const UTF8String_t *st) {
if(st && st->buf) {
return UTF8String__process(st, 0, 0);
} else { } else {
return U8E_EINVAL; return U8E_EINVAL;
} }
} }
size_t
UTF8String_to_wcs(const UTF8String_t *st, uint32_t *dst, size_t dstlen) {
if(st && st->buf) {
ssize_t ret = UTF8String__process(st, dst, dstlen);
return (ret < 0) ? 0 : ret;
} else {
return 0;
}
}
int int
UTF8String_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, UTF8String_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) { asn_app_consume_bytes_f *cb, void *app_key) {
......
...@@ -25,4 +25,17 @@ asn_constr_check_f UTF8String_constraint; ...@@ -25,4 +25,17 @@ asn_constr_check_f UTF8String_constraint;
*/ */
ssize_t UTF8String_length(const UTF8String_t *st); ssize_t UTF8String_length(const UTF8String_t *st);
/*
* Convert the UTF-8 string into a sequence of wide characters.
* Returns the number of characters necessary.
* Returned value might be greater than dstlen.
* In case of conversion error, 0 is returned.
*
* If st points to a valid UTF-8 string, calling
* UTF8String_to_wcs(st, 0, 0);
* is equivalent to
* UTF8String_length(const UTF8String_t *st);
*/
size_t UTF8String_to_wcs(const UTF8String_t *st, uint32_t *dst, size_t dstlen);
#endif /* _UTF8String_H_ */ #endif /* _UTF8String_H_ */
/*- /*-
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved. * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license. * Redistribution and modifications are permitted subject to BSD license.
*/ */
#include <asn_internal.h> #include <asn_internal.h>
#include <UniversalString.h> #include <UniversalString.h>
#include <UTF8String.h>
/* /*
* UniversalString basic type description. * UniversalString basic type description.
...@@ -18,10 +19,10 @@ asn_TYPE_descriptor_t asn_DEF_UniversalString = { ...@@ -18,10 +19,10 @@ asn_TYPE_descriptor_t asn_DEF_UniversalString = {
OCTET_STRING_free, OCTET_STRING_free,
UniversalString_print, /* Convert into UTF8 and print */ UniversalString_print, /* Convert into UTF8 and print */
asn_generic_no_constraint, asn_generic_no_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_decode_ber,
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der,
0, /* Not implemented yet */ UniversalString_decode_xer, /* Convert from UTF-8 */
UniversalString_encode_xer, /* Convert into UTF8 */ UniversalString_encode_xer, /* Convert into UTF-8 */
0, /* Use generic outmost tag fetcher */ 0, /* Use generic outmost tag fetcher */
asn_DEF_UniversalString_tags, asn_DEF_UniversalString_tags,
sizeof(asn_DEF_UniversalString_tags) sizeof(asn_DEF_UniversalString_tags)
...@@ -93,6 +94,63 @@ UniversalString__dump(const UniversalString_t *st, ...@@ -93,6 +94,63 @@ UniversalString__dump(const UniversalString_t *st,
return wrote; return wrote;
} }
asn_dec_rval_t
UniversalString_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td, void **sptr,
const char *opt_mname, void *buf_ptr, size_t size) {
asn_dec_rval_t rc;
rc = OCTET_STRING_decode_xer_utf8(opt_codec_ctx, td, sptr, opt_mname,
buf_ptr, size);
if(rc.code == RC_OK) {
/*
* Now we have a whole string in UTF-8 format.
* Convert it into UCS-4.
*/
uint32_t *wcs;
size_t wcs_len;
UTF8String_t *st;
#ifndef WORDS_BIGENDIAN
int little_endian = 1;
#endif
assert(*sptr);
st = (UTF8String_t *)*sptr;
assert(st->buf);
wcs_len = UTF8String_to_wcs(st, 0, 0);
wcs = (uint32_t *)MALLOC(4 * (wcs_len + 1));
if(wcs == 0 || UTF8String_to_wcs(st, wcs, wcs_len) != wcs_len) {
rc.code = RC_FAIL;
rc.consumed = 0;
return rc;
} else {
wcs[wcs_len] = 0; /* nul-terminate */
}
#ifndef WORDS_BIGENDIAN
if(*(char *)&little_endian) {
/* Swap byte order in encoding */
uint32_t *wc = wcs;
uint32_t *wc_end = wcs + wcs_len;
for(; wc < wc_end; wc++) {
/* *wc = htonl(*wc); */
uint32_t wch = *wc;
*((uint8_t *)wc + 0) = wch >> 24;
*((uint8_t *)wc + 1) = wch >> 16;
*((uint8_t *)wc + 2) = wch >> 8;
*((uint8_t *)wc + 3) = wch;
}
}
#endif /* WORDS_BIGENDIAN */
FREEMEM(st->buf);
st->buf = (uint8_t *)wcs;
st->size = 4 * wcs_len;
}
return rc;
}
asn_enc_rval_t asn_enc_rval_t
UniversalString_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, UniversalString_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
int ilevel, enum xer_encoder_flags_e flags, int ilevel, enum xer_encoder_flags_e flags,
......
...@@ -12,6 +12,7 @@ typedef OCTET_STRING_t UniversalString_t; /* Implemented via OCTET STRING */ ...@@ -12,6 +12,7 @@ typedef OCTET_STRING_t UniversalString_t; /* Implemented via OCTET STRING */
extern asn_TYPE_descriptor_t asn_DEF_UniversalString; extern asn_TYPE_descriptor_t asn_DEF_UniversalString;
asn_struct_print_f UniversalString_print; /* Human-readable output */ asn_struct_print_f UniversalString_print; /* Human-readable output */
xer_type_decoder_f UniversalString_decode_xer;
xer_type_encoder_f UniversalString_encode_xer; xer_type_encoder_f UniversalString_encode_xer;
#endif /* _UniversalString_H_ */ #endif /* _UniversalString_H_ */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# #
ANY.h ANY.c ANY.h ANY.c
BMPString.h BMPString.c BMPString.h BMPString.c UTF8String.h
BOOLEAN.h BOOLEAN.c BOOLEAN.h BOOLEAN.c
ENUMERATED.h ENUMERATED.c INTEGER.h ENUMERATED.h ENUMERATED.c INTEGER.h
GeneralString.h GeneralString.c GeneralString.h GeneralString.c
...@@ -30,7 +30,7 @@ T61String.h T61String.c ...@@ -30,7 +30,7 @@ T61String.h T61String.c
TeletexString.h TeletexString.c TeletexString.h TeletexString.c
UTCTime.h UTCTime.c GeneralizedTime.h UTCTime.h UTCTime.c GeneralizedTime.h
UTF8String.h UTF8String.c UTF8String.h UTF8String.c
UniversalString.h UniversalString.c UniversalString.h UniversalString.c UTF8String.h
VideotexString.h VideotexString.c VideotexString.h VideotexString.c
VisibleString.h VisibleString.c VisibleString.h VisibleString.c
asn_SEQUENCE_OF.h asn_SEQUENCE_OF.c asn_SET_OF.h asn_SEQUENCE_OF.h asn_SEQUENCE_OF.c asn_SET_OF.h
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment