File: fromucs.c

package info (click to toggle)
its-playback-time 0.2017-08-30.3c40fd3-1
  • links: PTS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 888 kB
  • sloc: ansic: 15,449; perl: 197; makefile: 29; sh: 1
file content (92 lines) | stat: -rw-r--r-- 2,047 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
 * fromucs.c - convert Unicode to other character sets.
 */

#include "charset.h"
#include "internal.h"

struct charset_emit_param {
    char *output;
    int outlen;
    const char *errstr;
    int errlen;
    int stopped;
};

static void charset_emit(void *ctx, long int output)
{
    struct charset_emit_param *param = (struct charset_emit_param *)ctx;
    char outval;
    char const *p;
    int outlen;

    if (output == ERROR) {
	p = param->errstr;
	outlen = param->errlen;
    } else {
	outval = output;
	p = &outval;
	outlen = 1;
    }

    if (param->outlen >= outlen) {
	while (outlen > 0) {
	    *param->output++ = *p++;
	    param->outlen--;
	    outlen--;
	}
    } else {
	param->stopped = 1;
    }
}

int charset_from_unicode(const wchar_t **input, int *inlen,
                         char *output, int outlen,
			 int charset, charset_state *state,
			 const char *errstr, int errlen)
{
    charset_spec const *spec = charset_find_spec(charset);
    charset_state localstate;
    struct charset_emit_param param;

    param.output = output;
    param.outlen = outlen;
    param.stopped = 0;

    /*
     * charset_emit will expect a valid errstr.
     */
    if (!errstr) {
	/* *shrug* this is good enough, and consistent across all SBCS... */
	param.errstr = ".";
	param.errlen = 1;
    }
    param.errstr = errstr;
    param.errlen = errlen;

    if (!state) {
	localstate.s0 = 0;
    } else {
	localstate = *state;	       /* structure copy */
    }
    state = &localstate;

    while (*inlen > 0) {
	int lenbefore = param.output - output;
	spec->write(spec, **input, &localstate, charset_emit, &param);
	if (param.stopped) {
	    /*
	     * The emit function has _tried_ to output some
	     * characters, but ran up against the end of the
	     * buffer. Leave immediately, and return what happened
	     * _before_ attempting to process this character.
	     */
	    return lenbefore;
	}
	if (state)
	    *state = localstate;       /* structure copy */
	(*input)++;
	(*inlen)--;
    }
    return param.output - output;
}