aboutsummaryrefslogtreecommitdiffstats
path: root/skeletons/UTF8String.c
diff options
context:
space:
mode:
Diffstat (limited to 'skeletons/UTF8String.c')
-rw-r--r--skeletons/UTF8String.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/skeletons/UTF8String.c b/skeletons/UTF8String.c
new file mode 100644
index 00000000..fdd13d87
--- /dev/null
+++ b/skeletons/UTF8String.c
@@ -0,0 +1,112 @@
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <UTF8String.h>
+
+/*
+ * UTF8String basic type description.
+ */
+static ber_tlv_tag_t asn1_DEF_UTF8String_tags[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (12 << 2))
+};
+asn1_TYPE_descriptor_t asn1_DEF_UTF8String = {
+ "UTF8String",
+ UTF8String_constraint, /* Check for invalid codes, etc. */
+ OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
+ OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
+ UTF8String_print,
+ OCTET_STRING_free,
+ 0, /* Use generic outmost tag fetcher */
+ asn1_DEF_UTF8String_tags,
+ sizeof(asn1_DEF_UTF8String_tags)
+ / sizeof(asn1_DEF_UTF8String_tags[0]),
+ 1, /* Single UNIVERSAL tag may be implicitly overriden */
+ -1, /* Both ways are fine */
+};
+
+static int _UTF8String_h1[16] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, /* 0x0 ... 0x7 */
+ 0, 0, 0, 0, 2, 2, 3, -1
+};
+static int _UTF8String_h2[16] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, /* 0xF0 .. 0xF7 */
+ 5, 5, 5, 5, 6, 6, -1, -1
+};
+
+int
+UTF8String_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_consume_bytes_f *app_errlog, void *app_key) {
+ ssize_t len;
+ len = UTF8String_length(sptr, td->name, app_errlog, app_key);
+ if(len > 0) len = 0;
+ return len;
+}
+
+ssize_t
+UTF8String_length(const UTF8String_t *st, const char *opt_type_name,
+ asn_app_consume_bytes_f *app_errlog, void *app_key) {
+
+ if(st && st->buf) {
+ size_t length = 0;
+ uint8_t *buf = st->buf;
+ uint8_t *end = buf + st->size;
+ int want; /* Number of bytes wanted */
+
+ for(want = 0; buf < end; buf++) {
+ uint8_t ch = *buf;
+ int w = _UTF8String_h1[ch >> 4];
+ if(want) { /* Continuation expected */
+ if(w) {
+ _ASN_ERRLOG("%s: UTF-8 expectation "
+ "failed at byte %d",
+ opt_type_name,
+ (buf - st->buf) + 1);
+ return -1;
+ }
+ want--;
+ } else {
+ switch(w) {
+ case -1: /* Long UTF-8 */
+ w = _UTF8String_h2[ch & 0xF0];
+ if(w != -1)
+ break;
+ /* Fall through */
+ case 0:
+ _ASN_ERRLOG(
+ "%s: UTF-8 expectation"
+ "failed at byte %d",
+ opt_type_name,
+ (buf - st->buf) + 1);
+ return -1;
+ }
+ want = w - 1; /* Expect this much */
+ }
+ if(!want) length++;
+ }
+
+ /* If still want something, then something is wrong */
+ if(want) {
+ _ASN_ERRLOG("%s: truncated UTF-8 sequence",
+ opt_type_name);
+ return -1;
+ }
+
+ return length;
+ } else {
+ _ASN_ERRLOG("%s: value not given", opt_type_name);
+ return -1;
+ }
+}
+
+int
+UTF8String_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const UTF8String_t *st = sptr;
+
+ if(st && st->buf) {
+ return cb(st->buf, st->size, app_key);
+ } else {
+ return cb("<absent>", 8, app_key);
+ }
+}