148 lines
3.4 KiB
C
148 lines
3.4 KiB
C
/*
|
|
* $Id$
|
|
*
|
|
Copyright 2006-2014 Chung, Hyung-Hwan.
|
|
This file is part of H2.
|
|
|
|
H2 is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as
|
|
published by the Free Software Foundation, either version 3 of
|
|
the License, or (at your option) any later version.
|
|
|
|
H2 is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with H2. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <h2/cmn/utf16.h>
|
|
|
|
#define LEAD_SURROGATE_MIN 0xD800lu
|
|
#define LEAD_SURROGATE_MAX 0xDBFFlu
|
|
#define TRAIL_SURROGATE_MIN 0xDC00lu
|
|
#define TRAIL_SURROGATE_MAX 0xDFFFlu
|
|
|
|
#define IS_SURROGATE(x) ((x) >= LEAD_SURROGATE_MIN && (x) <= TRAIL_SURROGATE_MAX)
|
|
#define IS_LEAD_SURROGATE(x) ((x) >= LEAD_SURROGATE_MIN && (x) <= LEAD_SURROGATE_MAX)
|
|
#define IS_TRAIL_SURROGATE(x) ((x) >= TRAIL_SURROGATE_MIN && (x) <= TRAIL_SURROGATE_MAX)
|
|
|
|
h2_size_t h2_uctoutf16 (h2_wxchar_t uc, h2_wchar_t* utf16, h2_size_t size)
|
|
{
|
|
#if (H2_SIZEOF_WXCHAR_T > H2_SIZEOF_WCHAR_T)
|
|
|
|
/*if (IS_SURROGATE(uc)) return 0;*/ /* illegal character */
|
|
|
|
if (uc <= 0xFFFFlu)
|
|
{
|
|
if (utf16 && size >= 1) *utf16 = uc;
|
|
return 1;
|
|
}
|
|
if (uc >= 0x10000lu && uc <= 0x10FFFlu)
|
|
{
|
|
if (utf16 && size >= 2)
|
|
{
|
|
h2_uint32_t tmp;
|
|
tmp = uc - 0x10000lu;
|
|
utf16[0] = LEAD_SURROGATE_MIN | (tmp >> 10);
|
|
utf16[1] = TRAIL_SURROGATE_MIN | (tmp & 0x3FFlu);
|
|
}
|
|
|
|
return 2;
|
|
}
|
|
else
|
|
{
|
|
return 0; /* illegal character */
|
|
}
|
|
|
|
#elif (H2_SIZEOF_WXCHAR_T == H2_SIZEOF_WCHAR_T)
|
|
|
|
/*if (IS_SURROGATE(uc)) return 0;*/ /* illegal character */
|
|
|
|
/* ucs2 is assumed in this case */
|
|
if (utf16 && size >= 1) *utf16 = uc;
|
|
|
|
/* small buffer is also indicated by this return value
|
|
* greater than 'size'. */
|
|
return 1;
|
|
|
|
#else
|
|
# error Unsupported size of h2_wxchar_t
|
|
#endif
|
|
}
|
|
|
|
h2_size_t h2_utf16touc (
|
|
const h2_wchar_t* utf16, h2_size_t size, h2_wxchar_t* uc)
|
|
{
|
|
H2_ASSERT (utf16 != H2_NULL);
|
|
H2_ASSERT (size > 0);
|
|
|
|
#if (H2_SIZEOF_WXCHAR_T > H2_SIZEOF_WCHAR_T)
|
|
|
|
if (IS_LEAD_SURROGATE(utf16[0]))
|
|
{
|
|
if (size >= 2)
|
|
{
|
|
if (IS_TRAIL_SURROGATE(utf16[1]))
|
|
{
|
|
if (uc)
|
|
{
|
|
h2_uint32_t tmp = 0x10000lu;
|
|
tmp += (utf16[0] & 0x3FFlu) << 10;
|
|
tmp += (utf16[1] & 0x3FFlu);
|
|
*uc = tmp;
|
|
}
|
|
|
|
/* this return value can indicate both
|
|
* the correct length (size >= 2)
|
|
* and
|
|
* the incomplete seqeunce error (size < 2).
|
|
*/
|
|
return 2;
|
|
}
|
|
else
|
|
{
|
|
return 0; /* invalid sequence */
|
|
}
|
|
}
|
|
else return 2; /* this should indicate the incomplete sequence */
|
|
}
|
|
else if (IS_TRAIL_SURROGATE(utf16[0]))
|
|
{
|
|
return 0; /* invalid sequence */
|
|
}
|
|
else
|
|
{
|
|
if (uc) *uc = utf16[0];
|
|
return 1;
|
|
}
|
|
|
|
#elif (H2_SIZEOF_WXCHAR_T == H2_SIZEOF_WCHAR_T)
|
|
|
|
/*if (IS_SURROGATE(utf16[0])) return 0;*/ /* illegal character */
|
|
|
|
/* ucs2 is assumed in this case */
|
|
if (uc) *uc = utf16[0];
|
|
|
|
/* small buffer is also indicated by this return value
|
|
* greater than 'size'. */
|
|
return 1;
|
|
|
|
#else
|
|
# error Unsupported size of h2_wxchar_t
|
|
#endif
|
|
}
|
|
|
|
h2_size_t h2_utf16len (const h2_wchar_t* utf16, h2_size_t size)
|
|
{
|
|
return h2_utf16touc (utf16, size, H2_NULL);
|
|
}
|
|
|
|
h2_size_t h2_utf16lenmax (void)
|
|
{
|
|
return H2_UTF16LEN_MAX;
|
|
}
|
|
|