~ubuntu-branches/ubuntu/intrepid/asn1c/intrepid

« back to all changes in this revision

Viewing changes to skeletons/UTF8String.c

  • Committer: Bazaar Package Importer
  • Author(s): W. Borgert
  • Date: 2005-05-28 12:36:42 UTC
  • Revision ID: james.westby@ubuntu.com-20050528123642-3h6kstws5u0xcovl
Tags: upstream-0.9.14
ImportĀ upstreamĀ versionĀ 0.9.14

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-
 
2
 * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
 
3
 * Redistribution and modifications are permitted subject to BSD license.
 
4
 */
 
5
#include <asn_internal.h>
 
6
#include <UTF8String.h>
 
7
 
 
8
/*
 
9
 * UTF8String basic type description.
 
10
 */
 
11
static ber_tlv_tag_t asn_DEF_UTF8String_tags[] = {
 
12
        (ASN_TAG_CLASS_UNIVERSAL | (12 << 2)),  /* [UNIVERSAL 12] IMPLICIT ...*/
 
13
        (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),   /* ... OCTET STRING */
 
14
};
 
15
asn_TYPE_descriptor_t asn_DEF_UTF8String = {
 
16
        "UTF8String",
 
17
        "UTF8String",
 
18
        OCTET_STRING_free,
 
19
        UTF8String_print,
 
20
        UTF8String_constraint,      /* Check for invalid codes, etc. */
 
21
        OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
 
22
        OCTET_STRING_encode_der,
 
23
        OCTET_STRING_decode_xer_utf8,
 
24
        OCTET_STRING_encode_xer_utf8,
 
25
        0, /* Use generic outmost tag fetcher */
 
26
        asn_DEF_UTF8String_tags,
 
27
        sizeof(asn_DEF_UTF8String_tags)
 
28
          / sizeof(asn_DEF_UTF8String_tags[0]) - 1,
 
29
        asn_DEF_UTF8String_tags,
 
30
        sizeof(asn_DEF_UTF8String_tags)
 
31
          / sizeof(asn_DEF_UTF8String_tags[0]),
 
32
        0, 0,   /* No members */
 
33
        0       /* No specifics */
 
34
};
 
35
 
 
36
/*
 
37
 * This is the table of length expectations.
 
38
 * The second half of this table is only applicable to the long sequences.
 
39
 */
 
40
static int UTF8String_ht[2][16] = {
 
41
        { /* 0x0 ... 0x7 */
 
42
          /* 0000..0111 */
 
43
          1, 1, 1, 1, 1, 1, 1, 1,
 
44
          /* 1000..1011(0), 1100..1101(2), 1110(3), 1111(-1) */
 
45
          0, 0, 0, 0, 2, 2, 3, -1 },
 
46
        { /* 0xF0 .. 0xF7 */
 
47
          /* 11110000..11110111 */
 
48
          4, 4, 4, 4, 4, 4, 4, 4,
 
49
          5, 5, 5, 5, 6, 6, -1, -1 }
 
50
};
 
51
static int32_t UTF8String_mv[7] = { 0, 0,
 
52
        0x00000080,
 
53
        0x00000800,
 
54
        0x00010000,
 
55
        0x00200000,
 
56
        0x04000000
 
57
};
 
58
 
 
59
/* Internal aliases for return codes */
 
60
#define U8E_TRUNC       -1      /* UTF-8 sequence truncated */
 
61
#define U8E_ILLSTART    -2      /* Illegal UTF-8 sequence start */
 
62
#define U8E_NOTCONT     -3      /* Continuation expectation failed */
 
63
#define U8E_NOTMIN      -4      /* Not minimal length encoding */
 
64
#define U8E_EINVAL      -5      /* Invalid arguments */
 
65
 
 
66
int
 
67
UTF8String_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 
68
                asn_app_consume_bytes_f *app_errlog, void *app_key) {
 
69
        ssize_t len = UTF8String_length((const UTF8String_t *)sptr);
 
70
        switch(len) {
 
71
        case U8E_EINVAL:
 
72
                _ASN_ERRLOG(app_errlog, app_key,
 
73
                        "%s: value not given", td->name);
 
74
                break;
 
75
        case U8E_TRUNC:
 
76
                _ASN_ERRLOG(app_errlog, app_key,
 
77
                        "%s: truncated UTF-8 sequence (%s:%d)",
 
78
                        td->name, __FILE__, __LINE__);
 
79
                break;
 
80
        case U8E_ILLSTART:
 
81
                _ASN_ERRLOG(app_errlog, app_key,
 
82
                        "%s: UTF-8 illegal start of encoding (%s:%d)",
 
83
                        td->name, __FILE__, __LINE__);
 
84
                break;
 
85
        case U8E_NOTCONT:
 
86
                _ASN_ERRLOG(app_errlog, app_key,
 
87
                        "%s: UTF-8 not continuation (%s:%d)",
 
88
                        td->name, __FILE__, __LINE__);
 
89
                break;
 
90
        case U8E_NOTMIN:
 
91
                _ASN_ERRLOG(app_errlog, app_key,
 
92
                        "%s: UTF-8 not minimal sequence (%s:%d)",
 
93
                        td->name, __FILE__, __LINE__);
 
94
                break;
 
95
        }
 
96
        return (len < 0) ? -1 : 0;
 
97
}
 
98
 
 
99
static ssize_t
 
100
UTF8String__process(const UTF8String_t *st, uint32_t *dst, size_t dstlen) {
 
101
        size_t length;
 
102
        uint8_t *buf = st->buf;
 
103
        uint8_t *end = buf + st->size;
 
104
 
 
105
        for(length = 0; buf < end; length++) {
 
106
                int ch = *buf;
 
107
                uint8_t *cend;
 
108
                int32_t value;
 
109
                int want;
 
110
 
 
111
                /* Compute the sequence length */
 
112
                want = UTF8String_ht[0][ch >> 4];
 
113
                switch(want) {
 
114
                case -1:
 
115
                        /* Second half of the table, long sequence */
 
116
                        want = UTF8String_ht[1][ch & 0x0F];
 
117
                        if(want != -1) break;
 
118
                        /* Fall through */
 
119
                case 0:
 
120
                        return U8E_ILLSTART;
 
121
                }
 
122
 
 
123
                /* assert(want >= 1 && want <= 6) */
 
124
 
 
125
                /* Check character sequence length */
 
126
                if(buf + want > end) return U8E_TRUNC;
 
127
 
 
128
                value = ch & (0xff >> (want + 1));
 
129
                cend = buf + want;
 
130
                for(buf++; buf < cend; buf++) {
 
131
                        ch = *buf;
 
132
                        if(ch < 0x80 || ch > 0xbf) return U8E_NOTCONT;
 
133
                        value = (value << 6) | (ch & 0x3F);
 
134
                }
 
135
                if(value < UTF8String_mv[want])
 
136
                        return U8E_NOTMIN;
 
137
                if(dstlen) *dst++ = value;      /* Record value */
 
138
        }
 
139
 
 
140
        if(dstlen) *dst = 0;    /* zero-terminate */
 
141
 
 
142
        return length;
 
143
}
 
144
 
 
145
 
 
146
ssize_t
 
147
UTF8String_length(const UTF8String_t *st) {
 
148
        if(st && st->buf) {
 
149
                return UTF8String__process(st, 0, 0);
 
150
        } else {
 
151
                return U8E_EINVAL;
 
152
        }
 
153
}
 
154
 
 
155
size_t
 
156
UTF8String_to_wcs(const UTF8String_t *st, uint32_t *dst, size_t dstlen) {
 
157
        if(st && st->buf) {
 
158
                ssize_t ret = UTF8String__process(st, dst, dstlen);
 
159
                return (ret < 0) ? 0 : ret;
 
160
        } else {
 
161
                return 0;
 
162
        }
 
163
}
 
164
 
 
165
int
 
166
UTF8String_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 
167
        asn_app_consume_bytes_f *cb, void *app_key) {
 
168
        const UTF8String_t *st = (const UTF8String_t *)sptr;
 
169
 
 
170
        (void)td;       /* Unused argument */
 
171
        (void)ilevel;   /* Unused argument */
 
172
 
 
173
        if(st && st->buf) {
 
174
                return (cb(st->buf, st->size, app_key) < 0) ? -1 : 0;
 
175
        } else {
 
176
                return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
 
177
        }
 
178
}