added qse_cmgr_t. still in primitive stage.

added qse_tio_getcmgr()/qse_tio_setcmgr()
added qse_pio_getcmgr()/qse_pio_setcmgr()
added qse_fio_getcmgr()/qse_fio_setcmgr()
added qse_fio_getcmgr()/qse_fio_setcmgr()
added mbs/wcs conversion functions using cmgr
This commit is contained in:
hyung-hwan 2011-12-30 14:44:21 +00:00
parent bd7fd49a72
commit a0fc992c65
21 changed files with 626 additions and 54 deletions

View File

@ -854,7 +854,7 @@ static int awk_main (int argc, qse_char_t* argv[])
/* TODO: change it to support multiple source files */
qse_awk_parsestd_in_t psin;
qse_awk_parsestd_out_t psout;
qse_mmgr_t* mmgr = QSE_NULL;
qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
memset (&arg, 0, QSE_SIZEOF(arg));

View File

@ -519,7 +519,7 @@ static void trace_exec (qse_sed_t* sed, qse_sed_exec_op_t op, const qse_sed_cmd_
int sed_main (int argc, qse_char_t* argv[])
{
qse_mmgr_t* mmgr = QSE_NULL;
qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
qse_sed_t* sed = QSE_NULL;
qse_fs_t* fs = QSE_NULL;
qse_size_t script_count;

View File

@ -200,6 +200,22 @@ void qse_fio_fini (
qse_fio_t* fio
);
/**
* The qse_fio_getcmgr() funcfion returns the current character manager.
* It returns #QSE_NULL is @a fio is not opened with #QSE_FIO_TEXT.
*/
qse_cmgr_t* qse_fio_getcmgr (
qse_fio_t* fio
);
/**
* The qse_fio_setcmgr() funcfion changes the character manager to @a cmgr.
* The character manager is used only if @a fio is opened with #QSE_FIO_TEXT.
*/
void qse_fio_setcmgr (
qse_fio_t* fio,
qse_cmgr_t* cmgr
);
/**
* The qse_fio_gethandle() function returns the native file handle.

View File

@ -77,7 +77,6 @@ enum qse_pio_flag_t
QSE_PIO_DROPERR = (1 << 18)
};
/**
* The qse_pio_hid_t type defines pipe IDs established to a child process.
*/
@ -138,7 +137,7 @@ typedef enum qse_pio_errnum_t qse_pio_errnum_t;
/* <os2def.h> => typedef LHANDLE HFILE;
typedef LHANDLE PID;
typedef unsigned long LHANDLE; */
typedef unsigned long qse_pio_hnd_t; /**< defines a pipe handle type */
typedef unsigned long qse_pio_hnd_t; /**< defines a pipe handle type */
typedef unsigned long qse_pio_pid_t; /**< defined a process handle type */
# define QSE_PIO_HND_NIL ((qse_pio_hnd_t)-1)
# define QSE_PIO_PID_NIL ((qse_pio_pid_t)-1)
@ -280,6 +279,25 @@ const qse_char_t* qse_pio_geterrmsg (
qse_pio_t* pio /**< pio object */
);
/**
* The qse_pio_getcmgr() function returns the current character manager.
* It returns #QSE_NULL is @a pio is not opened with #QSE_PIO_TEXT.
*/
qse_cmgr_t* qse_pio_getcmgr (
qse_pio_t* pio,
qse_pio_hid_t hid
);
/**
* The qse_pio_setcmgr() function changes the character manager to @a cmgr.
* The character manager is used only if @a pio is opened with #QSE_PIO_TEXT.
*/
void qse_pio_setcmgr (
qse_pio_t* pio,
qse_pio_hid_t hid,
qse_cmgr_t* cmgr
);
/**
* The qse_pio_gethandle() function gets a pipe handle.
* @return pipe handle
@ -303,9 +321,9 @@ qse_pio_pid_t qse_pio_getchild (
*/
qse_ssize_t qse_pio_read (
qse_pio_t* pio, /**< pio object */
qse_pio_hid_t hid, /**< handle ID */
void* buf, /**< buffer to fill */
qse_size_t size, /**< buffer size */
qse_pio_hid_t hid /**< handle ID */
qse_size_t size /**< buffer size */
);
/**
@ -316,9 +334,9 @@ qse_ssize_t qse_pio_read (
*/
qse_ssize_t qse_pio_write (
qse_pio_t* pio, /**< pio object */
qse_pio_hid_t hid, /**< handle ID */
const void* data, /**< data to write */
qse_size_t size, /**< data size */
qse_pio_hid_t hid /**< handle ID */
qse_size_t size /**< data size */
);
/**

View File

@ -144,6 +144,15 @@ qse_sio_errnum_t qse_sio_geterrnum (
qse_sio_t* sio
);
qse_cmgr_t* qse_sio_getcmgr (
qse_sio_t* sio
);
void qse_sio_setcmgr (
qse_sio_t* sio,
qse_cmgr_t* cmgr
);
qse_sio_hnd_t qse_sio_gethandle (
qse_sio_t* sio
);

View File

@ -110,16 +110,17 @@ struct qse_tio_t
{
QSE_DEFINE_COMMON_FIELDS (tio)
qse_tio_errnum_t errnum;
int flags;
int flags;
qse_cmgr_t* cmgr;
qse_tio_io_t in;
qse_tio_io_t out;
qse_tio_io_t in;
qse_tio_io_t out;
/* for house keeping from here */
int input_status;
qse_size_t inbuf_cur;
qse_size_t inbuf_len;
qse_size_t outbuf_len;
int input_status;
qse_size_t inbuf_cur;
qse_size_t inbuf_len;
qse_size_t outbuf_len;
};
#ifdef __cplusplus
@ -176,6 +177,21 @@ const qse_char_t* qse_tio_geterrmsg (
qse_tio_t* tio
);
/**
* The qse_tio_getcmgr() function returns the character manager.
*/
qse_cmgr_t* qse_tio_getcmgr (
qse_tio_t* tio
);
/**
* The qse_tio_setcmgr() function changes the character manager.
*/
void qse_tio_setcmgr (
qse_tio_t* tio,
qse_cmgr_t* cmgr
);
/**
* The qse_tio_attachin() function attachs an input handler .
* @return 0 on success, -1 on failure

View File

@ -716,6 +716,30 @@ struct qse_mmgr_t
};
typedef struct qse_mmgr_t qse_mmgr_t;
typedef qse_size_t (*qse_cmgr_mbtowc_t) (
const qse_mchar_t* mb,
qse_size_t size,
qse_wchar_t* wc
);
typedef qse_size_t (*qse_cmgr_wctomb_t) (
qse_wchar_t wc,
qse_mchar_t* mb,
qse_size_t size
);
/**
* The qse_cmgr_t type defines the interface to various character handling.
*/
struct qse_cmgr_t
{
qse_cmgr_mbtowc_t mbtowc;
qse_cmgr_wctomb_t wctomb;
};
typedef struct qse_cmgr_t qse_cmgr_t;
/**
* The #qse_foff_t type defines an integer that can represent a file offset.
* Depending on your system, it's defined to one of #qse_int64_t, #qse_int32_t,

View File

@ -224,12 +224,12 @@ int StdAwk::closePipe (Pipe& io)
StdAwk::ssize_t StdAwk::readPipe (Pipe& io, char_t* buf, size_t len)
{
return qse_pio_read ((qse_pio_t*)io.getHandle(), buf, len, QSE_PIO_OUT);
return qse_pio_read ((qse_pio_t*)io.getHandle(), QSE_PIO_OUT, buf, len);
}
StdAwk::ssize_t StdAwk::writePipe (Pipe& io, const char_t* buf, size_t len)
{
return qse_pio_write ((qse_pio_t*)io.getHandle(), buf, len, QSE_PIO_IN);
return qse_pio_write ((qse_pio_t*)io.getHandle(), QSE_PIO_IN, buf, len);
}
int StdAwk::flushPipe (Pipe& io)

View File

@ -863,9 +863,7 @@ static qse_ssize_t awk_rio_pipe (
{
return qse_pio_read (
(qse_pio_t*)riod->handle,
data,
size,
QSE_PIO_OUT
QSE_PIO_OUT, data, size
);
}
@ -873,9 +871,7 @@ static qse_ssize_t awk_rio_pipe (
{
return qse_pio_write (
(qse_pio_t*)riod->handle,
data,
size,
QSE_PIO_IN
QSE_PIO_IN, data, size
);
}

View File

@ -66,6 +66,7 @@ libqsecmn_la_SOURCES = \
str-fnmat.c \
str-incl.c \
str-len.c \
str-mbwc.c \
str-pac.c \
str-pbrk.c \
str-put.c \

View File

@ -82,12 +82,13 @@ am_libqsecmn_la_OBJECTS = alg-rand.lo alg-search.lo alg-sort.lo \
rbt.lo rex.lo sio.lo sll.lo stdio.lo str-beg.lo str-cat.lo \
str-chr.lo str-cnv.lo str-cmp.lo str-cpy.lo str-del.lo \
str-dup.lo str-dynm.lo str-dynw.lo str-end.lo str-excl.lo \
str-fcpy.lo str-fnmat.lo str-incl.lo str-len.lo str-pac.lo \
str-pbrk.lo str-put.lo str-rev.lo str-rot.lo str-set.lo \
str-spl.lo str-spn.lo str-str.lo str-subst.lo str-tok.lo \
str-trm.lo str-word.lo time.lo tio.lo tio-get.lo tio-put.lo \
tre.lo tre-ast.lo tre-compile.lo tre-match-backtrack.lo \
tre-match-parallel.lo tre-parse.lo tre-stack.lo utf8.lo xma.lo
str-fcpy.lo str-fnmat.lo str-incl.lo str-len.lo str-mbwc.lo \
str-pac.lo str-pbrk.lo str-put.lo str-rev.lo str-rot.lo \
str-set.lo str-spl.lo str-spn.lo str-str.lo str-subst.lo \
str-tok.lo str-trm.lo str-word.lo time.lo tio.lo tio-get.lo \
tio-put.lo tre.lo tre-ast.lo tre-compile.lo \
tre-match-backtrack.lo tre-match-parallel.lo tre-parse.lo \
tre-stack.lo utf8.lo xma.lo
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@ -335,6 +336,7 @@ libqsecmn_la_SOURCES = \
str-fnmat.c \
str-incl.c \
str-len.c \
str-mbwc.c \
str-pac.c \
str-pbrk.c \
str-put.c \
@ -492,6 +494,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-fnmat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-incl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-len.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-mbwc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-pac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-pbrk.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-put.Plo@am__quote@

View File

@ -551,6 +551,16 @@ void qse_fio_fini (qse_fio_t* fio)
}
}
qse_cmgr_t* qse_fio_getcmgr (qse_fio_t* fio)
{
return fio->tio? qse_tio_getcmgr (fio->tio): QSE_NULL;
}
void qse_fio_setcmgr (qse_fio_t* fio, qse_cmgr_t* cmgr)
{
if (fio->tio) qse_tio_setcmgr (fio->tio, cmgr);
}
qse_fio_hnd_t qse_fio_gethandle (qse_fio_t* fio)
{
return fio->handle;

View File

@ -967,6 +967,7 @@ int qse_pio_init (
if (flags & QSE_PIO_IGNOREMBWCERR) topt |= QSE_TIO_IGNOREMBWCERR;
if (flags & QSE_PIO_NOAUTOFLUSH) topt |= QSE_TIO_NOAUTOFLUSH;
QSE_ASSERT (QSE_COUNTOF(tio) == QSE_COUNTOF(pio->pin));
for (i = 0; i < QSE_COUNTOF(tio); i++)
{
int r;
@ -979,8 +980,10 @@ int qse_pio_init (
}
r = (i == QSE_PIO_IN)?
qse_tio_attachout (tio[i], pio_output, &pio->pin[i], QSE_NULL, 4096):
qse_tio_attachin (tio[i], pio_input, &pio->pin[i], QSE_NULL, 4096);
qse_tio_attachout (
tio[i], pio_output, &pio->pin[i], QSE_NULL, 4096):
qse_tio_attachin (
tio[i], pio_input, &pio->pin[i], QSE_NULL, 4096);
if (r <= -1) goto oops;
@ -1090,6 +1093,17 @@ const qse_char_t* qse_pio_geterrmsg (qse_pio_t* pio)
QSE_COUNTOF(__errstr) - 1: pio->errnum];
}
qse_cmgr_t* qse_pio_getcmgr (qse_pio_t* pio, qse_pio_hid_t hid)
{
return pio->pin[hid].tio?
qse_tio_getcmgr(pio->pin[hid].tio): QSE_NULL;
}
void qse_pio_setcmgr (qse_pio_t* pio, qse_pio_hid_t hid, qse_cmgr_t* cmgr)
{
if (pio->pin[hid].tio) qse_tio_setcmgr (pio->pin[hid].tio, cmgr);
}
qse_pio_hnd_t qse_pio_gethandle (qse_pio_t* pio, qse_pio_hid_t hid)
{
return pio->pin[hid].handle;
@ -1190,7 +1204,7 @@ reread:
}
qse_ssize_t qse_pio_read (
qse_pio_t* pio, void* buf, qse_size_t size, qse_pio_hid_t hid)
qse_pio_t* pio, qse_pio_hid_t hid, void* buf, qse_size_t size)
{
if (pio->pin[hid].tio == QSE_NULL)
return pio_read (pio, buf, size, pio->pin[hid].handle);
@ -1285,8 +1299,8 @@ rewrite:
}
qse_ssize_t qse_pio_write (
qse_pio_t* pio, const void* data, qse_size_t size,
qse_pio_hid_t hid)
qse_pio_t* pio, qse_pio_hid_t hid,
const void* data, qse_size_t size)
{
if (pio->pin[hid].tio == QSE_NULL)
return pio_write (pio, data, size, pio->pin[hid].handle);
@ -1547,7 +1561,8 @@ int qse_pio_kill (qse_pio_t* pio)
#endif
}
static qse_ssize_t pio_input (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size)
static qse_ssize_t pio_input (
qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size)
{
qse_pio_pin_t* pin = (qse_pio_pin_t*)arg;
QSE_ASSERT (pin != QSE_NULL);
@ -1562,7 +1577,8 @@ static qse_ssize_t pio_input (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_
return 0;
}
static qse_ssize_t pio_output (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size)
static qse_ssize_t pio_output (
qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size)
{
qse_pio_pin_t* pin = (qse_pio_pin_t*)arg;
QSE_ASSERT (pin != QSE_NULL);

View File

@ -140,6 +140,16 @@ void qse_sio_fini (qse_sio_t* sio)
qse_fio_fini (&sio->fio);
}
qse_cmgr_t* qse_sio_getcmgr (qse_sio_t* sio)
{
return qse_tio_getcmgr (&sio->tio);
}
void qse_sio_setcmgr (qse_sio_t* sio, qse_cmgr_t* cmgr)
{
qse_tio_setcmgr (&sio->tio, cmgr);
}
qse_sio_errnum_t qse_sio_geterrnum (qse_sio_t* sio)
{
return QSE_TIO_ERRNUM(&sio->tio);

View File

@ -134,12 +134,10 @@ qse_ulong_t qse_strxtoulong (const qse_char_t* str, qse_size_t len)
return v;
}
/*
* TODO: fix wrong mbstate handling
*/
int qse_mbstowcs (
const qse_mchar_t* mbs, qse_size_t* mbslen,
qse_wchar_t* wcs, qse_size_t* wcslen)

437
qse/lib/cmn/str-mbwc.c Normal file
View File

@ -0,0 +1,437 @@
/*
* $Id: str-cnv.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
#include <qse/cmn/str.h>
#include "mem.h"
int qse_mbstowcswithcmgr (
const qse_mchar_t* mbs, qse_size_t* mbslen,
qse_wchar_t* wcs, qse_size_t* wcslen, qse_cmgr_t* cmgr)
{
const qse_mchar_t* mp;
qse_size_t mlen, wlen;
int n;
for (mp = mbs; *mp != QSE_MT('\0'); mp++);
mlen = mp - mbs; wlen = *wcslen;
n = qse_mbsntowcsnwithcmgr (mbs, &mlen, wcs, &wlen, cmgr);
if (wcs)
{
if (wlen < *wcslen) wcs[wlen] = QSE_WT('\0');
else n = -2; /* buffer too small */
}
*mbslen = mlen; *wcslen = wlen;
return n;
}
int qse_mbsntowcsnwithcmgr (
const qse_mchar_t* mbs, qse_size_t* mbslen,
qse_wchar_t* wcs, qse_size_t* wcslen, qse_cmgr_t* cmgr)
{
const qse_mchar_t* p;
int ret = 0;
qse_size_t mlen;
if (wcs)
{
qse_wchar_t* q, * qend;
p = mbs;
q = wcs;
qend = wcs + *wcslen;
mlen = *mbslen;
while (mlen > 0)
{
qse_size_t n;
if (q >= qend)
{
/* buffer too small */
ret = -2;
break;
}
n = cmgr->mbtowc (p, mlen, q);
if (n == 0)
{
/* invalid sequence */
ret = -1;
break;
}
if (n > mlen)
{
/* incomplete sequence */
ret = -3;
break;
}
q++;
p += n;
mlen -= n;
}
*wcslen = q - wcs;
*mbslen = p - mbs;
}
else
{
qse_wchar_t w;
qse_size_t wlen = 0;
p = mbs;
mlen = *mbslen;
while (mlen > 0)
{
qse_size_t n;
n = cmgr->mbtowc (p, mlen, &w);
if (n == 0)
{
/* invalid sequence */
ret = -1;
break;
}
if (n > mlen)
{
/* incomplete sequence */
ret = -3;
break;
}
p += n;
mlen -= n;
wlen += 1;
}
*wcslen = wlen;
*mbslen = p - mbs;
}
return ret;
}
int qse_mbsntowcsnuptowithcmgr (
const qse_mchar_t* mbs, qse_size_t* mbslen,
qse_wchar_t* wcs, qse_size_t* wcslen, qse_wchar_t stopper, qse_cmgr_t* cmgr)
{
const qse_mchar_t* p;
int ret = 0;
qse_size_t mlen;
qse_wchar_t w;
qse_size_t wlen = 0;
qse_wchar_t* wend;
p = mbs;
mlen = *mbslen;
if (wcs) wend = wcs + *wcslen;
/* since it needs to break when a stopper is met,
* i can't perform bulky conversion using the buffer
* provided. so conversion is conducted character by
* character */
while (mlen > 0)
{
qse_size_t n;
n = cmgr->mbtowc (p, mlen, &w);
if (n == 0)
{
/* invalid sequence */
ret = -1;
break;
}
if (n > mlen)
{
/* incomplete sequence */
ret = -3;
break;
}
if (wcs)
{
if (wcs >= wend) break;
*wcs++ = w;
}
p += n;
mlen -= n;
wlen += 1;
if (w == stopper) break;
}
*wcslen = wlen;
*mbslen = p - mbs;
return ret;
}
qse_wchar_t* qse_mbstowcsdupwithcmgr (
const qse_mchar_t* mbs, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
{
qse_size_t mbslen, wcslen;
qse_wchar_t* wcs;
if (qse_mbstowcswithcmgr (mbs, &mbslen, QSE_NULL, &wcslen, cmgr) <= -1) return QSE_NULL;
wcslen++; /* for terminating null */
wcs = QSE_MMGR_ALLOC (mmgr, wcslen * QSE_SIZEOF(*wcs));
if (wcs == QSE_NULL) return QSE_NULL;
qse_mbstowcswithcmgr (mbs, &mbslen, wcs, &wcslen, cmgr);
return wcs;
}
qse_wchar_t* qse_mbsatowcsdupwithcmgr (
const qse_mchar_t* mbs[], qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
{
qse_wchar_t* buf, * ptr;
qse_size_t i;
qse_size_t capa = 0;
qse_size_t wl, ml;
QSE_ASSERT (mmgr != QSE_NULL);
for (i = 0; mbs[i]; i++)
{
if (qse_mbstowcswithcmgr (mbs[i], &ml, QSE_NULL, &wl, cmgr) <= -1) return QSE_NULL;
capa += wl;
}
buf = (qse_wchar_t*) QSE_MMGR_ALLOC (
mmgr, (capa + 1) * QSE_SIZEOF(*buf));
if (buf == QSE_NULL) return QSE_NULL;
ptr = buf;
for (i = 0; mbs[i]; i++)
{
wl = capa + 1;
qse_mbstowcswithcmgr (mbs[i], &ml, ptr, &wl, cmgr);
ptr += wl;
capa -= wl;
}
return buf;
}
int qse_wcstombswithcmgr (
const qse_wchar_t* wcs, qse_size_t* wcslen,
qse_mchar_t* mbs, qse_size_t* mbslen, qse_cmgr_t* cmgr)
{
const qse_wchar_t* p = wcs;
int ret = 0;
if (mbs)
{
qse_size_t rem = *mbslen;
while (*p != QSE_WT('\0'))
{
qse_size_t n;
if (rem <= 0)
{
ret = -2;
break;
}
n = cmgr->wctomb (*p, mbs, rem);
if (n == 0)
{
ret = -1;
break; /* illegal character */
}
if (n > rem)
{
ret = -2;
break; /* buffer too small */
}
mbs += n; rem -= n; p++;
}
/* update mbslen to the length of the mbs string converted excluding
* terminating null */
*mbslen -= rem;
/* null-terminate the multibyte sequence if it has sufficient space */
if (rem > 0) *mbs = QSE_MT('\0');
else
{
/* if ret is -2 and wcs[wcslen] == QSE_WT('\0'),
* this means that the mbs buffer was lacking one
* slot for the terminating null */
ret = -2; /* buffer too small */
}
}
else
{
qse_mchar_t mbsbuf[QSE_MBLEN_MAX];
qse_size_t mlen = 0;
while (*p != QSE_WT('\0'))
{
qse_size_t n;
n = cmgr->wctomb (*p, mbsbuf, QSE_COUNTOF(mbsbuf));
if (n == 0)
{
ret = -1;
break; /* illegal character */
}
/* it assumes that mbs is large enough to hold a character */
QSE_ASSERT (n <= QSE_COUNTOF(mbs));
p++; mlen += n;
}
/* this length holds the number of resulting multi-byte characters
* excluding the terminating null character */
*mbslen = mlen;
}
*wcslen = p - wcs; /* the number of wide characters handled. */
return ret;
}
int qse_wcsntombsnwithcmgr (
const qse_wchar_t* wcs, qse_size_t* wcslen,
qse_mchar_t* mbs, qse_size_t* mbslen, qse_cmgr_t* cmgr)
{
const qse_wchar_t* p = wcs;
const qse_wchar_t* end = wcs + *wcslen;
int ret = 0;
if (mbs)
{
qse_size_t rem = *mbslen;
while (p < end)
{
qse_size_t n;
if (rem <= 0)
{
ret = -2; /* buffer too small */
break;
}
n = cmgr->wctomb (*p, mbs, rem);
if (n == 0)
{
ret = -1;
break; /* illegal character */
}
if (n > rem)
{
ret = -2; /* buffer too small */
break;
}
mbs += n; rem -= n; p++;
}
*mbslen -= rem;
}
else
{
qse_mchar_t mbsbuf[QSE_MBLEN_MAX];
qse_size_t mlen = 0;
while (p < end)
{
qse_size_t n;
n = cmgr->wctomb (*p, mbsbuf, QSE_COUNTOF(mbsbuf));
if (n == 0)
{
ret = -1;
break; /* illegal character */
}
/* it assumes that mbs is large enough to hold a character */
QSE_ASSERT (n <= QSE_COUNTOF(mbsbuf));
p++; mlen += n;
}
/* this length excludes the terminating null character.
* this function doesn't event null-terminate the result. */
*mbslen = mlen;
}
*wcslen = p - wcs;
return ret;
}
qse_mchar_t* qse_wcstombsdupwithcmgr (const qse_wchar_t* wcs, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
{
qse_size_t wcslen, mbslen;
qse_mchar_t* mbs;
if (qse_wcstombswithcmgr (wcs, &wcslen, QSE_NULL, &mbslen, cmgr) <= -1) return QSE_NULL;
mbslen++; /* for the terminating null character */
mbs = QSE_MMGR_ALLOC (mmgr, mbslen * QSE_SIZEOF(*mbs));
if (mbs == QSE_NULL) return QSE_NULL;
qse_wcstombswithcmgr (wcs, &wcslen, mbs, &mbslen, cmgr);
return mbs;
}
qse_mchar_t* qse_wcsatombsdupwithcmgr (const qse_wchar_t* wcs[], qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
{
qse_mchar_t* buf, * ptr;
qse_size_t i;
qse_size_t wl, ml;
qse_size_t capa = 0;
QSE_ASSERT (mmgr != QSE_NULL);
for (i = 0; wcs[i]; i++)
{
if (qse_wcstombswithcmgr (wcs[i], &wl, QSE_NULL, &ml, cmgr) <= -1) return QSE_NULL;
capa += ml;
}
buf = (qse_mchar_t*) QSE_MMGR_ALLOC (
mmgr, (capa + 1) * QSE_SIZEOF(*buf));
if (buf == QSE_NULL) return QSE_NULL;
ptr = buf;
for (i = 0; wcs[i]; i++)
{
ml = capa + 1;
qse_wcstombswithcmgr (wcs[i], &wl, ptr, &ml, cmgr);
ptr += ml;
capa -= ml;
}
return buf;
}

View File

@ -132,9 +132,9 @@ static QSE_INLINE qse_ssize_t tio_read_widechars (
mlen = tio->inbuf_len - tio->inbuf_cur;
wlen = bufsize;
x = qse_mbsntowcsnupto (
x = qse_mbsntowcsnuptowithcmgr (
&tio->in.buf.ptr[tio->inbuf_cur],
&mlen, buf, &wlen, QSE_WT('\n'));
&mlen, buf, &wlen, QSE_WT('\n'), tio->cmgr);
tio->inbuf_cur += mlen;
if (x == -3)

View File

@ -142,8 +142,8 @@ qse_ssize_t qse_tio_writewcs (
capa = tio->out.buf.capa - tio->outbuf_len;
wcnt = xwlen; mcnt = capa;
n = qse_wcsntombsn (
wptr, &wcnt, &tio->out.buf.ptr[tio->outbuf_len], &mcnt);
n = qse_wcsntombsnwithcmgr (
wptr, &wcnt, &tio->out.buf.ptr[tio->outbuf_len], &mcnt, tio->cmgr);
tio->outbuf_len += mcnt;
if (n == -2)

View File

@ -19,6 +19,7 @@
*/
#include <qse/cmn/tio.h>
#include <qse/cmn/utf8.h>
#include "mem.h"
QSE_IMPLEMENT_COMMON_FUNCTIONS (tio)
@ -51,9 +52,19 @@ int qse_tio_close (qse_tio_t* tio)
int qse_tio_init (qse_tio_t* tio, qse_mmgr_t* mmgr, int flags)
{
/* TODO: set this default_cmgr differently depending on
* build options and platforms */
static qse_cmgr_t default_cmgr =
{
qse_utf8touc,
qse_uctoutf8
};
QSE_MEMSET (tio, 0, QSE_SIZEOF(*tio));
tio->mmgr = mmgr;
tio->cmgr = &default_cmgr;
/* mask off internal bits when storing the flags for safety */
tio->flags = flags & ~(QSE_TIO_DYNINBUF | QSE_TIO_DYNOUTBUF);
@ -111,6 +122,16 @@ const qse_char_t* qse_tio_geterrmsg (qse_tio_t* tio)
QSE_COUNTOF(__errmsg) - 1: tio->errnum];
}
qse_cmgr_t* qse_tio_getcmgr (qse_tio_t* tio)
{
return tio->cmgr;
}
void qse_tio_setcmgr (qse_tio_t* tio, qse_cmgr_t* cmgr)
{
tio->cmgr = cmgr;
}
int qse_tio_attachin (
qse_tio_t* tio, qse_tio_io_fun_t input, void* arg,
qse_mchar_t* bufptr, qse_size_t bufcapa)

View File

@ -955,10 +955,9 @@ qse_printf (QSE_T("READING CHUNKED MODE...\n"));
/* <- can i make it non-block?? or use select??? pio_tryread()? */
n = qse_pio_read (
cgi->pio,
cgi->pio, QSE_PIO_OUT,
&cgi->buf[cgi->buflen + QSE_SIZEOF(chunklen) - 1],
count - extra,
QSE_PIO_OUT
count - extra
);
if (n <= -1)
{
@ -994,10 +993,9 @@ qse_printf (QSE_T("READING CHUNKED MODE...\n"));
{
qse_printf (QSE_T("READING IN NON-CHUNKED MODE...\n"));
n = qse_pio_read (
cgi->pio,
cgi->pio, QSE_PIO_OUT,
&cgi->buf[cgi->buflen],
QSE_SIZEOF(cgi->buf) - cgi->buflen,
QSE_PIO_OUT
QSE_SIZEOF(cgi->buf) - cgi->buflen
);
if (n <= -1)
{
@ -1088,10 +1086,9 @@ static int task_main_cgi_2 (
qse_printf (QSE_T("[cgi_2 ]\n"));
/* <- can i make it non-block?? or use select??? pio_tryread()? */
n = qse_pio_read (
cgi->pio,
cgi->pio, QSE_PIO_OUT,
&cgi->buf[cgi->buflen],
QSE_SIZEOF(cgi->buf) - cgi->buflen,
QSE_PIO_OUT
QSE_SIZEOF(cgi->buf) - cgi->buflen
);
if (n <= -1)
{

View File

@ -47,7 +47,7 @@ static int pio1 (const qse_char_t* cmd, qse_env_t* env, int oflags, qse_pio_hid_
qse_ssize_t i;
/*qse_pio_canread (pio, QSE_PIO_ERR, 1000)*/
qse_ssize_t n = qse_pio_read (pio, buf, QSE_SIZEOF(buf), rhid);
qse_ssize_t n = qse_pio_read (pio, rhid, buf, QSE_SIZEOF(buf));
if (n == 0) break;
if (n <= -1)
{
@ -106,7 +106,7 @@ static int pio2 (const qse_char_t* cmd, qse_env_t* env, int oflags, qse_pio_hid_
qse_char_t buf[128];
qse_ssize_t i;
qse_ssize_t n = qse_pio_read (pio, buf, QSE_COUNTOF(buf), rhid);
qse_ssize_t n = qse_pio_read (pio, rhid, buf, QSE_COUNTOF(buf));
if (n == 0) break;
if (n < 0)
{
@ -352,7 +352,7 @@ static int test12 (void)
while (1)
{
qse_mchar_t buf[100];
qse_ssize_t x = qse_pio_read (pio, buf, QSE_SIZEOF(buf), QSE_PIO_OUT);
qse_ssize_t x = qse_pio_read (pio, QSE_PIO_OUT, buf, QSE_SIZEOF(buf));
if (x <= 0) break;
}