More unicode preparations.
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1515 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -743,6 +743,10 @@ SOURCE=..\sc2code\libs\strings\strings.c
|
|||||||
|
|
||||||
SOURCE=..\sc2code\libs\strings\strintrn.h
|
SOURCE=..\sc2code\libs\strings\strintrn.h
|
||||||
# End Source File
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\sc2code\libs\strings\unicode.c
|
||||||
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "video"
|
# Begin Group "video"
|
||||||
|
|
||||||
|
|||||||
+48
-30
@@ -188,8 +188,8 @@ add_text (int status, PTEXT pTextIn)
|
|||||||
TEXT locText;
|
TEXT locText;
|
||||||
PTEXT pText;
|
PTEXT pText;
|
||||||
SIZE leading;
|
SIZE leading;
|
||||||
UNICODE ch;
|
wchar_t ch;
|
||||||
const UNICODE *pStr;
|
const unsigned char *pStr;
|
||||||
SIZE text_width;
|
SIZE text_width;
|
||||||
int num_lines = 0;
|
int num_lines = 0;
|
||||||
static COORD last_baseline;
|
static COORD last_baseline;
|
||||||
@@ -238,13 +238,16 @@ add_text (int status, PTEXT pTextIn)
|
|||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case -3:
|
case -3:
|
||||||
SetContextForeGroundColor (BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
|
SetContextForeGroundColor (
|
||||||
|
BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
|
||||||
break;
|
break;
|
||||||
case -2:
|
case -2:
|
||||||
SetContextForeGroundColor (BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03));
|
SetContextForeGroundColor (
|
||||||
|
BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03));
|
||||||
break;
|
break;
|
||||||
case -1:
|
case -1:
|
||||||
SetContextForeGroundColor (BUILD_COLOR (MAKE_RGB15 (0x1A, 0x1A, 0x1A), 0x12));
|
SetContextForeGroundColor (
|
||||||
|
BUILD_COLOR (MAKE_RGB15 (0x1A, 0x1A, 0x1A), 0x12));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,8 +255,7 @@ add_text (int status, PTEXT pTextIn)
|
|||||||
locText = *pTextIn;
|
locText = *pTextIn;
|
||||||
locText.baseline.x -= 8;
|
locText.baseline.x -= 8;
|
||||||
locText.CharCount = 1;
|
locText.CharCount = 1;
|
||||||
ch = '*';
|
locText.pStr = "*";
|
||||||
locText.pStr = &ch;
|
|
||||||
font_DrawText (&locText);
|
font_DrawText (&locText);
|
||||||
|
|
||||||
locText = *pTextIn;
|
locText = *pTextIn;
|
||||||
@@ -264,7 +266,8 @@ add_text (int status, PTEXT pTextIn)
|
|||||||
numchars = 0;
|
numchars = 0;
|
||||||
pStr = pText->pStr;
|
pStr = pText->pStr;
|
||||||
|
|
||||||
if (status > 0 && (CommData.AlienTextTemplate.valign & (VALIGN_MIDDLE|VALIGN_BOTTOM))) {
|
if (status > 0 && (CommData.AlienTextTemplate.valign & (
|
||||||
|
VALIGN_MIDDLE|VALIGN_BOTTOM))) {
|
||||||
num_lines = _count_lines(pText);
|
num_lines = _count_lines(pText);
|
||||||
if (CommData.AlienTextTemplate.valign == VALIGN_BOTTOM)
|
if (CommData.AlienTextTemplate.valign == VALIGN_BOTTOM)
|
||||||
pText->baseline.y -= (leading * num_lines);
|
pText->baseline.y -= (leading * num_lines);
|
||||||
@@ -276,38 +279,55 @@ add_text (int status, PTEXT pTextIn)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
pText->pStr = pStr;
|
pText->pStr = pStr;
|
||||||
pText->CharCount = 1;
|
|
||||||
pText->baseline.y += leading;
|
pText->baseline.y += leading;
|
||||||
|
|
||||||
{
|
{
|
||||||
BOOLEAN eot;
|
BOOLEAN eot;
|
||||||
RECT r, old_r;
|
RECT r, old_r;
|
||||||
COUNT OldCount;
|
COUNT oldCount;
|
||||||
|
const unsigned char *oldPStr;
|
||||||
|
wchar_t oldCh;
|
||||||
|
COUNT charCount;
|
||||||
|
|
||||||
GetContextClipRect (&r);
|
GetContextClipRect (&r);
|
||||||
eot = FALSE;
|
oldCount = 1;
|
||||||
do
|
charCount = 0;
|
||||||
|
ch = '\0';
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
old_r = r;
|
old_r = r;
|
||||||
OldCount = pText->CharCount;
|
oldPStr = pStr;
|
||||||
while (!(eot = (BOOLEAN)(
|
oldCh = ch;
|
||||||
(ch = *++pStr) == '\0'
|
|
||||||
|| ch == '\n'
|
for (;;)
|
||||||
|| ch == '\r'
|
{
|
||||||
|| (COUNT)(pStr - pText->pStr) >= maxchars
|
ch = getCharFromString (&pStr);
|
||||||
)) && ch != ' ')
|
eot = ch == '\0' || ch == '\n' || ch == '\r'
|
||||||
;
|
|| charCount >= maxchars;
|
||||||
pText->CharCount = pStr - pText->pStr;
|
if (eot || ch == ' ')
|
||||||
|
break;
|
||||||
|
charCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
oldCount = pText->CharCount;
|
||||||
|
pText->CharCount = charCount;
|
||||||
TextRect (pText, &r, NULL_PTR);
|
TextRect (pText, &r, NULL_PTR);
|
||||||
} while (!eot && r.extent.width < text_width);
|
if (eot || r.extent.width >= text_width)
|
||||||
|
break;
|
||||||
|
charCount++;
|
||||||
|
// For the space in between words.
|
||||||
|
}
|
||||||
|
|
||||||
if (r.extent.width >= text_width)
|
if (r.extent.width >= text_width)
|
||||||
{
|
{
|
||||||
pText->CharCount = OldCount;
|
pText->CharCount = oldCount;
|
||||||
|
pStr = oldPStr;
|
||||||
r = old_r;
|
r = old_r;
|
||||||
|
ch = oldCh;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxchars -= pText->CharCount)
|
maxchars -= pText->CharCount;
|
||||||
|
if (maxchars != 0)
|
||||||
--maxchars;
|
--maxchars;
|
||||||
numchars += pText->CharCount;
|
numchars += pText->CharCount;
|
||||||
|
|
||||||
@@ -316,8 +336,7 @@ add_text (int status, PTEXT pTextIn)
|
|||||||
if (pText->baseline.y < SIS_SCREEN_HEIGHT)
|
if (pText->baseline.y < SIS_SCREEN_HEIGHT)
|
||||||
font_DrawText (pText);
|
font_DrawText (pText);
|
||||||
|
|
||||||
pStr = pText->pStr + pText->CharCount;
|
if (status < -4 && pText->baseline.y >= -status - 10)
|
||||||
if(status < -4 && pText->baseline.y >= -status - 10)
|
|
||||||
{
|
{
|
||||||
++pStr;
|
++pStr;
|
||||||
break;
|
break;
|
||||||
@@ -346,11 +365,9 @@ add_text (int status, PTEXT pTextIn)
|
|||||||
|
|
||||||
--pText->baseline.y;
|
--pText->baseline.y;
|
||||||
font_DrawText (pText);
|
font_DrawText (pText);
|
||||||
|
|
||||||
pStr = pText->pStr + pText->CharCount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ((ch = *pStr++) != '\0' && ch != '\n' && ch != '\r' && maxchars);
|
} while (ch != '\0' && ch != '\n' && ch != '\r' && maxchars);
|
||||||
pText->pStr = pStr;
|
pText->pStr = pStr;
|
||||||
|
|
||||||
if (status == 1)
|
if (status == 1)
|
||||||
@@ -363,7 +380,8 @@ add_text (int status, PTEXT pTextIn)
|
|||||||
// restores background
|
// restores background
|
||||||
TFB_DrawScreen_Copy (&r, TFB_SCREEN_EXTRA, TFB_SCREEN_MAIN);
|
TFB_DrawScreen_Copy (&r, TFB_SCREEN_EXTRA, TFB_SCREEN_MAIN);
|
||||||
// draws cached subtitle
|
// draws cached subtitle
|
||||||
TFB_DrawScreen_Image (subtitle_cache, r.corner.x, r.corner.y, 0, 0, TFB_SCREEN_MAIN);
|
TFB_DrawScreen_Image (subtitle_cache, r.corner.x, r.corner.y, 0, 0,
|
||||||
|
TFB_SCREEN_MAIN);
|
||||||
|
|
||||||
last_baseline = pText->baseline.y;
|
last_baseline = pText->baseline.y;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
extern FRAME Build_Font_Effect (FRAME FramePtr, DWORD from, DWORD to,
|
extern FRAME Build_Font_Effect (FRAME FramePtr, DWORD from, DWORD to,
|
||||||
BYTE type);
|
BYTE type);
|
||||||
static wchar_t getNextChar(const unsigned char **ptr);
|
|
||||||
static inline FRAME_DESC *getCharFrame (FONT_DESC *fontPtr, wchar_t ch);
|
static inline FRAME_DESC *getCharFrame (FONT_DESC *fontPtr, wchar_t ch);
|
||||||
|
|
||||||
static BYTE char_delta_array[MAX_DELTAS];
|
static BYTE char_delta_array[MAX_DELTAS];
|
||||||
@@ -134,28 +133,37 @@ GetContextFontLeading (PSIZE pheight)
|
|||||||
BOOLEAN
|
BOOLEAN
|
||||||
TextRect (PTEXT lpText, PRECT pRect, PBYTE pdelta)
|
TextRect (PTEXT lpText, PRECT pRect, PBYTE pdelta)
|
||||||
{
|
{
|
||||||
COUNT num_chars;
|
|
||||||
FONTPTR FontPtr;
|
FONTPTR FontPtr;
|
||||||
|
|
||||||
if ((FontPtr = _CurFontPtr) != 0 && (num_chars = lpText->CharCount))
|
FontPtr = _CurFontPtr;
|
||||||
|
if (FontPtr != 0 && lpText->CharCount != 0)
|
||||||
{
|
{
|
||||||
COORD top_y, bot_y;
|
COORD top_y, bot_y;
|
||||||
SIZE width;
|
SIZE width;
|
||||||
wchar_t next_ch;
|
wchar_t next_ch;
|
||||||
const unsigned char *pStr;
|
const unsigned char *pStr;
|
||||||
|
COUNT num_chars;
|
||||||
|
|
||||||
|
num_chars = lpText->CharCount;
|
||||||
|
/* At this point lpText->CharCount contains the *maximum* number of
|
||||||
|
* characters that lpText->pStr may contain.
|
||||||
|
* After the while loop below, it will contain the actual number.
|
||||||
|
*/
|
||||||
if (pdelta == 0)
|
if (pdelta == 0)
|
||||||
{
|
{
|
||||||
pdelta = char_delta_array;
|
pdelta = char_delta_array;
|
||||||
if (num_chars > MAX_DELTAS)
|
if (num_chars > MAX_DELTAS)
|
||||||
|
{
|
||||||
num_chars = MAX_DELTAS;
|
num_chars = MAX_DELTAS;
|
||||||
|
lpText->CharCount = MAX_DELTAS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
top_y = 0;
|
top_y = 0;
|
||||||
bot_y = 0;
|
bot_y = 0;
|
||||||
width = 0;
|
width = 0;
|
||||||
pStr = lpText->pStr;
|
pStr = lpText->pStr;
|
||||||
next_ch = getNextChar (&pStr);
|
next_ch = getCharFromString (&pStr);
|
||||||
if (next_ch == '\0')
|
if (next_ch == '\0')
|
||||||
num_chars = 0;
|
num_chars = 0;
|
||||||
while (num_chars--)
|
while (num_chars--)
|
||||||
@@ -167,9 +175,12 @@ TextRect (PTEXT lpText, PRECT pRect, PBYTE pdelta)
|
|||||||
last_width = width;
|
last_width = width;
|
||||||
|
|
||||||
ch = next_ch;
|
ch = next_ch;
|
||||||
next_ch = getNextChar (&pStr);
|
next_ch = getCharFromString (&pStr);
|
||||||
if (next_ch == '\0')
|
if (next_ch == '\0')
|
||||||
|
{
|
||||||
|
lpText->CharCount -= num_chars;
|
||||||
num_chars = 0;
|
num_chars = 0;
|
||||||
|
}
|
||||||
|
|
||||||
charFrame = getCharFrame (FontPtr, ch);
|
charFrame = getCharFrame (FontPtr, ch);
|
||||||
if (charFrame != NULL && GetFrameWidth (charFrame))
|
if (charFrame != NULL && GetFrameWidth (charFrame))
|
||||||
@@ -195,8 +206,6 @@ TextRect (PTEXT lpText, PRECT pRect, PBYTE pdelta)
|
|||||||
*pdelta++ = (BYTE)(width - last_width);
|
*pdelta++ = (BYTE)(width - last_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
lpText->CharCount = pStr - lpText->pStr - 1;
|
|
||||||
|
|
||||||
if (width > 0 && (bot_y -= top_y) > 0)
|
if (width > 0 && (bot_y -= top_y) > 0)
|
||||||
{
|
{
|
||||||
/* subtract off default character spacing */
|
/* subtract off default character spacing */
|
||||||
@@ -258,7 +267,7 @@ _text_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
|
|||||||
num_chars = TextPtr->CharCount;
|
num_chars = TextPtr->CharCount;
|
||||||
|
|
||||||
pStr = TextPtr->pStr;
|
pStr = TextPtr->pStr;
|
||||||
next_ch = getNextChar (&pStr);
|
next_ch = getCharFromString (&pStr);
|
||||||
if (next_ch == '\0')
|
if (next_ch == '\0')
|
||||||
num_chars = 0;
|
num_chars = 0;
|
||||||
while (num_chars--)
|
while (num_chars--)
|
||||||
@@ -266,7 +275,7 @@ _text_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
|
|||||||
wchar_t ch;
|
wchar_t ch;
|
||||||
|
|
||||||
ch = next_ch;
|
ch = next_ch;
|
||||||
next_ch = getNextChar (&pStr);
|
next_ch = getCharFromString (&pStr);
|
||||||
if (next_ch == '\0')
|
if (next_ch == '\0')
|
||||||
num_chars = 0;
|
num_chars = 0;
|
||||||
|
|
||||||
@@ -320,99 +329,3 @@ getCharFrame (FONT_DESC *fontPtr, wchar_t ch) {
|
|||||||
return &fontPtr->CharDesc[ch - FIRST_CHAR];
|
return &fontPtr->CharDesc[ch - FIRST_CHAR];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get one character from a UTF-8 encoded string.
|
|
||||||
// *ptr will point to the start of the next character.
|
|
||||||
// Returns 0 if the encoding is bad. This can be distinguished from the
|
|
||||||
// '\0' character by checking whether **ptr == '\0'.
|
|
||||||
static wchar_t
|
|
||||||
getNextChar(const unsigned char **ptr) {
|
|
||||||
wchar_t result;
|
|
||||||
|
|
||||||
if (**ptr < 0x80) {
|
|
||||||
// 0xxxxxxx, regular ASCII
|
|
||||||
result = **ptr;
|
|
||||||
(*ptr)++;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((**ptr & 0xe0) == 0xc0) {
|
|
||||||
// 110xxxxx; 10xxxxxx must follow
|
|
||||||
// Value between 0x00000080 and 0x0000007f (inclusive)
|
|
||||||
result = **ptr & 0x1f;
|
|
||||||
(*ptr)++;
|
|
||||||
|
|
||||||
if ((**ptr & 0xc0) != 0x80)
|
|
||||||
goto err;
|
|
||||||
result = (result << 6) | ((**ptr) & 0x3f);
|
|
||||||
(*ptr)++;
|
|
||||||
|
|
||||||
if (result < 0x00000080) {
|
|
||||||
// invalid encoding - must reject
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((**ptr & 0xf0) == 0xe0) {
|
|
||||||
// 1110xxxx; 10xxxxxx 10xxxxxx must follow
|
|
||||||
// Value between 0x00000800 and 0x000007ff (inclusive)
|
|
||||||
result = **ptr & 0x0f;
|
|
||||||
(*ptr)++;
|
|
||||||
|
|
||||||
if ((**ptr & 0xc0) != 0x80)
|
|
||||||
goto err;
|
|
||||||
result = (result << 6) | ((**ptr) & 0x3f);
|
|
||||||
(*ptr)++;
|
|
||||||
|
|
||||||
if ((**ptr & 0xc0) != 0x80)
|
|
||||||
goto err;
|
|
||||||
result = (result << 6) | ((**ptr) & 0x3f);
|
|
||||||
(*ptr)++;
|
|
||||||
|
|
||||||
if (result < 0x00000800) {
|
|
||||||
// invalid encoding - must reject
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((**ptr & 0xf8) == 0xf0) {
|
|
||||||
// 11110xxx; 10xxxxxx 10xxxxxx 10xxxxxx must follow
|
|
||||||
// Value between 0x00010000 and 0x0010ffff (inclusive)
|
|
||||||
result = **ptr & 0x07;
|
|
||||||
(*ptr)++;
|
|
||||||
|
|
||||||
if ((**ptr & 0xc0) != 0x80)
|
|
||||||
goto err;
|
|
||||||
result = (result << 6) | ((**ptr) & 0x3f);
|
|
||||||
(*ptr)++;
|
|
||||||
|
|
||||||
if ((**ptr & 0xc0) != 0x80)
|
|
||||||
goto err;
|
|
||||||
result = (result << 6) | ((**ptr) & 0x3f);
|
|
||||||
(*ptr)++;
|
|
||||||
|
|
||||||
if ((**ptr & 0xc0) != 0x80)
|
|
||||||
goto err;
|
|
||||||
result = (result << 6) | ((**ptr) & 0x3f);
|
|
||||||
(*ptr)++;
|
|
||||||
|
|
||||||
if (result < 0x00010000) {
|
|
||||||
// invalid encoding - must reject
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
err:
|
|
||||||
fprintf(stderr, "Warning: Invalid UTF8 sequence.\n");
|
|
||||||
|
|
||||||
// Resynchronise (skip everything starting with 0x10xxxxxx):
|
|
||||||
while ((**ptr & 0xc0) == 0x80)
|
|
||||||
*ptr++;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
uqm_CFILES="getstr.c sfileins.c sresins.c strings.c"
|
uqm_CFILES="getstr.c sfileins.c sresins.c strings.c unicode.c"
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// Get one character from a UTF-8 encoded string.
|
||||||
|
// *ptr will point to the start of the next character.
|
||||||
|
// Returns 0 if the encoding is bad. This can be distinguished from the
|
||||||
|
// '\0' character by checking whether **ptr == '\0'.
|
||||||
|
wchar_t
|
||||||
|
getCharFromString(const unsigned char **ptr) {
|
||||||
|
wchar_t result;
|
||||||
|
|
||||||
|
if (**ptr < 0x80) {
|
||||||
|
// 0xxxxxxx, regular ASCII
|
||||||
|
result = **ptr;
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((**ptr & 0xe0) == 0xc0) {
|
||||||
|
// 110xxxxx; 10xxxxxx must follow
|
||||||
|
// Value between 0x00000080 and 0x0000007f (inclusive)
|
||||||
|
result = **ptr & 0x1f;
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if ((**ptr & 0xc0) != 0x80)
|
||||||
|
goto err;
|
||||||
|
result = (result << 6) | ((**ptr) & 0x3f);
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if (result < 0x00000080) {
|
||||||
|
// invalid encoding - must reject
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((**ptr & 0xf0) == 0xe0) {
|
||||||
|
// 1110xxxx; 10xxxxxx 10xxxxxx must follow
|
||||||
|
// Value between 0x00000800 and 0x000007ff (inclusive)
|
||||||
|
result = **ptr & 0x0f;
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if ((**ptr & 0xc0) != 0x80)
|
||||||
|
goto err;
|
||||||
|
result = (result << 6) | ((**ptr) & 0x3f);
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if ((**ptr & 0xc0) != 0x80)
|
||||||
|
goto err;
|
||||||
|
result = (result << 6) | ((**ptr) & 0x3f);
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if (result < 0x00000800) {
|
||||||
|
// invalid encoding - must reject
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((**ptr & 0xf8) == 0xf0) {
|
||||||
|
// 11110xxx; 10xxxxxx 10xxxxxx 10xxxxxx must follow
|
||||||
|
// Value between 0x00010000 and 0x0010ffff (inclusive)
|
||||||
|
result = **ptr & 0x07;
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if ((**ptr & 0xc0) != 0x80)
|
||||||
|
goto err;
|
||||||
|
result = (result << 6) | ((**ptr) & 0x3f);
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if ((**ptr & 0xc0) != 0x80)
|
||||||
|
goto err;
|
||||||
|
result = (result << 6) | ((**ptr) & 0x3f);
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if ((**ptr & 0xc0) != 0x80)
|
||||||
|
goto err;
|
||||||
|
result = (result << 6) | ((**ptr) & 0x3f);
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if (result < 0x00010000) {
|
||||||
|
// invalid encoding - must reject
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
|
fprintf(stderr, "Warning: Invalid UTF8 sequence.\n");
|
||||||
|
|
||||||
|
// Resynchronise (skip everything starting with 0x10xxxxxx):
|
||||||
|
while ((**ptr & 0xc0) == 0x80)
|
||||||
|
*ptr++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -48,5 +48,8 @@ extern STRINGPTR GetStringTimeStamp (STRING String);
|
|||||||
extern BOOLEAN GetStringContents (STRING String, STRINGPTR StringBuf,
|
extern BOOLEAN GetStringContents (STRING String, STRINGPTR StringBuf,
|
||||||
BOOLEAN AppendSpace);
|
BOOLEAN AppendSpace);
|
||||||
|
|
||||||
|
wchar_t getCharFromString(const unsigned char **ptr);
|
||||||
|
|
||||||
#endif /* _STRLIB_H */
|
#endif /* _STRLIB_H */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user