refactor(fileio.c): refactor buf_write_bytes (2)

This commit is contained in:
Lewis Russell
2023-01-30 13:18:00 +00:00
parent f770e05c87
commit 740f6ae168

View File

@@ -3794,51 +3794,41 @@ static int buf_write_convert_with_iconv(struct bw_info *ip, char **bufp, int *le
return OK;
}
/// Call write() to write a number of bytes to the file.
/// Handles 'encoding' conversion.
///
/// @return FAIL for failure, OK otherwise.
static int buf_write_bytes(struct bw_info *ip)
static int buf_write_convert(struct bw_info *ip, char **bufp, int *lenp)
{
char *buf = ip->bw_buf; // data to write
int len = ip->bw_len; // length of data
#ifdef HAS_BW_FLAGS
int flags = ip->bw_flags; // extra flags
#endif
// Skip conversion when writing the BOM.
if (!(flags & FIO_NOCONVERT)) {
if (flags & FIO_UTF8) {
// Convert latin1 in the buffer to UTF-8 in the file.
char *p = ip->bw_conv_buf; // translate to buffer
for (int wlen = 0; wlen < len; wlen++) {
p += utf_char2bytes((uint8_t)buf[wlen], p);
for (int wlen = 0; wlen < *lenp; wlen++) {
p += utf_char2bytes((uint8_t)(*bufp)[wlen], p);
}
buf = ip->bw_conv_buf;
len = (int)(p - ip->bw_conv_buf);
*bufp = ip->bw_conv_buf;
*lenp = (int)(p - ip->bw_conv_buf);
} else if (flags & (FIO_UCS4 | FIO_UTF16 | FIO_UCS2 | FIO_LATIN1)) {
unsigned c;
int n = 0;
// Convert UTF-8 bytes in the buffer to UCS-2, UCS-4, UTF-16 or
// Latin1 chars in the file.
// translate in-place (can only get shorter) or to buffer
char *p = flags & FIO_LATIN1 ? buf : ip->bw_conv_buf;
for (int wlen = 0; wlen < len; wlen += n) {
char *p = flags & FIO_LATIN1 ? *bufp : ip->bw_conv_buf;
for (int wlen = 0; wlen < *lenp; wlen += n) {
if (wlen == 0 && ip->bw_restlen != 0) {
// Use remainder of previous call. Append the start of
// buf[] to get a full sequence. Might still be too
// short!
int l = MIN(len, CONV_RESTLEN - ip->bw_restlen);
memmove(ip->bw_rest + ip->bw_restlen, buf, (size_t)l);
int l = MIN(*lenp, CONV_RESTLEN - ip->bw_restlen);
memmove(ip->bw_rest + ip->bw_restlen, *bufp, (size_t)l);
n = utf_ptr2len_len((char *)ip->bw_rest, ip->bw_restlen + l);
if (n > ip->bw_restlen + len) {
if (n > ip->bw_restlen + *lenp) {
// We have an incomplete byte sequence at the end to
// be written. We can't convert it without the
// remaining bytes. Keep them for the next call.
if (ip->bw_restlen + len > CONV_RESTLEN) {
if (ip->bw_restlen + *lenp > CONV_RESTLEN) {
return FAIL;
}
ip->bw_restlen += len;
ip->bw_restlen += *lenp;
break;
}
if (n > 1) {
@@ -3856,23 +3846,23 @@ static int buf_write_bytes(struct bw_info *ip)
n = 0;
}
} else {
n = utf_ptr2len_len(buf + wlen, len - wlen);
if (n > len - wlen) {
n = utf_ptr2len_len(*bufp + wlen, *lenp - wlen);
if (n > *lenp - wlen) {
// We have an incomplete byte sequence at the end to
// be written. We can't convert it without the
// remaining bytes. Keep them for the next call.
if (len - wlen > CONV_RESTLEN) {
if (*lenp - wlen > CONV_RESTLEN) {
return FAIL;
}
ip->bw_restlen = len - wlen;
memmove(ip->bw_rest, buf + wlen,
ip->bw_restlen = *lenp - wlen;
memmove(ip->bw_rest, *bufp + wlen,
(size_t)ip->bw_restlen);
break;
}
if (n > 1) {
c = (unsigned)utf_ptr2char(buf + wlen);
c = (unsigned)utf_ptr2char(*bufp + wlen);
} else {
c = (uint8_t)buf[wlen];
c = (uint8_t)(*bufp)[wlen];
}
}
@@ -3885,18 +3875,39 @@ static int buf_write_bytes(struct bw_info *ip)
}
}
if (flags & FIO_LATIN1) {
len = (int)(p - buf);
*lenp = (int)(p - *bufp);
} else {
buf = ip->bw_conv_buf;
len = (int)(p - ip->bw_conv_buf);
*bufp = ip->bw_conv_buf;
*lenp = (int)(p - ip->bw_conv_buf);
}
}
if (ip->bw_iconv_fd != (iconv_t)-1) {
if (buf_write_convert_with_iconv(ip, &buf, &len) == FAIL) {
if (buf_write_convert_with_iconv(ip, bufp, lenp) == FAIL) {
return FAIL;
}
}
return OK;
}
/// Call write() to write a number of bytes to the file.
/// Handles 'encoding' conversion.
///
/// @return FAIL for failure, OK otherwise.
static int buf_write_bytes(struct bw_info *ip)
{
char *buf = ip->bw_buf; // data to write
int len = ip->bw_len; // length of data
#ifdef HAS_BW_FLAGS
int flags = ip->bw_flags; // extra flags
#endif
// Skip conversion when writing the BOM.
if (!(flags & FIO_NOCONVERT)) {
if (buf_write_convert(ip, &buf, &len) == FAIL) {
return FAIL;
}
}
if (ip->bw_fd < 0) {