Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1535 lines
47 KiB

  1. /*************************************************
  2. * conv.c *
  3. * *
  4. * Copyright (C) 1995-1999 Microsoft Inc. *
  5. * *
  6. *************************************************/
  7. #include "conv.h"
  8. DWORD dwBaseWordNum;
  9. HGLOBAL hCreateWord;
  10. HGLOBAL hWordIndex;
  11. HGLOBAL hEncode;
  12. #ifdef UNICODE
  13. TCHAR Title[] = {0x6D4F, 0x89C8, 0x0000};
  14. TCHAR szVer[] = {0x8F93, 0x5165, 0x6CD5, 0x0020, 0x7248, 0x672C, 0x0000};
  15. #else
  16. BYTE Title[] = "����";
  17. BYTE szVer[] = "���뷨 �汾";
  18. #endif
  19. /*****************************************************************************
  20. FUNCTION: ConvConv(HANDLE hWnd,LPCSTR lpSrcFileName, LPCSTR lpszMBFileName)
  21. PURPOSE: Processes MB conversion .
  22. PARAMETERS:
  23. hWnd - window handle of the parent window.
  24. lpSrcFileName - pointer to source text file name.
  25. lpszMBFileName - pointer to destinate .mb file name.
  26. RETURN VALUE:
  27. TRUE - conversion completed
  28. FALSE - conversion not completed
  29. HISTORY:
  30. ****************************************************************************/
  31. BOOL ConvConv(HANDLE hWnd,LPCTSTR lpSrcFileName, LPCTSTR lpszMBFileName)
  32. {
  33. int nTemp;
  34. DWORD dwDBCS;
  35. DWORD dwRuleOffset, dwRuleLen;
  36. DWORD dwDesOffset, dwDesLen;
  37. DWORD i;
  38. int nPages;
  39. TCHAR szDBCS[512];
  40. //dwRuleOffset: Rule segment's offset in source file
  41. MAINID MainID;
  42. LPMAININDEX lpMainIndex;
  43. LPCREATEWORD lpCreateWords;
  44. DESCRIPTION Descript;
  45. LPWORDINDEX lpWordIndex;
  46. LPRULE lpRule;
  47. HANDLE hReConvIndex, hMainIndex;
  48. LPRECONVINDEX lpReConvIndex;
  49. LPENCODEAREA lpEncode;
  50. DispInfo(hWnd,IDS_CONVERTINFO);
  51. nTemp = (int)ConvGetDescript(hWnd,lpSrcFileName,&dwDesOffset,
  52. &dwDesLen,&Descript,FALSE);
  53. if(nTemp == -ERR_FILENOTOPEN || nTemp < -4 )
  54. return FALSE;
  55. hMainIndex = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof(MAININDEX)*NUMTABLES);
  56. if(!(lpMainIndex = GlobalLock(hMainIndex) ) ) {
  57. ProcessError(ERR_GLOBALLOCK,hWnd,ERR);
  58. return FALSE;
  59. }
  60. ConvInit(&Descript,&MainID,lpMainIndex);
  61. nPages = 1;
  62. dwBaseWordNum = 0;
  63. nTemp = sizeof(WORDINDEX)*GMEM_PAGESIZE;
  64. hWordIndex=GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, nTemp);
  65. hCreateWord = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,
  66. (DWORD)Descript.wMaxCodes*NUM_OF_ENCODE*sizeof(TCHAR));
  67. if(!hMainIndex||!hCreateWord || !hWordIndex || !hRule) {
  68. ProcessError(ERR_OUTOFMEMORY,hWnd,ERR);
  69. goto err;
  70. }
  71. if(!(lpCreateWords = GlobalLock(hCreateWord) )
  72. ||!(lpWordIndex = (LPWORDINDEX) GlobalLock(hWordIndex))
  73. ||!(lpRule = GlobalLock(hRule)) ) {
  74. ProcessError(ERR_GLOBALLOCK,hWnd,ERR);
  75. goto err;
  76. }
  77. if(ConvGetRule(hWnd,lpSrcFileName,&dwRuleOffset,&dwRuleLen,
  78. lpRule,&Descript)<=0)
  79. goto err;
  80. hSRCFile = Create_File(hWnd,lpSrcFileName,GENERIC_READ,OPEN_EXISTING);
  81. if (hSRCFile == (HANDLE)-1)
  82. return FALSE;
  83. hMBFile = Create_File(hWnd,lpszMBFileName,GENERIC_READ|GENERIC_WRITE,
  84. CREATE_ALWAYS);
  85. if (hMBFile == (HANDLE)-1) {
  86. CloseHandle(hSRCFile);
  87. return FALSE;
  88. }
  89. if(!ConvWriteMainID(hMBFile,&MainID)) {
  90. ProcessError(ERR_WRITEID,hWnd,ERR);
  91. goto err;
  92. }
  93. if(!ConvWriteMainIndex(hMBFile,lpMainIndex)) {
  94. ProcessError(ERR_WRITEMAININDEX,hWnd,ERR);
  95. goto err;
  96. }
  97. if(!ConvWriteDescript(hMBFile, &Descript, lpMainIndex)) {
  98. ProcessError(ERR_WRITEDESCRIPT,hWnd,ERR);
  99. goto err;
  100. }
  101. if(lpMainIndex[TAG_RULE-1].dwLength != 0)
  102. if(!ConvWriteRule( hMBFile,Descript.wNumRules,lpRule, lpMainIndex)) {
  103. ProcessError(ERR_WRITERULE,hWnd,ERR);
  104. goto err;
  105. }
  106. hReConvIndex = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,
  107. (DWORD)Descript.wMaxCodes*NUM_OF_ENCODE*sizeof(TCHAR));
  108. if(!hReConvIndex) {
  109. ProcessError(ERR_OUTOFMEMORY,hWnd,ERR);
  110. goto err;
  111. }
  112. if(!(lpReConvIndex = GlobalLock(hReConvIndex))
  113. || !(lpEncode = GlobalLock(hEncode)) ) {
  114. ProcessError(ERR_GLOBALLOCK,hWnd,ERR);
  115. goto err;
  116. }
  117. DispInfo(hWnd,IDS_READTEXTINFO);
  118. if(!ReadSRCFile(hWnd,&nPages,hSRCFile,lpCreateWords,
  119. lpWordIndex,&dwDBCS,&Descript,lpReConvIndex)) {
  120. goto err;
  121. }
  122. DispInfo(hWnd,IDS_WRCRTINFO);
  123. //****** fill code mapping *****
  124. ConvWriteEncode(hMBFile,lpEncode,lpMainIndex);
  125. if(Descript.wNumRules != 0) {
  126. LoadString(NULL,IDS_ISCHECKCRTWORD,szDBCS, sizeof(szDBCS)/sizeof(TCHAR));
  127. if(ErrMessage(hWnd, szDBCS))
  128. {
  129. if(!CheckCrtData(hWnd,lpCreateWords,lpEncode,Descript.wMaxCodes) ) {
  130. ProcessError(ERR_GB2312NOTENTIRE,hWnd,ERR);
  131. goto err;
  132. }
  133. }
  134. } //******* Debug *******
  135. if(lpMainIndex[TAG_CRTWORDCODE-1].dwLength != 0)
  136. ConvWriteCrtData(hMBFile,lpCreateWords,lpMainIndex);
  137. if(lpMainIndex[TAG_RECONVINDEX-1].dwLength != 0)
  138. ConvWriteReConvIdx(hMBFile,lpReConvIndex,lpMainIndex);
  139. GlobalUnlock(hEncode);
  140. //****95.10.12 auto add code for phrases not exist code
  141. SetCursor (LoadCursor (NULL, IDC_WAIT));
  142. if( Descript.wNumRules != 0)
  143. {
  144. for(i=0; i<dwBaseWordNum; i++)
  145. {
  146. if(lpWordIndex[i].wDBCSLen > 1
  147. && (lstrlen(lpWordIndex[i].szCode) == 0)
  148. ) {
  149. SetFilePointer(hSRCFile,lpWordIndex[i].dwOffset,0,FILE_BEGIN);
  150. nTemp = 2*(DWORD)lpWordIndex[i].wDBCSLen;
  151. if (!ReadFile(hSRCFile,szDBCS,nTemp,&dwDBCS,NULL))
  152. goto err;
  153. szDBCS[nTemp] = 0;
  154. ConvBatCreate(hWnd,Descript,lpRule,
  155. lpCreateWords,szDBCS,
  156. lpWordIndex[i].szCode);
  157. if(lpWordIndex[i].szCode[0] == TEXT(',') && lpWordIndex[i].szCode[1] == TEXT('z'))
  158. continue;
  159. if(lstrlen(lpWordIndex[i].szCode) == 0)
  160. {
  161. goto err;
  162. }
  163. }
  164. }
  165. }
  166. SetCursor (LoadCursor (NULL, IDC_ARROW));
  167. DispInfo(hWnd,IDS_SORT);
  168. ConvSort(hWnd,lpWordIndex,dwBaseWordNum);
  169. SetFilePointer(hMBFile,lpMainIndex[TAG_BASEDICINDEX-1].dwOffset,0,FILE_BEGIN);
  170. //***** fill index area with null *****
  171. nTemp = Descript.wNumCodes;
  172. nTemp = sizeof(DWORD)*(nTemp+1)*nTemp;
  173. WriteFile(hMBFile,NULL,nTemp,&nTemp,NULL);
  174. //***** fill index area and length area *****
  175. ConvCalc(hWnd,hMBFile,lpWordIndex,lpMainIndex,&Descript);
  176. //***** fill dictionary area *****
  177. WriteMBFile(hWnd,hSRCFile,hMBFile,lpWordIndex,lpMainIndex,&Descript);
  178. MainID.dwNumWords = dwBaseWordNum;
  179. //***** fill changed MainID *****
  180. ConvWriteMainID(hMBFile,&MainID);
  181. GlobalUnlock(hRule);
  182. if(hCreateWord)
  183. GlobalFree(hCreateWord);
  184. GlobalUnlock(hReConvIndex);
  185. GlobalFree(hReConvIndex);
  186. GlobalUnlock(hWordIndex);
  187. GlobalFree(hWordIndex);
  188. CloseHandle(hMBFile);
  189. CloseHandle(hSRCFile);
  190. ProcessError(ERR_CONVEND, hWnd, INFO);
  191. return TRUE;
  192. err:
  193. if(hSRCFile)
  194. CloseHandle(hSRCFile);
  195. if(hMBFile)
  196. CloseHandle(hMBFile);
  197. if(hMainIndex)
  198. GlobalFree(hMainIndex);
  199. if(hWordIndex)
  200. GlobalFree(hWordIndex);
  201. if(hCreateWord)
  202. GlobalFree(hCreateWord);
  203. if(hReConvIndex)
  204. GlobalFree(hReConvIndex);
  205. if(hRule)
  206. GlobalUnlock(hRule);
  207. return FALSE;
  208. }
  209. /*****************************************************************************
  210. FUNCTION: ConvReadFile(HANDLE hWnd,LPCSTR lpSrcFileName, LPCSTR lpDestFile)
  211. PURPOSE: Processes source text file sorting.
  212. PARAMETERS:
  213. hWnd - window handle of the parent window.
  214. lpSrcFileName - pointer to source text file name.
  215. lpDestFile - pointer to destinate sorted text file name.
  216. RETURN VALUE:
  217. TRUE - sorting completed
  218. FALSE - sorting not completed
  219. HISTORY:
  220. ****************************************************************************/
  221. BOOL ConvReadFile(HANDLE hWnd,
  222. LPCTSTR lpSrcFileName,
  223. LPCTSTR lpDestFile)
  224. {
  225. DWORD i,j;
  226. DWORD dwRuleOffset, dwRuleLen;
  227. DWORD dwDesOffset, dwDesLen;
  228. DWORD dwReadBytes;
  229. DWORD dwFstOffset=0;
  230. DWORD dwOffset=0;
  231. TCHAR szStr[512],szDBCS[512];
  232. TCHAR *Buffer;
  233. BOOL bReadText = FALSE, bSameFile=FALSE;
  234. int nRet;
  235. int nPages;
  236. BOOL IsGenCmb = FALSE;
  237. HANDLE hRule0=NULL;
  238. LPCREATEWORD lpCreateWords;
  239. LPWORDINDEX lpWordIndex;
  240. LPRULE lpRule;
  241. DESCRIPTION Descript;
  242. HANDLE hDlgItem;
  243. Buffer = (TCHAR *)LocalAlloc(LMEM_FIXED, MAXREADBUFFER * sizeof(TCHAR));
  244. if (!Buffer)
  245. return (-ERR_OUTOFMEMORY);
  246. nRet = (int)ConvGetDescript(hWnd,lpSrcFileName,&dwDesOffset,
  247. &dwDesLen,&Descript,FALSE);
  248. if(nRet == -ERR_FILENOTOPEN)
  249. {
  250. LocalFree(Buffer);
  251. return FALSE;
  252. }
  253. if((-nRet)&7)
  254. bReadText = TRUE;
  255. if(Descript.wMaxCodes <= 0)
  256. Descript.wMaxCodes = MAXCODELEN;
  257. nPages = 1;
  258. dwBaseWordNum = 0;
  259. dwReadBytes = sizeof(WORDINDEX)*GMEM_PAGESIZE;
  260. hCreateWord = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,
  261. MAXCODELEN*NUM_OF_ENCODE*sizeof(TCHAR));
  262. hWordIndex=GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, dwReadBytes);
  263. if(!hWordIndex ) {
  264. ProcessError(ERR_OUTOFMEMORY,hWnd,ERR);
  265. goto err;
  266. }
  267. if(!hCreateWord ) {
  268. ProcessError(ERR_OUTOFMEMORY,hWnd,ERR);
  269. goto err;
  270. }
  271. if(!(lpCreateWords = GlobalLock(hCreateWord) )
  272. ||!(lpWordIndex = (LPWORDINDEX) GlobalLock(hWordIndex))
  273. ) {
  274. ProcessError(ERR_GLOBALLOCK,hWnd,ERR);
  275. goto err;
  276. }
  277. hRule0= GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,
  278. sizeof(RULE)*MAXCODELEN);
  279. if(!(lpRule = GlobalLock(hRule0)) ) {
  280. ProcessError(ERR_GLOBALLOCK,hWnd,ERR);
  281. goto err;
  282. }
  283. if(ConvGetRule(hWnd,lpSrcFileName,&dwRuleOffset,&dwRuleLen,
  284. lpRule,&Descript) == -ERR_FILENOTOPEN)
  285. goto err;
  286. hSRCFile = Create_File(hWnd,lpSrcFileName,GENERIC_READ,OPEN_EXISTING);
  287. if (hSRCFile == (HANDLE)-1)
  288. goto err;
  289. if(lstrcmpi(lpDestFile,lpSrcFileName)==0) {
  290. bSameFile = TRUE;
  291. LoadString(NULL,IDS_OVERWRITE,szStr, sizeof(szStr)/sizeof(TCHAR));
  292. StringCchPrintf(szDBCS, ARRAYSIZE(szDBCS), TEXT("\'%s\'\n%s"),lpSrcFileName,szStr);
  293. if(!ErrMessage(hWnd, szDBCS))
  294. {
  295. CloseHandle(hSRCFile);
  296. goto err;
  297. }
  298. #ifdef UNICODE
  299. if(!_waccess(TEXT(TempFile),0))
  300. #else
  301. if(!_access(TEXT(TempFile),0))
  302. #endif
  303. DeleteFile(TEXT(TempFile));
  304. hMBFile = Create_File(hWnd,TEXT(TempFile),GENERIC_WRITE|GENERIC_READ,CREATE_ALWAYS);
  305. }
  306. else
  307. hMBFile = Create_File(hWnd,lpDestFile,GENERIC_WRITE|GENERIC_READ,CREATE_ALWAYS);
  308. if(hMBFile==(HANDLE)-1) {
  309. CloseHandle(hSRCFile);
  310. goto err;
  311. }
  312. CloseHandle(hMBFile);
  313. DispInfo(hWnd,IDS_READTEXTINFO);
  314. SetFilePointer(hSRCFile,0,0,FILE_BEGIN);
  315. szStr[0] = 0;
  316. j = 0;
  317. SetCursor (LoadCursor (NULL, IDC_WAIT));
  318. SetDlgItemText (hWnd,TM_TOTALINFO,TEXT(""));
  319. LoadString(NULL,IDS_SORTWORDS,szStr,sizeof(szStr)/sizeof(TCHAR));
  320. SetDlgItemText (hWnd,TM_TOTAL,szStr);
  321. SetDlgItemInt (hWnd,TM_TOTALNUM,dwBaseWordNum,FALSE);
  322. hDlgItem=GetDlgItem(hWnd,TM_CONVNUM);
  323. InvalidateRect (hWnd,NULL,FALSE);
  324. while(ReadFile(hSRCFile,Buffer,MAXREADBUFFER,&dwReadBytes,NULL))
  325. {
  326. dwReadBytes = dwReadBytes/sizeof(TCHAR);
  327. for(i=0;i<(int)dwReadBytes;i++) {
  328. if(Buffer[i] == 0x0d || Buffer[i] == 0xfeff)
  329. continue;
  330. if(Buffer[i] == TEXT('\n'))
  331. {
  332. szStr[j]=0;
  333. j=0;
  334. if(lstrcmpi(szStr,TEXT(TextSeg))==0) {
  335. bReadText = TRUE;
  336. continue;
  337. }
  338. if(lstrcmpi(szStr,TEXT(RuleSeg))==0
  339. || lstrcmpi(szStr,TEXT(DescriptSeg))==0) {
  340. bReadText = FALSE;
  341. continue;
  342. }
  343. if(bReadText) {
  344. trim(szStr);
  345. if(lstrlen(szStr) != 0) {
  346. nRet = SimpleSplit(hWnd,&nPages,szStr,lpCreateWords,lpWordIndex,Descript.wMaxCodes);
  347. if(nRet == 1)
  348. {
  349. lpWordIndex[dwBaseWordNum-1].dwOffset = dwOffset;
  350. searchPos(lpWordIndex,dwBaseWordNum);
  351. if(dwBaseWordNum%100 == 0)
  352. {
  353. SetDlgItemInt (hWnd,TM_TOTALNUM,dwBaseWordNum,FALSE);
  354. InvalidateRect(hDlgItem,NULL,FALSE);
  355. }
  356. }
  357. }
  358. }
  359. else
  360. lstrcpy(szStr,TEXT(""));
  361. continue;
  362. }
  363. else {
  364. if(j == 0)
  365. dwOffset = dwFstOffset + i*sizeof(TCHAR);
  366. szStr[j]=Buffer[i];
  367. j++;
  368. }
  369. }
  370. if(dwReadBytes*sizeof(TCHAR) < MAXREADBUFFER)
  371. break;
  372. dwFstOffset += MAXREADBUFFER;
  373. };
  374. SetDlgItemInt (hWnd,TM_TOTALNUM,dwBaseWordNum,FALSE);
  375. InvalidateRect(hDlgItem,NULL,FALSE);
  376. if(bSameFile) {
  377. if(dwDesLen != 0)
  378. ConvSaveDescript(TEXT(TempFile),&Descript, 0,0);
  379. if(dwRuleLen != 0)
  380. ConvSaveRule(hWnd,TEXT(TempFile), dwDesLen, 0,
  381. lpRule, Descript.wNumRules);
  382. hMBFile= Create_File(hWnd,TEXT(TempFile),GENERIC_READ|GENERIC_WRITE,OPEN_EXISTING);
  383. }
  384. else {
  385. if(dwDesLen != 0)
  386. ConvSaveDescript(lpDestFile,&Descript, 0,0);
  387. if(dwRuleLen != 0)
  388. ConvSaveRule(hWnd,lpDestFile, dwDesLen, 0,
  389. lpRule, Descript.wNumRules);
  390. hMBFile= Create_File(hWnd,lpDestFile,GENERIC_READ|GENERIC_WRITE,OPEN_EXISTING);
  391. }
  392. SetCursor (LoadCursor (NULL, IDC_ARROW));
  393. if (hMBFile == (HANDLE)-1) {
  394. CloseHandle(hSRCFile);
  395. goto err;
  396. }
  397. SetCursor (LoadCursor (NULL, IDC_WAIT));
  398. DispInfo(hWnd,IDS_WRITETEXTINFO);
  399. {
  400. #ifdef UNICODE
  401. TCHAR cmbStr[] = {0x662F, 0x5426, 0x751F, 0x6210, 0x91CD, 0x7801, 0x8868, 0x0028, 0x0059, 0x002F, 0x004E, 0x0029, 0x003F, 0x0000};
  402. #else
  403. BYTE cmbStr[] = "�Ƿ�����������(Y/N)?";
  404. #endif //UNICODE
  405. TCHAR cmbExt[] = TEXT(".CMB");
  406. LPTSTR lpString;
  407. TCHAR cmbFileName[MAX_PATH];
  408. IsGenCmb = ErrMessage(hWnd, cmbStr);
  409. if(IsGenCmb)
  410. {
  411. StringCchCopy(cmbFileName, ARRAYSIZE(cmbFileName), lpSrcFileName);
  412. if( (lpString = _tcsrchr(cmbFileName, TEXT('.'))) != NULL)
  413. *lpString = 0;
  414. StringCchCat(cmbFileName, ARRAYSIZE(cmbFileName), cmbExt);
  415. hCmbFile= Create_File(hWnd, cmbFileName, GENERIC_READ|GENERIC_WRITE, CREATE_ALWAYS);
  416. if(hCmbFile == (HANDLE)-1)
  417. {
  418. CloseHandle(hSRCFile);
  419. CloseHandle(hMBFile);
  420. goto err;
  421. }
  422. }
  423. }
  424. SetCursor (LoadCursor (NULL, IDC_ARROW));
  425. WriteSortFile(hWnd,hSRCFile,hMBFile,lpWordIndex,lpCreateWords);
  426. GlobalUnlock(hCreateWord);
  427. GlobalFree(hCreateWord);
  428. GlobalFree(hWordIndex);
  429. SetCursor (LoadCursor (NULL, IDC_ARROW));
  430. if(hRule0)
  431. GlobalFree(hRule0);
  432. CloseHandle(hSRCFile);
  433. CloseHandle(hMBFile);
  434. if(hCmbFile > 0)
  435. CloseHandle(hCmbFile);
  436. if(bSameFile) {
  437. DeleteFile(lpSrcFileName);
  438. nRet = MoveFile(TEXT(TempFile),lpSrcFileName);
  439. }
  440. LoadString(NULL,IDS_SORTEND,szStr,ARRAYSIZE(szStr));
  441. #ifdef UNICODE
  442. {
  443. TCHAR UniTmp[]={0x8BCD, 0x8BED, 0x6392, 0x5E8F, 0x0000};
  444. MessageBox(hWnd,szStr,UniTmp,MB_OK);
  445. }
  446. #else
  447. MessageBox(hWnd,szStr,"��������",MB_OK);
  448. #endif
  449. LocalFree(Buffer);
  450. return TRUE;
  451. err:
  452. if(!_taccess(TEXT(TempFile),0))
  453. DeleteFile(TEXT(TempFile));
  454. if(hWordIndex)
  455. GlobalFree(hWordIndex);
  456. if(hCreateWord)
  457. GlobalFree(hCreateWord);
  458. if(hRule0)
  459. GlobalFree(hRule0);
  460. LocalFree(Buffer);
  461. return FALSE;
  462. }
  463. /*****************************************************************************
  464. FUNCTION: ConvReConv(HANDLE hWnd,LPCSTR lpSrcFileName, LPCSTR lpszMBFileName)
  465. PURPOSE: Processes MB reconversion .
  466. PARAMETERS:
  467. hWnd - window handle of the parent window.
  468. lpSrcFileName - pointer to source .mb file name.
  469. lpszMBFileName - pointer to destinate text file name.
  470. RETURN VALUE:
  471. TRUE - reconversion completed
  472. FALSE - reconversion not completed
  473. HISTORY:
  474. 05-21-95 Yehfew Tie modifyed.
  475. ****************************************************************************/
  476. BOOL ConvReConv(HANDLE hWnd,LPCTSTR lpSrcFileName,LPCTSTR lpMBFileName)
  477. {
  478. DWORD dwDesOffset,dwDesLen;
  479. HANDLE hRule0;
  480. MAINID MainID;
  481. LPRULE lpRule;
  482. DESCRIPTION Descript;
  483. HANDLE hReConvIndex;
  484. LPCREATEWORD lpCreateWords, lpReConvIndex;
  485. MAININDEX MainIndex[NUMTABLES];
  486. hMBFile = Create_File(hWnd,lpMBFileName,GENERIC_READ,OPEN_EXISTING);
  487. if (hMBFile == (HANDLE)-1)
  488. return FALSE;
  489. DispInfo(hWnd,IDS_RECONVINFO);
  490. ConvGetMainID(hMBFile,&MainID);
  491. if(!ConvGetMainIndex(hWnd,hMBFile,MainIndex)) {
  492. CloseHandle(hMBFile);
  493. return FALSE;
  494. }
  495. hSRCFile = Create_File(hWnd,lpSrcFileName,
  496. GENERIC_READ|GENERIC_WRITE,CREATE_ALWAYS);
  497. if (hSRCFile == (HANDLE)-1)
  498. return FALSE;
  499. CloseHandle(hSRCFile);
  500. ConvReadDescript(hMBFile,&Descript, MainIndex);
  501. ConvSaveDescript(lpSrcFileName,&Descript, 0,0);
  502. ConvGetDescript(hWnd,lpSrcFileName,&dwDesOffset,
  503. &dwDesLen,&Descript,FALSE);
  504. hCreateWord = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,
  505. (DWORD)Descript.wMaxCodes*NUM_OF_ENCODE*sizeof(TCHAR));
  506. if(!hCreateWord ) {
  507. ProcessError(ERR_OUTOFMEMORY,hWnd,ERR);
  508. return FALSE;
  509. }
  510. if(!(lpCreateWords = GlobalLock(hCreateWord)) ) {
  511. ProcessError(ERR_GLOBALLOCK,hWnd,ERR);
  512. return FALSE;
  513. }
  514. hReConvIndex = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,
  515. (DWORD)Descript.wMaxCodes*NUM_OF_ENCODE*sizeof(TCHAR));
  516. if(!hReConvIndex ) {
  517. ProcessError(ERR_OUTOFMEMORY,hWnd,ERR);
  518. CloseHandle(hMBFile);
  519. GlobalFree(hCreateWord);
  520. return FALSE;
  521. }
  522. if( !(lpReConvIndex = GlobalLock(hReConvIndex)) ) {
  523. ProcessError(ERR_GLOBALLOCK,hWnd,ERR);
  524. GlobalFree(hReConvIndex);
  525. CloseHandle(hMBFile);
  526. GlobalFree(hCreateWord);
  527. return FALSE;
  528. }
  529. if(Descript.wNumRules != 0) {
  530. hRule0 = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,
  531. sizeof(RULE)*Descript.wNumRules);
  532. if(!hRule0) {
  533. ProcessError(ERR_OUTOFMEMORY,hWnd,ERR);
  534. GlobalFree(hReConvIndex);
  535. CloseHandle(hMBFile);
  536. GlobalFree(hCreateWord);
  537. return FALSE;
  538. }
  539. if(!(lpRule = GlobalLock(hRule0)) ) {
  540. ProcessError(ERR_GLOBALLOCK,hWnd,ERR);
  541. CloseHandle(hMBFile);
  542. GlobalFree(hCreateWord);
  543. GlobalFree(hRule0);
  544. GlobalFree(hReConvIndex);
  545. return FALSE;
  546. }
  547. ConvReadRule(hMBFile,Descript.wNumRules ,lpRule, MainIndex);
  548. ConvSaveRule(hWnd,lpSrcFileName, dwDesLen, 0, lpRule, Descript.wNumRules);
  549. }
  550. ConvGetCrtData(hMBFile, lpCreateWords, MainIndex);
  551. ConvGetReConvIndex(hMBFile, lpReConvIndex,MainIndex);
  552. hSRCFile = Create_File(hWnd,lpSrcFileName,
  553. GENERIC_READ|GENERIC_WRITE,OPEN_EXISTING);
  554. if (hSRCFile == (HANDLE)-1)
  555. return FALSE;
  556. ConvWriteBaseWord(hWnd,hSRCFile,hMBFile,MainID,
  557. MainIndex[TAG_BASEDIC-1].dwOffset, lpCreateWords, lpReConvIndex,Descript.wMaxCodes);
  558. // DispInfo(hWnd,IDS_RECONVEND); bug#57932
  559. CloseHandle(hSRCFile);
  560. CloseHandle(hMBFile);
  561. GlobalFree(hCreateWord);
  562. GlobalFree(hReConvIndex);
  563. if(Descript.wNumRules != 0)
  564. GlobalFree(hRule0);
  565. ProcessError(ERR_RECONVEND, hWnd, INFO);
  566. return TRUE;
  567. }
  568. void ConvInit(LPDESCRIPTION lpDescript,
  569. LPMAINID lpMainID,
  570. LPMAININDEX lpMainIndex)
  571. {
  572. DWORD dwTotal;
  573. int i;
  574. //*** initializes struct MainID ***
  575. lstrcpy(lpMainID->szVersion,TEXT("95.01"));
  576. lpMainID->dwLanguageID = WIN95_PRC;
  577. #ifdef UNICODE
  578. lpMainID->dwEncodeID = UNICODE_IME;
  579. #else
  580. lpMainID->dwEncodeID = GBK_IME;
  581. #endif
  582. lpMainID->dwNumTables = NUMTABLES;
  583. lpMainID->dwNumWords = dwBaseWordNum;
  584. lpMainID->dwFileFlag = 0;
  585. if(lpDescript->byMaxElement > 1 )
  586. lpMainID->dwFileFlag |= FFLG_MULTIELEMENT;
  587. if(lpDescript->wNumRules > 0)
  588. lpMainID->dwFileFlag |= FFLG_RULE;
  589. //*** set tables tag ****
  590. lpMainIndex[TAG_DESCRIPTION-1].dwTag = TAG_DESCRIPTION;
  591. lpMainIndex[TAG_RULE-1].dwTag = TAG_RULE;
  592. lpMainIndex[TAG_ENCODE-1].dwTag = TAG_ENCODE;
  593. lpMainIndex[TAG_CRTWORDCODE-1].dwTag = TAG_CRTWORDCODE;
  594. lpMainIndex[TAG_RECONVINDEX-1].dwTag = TAG_RECONVINDEX;
  595. lpMainIndex[TAG_BASEDICINDEX-1].dwTag = TAG_BASEDICINDEX;
  596. lpMainIndex[TAG_BASEDIC-1].dwTag = TAG_BASEDIC;
  597. //*** set tables length ****
  598. lpMainIndex[TAG_DESCRIPTION-1].dwLength = sizeof(DESCRIPTION);
  599. lpMainIndex[TAG_RULE-1].dwLength= sizeof(RULE)* lpDescript->wNumRules;
  600. lpMainIndex[TAG_ENCODE-1].dwLength =
  601. 2*sizeof(DWORD) + NUMENCODEAREA*sizeof(ENCODEAREA);
  602. lpMainIndex[TAG_CRTWORDCODE-1].dwLength =
  603. (DWORD)NUM_OF_ENCODE*(DWORD)lpDescript->wMaxCodes*sizeof(TCHAR);
  604. lpMainIndex[TAG_RECONVINDEX-1].dwLength =
  605. (DWORD)lpDescript->wMaxCodes*NUM_OF_ENCODE*sizeof(TCHAR);
  606. switch(lpMainID->dwFileFlag) {
  607. case FFLG_RULE|FFLG_SINGLEELEMENT:
  608. lpMainIndex[TAG_RECONVINDEX-1].dwLength = 0;
  609. break;
  610. case FFLG_RULE|FFLG_MULTIELEMENT:
  611. break;
  612. case FFLG_NORULE|FFLG_SINGLEELEMENT:
  613. case FFLG_NORULE|FFLG_MULTIELEMENT:
  614. lpMainIndex[TAG_RULE-1].dwLength = 0;
  615. lpMainIndex[TAG_CRTWORDCODE-1].dwLength = 0;
  616. break;
  617. default:
  618. break;
  619. }
  620. lpMainIndex[TAG_BASEDICINDEX-1].dwLength =( (DWORD)lpDescript->wNumCodes+1)*
  621. (DWORD)lpDescript->wNumCodes*sizeof(DWORD)*2+MAXNUMCODES+CODEMAPOFFSET;
  622. lpMainIndex[TAG_BASEDIC-1].dwLength = 0;
  623. //***** set tables offset *****
  624. dwTotal = sizeof(MAINID) + sizeof(MAININDEX)*NUMTABLES;
  625. lpMainIndex[TAG_DESCRIPTION-1].dwOffset = dwTotal;
  626. dwTotal += lpMainIndex[TAG_DESCRIPTION-1].dwLength;
  627. lpMainIndex[TAG_RULE-1].dwOffset = dwTotal;
  628. dwTotal += lpMainIndex[TAG_RULE-1].dwLength;
  629. lpMainIndex[TAG_ENCODE-1].dwOffset = dwTotal;
  630. dwTotal += lpMainIndex[TAG_ENCODE-1].dwLength;
  631. lpMainIndex[TAG_CRTWORDCODE-1].dwOffset = dwTotal;
  632. dwTotal += lpMainIndex[TAG_CRTWORDCODE-1].dwLength;
  633. lpMainIndex[TAG_RECONVINDEX-1].dwOffset = dwTotal;
  634. dwTotal += lpMainIndex[TAG_RECONVINDEX-1].dwLength;
  635. lpMainIndex[TAG_BASEDICINDEX-1].dwOffset = dwTotal;
  636. dwTotal += lpMainIndex[TAG_BASEDICINDEX-1].dwLength;
  637. lpMainIndex[TAG_BASEDIC-1].dwOffset = dwTotal;
  638. for(i=0; i<NUMTABLES; i++)
  639. lpMainIndex[i].dwCheckSum = lpMainIndex[i].dwTag +
  640. lpMainIndex[i].dwLength +
  641. lpMainIndex[i].dwOffset;
  642. }
  643. BOOL ReadSRCFile(HANDLE hWnd,
  644. LPINT nPages,
  645. HANDLE hFile,
  646. LPCREATEWORD lpCreateWords,
  647. LPWORDINDEX lpWordIndex,
  648. LPINT dwWord, LPDESCRIPTION lpDescript,
  649. LPRECONVINDEX lpReConvIndex)
  650. {
  651. TCHAR szStr[256];
  652. TCHAR *Buffer;
  653. BOOL bReadText=FALSE;
  654. register int i,j;
  655. int nRet;
  656. DWORD dwReadBytes;
  657. DWORD dwFstOffset=0;
  658. DWORD dwOffset=0;
  659. Buffer = (TCHAR *)LocalAlloc(LMEM_FIXED, MAXREADBUFFER * sizeof(TCHAR));
  660. if (!Buffer)
  661. return (-ERR_OUTOFMEMORY);
  662. SetCursor (LoadCursor (NULL, IDC_WAIT));
  663. SetFilePointer(hFile,0,0,FILE_BEGIN);
  664. szStr[0] = 0;
  665. j = 0;
  666. dwLineNo = 0;
  667. dwOffset = 0;
  668. memset(WriteCrtFlag, 0, (NUM_OF_ENCODE+7)/8);
  669. while(ReadFile(hFile,Buffer,MAXREADBUFFER,&dwReadBytes,NULL))
  670. {
  671. dwReadBytes = dwReadBytes/sizeof(TCHAR);
  672. for(i=0;i<(int)dwReadBytes;i++) {
  673. if(Buffer[i] == 0x0d || Buffer[i] == 0xfeff) continue;
  674. if(Buffer[i] == TEXT('\n'))
  675. {
  676. dwLineNo ++;
  677. szStr[j]=0;
  678. j = 0;
  679. if(lstrcmpi(szStr,TEXT("[TEXT]"))==0) {
  680. bReadText = TRUE;
  681. lstrcpy(szStr,TEXT(""));
  682. continue;
  683. }
  684. if(lstrcmpi(szStr,TEXT(RuleSeg))==0
  685. || lstrcmpi(szStr,TEXT(DescriptSeg))==0) {
  686. bReadText = FALSE;
  687. lstrcpy(szStr,TEXT(""));
  688. continue;
  689. }
  690. if(bReadText) {
  691. trim(szStr);
  692. if(lstrlen(szStr) != 0) {
  693. nRet = WordSplit(hWnd,nPages,szStr,lpCreateWords,lpWordIndex,
  694. lpDescript,lpReConvIndex);
  695. if(nRet == 1)
  696. lpWordIndex[dwBaseWordNum-1].dwOffset = dwOffset;
  697. else if(!nRet) {
  698. SetCursor (LoadCursor (NULL, IDC_ARROW));
  699. LocalFree(Buffer);
  700. return FALSE;
  701. }
  702. }
  703. }
  704. else
  705. lstrcpy(szStr,TEXT(""));
  706. continue;
  707. }
  708. else {
  709. if(j == 0)
  710. dwOffset = dwFstOffset + i*sizeof(TCHAR);
  711. szStr[j]=Buffer[i];
  712. j++;
  713. }
  714. }
  715. if(dwReadBytes*sizeof(TCHAR) < MAXREADBUFFER) break;
  716. dwFstOffset += MAXREADBUFFER;
  717. };
  718. LocalFree(Buffer);
  719. SetCursor (LoadCursor (NULL, IDC_ARROW));
  720. if(dwBaseWordNum == 0) {
  721. ProcessError(ERR_TEXTSEG,hWnd,ERR);
  722. return FALSE;
  723. }
  724. else
  725. return TRUE;
  726. }
  727. BOOL ConvCalc(HANDLE hWnd,
  728. HANDLE hMBFile,
  729. LPWORDINDEX lpWordIndex,
  730. LPMAININDEX lpMainIndex,
  731. LPDESCRIPTION lpDescript)
  732. {
  733. DWORD i,j,dwRecLen,dwOffset;
  734. BYTE bySwap;
  735. TCHAR Code[MAXNUMCODES],cc;
  736. DWORD NumX,NumY,NumCodes,FstAdr,dwXStart,dwYStart,dwMaxXLen=0;
  737. HGLOBAL hNumXYWords,hDicIndex;
  738. LPNUMXYWORDS lpNumXYWords;
  739. LPDICINDEX lpDicIndex;
  740. BOOL bStart = FALSE;
  741. NumCodes=lpDescript->wNumCodes;
  742. hNumXYWords = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof(DWORD)*((NumCodes+1)*NumCodes+1L));
  743. hDicIndex = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof(DWORD)*(NumCodes+1)*NumCodes);
  744. if(!hNumXYWords || !hDicIndex) {
  745. ProcessError(ERR_OUTOFMEMORY,hWnd,ERR);
  746. return FALSE;
  747. }
  748. if( !(lpNumXYWords = GlobalLock(hNumXYWords))
  749. ||!(lpDicIndex = GlobalLock(hDicIndex)) ) {
  750. ProcessError(ERR_GLOBALLOCK,hWnd,ERR);
  751. GlobalFree(hNumXYWords);
  752. GlobalFree(hDicIndex);
  753. return FALSE;
  754. }
  755. StringCchCopy(Code, ARRAYSIZE(Code), lpDescript->szUsedCode);
  756. FstAdr = lpMainIndex[TAG_BASEDIC-1].dwOffset;
  757. NumX=0;
  758. NumY=0;
  759. dwXStart=0;
  760. dwYStart=0;
  761. dwOffset=0;
  762. lpNumXYWords[0]=0;
  763. lpDicIndex[0]=0;
  764. for(i =0; i<dwBaseWordNum;i++) {
  765. bySwap =(BYTE) lstrlen(lpWordIndex[i].szCode);
  766. dwRecLen = (DWORD)bySwap*sizeof(TCHAR)+sizeof(TCHAR);
  767. bySwap =(BYTE) lpWordIndex[i].wDBCSLen;
  768. // if the DBCS str length is longer than 126, just get the first 126 characters.
  769. if ( bySwap >= 126 )
  770. bySwap = 126;
  771. dwRecLen += 2*(DWORD)bySwap+sizeof(TCHAR);
  772. while( lpWordIndex[i].szCode[0] != Code[NumX] )
  773. {
  774. if(!bStart && NumY == 0)
  775. {
  776. lpNumXYWords[NumX*(NumCodes+1)+NumY+1] = i;
  777. lpDicIndex[NumX*(NumCodes+1)+NumY+1] = dwOffset;
  778. }
  779. while(NumY < NumCodes-1 )
  780. {
  781. NumY ++;
  782. lpNumXYWords[NumX*(NumCodes+1)+NumY+1] = i;
  783. lpDicIndex[NumX*(NumCodes+1)+NumY+1] = dwOffset;
  784. }
  785. NumX ++;
  786. if(NumX >= NumCodes) break;
  787. lpNumXYWords[NumX*(NumCodes+1)] = i;
  788. lpDicIndex[NumX*(NumCodes+1)] = dwOffset;
  789. NumY = 0;
  790. bStart = FALSE;
  791. }
  792. if(NumX >= NumCodes) break;
  793. cc = lpWordIndex[i].szCode[1];
  794. if(!bStart && cc != 0 && NumY == 0)
  795. {
  796. lpNumXYWords[NumX*(NumCodes+1)+1] = i;
  797. lpDicIndex[NumX*(NumCodes+1)+1] = dwOffset;
  798. bStart = TRUE;
  799. }
  800. while(bStart && cc != 0 && cc != Code[NumY] && NumY < NumCodes - 1 )
  801. {
  802. NumY ++;
  803. lpNumXYWords[NumX*(NumCodes+1)+NumY+1] = i;
  804. lpDicIndex[NumX*(NumCodes+1)+NumY+1] = dwOffset;
  805. }
  806. dwOffset += dwRecLen;
  807. if(i == dwBaseWordNum-1) {
  808. j = NumX*(NumCodes+1) + NumY + 1;
  809. while(j < (NumCodes+1)*NumCodes - 1 )
  810. {
  811. j ++;
  812. lpNumXYWords[j] = i + 1;
  813. lpDicIndex[j] = dwOffset;
  814. }
  815. lpNumXYWords[NumCodes*(NumCodes+1)] = i;
  816. }
  817. }
  818. for(i = 0; i < NumCodes ; i++)
  819. {
  820. for(j = 0; j < NumCodes + 1; j++)
  821. {
  822. if(j == 0)
  823. {
  824. lpNumXYWords[i*(NumCodes+1)] = lpNumXYWords[(i+1)*(NumCodes+1)] -
  825. lpNumXYWords[i*(NumCodes+1)];
  826. }
  827. else
  828. {
  829. lpNumXYWords[i*(NumCodes+1)+j] = lpNumXYWords[i*(NumCodes+1)+j+1] -
  830. lpNumXYWords[i*(NumCodes+1)+j];
  831. lpDicIndex[i*(NumCodes+1)+j] = lpDicIndex[i*(NumCodes+1)+j] -
  832. lpDicIndex[i*(NumCodes+1)];
  833. }
  834. }
  835. }
  836. lpMainIndex[TAG_BASEDIC-1].dwLength = dwOffset;
  837. lpMainIndex[TAG_BASEDIC-1].dwCheckSum = TAG_BASEDIC +
  838. lpMainIndex[TAG_BASEDIC-1].dwOffset+
  839. dwOffset;
  840. for(i=0; i< NumCodes - 1;i++) {
  841. dwRecLen = lpDicIndex[(i+1)*(NumCodes+1)]-lpDicIndex[(NumCodes+1)*i];
  842. dwMaxXLen = (dwRecLen>dwMaxXLen)? dwRecLen:dwMaxXLen;
  843. }
  844. dwRecLen = dwOffset - lpDicIndex[(NumCodes+1)*(NumCodes-1)];
  845. dwMaxXLen = (dwRecLen>dwMaxXLen)? dwRecLen:dwMaxXLen;
  846. ConvWriteMainIndex(hMBFile,lpMainIndex);
  847. ConvWriteCodeIndex(hMBFile,&dwMaxXLen,lpDescript->szUsedCode,lpMainIndex);
  848. ConvWriteDicIndex(hMBFile,lpDicIndex,lpDescript->wNumCodes,lpMainIndex);
  849. ConvWriteNumXYWords(hMBFile,lpNumXYWords,
  850. lpDescript->wNumCodes,lpMainIndex);
  851. GlobalUnlock(hDicIndex);
  852. GlobalUnlock(hNumXYWords);
  853. GlobalFree(hDicIndex);
  854. GlobalFree(hNumXYWords);
  855. return TRUE;
  856. }
  857. BOOL WriteMBFile(HANDLE hWnd,
  858. HANDLE hSRCFile,
  859. HANDLE hMBFile,
  860. LPWORDINDEX lpWordIndex,
  861. LPMAININDEX lpMainIndex,
  862. LPDESCRIPTION lpDescript)
  863. {
  864. DWORD i,dwBytes,NumCodes,FstAdr;
  865. WORD bySwap;
  866. TCHAR szStr[256];
  867. TCHAR Code[MAXNUMCODES];
  868. DWORD dwReadSum;
  869. HANDLE hDlgItem;
  870. SetCursor (LoadCursor (NULL, IDC_WAIT));
  871. SetDlgItemText(hWnd,TM_TOTALINFO,TEXT(""));
  872. LoadString(NULL,IDS_TOTALINFO,szStr,sizeof(szStr)/sizeof(TCHAR));
  873. SetDlgItemText(hWnd,TM_TOTAL,szStr);
  874. LoadString(NULL,IDS_CONVWORDS,szStr,sizeof(szStr)/sizeof(TCHAR));
  875. SetDlgItemText(hWnd,TM_CONVINFO,szStr);
  876. SetDlgItemInt(hWnd,TM_TOTALNUM,dwBaseWordNum,FALSE);
  877. dwReadSum = 0;
  878. SetDlgItemInt(hWnd,TM_CONVNUM,dwReadSum,FALSE);
  879. InvalidateRect(hWnd,NULL,FALSE);
  880. NumCodes=lpDescript->wNumCodes;
  881. lstrncpy(Code,NumCodes,lpDescript->szUsedCode);
  882. FstAdr = lpMainIndex[TAG_BASEDIC-1].dwOffset;
  883. SetFilePointer(hMBFile,FstAdr,0, FILE_BEGIN);
  884. for(i =0; i<dwBaseWordNum;i++) {
  885. SetFilePointer(hSRCFile,lpWordIndex[i].dwOffset,0,FILE_BEGIN);
  886. bySwap =(WORD) lpWordIndex[i].wDBCSLen;
  887. if (!ReadFile(hSRCFile,szStr,2*(DWORD)bySwap,&dwBytes,NULL))
  888. return FALSE;
  889. bySwap =(WORD) lstrlen(lpWordIndex[i].szCode);
  890. WriteFile(hMBFile,&bySwap,sizeof(TCHAR),&dwBytes,NULL);
  891. WriteFile(hMBFile,&(lpWordIndex[i].szCode),bySwap*sizeof(TCHAR),&dwBytes,NULL);
  892. bySwap =(WORD) lpWordIndex[i].wDBCSLen;
  893. // if the DBCS str length is longer than 126, just get the first 126 characters.
  894. if ( bySwap >= 126 )
  895. bySwap = 126;
  896. WriteFile(hMBFile,&bySwap,sizeof(TCHAR),&dwBytes,NULL);
  897. WriteFile(hMBFile,szStr,2*bySwap,&dwBytes,NULL);
  898. dwReadSum ++;
  899. if(dwReadSum%100 ==0 || dwReadSum == dwBaseWordNum) {
  900. SetDlgItemInt(hWnd,TM_CONVNUM,dwReadSum,FALSE);
  901. hDlgItem=GetDlgItem(hWnd,TM_CONVNUM);
  902. InvalidateRect(hDlgItem,NULL,FALSE);
  903. }
  904. }
  905. SetCursor (LoadCursor (NULL, IDC_ARROW));
  906. return TRUE;
  907. }
  908. BOOL WriteSortFile(HANDLE hWnd,
  909. HANDLE hSRCFile,
  910. HANDLE hDestFile,
  911. LPWORDINDEX lpWordIndex,
  912. LPCREATEWORD lpCreateWords)
  913. {
  914. DWORD i, k, dwBytes;
  915. WORD wRecLen;
  916. BYTE bySwap;
  917. TCHAR szStr[512],szDBCS[512];
  918. TCHAR szCode[13],szCreate[13];
  919. BOOL IsGenCmb = (hCmbFile)?TRUE:FALSE;
  920. BOOL bExistNext = FALSE;
  921. DWORD dwReadSum;
  922. SetFilePointer(hDestFile,0,0, FILE_END);
  923. dwReadSum = 0;
  924. for(i =0; i<dwBaseWordNum;i++) {
  925. SetFilePointer(hSRCFile,lpWordIndex[i].dwOffset,0,FILE_BEGIN);
  926. wRecLen = 2*lpWordIndex[i].wDBCSLen/sizeof(TCHAR);
  927. if (!ReadFile(hSRCFile,szDBCS,wRecLen*sizeof(TCHAR),&dwBytes,NULL))
  928. return FALSE;
  929. szDBCS[wRecLen] = 0;
  930. StringCchCopy(szCode, ARRAYSIZE(szCode), lpWordIndex[i].szCode);
  931. bySwap =(BYTE)lstrlen(lpWordIndex[i].szCode);
  932. if(wRecLen == 2/sizeof(TCHAR)){
  933. k = EncodeToNo(szDBCS);
  934. if((long)k>=0 && k < NUM_OF_ENCODE) {
  935. lstrncpy(szCreate,MAXCODELEN,&lpCreateWords[k*MAXCODELEN]);
  936. szCreate[MAXCODELEN]=0;
  937. if(lstrlen(szCreate))
  938. StringCchPrintf(szStr,ARRAYSIZE(szStr),TEXT("%s%s %s\r\n"),szDBCS,szCode,szCreate);
  939. else
  940. StringCchPrintf(szStr,ARRAYSIZE(szStr),TEXT("%s%s\r\n"),szDBCS,szCode);
  941. }
  942. else
  943. StringCchPrintf(szStr,ARRAYSIZE(szStr),TEXT("%s%s\r\n"),szDBCS,szCode);
  944. }
  945. else
  946. StringCchPrintf(szStr,ARRAYSIZE(szStr),TEXT("%s%s\r\n"),szDBCS,szCode);
  947. WriteFile(hDestFile,szStr,lstrlen(szStr)*sizeof(TCHAR),&dwBytes,NULL);
  948. if(IsGenCmb)
  949. {
  950. if(i != dwBaseWordNum - 1
  951. && _wcsicmp(lpWordIndex[i].szCode, lpWordIndex[i+1].szCode) == 0)
  952. {
  953. StringCchPrintf(szStr,ARRAYSIZE(szStr),TEXT("%s%s\r\n"),szCode,szDBCS);
  954. WriteFile(hCmbFile,szStr,lstrlen(szStr)*sizeof(TCHAR),&dwBytes,NULL);
  955. bExistNext = TRUE;
  956. dwReadSum ++;
  957. }
  958. else
  959. {
  960. if(bExistNext)
  961. {
  962. StringCchPrintf(szStr,ARRAYSIZE(szStr),TEXT("%s%s\r\n"),szCode,szDBCS);
  963. WriteFile(hCmbFile,szStr,lstrlen(szStr)*sizeof(TCHAR),&dwBytes,NULL);
  964. }
  965. bExistNext = FALSE;
  966. }
  967. }
  968. }
  969. if(IsGenCmb)
  970. {
  971. #ifdef UNICODE
  972. TCHAR UniTmp[] = {0x5171, 0x8BA1, 0x91CD, 0x7801, 0x8BCD, 0x6761, 0x6570, 0x0000};
  973. StringCchPrintf(szStr,ARRAYSIZE(szStr),TEXT("%ws = %d\n"), UniTmp, dwReadSum);
  974. #else
  975. StringCchPrintf(szStr,ARRAYSIZE(szStr),"�������������� = %ld\n", dwReadSum);
  976. #endif
  977. WriteFile(hCmbFile,szStr,lstrlen(szStr)*sizeof(TCHAR),&dwBytes,NULL);
  978. }
  979. return TRUE;
  980. }
  981. int SimpleSplit(HANDLE hWnd,
  982. LPINT nPages,
  983. LPTSTR szStr,
  984. LPCREATEWORD lpCreateWords,
  985. LPWORDINDEX lpWordIndex,
  986. WORD wMaxCodes)
  987. {
  988. register int i=0;
  989. int nDBCS=0, nCodes=0, nCreate = 0;
  990. TCHAR szDBCS[512],szCode[13],szCreate[128];
  991. if(ParseDBCSstr(hWnd,szStr,szDBCS,szCode,szCreate,wMaxCodes) != TRUE)
  992. {
  993. if(lstrlen(szDBCS) == 0)
  994. {
  995. LoadString(NULL, IDS_NOTEXISTDBCS, szCreate, sizeof(szCreate)/sizeof(TCHAR));
  996. StringCchPrintf(szDBCS, ARRAYSIZE(szDBCS), TEXT("\'%s%lu)"),szCreate,dwLineNo);
  997. FatalMessage(hWnd,szDBCS);
  998. }
  999. return FALSE;
  1000. }
  1001. nDBCS = lstrlen(szDBCS);
  1002. DelIllegalCode(szCode);
  1003. nCodes = lstrlen(szCode);
  1004. nCreate = lstrlen(szCreate);
  1005. dwBaseWordNum ++;
  1006. lpWordIndex[dwBaseWordNum-1].wDBCSLen =(WORD)(nDBCS*sizeof(TCHAR)/2);
  1007. lstrcpy(lpWordIndex[dwBaseWordNum-1].szCode,szCode);
  1008. if(nDBCS == 2/sizeof(TCHAR)) {
  1009. i = EncodeToNo(szDBCS);
  1010. if(i>=0 && i < NUM_OF_ENCODE)
  1011. {
  1012. if(nCreate != 0)
  1013. lstrncpy(lpCreateWords+i*MAXCODELEN,
  1014. MAXCODELEN, szCreate);
  1015. }
  1016. }
  1017. return TRUE;
  1018. }
  1019. int WordSplit(HANDLE hWnd,
  1020. LPINT nPages,
  1021. LPTSTR szStr,
  1022. LPCREATEWORD lpCreateWords,
  1023. LPWORDINDEX lpWordIndex,
  1024. LPDESCRIPTION lpDescript,
  1025. LPRECONVINDEX lpReConvIndex)
  1026. {
  1027. int i, nDBCS=0, nCodes=0, nCreate = 0;
  1028. TCHAR szTemp[512],szTmpStr[256];
  1029. TCHAR szDBCS[512],szCode[13],szCreate[128];
  1030. if(ParseDBCSstr(hWnd,szStr,szDBCS,szCode,szCreate,lpDescript->wMaxCodes) != TRUE)
  1031. {
  1032. if(lstrlen(szDBCS) == 0)
  1033. {
  1034. LoadString(NULL, IDS_NOTEXISTDBCS, szTmpStr, sizeof(szTmpStr)/sizeof(TCHAR));
  1035. StringCchPrintf(szTemp, ARRAYSIZE(szTemp), TEXT("\'%s%lu)"),szTmpStr,dwLineNo);
  1036. FatalMessage(hWnd,szTemp);
  1037. }
  1038. return FALSE;
  1039. }
  1040. if ( lstrlen(szDBCS) > 126 ) {
  1041. // if the string is longer than 126, the rest will be cut.
  1042. // so show a message to end user.
  1043. LoadString(NULL, IDS_DBCSTOOLONG, szTmpStr, sizeof(szTmpStr)/sizeof(TCHAR));
  1044. #ifdef UNICODE
  1045. {
  1046. TCHAR UniTmp[] = {0x0027, 0x0025, 0x0077, 0x0073, 0x0027, 0x0020, 0x0020,
  1047. 0x0020, 0x0028, 0x884C, 0x003A, 0x0025, 0x006C, 0x0075,
  1048. 0x0029, 0x0025, 0x0077, 0x0073, 0x000D, 0x000A, 0x000D,
  1049. 0x000A, 0x9000, 0x51FA, 0x5426, 0x003F, 0x0020, 0x0000};
  1050. StringCchPrintf(szTemp, ARRAYSIZE(szTemp), UniTmp, szDBCS,dwLineNo,szTmpStr);
  1051. }
  1052. #else
  1053. StringCchPrintf(szTemp, ARRAYSIZE(szTemp),"\'%s\'%s(��:%lu)\n�˳���? ",szDBCS,szTmpStr,dwLineNo);
  1054. #endif
  1055. if (ErrMessage(hWnd,szTemp))
  1056. return FALSE;
  1057. }
  1058. if(!CheckCodeLegal(hWnd,szDBCS,szCode,szCreate,lpDescript))
  1059. return FALSE;
  1060. nDBCS = lstrlen(szDBCS);
  1061. nCodes = lstrlen(szCode);
  1062. nCreate = lstrlen(szCreate);
  1063. if(nDBCS == 0)
  1064. return -1;
  1065. if(nDBCS == 2/sizeof(TCHAR))
  1066. {
  1067. i = EncodeToNo(szDBCS);
  1068. if(i < 0 || i >= NUM_OF_ENCODE)
  1069. return FALSE;
  1070. if(nCodes == 0) {
  1071. LoadString(NULL, IDS_CODEEMPTY, szTmpStr, sizeof(szTmpStr)/sizeof(TCHAR));
  1072. #ifdef UNICODE
  1073. {
  1074. TCHAR UniTmp[] = {0x005C, 0x0027, 0x0025, 0x0077, 0x0073, 0x005C, 0x0027, 0x0025, 0x0077, 0x0073, 0x0028, 0x884C, 0x003A, 0x0025, 0x006C, 0x0075, 0x0029, 0x005C, 0x006E, 0x9000, 0x51FA, 0x5426, 0x003F, 0x0020, 0x0000};
  1075. StringCchPrintf(szTemp, ARRAYSIZE(szTemp), UniTmp, szDBCS,szTmpStr,dwLineNo);
  1076. }
  1077. #else
  1078. StringCchPrintf(szTemp, ARRAYSIZE(szTemp),"\'%s\'%s(��:%lu)\n�˳���? ",szDBCS,szTmpStr,dwLineNo);
  1079. #endif \\UNICODE
  1080. if(ErrMessage(hWnd,szTemp))
  1081. return FALSE;
  1082. }
  1083. //**** write create words
  1084. if(lpDescript->wNumRules != 0 && nCreate != 0)
  1085. {
  1086. if(nCreate > lpDescript->wMaxCodes) {
  1087. LoadString(NULL,IDS_DBCSCODE,szTmpStr,sizeof(szTmpStr)/sizeof(TCHAR));
  1088. #ifdef UNICODE
  1089. {
  1090. TCHAR UniTmp[] = {0x005C, 0x0027, 0x0025, 0x0077, 0x0073, 0x0025, 0x0077, 0x0073, 0x005C, 0x0027, 0x0020, 0x0025, 0x0064, 0x0021, 0x0028, 0x884C, 0x003A, 0x0025, 0x006C, 0x0075, 0x0029, 0x005C, 0x006E, 0x9000, 0x51FA, 0x5426, 0x003F, 0x0000};
  1091. StringCchPrintf(szTemp, ARRAYSIZE(szTemp),UniTmp, szDBCS,szTmpStr,
  1092. lpDescript->byMaxElement,dwLineNo);
  1093. }
  1094. #else
  1095. StringCchPrintf(szTemp, ARRAYSIZE(szTemp),"\'%s%s\' %d!(��:%lu)\n�˳���?", szDBCS,szTmpStr,
  1096. lpDescript->byMaxElement,dwLineNo);
  1097. #endif \\UNICODE
  1098. if( ErrMessage(hWnd,szTemp))
  1099. return FALSE;
  1100. }
  1101. lstrncpy(szTmpStr,lpDescript->wMaxCodes,
  1102. lpCreateWords+i*(DWORD)lpDescript->wMaxCodes);
  1103. szTmpStr[lpDescript->wMaxCodes] = 0;
  1104. if(!(WriteCrtFlag[i/8] & (1 << (7 - (i%8))) ) )
  1105. lstrncpy(lpCreateWords+i*(DWORD)lpDescript->wMaxCodes,
  1106. lpDescript->wMaxCodes,
  1107. szCreate);
  1108. WriteCrtFlag[i/8] |= (1 << (7 - (i%8)) );
  1109. }
  1110. }
  1111. else if(nDBCS>2*sizeof(TCHAR) && nCodes==0 && lpDescript->wNumRules==0)
  1112. {
  1113. LoadString(NULL,IDS_CODEEMPTY,szTmpStr,sizeof(szTmpStr)/sizeof(TCHAR));
  1114. #ifdef UNICODE
  1115. {
  1116. TCHAR UniTmp[] = {0x005C, 0x0027, 0x0025, 0x0077, 0x0073, 0x005C, 0x0027, 0x0025, 0x0077, 0x0073, 0x0028, 0x884C, 0x003A, 0x0025, 0x006C, 0x0064, 0x0029, 0x0000};
  1117. StringCchPrintf(szTemp, ARRAYSIZE(szTemp),UniTmp, szDBCS,szTmpStr,dwLineNo);
  1118. }
  1119. #else
  1120. StringCchPrintf(szTemp, ARRAYSIZE(szTemp),"\'%s\'%s(��:%ld)", szDBCS,szTmpStr,dwLineNo);
  1121. #endif
  1122. WarnMessage(hWnd,szTemp);
  1123. return FALSE;
  1124. }
  1125. dwBaseWordNum ++;
  1126. if(dwBaseWordNum >(DWORD)(*nPages)*GMEM_PAGESIZE) {
  1127. GlobalUnlock(hWordIndex);
  1128. hWordIndex = IndexReAlloc(hWordIndex,nPages);
  1129. if(!hWordIndex) {
  1130. ProcessError(ERR_OUTOFMEMORY,hWnd,ERR);
  1131. return FALSE;
  1132. }
  1133. lpWordIndex = (LPWORDINDEX) GlobalLock(hWordIndex);
  1134. if( !lpWordIndex ) {
  1135. ProcessError(ERR_GLOBALLOCK,hWnd,ERR);
  1136. return FALSE;
  1137. }
  1138. }
  1139. lpWordIndex[dwBaseWordNum-1].wDBCSLen =(WORD)(nDBCS*sizeof(TCHAR)/2);
  1140. lstrcpy(lpWordIndex[dwBaseWordNum-1].szCode,szCode);
  1141. ConvReconvIndex(hWnd,szDBCS,lpCreateWords,lpWordIndex[dwBaseWordNum-1],lpDescript,lpReConvIndex);
  1142. return TRUE;
  1143. }
  1144. BOOL ConvWriteBaseWord (HANDLE hWnd,
  1145. HANDLE hSRCFile,
  1146. HANDLE hMBFile,
  1147. MAINID MainID,
  1148. DWORD dwOffset,
  1149. LPCREATEWORD lpCreateWords,
  1150. LPRECONVINDEX lpReConvIndex,
  1151. DWORD MaxCodes)
  1152. {
  1153. TCHAR szCode[13],szCreate[13],szDBCS[512],szReCode[13];
  1154. TCHAR szStr[512];
  1155. static TCHAR ReadBuf[MAXREADBUFFER];
  1156. static TCHAR WriteBuf[2*MAXREADBUFFER];
  1157. DWORD dwReadBytes,dwRecLen,i,j,k,dwReadWords=0;
  1158. DWORD dwFileFlag = MainID.dwFileFlag;
  1159. DWORD dwNumWords = MainID.dwNumWords;
  1160. DWORD dwReadSum;
  1161. HWND hDlgItem;
  1162. SetFilePointer(hMBFile,dwOffset,0,FILE_BEGIN);
  1163. SetFilePointer(hSRCFile,0,0,FILE_END);
  1164. SetDlgItemText(hWnd,TM_TOTALINFO,TEXT(""));
  1165. LoadString(NULL,IDS_TOTALINFO,szStr,sizeof(szStr)/sizeof(TCHAR));
  1166. SetDlgItemText(hWnd,TM_TOTAL,szStr);
  1167. LoadString(NULL,IDS_RECONVWORDS,szStr,sizeof(szStr)/sizeof(TCHAR));
  1168. SetDlgItemText(hWnd,TM_CONVINFO,szStr);
  1169. SetDlgItemInt(hWnd,TM_TOTALNUM,dwNumWords,FALSE);
  1170. dwReadSum = 0;
  1171. SetDlgItemInt(hWnd,TM_CONVNUM,dwReadSum,FALSE);
  1172. InvalidateRect(hWnd,NULL,FALSE);
  1173. i=0;
  1174. do {
  1175. if (!ReadFile(hMBFile,ReadBuf,sizeof(ReadBuf),&dwReadBytes,NULL))
  1176. break;
  1177. i=0;
  1178. if(dwReadBytes == 0 ) break;
  1179. WriteBuf[0]=0;
  1180. dwReadBytes = dwReadBytes/sizeof(TCHAR);
  1181. while( i < dwReadBytes-1 ) {
  1182. j = (DWORD)ReadBuf[i]+1;
  1183. dwRecLen = j+(DWORD)ReadBuf[i+j]*2/sizeof(TCHAR)+1;
  1184. if( (dwReadBytes*sizeof(TCHAR) < MAXREADBUFFER) ||
  1185. ((i+j) < (dwReadBytes-1) && (i+dwRecLen) < (dwReadBytes-1) ) ) {
  1186. lstrncpy(szCode,ReadBuf[i],&ReadBuf[i+1]);
  1187. szCode[ReadBuf[i]] = 0;
  1188. lstrncpy(szDBCS,ReadBuf[i+j]*2/sizeof(TCHAR),&ReadBuf[i+j+1]);
  1189. szDBCS[ReadBuf[i+j]*2/sizeof(TCHAR)] = 0;
  1190. if(ReadBuf[i+j]==1
  1191. &&(dwFileFlag&FFLG_RULE)) {
  1192. k = EncodeToNo(szDBCS);
  1193. if((long)k>=0 && k < NUM_OF_ENCODE) {
  1194. lstrncpy(szCreate,MaxCodes,&lpCreateWords[k*MaxCodes]);
  1195. lstrncpy(szReCode,MaxCodes,&lpReConvIndex[k*MaxCodes]);
  1196. szCreate[MaxCodes]=0;
  1197. szReCode[MaxCodes]=0;
  1198. if(lstrlen(szCreate) != 0 && lstrcmpi(szCreate,szCode) != 0)
  1199. StringCchPrintf(szStr, ARRAYSIZE(szStr),TEXT("%s%s %s\r\n"),szDBCS,szCode,szCreate);
  1200. else
  1201. StringCchPrintf(szStr, ARRAYSIZE(szStr),TEXT("%s%s\r\n"),szDBCS,szCode);
  1202. }
  1203. else
  1204. StringCchPrintf(szStr, ARRAYSIZE(szStr),TEXT("%s%s\r\n"),szDBCS,szCode);
  1205. }
  1206. else
  1207. StringCchPrintf(szStr, ARRAYSIZE(szStr),TEXT("%s%s\r\n"),szDBCS,szCode);
  1208. lstrcat(WriteBuf,szStr);
  1209. dwReadWords ++;
  1210. dwReadSum = dwReadWords;
  1211. if(dwReadSum%100 ==0 || dwReadSum == dwNumWords) {
  1212. SetDlgItemInt(hWnd,TM_CONVNUM,dwReadSum,FALSE);
  1213. hDlgItem=GetDlgItem(hWnd,TM_CONVNUM);
  1214. InvalidateRect(hDlgItem,NULL,FALSE);
  1215. }
  1216. i += dwRecLen;
  1217. }
  1218. else {
  1219. SetFilePointer(hMBFile,(i-dwReadBytes)*sizeof(TCHAR),0,FILE_CURRENT);
  1220. break;
  1221. }
  1222. }
  1223. WriteFile(hSRCFile,WriteBuf,lstrlen(WriteBuf)*sizeof(TCHAR),&k,NULL);
  1224. }while (dwReadBytes == MAXREADBUFFER) ;
  1225. return TRUE;
  1226. }
  1227. BOOL ConvBatCreate (HANDLE hWnd,
  1228. DESCRIPTION Descript,
  1229. LPRULE lpRule,
  1230. LPCREATEWORD lpCreateWord,
  1231. LPTSTR szWordStr,
  1232. LPTSTR lpCode)
  1233. {
  1234. int nWordLen=lstrlen(szWordStr)*sizeof(TCHAR)/2;
  1235. DWORD i,j,k,dwCodeLen;
  1236. DWORD dwNumRules = Descript.wNumRules;
  1237. WORD wMaxCodes = Descript.wMaxCodes;
  1238. TCHAR szDBCS[3],szCode[MAXCODELEN+1];
  1239. BOOL bReturn = FALSE;
  1240. lpCode[0] = 0;
  1241. if(dwNumRules == 0) {
  1242. ProcessError(ERR_NORULE,hWnd,ERR);
  1243. return FALSE;
  1244. }
  1245. for(i=0; i<dwNumRules; i++)
  1246. if( (lpRule[i].byLogicOpra == 0 && nWordLen == lpRule[i].byLength)
  1247. ||(lpRule[i].byLogicOpra == 1 && nWordLen >= lpRule[i].byLength)
  1248. ||(lpRule[i].byLogicOpra == 2 && nWordLen <= lpRule[i].byLength) ) {
  1249. int retCodeLen = 0;
  1250. for(j=0; j<lpRule[i].wNumCodeUnits; j++) {
  1251. k = lpRule[i].CodeUnit[j].wDBCSPosition;
  1252. if(k > (DWORD)nWordLen) k = (DWORD)nWordLen;
  1253. if(lpRule[i].CodeUnit[j].dwDirectMode == 0)
  1254. lstrncpy(szDBCS,2,&szWordStr[2*(k-1)]);
  1255. else
  1256. lstrncpy(szDBCS,2,&szWordStr[2*(nWordLen-k)]);
  1257. szDBCS[2] = 0;
  1258. k = EncodeToNo(szDBCS);
  1259. if((long)k>=0 && k< NUM_OF_ENCODE )
  1260. {
  1261. lstrncpy(szCode,wMaxCodes,&lpCreateWord[wMaxCodes*k]);
  1262. szCode[wMaxCodes] = 0;
  1263. dwCodeLen = lstrlen(szCode);
  1264. k = lpRule[i].CodeUnit[j].wCodePosition;
  1265. if(k == 0)
  1266. {
  1267. if(retCodeLen + dwCodeLen > Descript.wMaxCodes)
  1268. szCode[Descript.wMaxCodes - retCodeLen] = 0;
  1269. lstrcat(lpCode,szCode);
  1270. }
  1271. else
  1272. {
  1273. if(k > dwCodeLen) k = dwCodeLen;
  1274. lpCode[j] = (szCode[k-1] == 0)?((k > 1)? szCode[k-2]:Descript.szUsedCode[0]):szCode[k-1];
  1275. }
  1276. }
  1277. else
  1278. lpCode[j] = (j > 0)?lpCode[j-1]:Descript.szUsedCode[0];
  1279. retCodeLen = lstrlen(lpCode);
  1280. }
  1281. bReturn = TRUE;
  1282. break;
  1283. }
  1284. if(!bReturn)
  1285. ProcessError(ERR_NOTDEFRULE,hWnd,ERR);
  1286. lpCode[wMaxCodes] = 0;
  1287. return bReturn;
  1288. }
  1289. BOOL searchPos(LPWORDINDEX lpWordIndex, DWORD dwNumWords)
  1290. {
  1291. DWORD i, retPos;
  1292. WORDINDEX InsWordIndex = lpWordIndex[dwNumWords-1];
  1293. if(dwNumWords == 1)
  1294. return TRUE;
  1295. retPos = bSearch(lpWordIndex, 0, dwNumWords-2, InsWordIndex);
  1296. if(retPos == dwNumWords - 1)
  1297. return TRUE;
  1298. memmove(&lpWordIndex[retPos+1], &lpWordIndex[retPos],
  1299. sizeof(WORDINDEX)*(dwNumWords - 1 - retPos) );
  1300. lpWordIndex[retPos] = InsWordIndex;
  1301. return TRUE;
  1302. }
  1303. DWORD bSearch(LPWORDINDEX lpWordIndex, DWORD left, DWORD right, WORDINDEX InsWordIndex)
  1304. {
  1305. WORDINDEX MidWordIndex;
  1306. DWORD mid;
  1307. if(left > right)
  1308. return left;
  1309. mid = (left + right)/2;
  1310. MidWordIndex = lpWordIndex[mid];
  1311. if(_wcsicmp(MidWordIndex.szCode, InsWordIndex.szCode) <= 0)
  1312. {
  1313. if(mid == right || _wcsicmp(lpWordIndex[mid+1].szCode, InsWordIndex.szCode) > 0)
  1314. return mid+1;
  1315. else
  1316. return bSearch(lpWordIndex, mid+1, right, InsWordIndex);
  1317. }
  1318. else
  1319. {
  1320. if(mid == left || _wcsicmp(lpWordIndex[mid-1].szCode, InsWordIndex.szCode) <= 0)
  1321. return mid;
  1322. else
  1323. // return bSearch(lpWordIndex, left, mid, InsWordIndex);
  1324. return bSearch(lpWordIndex, left, mid-1, InsWordIndex);
  1325. }
  1326. return 0;
  1327. }
  1328. //***** end 95.10.17