📄 nls.c
字号:
/**
* @name IntMultiByteToWideCharCP
*
* Internal version of MultiByteToWideChar for code page tables.
*
* @see MultiByteToWideChar
* @todo Handle MB_PRECOMPOSED, MB_COMPOSITE, MB_USEGLYPHCHARS and
* DBCS codepages.
*/
static INT STDCALL
IntMultiByteToWideCharCP(UINT CodePage, DWORD Flags,
LPCSTR MultiByteString, INT MultiByteCount,
LPWSTR WideCharString, INT WideCharCount)
{
PCODEPAGE_ENTRY CodePageEntry;
PCPTABLEINFO CodePageTable;
LPCSTR TempString;
INT TempLength;
/* Get code page table. */
CodePageEntry = IntGetCodePageEntry(CodePage);
if (CodePageEntry == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
CodePageTable = &CodePageEntry->CodePageTable;
/* Different handling for DBCS code pages. */
if (CodePageTable->MaximumCharacterSize > 1)
{
/* FIXME */
UCHAR Char;
USHORT DBCSOffset;
LPCSTR MbsEnd = MultiByteString + MultiByteCount;
ULONG Count;
/* Does caller query for output buffer size? */
if (WideCharCount == 0)
{
for (; MultiByteString < MbsEnd; WideCharCount++)
{
Char = *MultiByteString++;
if (Char < 0x80)
continue;
DBCSOffset = CodePageTable->DBCSOffsets[Char];
if (!DBCSOffset)
continue;
if (MultiByteString < MbsEnd)
MultiByteString++;
}
return WideCharCount;
}
for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
{
Char = *MultiByteString++;
if (Char < 0x80)
{
*WideCharString++ = Char;
continue;
}
DBCSOffset = CodePageTable->DBCSOffsets[Char];
if (!DBCSOffset)
{
*WideCharString++ = CodePageTable->MultiByteTable[Char];
continue;
}
if (MultiByteString < MbsEnd)
*WideCharString++ =
CodePageTable->DBCSOffsets[DBCSOffset + *(PUCHAR)MultiByteString++];
}
if (MultiByteString < MbsEnd)
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return Count;
}
else /* Not DBCS code page */
{
/* Check for invalid characters. */
if (Flags & MB_ERR_INVALID_CHARS)
{
for (TempString = MultiByteString, TempLength = MultiByteCount;
TempLength > 0;
TempString++, TempLength--)
{
if (CodePageTable->MultiByteTable[(UCHAR)*TempString] ==
CodePageTable->UniDefaultChar &&
*TempString != CodePageEntry->CodePageTable.DefaultChar)
{
SetLastError(ERROR_NO_UNICODE_TRANSLATION);
return 0;
}
}
}
/* Does caller query for output buffer size? */
if (WideCharCount == 0)
return MultiByteCount;
/* Adjust buffer size. Wine trick ;-) */
if (WideCharCount < MultiByteCount)
{
MultiByteCount = WideCharCount;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
}
for (TempLength = MultiByteCount;
TempLength > 0;
MultiByteString++, TempLength--)
{
*WideCharString++ = CodePageTable->MultiByteTable[(UCHAR)*MultiByteString];
}
return MultiByteCount;
}
}
/**
* @name IntWideCharToMultiByteUTF8
*
* Internal version of WideCharToMultiByte for UTF8.
*
* @see WideCharToMultiByte
*/
static INT STDCALL
IntWideCharToMultiByteUTF8(UINT CodePage, DWORD Flags,
LPCWSTR WideCharString, INT WideCharCount,
LPSTR MultiByteString, INT MultiByteCount,
LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
{
INT TempLength;
WCHAR Char;
/* Does caller query for output buffer size? */
if (MultiByteCount == 0)
{
for (TempLength = 0; WideCharCount;
WideCharCount--, WideCharString++)
{
TempLength++;
if (*WideCharString >= 0x80)
{
TempLength++;
if (*WideCharString >= 0x800)
TempLength++;
}
}
return TempLength;
}
for (TempLength = MultiByteCount; WideCharCount;
WideCharCount--, WideCharString++)
{
Char = *WideCharString;
if (Char < 0x80)
{
if (!TempLength)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
}
TempLength--;
*MultiByteString++ = (CHAR)Char;
continue;
}
if (Char < 0x800) /* 0x80-0x7ff: 2 bytes */
{
if (TempLength < 2)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
}
MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
MultiByteString[0] = 0xc0 | Char;
MultiByteString += 2;
TempLength -= 2;
continue;
}
/* 0x800-0xffff: 3 bytes */
if (TempLength < 3)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
}
MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
MultiByteString[0] = 0xe0 | Char;
MultiByteString += 3;
TempLength -= 3;
}
return MultiByteCount - TempLength;
}
/**
* @name IntWideCharToMultiByteCP
*
* Internal version of WideCharToMultiByte for code page tables.
*
* @see WideCharToMultiByte
* @todo Handle default characters and flags.
*/
static INT STDCALL
IntWideCharToMultiByteCP(UINT CodePage, DWORD Flags,
LPCWSTR WideCharString, INT WideCharCount,
LPSTR MultiByteString, INT MultiByteCount,
LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
{
PCODEPAGE_ENTRY CodePageEntry;
PCPTABLEINFO CodePageTable;
INT TempLength;
/* Get code page table. */
CodePageEntry = IntGetCodePageEntry(CodePage);
if (CodePageEntry == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
CodePageTable = &CodePageEntry->CodePageTable;
/* Different handling for DBCS code pages. */
if (CodePageTable->MaximumCharacterSize > 1)
{
/* FIXME */
USHORT WideChar;
USHORT MbChar;
/* Does caller query for output buffer size? */
if (MultiByteCount == 0)
{
for (TempLength = 0; WideCharCount; WideCharCount--, TempLength++)
{
WideChar = *WideCharString++;
if (WideChar < 0x80)
continue;
MbChar = ((PWCHAR)CodePageTable->WideCharTable)[WideChar];
if (!(MbChar & 0xff00))
continue;
TempLength++;
}
return TempLength;
}
for (TempLength = MultiByteCount; WideCharCount; WideCharCount--)
{
WideChar = *WideCharString++;
if (WideChar < 0x80)
{
if (!TempLength)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
}
TempLength--;
*MultiByteString++ = (CHAR)WideChar;
continue;
}
MbChar = ((PWCHAR)CodePageTable->WideCharTable)[WideChar];
if (!(MbChar & 0xff00))
{
if (!TempLength)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
}
TempLength--;
*MultiByteString++ = (CHAR)MbChar;
continue;;
}
if (TempLength >= 2)
{
MultiByteString[1] = (CHAR)MbChar; MbChar >>= 8;
MultiByteString[0] = (CHAR)MbChar;
MultiByteString += 2;
TempLength -= 2;
}
else
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
}
}
return MultiByteCount - TempLength;
}
else /* Not DBCS code page */
{
/* Does caller query for output buffer size? */
if (MultiByteCount == 0)
return WideCharCount;
/* Adjust buffer size. Wine trick ;-) */
if (MultiByteCount < WideCharCount)
{
WideCharCount = MultiByteCount;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
}
for (TempLength = WideCharCount;
TempLength > 0;
WideCharString++, TempLength--)
{
*MultiByteString++ = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
}
/* FIXME */
if (UsedDefaultChar != NULL)
*UsedDefaultChar = FALSE;
return WideCharCount;
}
}
/**
* @name IntIsLeadByte
*
* Internal function to detect if byte is lead byte in specific character
* table.
*/
static BOOL STDCALL
IntIsLeadByte(PCPTABLEINFO TableInfo, BYTE Byte)
{
UINT LeadByteNo;
if (TableInfo->MaximumCharacterSize == 2)
{
for (LeadByteNo = 0; LeadByteNo < MAXIMUM_LEADBYTES; LeadByteNo++)
{
if (TableInfo->LeadByte[LeadByteNo] == Byte)
return TRUE;
}
}
return FALSE;
}
/* PUBLIC FUNCTIONS ***********************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -