354 lines
13 KiB
C
354 lines
13 KiB
C
|
|
||
|
/*************************************************
|
||
|
* gennpsrc.c *
|
||
|
* *
|
||
|
* Copyright (C) 1995-1999 Microsoft Inc. *
|
||
|
* *
|
||
|
*************************************************/
|
||
|
|
||
|
//
|
||
|
// This file is used to Generate a new source Phone Table File.
|
||
|
//
|
||
|
// it will read two files, one for Big5 and one for GB, to generate a new
|
||
|
// Phon code table file.
|
||
|
//
|
||
|
// the two input files are sorted on the external keystroke pattern,
|
||
|
// and both are complete Unicode files, ( there is 0xFEFF
|
||
|
// in its first two bytes),
|
||
|
//
|
||
|
// the two input files contain lots of lines,every line follows below format:
|
||
|
// XXXXTCFRL
|
||
|
// X: Key Code,
|
||
|
// T: Tab, 0x0009
|
||
|
// C: Unicode for this Character
|
||
|
// F: L' ' or L'*'
|
||
|
// R: 0x000D
|
||
|
// L: 0x000A
|
||
|
//
|
||
|
// we will generate a new table source file, if the same pattern exists in both
|
||
|
// Big5 file and GB file, all those lines will be appended to the new file, and// the lines of Big5 will be written first, then GB Lines
|
||
|
//
|
||
|
// the new generated file must be sorted on the pattern.
|
||
|
|
||
|
//
|
||
|
// Created by weibz, March 02, 1998
|
||
|
//
|
||
|
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <windows.h>
|
||
|
|
||
|
#define LINELEN (9 * sizeof(WORD) )
|
||
|
|
||
|
WCHAR Seq2Key[43] = { 0,
|
||
|
L'1', L'Q', L'A', L'Z', L'2', L'W', L'S', L'X',
|
||
|
L'E', L'D', L'C', L'R', L'F', L'V', L'5', L'T',
|
||
|
L'G', L'B', L'Y', L'H', L'N', L'U', L'J', L'M',
|
||
|
L'8', L'I', L'K', L',', L'9', L'O', L'L', L'.',
|
||
|
L'0', L'P', L';', L'/', L'-', L' ', L'6', L'3',
|
||
|
L'4', L'7' };
|
||
|
|
||
|
|
||
|
DWORD GetPattern( WORD *pWord )
|
||
|
{
|
||
|
int i, j;
|
||
|
WORD wValue;
|
||
|
DWORD dwPat, dwSeq;
|
||
|
|
||
|
dwPat = 0;
|
||
|
|
||
|
for (i=0; i<3; i++) {
|
||
|
|
||
|
wValue = *(pWord+i);
|
||
|
dwSeq = 0;
|
||
|
|
||
|
if ( wValue != L' ' ) {
|
||
|
|
||
|
for (j=0; j<43; j++) {
|
||
|
if ( wValue == Seq2Key[j] ) {
|
||
|
dwSeq = j;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
dwPat = (dwPat << 6) + dwSeq;
|
||
|
}
|
||
|
|
||
|
// handle the last character, it should be one of five tones.
|
||
|
|
||
|
wValue = *(pWord+3);
|
||
|
dwSeq = 0;
|
||
|
for (j=38; j<43; j++) {
|
||
|
if ( wValue == Seq2Key[j] ) {
|
||
|
dwSeq = j;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dwPat = (dwPat << 6) + dwSeq;
|
||
|
|
||
|
return dwPat;
|
||
|
|
||
|
}
|
||
|
|
||
|
void _cdecl main( int argc, TCHAR **argv) {
|
||
|
|
||
|
HANDLE hInBig5File, hInGBFile, hOutSrcFile;
|
||
|
HANDLE hInBig5Map, hInGBMap;
|
||
|
LPWORD lpInBig5File, lpInGBFile, lpStartBig5, lpStartGB;
|
||
|
DWORD dwBig5Line, dwGBLine;
|
||
|
DWORD iBig5Line, iGBLine, i;
|
||
|
DWORD dwInFileSize, BytesWritten;
|
||
|
WORD wOutData;
|
||
|
DWORD dwPatternBig5, dwPatternGB;
|
||
|
|
||
|
if ( argc != 4 ) {
|
||
|
printf("Usage: gennpsrc <Big5> <GB File> <New UnicdFile> \n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
hInBig5File = CreateFile( argv[1], // pointer to name of the file
|
||
|
GENERIC_READ, // access (read-write) mode
|
||
|
FILE_SHARE_READ, // share mode
|
||
|
NULL, // pointer to security attributes
|
||
|
OPEN_EXISTING, // how to create
|
||
|
FILE_ATTRIBUTE_NORMAL, // file attributes
|
||
|
NULL);
|
||
|
|
||
|
if ( hInBig5File == INVALID_HANDLE_VALUE ) return;
|
||
|
|
||
|
hInGBFile = CreateFile( argv[2], // pointer to name of the file
|
||
|
GENERIC_READ, // access (read-write) mode
|
||
|
FILE_SHARE_READ, // share mode
|
||
|
NULL, // pointer to security attributes
|
||
|
OPEN_EXISTING, // how to create
|
||
|
FILE_ATTRIBUTE_NORMAL, // file attributes
|
||
|
NULL);
|
||
|
|
||
|
if ( hInGBFile == INVALID_HANDLE_VALUE ) {
|
||
|
printf("hInGBFile is INVALID_HANDLE_VALUE\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
hOutSrcFile = CreateFile(argv[3], // pointer to name of the file
|
||
|
GENERIC_WRITE, // access (read-write) mode
|
||
|
FILE_SHARE_WRITE, // share mode
|
||
|
NULL, // pointer to security attributes
|
||
|
CREATE_ALWAYS, // how to create
|
||
|
FILE_ATTRIBUTE_NORMAL, // file attributes
|
||
|
NULL);
|
||
|
|
||
|
if ( hOutSrcFile == INVALID_HANDLE_VALUE ) {
|
||
|
printf("hOutSrcFile is INVALID_HANDLE_VALUE\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
hInBig5Map = CreateFileMapping(hInBig5File, // handle to file to map
|
||
|
NULL, // optional security attributes
|
||
|
PAGE_READONLY, // protection for mapping object
|
||
|
0, // high-order 32 bits of object size
|
||
|
0, // low-order 32 bits of object size
|
||
|
NULL); // name of file-mapping object);
|
||
|
if ( !hInBig5Map ) {
|
||
|
printf("hInBig5Map is NULL\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
hInGBMap = CreateFileMapping(hInGBFile, // handle to file to map
|
||
|
NULL, // optional security attributes
|
||
|
PAGE_READONLY, // protection for mapping object
|
||
|
0, // high-order 32 bits of object size
|
||
|
0, // low-order 32 bits of object size
|
||
|
NULL); // name of file-mapping object);
|
||
|
if ( !hInGBMap ) {
|
||
|
printf("hInGBMap is NULL\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
lpInBig5File = (LPWORD)MapViewOfFile(hInBig5Map, FILE_MAP_READ, 0, 0, 0);
|
||
|
|
||
|
lpInGBFile = (LPWORD)MapViewOfFile(hInGBMap, FILE_MAP_READ, 0, 0, 0);
|
||
|
|
||
|
lpStartBig5 = lpInBig5File + 1; // skip Unicode header signature 0xFEFF
|
||
|
|
||
|
lpStartGB = lpInGBFile + 1; // skip Unicode header signature 0xFEFF
|
||
|
|
||
|
dwInFileSize = GetFileSize(hInBig5File, NULL) - 2; // sub head two bytes
|
||
|
|
||
|
dwBig5Line = dwInFileSize / LINELEN;
|
||
|
|
||
|
dwInFileSize = GetFileSize(hInGBFile, NULL) - 2;
|
||
|
|
||
|
dwGBLine = dwInFileSize / LINELEN;
|
||
|
|
||
|
wOutData = 0xFEFF;
|
||
|
WriteFile(hOutSrcFile, // handle to file to write to
|
||
|
&wOutData, // pointer to data to write to file
|
||
|
2, // number of bytes to write
|
||
|
&BytesWritten, // pointer to number of bytes written
|
||
|
NULL); // pointer to structure needed for
|
||
|
// overlapped I/O
|
||
|
iBig5Line=iGBLine=0;
|
||
|
while ((iBig5Line < dwBig5Line) && (iGBLine < dwGBLine)) {
|
||
|
|
||
|
dwPatternBig5 = GetPattern(lpStartBig5);
|
||
|
dwPatternGB = GetPattern(lpStartGB);
|
||
|
|
||
|
if (dwPatternBig5 < dwPatternGB ) {
|
||
|
// in this case, we just keep all lines in Big5 File which have same
|
||
|
// dwpattern to new generated file.
|
||
|
|
||
|
// write lpStartBig5 to OutSrcFile
|
||
|
|
||
|
WriteFile(hOutSrcFile, // handle to file to write to
|
||
|
lpStartBig5, // pointer to data to write to file
|
||
|
LINELEN, // number of bytes to write
|
||
|
&BytesWritten, // pointer to number of bytes written
|
||
|
NULL); // pointer to structure needed for
|
||
|
// overlapped I/O
|
||
|
|
||
|
lpStartBig5 += LINELEN/sizeof(WORD);
|
||
|
iBig5Line ++;
|
||
|
|
||
|
while ( (iBig5Line < dwBig5Line) &&
|
||
|
(GetPattern(lpStartBig5) == dwPatternBig5) ) {
|
||
|
|
||
|
WriteFile(hOutSrcFile, // handle to file to write to
|
||
|
lpStartBig5, // pointer to data to write to file
|
||
|
LINELEN, // number of bytes to write
|
||
|
&BytesWritten, // pointer to number of bytes written
|
||
|
NULL); // pointer to structure needed for
|
||
|
// overlapped I/O
|
||
|
lpStartBig5 += LINELEN/sizeof(WORD);
|
||
|
iBig5Line ++;
|
||
|
}
|
||
|
}
|
||
|
else if ( dwPatternBig5 == dwPatternGB ) {
|
||
|
// in this case, we will put all the lines in BIG5 and then in GB with
|
||
|
// the same dwpattern to the new generated file.
|
||
|
|
||
|
WriteFile(hOutSrcFile, // handle to file to write to
|
||
|
lpStartBig5, // pointer to data to write to file
|
||
|
LINELEN, // number of bytes to write
|
||
|
&BytesWritten, // pointer to number of bytes written
|
||
|
NULL); // pointer to structure needed for
|
||
|
// overlapped I/O
|
||
|
|
||
|
lpStartBig5 += LINELEN/sizeof(WORD);
|
||
|
iBig5Line ++;
|
||
|
|
||
|
while ( (iBig5Line < dwBig5Line) &&
|
||
|
(GetPattern(lpStartBig5) == dwPatternBig5) ) {
|
||
|
|
||
|
WriteFile(hOutSrcFile, // handle to file to write to
|
||
|
lpStartBig5, // pointer to data to write to file
|
||
|
LINELEN, // number of bytes to write
|
||
|
&BytesWritten, // pointer to number of bytes written
|
||
|
NULL); // pointer to structure needed for
|
||
|
// overlapped I/O
|
||
|
lpStartBig5 += LINELEN/sizeof(WORD);
|
||
|
iBig5Line ++;
|
||
|
}
|
||
|
|
||
|
WriteFile(hOutSrcFile, // handle to file to write to
|
||
|
lpStartGB, // pointer to data to write to file
|
||
|
LINELEN, // number of bytes to write
|
||
|
&BytesWritten, // pointer to number of bytes written
|
||
|
NULL); // pointer to structure needed for
|
||
|
// overlapped I/O
|
||
|
|
||
|
lpStartGB += LINELEN/sizeof(WORD);
|
||
|
iGBLine ++;
|
||
|
|
||
|
while ( (iGBLine < dwGBLine) &&
|
||
|
(GetPattern(lpStartGB) == dwPatternGB) ) {
|
||
|
|
||
|
WriteFile(hOutSrcFile, // handle to file to write to
|
||
|
lpStartGB, // pointer to data to write to file
|
||
|
LINELEN, // number of bytes to write
|
||
|
&BytesWritten, // pointer to number of bytes written
|
||
|
NULL); // pointer to structure needed for
|
||
|
// overlapped I/O
|
||
|
lpStartGB += LINELEN/sizeof(WORD);
|
||
|
iGBLine ++;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
// in this case, we just put all the lines with same pattern in file
|
||
|
// GB to the new generated file.
|
||
|
|
||
|
WriteFile(hOutSrcFile, // handle to file to write to
|
||
|
lpStartGB, // pointer to data to write to file
|
||
|
LINELEN, // number of bytes to write
|
||
|
&BytesWritten, // pointer to number of bytes written
|
||
|
NULL); // pointer to structure needed for
|
||
|
// overlapped I/O
|
||
|
|
||
|
lpStartGB += LINELEN/sizeof(WORD);
|
||
|
iGBLine ++;
|
||
|
|
||
|
while ( (iGBLine < dwGBLine) &&
|
||
|
(GetPattern(lpStartGB) == dwPatternGB) ) {
|
||
|
|
||
|
WriteFile(hOutSrcFile, // handle to file to write to
|
||
|
lpStartGB, // pointer to data to write to file
|
||
|
LINELEN, // number of bytes to write
|
||
|
&BytesWritten, // pointer to number of bytes written
|
||
|
NULL); // pointer to structure needed for
|
||
|
// overlapped I/O
|
||
|
lpStartGB += LINELEN/sizeof(WORD);
|
||
|
iGBLine ++;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
} // while ...
|
||
|
|
||
|
if ( iBig5Line < dwBig5Line ) {
|
||
|
|
||
|
while ( iBig5Line < dwBig5Line ) {
|
||
|
|
||
|
WriteFile(hOutSrcFile, // handle to file to write to
|
||
|
lpStartBig5, // pointer to data to write to file
|
||
|
LINELEN, // number of bytes to write
|
||
|
&BytesWritten, // pointer to number of bytes written
|
||
|
NULL); // pointer to structure needed for
|
||
|
// overlapped I/O
|
||
|
lpStartBig5 += LINELEN/sizeof(WORD);
|
||
|
iBig5Line ++;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if ( iGBLine < dwGBLine ) {
|
||
|
|
||
|
while ( iGBLine < dwGBLine ) {
|
||
|
|
||
|
WriteFile(hOutSrcFile, // handle to file to write to
|
||
|
lpStartGB, // pointer to data to write to file
|
||
|
LINELEN, // number of bytes to write
|
||
|
&BytesWritten, // pointer to number of bytes written
|
||
|
NULL); // pointer to structure needed for
|
||
|
// overlapped I/O
|
||
|
lpStartGB += LINELEN/sizeof(WORD);
|
||
|
iGBLine ++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
UnmapViewOfFile(lpInBig5File);
|
||
|
UnmapViewOfFile(lpInGBFile);
|
||
|
|
||
|
CloseHandle(hInBig5Map);
|
||
|
CloseHandle(hInGBMap);
|
||
|
|
||
|
CloseHandle(hInBig5File);
|
||
|
CloseHandle(hInGBFile);
|
||
|
CloseHandle(hOutSrcFile);
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|