TRANUC.CPP
上传用户:zhang8947
上传日期:2007-01-08
资源大小:1910k
文件大小:11k
- //UCDOS输入法文本文件转换程序
- #include "stdafx.h"
- #include "windowsx.h"
- #include "tranuc.h"
- #include "csinput.h"
- CTranUcdos OTranUcdos ;
- //转换的接口
- BOOL CTranUcdos::TranslateUcdos( CString pathName )
- {
- //组织库文件名
- strcpy( m_sLibName , pathName ) ;
- m_sLibName[strlen(m_sLibName)-3] =' ' ;
- strcat( m_sLibName , "iml" ) ;
-
- //打开原文件
- CFile file ;
- if( !file.Open( pathName , CFile::modeRead|CFile::typeBinary ) )
- {
- AfxMessageBox( "Open file error" ) ;
- return 0 ;
- }
- //得到文件长度
- m_dwSourceLen =file.GetLength() ;
- //分配地址空间
- m_hpsSource =(char huge*)GlobalAllocPtr( GMEM_FIXED ,
- m_dwSourceLen ) ;
- if( !m_hpsSource )
- {
- AfxMessageBox( "GlobalAllocPtr error" ) ;
- file.Close() ;
- return 0 ;
- }
- //读出源文件内容
- file.ReadHuge( m_hpsSource , m_dwSourceLen ) ;
- //关闭文件
- file.Close() ;
-
- //对源库进行分析,以生成我的库
- //设置初始值
- //整个库所占字节数
- inputLibHead.dwTotalBytes =sizeof( INPUT_LIB_HEAD ) ;
- inputLibHead.dwTotalWords =0 ; //整个库中的词条数目
- inputLibHead.sName[0] =' ' ; //输入法名,以' '结束
- inputLibHead.nFunctionKey =0 ; //功能键号
- inputLibHead.nGodKey ='z' ; //万能键
- inputLibHead.nMaxCodeLen =0 ; //最大码长
- for( int i=0 ; i<CODE_CELL_NUM ; i++ )
- {
- inputLibHead.sCodeCells[i] =0 ;
- inputLibHead.dwIndex[i] =0 ; //首码索引表
- }
-
- Analysis() ;
-
- //释放申请的空间
- GlobalFreePtr( m_hpsSource ) ;
-
- //产生我的输入法文件
- CreateMyLib() ;
-
- return 1 ;
- }
- //创建我的输入法库
- void CTranUcdos::CreateMyLib( void )
- {
- DWORD dwLibPoint =sizeof( INPUT_LIB_HEAD ) ; //库指针
- char sFileName[13] ="a.tmp" ;
- CFile file ;
- DWORD dwFileLen ;
- char huge *hpsFile ;
-
- CFile libFile ; //库文件
- if( !libFile.Open( m_sLibName , CFile::modeReadWrite|
- CFile::modeCreate|
- CFile::typeBinary ) )
- {
- AfxMessageBox( "创建.iml文件失败" ) ;
- return ;
- }
- //将库头写入,主要是为了定位
- libFile.Write( &inputLibHead , sizeof( INPUT_LIB_HEAD ) ) ;
-
- INPUT_LIB_ITEM huge *pItem ;
- DWORD j ;
- DWORD dwItemNum ;
- int nItemLen ;
-
- for( int i=0 ; i<CODE_CELL_NUM ; i++ )
- {
- if( !inputLibHead.sCodeCells[i] ) //没有这个元
- continue ;
- //组织文件名
- sFileName[0] =i+33 ;
- //打开文件
- if( !file.Open( sFileName , CFile::modeRead|CFile::typeBinary ) )
- continue ; //可能该文件不存在
- //得到文件长度
- dwFileLen =file.GetLength() ;
- if( dwFileLen % sizeof( INPUT_LIB_ITEM ) )
- {
- AfxMessageBox( "文件长度不对" ) ;
- return ;
- }
- //分配空间
- hpsFile =(char huge*)GlobalAllocPtr( GMEM_FIXED ,
- dwFileLen ) ;
- if( !hpsFile )
- {
- AfxMessageBox( "GlobalAllocPtr error" ) ;
- return ;
- }
- //读出内容
- file.ReadHuge( hpsFile , dwFileLen ) ;
- //关闭文件
- file.Close() ;
- //删除该文件
- remove( sFileName ) ;
-
- //对该内容进行排序
- SortContent( hpsFile , dwFileLen ) ;
-
- //填写该码元检索表
- inputLibHead.dwIndex[i] =dwLibPoint ;
- //将排序结果写入库文件
- dwItemNum =dwFileLen/sizeof( INPUT_LIB_ITEM) ;
- pItem =(INPUT_LIB_ITEM huge*)hpsFile ;
- for( j=0 ; j<dwItemNum ; j++ )
- {
- //项长度
- nItemLen =1 + pItem->nEnglishLen + pItem->nChineseLen ;
- dwLibPoint +=nItemLen ; //修改库指针
- //写入项长度
- libFile.Write( &nItemLen , 1 ) ;
- //写入英文串
- libFile.Write( pItem->sEnglish , pItem->nEnglishLen ) ;
- //写入汉字串
- libFile.Write( pItem->sChinese , pItem->nChineseLen ) ;
-
- pItem++ ;
- }
-
- //释放空间
- GlobalFreePtr( hpsFile ) ;
- }
- //定位到库开始,重新写入库头
- libFile.SeekToBegin() ;
- libFile.Write( &inputLibHead , sizeof( INPUT_LIB_HEAD ) ) ;
- //关闭库文件
- libFile.Close() ;
-
- if( dwLibPoint != inputLibHead.dwTotalBytes )
- AfxMessageBox( "dwLibPoint!==dwTotalBytes" ) ;
- }
-
- //对该内容进行排序
- void CTranUcdos::SortContent( char huge *hpsFile , DWORD dwFileLen )
- {
- int nItemLen =sizeof( INPUT_LIB_ITEM ) ;
- DWORD dwItemNum =dwFileLen/nItemLen ; //项数
- INPUT_LIB_ITEM huge *pItem1 ;
- INPUT_LIB_ITEM huge *pItem2 ; //排序用
- INPUT_LIB_ITEM item ; //排序用缓冲区
- DWORD i , j ;
- int n ;
-
- for( i=0 ; i<dwItemNum ; i++ )
- {
- pItem1 =(INPUT_LIB_ITEM huge*)( hpsFile + i*nItemLen ) ;
- for( j=i+1 ; j<dwItemNum ; j++ )
- {
- pItem2 =(INPUT_LIB_ITEM huge*)( hpsFile + j*nItemLen ) ;
- //比较两者的编码
- n =_fstrncmp( pItem1->sEnglish , pItem2->sEnglish ,
- min( pItem1->nEnglishLen , pItem2->nEnglishLen ) ) ;
- if( !n ) //两者相等,长者在后,短者在前
- {
- if( pItem1->nEnglishLen > pItem2->nEnglishLen ) //交换
- {
- CopyInputItem( &item , pItem1 ) ;
- CopyInputItem( pItem1 , pItem2 ) ;
- CopyInputItem( pItem2 , &item ) ;
- }
- continue ;
- }
-
- if( n>0 ) //前者大,需要交换
- {
- CopyInputItem( &item , pItem1 ) ;
- CopyInputItem( pItem1 , pItem2 ) ;
- CopyInputItem( pItem2 , &item ) ;
- }
- //前者小,不需要交换
- }
- }
- }
- //拷贝输入项
- void CTranUcdos::CopyInputItem( INPUT_LIB_ITEM huge *item1 ,
- INPUT_LIB_ITEM huge *item2 )
- {
- item1->nEnglishLen =item2->nEnglishLen ;
- item1->nChineseLen =item2->nChineseLen ;
- _fstrncpy( item1->sEnglish , item2->sEnglish , item2->nEnglishLen ) ;
- _fstrncpy( item1->sChinese , item2->sChinese , item2->nChineseLen ) ;
- }
- void CTranUcdos::ShowResult( CDC *pdc )
- {
- char sBuff[100] ;
- int y =32 ;
-
- wsprintf( sBuff , "输入法名:%s" , inputLibHead.sName ) ;
- pdc->TextOut( 0 , y , sBuff , strlen( sBuff ) ) ;
- y +=16 ;
- wsprintf( sBuff , "功能键号:%c" , inputLibHead.nFunctionKey ) ;
- pdc->TextOut( 0 , y , sBuff , strlen( sBuff ) ) ;
- y +=16 ;
- wsprintf( sBuff , "万能键:%c" , inputLibHead.nGodKey ) ;
- pdc->TextOut( 0 , y , sBuff , strlen( sBuff ) ) ;
- y +=16 ;
- wsprintf( sBuff , "最大码长:%d" , inputLibHead.nMaxCodeLen ) ;
- pdc->TextOut( 0 , y , sBuff , strlen( sBuff ) ) ;
- y +=16 ;
- wsprintf( sBuff , "总字节数:%lu 总行数:%lu 总词条数:%lu" ,
- inputLibHead.dwTotalBytes ,
- m_dwTotalLines , inputLibHead.dwTotalWords ) ;
- pdc->TextOut( 0 , y , sBuff , strlen( sBuff ) ) ;
- }
- //得到一行
- BOOL CTranUcdos::GetOneLine( char *sLineBuff )
- {
- if( m_dwSourcePoint >= m_dwSourceLen ) //完了
- return 0 ;
- int nLineLen =0 ; //行长度
- for( ; m_dwSourcePoint < m_dwSourceLen ; m_dwSourcePoint++ )
- {
- if( m_dwSourcePoint < m_dwSourceLen-1 )
- {
- if( m_hpsSource[m_dwSourcePoint] == 0x0d &&
- m_hpsSource[m_dwSourcePoint+1] == 0x0a ) //行结束
- {
- m_dwSourcePoint +=2 ;
- break ;
- }
- }
- sLineBuff[nLineLen++] =m_hpsSource[m_dwSourcePoint] ;
- }
-
- sLineBuff[nLineLen] =' ' ;
- return 1 ;
- }
-
- //分析源库文件(指UCDOS输入法文本文件格式)
- BOOL CTranUcdos::Analysis( void )
- {
- char sLineBuff[201] ; //行缓冲
- //------------------------------------------------------------------//
-
- m_dwTotalLines =0 ;
- m_dwSourcePoint =0 ; //源库指针指向库头
- while( 1 )
- {
- //得到一行
- if( !GetOneLine( sLineBuff ) ) //到达库尾
- return 1 ;
- m_dwTotalLines++ ;
- if( sLineBuff[0] == ' ' || sLineBuff[0] == ' ' ) //行结束或空格
- continue ; //放弃该行
-
- if( sLineBuff[0] & 0x80 ) //是汉字
- {
- if( !AnalysisHead( sLineBuff ) ) //分析头
- return 0 ;
- }
- else //头个字母是英文,说明这行是编码内容
- {
- inputLibHead.dwTotalWords++ ; //词数增加
- if( !AnalysisContent( sLineBuff ) ) //分析编码项
- return 0 ;
- }
- }
-
- return 1 ;
- }
- BOOL CTranUcdos::AnalysisContent( char *psLine )
- {
- char sTmpFile[13] ="a.tmp" ; //临时文件名
- CFile tmpFile ;
-
- sTmpFile[0] =psLine[0] ; //构造文件名
- //打开该文件
- if( !tmpFile.Open( sTmpFile , CFile::modeReadWrite|CFile::typeBinary ) )
- {
- //创建该文件
- if( !tmpFile.Open( sTmpFile , CFile::modeReadWrite|CFile::modeCreate|CFile::typeBinary ) )
- {
- AfxMessageBox( "创建文件失败" ) ;
- return 0 ;
- }
- }
- else
- //定位到文件尾
- tmpFile.SeekToEnd() ;
-
- INPUT_LIB_ITEM item ; //英文,汉字对照项
- item.nEnglishLen =0 ;
- item.nChineseLen =0 ;
- //去掉行首空格
- for( ; (*psLine) == ' ' ; psLine++ )
- ;
- //得到英文编码
- for( ; (*psLine) && (*psLine)!=' ' ; psLine++ )
- item.sEnglish[item.nEnglishLen++] =*psLine ;
- //去掉空格
- for( ; (*psLine) == ' ' ; psLine++ )
- ;
- if( !(*psLine) ) //到达行尾
- {
- char sBuff[50] ;
- wsprintf( sBuff , "第%d行只有编码,没有汉字" , m_dwTotalLines ) ;
- AfxMessageBox( sBuff ) ;
- return 0 ;
- }
- //得到汉字,直到行末
- for( ; *psLine ; )
- {
- if( (*psLine) == ' ' )
- {
- item.sChinese[item.nChineseLen++] =' ' ;
- //去掉其后的所有空 格
- for( psLine++ ; (*psLine) && (*psLine)==' ' ; psLine ++ )
- ;
- }
- else
- item.sChinese[item.nChineseLen++] =*psLine++ ;
- }
-
- //写入文件
- tmpFile.Write( &item , sizeof( INPUT_LIB_ITEM ) ) ;
- //关闭文件
- tmpFile.Close() ;
-
- int nBuffLen =1+item.nEnglishLen+item.nChineseLen ;
- inputLibHead.dwTotalBytes +=nBuffLen ;
-
- return 1 ;
- }
-
- //分析UCDOS输入法文本文件的头
- BOOL CTranUcdos::AnalysisHead( char *psLine )
- {
- int nFlag ;
- int nNameLen ; //等号后内容的长度
- char *psNamePoint ; //等号后内容的名字
-
- int i ;
-
- nFlag =0 ;
- if( !strncmp( "名称" , psLine , 4 ) ) //是输入法名称
- {
- nFlag =1 ;
- psLine +=4 ;
- }
- else if( !strncmp( "功能键号" , psLine , 8 ) )
- {
- nFlag =2 ;
- psLine +=8 ;
- }
- else if( !strncmp( "码元表" , psLine , 6 ) )
- {
- nFlag =3 ;
- psLine +=6 ;
- }
- else if( !strncmp( "万能键" , psLine , 6 ) )
- {
- nFlag =4 ;
- psLine +=6 ;
- }
- else if( !strncmp( "最大码长" , psLine , 8 ) )
- {
- nFlag =5 ;
- psLine +=8 ;
- }
-
- if( !nFlag ) //不需要的东西
- return 1 ;
-
- //去掉空格和等号
- for( ; (*psLine) == ' ' || (*psLine) == '=' ; psLine++ )
- ;
- //得到下一串内容(在碰到空格或行结束之前)
- psNamePoint =psLine ;
- for( nNameLen=0 ; (*psLine) && (*psLine)!=' ' ;
- nNameLen++,psLine++)
- ;
- if( !nNameLen )
- {
- AfxMessageBox( "等号后没有东西" ) ;
- return 0 ;
- }
-
- switch( nFlag )
- {
- case 1: //输入法名称
- if( nNameLen > MAX_NAME_LEN ) //太长
- {
- AfxMessageBox( "文件名太长" ) ;
- return 0 ;
- }
- //得到文件名
- strncpy( inputLibHead.sName , psNamePoint , nNameLen ) ;
- inputLibHead.sName[nNameLen] =' ' ;
- break ;
- case 2: //功能键号
- if( nNameLen > 1 )
- {
- AfxMessageBox( "功能键号不是个位数" ) ;
- return 0 ;
- }
- inputLibHead.nFunctionKey =(int)(*psNamePoint) ;
- break ;
- case 3: //码元表
- if( nNameLen > CODE_CELL_NUM )
- {
- AfxMessageBox( "码元太多了" ) ;
- return 0 ;
- }
- for( i=0 ; i<nNameLen ; i++ ) //得到码元
- {
- if( psNamePoint[i] < 33 || psNamePoint[i] > 126 )
- {
- AfxMessageBox( "码元不合法" ) ;
- return 0 ;
- }
- //设上标记
- inputLibHead.sCodeCells[psNamePoint[i]-33] =1 ;
- }
- break ;
- case 4: //万能键
- if( nNameLen > 1 )
- {
- AfxMessageBox( "万能键不是一个键" ) ;
- return 0 ;
- }
- inputLibHead.nGodKey =(int)(*psNamePoint) ;
- break ;
- case 5: //最大码长
- psNamePoint[nNameLen] =' ' ;
- i =atoi( psNamePoint ) ; //将字符串转换成整数
- if( i<=0 || i>MAX_CODE_LEN )
- {
- AfxMessageBox( "最大码长不对" ) ;
- return 0 ;
- }
- inputLibHead.nMaxCodeLen =i ;
- break ;
- }
-
- return 1 ;
- }
- #ifdef __cplusplus
- extern "C" {
- #endif
- BOOL __export FAR PASCAL TranslateUcdos( LPCSTR pathName )
- {
- return OTranUcdos.TranslateUcdos( pathName ) ;
- }
- #ifdef __cplusplus
- }
- #endif