/*++ 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); }