📄 pgpunicode.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 Networks Associates Technology, Inc.
All rights reserved.
pgpUnicode.c - cross-platform Unicode conversion calls
$Id: pgpUnicode.c,v 1.7 2002/11/12 04:46:20 ajivsov Exp $
____________________________________________________________________________*/
#include "pgpUnicode.h"
#if PGP_OSX || PGP_UNIX
#define NULL ((void *)0)
#endif
/*____________________________________________________________________________
* Convert a string from Unicode UTF-8 to UCS-2. This doesn't call
* into any system functions and thus is secure.
*
* The output will be Null-terminated, if there is room in the output
* buffer. The output length does not include the terminating Null.
* If the input string is not a valid UTF-8 string, the output length
* will be returned as zero and the return value will indicate the
* position of the invalid character in the input string.
*
* If the input string is Null-terminated, you can avoid calculating
* the length and just pass in kPGPUnicodeNullTerminated for uLenUTF8.
*
* You can pass in NULL for wszWide if you don't want the output, but
* just want to get the output length (for allocating buffers, etc.).
*
* You can pass in NULL for puLenOut if you don't care about the output
* length.
*
* The return value is the number of bytes used from the input string.
* If there is an error in the conversion, the return value is the
* byte offset of the first offending character in the input string.
*/
PGPUInt32
pgpUTF8StringToUCS2 (
const char* pszUTF8,
PGPUInt32 uLenUTF8,
PGPUInt16* wszWide,
PGPUInt32 uMaxLenWide,
PGPUInt32* puLenOut)
{
const unsigned char* psrc = pszUTF8;
PGPUInt16* pdst = wszWide;
PGPUInt32 uIn = 0;
PGPUInt32 uOut = 0;
PGPUInt16 u;
if (pdst == NULL)
uMaxLenWide = 0xFFFFFFFF;
if (psrc != NULL)
{
while ((*psrc) &&
(uIn < uLenUTF8) &&
(uOut < uMaxLenWide))
{
u = 0;
if ((*psrc) < 0x80)
{
u = *psrc++;
uIn++;
}
else if ((*psrc) < 0xC0)
{
// invalid char
}
else if ((*psrc) < 0xE0)
{
u = (*psrc++) & 0x1F;
uIn++;
if ((*psrc & 0xC0) == 0x80)
{
u <<= 6;
u += (*psrc++) & 0x3F;
uIn++;
if (u < 0x80)
u = 0;
}
else
u = 0;
}
else if ((*psrc) < 0xF0)
{
u = (*psrc++) & 0x0F;
uIn++;
u <<= 6;
if ((*psrc & 0xC0) == 0x80)
{
u += (*psrc++) & 0x3F;
uIn++;
u <<= 6;
if ((*psrc & 0xC0) == 0x80)
{
u += (*psrc++) & 0x3F;
uIn++;
if (u < 0x800)
u = 0;
}
else
u = 0;
}
else
u = 0;
}
else
{
// too many bits to hold in a UCS-2 char
}
if (u)
{
if (pdst != NULL)
*pdst++ = u;
uOut++;
}
else
{
// invalid character or NULL
uOut = 0;
break;
}
}
if (uOut < uMaxLenWide)
{
if (pdst != NULL)
*pdst = 0;
}
}
if (puLenOut)
*puLenOut = uOut;
return uIn;
}
/*____________________________________________________________________________
* Convert a string from Unicode UCS-2 to UTF-8. This doesn't call
* into any system functions and thus is secure.
*
* The output will be Null-terminated, if there is room in the outpub
* buffer. The output length does not include the terminating Null.
*
* If the input string is Null-terminated, you can avoid calculating
* the length and just pass in kPGPUnicodeNullTerminated for uLenWide.
*
* You can pass in Null for pszUTF8 if you don't want the output, but
* just want to get the output length (for allocating buffers, etc.).
*
* You can pass in Null for puLenOut if you don't care about the output
* length.
*
* The return value is the number of wide chars used from the input string.
*/
PGPUInt32
pgpUCS2StringToUTF8 (
PGPUInt16* wszWide,
PGPUInt32 uLenWide,
char* pszUTF8,
PGPUInt32 uMaxLenUTF8,
PGPUInt32* puLenOut)
{
PGPUInt16* psrc = wszWide;
unsigned char* pdst = pszUTF8;
PGPUInt32 uIn = 0;
PGPUInt32 uOut = 0;
PGPUInt32 uBytes;
PGPUInt16 u;
PGPByte b[3];
if (pdst == NULL)
{
if (psrc != NULL)
{
// just count the number of bytes necessary
while ((*psrc) &&
(uIn < uLenWide))
{
if ((*psrc) < 0x0080)
uOut += 1;
else if ((*psrc) < 0x0800)
uOut += 2;
else
uOut += 3;
psrc++;
uIn++;
}
}
if (puLenOut)
*puLenOut = uOut;
return uIn;
}
if (psrc != NULL)
{
while ((*psrc) &&
(uIn < uLenWide) &&
(uOut < uMaxLenUTF8))
{
if ((*psrc) < 0x0080)
{
b[0] = (PGPByte)(*psrc++);
uBytes = 1;
}
else if ((*psrc) < 0x0800)
{
u = *psrc++;
b[0] = 0xC0 | (u >> 6);
b[1] = 0x80 | (u & 0x003F);
uBytes = 2;
}
else
{
u = *psrc++;
b[0] = 0xE0 | (u >> 12);
b[1] = 0x80 | ((u >> 6) & 0x003F);
b[2] = 0x80 | (u & 0x003F);
uBytes = 3;
}
uIn++;
if ((uOut + uBytes) < uMaxLenUTF8)
{
for (u=0; u<uBytes; u++)
*pdst++ = b[u];
uOut += uBytes;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -