- Notifications
You must be signed in to change notification settings - Fork 8.5k
/
Copy pathdbcs.cpp
128 lines (115 loc) · 3.46 KB
/
dbcs.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include"precomp.h"
#include"dbcs.h"
#include"misc.h"
#include"../types/inc/convert.hpp"
#include"../interactivity/inc/ServiceLocator.hpp"
#pragma hdrstop
using Microsoft::Console::Interactivity::ServiceLocator;
// Routine Description:
// - This routine check bisected on Ascii string end.
// Arguments:
// - pchBuf - Pointer to Ascii string buffer.
// - cbBuf - Number of Ascii string.
// Return Value:
// - TRUE - Bisected character.
// - FALSE - Correctly.
boolCheckBisectStringA(_In_reads_bytes_(cbBuf) PCHAR pchBuf, _In_ DWORD cbBuf, const CPINFO* const pCPInfo)
{
while (cbBuf)
{
if (IsDBCSLeadByteConsole(*pchBuf, pCPInfo))
{
if (cbBuf <= 1)
{
returntrue;
}
else
{
pchBuf += 2;
cbBuf -= 2;
}
}
else
{
pchBuf++;
cbBuf--;
}
}
returnfalse;
}
// Routine Description:
// - Checks if a char is a lead byte for a given code page.
// Arguments:
// - ch - the char to check.
// - pCPInfo - the code page to check the char in.
// Return Value:
// true if ch is a lead byte, false otherwise.
boolIsDBCSLeadByteConsole(const CHAR ch, const CPINFO* const pCPInfo)
{
FAIL_FAST_IF_NULL(pCPInfo);
// NOTE: This must be unsigned for the comparison. If we compare signed, this will never hit
// because lead bytes are ironically enough always above 0x80 (signed char negative range).
constauto uchComparison = (unsignedchar)ch;
auto i = 0;
// this is ok because the array is guaranteed to have 2
// null bytes at the end.
while (pCPInfo->LeadByte[i])
{
if (pCPInfo->LeadByte[i] <= uchComparison && uchComparison <= pCPInfo->LeadByte[i + 1])
{
returntrue;
}
i += 2;
}
returnfalse;
}
BYTE CodePageToCharSet(const UINT uiCodePage)
{
CHARSETINFO csi{};
if (!TranslateCharsetInfo((DWORD*)IntToPtr(uiCodePage), &csi, TCI_SRCCODEPAGE))
{
// On OneCore-based editions of Windows, the extension apiset containing
// TranslateCharsetInfo is not hosted. OneCoreUAP hosts it, but the lower
// editions do not. If we find that we failed to delay-load it, fall back
// to our "simple" OneCore-OK implementation.
if (GetLastError() == ERROR_PROC_NOT_FOUND)
{
switch (uiCodePage)
{
case CP_JAPANESE:
csi.ciCharset = SHIFTJIS_CHARSET;
break;
case CP_CHINESE_SIMPLIFIED:
csi.ciCharset = GB2312_CHARSET;
break;
case CP_KOREAN:
csi.ciCharset = HANGEUL_CHARSET;
break;
case CP_CHINESE_TRADITIONAL:
csi.ciCharset = CHINESEBIG5_CHARSET;
break;
}
}
else
{
csi.ciCharset = OEM_CHARSET;
}
}
return (BYTE)csi.ciCharset;
}
BOOL IsAvailableEastAsianCodePage(const UINT uiCodePage)
{
constauto CharSet = CodePageToCharSet(uiCodePage);
switch (CharSet)
{
case SHIFTJIS_CHARSET:
case HANGEUL_CHARSET:
case CHINESEBIG5_CHARSET:
case GB2312_CHARSET:
returntrue;
default:
returnfalse;
}
}