blob: ac12b6709c741c9f182e25e41444a6abca7d2a86 [file] [log] [blame]
/*
********************************************************************************
* *
* COPYRIGHT: *
* (C) Copyright International Business Machines Corporation, 1998 *
* Licensed Material - Program-Property of IBM - All Rights Reserved. *
* US Government Users Restricted Rights - Use, duplication, or disclosure *
* restricted by GSA ADP Schedule Contract with IBM Corp. *
* *
********************************************************************************
*
*
* makeconv.c:
* tool creating a binary (compressed) representation of the conversion mapping
* table (IBM NLTC ucmap format).
*/
#include <stdio.h>
#include "ucmp16.h"
#include "ucmp8.h"
#include "ucnv_io.h"
#include "ucnv_bld.h"
#include "ucnv_err.h"
#include "cstring.h"
#include "cmemory.h"
#include "filestrm.h"
/*Reads the header of the table file and fills in basic knowledge about the converter
*in "converter"
*/
static void readHeaderFromFile(UConverter* myConverter, FileStream* convFile, UErrorCode* err);
/*Reads the rest of the file, and fills up the shared objects if necessary*/
static void loadMBCSTableFromFile(FileStream* convFile, UConverter* converter, UErrorCode* err);
/*Reads the rest of the file, and fills up the shared objects if necessary*/
static void loadEBCDIC_STATEFULTableFromFile(FileStream* convFile, UConverter* converter, UErrorCode* err);
/*Reads the rest of the file, and fills up the shared objects if necessary*/
static void loadSBCSTableFromFile(FileStream* convFile, UConverter* converter, UErrorCode* err);
/*Reads the rest of the file, and fills up the shared objects if necessary*/
static void loadDBCSTableFromFile(FileStream* convFile, UConverter* converter, UErrorCode* err);
/* creates a UConverterSharedData from a mapping file, fills in necessary links to it the
* appropriate function pointers
* if the data tables are already in memory
*/
static UConverterSharedData* createConverterFromTableFile(const char* realName, UErrorCode* err);
/*writes a CompactShortArray to a file*/
static void writeCompactShortArrayToFile(FileStream* outfile, const CompactShortArray* myArray);
/*writes a CompactByteArray to a file*/
static void writeCompactByteArrayToFile(FileStream* outfile, const CompactByteArray* myArray);
/*writes a binary to a file*/
static void writeUConverterSharedDataToFile(const char* filename,
UConverterSharedData* mySharedData,
UErrorCode* err);
static UCNV_PLATFORM getPlatformFromName(char* name);
static int32_t getCodepageNumberFromName(char* name);
static const char NLTC_SEPARATORS[9] = { '\r', '\n', '\t', ' ', '<', '>' ,'"' , 'U', '\0' };
static const char PLAIN_SEPARATORS[9] = { '\r', '\n', '\t', ' ', '<', '>' ,'"' , '\0' };
static const char CODEPOINT_SEPARATORS[8] = { '\r', '>', '\\', 'x', '\n', ' ', '\t', '\0' };
static const char UNICODE_CODEPOINT_SEPARATORS[6] = { '<', '>', 'U', ' ', '\t', '\0' };
int main(int argc, char** argv)
{
UConverterSharedData* mySharedData = NULL;
UErrorCode err = ZERO_ERROR;
char outFileName[MAX_FULL_FILE_NAME_LENGTH];
char* dot = NULL;
if (argc == 1)
{
/*prints out a usage message*/
printf("usage: %s file1 file2 file3 ...\n", argv[0]);
}
while (--argc)
{
/*removes the extension if any is found*/
icu_strcpy(outFileName, argv[argc]);
if (dot = icu_strchr(outFileName + icu_strlen(outFileName) - 4, '.'))
{
*dot = '\0';
}
/*Adds the target extension*/
icu_strcat(outFileName, CONVERTER_FILE_EXTENSION);
mySharedData = createConverterFromTableFile(argv[argc], &err);
if (FAILURE(err) || (mySharedData == NULL))
{
/* in an error is found, print out a error msg and keep going*/
printf("Error creating \"%s\" file for \"%s\" (error code %d)\n", outFileName, argv[argc], err);
err = ZERO_ERROR;
}
else
{
writeUConverterSharedDataToFile(outFileName, mySharedData, &err);
deleteSharedConverterData(mySharedData);
puts(outFileName);
}
}
return err;
}
/*Streams out to a file a compact short array*/
void writeCompactShortArrayToFile(FileStream* outfile, const CompactShortArray* myArray)
{
int32_t i = 0;
const int16_t* myShortArray = NULL;
const uint16_t* myIndexArray = NULL;
int32_t myValuesCount = 0;
int32_t myIndexCount = ucmp16_getkUnicodeCount() / ucmp16_getkBlockCount();
int32_t myBlockShift = myArray->kBlockShift;
/*streams out the length of the arrays to come*/
myValuesCount = myArray->fCount;
T_FileStream_write(outfile, &myValuesCount, sizeof(int32_t));
T_FileStream_write(outfile, &myIndexCount, sizeof(int32_t));
T_FileStream_write(outfile, &myBlockShift, sizeof(int32_t));
/*Gets pointers to the internal arrays*/
myShortArray = myArray->fArray;
myIndexArray = myArray->fIndex;
/*streams out the 2 arrays*/
T_FileStream_write(outfile, myShortArray, myValuesCount*sizeof(int16_t));
T_FileStream_write(outfile, myIndexArray, myIndexCount*sizeof(uint16_t));
return ;
}
void writeCompactByteArrayToFile(FileStream* outfile, const CompactByteArray* myArray)
{
int32_t i = 0;
const int8_t* myByteArray = NULL;
const uint16_t* myIndexArray = NULL;
int32_t myValuesCount = 0;
int32_t myIndexCount = ucmp8_getkUnicodeCount() / ucmp8_getkBlockCount();
/*streams out the length of the arrays to come*/
myValuesCount = ucmp8_getCount(myArray);
T_FileStream_write(outfile, &myValuesCount, sizeof(int32_t));
T_FileStream_write(outfile, &myIndexCount, sizeof(int32_t));
/*Gets pointers to the internal arrays*/
myByteArray = myArray->fArray;
myIndexArray = myArray->fIndex;
/*streams out the 2 arrays*/
T_FileStream_write(outfile, myByteArray, myValuesCount*sizeof(int8_t));
T_FileStream_write(outfile, myIndexArray, myIndexCount*sizeof(uint16_t));
return ;
}
void writeUConverterSharedDataToFile(const char* filename,
UConverterSharedData* mySharedData,
UErrorCode* err)
{
int32_t i = 0;
const int8_t* myByteArray = NULL;
const uint16_t* myIndexArray = NULL;
int32_t myValuesCount = 0;
int32_t myIndexCount = 0;
int32_t myCheck = FILE_CHECK_MARKER;
FileStream* outfile = NULL;
ConverterTable* myTableAlias = NULL;
if (FAILURE(*err)) return;
outfile = T_FileStream_open(filename, "wb");
if (outfile == NULL)
{
*err = FILE_ACCESS_ERROR;
return;
}
/*Writes a Sentinel value*/
T_FileStream_write(outfile, &myCheck, sizeof(int32_t));
T_FileStream_write(outfile, COPYRIGHT_STRING, COPYRIGHT_STRING_LENGTH);
/*Writes NULL in places where there is a pointer in order
*to enable bitwise equivalence of binary files
*/
myTableAlias = mySharedData->table;
mySharedData->table = NULL;
T_FileStream_write(outfile, mySharedData, sizeof(UConverterSharedData));
mySharedData->table = myTableAlias;
switch (mySharedData->conversionType)
{
case SBCS :
{
T_FileStream_write(outfile, mySharedData->table->sbcs.toUnicode, 256*sizeof(UChar));
writeCompactByteArrayToFile(outfile, mySharedData->table->sbcs.fromUnicode);
}break;
case DBCS : case EBCDIC_STATEFUL:
{
writeCompactShortArrayToFile(outfile, mySharedData->table->dbcs.toUnicode);
writeCompactShortArrayToFile(outfile, mySharedData->table->dbcs.fromUnicode);
}break;
case MBCS :
{
T_FileStream_write(outfile, mySharedData->table->mbcs.starters, 256*sizeof(bool_t));
writeCompactShortArrayToFile(outfile, mySharedData->table->mbcs.toUnicode);
writeCompactShortArrayToFile(outfile, mySharedData->table->mbcs.fromUnicode);
}break;
};
if (T_FileStream_error(outfile))
{
*err = FILE_ACCESS_ERROR;
}
T_FileStream_close(outfile);
}
void copyPlatformString(char* platformString, UCNV_PLATFORM pltfrm)
{
switch (pltfrm)
{
case IBM: {icu_strcpy(platformString, "ibm");break;}
default: {icu_strcpy(platformString, "");break;}
};
return;
}
UCNV_PLATFORM getPlatformFromName(char* name)
{
char myPlatform[10];
char mySeparators[2] = { '-', '\0' };
getToken(myPlatform, name, mySeparators);
strtoupper(myPlatform);
if (icu_strcmp(myPlatform, "IBM") == 0) return IBM;
else return UNKNOWN;
}
int32_t getCodepageNumberFromName(char* name)
{
char myNumber[10];
char mySeparators[2] = { '-', '\0' };
char* line = NULL;
line = getToken(myNumber, name, mySeparators);
getToken(myNumber, line, mySeparators);
return T_CString_stringToInteger(myNumber, 10);
}
/*Reads the header of the table file and fills in basic knowledge about the converter in "converter"*/
void readHeaderFromFile(UConverter* myConverter,
FileStream* convFile,
UErrorCode* err)
{
char storeLine[MAX_LINE_TEXT];
char key[15];
char value[30];
char* line = storeLine;
bool_t endOfHeader = FALSE;
bool_t hasConvClass = FALSE;
bool_t hasSubChar = FALSE;
char codepointByte[3];
if (FAILURE(*err)) return;
while (!endOfHeader && T_FileStream_readLine(convFile, line, MAX_LINE_TEXT))
{
removeComments(line);
/*skip blank lines*/
if (*(line + nextTokenOffset(line, NLTC_SEPARATORS)) != '\0')
{
/*gets the key that will qualify adjacent information*/
/*gets the adjacent value*/
line = getToken(key, line, NLTC_SEPARATORS);
if (icu_strcmp(key, "uconv_class"))
line = getToken(value, line, NLTC_SEPARATORS);
else
line = getToken(value, line, PLAIN_SEPARATORS);
/*
Figure out what key was found and fills in myConverter with the appropriate values
a switch statement for strings...
*/
/*Checks for end of header marker*/
if (icu_strcmp(key, "CHARMAP") == 0) endOfHeader = TRUE;
/*get name tag*/
else if (icu_strcmp(key, "code_set_name") == 0)
{
icu_strcpy(myConverter->sharedData->name, value);
myConverter->sharedData->platform = getPlatformFromName(value);
myConverter->sharedData->codepage = getCodepageNumberFromName(value);
}
/*get conversion type*/
else if (icu_strcmp(key, "uconv_class") == 0)
{
hasConvClass = TRUE;
if (icu_strcmp(value, "DBCS") == 0)
{
myConverter->sharedData->conversionType = DBCS;
}
else if (icu_strcmp(value, "SBCS") == 0)
{
myConverter->sharedData->conversionType = SBCS;
}
else if (icu_strcmp(value, "MBCS") == 0)
{
myConverter->sharedData->conversionType = MBCS;
}
else if (icu_strcmp(value, "EBCDIC_STATEFUL") == 0)
{
myConverter->sharedData->conversionType = EBCDIC_STATEFUL;
}
else
{
*err = INVALID_TABLE_FORMAT;
return;
}
}
/*get mb_cur_max amount*/
else if (icu_strcmp(key, "mb_cur_max") == 0)
myConverter->sharedData->maxBytesPerChar = (int8_t)T_CString_stringToInteger(value, 10);
/*get mb_cur_max amount*/
else if (icu_strcmp(key, "mb_cur_min") == 0)
myConverter->sharedData->minBytesPerChar = (int8_t)T_CString_stringToInteger(value, 10);
else if (icu_strcmp(key, "subchar") == 0)
{
hasSubChar = TRUE;
myConverter->sharedData->defaultConverterValues.subCharLen = 0;
/*readies value for tokenizing, we want to break each byte of the codepoint into single tokens*/
line = value;
while (*line)
{
line = getToken(codepointByte, line, CODEPOINT_SEPARATORS);
myConverter->sharedData->defaultConverterValues.subChar[(myConverter->sharedData->defaultConverterValues.subCharLen++)] =
(unsigned char)T_CString_stringToInteger(codepointByte, 16);
}
/*Initializes data from the mutable area to that found in the immutable area*/
}
}
/*make line point to the beginning of the storage buffer again*/
line = storeLine;
}
if (!hasSubChar) {myConverter->subCharLen = myConverter->sharedData->defaultConverterValues.subCharLen = 0;}
else
{
myConverter->subCharLen = myConverter->sharedData->defaultConverterValues.subCharLen;
icu_memcpy(myConverter->subChar,
myConverter->sharedData->defaultConverterValues.subChar,
myConverter->subCharLen);
}
if (!endOfHeader || !hasConvClass) *err = INVALID_TABLE_FORMAT;
return;
}
void loadSBCSTableFromFile(FileStream* convFile, UConverter* myConverter, UErrorCode* err)
{
char storageLine[MAX_LINE_TEXT];
char* line = NULL;
ConverterTable* myConverterTable = NULL;
UChar unicodeValue = 0xFFFF;
int32_t sbcsCodepageValue = 0;
char codepointBytes[5];
unsigned char replacementChar = '\0';
int32_t i = 0;
CompactByteArray* myFromUnicode = NULL;
if (FAILURE(*err)) return;
replacementChar = myConverter->subChar[0];
myConverterTable = (ConverterTable*)icu_malloc(sizeof(SBCS_TABLE));
if (myConverterTable == NULL)
{
*err = MEMORY_ALLOCATION_ERROR;
return;
}
/*create a compact array with replacement chars as default chars*/
myFromUnicode = ucmp8_open(0);
if (myFromUnicode == NULL)
{
icu_free(myConverterTable);
*err = MEMORY_ALLOCATION_ERROR;
return;
}
/*fills in the toUnicode array with the Unicode Replacement Char*/
for (i=0;i<255;i++) myConverterTable->sbcs.toUnicode[i] = unicodeValue;
while (T_FileStream_readLine(convFile, storageLine, MAX_LINE_TEXT))
{
/*removes comments*/
removeComments(storageLine);
/*set alias pointer back to the beginning of the buffer*/
line = storageLine;
/*skips empty lines*/
if (line[nextTokenOffset(line, NLTC_SEPARATORS)] != '\0')
{
line = getToken(codepointBytes, line, UNICODE_CODEPOINT_SEPARATORS);
if (!icu_strcmp(codepointBytes, "END")) break;
unicodeValue = (UChar)T_CString_stringToInteger(codepointBytes, 16);
line = getToken(codepointBytes, line, CODEPOINT_SEPARATORS);
sbcsCodepageValue = T_CString_stringToInteger(codepointBytes, 16);
/*Store in the toUnicode array*/
myConverterTable->sbcs.toUnicode[sbcsCodepageValue] = unicodeValue;
/*Store in the fromUnicode compact array*/
ucmp8_set(myFromUnicode, unicodeValue, (int8_t)sbcsCodepageValue);
}
}
ucmp8_compact(myFromUnicode, 1);
myConverterTable->sbcs.fromUnicode = myFromUnicode;
/*Initially sets the referenceCounter to 1*/
myConverter->sharedData->referenceCounter = 1;
myConverter->sharedData->table = myConverterTable;
return;
}
void loadMBCSTableFromFile(FileStream* convFile, UConverter* myConverter, UErrorCode* err)
{
char storageLine[MAX_LINE_TEXT];
char* line = NULL;
ConverterTable* myConverterTable = NULL;
UChar unicodeValue = 0xFFFF;
int32_t mbcsCodepageValue = '\0';
char codepointBytes[6];
int32_t replacementChar = 0x0000;
uint16_t i = 0;
CompactShortArray* myFromUnicode = NULL;
CompactShortArray* myToUnicode = NULL;
/*Evaluates the replacement codepoint*/
replacementChar = 0xFFFF;
myConverterTable = (ConverterTable*)icu_malloc(sizeof(MBCS_TABLE));
if (myConverterTable == NULL)
{
*err = MEMORY_ALLOCATION_ERROR;
return;
}
/*Initializes the mbcs.starters to FALSE*/
for (i=0; i<=255; i++)
{
myConverterTable->mbcs.starters[i] = FALSE;
}
myFromUnicode = ucmp16_open((uint16_t)replacementChar);
myToUnicode = ucmp16_open((int16_t)0xFFFD);
while (T_FileStream_readLine(convFile, storageLine, MAX_LINE_TEXT))
{
removeComments(storageLine);
line = storageLine;
if (line[nextTokenOffset(line, NLTC_SEPARATORS)] != '\0')
{
line = getToken(codepointBytes, line, UNICODE_CODEPOINT_SEPARATORS);
if (!icu_strcmp(codepointBytes, "END")) break;
unicodeValue = (UChar)T_CString_stringToInteger(codepointBytes, 16);
line = getToken(codepointBytes, line, CODEPOINT_SEPARATORS);
if (line[nextTokenOffset(line, CODEPOINT_SEPARATORS)] != '\0')
{
/*When there is a second byte*/
myConverterTable->mbcs.starters[T_CString_stringToInteger(codepointBytes, 16)] = TRUE;
line = getToken(codepointBytes+2, line, CODEPOINT_SEPARATORS);
}
mbcsCodepageValue = T_CString_stringToInteger(codepointBytes, 16);
ucmp16_set(myToUnicode, (int16_t)mbcsCodepageValue, unicodeValue);
ucmp16_set(myFromUnicode, unicodeValue, (int16_t)mbcsCodepageValue);
}
}
ucmp16_compact(myFromUnicode);
ucmp16_compact(myToUnicode);
myConverterTable->mbcs.fromUnicode = myFromUnicode;
myConverterTable->mbcs.toUnicode = myToUnicode;
myConverter->sharedData->referenceCounter = 1;
myConverter->sharedData->table = myConverterTable;
/* if the default subCharLen is > 1 we need to insert it in the data structure
so that we know how to transition */
if (myConverter->subCharLen > 1)
{
myConverter->sharedData->table->mbcs.starters[myConverter->subChar[0]] = TRUE;
}
return;
}
void loadEBCDIC_STATEFULTableFromFile(FileStream* convFile, UConverter* myConverter, UErrorCode* err)
{
char storageLine[MAX_LINE_TEXT];
char* line = NULL;
ConverterTable* myConverterTable = NULL;
UChar unicodeValue = 0xFFFF;
int32_t mbcsCodepageValue = '\0';
char codepointBytes[6];
int32_t replacementChar = 0x0000;
uint8_t i = 0;
CompactShortArray* myFromUnicode = NULL;
CompactShortArray* myToUnicode = NULL;
/*Evaluates the replacement codepoint*/
replacementChar = 0xFFFF;
myConverterTable = (ConverterTable*)icu_malloc(sizeof(MBCS_TABLE));
if (myConverterTable == NULL)
{
*err = MEMORY_ALLOCATION_ERROR;
return;
}
myFromUnicode = ucmp16_open((uint16_t)replacementChar);
myToUnicode = ucmp16_open((int16_t)0xFFFD);
while (T_FileStream_readLine(convFile, storageLine, MAX_LINE_TEXT))
{
removeComments(storageLine);
line = storageLine;
if (line[nextTokenOffset(line, NLTC_SEPARATORS)] != '\0')
{
line = getToken(codepointBytes, line, UNICODE_CODEPOINT_SEPARATORS);
if (!icu_strcmp(codepointBytes, "END")) break;
unicodeValue = (UChar)T_CString_stringToInteger(codepointBytes, 16);
line = getToken(codepointBytes, line, CODEPOINT_SEPARATORS);
if (line[nextTokenOffset(line, CODEPOINT_SEPARATORS)] != '\0')
{
/*two-byter!*/
line = getToken(codepointBytes+2, line, CODEPOINT_SEPARATORS);
}
mbcsCodepageValue = T_CString_stringToInteger(codepointBytes, 16);
ucmp16_set(myToUnicode, (int16_t)mbcsCodepageValue, unicodeValue);
ucmp16_set(myFromUnicode, unicodeValue, (int16_t)mbcsCodepageValue);
}
}
ucmp16_compact(myFromUnicode);
ucmp16_compact(myToUnicode);
myConverterTable->dbcs.fromUnicode = myFromUnicode;
myConverterTable->dbcs.toUnicode = myToUnicode;
myConverter->sharedData->referenceCounter = 1;
myConverter->sharedData->table = myConverterTable;
/* if the default subCharLen is > 1 we need to insert it in the data structure
so that we know how to transition */
if (myConverter->subCharLen > 1)
{
myConverter->sharedData->table->mbcs.starters[myConverter->subChar[0]] = TRUE;
}
return;
}
void loadDBCSTableFromFile(FileStream* convFile, UConverter* myConverter, UErrorCode* err)
{
char storageLine[MAX_LINE_TEXT];
char* line = NULL;
ConverterTable* myConverterTable = NULL;
UChar unicodeValue = 0xFFFD;
int32_t dbcsCodepageValue = '\0';
char codepointBytes[6];
int32_t replacementChar = 0x0000;
uint8_t i = 0;
CompactShortArray* myFromUnicode = NULL;
CompactShortArray* myToUnicode = NULL;
/*Evaluates the replacement codepoint*/
replacementChar = 0xFFFF;
myConverterTable = (ConverterTable*)icu_malloc(sizeof(DBCS_TABLE));
if (myConverterTable == NULL)
{
*err = MEMORY_ALLOCATION_ERROR;
return;
}
myFromUnicode = ucmp16_open((int16_t)replacementChar);
myToUnicode = ucmp16_open((int16_t)0xFFFD);
while (T_FileStream_readLine(convFile, storageLine, MAX_LINE_TEXT))
{
removeComments(storageLine);
line = storageLine;
if (line[nextTokenOffset(line, NLTC_SEPARATORS)] != '\0')
{
line = getToken(codepointBytes, line, UNICODE_CODEPOINT_SEPARATORS);
if (!icu_strcmp(codepointBytes, "END")) break;
unicodeValue = (UChar)T_CString_stringToInteger(codepointBytes, 16);
/*first byte*/
line = getToken(codepointBytes, line, CODEPOINT_SEPARATORS);
/*second byte*/
line = getToken(codepointBytes+2, line, CODEPOINT_SEPARATORS);
}
dbcsCodepageValue = T_CString_stringToInteger(codepointBytes, 16);
ucmp16_set(myToUnicode, (int16_t)dbcsCodepageValue, unicodeValue);
ucmp16_set(myFromUnicode, unicodeValue, (int16_t)dbcsCodepageValue);
}
ucmp16_compact(myFromUnicode);
ucmp16_compact(myToUnicode);
myConverterTable->dbcs.fromUnicode = myFromUnicode;
myConverterTable->dbcs.toUnicode = myToUnicode;
myConverter->sharedData->referenceCounter = 1;
myConverter->sharedData->table = myConverterTable;
return;
}
/*deletes the "shared" type object*/
bool_t deleteSharedConverterData(UConverterSharedData* deadSharedData)
{
if (deadSharedData->conversionType == SBCS)
{
ucmp8_close(deadSharedData->table->sbcs.fromUnicode);
icu_free(deadSharedData->table);
icu_free(deadSharedData);
}
else if (deadSharedData->conversionType == MBCS)
{
ucmp16_close(deadSharedData->table->mbcs.fromUnicode);
ucmp16_close(deadSharedData->table->mbcs.toUnicode);
icu_free(deadSharedData->table);
icu_free(deadSharedData);
}
else if ((deadSharedData->conversionType == DBCS) || (deadSharedData->conversionType == EBCDIC_STATEFUL))
{
ucmp16_close(deadSharedData->table->dbcs.fromUnicode);
ucmp16_close(deadSharedData->table->dbcs.toUnicode);
icu_free(deadSharedData->table);
icu_free(deadSharedData);
}
else
{
icu_free(deadSharedData);
}
return TRUE;
}
/*creates a UConverter, fills in necessary links to it the appropriate function pointers*/
UConverterSharedData* createConverterFromTableFile(const char* converterName, UErrorCode* err)
{
FileStream* convFile = NULL;
int32_t i = 0;
UConverterSharedData* mySharedData = NULL;
UConverter myConverter;
if (FAILURE(*err)) return NULL;
convFile = T_FileStream_open(converterName, "r");
if (convFile == NULL)
{
*err = FILE_ACCESS_ERROR;
return NULL;
}
mySharedData = (UConverterSharedData*) icu_malloc(sizeof(UConverterSharedData));
if (mySharedData == NULL)
{
*err = MEMORY_ALLOCATION_ERROR;
T_FileStream_close(convFile);
}
myConverter.sharedData = mySharedData;
readHeaderFromFile(&myConverter, convFile, err);
if (FAILURE(*err)) return NULL;
switch (mySharedData->conversionType)
{
case SBCS:
{
loadSBCSTableFromFile(convFile, &myConverter, err);
break;
}
case MBCS:
{
loadMBCSTableFromFile(convFile, &myConverter, err);
break;
}
case EBCDIC_STATEFUL:
{
loadEBCDIC_STATEFULTableFromFile(convFile, &myConverter, err);
break;
}
case DBCS:
{
loadDBCSTableFromFile(convFile, &myConverter, err);
break;
}
default : break;
};
T_FileStream_close(convFile);
return mySharedData;
}