You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
485 lines
12 KiB
485 lines
12 KiB
/*++
|
|
|
|
Copyright (c) 1991-1999, Microsoft Corporation All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
c_iscii.c
|
|
|
|
Abstract:
|
|
|
|
This file contains the main functions for this module.
|
|
|
|
External Routines in this file:
|
|
DllEntry
|
|
NlsDllCodePageTranslation
|
|
|
|
Revision History:
|
|
|
|
2-28-98 KChang Created.
|
|
|
|
--*/
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Conversions for Ten ISCII codepages
|
|
//
|
|
// 57002 : Devanagari
|
|
// 57003 : Bengali
|
|
// 57004 : Tamil
|
|
// 57005 : Telugu
|
|
// 57006 : Assamese (same as Bengali)
|
|
// 57007 : Oriya
|
|
// 57008 : Kannada
|
|
// 57009 : Malayalam
|
|
// 57010 : Gujarati
|
|
// 57011 : Punjabi (Gurmukhi)
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//
|
|
// Include Files.
|
|
//
|
|
|
|
#include <share.h>
|
|
#include "c_iscii.h"
|
|
|
|
|
|
|
|
|
|
//
|
|
// Forward Declarations.
|
|
//
|
|
|
|
DWORD MBToWC(
|
|
BYTE CP,
|
|
LPSTR lpMultiByteStr,
|
|
int cchMultiByte,
|
|
LPWSTR lpWideCharStr,
|
|
int cchWideChar);
|
|
|
|
DWORD WCToMB(
|
|
BYTE CP,
|
|
LPWSTR lpWideCharStr,
|
|
int cchWideChar,
|
|
LPSTR lpMBStr,
|
|
int cchMultiByte);
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------//
|
|
// DLL ENTRY POINT //
|
|
//-------------------------------------------------------------------------//
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DllEntry
|
|
//
|
|
// DLL Entry initialization procedure.
|
|
//
|
|
// 10-30-96 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL DllEntry(
|
|
HANDLE hModule,
|
|
DWORD dwReason,
|
|
LPVOID lpRes)
|
|
{
|
|
switch (dwReason)
|
|
{
|
|
case ( DLL_THREAD_ATTACH ) :
|
|
{
|
|
return (TRUE);
|
|
}
|
|
case ( DLL_THREAD_DETACH ) :
|
|
{
|
|
return (TRUE);
|
|
}
|
|
case ( DLL_PROCESS_ATTACH ) :
|
|
{
|
|
return (TRUE);
|
|
}
|
|
case ( DLL_PROCESS_DETACH ) :
|
|
{
|
|
return (TRUE);
|
|
}
|
|
}
|
|
|
|
return (FALSE);
|
|
hModule;
|
|
lpRes;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------//
|
|
// EXTERNAL ROUTINES //
|
|
//-------------------------------------------------------------------------//
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// NlsDllCodePageTranslation
|
|
//
|
|
// This routine is the main exported procedure for the functionality in
|
|
// this DLL. All calls to this DLL must go through this function.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
DWORD NlsDllCodePageTranslation(
|
|
DWORD CodePage,
|
|
DWORD dwFlags,
|
|
LPSTR lpMultiByteStr,
|
|
int cchMultiByte,
|
|
LPWSTR lpWideCharStr,
|
|
int cchWideChar,
|
|
LPCPINFO lpCPInfo)
|
|
{
|
|
BYTE CP;
|
|
|
|
if ((CodePage < 57002) || (CodePage > 57011))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return (0);
|
|
}
|
|
|
|
CP = (BYTE)(CodePage % 100);
|
|
|
|
switch (dwFlags)
|
|
{
|
|
case ( NLS_CP_CPINFO ) :
|
|
{
|
|
memset(lpCPInfo, 0, sizeof(CPINFO));
|
|
|
|
lpCPInfo->MaxCharSize = 4;
|
|
lpCPInfo->DefaultChar[0] = SUB;
|
|
|
|
//
|
|
// The lead-byte does not apply here, leave them all NULL.
|
|
//
|
|
return (TRUE);
|
|
}
|
|
case ( NLS_CP_MBTOWC ) :
|
|
{
|
|
if (cchMultiByte == -1)
|
|
{
|
|
cchMultiByte = strlen(lpMultiByteStr) + 1;
|
|
}
|
|
|
|
return (MBToWC( CP,
|
|
lpMultiByteStr,
|
|
cchMultiByte,
|
|
lpWideCharStr,
|
|
cchWideChar ));
|
|
}
|
|
case ( NLS_CP_WCTOMB ) :
|
|
{
|
|
int cchMBCount;
|
|
|
|
if (cchWideChar == -1)
|
|
{
|
|
cchWideChar = wcslen(lpWideCharStr) + 1;
|
|
}
|
|
|
|
cchMBCount = WCToMB( CP,
|
|
lpWideCharStr,
|
|
cchWideChar,
|
|
lpMultiByteStr,
|
|
cchMultiByte );
|
|
|
|
return (cchMBCount);
|
|
}
|
|
}
|
|
|
|
//
|
|
// This shouldn't happen since this function gets called by
|
|
// the NLS API routines.
|
|
//
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return (0);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------//
|
|
// INTERNAL ROUTINES //
|
|
//-------------------------------------------------------------------------//
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// MBToWC
|
|
//
|
|
// This routine does the translations from ISCII to Unicode.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
DWORD MBToWC(
|
|
BYTE CP,
|
|
LPSTR lpMultiByteStr,
|
|
int cchMultiByte,
|
|
LPWSTR lpWideCharStr,
|
|
int cchWideChar)
|
|
{
|
|
BYTE CurCP = CP;
|
|
int ctr;
|
|
int cchWCCount = 0;
|
|
LPWSTR lpWCTempStr;
|
|
|
|
//
|
|
// Allocate a buffer of the appropriate size.
|
|
// Use sizeof(WCHAR) because size could potentially double if
|
|
// the buffer contains all halfwidth Katakanas
|
|
//
|
|
lpWCTempStr = (LPWSTR)NLS_ALLOC_MEM(cchMultiByte * sizeof(WCHAR));
|
|
if (lpWCTempStr == NULL)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return (0);
|
|
}
|
|
|
|
for (ctr = 0; ctr < cchMultiByte; ctr++)
|
|
{
|
|
BYTE mb = (BYTE)lpMultiByteStr[ctr];
|
|
|
|
if (mb < MB_Beg)
|
|
{
|
|
lpWCTempStr[cchWCCount++] = (WCHAR)mb;
|
|
}
|
|
else if (mb == ATR)
|
|
{
|
|
if (ctr >= (cchMultiByte - 1))
|
|
{
|
|
//
|
|
// Incomplete ATR.
|
|
//
|
|
lpWCTempStr[cchWCCount++] = SUB;
|
|
}
|
|
else
|
|
{
|
|
BYTE mb1 = (BYTE)lpMultiByteStr[ctr + 1];
|
|
|
|
if ((mb1 < 0x40) || (mb1 > 0x4B))
|
|
{
|
|
lpWCTempStr[cchWCCount++] = SUB;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Bug #239926 10/29/00 WEIWU
|
|
// We don't support Roman script transliteration yet.
|
|
// To avoid invoking NULL table, we treat ATR code 0x41 as 0x40.
|
|
//
|
|
if (mb1 == 0x40 || mb1 == 0x41)
|
|
{
|
|
CurCP = CP;
|
|
}
|
|
else
|
|
{
|
|
CurCP = mb1 & 0x0F;
|
|
}
|
|
ctr++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WCHAR U1 = UniChar(CurCP, mb);
|
|
WCHAR U21 = TwoTo1U(CurCP, mb);
|
|
|
|
if (U21 == 0)
|
|
{
|
|
lpWCTempStr[cchWCCount++] = U1;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Possible two MBs to one Unicode.
|
|
//
|
|
if (ctr >= (cchMultiByte - 1))
|
|
{
|
|
lpWCTempStr[cchWCCount++] = U1;
|
|
}
|
|
else
|
|
{
|
|
BYTE mb1 = (BYTE)lpMultiByteStr[ctr + 1];
|
|
|
|
if (mb == VIRAMA)
|
|
{
|
|
lpWCTempStr[cchWCCount++] = U1;
|
|
if (mb1 == VIRAMA)
|
|
{
|
|
lpWCTempStr[cchWCCount++] = ZWNJ; // ZWNJ = U+200C
|
|
ctr++;
|
|
}
|
|
else if (mb1 == NUKTA)
|
|
{
|
|
lpWCTempStr[cchWCCount++] = ZWJ; // U+200D
|
|
ctr++;
|
|
}
|
|
}
|
|
else if ((U21 & 0xf000) == 0)
|
|
{
|
|
if (mb1 == SecondByte[1])
|
|
{
|
|
//
|
|
// NextByte == 0xe9 ?
|
|
//
|
|
lpWCTempStr[cchWCCount++] = U21;
|
|
ctr++;
|
|
}
|
|
else
|
|
{
|
|
lpWCTempStr[cchWCCount++] = U1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Devanagari EXT
|
|
//
|
|
if (mb1 == ExtMBList[0].mb) // 0xf0_0xb8
|
|
{
|
|
lpWCTempStr[cchWCCount++] = ExtMBList[0].wc; // U+0952
|
|
ctr++;
|
|
}
|
|
else if (mb1 == ExtMBList[1].mb) // 0xf0_0xbf
|
|
{
|
|
lpWCTempStr[cchWCCount++] = ExtMBList[1].wc; // U+0970
|
|
ctr++;
|
|
}
|
|
else
|
|
{
|
|
lpWCTempStr[cchWCCount++] = SUB;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cchWideChar)
|
|
{
|
|
if (cchWCCount > cchWideChar)
|
|
{
|
|
//
|
|
// Output buffer is too small.
|
|
//
|
|
NLS_FREE_MEM(lpWCTempStr);
|
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
|
return (0);
|
|
}
|
|
|
|
wcsncpy(lpWideCharStr, lpWCTempStr, cchWCCount);
|
|
}
|
|
|
|
NLS_FREE_MEM(lpWCTempStr);
|
|
return (cchWCCount);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// WCToMB
|
|
//
|
|
// This routine does the translations from Unicode to ISCII.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
DWORD WCToMB(
|
|
BYTE CP,
|
|
LPWSTR lpWideCharStr,
|
|
int cchWideChar,
|
|
LPSTR lpMBStr,
|
|
int cchMultiByte)
|
|
{
|
|
BYTE CurCP = CP;
|
|
int ctr;
|
|
int cchMBCount = 0;
|
|
LPSTR lpMBTmpStr;
|
|
|
|
lpMBTmpStr = (LPSTR)NLS_ALLOC_MEM(cchWideChar * 4);
|
|
if (lpMBTmpStr == NULL)
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return (0);
|
|
}
|
|
|
|
for (ctr = 0; ctr < cchWideChar; ctr++)
|
|
{
|
|
WCHAR wc = lpWideCharStr[ctr];
|
|
|
|
if (wc < (WCHAR)MB_Beg)
|
|
{
|
|
lpMBTmpStr[cchMBCount++] = (BYTE)wc;
|
|
}
|
|
else if ((wc < WC_Beg) || (wc > WC_End))
|
|
{
|
|
lpMBTmpStr[cchMBCount++] = SUB;
|
|
}
|
|
else
|
|
{
|
|
BYTE mb = MBChar(wc);
|
|
|
|
if ((Script(wc) != 0) && (Script(wc) != CurCP))
|
|
{
|
|
lpMBTmpStr[cchMBCount++] = (BYTE)ATR;
|
|
CurCP = Script(wc);
|
|
lpMBTmpStr[cchMBCount++] = CurCP | 0x40;
|
|
}
|
|
|
|
lpMBTmpStr[cchMBCount++] = mb;
|
|
|
|
if (mb == VIRAMA)
|
|
{
|
|
if (ctr < (cchMultiByte - 1))
|
|
{
|
|
WCHAR wc1 = lpWideCharStr[ctr + 1];
|
|
|
|
if (wc1 == ZWNJ)
|
|
{
|
|
lpMBTmpStr[cchMBCount++] = VIRAMA;
|
|
ctr++;
|
|
}
|
|
else if (wc1 == ZWJ)
|
|
{
|
|
lpMBTmpStr[cchMBCount++] = NUKTA;
|
|
ctr++;
|
|
}
|
|
}
|
|
}
|
|
else if (OneU_2M(wc) != 0)
|
|
{
|
|
lpMBTmpStr[cchMBCount++] = SecondByte[OneU_2M(wc) >> 12];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cchMultiByte)
|
|
{
|
|
if (cchMBCount > cchMultiByte)
|
|
{
|
|
//
|
|
// Output buffer is too small.
|
|
//
|
|
NLS_FREE_MEM(lpMBTmpStr);
|
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
|
return (0);
|
|
}
|
|
|
|
strncpy(lpMBStr, lpMBTmpStr, cchMBCount);
|
|
}
|
|
|
|
NLS_FREE_MEM(lpMBTmpStr);
|
|
return (cchMBCount);
|
|
}
|