checking in all the old panacean stuff
This commit is contained in:
91
puttysrc/CHARSET/FROMUCS.C
Normal file
91
puttysrc/CHARSET/FROMUCS.C
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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(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;
|
||||
}
|
||||
Reference in New Issue
Block a user