added qse_wcsatombsdup()/qse_mbsatowcsdup()

added macro redefinition for QSE_MBLEN_MAX in some special cases
fixed a bug of defining QSE_TOMUPPER and QSE_TOMLOWER wrongly
changed data types of utf8 functions.
fixed null-terminating bugs in qse_mbstowcs()/qse_wcstombs()
This commit is contained in:
2011-12-05 13:43:56 +00:00
parent c2264998f2
commit 2faee1f23f
17 changed files with 535 additions and 295 deletions

View File

@ -19,6 +19,7 @@
*/
#include <qse/cmn/chr.h>
#include <qse/cmn/utf8.h>
#include "mem.h"
#if !defined(QSE_HAVE_CONFIG_H)
@ -41,7 +42,11 @@
qse_size_t qse_mbrlen (
const qse_mchar_t* mb, qse_size_t mbl, qse_mbstate_t* state)
{
#ifdef HAVE_MBRLEN
#if defined(_WIN32)
/* TODO: provide an option to use windows api */
return qse_utf8len (mb, mbl);
#elif defined(HAVE_MBRLEN)
size_t n;
n = mbrlen (mb, mbl, (mbstate_t*)state);
@ -67,7 +72,17 @@ qse_size_t qse_mbrtowc (
const qse_mchar_t* mb, qse_size_t mbl,
qse_wchar_t* wc, qse_mbstate_t* state)
{
#ifdef HAVE_MBRTOWC
#if defined(_WIN32)
/*
int n;
n = MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS, mb, mbl, wc, 1);
if (n == 0) return 0;
return mbl;
*/
return qse_utf8touc (mb, mbl, wc);
#elif defined(HAVE_MBRTOWC)
size_t n;
n = mbrtowc (wc, mb, mbl, (mbstate_t*)state);
@ -89,7 +104,10 @@ qse_size_t qse_wcrtomb (
qse_wchar_t wc, qse_mchar_t* mb,
qse_size_t mbl, qse_mbstate_t* state)
{
#ifdef HAVE_WCRTOMB
#if defined(_WIN32)
return qse_uctoutf8 (wc, mb, mbl);
#elif defined(HAVE_WCRTOMB)
size_t n;
if (mbl < QSE_MBLEN_MAX)
@ -113,7 +131,7 @@ qse_size_t qse_wcrtomb (
if (n == (size_t)-1) return 0; /* illegal character */
}
return n;
return n; /* number of bytes written to the buffer */
#else
#error #### NOT SUPPORTED ####
#endif
@ -147,5 +165,6 @@ qse_size_t qse_wctomb (qse_wchar_t wc, qse_mchar_t* mb, qse_size_t mbl)
int qse_mbcurmax (void)
{
return MB_CUR_MAX;
/* TODO: consider other encodings */
return (QSE_UTF8LEN_MAX > MB_CUR_MAX)? QSE_UTF8LEN_MAX: MB_CUR_MAX;
}

View File

@ -42,14 +42,15 @@ struct fop_t
{
int flags;
qse_lstat_t old_stat;
qse_lstat_t new_stat;
#if defined(_WIN32)
qse_wchar_t* old_path;
qse_wchar_t* new_path;
qse_wchar_t* new_path2;
#else
qse_lstat_t old_stat;
qse_lstat_t new_stat;
qse_mchar_t* old_path;
qse_mchar_t* new_path;
qse_mchar_t* new_path2;
@ -178,7 +179,7 @@ int qse_fs_move (
fs->errnum = QSE_FS_ENOMEM;
goto oops;
}
qse_printf (QSE_T("new_path2 => [%S]\n"), fop.new_path2);
qse_printf (QSE_T("new_path2 => [%hs]\n"), fop.new_path2);
}
else
{

View File

@ -365,7 +365,8 @@ int qse_sio_seek (qse_sio_t* sio, qse_sio_seek_t pos)
}
#endif
static qse_ssize_t __sio_input (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size)
static qse_ssize_t __sio_input (
qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size)
{
qse_sio_t* sio = (qse_sio_t*)arg;
@ -394,7 +395,8 @@ static qse_ssize_t __sio_input (qse_tio_cmd_t cmd, void* arg, void* buf, qse_siz
return 0;
}
static qse_ssize_t __sio_output (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size)
static qse_ssize_t __sio_output (
qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size)
{
qse_sio_t* sio = (qse_sio_t*)arg;

View File

@ -20,48 +20,17 @@
#include <qse/cmn/stdio.h>
#include <qse/cmn/chr.h>
#include <qse/cmn/str.h>
#include "mem.h"
#include <wchar.h>
#include <stdlib.h>
#include <limits.h>
#ifndef PATH_MAX
#define PATH_MAX 2048
# define PATH_MAX 2048
#endif
#if defined(_WIN32) && !defined(__WATCOMC__)
int qse_vsprintf (qse_char_t* buf, qse_size_t size, const qse_char_t* fmt, va_list ap)
{
int n;
#ifdef QSE_CHAR_IS_MCHAR
n = _vsnprintf (buf, size, fmt, ap);
#else
n = _vsnwprintf (buf, size, fmt, ap);
#endif
if (n < 0 || (size_t)n >= size)
{
if (size > 0) buf[size-1] = QSE_T('\0');
n = -1;
}
return n;
}
int qse_sprintf (qse_char_t* buf, qse_size_t size, const qse_char_t* fmt, ...)
{
int n;
va_list ap;
va_start (ap, fmt);
n = qse_vsprintf (buf, size, fmt, ap);
va_end (ap);
return n;
}
#else
static qse_char_t* __adjust_format (const qse_char_t* format);
int qse_vfprintf (QSE_FILE *stream, const qse_char_t* fmt, va_list ap)
@ -70,12 +39,12 @@ int qse_vfprintf (QSE_FILE *stream, const qse_char_t* fmt, va_list ap)
qse_char_t* nf = __adjust_format (fmt);
if (nf == NULL) return -1;
#ifdef QSE_CHAR_IS_MCHAR
#if defined(QSE_CHAR_IS_MCHAR)
n = vfprintf (stream, nf, ap);
#else
#else
n = vfwprintf (stream, nf, ap);
#endif
free (nf);
#endif
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), nf);
return n;
}
@ -112,20 +81,27 @@ int qse_vsprintf (qse_char_t* buf, qse_size_t size, const qse_char_t* fmt, va_li
qse_char_t* nf = __adjust_format (fmt);
if (nf == NULL) return -1;
#if defined(QSE_CHAR_IS_MCHAR)
n = vsnprintf (buf, size, nf, ap);
#elif defined(_WIN32) && !defined(__WATCOMC__)
n = _vsnwprintf (buf, size, nf, ap);
#else
n = vswprintf (buf, size, nf, ap);
#endif
#if defined(QSE_CHAR_IS_MCHAR)
#if defined(_WIN32) && !defined(__WATCOMC__)
n = _vsnprintf (buf, size, nf, ap);
#else
n = vsnprintf (buf, size, nf, ap);
#endif
#else
#if defined(_WIN32) && !defined(__WATCOMC__)
n = _vsnwprintf (buf, size, nf, ap);
#else
n = vswprintf (buf, size, nf, ap);
#endif
#endif
if (n < 0 || (size_t)n >= size)
{
if (size > 0) buf[size-1] = QSE_T('\0');
n = -1;
}
free (nf);
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), nf);
return n;
}
@ -149,11 +125,12 @@ int qse_sprintf (qse_char_t* buf, qse_size_t size, const qse_char_t* fmt, ...)
if (buf.len >= buf.cap) \
{ \
qse_char_t* tmp; \
tmp = (qse_char_t*)realloc ( \
buf.ptr, sizeof(qse_char_t)*(buf.cap+256+1)); \
tmp = (qse_char_t*) QSE_MMGR_REALLOC ( \
QSE_MMGR_GETDFL(), buf.ptr, \
QSE_SIZEOF(qse_char_t) * (buf.cap+256+1)); \
if (tmp == NULL) \
{ \
free (buf.ptr); \
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), buf.ptr); \
return NULL; \
} \
buf.ptr = tmp; \
@ -177,11 +154,9 @@ static qse_char_t* __adjust_format (const qse_char_t* format)
buf.len = 0;
buf.cap = 256;
#if (defined(vms) || defined(__vms)) && (QSE_SIZEOF_VOID_P >= 8)
buf.ptr = (qse_char_t*) _malloc32 (sizeof(qse_char_t)*(buf.cap+1));
#else
buf.ptr = (qse_char_t*) malloc (sizeof(qse_char_t)*(buf.cap+1));
#endif
buf.ptr = (qse_char_t*) QSE_MMGR_ALLOC (
QSE_MMGR_GETDFL(), QSE_SIZEOF(qse_char_t) * (buf.cap+1));
if (buf.ptr == NULL) return NULL;
while (*fp != QSE_T('\0'))
@ -267,70 +242,136 @@ static qse_char_t* __adjust_format (const qse_char_t* format)
ch = *fp++;
}
/* type */
if (ch == QSE_T('%')) ADDC (buf, ch);
else if (ch == QSE_T('c') || ch == QSE_T('s'))
switch (ch)
{
#if !defined(QSE_CHAR_IS_MCHAR) && !defined(_WIN32)
ADDC (buf, 'l');
#endif
ADDC (buf, ch);
}
else if (ch == QSE_T('C') || ch == QSE_T('S'))
{
#if defined(_WIN32) && !defined(__WATCOMC__)
ADDC (buf, ch);
#else
#ifdef QSE_CHAR_IS_MCHAR
ADDC (buf, 'l');
#endif
ADDC (buf, QSE_TOLOWER(ch));
#endif
}
else if (ch == QSE_T('d') || ch == QSE_T('i') ||
ch == QSE_T('o') || ch == QSE_T('u') ||
ch == QSE_T('x') || ch == QSE_T('X'))
{
if (modifier == MOD_SHORT)
case QSE_T('\0'):
goto done;
case QSE_T('%'):
{
ADDC (buf, 'h');
ADDC (buf, ch);
break;
}
else if (modifier == MOD_LONG)
case QSE_T('c'):
case QSE_T('s'):
{
ADDC (buf, 'l');
if (modifier == MOD_SHORT)
{
/* always multibyte */
#if defined(QSE_CHAR_IS_MCHAR)
goto mchar_multi;
#else
ch = QSE_TOUPPER(ch);
goto wchar_multi;
#endif
}
else if (modifier == MOD_LONG)
{
/* always wide-character */
#if defined(QSE_CHAR_IS_MCHAR)
ch = QSE_TOUPPER(ch);
goto mchar_wide;
#else
goto wchar_wide;
#endif
}
else
{
#if defined(QSE_CHAR_IS_MCHAR)
mchar_multi:
#if defined(_WIN32) && !defined(__WATCOMC__)
ADDC (buf, ch);
#else
ADDC (buf, ch);
#endif
#else
wchar_wide:
#if defined(_WIN32) && !defined(__WATCOMC__)
ADDC (buf, ch);
#else
ADDC (buf, QSE_WT('l'));
ADDC (buf, ch);
#endif
#endif
}
break;
}
else if (modifier == MOD_LONGLONG)
case QSE_T('C'):
case QSE_T('S'):
{
#if defined(_WIN32) && !defined(__LCC__)
ADDC (buf, 'I');
ADDC (buf, '6');
ADDC (buf, '4');
#else
ADDC (buf, 'l');
ADDC (buf, 'l');
#endif
#if defined(QSE_CHAR_IS_MCHAR)
mchar_wide:
#if defined(_WIN32) && !defined(__WATCOMC__)
ADDC (buf, ch);
#else
ADDC (buf, QSE_MT('l'));
ADDC (buf, QSE_TOLOWER(ch));
#endif
#else
wchar_multi:
#if defined(_WIN32) && !defined(__WATCOMC__)
ADDC (buf, ch);
#else
ADDC (buf, QSE_TOLOWER(ch));
#endif
#endif
break;
}
case QSE_T('d'):
case QSE_T('i'):
case QSE_T('o'):
case QSE_T('u'):
case QSE_T('x'):
case QSE_T('X'):
{
if (modifier == MOD_SHORT)
{
ADDC (buf, 'h');
}
else if (modifier == MOD_LONG)
{
ADDC (buf, 'l');
}
else if (modifier == MOD_LONGLONG)
{
#if defined(_WIN32) && !defined(__LCC__)
ADDC (buf, 'I');
ADDC (buf, '6');
ADDC (buf, '4');
#else
ADDC (buf, 'l');
ADDC (buf, 'l');
#endif
}
ADDC (buf, ch);
break;
}
default:
{
ADDC (buf, ch);
break;
}
ADDC (buf, ch);
}
else if (ch == QSE_T('\0')) break;
else ADDC (buf, ch);
}
done:
buf.ptr[buf.len] = QSE_T('\0');
return buf.ptr;
}
#endif
int qse_dprintf (const qse_char_t* fmt, ...)
{
int n;
va_list ap;
va_start (ap, fmt);
n = qse_vfprintf (stderr, fmt, ap);
n = qse_vfprintf (QSE_STDERR, fmt, ap);
va_end (ap);
return n;
}
@ -343,19 +384,23 @@ QSE_FILE* qse_fopen (const qse_char_t* path, const qse_char_t* mode)
return _wfopen (path, mode);
#else
char path_mb[PATH_MAX + 1];
char mode_mb[32];
size_t n;
QSE_FILE* fp = QSE_NULL;
qse_mchar_t* path_mb;
qse_mchar_t* mode_mb;
n = wcstombs (path_mb, path, QSE_COUNTOF(path_mb));
if (n == (size_t)-1) return NULL;
if (n == QSE_COUNTOF(path_mb)) path_mb[QSE_COUNTOF(path_mb)-1] = '\0';
path_mb = qse_wcstombsdup (path, QSE_MMGR_GETDFL());
mode_mb = qse_wcstombsdup (mode, QSE_MMGR_GETDFL());
n = wcstombs (mode_mb, mode, QSE_COUNTOF(mode_mb));
if (n == (size_t)-1) return NULL;
if (n == QSE_COUNTOF(mode_mb)) path_mb[QSE_COUNTOF(mode_mb)-1] = '\0';
if (path_mb && mode_mb)
{
fp = fopen (path_mb, mode_mb);
}
if (mode_mb) QSE_MMGR_FREE (QSE_MMGR_GETDFL(), mode_mb);
if (path_mb) QSE_MMGR_FREE (QSE_MMGR_GETDFL(), path_mb);
return fp;
return fopen (path_mb, mode_mb);
#endif
}
@ -378,19 +423,36 @@ QSE_FILE* qse_popen (const qse_char_t* cmd, const qse_char_t* mode)
return QSE_NULL;
#else
char cmd_mb[PATH_MAX + 1];
char mode_mb[32];
size_t n;
n = wcstombs (cmd_mb, cmd, QSE_COUNTOF(cmd_mb));
if (n == (size_t)-1) return NULL;
if (n == QSE_COUNTOF(cmd_mb)) cmd_mb[QSE_COUNTOF(cmd_mb)-1] = '\0';
QSE_FILE* fp = QSE_NULL;
qse_mchar_t* cmd_mb;
n = wcstombs (mode_mb, mode, QSE_COUNTOF(mode_mb));
if (n == (size_t)-1) return NULL;
if (n == QSE_COUNTOF(mode_mb)) cmd_mb[QSE_COUNTOF(mode_mb)-1] = '\0';
cmd_mb = qse_wcstombsdup (cmd, QSE_MMGR_GETDFL());
if (cmd_mb)
{
char mode_mb[3];
int mode_mb_len;
int mode_flag = 0;
fp = popen (cmd_mb, mode_mb);
while (*mode)
{
if (*mode == QSE_T('r')) mode_flag |= 1;
else if (*mode == QSE_T('w')) mode_flag |= 2;
mode++;
}
mode_mb_len = 0;
if (mode_flag & 1) mode_mb[mode_mb_len++] = QSE_MT('r');
if (mode_flag & 2) mode_mb[mode_mb_len++] = QSE_MT('w');
mode_mb[mode_mb_len++] = QSE_MT('\0');
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), cmd_mb);
}
return fp;
return popen (cmd_mb, mode_mb);
#endif
}
@ -423,11 +485,8 @@ qse_ssize_t qse_getdelim (
if (b == QSE_NULL)
{
capa = 256;
#if (defined(vms) || defined(__vms)) && (QSE_SIZEOF_VOID_P >= 8)
b = (qse_char_t*) _malloc32 (sizeof(qse_char_t)*(capa+1));
#else
b = (qse_char_t*) malloc (sizeof(qse_char_t)*(capa+1));
#endif
b = (qse_char_t*) QSE_MMGR_ALLOC (
QSE_MMGR_GETDFL(), QSE_SIZEOF(qse_char_t)*(capa+1));
if (b == QSE_NULL) return -2;
}
@ -461,7 +520,8 @@ qse_ssize_t qse_getdelim (
qse_size_t ncapa = capa + 256;
qse_char_t* nb;
nb = realloc (b, ncapa*sizeof(qse_char_t));
nb = QSE_MMGR_REALLOC (
QSE_MMGR_GETDFL(), b, ncapa * QSE_SIZEOF(qse_char_t));
if (nb == QSE_NULL)
{
len = (qse_size_t)-2;

View File

@ -138,7 +138,6 @@ qse_ulong_t qse_strxtoulong (const qse_char_t* str, qse_size_t len)
/*
* TODO: fix wrong mbstate handling
*/
qse_size_t qse_mbstowcslen (const qse_mchar_t* mcs, qse_size_t* wcslen)
{
qse_wchar_t wc;
@ -206,10 +205,9 @@ qse_size_t qse_mbstowcs (
}
/* if null-terminated properly, the input wcslen must be less than
* the output wcslen. (input length includs the terminating null
* the output wcslen. (input length includes the terminating null
* while the output length excludes the terminating null) */
*wcslen = wlen;
return mlen;
}
@ -243,7 +241,7 @@ qse_size_t qse_mbsntowcsn (
qse_size_t qse_wcstombslen (const qse_wchar_t* wcs, qse_size_t* mbslen)
{
const qse_wchar_t* p = wcs;
qse_mchar_t mbs[32];
qse_mchar_t mbs[QSE_MBLEN_MAX];
qse_size_t mlen = 0;
qse_mbstate_t state = {{ 0, }};
@ -273,7 +271,7 @@ qse_size_t qse_wcsntombsnlen (
{
const qse_wchar_t* p = wcs;
const qse_wchar_t* end = wcs + wcslen;
qse_mchar_t mbs[32];
qse_mchar_t mbs[QSE_MBLEN_MAX];
qse_size_t mlen = 0;
qse_mbstate_t state = {{ 0, }};
@ -288,7 +286,8 @@ qse_size_t qse_wcsntombsnlen (
p++; mlen += n;
}
/* this length excludes the terminating null character. */
/* this length excludes the terminating null character.
* this function doesn't event null-terminate the result. */
*mbslen = mlen;
/* returns the number of characters handled.
@ -304,7 +303,7 @@ qse_size_t qse_wcstombs (
qse_size_t rem = *mbslen;
qse_mbstate_t state = {{ 0, }};
while (*p != QSE_WT('\0') && rem > 1)
while (*p != QSE_WT('\0') && rem > 0)
{
qse_size_t n = qse_wcrtomb (*p, mbs, rem, &state);
if (n == 0 || n > rem)
@ -313,14 +312,6 @@ qse_size_t qse_wcstombs (
break;
}
if (rem == n)
{
/* the buffer is full without the space for a
* terminating null. should stop processing further
* excluding this last character emitted. */
break;
}
mbs += n; rem -= n; p++;
}
@ -371,16 +362,16 @@ int qse_mbstowcsrigid (
qse_size_t wn = wcslen;
n = qse_mbstowcs (mbs, wcs, &wn);
if (mbs[n] != QSE_MT('\0'))
{
/* incomplete sequence or invalid sequence */
return -1;
}
if (wn >= wcslen)
{
/* wcs not big enough to be null-terminated.
* if it has been null-terminated properly,
* wn should be less than wcslen. */
return -1;
}
if (mbs[n] != QSE_MT('\0'))
{
/* incomplete sequence or invalid sequence */
return -2;
}
@ -395,19 +386,19 @@ int qse_wcstombsrigid (
qse_size_t mn = mbslen;
n = qse_wcstombs (wcs, mbs, &mn);
if (mn >= mbslen)
{
/* mbs not big enough to be null-terminated.
* if it has been null-terminated properly,
* mn should be less than mbslen. */
return -1;
}
if (wcs[n] != QSE_WT('\0'))
{
/* if qse_wcstombs() processed all wide characters,
* the character at position 'n' should be a null character
* as 'n' is the number of wide characters processed. */
return -2;
return -1;
}
if (mn >= mbslen)
{
/* mbs not big enough to be null-terminated.
* if it has been null-terminated properly,
* mn should be less than mbslen. */
return -2;
}
return 0;
@ -447,6 +438,37 @@ qse_mchar_t* qse_wcstombsdup (const qse_wchar_t* wcs, qse_mmgr_t* mmgr)
return mbs;
}
qse_wchar_t* qse_mbsatowcsdup (const qse_mchar_t* mbs[], qse_mmgr_t* mmgr)
{
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++)
{
ml = qse_mbstowcslen(mbs[i], &wl);
if (mbs[i][ml] != QSE_MT('\0')) 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;
ml = qse_mbstowcs (mbs[i], ptr, &wl);
ptr += wl;
capa -= wl;
}
return buf;
}
qse_mchar_t* qse_wcsatombsdup (const qse_wchar_t* wcs[], qse_mmgr_t* mmgr)
{
@ -464,7 +486,8 @@ qse_mchar_t* qse_wcsatombsdup (const qse_wchar_t* wcs[], qse_mmgr_t* mmgr)
capa += ml;
}
buf = (qse_mchar_t*) QSE_MMGR_ALLOC (mmgr, (capa+1)*QSE_SIZEOF(*buf));
buf = (qse_mchar_t*) QSE_MMGR_ALLOC (
mmgr, (capa + 1) * QSE_SIZEOF(*buf));
if (buf == QSE_NULL) return QSE_NULL;
ptr = buf;

View File

@ -67,6 +67,7 @@ static qse_ssize_t tio_putc (qse_tio_t* tio, qse_char_t c, int* flush_needed)
return -1;
}
for (i = 0; i < n; i++)
{
tio->outbuf[tio->outbuf_len++] = mc[i];

View File

@ -38,6 +38,7 @@ struct __utf8_t
qse_uint32_t upper;
qse_uint8_t fbyte; /* mask to the first utf8 byte */
qse_uint8_t mask;
qse_uint8_t fmask;
int length; /* number of bytes */
};
@ -45,12 +46,12 @@ typedef struct __utf8_t __utf8_t;
static __utf8_t utf8_table[] =
{
{0x00000000ul, 0x0000007Ful, 0x00, 0x80, 1},
{0x00000080ul, 0x000007FFul, 0xC0, 0xE0, 2},
{0x00000800ul, 0x0000FFFFul, 0xE0, 0xF0, 3},
{0x00010000ul, 0x001FFFFFul, 0xF0, 0xF8, 4},
{0x00200000ul, 0x03FFFFFFul, 0xF8, 0xFC, 5},
{0x04000000ul, 0x7FFFFFFFul, 0xFC, 0xFE, 6}
{0x00000000ul, 0x0000007Ful, 0x00, 0x80, 0x7F, 1},
{0x00000080ul, 0x000007FFul, 0xC0, 0xE0, 0x1F, 2},
{0x00000800ul, 0x0000FFFFul, 0xE0, 0xF0, 0x0F, 3},
{0x00010000ul, 0x001FFFFFul, 0xF0, 0xF8, 0x07, 4},
{0x00200000ul, 0x03FFFFFFul, 0xF8, 0xFC, 0x03, 5},
{0x04000000ul, 0x7FFFFFFFul, 0xFC, 0xFE, 0x01, 6}
};
static QSE_INLINE __utf8_t* get_utf8_slot (qse_wchar_t uc)
@ -72,23 +73,25 @@ static QSE_INLINE __utf8_t* get_utf8_slot (qse_wchar_t uc)
return QSE_NULL; /* invalid character */
}
int qse_uctoutf8len (qse_wchar_t uc)
qse_size_t qse_uctoutf8len (qse_wchar_t uc)
{
__utf8_t* cur = get_utf8_slot (uc);
return (cur == QSE_NULL)? 0: cur->length;
return (cur == QSE_NULL)? 0: (qse_size_t)cur->length;
}
int qse_uctoutf8 (qse_wchar_t uc, qse_mchar_t* utf8, int size)
/* wctomb for utf8/unicode */
qse_size_t qse_uctoutf8 (qse_wchar_t uc, qse_mchar_t* utf8, qse_size_t size)
{
__utf8_t* cur = get_utf8_slot (uc);
int index;
if (cur == QSE_NULL) return 0; /* invalid character */
if (cur == QSE_NULL) return 0; /* illegal character */
if (cur->length > size)
{
/* buffer not big enough. index indicates the buffer size needed */
return -index;
/* buffer not big enough. index indicates the buffer
* size needed */
return size + 1;
}
index = cur->length;
@ -103,16 +106,18 @@ int qse_uctoutf8 (qse_wchar_t uc, qse_mchar_t* utf8, int size)
}
utf8[0] = uc | cur->fbyte;
return cur->length;
return (qse_size_t)cur->length;
}
int qse_utf8touc (
const qse_mchar_t* utf8, int size, qse_wchar_t* uc)
/* mbtowc for utf8/unicode */
qse_size_t qse_utf8touc (
const qse_mchar_t* utf8, qse_size_t size, qse_wchar_t* uc)
{
__utf8_t* cur, * end;
#if 0
qse_mchar_t c, t;
qse_wchar_t w;
int count = 0;
#endif
QSE_ASSERT (utf8 != QSE_NULL);
QSE_ASSERT (QSE_SIZEOF(qse_mchar_t) == 1);
@ -120,7 +125,32 @@ int qse_utf8touc (
end = utf8_table + QSE_COUNTOF(utf8_table);
cur = utf8_table;
while (cur < end)
{
if ((utf8[0] & cur->mask) == cur->fbyte)
{
int i;
qse_wchar_t w;
if (size < cur->length) return size + 1;
w = utf8[0] & cur->fmask;
for (i = 1; i < cur->length; i++)
{
if (!(utf8[i] & 0x80)) return 0;
w = (w << 6) | (utf8[i] & 0x3F);
}
*uc = w;
return (qse_size_t)cur->length;
}
cur++;
}
return 0; /* error - invalid sequence */
#if 0
c = *utf8;
w = c;
@ -133,7 +163,7 @@ int qse_utf8touc (
w &= cur->upper;
if (w < cur->lower) break; /* wrong value */
*uc = w;
return count;
return (qse_size_t)count;
}
if (size <= count) break; /* insufficient input */
@ -147,10 +177,11 @@ int qse_utf8touc (
}
return 0; /* error - invalid sequence */
#endif
}
#if 0
int qse_utf8len (qse_mchar_t first)
/* mblen for utf8 */
qse_size_t qse_utf8len (const qse_mchar_t* utf8, qse_size_t len)
{
__utf8_t* cur, * end;
@ -159,10 +190,32 @@ int qse_utf8len (qse_mchar_t first)
while (cur < end)
{
if ((first & cur->mask) == cur->fbyte) return cur->length;
if ((utf8[0] & cur->mask) == cur->fbyte)
{
int i;
if (len < cur->length)
{
/* the input is not as large as
* the expected number of bytes */
return len + 1; /* incomplete sequence */
}
for (i = 1; i < cur->length; i++)
{
/* in utf8, trailing bytes are all
* set with 0x80. if not, invalid */
if (!(utf8[i] & 0x80)) return 0;
}
return (qse_size_t)cur->length;
}
cur++;
}
return 0; /* error - invalid sequence */
}
#endif
qse_size_t qse_utf8lenmax (void)
{
return QSE_UTF8LEN_MAX;
}

View File

@ -715,7 +715,7 @@ static void* response_thread (void* arg)
if (n <= -1)
{
/*if (errno == EINTR) continue; */
qse_fprintf (QSE_STDERR, QSE_T("Error: select returned failure - %S\n"), strerror(errno));
qse_fprintf (QSE_STDERR, QSE_T("Error: select returned failure - %hs\n"), strerror(errno));
/* break; */
continue;
}

View File

@ -472,7 +472,7 @@ static int task_main_path (
struct stat st;
qse_httpd_task_t* x = task;
qse_printf (QSE_T("opending file %S\n"), data->name);
qse_printf (QSE_T("opending file %hs\n"), data->name);
handle.i = open (data->name, O_RDONLY);
if (handle.i <= -1)
{