OSDN Git Service

Change OpenSSL context mode flags.
[ffftp/ffftp.git] / contrib / putty / CHARSET / FROMUCS.C
1 /*\r
2  * fromucs.c - convert Unicode to other character sets.\r
3  */\r
4 \r
5 #include "charset.h"\r
6 #include "internal.h"\r
7 \r
8 struct charset_emit_param {\r
9     char *output;\r
10     int outlen;\r
11     const char *errstr;\r
12     int errlen;\r
13     int stopped;\r
14 };\r
15 \r
16 static void charset_emit(void *ctx, long int output)\r
17 {\r
18     struct charset_emit_param *param = (struct charset_emit_param *)ctx;\r
19     char outval;\r
20     char const *p;\r
21     int outlen;\r
22 \r
23     if (output == ERROR) {\r
24         p = param->errstr;\r
25         outlen = param->errlen;\r
26     } else {\r
27         outval = output;\r
28         p = &outval;\r
29         outlen = 1;\r
30     }\r
31 \r
32     if (param->outlen >= outlen) {\r
33         while (outlen > 0) {\r
34             *param->output++ = *p++;\r
35             param->outlen--;\r
36             outlen--;\r
37         }\r
38     } else {\r
39         param->stopped = 1;\r
40     }\r
41 }\r
42 \r
43 int charset_from_unicode(wchar_t **input, int *inlen, char *output, int outlen,\r
44                          int charset, charset_state *state,\r
45                          const char *errstr, int errlen)\r
46 {\r
47     charset_spec const *spec = charset_find_spec(charset);\r
48     charset_state localstate;\r
49     struct charset_emit_param param;\r
50 \r
51     param.output = output;\r
52     param.outlen = outlen;\r
53     param.stopped = 0;\r
54 \r
55     /*\r
56      * charset_emit will expect a valid errstr.\r
57      */\r
58     if (!errstr) {\r
59         /* *shrug* this is good enough, and consistent across all SBCS... */\r
60         param.errstr = ".";\r
61         param.errlen = 1;\r
62     }\r
63     param.errstr = errstr;\r
64     param.errlen = errlen;\r
65 \r
66     if (!state) {\r
67         localstate.s0 = 0;\r
68     } else {\r
69         localstate = *state;           /* structure copy */\r
70     }\r
71     state = &localstate;\r
72 \r
73     while (*inlen > 0) {\r
74         int lenbefore = param.output - output;\r
75         spec->write(spec, **input, &localstate, charset_emit, &param);\r
76         if (param.stopped) {\r
77             /*\r
78              * The emit function has _tried_ to output some\r
79              * characters, but ran up against the end of the\r
80              * buffer. Leave immediately, and return what happened\r
81              * _before_ attempting to process this character.\r
82              */\r
83             return lenbefore;\r
84         }\r
85         if (state)\r
86             *state = localstate;       /* structure copy */\r
87         (*input)++;\r
88         (*inlen)--;\r
89     }\r
90     return param.output - output;\r
91 }\r