2008-03-18 22:09:04 +00:00
|
|
|
/*
|
2008-11-27 03:05:00 +00:00
|
|
|
* $Id: str_cnv.c 455 2008-11-26 09:05:00Z baconevi $
|
2008-03-18 22:09:04 +00:00
|
|
|
*
|
2009-01-06 04:40:25 +00:00
|
|
|
Copyright 2006-2008 Chung, Hyung-Hwan.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
2008-03-18 22:09:04 +00:00
|
|
|
*/
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
#include <qse/cmn/str.h>
|
2008-03-18 22:09:04 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
int qse_strtoi (const qse_char_t* str)
|
2008-03-19 00:29:25 +00:00
|
|
|
{
|
|
|
|
int v;
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_STRTONUM (v, str, QSE_NULL, 10);
|
2008-03-19 00:29:25 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
long qse_strtol (const qse_char_t* str)
|
2008-03-19 00:29:25 +00:00
|
|
|
{
|
|
|
|
long v;
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_STRTONUM (v, str, QSE_NULL, 10);
|
2008-03-19 00:29:25 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
unsigned int qse_strtoui (const qse_char_t* str)
|
2008-03-19 00:29:25 +00:00
|
|
|
{
|
|
|
|
unsigned int v;
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_STRTONUM (v, str, QSE_NULL, 10);
|
2008-03-19 00:29:25 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
unsigned long qse_strtoul (const qse_char_t* str)
|
2008-03-19 00:29:25 +00:00
|
|
|
{
|
|
|
|
unsigned long v;
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_STRTONUM (v, str, QSE_NULL, 10);
|
2008-03-19 00:29:25 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
int qse_strxtoi (const qse_char_t* str, qse_size_t len)
|
2008-03-19 00:29:25 +00:00
|
|
|
{
|
|
|
|
int v;
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_STRXTONUM (v, str, len, QSE_NULL, 10);
|
2008-03-19 00:29:25 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
long qse_strxtol (const qse_char_t* str, qse_size_t len)
|
2008-03-19 00:29:25 +00:00
|
|
|
{
|
|
|
|
long v;
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_STRXTONUM (v, str, len, QSE_NULL, 10);
|
2008-03-19 00:29:25 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
unsigned int qse_strxtoui (const qse_char_t* str, qse_size_t len)
|
2008-03-19 00:29:25 +00:00
|
|
|
{
|
|
|
|
unsigned int v;
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_STRXTONUM (v, str, len, QSE_NULL, 10);
|
2008-03-19 00:29:25 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
unsigned long qse_strxtoul (const qse_char_t* str, qse_size_t len)
|
2008-03-19 00:29:25 +00:00
|
|
|
{
|
|
|
|
unsigned long v;
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_STRXTONUM (v, str, len, QSE_NULL, 10);
|
2008-03-19 00:29:25 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_int_t qse_strtoint (const qse_char_t* str)
|
2008-03-18 22:09:04 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_int_t v;
|
|
|
|
QSE_STRTONUM (v, str, QSE_NULL, 10);
|
2008-03-18 22:09:04 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_long_t qse_strtolong (const qse_char_t* str)
|
2008-03-18 22:09:04 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_long_t v;
|
|
|
|
QSE_STRTONUM (v, str, QSE_NULL, 10);
|
2008-03-18 22:09:04 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_uint_t qse_strtouint (const qse_char_t* str)
|
2008-03-18 22:09:04 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_uint_t v;
|
|
|
|
QSE_STRTONUM (v, str, QSE_NULL, 10);
|
2008-03-18 22:09:04 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_ulong_t qse_strtoulong (const qse_char_t* str)
|
2008-03-18 22:09:04 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_ulong_t v;
|
|
|
|
QSE_STRTONUM (v, str, QSE_NULL, 10);
|
2008-03-19 00:29:25 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_int_t qse_strxtoint (const qse_char_t* str, qse_size_t len)
|
2008-03-19 00:29:25 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_int_t v;
|
|
|
|
QSE_STRXTONUM (v, str, len, QSE_NULL, 10);
|
2008-03-19 00:29:25 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_long_t qse_strxtolong (const qse_char_t* str, qse_size_t len)
|
2008-03-19 00:29:25 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_long_t v;
|
|
|
|
QSE_STRXTONUM (v, str, len, QSE_NULL, 10);
|
2008-03-19 00:29:25 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_uint_t qse_strxtouint (const qse_char_t* str, qse_size_t len)
|
2008-03-19 00:29:25 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_uint_t v;
|
|
|
|
QSE_STRXTONUM (v, str, len, QSE_NULL, 10);
|
2008-03-19 00:29:25 +00:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_ulong_t qse_strxtoulong (const qse_char_t* str, qse_size_t len)
|
2008-03-19 00:29:25 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_ulong_t v;
|
|
|
|
QSE_STRXTONUM (v, str, len, QSE_NULL, 10);
|
2008-03-18 22:09:04 +00:00
|
|
|
return v;
|
|
|
|
}
|
2008-10-18 05:43:20 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t qse_mbstowcs (
|
|
|
|
const qse_mchar_t* mbs, qse_wchar_t* wcs, qse_size_t* wcslen)
|
2008-10-18 05:43:20 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t wlen, mlen;
|
|
|
|
const qse_mchar_t* mp;
|
2008-10-18 05:43:20 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
/* get the length of mbs and pass it to qse_mbsntowcsn as
|
|
|
|
* qse_mbtowc called by qse_mbsntowcsn needs it. */
|
2008-10-21 05:13:55 +00:00
|
|
|
for (mp = mbs; *mp != '\0'; mp++);
|
2008-10-18 05:43:20 +00:00
|
|
|
|
2008-10-21 05:13:55 +00:00
|
|
|
if (*wcslen <= 0)
|
|
|
|
{
|
|
|
|
/* buffer too small. cannot null-terminate it */
|
|
|
|
return 0;
|
|
|
|
}
|
2008-10-18 05:43:20 +00:00
|
|
|
if (*wcslen == 1)
|
|
|
|
{
|
|
|
|
wcs[0] = L'\0';
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
wlen = *wcslen - 1;
|
2008-12-21 21:35:07 +00:00
|
|
|
mlen = qse_mbsntowcsn (mbs, mp - mbs, wcs, &wlen);
|
2008-10-18 05:43:20 +00:00
|
|
|
|
|
|
|
wcs[wlen] = L'\0';
|
|
|
|
*wcslen = wlen;
|
2008-10-21 05:13:55 +00:00
|
|
|
|
|
|
|
return mlen;
|
2008-10-18 05:43:20 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t qse_mbsntowcsn (
|
|
|
|
const qse_mchar_t* mbs, qse_size_t mbslen,
|
|
|
|
qse_wchar_t* wcs, qse_size_t* wcslen)
|
2008-10-18 05:43:20 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t mlen = mbslen, n;
|
|
|
|
const qse_mchar_t* p;
|
|
|
|
qse_wchar_t* q, * qend ;
|
2008-10-18 05:43:20 +00:00
|
|
|
|
|
|
|
qend = wcs + *wcslen;
|
|
|
|
|
|
|
|
for (p = mbs, q = wcs; mlen > 0 && q < qend; p += n, mlen -= n)
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
n = qse_mbtowc (p, mlen, q);
|
2008-10-18 05:43:20 +00:00
|
|
|
if (n == 0 || n > mlen)
|
|
|
|
{
|
|
|
|
/* wrong sequence or insufficient input */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
q++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*wcslen = q - wcs;
|
|
|
|
return p - mbs; /* returns the number of bytes processed */
|
|
|
|
}
|
|
|
|
|
2009-01-11 09:25:33 +00:00
|
|
|
qse_size_t qse_wcstombslen (const qse_wchar_t* wcs, qse_size_t* mbslen)
|
2008-10-18 05:43:20 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
const qse_wchar_t* p = wcs;
|
2009-01-11 09:25:33 +00:00
|
|
|
qse_mchar_t mbs[32];
|
|
|
|
qse_size_t mlen = 0;
|
2008-10-18 05:43:20 +00:00
|
|
|
|
2009-01-11 09:25:33 +00:00
|
|
|
while (*p != QSE_WT('\0'))
|
2008-10-18 05:43:20 +00:00
|
|
|
{
|
2009-01-11 09:25:33 +00:00
|
|
|
qse_size_t n = qse_wctomb (*p, mbs, QSE_COUNTOF(mbs));
|
|
|
|
if (n == 0) break; /* illegal character */
|
2008-10-21 05:13:55 +00:00
|
|
|
|
2009-01-11 09:25:33 +00:00
|
|
|
/* it assumes that mbs is large enough to hold a character */
|
|
|
|
QSE_ASSERT (n <= QSE_COUNTOF(mbs));
|
2008-10-21 05:13:55 +00:00
|
|
|
|
2009-01-11 09:25:33 +00:00
|
|
|
p++; mlen += n;
|
2008-10-18 05:43:20 +00:00
|
|
|
}
|
|
|
|
|
2009-01-11 09:25:33 +00:00
|
|
|
/* this length excludes the terminating null character. */
|
|
|
|
*mbslen = mlen;
|
2009-01-06 04:40:25 +00:00
|
|
|
|
2009-01-11 09:25:33 +00:00
|
|
|
/* returns the number of characters handled.
|
|
|
|
* if the function has encountered an illegal character in
|
|
|
|
* the while loop above, wcs[p-wcs] will not be a null character */
|
|
|
|
return p - wcs;
|
2009-01-06 04:40:25 +00:00
|
|
|
}
|
|
|
|
|
2009-01-11 09:25:33 +00:00
|
|
|
qse_size_t qse_wcsntombsnlen (
|
|
|
|
const qse_wchar_t* wcs, qse_size_t wcslen, qse_size_t* mbslen)
|
2009-01-06 04:40:25 +00:00
|
|
|
{
|
|
|
|
const qse_wchar_t* p = wcs;
|
2009-01-11 09:25:33 +00:00
|
|
|
const qse_wchar_t* end = wcs + wcslen;
|
2009-01-08 08:14:06 +00:00
|
|
|
qse_mchar_t mbs[32];
|
2009-01-06 04:40:25 +00:00
|
|
|
qse_size_t mlen = 0;
|
|
|
|
|
2009-01-11 09:25:33 +00:00
|
|
|
while (p < end)
|
2009-01-06 04:40:25 +00:00
|
|
|
{
|
|
|
|
qse_size_t n = qse_wctomb (*p, mbs, QSE_COUNTOF(mbs));
|
|
|
|
if (n == 0) break; /* illegal character */
|
|
|
|
|
|
|
|
/* it assumes that mbs is large enough to hold a character */
|
|
|
|
QSE_ASSERT (n <= QSE_COUNTOF(mbs));
|
|
|
|
|
|
|
|
p++; mlen += n;
|
|
|
|
}
|
|
|
|
|
2009-01-08 04:26:55 +00:00
|
|
|
/* this length excludes the terminating null character. */
|
2009-01-06 04:40:25 +00:00
|
|
|
*mbslen = mlen;
|
2008-10-21 05:13:55 +00:00
|
|
|
|
2009-01-08 04:26:55 +00:00
|
|
|
/* returns the number of characters handled.
|
|
|
|
* if the function has encountered an illegal character in
|
|
|
|
* the while loop above, wcs[p-wcs] will not be a null character */
|
|
|
|
return p - wcs;
|
2008-10-18 05:43:20 +00:00
|
|
|
}
|
|
|
|
|
2009-01-11 09:25:33 +00:00
|
|
|
qse_size_t qse_wcstombs (
|
|
|
|
const qse_wchar_t* wcs, qse_mchar_t* mbs, qse_size_t* mbslen)
|
|
|
|
{
|
|
|
|
const qse_wchar_t* p = wcs;
|
|
|
|
qse_size_t rem = *mbslen;
|
|
|
|
|
|
|
|
while (*p != QSE_WT('\0') && rem > 1)
|
|
|
|
{
|
|
|
|
qse_size_t n = qse_wctomb (*p, mbs, rem);
|
|
|
|
if (n == 0 || n > rem)
|
|
|
|
{
|
|
|
|
/* illegal character or buffer not enough */
|
|
|
|
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++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*mbslen -= rem;
|
|
|
|
|
|
|
|
/* null-terminate the multibyte sequence if it has sufficient space */
|
|
|
|
if (rem > 0) *mbs = QSE_MT('\0');
|
|
|
|
|
|
|
|
/* returns the number of characters handled. */
|
|
|
|
return p - wcs;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t qse_wcsntombsn (
|
|
|
|
const qse_wchar_t* wcs, qse_size_t wcslen,
|
|
|
|
qse_mchar_t* mbs, qse_size_t* mbslen)
|
2008-10-18 05:43:20 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
const qse_wchar_t* p = wcs;
|
|
|
|
const qse_wchar_t* end = wcs + wcslen;
|
|
|
|
qse_size_t len = *mbslen;
|
2008-10-18 05:43:20 +00:00
|
|
|
|
|
|
|
while (p < end && len > 0)
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t n = qse_wctomb (*p, mbs, len);
|
2008-10-18 05:43:20 +00:00
|
|
|
if (n == 0 || n > len)
|
|
|
|
{
|
|
|
|
/* illegal character or buffer not enough */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
mbs += n; len -= n; p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*mbslen -= len;
|
|
|
|
|
|
|
|
/* returns the number of characters handled.
|
|
|
|
* the caller can check if the return value is as large is wcslen
|
|
|
|
* for an error. */
|
|
|
|
return p - wcs;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
int qse_wcstombs_strict (
|
|
|
|
const qse_wchar_t* wcs, qse_mchar_t* mbs, qse_size_t mbslen)
|
2008-11-27 03:05:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t n;
|
|
|
|
qse_size_t mn = mbslen;
|
2008-11-27 03:05:00 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
n = qse_wcstombs (wcs, mbs, &mn);
|
2009-01-06 04:40:25 +00:00
|
|
|
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 -1;
|
|
|
|
}
|
2008-11-27 03:05:00 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|