]> git.ipfire.org Git - people/ms/putty.git/blob - charset/toucs.c
Drop tag for 0.61 release.
[people/ms/putty.git] / charset / toucs.c
1 /*
2 * toucs.c - convert charsets to Unicode.
3 */
4
5 #include "charset.h"
6 #include "internal.h"
7
8 struct unicode_emit_param {
9 wchar_t *output;
10 int outlen;
11 const wchar_t *errstr;
12 int errlen;
13 int stopped;
14 };
15
16 static void unicode_emit(void *ctx, long int output)
17 {
18 struct unicode_emit_param *param = (struct unicode_emit_param *)ctx;
19 wchar_t outval;
20 wchar_t const *p;
21 int outlen;
22
23 if (output == ERROR) {
24 if (param->errstr) {
25 p = param->errstr;
26 outlen = param->errlen;
27 } else {
28 outval = 0xFFFD; /* U+FFFD REPLACEMENT CHARACTER */
29 p = &outval;
30 outlen = 1;
31 }
32 } else {
33 outval = output;
34 p = &outval;
35 outlen = 1;
36 }
37
38 if (param->outlen >= outlen) {
39 while (outlen > 0) {
40 *param->output++ = *p++;
41 param->outlen--;
42 outlen--;
43 }
44 } else {
45 param->stopped = 1;
46 }
47 }
48
49 int charset_to_unicode(char **input, int *inlen, wchar_t *output, int outlen,
50 int charset, charset_state *state,
51 const wchar_t *errstr, int errlen)
52 {
53 charset_spec const *spec = charset_find_spec(charset);
54 charset_state localstate;
55 struct unicode_emit_param param;
56
57 param.output = output;
58 param.outlen = outlen;
59 param.errstr = errstr;
60 param.errlen = errlen;
61 param.stopped = 0;
62
63 if (!state) {
64 localstate.s0 = 0;
65 } else {
66 localstate = *state; /* structure copy */
67 }
68
69 while (*inlen > 0) {
70 int lenbefore = param.output - output;
71 spec->read(spec, (unsigned char)**input, &localstate,
72 unicode_emit, &param);
73 if (param.stopped) {
74 /*
75 * The emit function has _tried_ to output some
76 * characters, but ran up against the end of the
77 * buffer. Leave immediately, and return what happened
78 * _before_ attempting to process this character.
79 */
80 return lenbefore;
81 }
82 if (state)
83 *state = localstate; /* structure copy */
84 (*input)++;
85 (*inlen)--;
86 }
87
88 return param.output - output;
89 }