added qse_tio_writembs() and qse_tio_readmbs()

This commit is contained in:
2011-12-18 17:40:37 +00:00
parent 7f0ad74286
commit d5db73dfce
20 changed files with 777 additions and 555 deletions

View File

@ -48,7 +48,7 @@
#define WRITE_CHAR(sio,c) \
do { \
qse_mchar_t __xxx_c = c; \
if (qse_sio_putmsn (sio, &__xxx_c, 1) != 1) return -1; \
if (qse_sio_putmbsn (sio, &__xxx_c, 1) != 1) return -1; \
} while (0)
static int write_num (qse_sio_t* sio, qse_size_t x, int base)
@ -101,39 +101,39 @@ void qse_assert_failed (
sio = QSE_SIO_ERR;
}
qse_sio_putms (sio, QSE_MT("=[ASSERTION FAILURE]============================================================\n"));
qse_sio_putmbs (sio, QSE_MT("=[ASSERTION FAILURE]============================================================\n"));
#if 1
qse_sio_putms (sio, QSE_MT(" __ \n"));
qse_sio_putms (sio, QSE_MT(" _____ _____ _____ _____| |\n"));
qse_sio_putms (sio, QSE_MT("| | | _ | __| |\n"));
qse_sio_putms (sio, QSE_MT("| | | | | __|__ |__|\n"));
qse_sio_putms (sio, QSE_MT("|_____|_____|__| |_____|__|\n"));
qse_sio_putms (sio, QSE_MT(" \n"));
qse_sio_putmbs (sio, QSE_MT(" __ \n"));
qse_sio_putmbs (sio, QSE_MT(" _____ _____ _____ _____| |\n"));
qse_sio_putmbs (sio, QSE_MT("| | | _ | __| |\n"));
qse_sio_putmbs (sio, QSE_MT("| | | | | __|__ |__|\n"));
qse_sio_putmbs (sio, QSE_MT("|_____|_____|__| |_____|__|\n"));
qse_sio_putmbs (sio, QSE_MT(" \n"));
#else
qse_sio_putms (sio, QSE_MT(" __ \n"));
qse_sio_putms (sio, QSE_MT(" _____ _____ _____ _____ | |\n"));
qse_sio_putms (sio, QSE_MT("| | | _ | __| | |\n"));
qse_sio_putms (sio, QSE_MT("| | | | | __|__ | |__|\n"));
qse_sio_putms (sio, QSE_MT("|_____|_____|__| |_____| |__|\n"));
qse_sio_putms (sio, QSE_MT(" __ \n"));
qse_sio_putmbs (sio, QSE_MT(" __ \n"));
qse_sio_putmbs (sio, QSE_MT(" _____ _____ _____ _____ | |\n"));
qse_sio_putmbs (sio, QSE_MT("| | | _ | __| | |\n"));
qse_sio_putmbs (sio, QSE_MT("| | | | | __|__ | |__|\n"));
qse_sio_putmbs (sio, QSE_MT("|_____|_____|__| |_____| |__|\n"));
qse_sio_putmbs (sio, QSE_MT(" __ \n"));
#endif
qse_sio_putms (sio, QSE_MT("FILE: "));
qse_sio_puts (sio, file);
qse_sio_putms (sio, QSE_MT(" LINE: "));
qse_sio_putmbs (sio, QSE_MT("FILE: "));
qse_sio_putstr (sio, file);
qse_sio_putmbs (sio, QSE_MT(" LINE: "));
write_num (sio, line, 10);
qse_sio_putms (sio, QSE_MT("\nEXPRESSION: "));
qse_sio_puts (sio, expr);
qse_sio_putms (sio, QSE_MT("\n"));
qse_sio_putmbs (sio, QSE_MT("\nEXPRESSION: "));
qse_sio_putstr (sio, expr);
qse_sio_putmbs (sio, QSE_MT("\n"));
if (desc != QSE_NULL)
{
qse_sio_putms (sio, QSE_MT("DESCRIPTION: "));
qse_sio_puts (sio, desc);
qse_sio_putms (sio, QSE_MT("\n"));
qse_sio_putmbs (sio, QSE_MT("DESCRIPTION: "));
qse_sio_putstr (sio, desc);
qse_sio_putmbs (sio, QSE_MT("\n"));
}
#ifdef HAVE_BACKTRACE
@ -141,19 +141,19 @@ void qse_assert_failed (
btsyms = backtrace_symbols (btarray, btsize);
if (btsyms != QSE_NULL)
{
qse_sio_putms (sio, QSE_MT("=[BACKTRACES]===================================================================\n"));
qse_sio_putmbs (sio, QSE_MT("=[BACKTRACES]===================================================================\n"));
for (i = 0; i < btsize; i++)
{
qse_sio_putms (sio, btsyms[i]);
qse_sio_putms (sio, QSE_MT("\n"));
qse_sio_putmbs (sio, btsyms[i]);
qse_sio_putmbs (sio, QSE_MT("\n"));
}
free (btsyms);
}
#endif
qse_sio_putms (sio, QSE_MT("================================================================================\n"));
qse_sio_putmbs (sio, QSE_MT("================================================================================\n"));
qse_sio_flush (sio);
if (sio != QSE_SIO_ERR) qse_sio_fini (sio);

View File

@ -1012,6 +1012,7 @@ int qse_pio_init (
int topt = 0;
if (oflags & QSE_PIO_IGNOREMBWCERR) topt |= QSE_TIO_IGNOREMBWCERR;
if (oflags & QSE_PIO_NOAUTOFLUSH) topt |= QSE_TIO_NOAUTOFLUSH;
for (i = 0; i < QSE_COUNTOF(tio); i++)
{
@ -1168,7 +1169,10 @@ static qse_ssize_t pio_read (
}
#if defined(_WIN32)
if (size > QSE_TYPE_MAX(DWORD)) size = QSE_TYPE_MAX(DWORD);
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD)))
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD);
if (ReadFile(hnd, buf, (DWORD)size, &count, QSE_NULL) == FALSE)
{
/* ReadFile receives ERROR_BROKEN_PIPE when the write end
@ -1180,7 +1184,10 @@ static qse_ssize_t pio_read (
return (qse_ssize_t)count;
#elif defined(__OS2__)
if (size > QSE_TYPE_MAX(ULONG)) size = QSE_TYPE_MAX(ULONG);
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG)))
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG);
rc = DosRead (hnd, buf, (ULONG)size, &count);
if (rc != NO_ERROR)
{
@ -1192,8 +1199,9 @@ static qse_ssize_t pio_read (
#elif defined(__DOS__)
/* TODO: verify this */
if (size > QSE_TYPE_MAX(unsigned int))
size = QSE_TYPE_MAX(unsigned int);
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(unsigned int)))
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(unsigned int);
n = read (hnd, buf, size);
if (n == -1) pio->errnum = QSE_PIO_ESUBSYS;
@ -1201,7 +1209,8 @@ static qse_ssize_t pio_read (
#else
if (size > QSE_TYPE_MAX(size_t)) size = QSE_TYPE_MAX(size_t);
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t)))
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t);
reread:
n = QSE_READ (hnd, buf, size);
@ -1254,12 +1263,14 @@ static qse_ssize_t pio_write (
{
/* the stream is already closed */
pio->errnum = QSE_PIO_ENOHND;
return (qse_ssize_t)-1;
return -1;
}
#if defined(_WIN32)
if (size > QSE_TYPE_MAX(DWORD)) size = QSE_TYPE_MAX(DWORD);
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD)))
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD);
if (WriteFile (hnd, data, (DWORD)size, &count, QSE_NULL) == FALSE)
{
pio->errnum = (GetLastError() == ERROR_BROKEN_PIPE)?
@ -1270,7 +1281,9 @@ static qse_ssize_t pio_write (
#elif defined(__OS2__)
if (size > QSE_TYPE_MAX(ULONG)) size = QSE_TYPE_MAX(ULONG);
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG)))
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(ULONG);
rc = DosWrite (hnd, (PVOID)data, (ULONG)size, &count);
if (rc != NO_ERROR)
{
@ -1281,8 +1294,9 @@ static qse_ssize_t pio_write (
return (qse_ssize_t)count;
#elif defined(__DOS__)
if (size > QSE_TYPE_MAX(unsigned int))
size = QSE_TYPE_MAX(unsigned int);
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(unsigned int)))
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(unsigned int);
n = write (hnd, data, size);
if (n == -1) pio->errnum = QSE_PIO_ESUBSYS;
@ -1290,7 +1304,8 @@ static qse_ssize_t pio_write (
#else
if (size > QSE_TYPE_MAX(size_t)) size = QSE_TYPE_MAX(size_t);
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t)))
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t);
rewrite:
n = QSE_WRITE (hnd, data, size);

View File

@ -38,7 +38,6 @@ static qse_sio_t __sio_in =
/* fio */
{
QSE_NULL, /* mmgr */
0, /* errnum */
#if defined(_WIN32)
/* this is not a handle. it is adjusted to
@ -59,7 +58,7 @@ static qse_sio_t __sio_in =
/* tio */
{
QSE_NULL,
0,
QSE_TIO_ENOERR,
QSE_TIO_IGNOREMBWCERR,
__sio_input,
@ -71,7 +70,10 @@ static qse_sio_t __sio_in =
0,
0,
0,
0,
0,
{ 0 },
{ 0 },
{ 0 }
}
@ -84,7 +86,6 @@ static qse_sio_t __sio_out =
/* fio */
{
QSE_NULL,
0,
#if defined(_WIN32)
/* this is not a handle. it is adjusted to
@ -105,7 +106,7 @@ static qse_sio_t __sio_out =
/* tio */
{
QSE_NULL,
0,
QSE_TIO_ENOERR,
QSE_TIO_IGNOREMBWCERR,
__sio_input,
@ -117,7 +118,10 @@ static qse_sio_t __sio_out =
0,
0,
0,
0,
0,
{ 0 },
{ 0 },
{ 0 }
}
@ -130,7 +134,6 @@ static qse_sio_t __sio_err =
/* fio */
{
QSE_NULL,
0,
#if defined(_WIN32)
/* this is not a handle. it is adjusted to
@ -151,7 +154,7 @@ static qse_sio_t __sio_err =
/* tio */
{
QSE_NULL,
0,
QSE_TIO_ENOERR,
QSE_TIO_IGNOREMBWCERR,
__sio_input,
@ -163,7 +166,10 @@ static qse_sio_t __sio_err =
0,
0,
0,
0,
0,
{ 0 },
{ 0 },
{ 0 }
}
@ -272,6 +278,11 @@ void qse_sio_fini (qse_sio_t* sio)
else if (sio == qse_sio_err) qse_sio_err = QSE_NULL;
}
qse_sio_errnum_t qse_sio_geterrnum (qse_sio_t* sio)
{
return QSE_TIO_ERRNUM(&sio->tio);
}
qse_sio_hnd_t qse_sio_gethandle (qse_sio_t* sio)
{
/*return qse_fio_gethandle (&sio->fio);*/
@ -288,61 +299,82 @@ void qse_sio_purge (qse_sio_t* sio)
qse_tio_purge (&sio->tio);
}
qse_ssize_t qse_sio_getc (qse_sio_t* sio, qse_char_t* c)
qse_ssize_t qse_sio_getmb (qse_sio_t* sio, qse_mchar_t* c)
{
return qse_tio_read (&sio->tio, c, 1);
return qse_tio_readmbs (&sio->tio, c, 1);
}
qse_ssize_t qse_sio_gets (
qse_sio_t* sio, qse_char_t* buf, qse_size_t size)
qse_ssize_t qse_sio_getwc (qse_sio_t* sio, qse_wchar_t* c)
{
return qse_tio_readwcs (&sio->tio, c, 1);
}
qse_ssize_t qse_sio_getmbs (
qse_sio_t* sio, qse_mchar_t* buf, qse_size_t size)
{
qse_ssize_t n;
if (size <= 0) return 0;
n = qse_tio_read (&sio->tio, buf, size -1);
if (n == -1) return -1;
buf[n] = QSE_T('\0');
n = qse_tio_readmbs (&sio->tio, buf, size - 1);
if (n <= -1) return -1;
buf[n] = QSE_MT('\0');
return n;
}
qse_ssize_t qse_sio_getsn (
qse_sio_t* sio, qse_char_t* buf, qse_size_t size)
qse_ssize_t qse_sio_getmbsn (
qse_sio_t* sio, qse_mchar_t* buf, qse_size_t size)
{
return qse_tio_read (&sio->tio, buf, size);
return qse_tio_readmbs (&sio->tio, buf, size);
}
qse_ssize_t qse_sio_putc (qse_sio_t* sio, qse_char_t c)
qse_ssize_t qse_sio_getwcs (
qse_sio_t* sio, qse_wchar_t* buf, qse_size_t size)
{
return qse_tio_write (&sio->tio, &c, 1);
qse_ssize_t n;
if (size <= 0) return 0;
n = qse_tio_readwcs (&sio->tio, buf, size - 1);
if (n <= -1) return -1;
buf[n] = QSE_WT('\0');
return n;
}
#if 0
qse_ssize_t qse_sio_puts (qse_sio_t* sio, const qse_char_t* str)
qse_ssize_t qse_sio_getwcsn (
qse_sio_t* sio, qse_wchar_t* buf, qse_size_t size)
{
return qse_tio_write (&sio->tio, str, (qse_size_t)-1);
}
#endif
qse_ssize_t qse_sio_putms (qse_sio_t* sio, const qse_mchar_t* str)
{
return qse_tio_writembsn (&sio->tio, str, qse_mbslen(str));
return qse_tio_readwcs (&sio->tio, buf, size);
}
qse_ssize_t qse_sio_putws (qse_sio_t* sio, const qse_wchar_t* str)
qse_ssize_t qse_sio_putmb (qse_sio_t* sio, qse_mchar_t c)
{
return qse_tio_writewcsn (&sio->tio, str, qse_wcslen(str));
return qse_tio_writembs (&sio->tio, &c, 1);
}
qse_ssize_t qse_sio_putmsn (
qse_ssize_t qse_sio_putwc (qse_sio_t* sio, qse_wchar_t c)
{
return qse_tio_writewcs (&sio->tio, &c, 1);
}
qse_ssize_t qse_sio_putmbs (qse_sio_t* sio, const qse_mchar_t* str)
{
return qse_tio_writembs (&sio->tio, str, (qse_size_t)-1);
}
qse_ssize_t qse_sio_putwcs (qse_sio_t* sio, const qse_wchar_t* str)
{
return qse_tio_writewcs (&sio->tio, str, (qse_size_t)-1);
}
qse_ssize_t qse_sio_putmbsn (
qse_sio_t* sio, const qse_mchar_t* str, qse_size_t size)
{
return qse_tio_writembsn (&sio->tio, str, size);
return qse_tio_writembs (&sio->tio, str, size);
}
qse_ssize_t qse_sio_putwsn (
qse_ssize_t qse_sio_putwcsn (
qse_sio_t* sio, const qse_wchar_t* str, qse_size_t size)
{
return qse_tio_writewcsn (&sio->tio, str, size);
return qse_tio_writewcs (&sio->tio, str, size);
}
int qse_sio_getpos (qse_sio_t* sio, qse_sio_pos_t* pos)

View File

@ -22,45 +22,98 @@
#include <qse/cmn/chr.h>
#include "mem.h"
#define STATUS_GETC_EILSEQ (1 << 0)
#define STATUS_ILLSEQ (1 << 0)
#define STATUS_EOF (1 << 1)
static qse_ssize_t tio_getc (qse_tio_t* tio, qse_char_t* c)
qse_ssize_t qse_tio_readmbs (qse_tio_t* tio, qse_mchar_t* buf, qse_size_t size)
{
qse_size_t left = 0;
qse_size_t nread;
qse_ssize_t n;
qse_char_t curc;
/* TODO: more efficient way to check this?
* maybe better to use QSE_ASSERT
* QSE_ASSERT (tio->input_func != QSE_NULL);
*/
/*QSE_ASSERT (tio->input_func != QSE_NULL);*/
if (tio->input_func == QSE_NULL)
{
tio->errnum = QSE_TIO_ENOINF;
return -1;
}
if (tio->input_status & STATUS_GETC_EILSEQ)
/* note that this function doesn't check if
* tio->input_status is set with STATUS_ILLSEQ
* since this function can simply return the next
* available byte. */
if (size > QSE_TYPE_MAX(qse_ssize_t)) size = QSE_TYPE_MAX(qse_ssize_t);
/* TODO: HOW TO HANDLE those already converted to wchar???? */
nread = 0;
while (nread < size)
{
tio->input_status &= ~STATUS_GETC_EILSEQ;
tio->errnum = QSE_TIO_EILSEQ;
return -1;
if (tio->inbuf_cur >= tio->inbuf_len)
{
n = tio->input_func (
QSE_TIO_IO_DATA, tio->input_arg,
tio->inbuf, QSE_COUNTOF(tio->inbuf));
if (n == 0) break;
if (n <= -1)
{
tio->errnum = QSE_TIO_EINPUT;
return -1;
}
tio->inbuf_cur = 0;
tio->inbuf_len = (qse_size_t)n;
}
do
{
buf[nread] = tio->inbuf[tio->inbuf_cur++];
/* TODO: support a different line terminator */
if (buf[nread++] == QSE_MT('\n')) goto done;
}
while (tio->inbuf_cur < tio->inbuf_len && nread < size);
}
if (tio->inbuf_curp >= tio->inbuf_len)
done:
return nread;
}
static QSE_INLINE int tio_read_widechars (qse_tio_t* tio)
{
qse_size_t mlen, wlen;
qse_ssize_t n;
int x;
if (tio->inbuf_cur >= tio->inbuf_len)
{
tio->inbuf_cur = 0;
tio->inbuf_len = 0;
getc_conv:
n = tio->input_func (
QSE_TIO_IO_DATA, tio->input_arg,
&tio->inbuf[left], QSE_COUNTOF(tio->inbuf)-left);
if (tio->input_status & STATUS_EOF) n = 0;
else
{
n = tio->input_func (
QSE_TIO_IO_DATA, tio->input_arg,
&tio->inbuf[tio->inbuf_len], QSE_COUNTOF(tio->inbuf) - tio->inbuf_len);
}
if (n == 0)
{
if (tio->inbuf_curp < tio->inbuf_len &&
!(tio->flags & QSE_TIO_IGNOREMBWCERR))
tio->input_status |= STATUS_EOF;
if (tio->inbuf_cur < tio->inbuf_len)
{
/* gargage left in the buffer */
tio->errnum = QSE_TIO_EICSEQ;
return -1;
/* no more input from the underlying input handler.
* but some incomplete bytes in the buffer. */
if (tio->flags & QSE_TIO_IGNOREMBWCERR)
{
/* tread them as illegal sequence */
goto ignore_illseq;
}
else
{
tio->errnum = QSE_TIO_EICSEQ;
return -1;
}
}
return 0;
@ -71,78 +124,106 @@ static qse_ssize_t tio_getc (qse_tio_t* tio, qse_char_t* c)
return -1;
}
tio->inbuf_curp = 0;
tio->inbuf_len = (qse_size_t)n + left;
tio->inbuf_len += n;
}
#ifdef QSE_CHAR_IS_MCHAR
curc = tio->inbuf[tio->inbuf_curp++];
#else
left = tio->inbuf_len - tio->inbuf_curp;
mlen = tio->inbuf_len - tio->inbuf_cur;
wlen = QSE_COUNTOF(tio->inwbuf);
n = qse_mbrtowc (
&tio->inbuf[tio->inbuf_curp], left, &curc, &tio->mbstate.in);
if (n == 0)
x = qse_mbsntowcsn (&tio->inbuf[tio->inbuf_cur], &mlen, tio->inwbuf, &wlen);
tio->inbuf_cur += mlen;
if (x == -3)
{
/* incomplete sequence */
if (wlen <= 0)
{
/* not even a single character was handled.
* shift bytes in the buffer to the head. */
QSE_ASSERT (mlen <= 0);
tio->inbuf_len = tio->inbuf_len - tio->inbuf_cur;
QSE_MEMCPY (&tio->inbuf[0],
&tio->inbuf[tio->inbuf_cur],
tio->inbuf_len * QSE_SIZEOF(tio->inbuf[0]));
tio->inbuf_cur = 0;
goto getc_conv; /* and read more */
}
/* get going if some characters are handled */
}
else if (x == -2)
{
/* buffer not large enough */
QSE_ASSERTX (wlen > 0,
"You must enlarge the size of tio->inwbuf if this happens.");
/* the wide-character buffer is not just large enough to
* hold the entire conversion result. lets's go on so long as
* 1 wide-character is produced though it may be inefficient */
}
else if (x <= -1)
{
/* illegal sequence */
if (tio->flags & QSE_TIO_IGNOREMBWCERR)
{
/* *c = tio->inbuf[tio->inbuf_curp++]; */
*c = QSE_WT('?');
tio->inbuf_curp++;
return 1;
ignore_illseq:
tio->inbuf_cur++; /* skip one byte */
tio->inwbuf[wlen++] = QSE_WT('?');
}
tio->inbuf_curp++; /* skip one byte */
tio->errnum = QSE_TIO_EILSEQ;
return -1;
}
if (n > left)
{
/* incomplete sequence */
if (tio->inbuf_curp > 0)
else if (wlen <= 0)
{
QSE_MEMCPY (tio->inbuf, &tio->inbuf[tio->inbuf_curp], left);
tio->inbuf_curp = 0;
tio->inbuf_len = left;
tio->errnum = QSE_TIO_EILSEQ;
return -1;
}
else
{
/* some characters are already handled.
* mark that an illegal sequence encountered
* and carry on. */
tio->input_status |= STATUS_ILLSEQ;
}
goto getc_conv;
}
tio->inbuf_curp += n;
#endif
*c = curc;
tio->inwbuf_cur = 0;
tio->inwbuf_len = wlen;
return 1;
}
qse_ssize_t qse_tio_read (qse_tio_t* tio, qse_char_t* buf, qse_size_t size)
qse_ssize_t qse_tio_readwcs (qse_tio_t* tio, qse_wchar_t* buf, qse_size_t size)
{
qse_ssize_t n;
qse_char_t* p, * end, c;
qse_size_t nread = 0;
if (size <= 0) return 0;
p = buf; end = buf + size;
while (p < end)
/*QSE_ASSERT (tio->input_func != QSE_NULL);*/
if (tio->input_func == QSE_NULL)
{
n = tio_getc (tio, &c);
if (n == -1)
{
if (p > buf && tio->errnum == QSE_TIO_EILSEQ)
{
tio->input_status |= STATUS_GETC_EILSEQ;
break;
}
return -1;
}
if (n == 0) break;
*p++ = c;
/* TODO: support a different line breaker */
if (c == QSE_T('\n')) break;
tio->errnum = QSE_TIO_ENOINF;
return -1;
}
return p - buf;
}
if (size > QSE_TYPE_MAX(qse_ssize_t)) size = QSE_TYPE_MAX(qse_ssize_t);
while (nread < size)
{
if (tio->inwbuf_cur >= tio->inwbuf_len)
{
int n;
/* no more characters in the wide-charcter buffer */
if (tio->input_status & STATUS_ILLSEQ)
{
tio->input_status &= ~STATUS_ILLSEQ;
tio->errnum = QSE_TIO_EILSEQ;
return -1;
}
n = tio_read_widechars (tio);
if (n == 0) break;
if (n <= -1) return -1;
}
buf[nread] = tio->inwbuf[tio->inwbuf_cur++];
if (buf[nread++] == QSE_WT('\n')) break;
}
return nread;
}

View File

@ -21,121 +21,9 @@
#include <qse/cmn/tio.h>
#include <qse/cmn/chr.h>
static qse_ssize_t tio_putc (qse_tio_t* tio, qse_char_t c, int* flush_needed)
{
#ifdef QSE_CHAR_IS_WCHAR
qse_size_t n, i;
qse_mchar_t mc[QSE_MBLEN_MAX];
#endif
if (tio->outbuf_len >= QSE_COUNTOF(tio->outbuf))
{
/* maybe, previous flush operation has failed a few
* times previously. so the buffer is full.
*/
tio->errnum = QSE_TIO_ENOSPC;
return -1;
}
#ifdef QSE_CHAR_IS_MCHAR
tio->outbuf[tio->outbuf_len++] = c;
if (tio->outbuf_len >= QSE_COUNTOF(tio->outbuf))
{
*flush_needed = 0;
return qse_tio_flush (tio);
}
#else /* QSE_CHAR_IS_WCHAR */
n = qse_wcrtomb (c, mc, QSE_COUNTOF(mc), &tio->mbstate.out);
if (n == 0)
{
if (tio->flags & QSE_TIO_IGNOREMBWCERR)
{
/* return 1 as if c has been written successfully */
return 1;
}
tio->errnum = QSE_TIO_EILCHR;
return -1;
}
else if (n > QSE_COUNTOF(mc))
{
if (tio->flags & QSE_TIO_IGNOREMBWCERR) return 1;
tio->errnum = QSE_TIO_ENOSPC;
return -1;
}
for (i = 0; i < n; i++)
{
tio->outbuf[tio->outbuf_len++] = mc[i];
if (tio->outbuf_len >= QSE_COUNTOF(tio->outbuf))
{
*flush_needed = 0;
if (qse_tio_flush (tio) <= -1) return -1;
}
}
#endif
if (c == QSE_T('\n') && tio->outbuf_len > 0)
{
/*if (qse_tio_flush (tio) <= -1) return -1;*/
*flush_needed = 1;
}
return 1;
}
qse_ssize_t qse_tio_write (qse_tio_t* tio, const qse_char_t* str, qse_size_t size)
{
qse_ssize_t n;
const qse_char_t* p;
int flush_needed = 0;
if (size == 0) return 0;
p = str;
if (size == (qse_size_t)-1)
{
/* TODO: should not write more than than QSE_TYPE_MAX(qse_ssize_t) */
while (*p != QSE_T('\0'))
{
n = tio_putc (tio, *p, &flush_needed);
if (n <= -1) return -1;
if (n == 0) break;
p++;
}
}
else
{
const qse_char_t* end;
/* TODO: size should not be longer than QSE_TYPE_MAX(qse_ssize_t) */
end = str + size;
while (p < end)
{
n = tio_putc (tio, *p, &flush_needed);
if (n <= -1) return -1;
if (n == 0) break;
p++;
}
}
if (flush_needed && qse_tio_flush(tio) <= -1) return -1;
return p - str;
}
qse_ssize_t qse_tio_writembsn (
qse_ssize_t qse_tio_writembs (
qse_tio_t* tio, const qse_mchar_t* mptr, qse_size_t mlen)
{
const qse_mchar_t* xptr, * xend;
qse_size_t capa;
int nl = 0;
if (tio->outbuf_len >= QSE_COUNTOF(tio->outbuf))
{
/* maybe, previous flush operation has failed a few
@ -145,58 +33,107 @@ qse_ssize_t qse_tio_writembsn (
return -1;
}
/* adjust mlen for the type difference between the parameter
* and the return value */
if (mlen > QSE_TYPE_MAX(qse_ssize_t)) mlen = QSE_TYPE_MAX(qse_ssize_t);
xptr = mptr;
if (mlen == (qse_size_t)-1)
{
qse_size_t pos = 0;
/* handle the parts that can't fit into the internal buffer */
while (mlen >= (capa = QSE_COUNTOF(tio->outbuf) - tio->outbuf_len))
{
for (xend = xptr + capa; xptr < xend; xptr++)
tio->outbuf[tio->outbuf_len++] = *xptr;
if (qse_tio_flush (tio) <= -1) return -1;
mlen -= capa;
}
if (tio->flags & QSE_TIO_NOAUTOFLUSH)
{
/* handle the last part that can fit into the internal buffer */
for (xend = xptr + mlen; xptr < xend; xptr++)
tio->outbuf[tio->outbuf_len++] = *xptr;
}
else
{
/* handle the last part that can fit into the internal buffer */
for (xend = xptr + mlen; xptr < xend; xptr++)
if (tio->flags & QSE_TIO_NOAUTOFLUSH)
{
/* TODO: support different line terminating characeter */
tio->outbuf[tio->outbuf_len++] = *xptr;
if (*xptr == QSE_MT('\n'))
while (mptr[pos])
{
nl = 1;
break;
tio->outbuf[tio->outbuf_len++] = mptr[pos++];
if (tio->outbuf_len >= QSE_COUNTOF(tio->outbuf) &&
qse_tio_flush (tio) <= -1) return -1;
if (pos >= QSE_TYPE_MAX(qse_ssize_t)) break;
}
}
else
{
int nl = 0;
while (mptr[pos])
{
tio->outbuf[tio->outbuf_len++] = mptr[pos];
if (tio->outbuf_len >= QSE_COUNTOF(tio->outbuf))
{
if (qse_tio_flush (tio) <= -1) return -1;
nl = 0;
}
else if (mptr[pos] == QSE_T('\n')) nl = 1;
/* TODO: different line terminator */
if (++pos >= QSE_TYPE_MAX(qse_ssize_t)) break;
}
if (nl && qse_tio_flush(tio) <= -1) return -1;
}
for (; xptr < xend; xptr++)
tio->outbuf[tio->outbuf_len++] = *xptr;
return pos;
}
else
{
const qse_mchar_t* xptr, * xend;
qse_size_t capa;
int nl = 0;
/* if the last part contains a new line, flush the internal
* buffer. note that this flushes characters after nl also.*/
if (nl && qse_tio_flush (tio) <= -1) return -1;
/* adjust mlen for the type difference between the parameter
* and the return value */
if (mlen > QSE_TYPE_MAX(qse_ssize_t)) mlen = QSE_TYPE_MAX(qse_ssize_t);
xptr = mptr;
/* returns the number multi-bytes characters handled */
return xptr - mptr;
/* handle the parts that can't fit into the internal buffer */
while (mlen >= (capa = QSE_COUNTOF(tio->outbuf) - tio->outbuf_len))
{
for (xend = xptr + capa; xptr < xend; xptr++)
tio->outbuf[tio->outbuf_len++] = *xptr;
if (qse_tio_flush (tio) <= -1) return -1;
mlen -= capa;
}
if (tio->flags & QSE_TIO_NOAUTOFLUSH)
{
/* handle the last part that can fit into the internal buffer */
for (xend = xptr + mlen; xptr < xend; xptr++)
tio->outbuf[tio->outbuf_len++] = *xptr;
}
else
{
/* handle the last part that can fit into the internal buffer */
for (xend = xptr + mlen; xptr < xend; xptr++)
{
/* TODO: support different line terminating characeter */
tio->outbuf[tio->outbuf_len++] = *xptr;
if (*xptr == QSE_MT('\n'))
{
nl = 1;
break;
}
}
while (xptr < xend) tio->outbuf[tio->outbuf_len++] = *xptr++;
}
/* if the last part contains a new line, flush the internal
* buffer. note that this flushes characters after nl also.*/
if (nl && qse_tio_flush (tio) <= -1) return -1;
/* returns the number multi-bytes characters handled */
return xptr - mptr;
}
}
qse_ssize_t qse_tio_writewcsn (
qse_ssize_t qse_tio_writewcs (
qse_tio_t* tio, const qse_wchar_t* wptr, qse_size_t wlen)
{
qse_size_t capa, wcnt, mcnt, xwlen;
int n, nl = 0;
if (tio->outbuf_len >= QSE_COUNTOF(tio->outbuf))
{
/* maybe, previous flush operation has failed a few
* times previously. so the buffer is full.
*/
tio->errnum = QSE_TIO_ENOSPC;
return -1;
}
if (wlen == (qse_size_t)-1) wlen = qse_wcslen(wptr);
if (wlen > QSE_TYPE_MAX(qse_ssize_t)) wlen = QSE_TYPE_MAX(qse_ssize_t);
xwlen = wlen;
@ -251,13 +188,16 @@ qse_ssize_t qse_tio_writewcsn (
{
if (!(tio->flags & QSE_TIO_NOAUTOFLUSH) && !nl)
{
qse_size_t i;
/* checking for a newline this way looks damn ugly.
* TODO: how can i do this more elegantly? */
for (i = 0; i < wcnt; i++)
qse_size_t i = wcnt;
while (i > 0)
{
if (wptr[i] == QSE_WT('\n'))
/* scan backward assuming a line terminator
* is typically at the back */
if (wptr[--i] == QSE_WT('\n'))
{
/* TOOD: differetn line terminator */
nl = 1;
break;
}

View File

@ -72,7 +72,7 @@ int qse_tio_init (qse_tio_t* tio, qse_mmgr_t* mmgr, int flags)
tio->output_arg = QSE_NULL;
tio->input_status = 0;
tio->inbuf_curp = 0;
tio->inbuf_cur = 0;
tio->inbuf_len = 0;
tio->outbuf_len = 0;
*/
@ -136,7 +136,7 @@ int qse_tio_attachin (qse_tio_t* tio, qse_tio_io_t input, void* arg)
tio->input_arg = arg;
tio->input_status = 0;
tio->inbuf_curp = 0;
tio->inbuf_cur = 0;
tio->inbuf_len = 0;
return 0;
@ -237,7 +237,7 @@ qse_ssize_t qse_tio_flush (qse_tio_t* tio)
void qse_tio_purge (qse_tio_t* tio)
{
tio->input_status = 0;
tio->inbuf_curp = 0;
tio->inbuf_cur = 0;
tio->inbuf_len = 0;
tio->outbuf_len = 0;
tio->errnum = QSE_TIO_ENOERR;