added qse_mbsntowcsnupto()
changed qse_tio_readwcs() to utilize qse_mbsntowcsnupto()
This commit is contained in:
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user