fixed bugs in ase_mbstowcs and ase_wcstombs

This commit is contained in:
hyung-hwan 2008-10-21 05:13:55 +00:00
parent fa6dfeddc9
commit ef1b5e1dac

View File

@ -1,5 +1,5 @@
/* /*
* $Id: str_cnv.c 430 2008-10-17 11:43:20Z baconevi $ * $Id: str_cnv.c 431 2008-10-20 11:13:55Z baconevi $
* *
* {License} * {License}
*/ */
@ -125,26 +125,31 @@ ase_ulong_t ase_strxtoulong (const ase_char_t* str, ase_size_t len)
ase_size_t ase_mbstowcs ( ase_size_t ase_mbstowcs (
const ase_mchar_t* mbs, ase_wchar_t* wcs, ase_size_t* wcslen) const ase_mchar_t* mbs, ase_wchar_t* wcs, ase_size_t* wcslen)
{ {
ase_size_t len, wlen; ase_size_t wlen, mlen;
for (len = 0; *mbs++ != '\0'; len++); const ase_mchar_t* mp;
/* get the lenght of mbs and pass it to ase_mbsntowcsn as
* ase_mbtowc needs it. */
for (mp = mbs; *mp != '\0'; mp++);
if (*wcslen <= 0) return 0; if (*wcslen <= 0)
{
/* buffer too small. cannot null-terminate it */
return 0;
}
if (*wcslen == 1) if (*wcslen == 1)
{ {
wcs[0] = L'\0'; wcs[0] = L'\0';
return 0; return 0;
} }
/* because ase_mbtowc needs the length, we get the lenght of mbs
* and pass it to ase_mbsntowcsn */
wlen = *wcslen - 1; wlen = *wcslen - 1;
len = ase_mbsntowcsn (mbs, len, wcs, &wlen); mlen = ase_mbsntowcsn (mbs, mp - mbs, wcs, &wlen);
wcs[wlen] = L'\0'; wcs[wlen] = L'\0';
*wcslen = wlen; *wcslen = wlen;
/* TODO: wcslen should include the length including null? */
return len; return mlen;
} }
ase_size_t ase_mbsntowcsn ( ase_size_t ase_mbsntowcsn (
@ -173,29 +178,38 @@ ase_size_t ase_mbsntowcsn (
return p - mbs; /* returns the number of bytes processed */ return p - mbs; /* returns the number of bytes processed */
} }
ase_size_t wcstombs ( ase_size_t ase_wcstombs (
const ase_wchar_t* wcs, ase_mchar_t* mbs, ase_size_t* mbslen) const ase_wchar_t* wcs, ase_mchar_t* mbs, ase_size_t* mbslen)
{ {
const ase_wchar_t* p = wcs; const ase_wchar_t* p = wcs;
ase_size_t len = *mbslen; ase_size_t rem = *mbslen;
while (*p != ASE_T('\0') && len > 1) while (*p != ASE_T('\0') && rem > 1)
{ {
ase_size_t n = ase_wctomb (*p, mbs, len); ase_size_t n = ase_wctomb (*p, mbs, rem);
if (n == 0 || n > len) if (n == 0 || n > rem)
{ {
/* illegal character or buffer not enough */ /* illegal character or buffer not enough */
break; break;
} }
mbs += n; len -= n; p++;
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++;
} }
*mbslen -= len; *mbslen -= rem;
if (len > 0) *mbs = '\0';
/* returns the number of characters handled. /* null-terminate the multibyte sequence if it has sufficient space */
* the caller can check if the return value is as large is wcslen if (rem > 0) *mbs = '\0';
* for an error. */
/* returns the number of characters handled. */
return p - wcs; return p - wcs;
} }