windows-nt/Source/XPSP1/NT/base/win32/winnls/nlstrans/codepage.c

1422 lines
34 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1991-1999, Microsoft Corporation All rights reserved.
Module Name:
codepage.c
Abstract:
This file contains functions necessary to parse and write the code page
specific tables to a data file.
External Routines in this file:
ParseCodePage
WriteCodePage
Revision History:
12-10-91 JulieB Created.
03-10-00 lguindon Add explicit typecast to remove build errors
--*/
//
// Include Files.
//
#include "nlstrans.h"
//
// Forward Declarations.
//
int
GetMBTable(
PCODEPAGE pCP,
int Size);
int
GetGlyphTable(
PCODEPAGE pCP,
int Size);
int
GetDBCSRanges(
PCODEPAGE pCP,
int Size);
int
GetAllDBCSTables(
int NumTables,
PDBCS_TBL_ARRAY pArray);
int
GetDBCSTable(
int Size,
PDBCS_TBL pTable);
int
GetWCTable(
PCODEPAGE pCP,
int Size,
BOOL IsMBCodePage);
int
WriteCPInfo(
PCODEPAGE pCP,
FILE *pOutputFile);
int
WriteMB(
PCODEPAGE pCP,
FILE *pOutputFile);
int
WriteWC(
PCODEPAGE pCP,
BOOL IsMBCodePage,
FILE *pOutputFile);
void
FreeMB(
PCODEPAGE pCP);
int
GetTransDefaultChars(
PCODEPAGE pCP);
//-------------------------------------------------------------------------//
// EXTERNAL ROUTINES //
//-------------------------------------------------------------------------//
////////////////////////////////////////////////////////////////////////////
//
// ParseCodePage
//
// This routine parses the input file for the code page specific tables.
// This routine is only entered when the CODEPAGE keyword is found.
// The parsing continues until the ENDCODEPAGE keyword is found.
//
// 12-10-91 JulieB Created.
////////////////////////////////////////////////////////////////////////////
int ParseCodePage(
PCODEPAGE pCP,
PSZ pszKeyWord)
{
int size; // size of table to follow
int DefChar; // default character
int UniDefChar; // unicode default char
int NumItems; // number of items returned from fscanf
//
// Get CodePageValue parameter.
//
pCP->CodePageValue = atoi(pCP->pszName);
//
// Read in the rest of the code page information.
//
while (fscanf(pInputFile, "%s", pszKeyWord) == 1)
{
if (_stricmp(pszKeyWord, "CPINFO") == 0)
{
if (Verbose)
printf("\n\nFound CPINFO keyword.\n");
//
// Get MaxCharSize parameter.
// Get DefaultChar parameter.
// Get Unicode Translation of default char parameter.
//
NumItems = fscanf( pInputFile,
"%d %x %x ;%*[^\n]",
&size,
&DefChar,
&UniDefChar );
if ((NumItems != 3) || ((size != 1) && (size != 2)))
{
return (1);
}
pCP->MaxCharSize = size;
pCP->DefaultChar = (WORD)DefChar;
pCP->UniDefaultChar = (WORD)UniDefChar;
if (Verbose)
{
printf(" MAXCHARSIZE = %d\n", size);
printf(" DEFAULTCHAR = %x\n\n", DefChar);
printf(" UNICODE DEFAULT CHAR = %x\n\n", UniDefChar);
}
//
// Set WriteFlags for CPINFO Table.
//
pCP->WriteFlags |= F_CPINFO;
}
else if (_stricmp(pszKeyWord, "MBTABLE") == 0)
{
if (Verbose)
printf("\n\nFound MBTABLE keyword.\n");
//
// Get size parameter.
//
if (GetSize(&size))
return (1);
//
// Get MB table.
//
if (GetMBTable(pCP, size))
{
return (1);
}
//
// Set WriteFlags for MB Table.
//
pCP->WriteFlags |= F_MB;
}
else if (_stricmp(pszKeyWord, "GLYPHTABLE") == 0)
{
if (Verbose)
printf("\n\nFound GLYPHTABLE keyword.\n");
//
// Get size parameter.
//
if (GetSize(&size))
return (1);
//
// Get GLYPH table.
//
if (GetGlyphTable(pCP, size))
{
return (1);
}
//
// Set WriteFlags for GLYPH Table.
//
pCP->WriteFlags |= F_GLYPH;
}
else if (_stricmp(pszKeyWord, "DBCSRANGE") == 0)
{
if (Verbose)
printf("\n\nFound DBCSRANGE keyword.\n");
//
// Get size parameter.
//
if (GetSize(&size))
return (1);
//
// Get DBCS ranges and tables.
//
if (GetDBCSRanges(pCP, size))
{
return (1);
}
//
// Set WriteFlags for DBCS Table.
//
pCP->WriteFlags |= F_DBCS;
}
else if (_stricmp(pszKeyWord, "WCTABLE") == 0)
{
if (Verbose)
printf("\n\nFound WCTABLE keyword.\n");
//
// Get size parameter.
//
if (GetSize(&size))
return (1);
//
// Get WC Table.
//
if (GetWCTable( pCP,
size,
(pCP->MaxCharSize - 1) ))
{
return (1);
}
//
// Set WriteFlags for WC Table.
//
pCP->WriteFlags |= F_WC;
}
else if (_stricmp(pszKeyWord, "ENDCODEPAGE") == 0)
{
if (Verbose)
printf("\n\nFound ENDCODEPAGE keyword.\n");
//
// Return success.
//
return (0);
}
else
{
printf("Parse Error: Invalid Instruction '%s'.\n", pszKeyWord);
return (1);
}
}
//
// If this point is reached, then the ENDCODEPAGE keyword was
// not found. Return an error.
//
printf("Parse Error: Expecting ENDCODEPAGE keyword.\n");
return (1);
}
////////////////////////////////////////////////////////////////////////////
//
// WriteCodePage
//
// This routine writes the code page specific tables to an output file.
//
// 12-10-91 JulieB Created.
////////////////////////////////////////////////////////////////////////////
int WriteCodePage(
PCODEPAGE pCP)
{
char pszFile[FILE_NAME_LEN]; // file name storage
FILE *pOutputFile; // ptr to output file
//
// Make sure all tables are present.
//
if (!((pCP->WriteFlags & F_CPINFO) &&
(pCP->WriteFlags & F_MB) &&
(pCP->WriteFlags & F_WC)))
{
printf("Write Error: All tables must be present -\n");
printf(" CPInfo, MultiByte, and WideChar Translation Tables.\n");
return (1);
}
//
// Get the name of the output file.
//
memset(pszFile, 0, FILE_NAME_LEN * sizeof(char));
strcpy(pszFile, CP_PREFIX);
strcat(pszFile, pCP->pszName);
strcat(pszFile, DATA_FILE_SUFFIX);
//
// Make sure output file can be opened for writing.
//
if ((pOutputFile = fopen(pszFile, "w+b")) == 0)
{
printf("Error opening output file %s.\n", pszFile);
return (1);
}
if (Verbose)
printf("\n\nWriting output file %s...\n", pszFile);
//
// Write the CPINFO.
//
if (WriteCPInfo(pCP, pOutputFile))
{
fclose(pOutputFile);
return (1);
}
//
// Write MB Table, Glyph Table (if any) and DBCS Table (if any) to
// output file.
//
if (WriteMB(pCP, pOutputFile))
{
fclose(pOutputFile);
return (1);
}
//
// Free MB table structures.
//
FreeMB(pCP);
//
// Write WC Table to output file.
//
if (WriteWC( pCP,
(pCP->WriteFlags & F_DBCS),
pOutputFile ))
{
fclose(pOutputFile);
return (1);
}
//
// Free WC table structures.
//
free(pCP->pWC);
//
// Close the output file.
//
fclose(pOutputFile);
//
// Return success.
//
printf("\nSuccessfully wrote output file %s\n", pszFile);
return (0);
}
//-------------------------------------------------------------------------//
// INTERNAL ROUTINES //
//-------------------------------------------------------------------------//
////////////////////////////////////////////////////////////////////////////
//
// GetMBTable
//
// This routine gets the multibyte table from the input file. It uses the
// size parameter to know when to stop reading from the file. If an error
// is encountered, a message is printed and an error is returned.
//
// 07-30-91 JulieB Created.
// 12-10-91 JulieB Modified for new table format.
////////////////////////////////////////////////////////////////////////////
int GetMBTable(
PCODEPAGE pCP,
int Size)
{
int Ctr; // loop counter
int Index; // index into array - single byte char
int Value; // value - WC translation
int NumItems; // number of items returned from fscanf
//
// Allocate MB table.
//
if (AllocateMB(pCP))
{
return (1);
}
//
// For each table entry, read the MB char and the wide char
// from the input file and store the wide char in the array.
//
for (Ctr = 0; Ctr < Size; Ctr++)
{
//
// Get the index and the value to store from the file.
//
NumItems = fscanf( pInputFile,
"%x %x ;%*[^\n]",
&Index,
&Value );
if (NumItems != 2)
{
printf("Parse Error: Error reading MBTABLE values.\n");
return (1);
}
if (Index > MB_TABLE_SIZE)
{
printf("Parse Error: Multibyte char value too large.\n");
printf(" Value must be less than 0x%x.\n", MB_TABLE_SIZE);
return (1);
}
//
// Store the wide character value in the array.
//
(pCP->pMB)[Index] = (WORD)Value;
if (Verbose)
printf(" MB = %x\tWC = %x\n", Index, Value);
}
//
// Return success.
//
return (0);
}
////////////////////////////////////////////////////////////////////////////
//
// GetGlyphTable
//
// This routine gets the glyph table from the input file. It uses the
// size parameter to know when to stop reading from the file. If an error
// is encountered, a message is printed and an error is returned.
//
// 06-02-92 JulieB Created.
////////////////////////////////////////////////////////////////////////////
int GetGlyphTable(
PCODEPAGE pCP,
int Size)
{
int Ctr; // loop counter
int Index; // index into array - single byte char
int Value; // value - WC translation
int NumItems; // number of items returned from fscanf
//
// Allocate Glyph table.
//
if (AllocateGlyph(pCP))
{
return (1);
}
//
// For each table entry, read the MB char and the wide char
// from the input file and store the wide char in the array.
//
for (Ctr = 0; Ctr < Size; Ctr++)
{
//
// Get the index and the value to store from the file.
//
NumItems = fscanf( pInputFile,
"%x %x ;%*[^\n]",
&Index,
&Value );
if (NumItems != 2)
{
printf("Parse Error: Error reading GLYPHTABLE values.\n");
return (1);
}
if (Index > GLYPH_TABLE_SIZE)
{
printf("Parse Error: Multibyte char value too large.\n");
printf(" Value must be less than 0x%x.\n", GLYPH_TABLE_SIZE);
return (1);
}
//
// Store the wide character value in the array.
//
(pCP->pGlyph)[Index] = (WORD)Value;
if (Verbose)
printf(" MB = %x\tWC = %x\n", Index, Value);
}
//
// Return success.
//
return (0);
}
////////////////////////////////////////////////////////////////////////////
//
// GetDBCSRanges
//
// This routine gets the DBCS ranges from the input file. It uses the
// size parameter to know when to stop reading from the file. If an error
// is encountered, a message is printed and an error is returned.
//
// 07-30-91 JulieB Created.
// 12-10-91 JulieB Modified for new table format.
////////////////////////////////////////////////////////////////////////////
int GetDBCSRanges(
PCODEPAGE pCP,
int Size)
{
int Ctr; // loop counter
int Ctr2; // loop counter
int Low; // low end range value
int High; // high end range value
int Offset = DBCS_OFFSET_SIZE; // offset to DBCS table
int NumItems; // # of items returned from fscanf
//
// Save the number of ranges for later.
//
if ((Size < 1) || (Size > 5))
{
printf("Parse Error: Number of DBCS Ranges must be between 1 and 5.\n");
return (1);
}
pCP->NumDBCSRanges = Size;
//
// Allocate initial DBCS array structure.
//
if (AllocateTopDBCS(pCP, Size))
{
return (1);
}
//
// For each range, read the low range, the high range, and the
// DBCS tables for these ranges. DBCS tables MUST be in the
// correct order (low range to high range).
//
for (Ctr = 0; Ctr < Size; Ctr++)
{
//
// Read low and high range.
//
NumItems = fscanf( pInputFile,
"%x %x ;%*[^\n]",
&Low,
&High );
if (NumItems != 2)
{
printf("Parse Error: Error reading DBCS Range values.\n");
return (1);
}
if (High < Low)
{
printf("Parse Error: High Range must be greater than Low Range.\n");
return (1);
}
//
// Allocate DBCS structures.
//
if (AllocateDBCS(pCP, Low, High, Ctr))
{
return (1);
}
//
// Set the range in the structure.
//
(pCP->pDBCS)[Ctr]->LowRange = (WORD)Low;
(pCP->pDBCS)[Ctr]->HighRange = (WORD)High;
if (Verbose)
printf(" LOW = %x\tHIGH = %x\n", Low, High);
//
// Get Tables for this range.
//
if (GetAllDBCSTables( High - Low + 1,
(pCP->pDBCS)[Ctr]->pDBCSTbls ))
{
return (1);
}
//
// Set the offsets for the range.
// Offsets are in WORDS.
//
for (Ctr2 = Low; Ctr2 <= High; Ctr2++)
{
pCP->pDBCSOff[Ctr2] = (WORD)Offset;
Offset += DBCS_TABLE_SIZE;
//
// This shouldn't happen, but check it just in case.
// ( 254 tables max - (65536/256) - 2 )
//
if (Offset > 65536)
{
printf("FATAL Error: Too many DBCS tables - 254 max allowed.\n");
return (1);
}
}
//
// Save the LeadByte values in pCP structure again for easy
// writing to file.
//
(pCP->LeadBytes)[Ctr * 2] = (BYTE)Low;
(pCP->LeadBytes)[(Ctr * 2) + 1] = (BYTE)High;
}
//
// Return success.
//
return (0);
}
////////////////////////////////////////////////////////////////////////////
//
// GetAllDBCSTables
//
// This routine gets the DBCS tables (for one range) from the input file
// and places them in the appropriate structures.
//
// 07-30-91 JulieB Created.
////////////////////////////////////////////////////////////////////////////
int GetAllDBCSTables(
int NumTables,
PDBCS_TBL_ARRAY pArray)
{
int Ctr; // loop counter
char pszKeyWord[MAX]; // input token
int size; // size of table to follow
//
// Read each table.
//
for (Ctr = 0; Ctr < NumTables; Ctr++)
{
//
// Get DBCSTABLE keyword.
//
if ((fscanf(pInputFile, "%s", pszKeyWord) != 1) ||
(_stricmp(pszKeyWord, "DBCSTABLE") != 0))
{
printf("Parse Error: Error reading DBCSTABLE keyword.\n");
return (1);
}
if (Verbose)
printf("\n Found DBCSTABLE keyword.\n");
//
// Get size parameter.
//
if (GetSize(&size))
return (1);
//
// Get DBCS Table.
//
if (GetDBCSTable(size, pArray[Ctr]))
{
return (1);
}
}
//
// Return success.
//
return (0);
}
////////////////////////////////////////////////////////////////////////////
//
// GetDBCSTable
//
// This routine gets the DBCS table from the input file. It uses the
// size parameter to know when to stop reading from the file. If an error
// is encountered, a message is printed and an error is returned.
//
// 07-30-91 JulieB Created.
////////////////////////////////////////////////////////////////////////////
int GetDBCSTable(
int Size,
PDBCS_TBL pTable)
{
int Ctr; // loop counter
int Index; // index into array - single byte char
int Value; // value - WC translation
int NumItems; // number of items returned from fscanf
//
// For each table entry, read the MB char and the wide char
// from the input file and store the wide char in the array.
//
for (Ctr = 0; Ctr < Size; Ctr++)
{
//
// Get the index and the value to store from the file.
//
NumItems = fscanf( pInputFile,
"%x %x ;%*[^\n]",
&Index,
&Value );
if (NumItems != 2)
{
printf("Parse Error: Error reading DBCSTABLE values.\n");
return (1);
}
if (Index > DBCS_TABLE_SIZE)
{
printf("Parse Error: DBCS character value too large.\n");
printf(" Value must be less than 0x%x.\n", DBCS_TABLE_SIZE);
return (1);
}
//
// Store the wide character value in the array.
//
pTable[Index] = (WORD)Value;
if (Verbose)
printf(" MB = %x\tWC = %x\n", Index, Value);
}
//
// Return success.
//
return (0);
}
////////////////////////////////////////////////////////////////////////////
//
// GetWCTable
//
// This routine gets the wide character table from the input file. It uses
// the size parameter to know when to stop reading from the file. If an
// error is encountered, a message is printed and an error is returned.
//
// 07-30-91 JulieB Created.
// 12-10-91 JulieB Modified for new table format.
////////////////////////////////////////////////////////////////////////////
int GetWCTable(
PCODEPAGE pCP,
int Size,
BOOL IsMBCodePage)
{
int WChar; // wide character value
int MBChar; // multibyte character value
register int Ctr; // loop counter
BYTE *pBytePtr; // ptr to byte table
WORD *pWordPtr; // ptr to word table
int NumItems; // number of items returned from fscanf
//
// Allocate buffer for 1-to-1 mapping table.
//
if (IsMBCodePage)
{
if (AllocateWCTable(pCP, sizeof(WORD)))
{
return (1);
}
pWordPtr = (WORD *)(pCP->pWC);
}
else
{
if (AllocateWCTable(pCP, sizeof(BYTE)))
{
return (1);
}
pBytePtr = (BYTE *)(pCP->pWC);
}
//
// For each entry in table, read in wide character and multibyte
// character from input file.
//
for (Ctr = 0; Ctr < Size; Ctr++)
{
//
// Read in wide character and multibyte character.
//
NumItems = fscanf( pInputFile,
"%x %x ;%*[^\n]",
&WChar,
&MBChar );
if (NumItems != 2)
{
printf("Parse Error: Error reading WCTABLE values.\n");
return (1);
}
if (Verbose)
printf(" WC = %x\tMB = %x\n", WChar, MBChar);
//
// Insert MBChar into the appropriate translation table buffer.
//
if (IsMBCodePage)
{
pWordPtr[WChar] = (WORD)MBChar;
}
else
{
pBytePtr[WChar] = (BYTE)MBChar;
}
}
//
// Return success.
//
return (0);
}
////////////////////////////////////////////////////////////////////////////
//
// WriteCPInfo
//
// This routine writes the CP information to the output file.
//
// 12-10-91 JulieB Created.
////////////////////////////////////////////////////////////////////////////
int WriteCPInfo(
PCODEPAGE pCP,
FILE *pOutputFile)
{
int Size = CP_INFO_SIZE; // size of CPINFO information
WORD wValue; // temp storage value
//
// Get the translation of the MB default char and the
// Unicode default char.
//
if (GetTransDefaultChars(pCP))
{
return (1);
}
if (Verbose)
printf("\nWriting CP Info...\n");
//
// Write size of CPInfo to file.
//
wValue = (WORD)Size;
if (FileWrite( pOutputFile,
&wValue,
sizeof(WORD),
1,
"CPINFO Table Size" ))
{
return (1);
}
//
// Write CodePageValue to file.
//
wValue = (WORD)(pCP->CodePageValue);
if (FileWrite( pOutputFile,
&wValue,
sizeof(WORD),
1,
"CPINFO Code Page Value" ))
{
return (1);
}
//
// Write MaxCharSize to file.
//
wValue = (WORD)(pCP->MaxCharSize);
if (FileWrite( pOutputFile,
&wValue,
sizeof(WORD),
1,
"CPINFO Max Char Size" ))
{
return (1);
}
//
// Write Default Char to file.
//
if (FileWrite( pOutputFile,
&(pCP->DefaultChar),
sizeof(WORD),
1,
"CPINFO Default Char" ))
{
return (1);
}
//
// Write Unicode Default Char to file.
//
if (FileWrite( pOutputFile,
&(pCP->UniDefaultChar),
sizeof(WORD),
1,
"CPINFO Unicode Default Char" ))
{
return (1);
}
//
// Write Translation of Default Char to file.
//
if (FileWrite( pOutputFile,
&(pCP->TransDefChar),
sizeof(WORD),
1,
"CPINFO Translation of Default Char" ))
{
return (1);
}
//
// Write Translation of Unicode Default Char to file.
//
if (FileWrite( pOutputFile,
&(pCP->TransUniDefChar),
sizeof(WORD),
1,
"CPINFO Translation of Unicode Default Char" ))
{
return (1);
}
//
// Write DBCS LeadByte Ranges to file.
//
if (FileWrite( pOutputFile,
&(pCP->LeadBytes),
sizeof(BYTE),
MAX_NUM_LEADBYTE,
"CPINFO LeadBytes" ))
{
return (1);
}
//
// Return success.
//
return (0);
}
////////////////////////////////////////////////////////////////////////////
//
// WriteMB
//
// This routine writes the MB table, GLYPH table (if it exists), and
// DBCS table (if it exists) to the output file.
//
// 07-30-91 JulieB Created.
////////////////////////////////////////////////////////////////////////////
int WriteMB(
PCODEPAGE pCP,
FILE *pOutputFile)
{
int TblSize; // size of table
int Ctr; // loop counter
int Ctr2; // loop counter
PDBCS_ARRAY pDBCSArray; // ptr to DBCS array
PDBCS_RANGE pRange; // ptr to range structure
register int NumRanges; // number of DBCS ranges
register int NumTables; // number of tables for range
WORD wValue; // temp storage value
if (Verbose)
printf("\nWriting MB Table...\n");
//
// Compute size of table and write it to the output file.
//
TblSize = ComputeMBSize(pCP);
wValue = (WORD)TblSize;
if (FileWrite( pOutputFile,
&wValue,
sizeof(WORD),
1,
"MB size" ))
{
return (1);
}
//
// Write MB Table to output file.
//
if (FileWrite( pOutputFile,
pCP->pMB,
sizeof(WORD),
MB_TABLE_SIZE,
"MB table" ))
{
return (1);
}
//
// Write Glyph Table to output file (if it exists).
//
if (pCP->WriteFlags & F_GLYPH)
{
wValue = GLYPH_TABLE_SIZE;
if (FileWrite( pOutputFile,
&wValue,
sizeof(WORD),
1,
"GLYPH table size" ))
{
return (1);
}
if (FileWrite( pOutputFile,
pCP->pGlyph,
sizeof(WORD),
GLYPH_TABLE_SIZE,
"GLYPH table" ))
{
return (1);
}
}
else
{
wValue = 0;
if (FileWrite( pOutputFile,
&wValue,
sizeof(WORD),
1,
"GLYPH table size" ))
{
return (1);
}
}
//
// Write number of DBCS ranges to output file.
//
wValue = (WORD)(pCP->NumDBCSRanges);
if (FileWrite( pOutputFile,
&wValue,
sizeof(WORD),
1,
"DBCS Ranges" ))
{
return (1);
}
//
// Write the DBCS tables to the file (if any exist).
//
NumRanges = pCP->NumDBCSRanges;
if ((NumRanges > 0) && (pCP->WriteFlags & F_DBCS))
{
if (Verbose)
printf("\n Writing DBCS Table...\n");
//
// Write the offsets.
//
if (FileWrite( pOutputFile,
pCP->pDBCSOff,
sizeof(WORD),
DBCS_OFFSET_SIZE,
"DBCS Offsets" ))
{
return (1);
}
//
// Write the tables.
//
pDBCSArray = pCP->pDBCS;
for (Ctr = 0; Ctr < NumRanges; Ctr++)
{
pRange = pDBCSArray[Ctr];
if (Verbose)
printf(" Writing DBCS range %x to %x\n",
pRange->LowRange, pRange->HighRange);
NumTables = pRange->HighRange - pRange->LowRange + 1;
for (Ctr2 = 0; Ctr2 < NumTables; Ctr2++)
{
if (FileWrite( pOutputFile,
pRange->pDBCSTbls[Ctr2],
sizeof(WORD),
DBCS_TABLE_SIZE,
"DBCS Table" ))
{
return (1);
}
if (Verbose)
printf(" Writing DBCS table %d\n", Ctr2 + 1);
}
}
}
//
// Return success.
//
return (0);
}
////////////////////////////////////////////////////////////////////////////
//
// WriteWC
//
// This routine writes the WC information to the output file.
//
// 07-30-91 JulieB Created.
////////////////////////////////////////////////////////////////////////////
int WriteWC(
PCODEPAGE pCP,
BOOL IsMBCodePage,
FILE *pOutputFile)
{
WORD wValue; // temp storage value
if (Verbose)
printf("\nWriting WC Table...\n");
//
// Write 0 for SB or 1 for DB code page to the output file.
//
wValue = (WORD)IsMBCodePage;
if (FileWrite( pOutputFile,
&wValue,
sizeof(WORD),
1,
"SB or DB flag" ))
{
return (1);
}
//
// Write WC translation table to the output file.
//
if (FileWrite( pOutputFile,
pCP->pWC,
(IsMBCodePage) ? sizeof(WORD) : sizeof(BYTE),
WC_TABLE_SIZE,
"WC Table" ))
{
return (1);
}
//
// Return success.
//
return (0);
}
////////////////////////////////////////////////////////////////////////////
//
// FreeMB
//
// This routine frees the memory used to build the MB table and the DBCS
// table.
//
// 07-30-91 JulieB Created.
////////////////////////////////////////////////////////////////////////////
void FreeMB(
PCODEPAGE pCP)
{
int Ctr; // loop counter
int Ctr2; // loop counter
PDBCS_ARRAY pDBCSArray; // ptr to DBCS array
PDBCS_RANGE pRange; // ptr to DBCS Range structure
PDBCS_TBL_ARRAY pTbls; // ptr to DBCS table array
register int NumRanges; // number of DBCS ranges
register int NumTables; // number of tables in range
//
// Free Multibyte Table structures.
//
if (pCP->pMB != NULL)
{
free(pCP->pMB);
}
//
// Free Glyph Table structures.
//
if (pCP->pGlyph != NULL)
{
free(pCP->pGlyph);
}
//
// Free DBCS Table structures.
//
if ((pDBCSArray = pCP->pDBCS) != NULL)
{
NumRanges = pCP->NumDBCSRanges;
for (Ctr = 0; Ctr < NumRanges; Ctr++)
{
if ((pRange = pDBCSArray[Ctr]) != NULL)
{
if ((pTbls = pRange->pDBCSTbls) != NULL)
{
NumTables = pRange->HighRange - pRange->LowRange + 1;
for (Ctr2 = 0; Ctr2 < NumTables; Ctr2++)
{
if (pTbls[Ctr2] != NULL)
{
free(pTbls[Ctr2]);
}
}
free(pTbls);
}
free(pRange);
}
}
free(pDBCSArray);
}
if (pCP->pDBCSOff != NULL)
{
free(pCP->pDBCSOff);
}
}
////////////////////////////////////////////////////////////////////////////
//
// GetTransDefaultChars
//
// Gets the MB translation for the Unicode default char and
// the Unicode translation for the MB default char.
//
// This allows the multi byte default char and the Unicode default char
// to be different in the data file.
//
// 09-01-93 JulieB Created.
////////////////////////////////////////////////////////////////////////////
int GetTransDefaultChars(
PCODEPAGE pCP)
{
WORD wDefChar; // default char to translate
WORD Lead; // lead byte of DBCS char
WORD Low; // low part of DBCS range
WORD High; // high part of DBCS range
int ctr; // loop counter
PDBCS_TBL pDBCSTable; // ptr to appropriate DBCS table
//
// Get the MB translation for the Unicode Default Char.
//
wDefChar = pCP->UniDefaultChar;
if (pCP->MaxCharSize == 1)
{
//
// Single byte code page.
//
pCP->TransUniDefChar = ((WORD)(((BYTE *)(pCP->pWC))[wDefChar]));
}
else
{
//
// Double byte code page.
//
pCP->TransUniDefChar = ((WORD)(((WORD *)(pCP->pWC))[wDefChar]));
}
//
// Get the Unicode translation for the MB Default Char.
//
wDefChar = pCP->DefaultChar;
if (Lead = (WORD)HIBYTE(wDefChar))
{
//
// Make sure the DBCS tables exist.
//
if (!(pCP->pDBCS))
{
printf("Parse Error: Invalid default char '%x'.\n", wDefChar);
return (1);
}
//
// Search for the correct range.
//
for (ctr = 0; ctr < pCP->NumDBCSRanges; ctr++)
{
Low = ((pCP->pDBCS)[ctr])->LowRange;
High = ((pCP->pDBCS)[ctr])->HighRange;
if ((Lead >= Low) && (Lead <= High))
{
break;
}
}
//
// Make sure the lead byte is valid.
//
if (ctr == pCP->NumDBCSRanges)
{
printf("Parse Error: Invalid default char '%x'.\n", wDefChar);
return (1);
}
//
// Get the Unicode translation of the DBCS char.
//
pDBCSTable = (((pCP->pDBCS)[ctr])->pDBCSTbls)[Lead - Low];
pCP->TransDefChar = ((WORD)(pDBCSTable[LOBYTE(wDefChar)]));
//
// Make sure the trail byte is valid.
//
if ((pCP->TransDefChar == pCP->UniDefaultChar) &&
(wDefChar != pCP->TransUniDefChar))
{
printf("Parse Error: Invalid default char '%x'.\n", wDefChar);
return (1);
}
}
else
{
pCP->TransDefChar = ((WORD)((pCP->pMB)[LOBYTE(wDefChar)]));
}
//
// Return success.
//
return (0);
}