added qse_mbsntowcsnupto()

changed qse_tio_readwcs() to utilize qse_mbsntowcsnupto()
This commit is contained in:
2011-12-21 16:21:46 +00:00
parent 38d3c22d1f
commit 14acf9a920
24 changed files with 1311 additions and 806 deletions

View File

@ -40,10 +40,6 @@
# include "syscall.h"
# include <sys/types.h>
# include <fcntl.h>
# include <limits.h>
# ifndef PATH_MAX
# define PATH_MAX 2048
# endif
#endif
QSE_IMPLEMENT_COMMON_FUNCTIONS (fio)
@ -250,13 +246,23 @@ int qse_fio_init (
ULONG open_action, open_mode, open_attr;
LONGLONG zero;
#ifdef QSE_CHAR_IS_MCHAR
#if defined(QSE_CHAR_IS_MCHAR)
const qse_mchar_t* path_mb = path;
#else
qse_mchar_t path_mb[CCHMAXPATH];
qse_size_t wl, ml = QSE_COUNTOF(path_mb);
/* TODO: use wcstombsdup??? */
if (qse_wcstombs (path, &wl, path_mb, &ml) <= -1) return -1;
qse_mchar_t path_mb_buf[CCHMAXPATH];
qse_mchar_t* path_mb;
qse_size_t wl, ml;
int px;
path_mb = path_mb_buf;
ml = QSE_COUNTOF(path_mb_buf);
px = qse_wcstombs (path, &wl, path_mb, &ml);
if (px == -2)
{
path_mb = qse_wcstombsdup (path, mmgr);
if (path_mb == QSE_NULL) return -1;
}
else if (px <= -1) return -1;
#endif
zero.ulLo = 0;
@ -323,6 +329,12 @@ int qse_fio_init (
0L
);
#if defined(QSE_CHAR_IS_MCHAR)
/* nothing to do */
#else
if (path_mb != path_mb_buf) QSE_MMGR_FREE (mmgr, path_mb);
#endif
if (ret != NO_ERROR)
{
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
@ -341,12 +353,23 @@ int qse_fio_init (
int oflags = 0;
int permission = 0;
#ifdef QSE_CHAR_IS_MCHAR
#if defined(QSE_CHAR_IS_MCHAR)
const qse_mchar_t* path_mb = path;
#else
qse_mchar_t path_mb[_MAX_PATH];
qse_size_t wl, ml = QSE_COUNTOF(path_mb);
if (qse_wcstombs (path, &wl, path_mb, &ml) <= -1) return -1;
qse_mchar_t path_mb_buf[_MAX_PATH];
qse_mchar_t* path_mb;
qse_size_t wl, ml;
int px;
path_mb = path_mb_buf;
ml = QSE_COUNTOF(path_mb_buf);
px = qse_wcstombs (path, &wl, path_mb, &ml);
if (px == -2)
{
path_mb = qse_wcstombsdup (path, mmgr);
if (path_mb == QSE_NULL) return -1;
}
else if (px <= -1) return -1;
#endif
if (flags & QSE_FIO_APPEND)
@ -377,6 +400,13 @@ int qse_fio_init (
oflags,
permission
);
#if defined(QSE_CHAR_IS_MCHAR)
/* nothing to do */
#else
if (path_mb != path_mb_buf) QSE_MMGR_FREE (mmgr, path_mb);
#endif
if (handle <= -1)
{
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
@ -394,13 +424,23 @@ int qse_fio_init (
{
int desired_access = 0;
#ifdef QSE_CHAR_IS_MCHAR
#if defined(QSE_CHAR_IS_MCHAR)
const qse_mchar_t* path_mb = path;
#else
qse_mchar_t path_mb[PATH_MAX + 1];
/* TODO: use qse_wcstombsdup(). path name may exceede PATH_MAX if it contains .. or . */
qse_size_t wl, ml = QSE_COUNTOF(path_mb);
if (qse_wcstombs (path, &wl, path_mb, &ml) <= -1) return -1;
qse_mchar_t path_mb_buf[1024]; /* PATH_MAX instead? */
qse_mchar_t* path_mb;
qse_size_t wl, ml;
int px;
path_mb = path_mb_buf;
ml = QSE_COUNTOF(path_mb_buf);
px = qse_wcstombs (path, &wl, path_mb, &ml);
if (px == -2)
{
path_mb = qse_wcstombsdup (path, mmgr);
if (path_mb == QSE_NULL) return -1;
}
else if (px <= -1) return -1;
#endif
/*
* rwa -> RDWR | APPEND
@ -439,6 +479,12 @@ int qse_fio_init (
#endif
handle = QSE_OPEN (path_mb, desired_access, mode);
#if defined(QSE_CHAR_IS_MCHAR)
/* nothing to do */
#else
if (path_mb != path_mb_buf) QSE_MMGR_FREE (mmgr, path_mb);
#endif
}
if (handle == -1)

View File

@ -251,6 +251,65 @@ int qse_mbsntowcsn (
return ret;
}
int qse_mbsntowcsnupto (
const qse_mchar_t* mbs, qse_size_t* mbslen,
qse_wchar_t* wcs, qse_size_t* wcslen, qse_wchar_t stopper)
{
const qse_mchar_t* p;
qse_mbstate_t state = {{ 0, }};
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 = qse_mbrtowc (p, mlen, &w, &state);
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_mbstowcsdup (const qse_mchar_t* mbs, qse_mmgr_t* mmgr)
{
qse_size_t mbslen, wcslen;

View File

@ -44,7 +44,6 @@ qse_ssize_t qse_tio_readmbs (qse_tio_t* tio, qse_mchar_t* buf, qse_size_t size)
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)
{
@ -77,7 +76,8 @@ done:
return nread;
}
static QSE_INLINE int tio_read_widechars (qse_tio_t* tio)
static QSE_INLINE qse_ssize_t tio_read_widechars (
qse_tio_t* tio, qse_wchar_t* buf, qse_size_t bufsize)
{
qse_size_t mlen, wlen;
qse_ssize_t n;
@ -128,9 +128,9 @@ static QSE_INLINE int tio_read_widechars (qse_tio_t* tio)
}
mlen = tio->inbuf_len - tio->inbuf_cur;
wlen = QSE_COUNTOF(tio->inwbuf);
wlen = bufsize;
x = qse_mbsntowcsn (&tio->inbuf[tio->inbuf_cur], &mlen, tio->inwbuf, &wlen);
x = qse_mbsntowcsnupto (&tio->inbuf[tio->inbuf_cur], &mlen, buf, &wlen, QSE_WT('\n'));
tio->inbuf_cur += mlen;
if (x == -3)
@ -154,12 +154,12 @@ static QSE_INLINE int tio_read_widechars (qse_tio_t* tio)
else if (x == -2)
{
/* buffer not large enough */
QSE_ASSERTX (wlen > 0,
"You must enlarge the size of tio->inwbuf if this happens.");
QSE_ASSERT (wlen > 0);
/* 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 */
* 1 wide-character is produced though it may be inefficient.
*/
}
else if (x <= -1)
{
@ -168,7 +168,7 @@ static QSE_INLINE int tio_read_widechars (qse_tio_t* tio)
{
ignore_illseq:
tio->inbuf_cur++; /* skip one byte */
tio->inwbuf[wlen++] = QSE_WT('?');
buf[wlen++] = QSE_WT('?');
}
else if (wlen <= 0)
{
@ -184,14 +184,13 @@ static QSE_INLINE int tio_read_widechars (qse_tio_t* tio)
}
}
tio->inwbuf_cur = 0;
tio->inwbuf_len = wlen;
return 1;
return wlen;
}
qse_ssize_t qse_tio_readwcs (qse_tio_t* tio, qse_wchar_t* buf, qse_size_t size)
{
qse_size_t nread = 0;
qse_ssize_t n;
/*QSE_ASSERT (tio->input_func != QSE_NULL);*/
if (tio->input_func == QSE_NULL)
@ -204,25 +203,19 @@ qse_ssize_t qse_tio_readwcs (qse_tio_t* tio, qse_wchar_t* buf, qse_size_t size)
while (nread < size)
{
if (tio->inwbuf_cur >= tio->inwbuf_len)
if (tio->input_status & STATUS_ILLSEQ)
{
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;
tio->input_status &= ~STATUS_ILLSEQ;
tio->errnum = QSE_TIO_EILSEQ;
return -1;
}
n = tio_read_widechars (tio, &buf[nread], size - nread);
if (n == 0) break;
if (n <= -1) return -1;
buf[nread] = tio->inwbuf[tio->inwbuf_cur++];
if (buf[nread++] == QSE_WT('\n')) break;
nread += n;
if (buf[nread-1] == QSE_WT('\n')) break;
}
return nread;