int charset_from_unicode(const wchar_t **input, int *inlen, char *output, int outlen, int charset, charset_state *state, int *error) { charset_spec const *spec = charset_find_spec(charset); charset_state localstate = CHARSET_INIT_STATE; struct charset_emit_param param; int locallen; if (!input) { locallen = 1; inlen = &locallen; } param.output = output; param.outlen = outlen; param.stopped = 0; if (state) localstate = *state; /* structure copy */ if (error) *error = FALSE; while (*inlen > 0) { int lenbefore = param.output - output; int ret; if (input) ret = spec->write(spec, **input, &localstate, charset_emit, ¶m); else ret = spec->write(spec, -1, &localstate, charset_emit, ¶m); if (error && !ret) { /* * We have hit a difficult character, which the user * wants to know about. Leave now. */ *error = TRUE; return lenbefore; } 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 */ if (input) (*input)++; (*inlen)--; } return param.output - output; }
int charset_from_unicode(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, ¶m); 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; }
int charset_to_unicode(const char **input, int *inlen, wchar_t *output, int outlen, int charset, charset_state *state, const wchar_t *errstr, int errlen) { charset_spec const *spec = charset_find_spec(charset); charset_state localstate; struct unicode_emit_param param; param.output = output; param.outlen = outlen; param.errstr = errstr; param.errlen = errlen; param.stopped = 0; if (!state) { localstate.s0 = 0; } else { localstate = *state; /* structure copy */ } while (*inlen > 0) { int lenbefore = param.output - output; spec->read(spec, (unsigned char)**input, &localstate, unicode_emit, ¶m); 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; }
int charset_exists(int charset) { return charset_find_spec(charset) != NULL; }