added qse_tio_writembs() and qse_tio_readmbs()

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

View File

@ -78,7 +78,7 @@ static qse_ssize_t in (
case QSE_CUT_IO_READ:
{
qse_ssize_t n = qse_sio_getsn (arg->handle, buf, size);
qse_ssize_t n = qse_sio_getstrn (arg->handle, buf, size);
if (n <= -1)
{
qse_cstr_t ea;
@ -139,7 +139,7 @@ static qse_ssize_t out (
case QSE_CUT_IO_WRITE:
{
qse_ssize_t n = qse_sio_putsn (arg->handle, data, len);
qse_ssize_t n = qse_sio_putstrn (arg->handle, data, len);
if (n <= -1)
{
qse_cstr_t ea;

View File

@ -133,7 +133,6 @@ struct qse_fio_t
* in sio.c. make sure that you update the static instantiation
* when you change the structure of qse_fio_t */
QSE_DEFINE_COMMON_FIELDS (fio)
int errnum;
qse_fio_hnd_t handle;
int flags; /* extra flags */
qse_tio_t* tio;
@ -147,7 +146,6 @@ struct qse_fio_lck_t
qse_fio_ori_t origin; /* origin */
};
#define QSE_FIO_ERRNUM(fio) ((fio)->errnum)
#define QSE_FIO_HANDLE(fio) ((fio)->handle)
#ifdef __cplusplus

View File

@ -40,6 +40,7 @@ enum qse_pio_oflag_t
/** enable text based I/O. */
QSE_PIO_TEXT = (1 << 0),
QSE_PIO_IGNOREMBWCERR = (1 << 1),
QSE_PIO_NOAUTOFLUSH = (1 << 2),
/** execute the command via a system shell
* (/bin/sh on *nix, cmd.exe on windows) */

View File

@ -30,7 +30,7 @@
#include <qse/cmn/fio.h>
#include <qse/cmn/tio.h>
enum qse_sio_open_flag_t
enum qse_sio_oflag_t
{
QSE_SIO_HANDLE = QSE_FIO_HANDLE,
QSE_SIO_TEMPORARY = QSE_FIO_TEMPORARY,
@ -60,6 +60,15 @@ enum qse_sio_open_flag_t
QSE_SIO_NOAUTOFLUSH = (1 << 31)
};
typedef qse_tio_errnum_t qse_sio_errnum_t;
#define QSE_SIO_ENOERR QSE_TIO_ENOERR
#define QSE_SIO_ENOMEM QSE_TIO_ENOMEM
#define QSE_SIO_ENOSPC QSE_TIO_ENOSPC
#define QSE_SIO_EILSEQ QSE_TIO_EILSEQ
#define QSE_SIO_EICSEQ QSE_TIO_EICSEQ
#define QSE_SIO_EILCHR QSE_TIO_EILCHR
#define QSE_SIO_ERRNUM(sio) QSE_TIO_ERRNUM(&((sio)->tio))
typedef qse_fio_off_t qse_sio_pos_t;
typedef qse_fio_hnd_t qse_sio_hnd_t;
typedef qse_fio_std_t qse_sio_std_t;
@ -76,7 +85,7 @@ typedef struct qse_sio_t qse_sio_t;
struct qse_sio_t
{
qse_mmgr_t* mmgr;
QSE_DEFINE_COMMON_FIELDS (tio)
qse_fio_t fio;
qse_tio_t tio;
};
@ -100,14 +109,14 @@ qse_sio_t* qse_sio_open (
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t xtnsize, /**< extension size in bytes */
const qse_char_t* file, /**< file name */
int flags /**< number OR'ed of #qse_sio_open_flag_t */
int oflags /**< number OR'ed of #qse_sio_oflag_t */
);
qse_sio_t* qse_sio_openstd (
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t xtnsize, /**< extension size in bytes */
qse_sio_std_t std, /**< standard I/O identifier */
int flags /**< number OR'ed of #qse_sio_open_flag_t */
int oflags /**< number OR'ed of #qse_sio_oflag_t */
);
/**
@ -135,7 +144,11 @@ void qse_sio_fini (
qse_sio_t* sio
);
qse_fio_hnd_t qse_sio_gethandle (
qse_sio_errnum_t qse_sio_geterrnum (
qse_sio_t* sio
);
qse_sio_hnd_t qse_sio_gethandle (
qse_sio_t* sio
);
@ -147,57 +160,91 @@ void qse_sio_purge (
qse_sio_t* sio
);
qse_ssize_t qse_sio_getc (
qse_ssize_t qse_sio_getmc (
qse_sio_t* sio,
qse_char_t* c
qse_mchar_t* c
);
qse_ssize_t qse_sio_gets (
qse_ssize_t qse_sio_getwc (
qse_sio_t* sio,
qse_char_t* buf,
qse_wchar_t* c
);
qse_ssize_t qse_sio_getmbs (
qse_sio_t* sio,
qse_mchar_t* buf,
qse_size_t size
);
qse_ssize_t qse_sio_getsn (
qse_ssize_t qse_sio_getmbsn (
qse_sio_t* sio,
qse_char_t* buf,
qse_mchar_t* buf,
qse_size_t size
);
qse_ssize_t qse_sio_putc (
qse_ssize_t qse_sio_getwcs (
qse_sio_t* sio,
qse_char_t c
qse_wchar_t* buf,
qse_size_t size
);
qse_ssize_t qse_sio_putms (
qse_ssize_t qse_sio_getwcsn (
qse_sio_t* sio,
qse_wchar_t* buf,
qse_size_t size
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_sio_getc(sio,c) qse_sio_getmb(sio,c)
# define qse_sio_getstr(sio,buf,size) qse_sio_getmbs(sio,buf,size)
# define qse_sio_getstrn(sio,buf,size) qse_sio_getmbsn(sio,buf,size)
#else
# define qse_sio_getc(sio,c) qse_sio_getwc(sio,c)
# define qse_sio_getstr(sio,buf,size) qse_sio_getwcs(sio,buf,size)
# define qse_sio_getstrn(sio,buf,size) qse_sio_getwcsn(sio,buf,size)
#endif
qse_ssize_t qse_sio_putmb (
qse_sio_t* sio,
qse_mchar_t c
);
qse_ssize_t qse_sio_putwc (
qse_sio_t* sio,
qse_wchar_t c
);
qse_ssize_t qse_sio_putmbs (
qse_sio_t* sio,
const qse_mchar_t* str
);
qse_ssize_t qse_sio_putws (
qse_ssize_t qse_sio_putwcs (
qse_sio_t* sio,
const qse_wchar_t* str
);
qse_ssize_t qse_sio_putmsn (
qse_ssize_t qse_sio_putmbsn (
qse_sio_t* sio,
const qse_mchar_t* str,
qse_size_t 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
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_sio_puts(sio,str) qse_sio_putms(sio,str)
# define qse_sio_putsn(sio,str,size) qse_sio_putmsn(sio,str,size)
# define qse_sio_putc(sio,c) qse_sio_putmb(sio,c)
# define qse_sio_putstr(sio,str) qse_sio_putmbs(sio,str)
# define qse_sio_putstrn(sio,str,size) qse_sio_putmbsn(sio,str,size)
#else
# define qse_sio_puts(sio,str) qse_sio_putws(sio,str)
# define qse_sio_putsn(sio,str,size) qse_sio_putwsn(sio,str,size)
# define qse_sio_putc(sio,c) qse_sio_putwc(sio,c)
# define qse_sio_putstr(sio,str) qse_sio_putwcs(sio,str)
# define qse_sio_putstrn(sio,str,size) qse_sio_putwcsn(sio,str,size)
#endif
/**

View File

@ -57,7 +57,8 @@ enum
* (i.e. 6 for utf8)
*/
QSE_TIO_MAX_INBUF_LEN = 4096,
QSE_TIO_MAX_OUTBUF_LEN = 4096
QSE_TIO_MAX_OUTBUF_LEN = 4096,
QSE_TIO_MAX_INWBUF_LEN = 1024
};
enum qse_tio_cmd_t
@ -107,20 +108,15 @@ struct qse_tio_t
/* for housekeeping */
int input_status;
qse_size_t inbuf_curp;
qse_size_t inbuf_cur;
qse_size_t inbuf_len;
qse_size_t outbuf_len;
qse_size_t inwbuf_cur;
qse_size_t inwbuf_len;
qse_mchar_t inbuf[QSE_TIO_MAX_INBUF_LEN];
qse_mchar_t outbuf[QSE_TIO_MAX_OUTBUF_LEN];
#ifdef QSE_CHAR_IS_WCHAR
struct
{
qse_mbstate_t in;
qse_mbstate_t out;
} mbstate;
#endif
qse_wchar_t inwbuf[QSE_TIO_MAX_INWBUF_LEN];
};
#ifdef __cplusplus
@ -133,9 +129,9 @@ QSE_DEFINE_COMMON_FUNCTIONS (tio)
* The qse_tio_open() function creates an text stream processoor.
*/
qse_tio_t* qse_tio_open (
qse_mmgr_t* mmgr,
qse_size_t xtnsize,
int flags
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t xtnsize, /**< extension size in bytes */
int flags /**< ORed of qse_tio_flag_t enumerators */
);
/**
@ -228,37 +224,63 @@ void qse_tio_purge (
qse_tio_t* tio
);
/**
* The qse_tio_read() functio reads text.
*/
qse_ssize_t qse_tio_read (
qse_ssize_t qse_tio_readmbs (
qse_tio_t* tio,
qse_char_t* buf,
qse_mchar_t* buf,
qse_size_t size
);
qse_ssize_t qse_tio_readwcs (
qse_tio_t* tio,
qse_wchar_t* buf,
qse_size_t size
);
/**
* The qse_tio_write() function writes text.
* If the size paramenter is (qse_size_t)-1, the function treats the data
* parameter as a pointer to a null-terminated string.
* The qse_tio_read() macro is character-type neutral. It maps
* to qse_tio_readmbs() or qse_tio_readwcs().
*/
qse_ssize_t qse_tio_write (
#ifdef QSE_CHAR_IS_MCHAR
# define qse_tio_read(tio,buf,size) qse_tio_readmbs(tio,buf,size)
#else
# define qse_tio_read(tio,buf,size) qse_tio_readwcs(tio,buf,size)
#endif
/**
* The qse_tio_writembs() function writes the @a size characters
* from a multibyte string @a str. If @a size is (qse_size_t)-1,
* it writes on until a terminating null is found. It doesn't
* write more than QSE_TYPE_MAX(qse_ssize_t) characters.
* @return number of characters written on success, -1 on failure.
*/
qse_ssize_t qse_tio_writembs (
qse_tio_t* tio,
const qse_char_t* data,
const qse_mchar_t* str,
qse_size_t size
);
qse_ssize_t qse_tio_writembsn (
/**
* The qse_tio_writembs() function writes the @a size characters
* from a wide-character string @a str. If @a size is (qse_size_t)-1,
* it writes on until a terminating null is found. It doesn't write
* more than QSE_TYPE_MAX(qse_ssize_t) characters.
* @return number of characters written on success, -1 on failure.
*/
qse_ssize_t qse_tio_writewcs (
qse_tio_t* tio,
const qse_mchar_t* data,
const qse_wchar_t* str,
qse_size_t size
);
qse_ssize_t qse_tio_writewcsn (
qse_tio_t* tio,
const qse_wchar_t* data,
qse_size_t size
);
/**
* The qse_tio_write() macro is character-type neutral. It maps
* to qse_tio_writembs() or qse_tio_writewcs().
*/
#ifdef QSE_CHAR_IS_MCHAR
# define qse_tio_write(tio,str,size) qse_tio_writembs(tio,str,size)
#else
# define qse_tio_write(tio,str,size) qse_tio_writewcs(tio,str,size)
#endif
#ifdef __cplusplus
}

View File

@ -533,16 +533,7 @@ int StdAwk::openConsole (Console& io)
int StdAwk::closeConsole (Console& io)
{
qse_sio_t* sio;
sio = (qse_sio_t*)io.getHandle();
if (sio != qse_sio_in &&
sio != qse_sio_out &&
sio != qse_sio_err)
{
qse_sio_close (sio);
}
qse_sio_close ((qse_sio_t*)io.getHandle());
return 0;
}
@ -550,7 +541,7 @@ StdAwk::ssize_t StdAwk::readConsole (Console& io, char_t* data, size_t size)
{
qse_ssize_t nn;
while ((nn = qse_sio_getsn((qse_sio_t*)io.getHandle(),data,size)) == 0)
while ((nn = qse_sio_getstrn((qse_sio_t*)io.getHandle(),data,size)) == 0)
{
int n;
qse_sio_t* sio = (qse_sio_t*)io.getHandle();
@ -564,13 +555,7 @@ StdAwk::ssize_t StdAwk::readConsole (Console& io, char_t* data, size_t size)
return 0;
}
if (sio != QSE_NULL &&
sio != qse_sio_in &&
sio != qse_sio_out &&
sio != qse_sio_err)
{
qse_sio_close (sio);
}
if (sio) qse_sio_close (sio);
}
return nn;
@ -578,7 +563,7 @@ StdAwk::ssize_t StdAwk::readConsole (Console& io, char_t* data, size_t size)
StdAwk::ssize_t StdAwk::writeConsole (Console& io, const char_t* data, size_t size)
{
return qse_sio_putsn (
return qse_sio_putstrn (
(qse_sio_t*)io.getHandle(),
data,
size
@ -605,14 +590,7 @@ int StdAwk::nextConsole (Console& io)
return 0;
}
if (sio != QSE_NULL &&
sio != qse_sio_in &&
sio != qse_sio_out &&
sio != qse_sio_err)
{
qse_sio_close (sio);
}
if (sio) qse_sio_close (sio);
return n;
}
@ -872,25 +850,19 @@ int StdAwk::SourceFile::open (Data& io)
int StdAwk::SourceFile::close (Data& io)
{
qse_sio_t* sio = (qse_sio_t*)io.getHandle();
qse_sio_flush (sio);
if (sio != qse_sio_in && sio != qse_sio_out && sio != qse_sio_err)
{
qse_sio_close (sio);
}
return 0;
}
StdAwk::ssize_t StdAwk::SourceFile::read (Data& io, char_t* buf, size_t len)
{
return qse_sio_getsn ((qse_sio_t*)io.getHandle(), buf, len);
return qse_sio_getstrn ((qse_sio_t*)io.getHandle(), buf, len);
}
StdAwk::ssize_t StdAwk::SourceFile::write (Data& io, const char_t* buf, size_t len)
{
return qse_sio_putsn ((qse_sio_t*)io.getHandle(), buf, len);
return qse_sio_putstrn ((qse_sio_t*)io.getHandle(), buf, len);
}
int StdAwk::SourceString::open (Data& io)
@ -947,7 +919,7 @@ StdAwk::ssize_t StdAwk::SourceString::read (Data& io, char_t* buf, size_t len)
}
else
{
return qse_sio_getsn ((qse_sio_t*)io.getHandle(), buf, len);
return qse_sio_getstrn ((qse_sio_t*)io.getHandle(), buf, len);
}
}
@ -961,7 +933,7 @@ StdAwk::ssize_t StdAwk::SourceString::write (Data& io, const char_t* buf, size_t
{
// in fact, this block will never be reached as
// there is no included file concept for deparsing
return qse_sio_putsn ((qse_sio_t*)io.getHandle(), buf, len);
return qse_sio_putstrn ((qse_sio_t*)io.getHandle(), buf, len);
}
}

View File

@ -509,7 +509,7 @@ static qse_ssize_t sf_in_read (
qse_ssize_t n;
QSE_ASSERT (xtn->s.in.handle != QSE_NULL);
n = qse_sio_getsn (xtn->s.in.handle, data, size);
n = qse_sio_getstrn (xtn->s.in.handle, data, size);
if (n == -1)
{
qse_cstr_t ea;
@ -549,7 +549,7 @@ static qse_ssize_t sf_in_read (
qse_ssize_t n;
QSE_ASSERT (arg->handle != QSE_NULL);
n = qse_sio_getsn (arg->handle, data, size);
n = qse_sio_getstrn (arg->handle, data, size);
if (n == -1)
{
qse_cstr_t ea;
@ -672,7 +672,7 @@ static qse_ssize_t sf_out (
{
qse_ssize_t n;
QSE_ASSERT (xtn->s.out.handle != QSE_NULL);
n = qse_sio_putsn (xtn->s.out.handle, data, size);
n = qse_sio_putstrn (xtn->s.out.handle, data, size);
if (n == -1)
{
qse_cstr_t ea;
@ -1220,7 +1220,7 @@ static qse_ssize_t awk_rio_console (
{
qse_ssize_t nn;
while ((nn = qse_sio_getsn((qse_sio_t*)riod->handle,data,size)) == 0)
while ((nn = qse_sio_getstrn((qse_sio_t*)riod->handle,data,size)) == 0)
{
int n;
qse_sio_t* sio = (qse_sio_t*)riod->handle;
@ -1241,7 +1241,7 @@ static qse_ssize_t awk_rio_console (
}
case QSE_AWK_RIO_WRITE:
return qse_sio_putsn (
return qse_sio_putstrn (
(qse_sio_t*)riod->handle,
data,
size

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,46 +22,99 @@
#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;
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;
}
if (tio->inbuf_curp >= tio->inbuf_len)
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);
}
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:
if (tio->input_status & STATUS_EOF) n = 0;
else
{
n = tio->input_func (
QSE_TIO_IO_DATA, tio->input_arg,
&tio->inbuf[left], QSE_COUNTOF(tio->inbuf)-left);
&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)
{
/* 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
{
/* gargage left in the buffer */
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 */
else if (wlen <= 0)
{
tio->errnum = QSE_TIO_EILSEQ;
return -1;
}
if (n > left)
else
{
/* incomplete sequence */
if (tio->inbuf_curp > 0)
{
QSE_MEMCPY (tio->inbuf, &tio->inbuf[tio->inbuf_curp], left);
tio->inbuf_curp = 0;
tio->inbuf_len = left;
/* 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;
}
tio->errnum = QSE_TIO_ENOINF;
return -1;
}
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;
*p++ = c;
/* TODO: support a different line breaker */
if (c == QSE_T('\n')) break;
if (n <= -1) return -1;
}
return p - buf;
buf[nread] = tio->inwbuf[tio->inwbuf_cur++];
if (buf[nread++] == QSE_WT('\n')) break;
}
return nread;
}

View File

@ -21,13 +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)
qse_ssize_t qse_tio_writembs (
qse_tio_t* tio, const qse_mchar_t* mptr, qse_size_t mlen)
{
#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
@ -37,114 +33,46 @@ static qse_ssize_t tio_putc (qse_tio_t* tio, qse_char_t c, int* flush_needed)
return -1;
}
#ifdef QSE_CHAR_IS_MCHAR
tio->outbuf[tio->outbuf_len++] = c;
if (tio->outbuf_len >= QSE_COUNTOF(tio->outbuf))
if (mlen == (qse_size_t)-1)
{
*flush_needed = 0;
return qse_tio_flush (tio);
}
qse_size_t pos = 0;
#else /* QSE_CHAR_IS_WCHAR */
n = qse_wcrtomb (c, mc, QSE_COUNTOF(mc), &tio->mbstate.out);
if (n == 0)
if (tio->flags & QSE_TIO_NOAUTOFLUSH)
{
if (tio->flags & QSE_TIO_IGNOREMBWCERR)
while (mptr[pos])
{
/* 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++;
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
{
const qse_char_t* end;
/* TODO: size should not be longer than QSE_TYPE_MAX(qse_ssize_t) */
end = str + size;
while (p < end)
int nl = 0;
while (mptr[pos])
{
n = tio_putc (tio, *p, &flush_needed);
if (n <= -1) return -1;
if (n == 0) break;
p++;
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;
}
if (flush_needed && qse_tio_flush(tio) <= -1) return -1;
return p - str;
return pos;
}
qse_ssize_t qse_tio_writembsn (
qse_tio_t* tio, const qse_mchar_t* mptr, qse_size_t mlen)
else
{
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
* times previously. so the buffer is full.
*/
tio->errnum = QSE_TIO_ENOSPC;
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);
@ -178,9 +106,7 @@ qse_ssize_t qse_tio_writembsn (
break;
}
}
for (; xptr < xend; xptr++)
tio->outbuf[tio->outbuf_len++] = *xptr;
while (xptr < xend) tio->outbuf[tio->outbuf_len++] = *xptr++;
}
/* if the last part contains a new line, flush the internal
@ -190,13 +116,24 @@ qse_ssize_t qse_tio_writembsn (
/* 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;

View File

@ -28,61 +28,59 @@
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
static qse_sio_t* open_sio (StdCut::Stream::Data& io, const qse_char_t* file, int flags)
{
qse_sio_t* sio;
sio = qse_sio_open (((StdCut::cut_t*)io)->mmgr, 0, file, flags);
if (sio == QSE_NULL)
{
qse_cstr_t ea;
ea.ptr = file;
ea.len = qse_strlen (file);
((StdCut::Cut*)io)->setError (QSE_CUT_EIOFIL, &ea);
}
return sio;
}
static qse_sio_t* open_sio_std (StdCut::Stream::Data& io, qse_sio_std_t std, int flags)
{
qse_sio_t* sio;
static const qse_char_t* std_names[] =
{
QSE_T("stdin"),
QSE_T("stdout"),
QSE_T("stderr"),
};
sio = qse_sio_openstd (((StdCut::cut_t*)io)->mmgr, 0, std, flags);
if (sio == QSE_NULL)
{
qse_cstr_t ea;
ea.ptr = std_names[std];
ea.len = qse_strlen (std_names[std]);
((StdCut::Cut*)io)->setError (QSE_CUT_EIOFIL, &ea);
}
return sio;
}
int StdCut::FileStream::open (Data& io)
{
qse_sio_t* sio;
if (io.getMode() == READ)
{
if (infile == QSE_NULL) sio = qse_sio_in;
else
{
sio = qse_sio_open (
((cut_t*)io)->mmgr,
0,
infile,
QSE_SIO_READ
);
if (sio == QSE_NULL)
{
// set the error message explicitly
// as the file name is different from
// the standard console name (NULL)
qse_cstr_t ea;
ea.ptr = infile;
ea.len = qse_strlen (infile);
((Cut*)io)->setError (
QSE_CUT_EIOFIL, &ea);
return -1;
}
}
sio = (infile == QSE_NULL)?
open_sio_std (io, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR):
open_sio (io, infile, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
if (sio == QSE_NULL) return -1;
}
else
{
if (outfile == QSE_NULL) sio = qse_sio_out;
else
{
sio = qse_sio_open (
((cut_t*)io)->mmgr,
0,
outfile,
QSE_SIO_WRITE |
QSE_SIO_CREATE |
QSE_SIO_TRUNCATE
);
if (sio == QSE_NULL)
{
// set the error message explicitly
// as the file name is different from
// the standard console name (NULL)
qse_cstr_t ea;
ea.ptr = outfile;
ea.len = qse_strlen (outfile);
((Cut*)io)->setError (
QSE_CUT_EIOFIL, &ea);
return -1;
}
}
sio = (outfile == QSE_NULL)?
open_sio_std (io, QSE_SIO_STDIN, QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR):
open_sio (io, outfile, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR);
if (sio == QSE_NULL) return -1;
}
io.setHandle (sio);
@ -94,7 +92,6 @@ int StdCut::FileStream::close (Data& io)
qse_sio_t* sio = (qse_sio_t*)io.getHandle();
qse_sio_flush (sio);
if (sio != qse_sio_in && sio != qse_sio_out && sio != qse_sio_err)
qse_sio_close (sio);
return 0;
@ -102,7 +99,7 @@ int StdCut::FileStream::close (Data& io)
StdCut::ssize_t StdCut::FileStream::read (Data& io, char_t* buf, size_t len)
{
ssize_t n = qse_sio_getsn ((qse_sio_t*)io.getHandle(), buf, len);
ssize_t n = qse_sio_getstrn ((qse_sio_t*)io.getHandle(), buf, len);
if (n == -1)
{
@ -123,7 +120,7 @@ StdCut::ssize_t StdCut::FileStream::read (Data& io, char_t* buf, size_t len)
StdCut::ssize_t StdCut::FileStream::write (Data& io, const char_t* buf, size_t len)
{
ssize_t n = qse_sio_putsn ((qse_sio_t*)io.getHandle(), buf, len);
ssize_t n = qse_sio_putstrn ((qse_sio_t*)io.getHandle(), buf, len);
if (n == -1)
{

View File

@ -64,6 +64,43 @@ int qse_cut_compstd (qse_cut_t* cut, const qse_char_t* sptr)
return qse_cut_comp (cut, sptr, qse_strlen(sptr));
}
static qse_sio_t* open_sio (qse_cut_t* cut, const qse_char_t* file, int flags)
{
qse_sio_t* sio;
sio = qse_sio_open (cut->mmgr, 0, file, flags);
if (sio == QSE_NULL)
{
qse_cstr_t ea;
ea.ptr = file;
ea.len = qse_strlen (file);
qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea);
}
return sio;
}
static const qse_char_t* sio_std_names[] =
{
QSE_T("stdin"),
QSE_T("stdout"),
QSE_T("stderr"),
};
static qse_sio_t* open_sio_std (qse_cut_t* cut, qse_sio_std_t std, int flags)
{
qse_sio_t* sio;
sio = qse_sio_openstd (cut->mmgr, 0, std, flags);
if (sio == QSE_NULL)
{
qse_cstr_t ea;
ea.ptr = sio_std_names[std];
ea.len = qse_strlen (sio_std_names[std]);
qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea);
}
return sio;
}
static qse_ssize_t xin (
qse_cut_t* cut, qse_cut_io_cmd_t cmd, qse_cut_io_arg_t* arg,
qse_char_t* buf, qse_size_t len)
@ -76,28 +113,9 @@ static qse_ssize_t xin (
case QSE_CUT_IO_OPEN:
{
/* main data stream */
if (xtn->infile == QSE_NULL) sio = qse_sio_in;
else
{
sio = qse_sio_open (
cut->mmgr,
0,
xtn->infile,
QSE_SIO_READ
);
if (sio == QSE_NULL)
{
/* set the error message explicitly
* as the file name is different from
* the standard console name (NULL) */
qse_cstr_t ea;
ea.ptr = xtn->infile;
ea.len = qse_strlen (xtn->infile);
qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea);
return -1;
}
}
sio = (xtn->infile == QSE_NULL)?
open_sio_std (cut, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR):
open_sio (cut, xtn->infile, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
if (sio == QSE_NULL) return -1;
arg->handle = sio;
return 1;
@ -106,14 +124,13 @@ static qse_ssize_t xin (
case QSE_CUT_IO_CLOSE:
{
sio = (qse_sio_t*)arg->handle;
if (sio != qse_sio_in && sio != qse_sio_out && sio != qse_sio_err)
qse_sio_close (sio);
return 0;
}
case QSE_CUT_IO_READ:
{
qse_ssize_t n = qse_sio_getsn (arg->handle, buf, len);
qse_ssize_t n = qse_sio_getstrn (arg->handle, buf, len);
if (n == -1)
{
@ -145,30 +162,9 @@ static qse_ssize_t xout (
{
case QSE_CUT_IO_OPEN:
{
if (xtn->outfile == QSE_NULL) sio = qse_sio_out;
else
{
sio = qse_sio_open (
cut->mmgr,
0,
xtn->outfile,
QSE_SIO_WRITE |
QSE_SIO_CREATE |
QSE_SIO_TRUNCATE
);
if (sio == QSE_NULL)
{
/* set the error message explicitly
* as the file name is different from
* the standard console name (NULL) */
qse_cstr_t ea;
ea.ptr = xtn->outfile;
ea.len = qse_strlen (xtn->outfile);
qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea);
return -1;
}
}
sio = (xtn->infile == QSE_NULL)?
open_sio_std (cut, QSE_SIO_STDOUT, QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR):
open_sio (cut, xtn->outfile, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR);
if (sio == QSE_NULL) return -1;
arg->handle = sio;
return 1;
@ -178,14 +174,13 @@ static qse_ssize_t xout (
{
sio = (qse_sio_t*)arg->handle;
qse_sio_flush (sio);
if (sio != qse_sio_in && sio != qse_sio_out && sio != qse_sio_err)
qse_sio_close (sio);
return 0;
}
case QSE_CUT_IO_WRITE:
{
qse_ssize_t n = qse_sio_putsn (arg->handle, dat, len);
qse_ssize_t n = qse_sio_putstrn (arg->handle, dat, len);
if (n == -1)
{

View File

@ -114,7 +114,7 @@ int StdSed::FileStream::close (Data& io)
StdSed::ssize_t StdSed::FileStream::read (Data& io, char_t* buf, size_t len)
{
ssize_t n = qse_sio_getsn ((qse_sio_t*)io.getHandle(), buf, len);
ssize_t n = qse_sio_getstrn ((qse_sio_t*)io.getHandle(), buf, len);
if (n == -1)
{
@ -135,7 +135,7 @@ StdSed::ssize_t StdSed::FileStream::read (Data& io, char_t* buf, size_t len)
StdSed::ssize_t StdSed::FileStream::write (Data& io, const char_t* buf, size_t len)
{
ssize_t n = qse_sio_putsn ((qse_sio_t*)io.getHandle(), buf, len);
ssize_t n = qse_sio_putstrn ((qse_sio_t*)io.getHandle(), buf, len);
if (n == -1)
{
@ -242,7 +242,7 @@ StdSed::ssize_t StdSed::StringStream::read (Data& io, char_t* buf, size_t len)
else
{
QSE_ASSERT (handle != &out.buf);
return qse_sio_getsn ((qse_sio_t*)handle, buf, len);
return qse_sio_getstrn ((qse_sio_t*)handle, buf, len);
}
}
@ -265,7 +265,7 @@ StdSed::ssize_t StdSed::StringStream::write (Data& io, const char_t* data, size_
else
{
QSE_ASSERT (handle != in.ptr);
return qse_sio_putsn ((qse_sio_t*)handle, data, len);
return qse_sio_putstrn ((qse_sio_t*)handle, data, len);
}
}

View File

@ -347,7 +347,7 @@ static qse_ssize_t read_input_stream (
while (base->mempos < io->u.mem.len && n < len)
buf[n++] = io->u.mem.ptr[base->mempos++];
}
else n = qse_sio_getsn (arg->handle, buf, len);
else n = qse_sio_getstrn (arg->handle, buf, len);
if (n != 0)
{
if (n <= -1)
@ -523,7 +523,7 @@ static qse_ssize_t x_in (
if (xtn->e.in.ptr == QSE_NULL)
{
qse_ssize_t n;
n = qse_sio_getsn (arg->handle, buf, len);
n = qse_sio_getstrn (arg->handle, buf, len);
if (n <= -1)
{
qse_cstr_t ea;
@ -539,7 +539,7 @@ static qse_ssize_t x_in (
else
{
qse_ssize_t n;
n = qse_sio_getsn (arg->handle, buf, len);
n = qse_sio_getstrn (arg->handle, buf, len);
if (n <= -1)
{
qse_cstr_t ea;
@ -631,7 +631,7 @@ static qse_ssize_t x_out (
if (xtn->e.out.ptr== QSE_NULL)
{
qse_ssize_t n;
n = qse_sio_putsn (arg->handle, dat, len);
n = qse_sio_putstrn (arg->handle, dat, len);
if (n <= -1)
{
qse_cstr_t ea;
@ -659,7 +659,7 @@ static qse_ssize_t x_out (
else
{
qse_ssize_t n;
n = qse_sio_putsn (arg->handle, dat, len);
n = qse_sio_putstrn (arg->handle, dat, len);
if (n <= -1)
{
qse_cstr_t ea;
@ -674,7 +674,7 @@ static qse_ssize_t x_out (
else
{
qse_ssize_t n;
n = qse_sio_putsn (arg->handle, dat, len);
n = qse_sio_putstrn (arg->handle, dat, len);
if (n <= -1)
{
qse_cstr_t ea;

View File

@ -1,11 +1,12 @@
#include <qse/cmn/sio.h>
#include <qse/cmn/fmt.h>
#include <locale.h>
#define R(f) \
do { \
qse_sio_puts (qse_sio_out,QSE_T("== ")); \
qse_sio_puts (qse_sio_out,QSE_T(#f)); \
qse_sio_puts (qse_sio_out,QSE_T(" ==\n")); \
qse_sio_putstr (qse_sio_out,QSE_T("== ")); \
qse_sio_putstr (qse_sio_out,QSE_T(#f)); \
qse_sio_putstr (qse_sio_out,QSE_T(" ==\n")); \
if (f() == -1) return -1; \
} while (0)
@ -13,33 +14,51 @@ static int test1 (void)
{
qse_sio_t* sio;
int i;
const qse_wchar_t* x[] =
const qse_wchar_t unistr[] =
{
L"\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?",
L"Fly to the universe, kick you ass",
L"\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?",
L"Fly to the universe, kick you ass",
L"Fly to the universe, kick you ass",
L"\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?"
/*L"\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?",*/
0xB108,
L' ',
0xBB50,
0xAC00,
L' ',
0xC798,
0xB0AC,
0xC5B4,
L'?',
L'\0'
};
const qse_wchar_t* x[] =
{
L"",
L"Fly to the universe, kick you ass",
L"",
L"Fly to the universe, kick you ass",
L"Fly to the universe, kick you ass",
L""
};
x[0] = unistr;
x[2] = unistr;
x[5] = unistr;
sio = qse_sio_open (QSE_NULL, 0, QSE_T("sio.txt"),
QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE);
if (sio == QSE_NULL)
{
qse_sio_puts (qse_sio_err, QSE_T("cannot open file\n"));
qse_sio_putstr (qse_sio_err, QSE_T("cannot open file\n"));
return -1;
}
for (i = 0; i < QSE_COUNTOF(x); i++)
{
qse_sio_puts (qse_sio_out, QSE_T("written: ["));
qse_sio_puts (qse_sio_out, x[i]);
qse_sio_puts (qse_sio_out, QSE_T("]\n"));
qse_sio_putstr (qse_sio_out, QSE_T("written: ["));
qse_sio_putstr (qse_sio_out, x[i]);
qse_sio_putstr (qse_sio_out, QSE_T("]\n"));
qse_sio_puts (sio, x[i]);
qse_sio_putstr (sio, x[i]);
qse_sio_putc (sio, QSE_T('\n'));
}
@ -51,35 +70,79 @@ static int test1 (void)
static int test2 (void)
{
qse_ssize_t n;
qse_char_t buf[20];
qse_wchar_t buf[20];
qse_sio_t* in, * out;
qse_sio_puts (qse_sio_out, QSE_T("type something...\n"));
in = qse_sio_openstd (QSE_NULL, 0, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
out = qse_sio_openstd (QSE_NULL, 0, QSE_SIO_STDOUT, QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR);
qse_sio_putstr (out, QSE_T("Type something...\n"));
while (1)
{
n = qse_sio_gets (qse_sio_in, buf, QSE_COUNTOF(buf));
n = qse_sio_getwcs (in, buf, QSE_COUNTOF(buf));
if (n == 0) break;
if (n < 0)
if (n <= -1)
{
qse_sio_puts (qse_sio_err, QSE_T("error ....\n"));
qse_char_t buf[32];
qse_fmtintmax (buf, QSE_COUNTOF(buf), qse_sio_geterrnum(in), 10, -1, QSE_T('\0'), QSE_NULL);
qse_sio_putstr (out, QSE_T("error .... "));
qse_sio_putstr (out, buf);
qse_sio_putstr (out, QSE_T("\n"));
break;
}
qse_sio_puts (qse_sio_out, buf);
qse_sio_putwcs (out, buf);
}
qse_sio_close (out);
qse_sio_close (in);
return 0;
}
static int test3 (void)
{
qse_ssize_t n;
qse_mchar_t buf[20];
qse_sio_t* in, * out;
in = qse_sio_openstd (QSE_NULL, 0, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
out = qse_sio_openstd (QSE_NULL, 0, QSE_SIO_STDOUT, QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR);
qse_sio_putstr (out, QSE_T("Type something...\n"));
while (1)
{
n = qse_sio_getmbs (in, buf, QSE_COUNTOF(buf));
if (n == 0) break;
if (n < 0)
{
qse_char_t buf[32];
qse_fmtintmax (buf, QSE_COUNTOF(buf), qse_sio_geterrnum(in), 10, -1, QSE_T('\0'), QSE_NULL);
qse_sio_putstr (out, QSE_T("error .... "));
qse_sio_putstr (out, buf);
qse_sio_putstr (out, QSE_T("\n"));
break;
}
qse_sio_putmbs (out, buf);
}
qse_sio_close (out);
qse_sio_close (in);
return 0;
}
int main ()
{
setlocale (LC_ALL, "");
qse_sio_puts (qse_sio_out, QSE_T("--------------------------------------------------------------------------------\n"));
qse_sio_puts (qse_sio_out, QSE_T("Set the environment LANG to a Unicode locale such as UTF-8 if you see the illegal XXXXX errors. If you see such errors in Unicode locales, this program might be buggy. It is normal to see such messages in non-Unicode locales as it uses Unicode data\n"));
qse_sio_puts (qse_sio_out, QSE_T("--------------------------------------------------------------------------------\n"));
qse_sio_putstr (qse_sio_out, QSE_T("--------------------------------------------------------------------------------\n"));
qse_sio_putstr (qse_sio_out, QSE_T("Set the environment LANG to a Unicode locale such as UTF-8 if you see the illegal XXXXX errors. If you see such errors in Unicode locales, this program might be buggy. It is normal to see such messages in non-Unicode locales as it uses Unicode data\n"));
qse_sio_putstr (qse_sio_out, QSE_T("--------------------------------------------------------------------------------\n"));
R (test1);
R (test2);
R (test3);
return 0;
}

View File

@ -60,14 +60,71 @@ static int test1 (void)
for (i = 0; i < QSE_COUNTOF(x); i++)
{
qse_sio_putws (sio, x[i]);
qse_sio_putws (sio, QSE_WT("\n"));
qse_sio_putwcs (sio, x[i]);
qse_sio_putwc (sio, QSE_WT('\n'));
}
qse_sio_close (sio);
return 0;
}
static int test2 (void)
{
const qse_mchar_t* x[] =
{
QSE_MT("\0\0\0"),
QSE_MT("이거슨"),
QSE_MT("뭐냐이거"),
QSE_MT("過去一個月"),
QSE_MT("是成功的建商"),
QSE_MT("뛰어 올라봐. 멀리멀리 잘난척하기는"),
QSE_MT("Fly to the universe")
};
int i;
qse_sio_t* sio;
sio = qse_sio_openstd (QSE_NULL, 0, QSE_SIO_STDOUT, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR | QSE_SIO_NOAUTOFLUSH);
if (sio == QSE_NULL) return -1;
for (i = 0; i < QSE_COUNTOF(x); i++)
{
qse_sio_putmbs (sio, x[i]);
qse_sio_putmb (sio, QSE_MT('\n'));
}
qse_sio_close (sio);
return 0;
}
static int test3 (void)
{
const qse_mchar_t* x[] =
{
QSE_MT("\0\0\0"),
QSE_MT("이거슨"),
QSE_MT("뭐냐이거"),
QSE_MT("過去一個月"),
QSE_MT("是成功的建商"),
QSE_MT("뛰어 올라봐. 멀리멀리 잘난척하기는"),
QSE_MT("Fly to the universe")
};
int i;
qse_sio_t* sio;
sio = qse_sio_openstd (QSE_NULL, 0, QSE_SIO_STDOUT, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR | QSE_SIO_NOAUTOFLUSH);
if (sio == QSE_NULL) return -1;
for (i = 0; i < QSE_COUNTOF(x); i++)
{
qse_sio_putmbsn (sio, x[i], qse_mbslen(x[i]));
qse_sio_putmb (sio, QSE_MT('\n'));
}
qse_sio_close (sio);
return 0;
}
int main ()
{
#if defined(_WIN32)
@ -89,6 +146,8 @@ int main ()
qse_printf (QSE_T("--------------------------------------------------------------------------------\n"));
R (test1);
R (test2);
R (test3);
#if defined(_WIN32)
SetConsoleOutputCP (old_cp);

View File

@ -54,9 +54,9 @@ static int test1 (void)
(int)wlen, (int)mlen, (int)wlen1, (int)mlen1, buf2);
qse_fflush (QSE_STDOUT);
qse_sio_putws (QSE_SIO_OUT, QSE_T("<<"));
qse_sio_putws (QSE_SIO_OUT, buf2);
qse_sio_putws (QSE_SIO_OUT, QSE_T(">>\n"));
qse_sio_putwcs (QSE_SIO_OUT, QSE_T("<<"));
qse_sio_putwcs (QSE_SIO_OUT, buf2);
qse_sio_putwcs (QSE_SIO_OUT, QSE_T(">>\n"));
qse_sio_flush (QSE_SIO_OUT);
}
@ -76,9 +76,9 @@ static int test1 (void)
(int)wlen, (int)mlen, (int)wlen, (int)wlen1, (int)mlen1, buf2);
qse_fflush (QSE_STDOUT);
qse_sio_putws (QSE_SIO_OUT, QSE_T("<<"));
qse_sio_putws (QSE_SIO_OUT, buf2);
qse_sio_putws (QSE_SIO_OUT, QSE_T(">>\n"));
qse_sio_putwcs (QSE_SIO_OUT, QSE_T("<<"));
qse_sio_putwcs (QSE_SIO_OUT, buf2);
qse_sio_putwcs (QSE_SIO_OUT, QSE_T(">>\n"));
qse_sio_flush (QSE_SIO_OUT);
}