asn1c/skeletons/BMPString.c

231 lines
5.7 KiB
C
Raw Normal View History

2004-06-03 03:38:44 +00:00
/*-
2004-10-23 11:20:06 +00:00
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
2004-06-03 03:38:44 +00:00
* Redistribution and modifications are permitted subject to BSD license.
*/
2004-09-22 16:06:28 +00:00
#include <asn_internal.h>
2004-06-03 03:38:44 +00:00
#include <BMPString.h>
2004-10-23 11:20:06 +00:00
#include <UTF8String.h>
2004-06-03 03:38:44 +00:00
/*
* BMPString basic type description.
*/
static const ber_tlv_tag_t asn_DEF_BMPString_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (30 << 2)), /* [UNIVERSAL 30] IMPLICIT ...*/
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
2004-06-03 03:38:44 +00:00
};
asn_OCTET_STRING_specifics_t asn_SPC_BMPString_specs = {
2006-11-24 11:20:27 +00:00
sizeof(BMPString_t),
offsetof(BMPString_t, _asn_ctx),
ASN_OSUBV_U16 /* 16-bits character */
};
2017-07-07 17:07:30 +00:00
static asn_per_constraints_t asn_DEF_BMPString_per_constraints = {
2006-11-24 11:20:27 +00:00
{ APC_CONSTRAINED, 16, 16, 0, 65535 },
{ APC_SEMI_CONSTRAINED, -1, -1, 0, 0 },
0, 0
};
asn_TYPE_operation_t asn_OP_BMPString = {
2004-09-22 16:06:28 +00:00
OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
BMPString_print,
2017-08-10 09:14:59 +00:00
OCTET_STRING_compare,
2004-10-23 11:20:06 +00:00
OCTET_STRING_decode_ber,
OCTET_STRING_encode_der,
BMPString_decode_xer, /* Convert from UTF-8 */
BMPString_encode_xer, /* Convert to UTF-8 */
2017-07-06 15:26:36 +00:00
#ifdef ASN_DISABLE_OER_SUPPORT
0,
0,
#else
2017-07-25 14:58:05 +00:00
OCTET_STRING_decode_oer,
OCTET_STRING_encode_oer,
2017-07-06 15:26:36 +00:00
#endif /* ASN_DISABLE_OER_SUPPORT */
2017-07-14 10:59:52 +00:00
#ifdef ASN_DISABLE_PER_SUPPORT
0,
0,
#else
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_BMPString = {
"BMPString",
"BMPString",
&asn_OP_BMPString,
2004-09-29 13:26:15 +00:00
asn_DEF_BMPString_tags,
sizeof(asn_DEF_BMPString_tags)
/ sizeof(asn_DEF_BMPString_tags[0]) - 1,
asn_DEF_BMPString_tags,
sizeof(asn_DEF_BMPString_tags)
/ sizeof(asn_DEF_BMPString_tags[0]),
{ 0, &asn_DEF_BMPString_per_constraints, BMPString_constraint },
2004-08-20 13:23:42 +00:00
0, 0, /* No members */
&asn_SPC_BMPString_specs
2004-06-03 03:38:44 +00:00
};
int
BMPString_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
asn_app_constraint_failed_f *ctfailcb,
void *app_key) {
const BMPString_t *st = (const BMPString_t *)sptr;
if(st && st->buf) {
if(st->size & 1) {
ASN__CTFAIL(app_key, td, sptr,
"%s: invalid size %zu not divisible by 2 (%s:%d)",
td->name, st->size, __FILE__, __LINE__);
return -1;
}
} else {
ASN__CTFAIL(app_key, td, sptr, "%s: value not given (%s:%d)", td->name,
__FILE__, __LINE__);
return -1;
}
return 0;
}
2004-06-03 03:38:44 +00:00
/*
* BMPString specific contents printer.
*/
2004-09-22 16:06:28 +00:00
static ssize_t
BMPString__dump(const BMPString_t *st,
2004-06-03 03:38:44 +00:00
asn_app_consume_bytes_f *cb, void *app_key) {
char scratch[128]; /* Scratchpad buffer */
2004-09-22 16:06:28 +00:00
char *p = scratch;
ssize_t wrote = 0;
uint8_t *ch;
uint8_t *end;
2004-06-03 03:38:44 +00:00
2004-09-22 16:06:28 +00:00
ch = st->buf;
end = (st->buf + st->size);
for(end--; ch < end; ch += 2) {
uint16_t wc = (ch[0] << 8) | ch[1]; /* 2 bytes */
2004-06-03 03:38:44 +00:00
if(sizeof(scratch) - (p - scratch) < 3) {
2004-09-22 16:06:28 +00:00
wrote += p - scratch;
if(cb(scratch, p - scratch, app_key) < 0)
2004-06-03 03:38:44 +00:00
return -1;
p = scratch;
}
if(wc < 0x80) {
*p++ = (char)wc;
} else if(wc < 0x800) {
*p++ = 0xc0 | ((wc >> 6));
*p++ = 0x80 | ((wc & 0x3f));
} else {
*p++ = 0xe0 | ((wc >> 12));
*p++ = 0x80 | ((wc >> 6) & 0x3f);
*p++ = 0x80 | ((wc & 0x3f));
}
}
2004-09-22 16:06:28 +00:00
wrote += p - scratch;
if(cb(scratch, p - scratch, app_key) < 0)
return -1;
return wrote;
2004-06-03 03:38:44 +00:00
}
2004-09-22 16:06:28 +00:00
2004-10-23 11:20:06 +00:00
asn_dec_rval_t
2017-09-13 06:30:27 +00:00
BMPString_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
2004-10-23 11:20:06 +00:00
asn_TYPE_descriptor_t *td, void **sptr,
2005-03-10 18:52:02 +00:00
const char *opt_mname, const void *buf_ptr, size_t size) {
2004-10-23 11:20:06 +00:00
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;
2006-09-17 01:27:44 +00:00
uint32_t *wc_end = wcs + wcs_len;
2004-10-23 11:20:06 +00:00
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;
}
2004-10-23 13:13:19 +00:00
dstwc = (uint16_t *)REALLOC(wcs, 2 * (wcs_len + 1));
2004-10-23 11:20:06 +00:00
if(!dstwc) {
FREEMEM(wcs);
rc.code = RC_FAIL;
rc.consumed = 0;
return rc;
} else {
2006-11-24 11:20:27 +00:00
dstwc[wcs_len] = 0; /* nul-terminate */
2013-12-07 18:58:10 +00:00
wcs = (uint32_t *)(void *)dstwc; /* Alignment OK */
2004-10-23 11:20:06 +00:00
}
}
FREEMEM(st->buf);
st->buf = (uint8_t *)wcs;
st->size = 2 * wcs_len;
}
return rc;
}
2004-09-22 16:06:28 +00:00
asn_enc_rval_t
2004-09-29 13:26:15 +00:00
BMPString_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
2004-09-22 16:06:28 +00:00
int ilevel, enum xer_encoder_flags_e flags,
asn_app_consume_bytes_f *cb, void *app_key) {
const BMPString_t *st = (const BMPString_t *)sptr;
asn_enc_rval_t er;
(void)ilevel;
(void)flags;
if(!st || !st->buf)
2016-03-14 10:08:15 +00:00
ASN__ENCODE_FAILED;
2004-09-22 16:06:28 +00:00
er.encoded = BMPString__dump(st, cb, app_key);
2016-03-14 10:08:15 +00:00
if(er.encoded < 0) ASN__ENCODE_FAILED;
2004-09-22 16:06:28 +00:00
2016-03-14 10:08:15 +00:00
ASN__ENCODED_OK(er);
2004-09-22 16:06:28 +00:00
}
int
2004-09-29 13:26:15 +00:00
BMPString_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
2004-09-22 16:06:28 +00:00
asn_app_consume_bytes_f *cb, void *app_key) {
const BMPString_t *st = (const BMPString_t *)sptr;
(void)td; /* Unused argument */
(void)ilevel; /* Unused argument */
if(!st || !st->buf)
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
2004-09-22 16:06:28 +00:00
if(BMPString__dump(st, cb, app_key) < 0)
return -1;
return 0;
}