2011-12-30 14:44:21 +00:00
|
|
|
/*
|
2011-12-31 15:24:48 +00:00
|
|
|
* $Id$
|
2011-12-30 14:44:21 +00:00
|
|
|
*
|
2019-06-06 05:28:23 +00:00
|
|
|
Copyright (c) 2006-2019 Chung, Hyung-Hwan. All rights reserved.
|
2014-11-19 14:42:24 +00:00
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions
|
|
|
|
are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in the
|
|
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
|
|
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2011-12-30 14:44:21 +00:00
|
|
|
*/
|
|
|
|
|
2011-12-31 15:24:48 +00:00
|
|
|
#include <qse/cmn/mbwc.h>
|
2016-04-29 03:55:42 +00:00
|
|
|
#include "mem-prv.h"
|
2011-12-30 14:44:21 +00:00
|
|
|
|
2012-01-15 15:25:28 +00:00
|
|
|
static int mbsn_to_wcsn_with_cmgr (
|
2011-12-30 14:44:21 +00:00
|
|
|
const qse_mchar_t* mbs, qse_size_t* mbslen,
|
2012-01-15 15:25:28 +00:00
|
|
|
qse_wchar_t* wcs, qse_size_t* wcslen, qse_cmgr_t* cmgr, int all);
|
|
|
|
|
|
|
|
static int mbs_to_wcs_with_cmgr (
|
|
|
|
const qse_mchar_t* mbs, qse_size_t* mbslen,
|
|
|
|
qse_wchar_t* wcs, qse_size_t* wcslen, qse_cmgr_t* cmgr, int all)
|
2011-12-30 14:44:21 +00:00
|
|
|
{
|
|
|
|
const qse_mchar_t* mp;
|
|
|
|
qse_size_t mlen, wlen;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
for (mp = mbs; *mp != QSE_MT('\0'); mp++);
|
|
|
|
|
|
|
|
mlen = mp - mbs; wlen = *wcslen;
|
2019-03-14 08:01:04 +00:00
|
|
|
n = mbsn_to_wcsn_with_cmgr(mbs, &mlen, wcs, &wlen, cmgr, all);
|
2011-12-30 14:44:21 +00:00
|
|
|
if (wcs)
|
|
|
|
{
|
|
|
|
if (wlen < *wcslen) wcs[wlen] = QSE_WT('\0');
|
|
|
|
else n = -2; /* buffer too small */
|
|
|
|
}
|
|
|
|
*mbslen = mlen; *wcslen = wlen;
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2012-01-15 15:25:28 +00:00
|
|
|
int qse_mbstowcswithcmgr (
|
|
|
|
const qse_mchar_t* mbs, qse_size_t* mbslen,
|
|
|
|
qse_wchar_t* wcs, qse_size_t* wcslen, qse_cmgr_t* cmgr)
|
|
|
|
{
|
2019-03-14 08:01:04 +00:00
|
|
|
return mbs_to_wcs_with_cmgr(mbs, mbslen, wcs, wcslen, cmgr, 0);
|
2012-01-15 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int qse_mbstowcsallwithcmgr (
|
2011-12-30 14:44:21 +00:00
|
|
|
const qse_mchar_t* mbs, qse_size_t* mbslen,
|
|
|
|
qse_wchar_t* wcs, qse_size_t* wcslen, qse_cmgr_t* cmgr)
|
2012-01-15 15:25:28 +00:00
|
|
|
{
|
2019-03-14 08:01:04 +00:00
|
|
|
return mbs_to_wcs_with_cmgr(mbs, mbslen, wcs, wcslen, cmgr, 1);
|
2012-01-15 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int mbsn_to_wcsn_with_cmgr (
|
|
|
|
const qse_mchar_t* mbs, qse_size_t* mbslen,
|
|
|
|
qse_wchar_t* wcs, qse_size_t* wcslen, qse_cmgr_t* cmgr, int all)
|
2011-12-30 14:44:21 +00:00
|
|
|
{
|
|
|
|
const qse_mchar_t* p;
|
|
|
|
int ret = 0;
|
|
|
|
qse_size_t mlen;
|
|
|
|
|
|
|
|
if (wcs)
|
|
|
|
{
|
|
|
|
qse_wchar_t* q, * qend;
|
|
|
|
|
|
|
|
p = mbs;
|
|
|
|
q = wcs;
|
|
|
|
qend = wcs + *wcslen;
|
|
|
|
mlen = *mbslen;
|
|
|
|
|
|
|
|
while (mlen > 0)
|
|
|
|
{
|
|
|
|
qse_size_t n;
|
|
|
|
|
|
|
|
if (q >= qend)
|
|
|
|
{
|
|
|
|
/* buffer too small */
|
|
|
|
ret = -2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-03-14 08:01:04 +00:00
|
|
|
n = cmgr->mbtowc(p, mlen, q);
|
2011-12-30 14:44:21 +00:00
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
/* invalid sequence */
|
2012-01-15 15:25:28 +00:00
|
|
|
if (all)
|
|
|
|
{
|
|
|
|
n = 1;
|
|
|
|
*q = QSE_WT('?');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = -1;
|
|
|
|
break;
|
|
|
|
}
|
2011-12-30 14:44:21 +00:00
|
|
|
}
|
|
|
|
if (n > mlen)
|
|
|
|
{
|
|
|
|
/* incomplete sequence */
|
2012-01-15 15:25:28 +00:00
|
|
|
if (all)
|
|
|
|
{
|
|
|
|
n = 1;
|
|
|
|
*q = QSE_WT('?');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = -3;
|
|
|
|
break;
|
|
|
|
}
|
2011-12-30 14:44:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
q++;
|
|
|
|
p += n;
|
|
|
|
mlen -= n;
|
|
|
|
}
|
|
|
|
|
|
|
|
*wcslen = q - wcs;
|
|
|
|
*mbslen = p - mbs;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
qse_wchar_t w;
|
|
|
|
qse_size_t wlen = 0;
|
|
|
|
|
|
|
|
p = mbs;
|
|
|
|
mlen = *mbslen;
|
|
|
|
|
|
|
|
while (mlen > 0)
|
|
|
|
{
|
|
|
|
qse_size_t n;
|
|
|
|
|
2020-08-28 09:37:46 +00:00
|
|
|
n = cmgr->mbtowc(p, mlen, &w);
|
2011-12-30 14:44:21 +00:00
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
/* invalid sequence */
|
2012-01-15 15:25:28 +00:00
|
|
|
if (all) n = 1;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = -1;
|
|
|
|
break;
|
|
|
|
}
|
2011-12-30 14:44:21 +00:00
|
|
|
}
|
|
|
|
if (n > mlen)
|
|
|
|
{
|
|
|
|
/* incomplete sequence */
|
2012-01-15 15:25:28 +00:00
|
|
|
if (all) n = 1;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = -3;
|
|
|
|
break;
|
|
|
|
}
|
2011-12-30 14:44:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
p += n;
|
|
|
|
mlen -= n;
|
|
|
|
wlen += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*wcslen = wlen;
|
|
|
|
*mbslen = p - mbs;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-01-15 15:25:28 +00:00
|
|
|
int qse_mbsntowcsnwithcmgr (
|
|
|
|
const qse_mchar_t* mbs, qse_size_t* mbslen,
|
|
|
|
qse_wchar_t* wcs, qse_size_t* wcslen, qse_cmgr_t* cmgr)
|
|
|
|
{
|
2019-03-14 08:01:04 +00:00
|
|
|
return mbsn_to_wcsn_with_cmgr(mbs, mbslen, wcs, wcslen, cmgr, 0);
|
2012-01-15 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int qse_mbsntowcsnallwithcmgr (
|
|
|
|
const qse_mchar_t* mbs, qse_size_t* mbslen,
|
|
|
|
qse_wchar_t* wcs, qse_size_t* wcslen, qse_cmgr_t* cmgr)
|
|
|
|
{
|
2019-03-14 08:01:04 +00:00
|
|
|
return mbsn_to_wcsn_with_cmgr(mbs, mbslen, wcs, wcslen, cmgr, 1);
|
2012-01-15 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
2011-12-30 14:44:21 +00:00
|
|
|
int qse_mbsntowcsnuptowithcmgr (
|
|
|
|
const qse_mchar_t* mbs, qse_size_t* mbslen,
|
|
|
|
qse_wchar_t* wcs, qse_size_t* wcslen, qse_wchar_t stopper, qse_cmgr_t* cmgr)
|
|
|
|
{
|
|
|
|
const qse_mchar_t* p;
|
|
|
|
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 = cmgr->mbtowc (p, mlen, &w);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2012-10-29 14:41:39 +00:00
|
|
|
static qse_wchar_t* mbsn_to_wcs_dup_with_cmgr (
|
|
|
|
const qse_mchar_t* mbs, qse_size_t* mbslen, qse_size_t* wcslen,
|
|
|
|
qse_mmgr_t* mmgr, qse_cmgr_t* cmgr, int all)
|
|
|
|
{
|
|
|
|
qse_size_t ml, wl;
|
|
|
|
qse_wchar_t* wcs;
|
|
|
|
|
|
|
|
ml = *mbslen;
|
2019-03-14 08:01:04 +00:00
|
|
|
if (mbsn_to_wcsn_with_cmgr(mbs, &ml, QSE_NULL, &wl, cmgr, all) <= -1) return QSE_NULL;
|
2012-10-29 14:41:39 +00:00
|
|
|
|
|
|
|
wl++; /* for terminating null */
|
2019-08-27 14:52:19 +00:00
|
|
|
wcs = (qse_wchar_t*)QSE_MMGR_ALLOC(mmgr, wl * QSE_SIZEOF(*wcs));
|
|
|
|
if (!wcs) return QSE_NULL;
|
2012-10-29 14:41:39 +00:00
|
|
|
|
|
|
|
mbsn_to_wcsn_with_cmgr (mbs, mbslen, wcs, &wl, cmgr, all);
|
|
|
|
wcs[wl] = QSE_WT('\0');
|
|
|
|
|
|
|
|
if (wcslen) *wcslen = wl;
|
|
|
|
return wcs;
|
|
|
|
}
|
|
|
|
|
2019-04-15 15:36:23 +00:00
|
|
|
qse_wchar_t* qse_mbsntowcsdupwithcmgr (const qse_mchar_t* mbs, qse_size_t* mbslen, qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
|
2012-10-29 14:41:39 +00:00
|
|
|
{
|
|
|
|
return mbsn_to_wcs_dup_with_cmgr (mbs, mbslen, wcslen, mmgr, cmgr, 0);
|
|
|
|
}
|
|
|
|
|
2019-04-15 15:36:23 +00:00
|
|
|
qse_wchar_t* qse_mbsntowcsalldupwithcmgr (const qse_mchar_t* mbs, qse_size_t* mbslen, qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
|
2012-10-29 14:41:39 +00:00
|
|
|
{
|
|
|
|
return mbsn_to_wcs_dup_with_cmgr (mbs, mbslen, wcslen, mmgr, cmgr, 1);
|
|
|
|
}
|
|
|
|
|
2019-04-15 15:36:23 +00:00
|
|
|
static qse_wchar_t* mbs_to_wcs_dup_with_cmgr (const qse_mchar_t* mbs, qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr, int all)
|
2011-12-30 14:44:21 +00:00
|
|
|
{
|
2012-10-18 06:52:03 +00:00
|
|
|
qse_size_t ml, wl;
|
2011-12-30 14:44:21 +00:00
|
|
|
qse_wchar_t* wcs;
|
|
|
|
|
2019-08-27 14:52:19 +00:00
|
|
|
if (mbs_to_wcs_with_cmgr(mbs, &ml, QSE_NULL, &wl, cmgr, all) <= -1) return QSE_NULL;
|
2011-12-30 14:44:21 +00:00
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
wl++; /* for terminating null */
|
2019-08-27 14:52:19 +00:00
|
|
|
wcs = (qse_wchar_t*)QSE_MMGR_ALLOC(mmgr, wl * QSE_SIZEOF(*wcs));
|
|
|
|
if (!wcs) return QSE_NULL;
|
2011-12-30 14:44:21 +00:00
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
mbs_to_wcs_with_cmgr (mbs, &ml, wcs, &wl, cmgr, all);
|
|
|
|
|
|
|
|
if (wcslen) *wcslen = wl;
|
2011-12-30 14:44:21 +00:00
|
|
|
return wcs;
|
|
|
|
}
|
|
|
|
|
2019-08-27 14:52:19 +00:00
|
|
|
qse_wchar_t* qse_mbstowcsdupwithcmgr (const qse_mchar_t* mbs, qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
|
2012-01-15 15:25:28 +00:00
|
|
|
{
|
2020-08-28 09:37:46 +00:00
|
|
|
return mbs_to_wcs_dup_with_cmgr(mbs, wcslen, mmgr, cmgr, 0);
|
2012-01-15 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 14:52:19 +00:00
|
|
|
qse_wchar_t* qse_mbstowcsalldupwithcmgr (const qse_mchar_t* mbs, qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
|
2012-01-15 15:25:28 +00:00
|
|
|
{
|
2020-08-28 09:37:46 +00:00
|
|
|
return mbs_to_wcs_dup_with_cmgr(mbs, wcslen, mmgr, cmgr, 1);
|
2012-01-15 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 14:52:19 +00:00
|
|
|
static qse_wchar_t* mbsa_to_wcs_dup_with_cmgr (const qse_mchar_t* mbs[], qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr, int all)
|
2011-12-30 14:44:21 +00:00
|
|
|
{
|
2012-10-18 06:52:03 +00:00
|
|
|
qse_wchar_t* buf;
|
2011-12-30 14:44:21 +00:00
|
|
|
qse_size_t i;
|
2012-10-18 06:52:03 +00:00
|
|
|
qse_size_t capa, pos;
|
2011-12-30 14:44:21 +00:00
|
|
|
qse_size_t wl, ml;
|
|
|
|
|
|
|
|
QSE_ASSERT (mmgr != QSE_NULL);
|
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
for (capa = 0, i = 0; mbs[i]; i++)
|
2011-12-30 14:44:21 +00:00
|
|
|
{
|
2012-01-15 15:25:28 +00:00
|
|
|
if (mbs_to_wcs_with_cmgr (mbs[i], &ml, QSE_NULL, &wl, cmgr, all) <= -1)
|
|
|
|
return QSE_NULL;
|
2011-12-30 14:44:21 +00:00
|
|
|
capa += wl;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf = (qse_wchar_t*) QSE_MMGR_ALLOC (
|
|
|
|
mmgr, (capa + 1) * QSE_SIZEOF(*buf));
|
|
|
|
if (buf == QSE_NULL) return QSE_NULL;
|
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
for (pos = 0, i = 0; mbs[i]; i++)
|
2011-12-30 14:44:21 +00:00
|
|
|
{
|
2012-10-18 06:52:03 +00:00
|
|
|
wl = capa - pos + 1;
|
|
|
|
mbs_to_wcs_with_cmgr (mbs[i], &ml, &buf[pos], &wl, cmgr, all);
|
|
|
|
pos += wl;
|
2011-12-30 14:44:21 +00:00
|
|
|
}
|
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
QSE_ASSERT (pos == capa);
|
|
|
|
|
|
|
|
if (wcslen) *wcslen = capa;
|
2011-12-30 14:44:21 +00:00
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
2019-08-27 14:52:19 +00:00
|
|
|
qse_wchar_t* qse_mbsatowcsdupwithcmgr (const qse_mchar_t* mbs[], qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
|
2012-01-15 15:25:28 +00:00
|
|
|
{
|
2020-08-28 09:37:46 +00:00
|
|
|
return mbsa_to_wcs_dup_with_cmgr(mbs, wcslen, mmgr, cmgr, 0);
|
2012-01-15 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 14:52:19 +00:00
|
|
|
qse_wchar_t* qse_mbsatowcsalldupwithcmgr (const qse_mchar_t* mbs[], qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
|
2012-01-15 15:25:28 +00:00
|
|
|
{
|
2020-08-28 09:37:46 +00:00
|
|
|
return mbsa_to_wcs_dup_with_cmgr(mbs, wcslen, mmgr, cmgr, 1);
|
2012-01-15 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ======================================================================== */
|
|
|
|
|
2011-12-30 14:44:21 +00:00
|
|
|
int qse_wcstombswithcmgr (
|
|
|
|
const qse_wchar_t* wcs, qse_size_t* wcslen,
|
|
|
|
qse_mchar_t* mbs, qse_size_t* mbslen, qse_cmgr_t* cmgr)
|
|
|
|
{
|
|
|
|
const qse_wchar_t* p = wcs;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (mbs)
|
|
|
|
{
|
|
|
|
qse_size_t rem = *mbslen;
|
|
|
|
|
|
|
|
while (*p != QSE_WT('\0'))
|
|
|
|
{
|
|
|
|
qse_size_t n;
|
|
|
|
|
|
|
|
if (rem <= 0)
|
|
|
|
{
|
|
|
|
ret = -2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
n = cmgr->wctomb (*p, mbs, rem);
|
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
ret = -1;
|
|
|
|
break; /* illegal character */
|
|
|
|
}
|
|
|
|
if (n > rem)
|
|
|
|
{
|
|
|
|
ret = -2;
|
|
|
|
break; /* buffer too small */
|
|
|
|
}
|
|
|
|
|
|
|
|
mbs += n; rem -= n; p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* update mbslen to the length of the mbs string converted excluding
|
|
|
|
* terminating null */
|
|
|
|
*mbslen -= rem;
|
|
|
|
|
|
|
|
/* null-terminate the multibyte sequence if it has sufficient space */
|
|
|
|
if (rem > 0) *mbs = QSE_MT('\0');
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* if ret is -2 and wcs[wcslen] == QSE_WT('\0'),
|
|
|
|
* this means that the mbs buffer was lacking one
|
|
|
|
* slot for the terminating null */
|
|
|
|
ret = -2; /* buffer too small */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
qse_mchar_t mbsbuf[QSE_MBLEN_MAX];
|
|
|
|
qse_size_t mlen = 0;
|
|
|
|
|
|
|
|
while (*p != QSE_WT('\0'))
|
|
|
|
{
|
|
|
|
qse_size_t n;
|
|
|
|
|
2019-05-07 07:39:49 +00:00
|
|
|
n = cmgr->wctomb(*p, mbsbuf, QSE_COUNTOF(mbsbuf));
|
2011-12-30 14:44:21 +00:00
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
ret = -1;
|
|
|
|
break; /* illegal character */
|
|
|
|
}
|
|
|
|
|
2019-05-07 07:39:49 +00:00
|
|
|
/* it assumes that mbsbuf is large enough to hold a character.
|
|
|
|
* since mbsbuf is of the QSE_MBLEN_MAX size, the return value
|
|
|
|
* must not exceed the size of mbsbuf. */
|
|
|
|
QSE_ASSERT (n <= QSE_COUNTOF(mbsbuf));
|
2011-12-30 14:44:21 +00:00
|
|
|
|
|
|
|
p++; mlen += n;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this length holds the number of resulting multi-byte characters
|
|
|
|
* excluding the terminating null character */
|
|
|
|
*mbslen = mlen;
|
|
|
|
}
|
|
|
|
|
|
|
|
*wcslen = p - wcs; /* the number of wide characters handled. */
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int qse_wcsntombsnwithcmgr (
|
|
|
|
const qse_wchar_t* wcs, qse_size_t* wcslen,
|
|
|
|
qse_mchar_t* mbs, qse_size_t* mbslen, qse_cmgr_t* cmgr)
|
|
|
|
{
|
|
|
|
const qse_wchar_t* p = wcs;
|
|
|
|
const qse_wchar_t* end = wcs + *wcslen;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (mbs)
|
|
|
|
{
|
|
|
|
qse_size_t rem = *mbslen;
|
|
|
|
|
|
|
|
while (p < end)
|
|
|
|
{
|
|
|
|
qse_size_t n;
|
|
|
|
|
|
|
|
if (rem <= 0)
|
|
|
|
{
|
|
|
|
ret = -2; /* buffer too small */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
n = cmgr->wctomb (*p, mbs, rem);
|
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
ret = -1;
|
|
|
|
break; /* illegal character */
|
|
|
|
}
|
|
|
|
if (n > rem)
|
|
|
|
{
|
|
|
|
ret = -2; /* buffer too small */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
mbs += n; rem -= n; p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*mbslen -= rem;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
qse_mchar_t mbsbuf[QSE_MBLEN_MAX];
|
|
|
|
qse_size_t mlen = 0;
|
|
|
|
|
|
|
|
while (p < end)
|
|
|
|
{
|
|
|
|
qse_size_t n;
|
|
|
|
|
|
|
|
n = cmgr->wctomb (*p, mbsbuf, QSE_COUNTOF(mbsbuf));
|
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
ret = -1;
|
|
|
|
break; /* illegal character */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* it assumes that mbs is large enough to hold a character */
|
|
|
|
QSE_ASSERT (n <= QSE_COUNTOF(mbsbuf));
|
|
|
|
|
|
|
|
p++; mlen += n;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this length excludes the terminating null character.
|
|
|
|
* this function doesn't event null-terminate the result. */
|
|
|
|
*mbslen = mlen;
|
|
|
|
}
|
|
|
|
|
|
|
|
*wcslen = p - wcs;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
qse_mchar_t* qse_wcstombsdupwithcmgr (
|
|
|
|
const qse_wchar_t* wcs, qse_size_t* mbslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
|
2011-12-30 14:44:21 +00:00
|
|
|
{
|
2012-10-18 06:52:03 +00:00
|
|
|
qse_size_t wl, ml;
|
2011-12-30 14:44:21 +00:00
|
|
|
qse_mchar_t* mbs;
|
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
if (qse_wcstombswithcmgr (wcs, &wl, QSE_NULL, &ml, cmgr) <= -1) return QSE_NULL;
|
2011-12-30 14:44:21 +00:00
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
ml++; /* for the terminating null character */
|
2011-12-30 14:44:21 +00:00
|
|
|
|
2019-08-28 14:01:28 +00:00
|
|
|
mbs = QSE_MMGR_ALLOC(mmgr, ml * QSE_SIZEOF(*mbs));
|
2011-12-30 14:44:21 +00:00
|
|
|
if (mbs == QSE_NULL) return QSE_NULL;
|
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
qse_wcstombswithcmgr (wcs, &wl, mbs, &ml, cmgr);
|
|
|
|
|
|
|
|
if (mbslen) *mbslen = ml;
|
2011-12-30 14:44:21 +00:00
|
|
|
return mbs;
|
|
|
|
}
|
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
qse_mchar_t* qse_wcsntombsdupwithcmgr (
|
|
|
|
const qse_wchar_t* wcs, qse_size_t wcslen,
|
|
|
|
qse_size_t* mbslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
|
2012-09-30 13:56:20 +00:00
|
|
|
{
|
2019-08-28 14:01:28 +00:00
|
|
|
qse_size_t wl, ml;
|
2012-09-30 13:56:20 +00:00
|
|
|
qse_mchar_t* mbs;
|
|
|
|
|
2019-08-28 14:01:28 +00:00
|
|
|
wl = wcslen;
|
|
|
|
if (qse_wcsntombsnwithcmgr(wcs, &wl, QSE_NULL, &ml, cmgr) <= -1) return QSE_NULL;
|
2012-09-30 13:56:20 +00:00
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
mbs = QSE_MMGR_ALLOC (mmgr, (ml + 1) * QSE_SIZEOF(*mbs));
|
2012-09-30 13:56:20 +00:00
|
|
|
if (mbs == QSE_NULL) return QSE_NULL;
|
|
|
|
|
2019-08-28 14:01:28 +00:00
|
|
|
wl = wcslen;
|
|
|
|
qse_wcsntombsnwithcmgr (wcs, &wl, mbs, &ml, cmgr);
|
2012-10-18 06:52:03 +00:00
|
|
|
mbs[ml] = QSE_MT('\0');
|
|
|
|
|
|
|
|
if (mbslen) *mbslen = ml;
|
2012-09-30 13:56:20 +00:00
|
|
|
return mbs;
|
|
|
|
}
|
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
qse_mchar_t* qse_wcsatombsdupwithcmgr (
|
|
|
|
const qse_wchar_t* wcs[], qse_size_t* mbslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
|
2011-12-30 14:44:21 +00:00
|
|
|
{
|
2012-10-18 06:52:03 +00:00
|
|
|
qse_size_t wl, ml, capa, pos, i;
|
|
|
|
qse_mchar_t* mbs;
|
2011-12-30 14:44:21 +00:00
|
|
|
|
|
|
|
QSE_ASSERT (mmgr != QSE_NULL);
|
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
for (capa = 0, i = 0; wcs[i]; i++)
|
2011-12-30 14:44:21 +00:00
|
|
|
{
|
|
|
|
if (qse_wcstombswithcmgr (wcs[i], &wl, QSE_NULL, &ml, cmgr) <= -1) return QSE_NULL;
|
|
|
|
capa += ml;
|
|
|
|
}
|
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
mbs = (qse_mchar_t*) QSE_MMGR_ALLOC (mmgr, (capa + 1) * QSE_SIZEOF(*mbs));
|
|
|
|
if (mbs == QSE_NULL) return QSE_NULL;
|
2011-12-30 14:44:21 +00:00
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
for (pos = 0, i = 0; wcs[i]; i++)
|
2011-12-30 14:44:21 +00:00
|
|
|
{
|
2012-10-18 06:52:03 +00:00
|
|
|
ml = capa - pos + 1;
|
|
|
|
qse_wcstombswithcmgr (wcs[i], &wl, &mbs[pos], &ml, cmgr);
|
|
|
|
pos += ml;
|
2011-12-30 14:44:21 +00:00
|
|
|
}
|
|
|
|
|
2012-10-18 06:52:03 +00:00
|
|
|
if (mbslen) *mbslen = capa;
|
|
|
|
return mbs;
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_mchar_t* qse_wcsnatombsdupwithcmgr (
|
2014-07-08 14:30:42 +00:00
|
|
|
const qse_wcstr_t wcs[], qse_size_t* mbslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
|
2012-10-18 06:52:03 +00:00
|
|
|
{
|
|
|
|
qse_size_t wl, ml, capa, pos, i;
|
|
|
|
qse_mchar_t* mbs;
|
|
|
|
|
|
|
|
for (capa = 0, i = 0; wcs[i].ptr; i++)
|
|
|
|
{
|
|
|
|
wl = wcs[i].len;
|
|
|
|
if (qse_wcsntombsnwithcmgr (wcs[i].ptr, &wl, QSE_NULL, &ml, cmgr) <= -1) return QSE_NULL;
|
|
|
|
capa += ml;
|
|
|
|
}
|
|
|
|
|
|
|
|
mbs = QSE_MMGR_ALLOC (mmgr, (capa + 1) * QSE_SIZEOF(*mbs));
|
|
|
|
if (mbs == QSE_NULL) return QSE_NULL;
|
|
|
|
|
|
|
|
for (pos = 0, i = 0; wcs[i].ptr; i++)
|
|
|
|
{
|
|
|
|
wl = wcs[i].len;
|
|
|
|
ml = capa - pos + 1;
|
|
|
|
qse_wcsntombsnwithcmgr (wcs[i].ptr, &wl, &mbs[pos], &ml, cmgr);
|
|
|
|
pos += ml;
|
|
|
|
}
|
|
|
|
mbs[pos] = QSE_MT('\0');
|
|
|
|
|
|
|
|
QSE_ASSERT (pos == capa);
|
|
|
|
|
|
|
|
if (mbslen) *mbslen = capa;
|
|
|
|
return mbs;
|
2011-12-30 14:44:21 +00:00
|
|
|
}
|