output length to charset_{to,from}_unicode, permitting convenient
dry-running of conversions to determine the required output length
and/or test for the presence of difficult characters.
git-svn-id: svn://svn.tartarus.org/sgt/charset@7677
cda61777-01e9-0310-a592-
d414129be87e
* NULL, `errlen' will be ignored, and the library will choose
* something sensible to do on its own. For Unicode, this will be
* U+FFFD (REPLACEMENT CHARACTER).
* NULL, `errlen' will be ignored, and the library will choose
* something sensible to do on its own. For Unicode, this will be
* U+FFFD (REPLACEMENT CHARACTER).
+ *
+ * `output' may be NULL, in which case the entire translation will
+ * be performed in theory (e.g. a dry run to work out how much
+ * space needs to be allocated for the real thing). `outlen' may
+ * also be negative, indicating an unlimited buffer length
+ * (although this is almost certainly unwise if `output' is _not_
+ * NULL).
*/
int charset_to_unicode(const char **input, int *inlen,
*/
int charset_to_unicode(const char **input, int *inlen,
* If `input' is NULL, this routine will output the necessary bytes
* to reset the encoding state in any way which might be required
* at the end of an output piece of text.
* If `input' is NULL, this routine will output the necessary bytes
* to reset the encoding state in any way which might be required
* at the end of an output piece of text.
+ *
+ * `output' may be NULL, in which case the entire translation will
+ * be performed in theory (e.g. a dry run to work out how much
+ * space needs to be allocated for the real thing). `outlen' may
+ * also be negative, indicating an unlimited buffer length
+ * (although this is almost certainly unwise if `output' is _not_
+ * NULL).
*/
int charset_from_unicode(const wchar_t **input, int *inlen,
*/
int charset_from_unicode(const wchar_t **input, int *inlen,
struct charset_emit_param {
char *output;
int outlen;
struct charset_emit_param {
char *output;
int outlen;
{
struct charset_emit_param *param = (struct charset_emit_param *)ctx;
{
struct charset_emit_param *param = (struct charset_emit_param *)ctx;
- if (param->outlen > 0) {
- *param->output++ = output;
- param->outlen--;
+ if (param->outlen != 0) {
+ if (param->output)
+ *param->output++ = output;
+ if (param->outlen > 0)
+ param->outlen--;
+ param->writtenlen++;
} else {
param->stopped = 1;
}
} else {
param->stopped = 1;
}
param.output = output;
param.outlen = outlen;
param.output = output;
param.outlen = outlen;
param.stopped = 0;
if (state)
param.stopped = 0;
if (state)
*error = FALSE;
while (*inlen > 0) {
*error = FALSE;
while (*inlen > 0) {
- int lenbefore = param.output - output;
+ int lenbefore = param.writtenlen;
(*input)++;
(*inlen)--;
}
(*input)++;
(*inlen)--;
}
- return param.output - output;
+ return param.writtenlen;
struct unicode_emit_param {
wchar_t *output;
int outlen;
struct unicode_emit_param {
wchar_t *output;
int outlen;
const wchar_t *errstr;
int errlen;
int stopped;
const wchar_t *errstr;
int errlen;
int stopped;
- if (param->outlen >= outlen) {
+ if (param->outlen < 0 || param->outlen >= outlen) {
- *param->output++ = *p++;
- param->outlen--;
+ if (param->output)
+ *param->output++ = *p++;
+ if (param->outlen > 0)
+ param->outlen--;
}
} else {
param->stopped = 1;
}
} else {
param->stopped = 1;
param.outlen = outlen;
param.errstr = errstr;
param.errlen = errlen;
param.outlen = outlen;
param.errstr = errstr;
param.errlen = errlen;
param.stopped = 0;
if (state)
localstate = *state; /* structure copy */
while (*inlen > 0) {
param.stopped = 0;
if (state)
localstate = *state; /* structure copy */
while (*inlen > 0) {
- int lenbefore = param.output - output;
+ int lenbefore = param.writtenlen;
spec->read(spec, (unsigned char)**input, &localstate,
unicode_emit, ¶m);
if (param.stopped) {
spec->read(spec, (unsigned char)**input, &localstate,
unicode_emit, ¶m);
if (param.stopped) {
- return param.output - output;
+ return param.writtenlen;