Source code of Windows XP (NT5)
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.

1421 lines
34 KiB

  1. /*++
  2. Copyright (c) 1991-1999, Microsoft Corporation All rights reserved.
  3. Module Name:
  4. codepage.c
  5. Abstract:
  6. This file contains functions necessary to parse and write the code page
  7. specific tables to a data file.
  8. External Routines in this file:
  9. ParseCodePage
  10. WriteCodePage
  11. Revision History:
  12. 12-10-91 JulieB Created.
  13. 03-10-00 lguindon Add explicit typecast to remove build errors
  14. --*/
  15. //
  16. // Include Files.
  17. //
  18. #include "nlstrans.h"
  19. //
  20. // Forward Declarations.
  21. //
  22. int
  23. GetMBTable(
  24. PCODEPAGE pCP,
  25. int Size);
  26. int
  27. GetGlyphTable(
  28. PCODEPAGE pCP,
  29. int Size);
  30. int
  31. GetDBCSRanges(
  32. PCODEPAGE pCP,
  33. int Size);
  34. int
  35. GetAllDBCSTables(
  36. int NumTables,
  37. PDBCS_TBL_ARRAY pArray);
  38. int
  39. GetDBCSTable(
  40. int Size,
  41. PDBCS_TBL pTable);
  42. int
  43. GetWCTable(
  44. PCODEPAGE pCP,
  45. int Size,
  46. BOOL IsMBCodePage);
  47. int
  48. WriteCPInfo(
  49. PCODEPAGE pCP,
  50. FILE *pOutputFile);
  51. int
  52. WriteMB(
  53. PCODEPAGE pCP,
  54. FILE *pOutputFile);
  55. int
  56. WriteWC(
  57. PCODEPAGE pCP,
  58. BOOL IsMBCodePage,
  59. FILE *pOutputFile);
  60. void
  61. FreeMB(
  62. PCODEPAGE pCP);
  63. int
  64. GetTransDefaultChars(
  65. PCODEPAGE pCP);
  66. //-------------------------------------------------------------------------//
  67. // EXTERNAL ROUTINES //
  68. //-------------------------------------------------------------------------//
  69. ////////////////////////////////////////////////////////////////////////////
  70. //
  71. // ParseCodePage
  72. //
  73. // This routine parses the input file for the code page specific tables.
  74. // This routine is only entered when the CODEPAGE keyword is found.
  75. // The parsing continues until the ENDCODEPAGE keyword is found.
  76. //
  77. // 12-10-91 JulieB Created.
  78. ////////////////////////////////////////////////////////////////////////////
  79. int ParseCodePage(
  80. PCODEPAGE pCP,
  81. PSZ pszKeyWord)
  82. {
  83. int size; // size of table to follow
  84. int DefChar; // default character
  85. int UniDefChar; // unicode default char
  86. int NumItems; // number of items returned from fscanf
  87. //
  88. // Get CodePageValue parameter.
  89. //
  90. pCP->CodePageValue = atoi(pCP->pszName);
  91. //
  92. // Read in the rest of the code page information.
  93. //
  94. while (fscanf(pInputFile, "%s", pszKeyWord) == 1)
  95. {
  96. if (_stricmp(pszKeyWord, "CPINFO") == 0)
  97. {
  98. if (Verbose)
  99. printf("\n\nFound CPINFO keyword.\n");
  100. //
  101. // Get MaxCharSize parameter.
  102. // Get DefaultChar parameter.
  103. // Get Unicode Translation of default char parameter.
  104. //
  105. NumItems = fscanf( pInputFile,
  106. "%d %x %x ;%*[^\n]",
  107. &size,
  108. &DefChar,
  109. &UniDefChar );
  110. if ((NumItems != 3) || ((size != 1) && (size != 2)))
  111. {
  112. return (1);
  113. }
  114. pCP->MaxCharSize = size;
  115. pCP->DefaultChar = (WORD)DefChar;
  116. pCP->UniDefaultChar = (WORD)UniDefChar;
  117. if (Verbose)
  118. {
  119. printf(" MAXCHARSIZE = %d\n", size);
  120. printf(" DEFAULTCHAR = %x\n\n", DefChar);
  121. printf(" UNICODE DEFAULT CHAR = %x\n\n", UniDefChar);
  122. }
  123. //
  124. // Set WriteFlags for CPINFO Table.
  125. //
  126. pCP->WriteFlags |= F_CPINFO;
  127. }
  128. else if (_stricmp(pszKeyWord, "MBTABLE") == 0)
  129. {
  130. if (Verbose)
  131. printf("\n\nFound MBTABLE keyword.\n");
  132. //
  133. // Get size parameter.
  134. //
  135. if (GetSize(&size))
  136. return (1);
  137. //
  138. // Get MB table.
  139. //
  140. if (GetMBTable(pCP, size))
  141. {
  142. return (1);
  143. }
  144. //
  145. // Set WriteFlags for MB Table.
  146. //
  147. pCP->WriteFlags |= F_MB;
  148. }
  149. else if (_stricmp(pszKeyWord, "GLYPHTABLE") == 0)
  150. {
  151. if (Verbose)
  152. printf("\n\nFound GLYPHTABLE keyword.\n");
  153. //
  154. // Get size parameter.
  155. //
  156. if (GetSize(&size))
  157. return (1);
  158. //
  159. // Get GLYPH table.
  160. //
  161. if (GetGlyphTable(pCP, size))
  162. {
  163. return (1);
  164. }
  165. //
  166. // Set WriteFlags for GLYPH Table.
  167. //
  168. pCP->WriteFlags |= F_GLYPH;
  169. }
  170. else if (_stricmp(pszKeyWord, "DBCSRANGE") == 0)
  171. {
  172. if (Verbose)
  173. printf("\n\nFound DBCSRANGE keyword.\n");
  174. //
  175. // Get size parameter.
  176. //
  177. if (GetSize(&size))
  178. return (1);
  179. //
  180. // Get DBCS ranges and tables.
  181. //
  182. if (GetDBCSRanges(pCP, size))
  183. {
  184. return (1);
  185. }
  186. //
  187. // Set WriteFlags for DBCS Table.
  188. //
  189. pCP->WriteFlags |= F_DBCS;
  190. }
  191. else if (_stricmp(pszKeyWord, "WCTABLE") == 0)
  192. {
  193. if (Verbose)
  194. printf("\n\nFound WCTABLE keyword.\n");
  195. //
  196. // Get size parameter.
  197. //
  198. if (GetSize(&size))
  199. return (1);
  200. //
  201. // Get WC Table.
  202. //
  203. if (GetWCTable( pCP,
  204. size,
  205. (pCP->MaxCharSize - 1) ))
  206. {
  207. return (1);
  208. }
  209. //
  210. // Set WriteFlags for WC Table.
  211. //
  212. pCP->WriteFlags |= F_WC;
  213. }
  214. else if (_stricmp(pszKeyWord, "ENDCODEPAGE") == 0)
  215. {
  216. if (Verbose)
  217. printf("\n\nFound ENDCODEPAGE keyword.\n");
  218. //
  219. // Return success.
  220. //
  221. return (0);
  222. }
  223. else
  224. {
  225. printf("Parse Error: Invalid Instruction '%s'.\n", pszKeyWord);
  226. return (1);
  227. }
  228. }
  229. //
  230. // If this point is reached, then the ENDCODEPAGE keyword was
  231. // not found. Return an error.
  232. //
  233. printf("Parse Error: Expecting ENDCODEPAGE keyword.\n");
  234. return (1);
  235. }
  236. ////////////////////////////////////////////////////////////////////////////
  237. //
  238. // WriteCodePage
  239. //
  240. // This routine writes the code page specific tables to an output file.
  241. //
  242. // 12-10-91 JulieB Created.
  243. ////////////////////////////////////////////////////////////////////////////
  244. int WriteCodePage(
  245. PCODEPAGE pCP)
  246. {
  247. char pszFile[FILE_NAME_LEN]; // file name storage
  248. FILE *pOutputFile; // ptr to output file
  249. //
  250. // Make sure all tables are present.
  251. //
  252. if (!((pCP->WriteFlags & F_CPINFO) &&
  253. (pCP->WriteFlags & F_MB) &&
  254. (pCP->WriteFlags & F_WC)))
  255. {
  256. printf("Write Error: All tables must be present -\n");
  257. printf(" CPInfo, MultiByte, and WideChar Translation Tables.\n");
  258. return (1);
  259. }
  260. //
  261. // Get the name of the output file.
  262. //
  263. memset(pszFile, 0, FILE_NAME_LEN * sizeof(char));
  264. strcpy(pszFile, CP_PREFIX);
  265. strcat(pszFile, pCP->pszName);
  266. strcat(pszFile, DATA_FILE_SUFFIX);
  267. //
  268. // Make sure output file can be opened for writing.
  269. //
  270. if ((pOutputFile = fopen(pszFile, "w+b")) == 0)
  271. {
  272. printf("Error opening output file %s.\n", pszFile);
  273. return (1);
  274. }
  275. if (Verbose)
  276. printf("\n\nWriting output file %s...\n", pszFile);
  277. //
  278. // Write the CPINFO.
  279. //
  280. if (WriteCPInfo(pCP, pOutputFile))
  281. {
  282. fclose(pOutputFile);
  283. return (1);
  284. }
  285. //
  286. // Write MB Table, Glyph Table (if any) and DBCS Table (if any) to
  287. // output file.
  288. //
  289. if (WriteMB(pCP, pOutputFile))
  290. {
  291. fclose(pOutputFile);
  292. return (1);
  293. }
  294. //
  295. // Free MB table structures.
  296. //
  297. FreeMB(pCP);
  298. //
  299. // Write WC Table to output file.
  300. //
  301. if (WriteWC( pCP,
  302. (pCP->WriteFlags & F_DBCS),
  303. pOutputFile ))
  304. {
  305. fclose(pOutputFile);
  306. return (1);
  307. }
  308. //
  309. // Free WC table structures.
  310. //
  311. free(pCP->pWC);
  312. //
  313. // Close the output file.
  314. //
  315. fclose(pOutputFile);
  316. //
  317. // Return success.
  318. //
  319. printf("\nSuccessfully wrote output file %s\n", pszFile);
  320. return (0);
  321. }
  322. //-------------------------------------------------------------------------//
  323. // INTERNAL ROUTINES //
  324. //-------------------------------------------------------------------------//
  325. ////////////////////////////////////////////////////////////////////////////
  326. //
  327. // GetMBTable
  328. //
  329. // This routine gets the multibyte table from the input file. It uses the
  330. // size parameter to know when to stop reading from the file. If an error
  331. // is encountered, a message is printed and an error is returned.
  332. //
  333. // 07-30-91 JulieB Created.
  334. // 12-10-91 JulieB Modified for new table format.
  335. ////////////////////////////////////////////////////////////////////////////
  336. int GetMBTable(
  337. PCODEPAGE pCP,
  338. int Size)
  339. {
  340. int Ctr; // loop counter
  341. int Index; // index into array - single byte char
  342. int Value; // value - WC translation
  343. int NumItems; // number of items returned from fscanf
  344. //
  345. // Allocate MB table.
  346. //
  347. if (AllocateMB(pCP))
  348. {
  349. return (1);
  350. }
  351. //
  352. // For each table entry, read the MB char and the wide char
  353. // from the input file and store the wide char in the array.
  354. //
  355. for (Ctr = 0; Ctr < Size; Ctr++)
  356. {
  357. //
  358. // Get the index and the value to store from the file.
  359. //
  360. NumItems = fscanf( pInputFile,
  361. "%x %x ;%*[^\n]",
  362. &Index,
  363. &Value );
  364. if (NumItems != 2)
  365. {
  366. printf("Parse Error: Error reading MBTABLE values.\n");
  367. return (1);
  368. }
  369. if (Index > MB_TABLE_SIZE)
  370. {
  371. printf("Parse Error: Multibyte char value too large.\n");
  372. printf(" Value must be less than 0x%x.\n", MB_TABLE_SIZE);
  373. return (1);
  374. }
  375. //
  376. // Store the wide character value in the array.
  377. //
  378. (pCP->pMB)[Index] = (WORD)Value;
  379. if (Verbose)
  380. printf(" MB = %x\tWC = %x\n", Index, Value);
  381. }
  382. //
  383. // Return success.
  384. //
  385. return (0);
  386. }
  387. ////////////////////////////////////////////////////////////////////////////
  388. //
  389. // GetGlyphTable
  390. //
  391. // This routine gets the glyph table from the input file. It uses the
  392. // size parameter to know when to stop reading from the file. If an error
  393. // is encountered, a message is printed and an error is returned.
  394. //
  395. // 06-02-92 JulieB Created.
  396. ////////////////////////////////////////////////////////////////////////////
  397. int GetGlyphTable(
  398. PCODEPAGE pCP,
  399. int Size)
  400. {
  401. int Ctr; // loop counter
  402. int Index; // index into array - single byte char
  403. int Value; // value - WC translation
  404. int NumItems; // number of items returned from fscanf
  405. //
  406. // Allocate Glyph table.
  407. //
  408. if (AllocateGlyph(pCP))
  409. {
  410. return (1);
  411. }
  412. //
  413. // For each table entry, read the MB char and the wide char
  414. // from the input file and store the wide char in the array.
  415. //
  416. for (Ctr = 0; Ctr < Size; Ctr++)
  417. {
  418. //
  419. // Get the index and the value to store from the file.
  420. //
  421. NumItems = fscanf( pInputFile,
  422. "%x %x ;%*[^\n]",
  423. &Index,
  424. &Value );
  425. if (NumItems != 2)
  426. {
  427. printf("Parse Error: Error reading GLYPHTABLE values.\n");
  428. return (1);
  429. }
  430. if (Index > GLYPH_TABLE_SIZE)
  431. {
  432. printf("Parse Error: Multibyte char value too large.\n");
  433. printf(" Value must be less than 0x%x.\n", GLYPH_TABLE_SIZE);
  434. return (1);
  435. }
  436. //
  437. // Store the wide character value in the array.
  438. //
  439. (pCP->pGlyph)[Index] = (WORD)Value;
  440. if (Verbose)
  441. printf(" MB = %x\tWC = %x\n", Index, Value);
  442. }
  443. //
  444. // Return success.
  445. //
  446. return (0);
  447. }
  448. ////////////////////////////////////////////////////////////////////////////
  449. //
  450. // GetDBCSRanges
  451. //
  452. // This routine gets the DBCS ranges from the input file. It uses the
  453. // size parameter to know when to stop reading from the file. If an error
  454. // is encountered, a message is printed and an error is returned.
  455. //
  456. // 07-30-91 JulieB Created.
  457. // 12-10-91 JulieB Modified for new table format.
  458. ////////////////////////////////////////////////////////////////////////////
  459. int GetDBCSRanges(
  460. PCODEPAGE pCP,
  461. int Size)
  462. {
  463. int Ctr; // loop counter
  464. int Ctr2; // loop counter
  465. int Low; // low end range value
  466. int High; // high end range value
  467. int Offset = DBCS_OFFSET_SIZE; // offset to DBCS table
  468. int NumItems; // # of items returned from fscanf
  469. //
  470. // Save the number of ranges for later.
  471. //
  472. if ((Size < 1) || (Size > 5))
  473. {
  474. printf("Parse Error: Number of DBCS Ranges must be between 1 and 5.\n");
  475. return (1);
  476. }
  477. pCP->NumDBCSRanges = Size;
  478. //
  479. // Allocate initial DBCS array structure.
  480. //
  481. if (AllocateTopDBCS(pCP, Size))
  482. {
  483. return (1);
  484. }
  485. //
  486. // For each range, read the low range, the high range, and the
  487. // DBCS tables for these ranges. DBCS tables MUST be in the
  488. // correct order (low range to high range).
  489. //
  490. for (Ctr = 0; Ctr < Size; Ctr++)
  491. {
  492. //
  493. // Read low and high range.
  494. //
  495. NumItems = fscanf( pInputFile,
  496. "%x %x ;%*[^\n]",
  497. &Low,
  498. &High );
  499. if (NumItems != 2)
  500. {
  501. printf("Parse Error: Error reading DBCS Range values.\n");
  502. return (1);
  503. }
  504. if (High < Low)
  505. {
  506. printf("Parse Error: High Range must be greater than Low Range.\n");
  507. return (1);
  508. }
  509. //
  510. // Allocate DBCS structures.
  511. //
  512. if (AllocateDBCS(pCP, Low, High, Ctr))
  513. {
  514. return (1);
  515. }
  516. //
  517. // Set the range in the structure.
  518. //
  519. (pCP->pDBCS)[Ctr]->LowRange = (WORD)Low;
  520. (pCP->pDBCS)[Ctr]->HighRange = (WORD)High;
  521. if (Verbose)
  522. printf(" LOW = %x\tHIGH = %x\n", Low, High);
  523. //
  524. // Get Tables for this range.
  525. //
  526. if (GetAllDBCSTables( High - Low + 1,
  527. (pCP->pDBCS)[Ctr]->pDBCSTbls ))
  528. {
  529. return (1);
  530. }
  531. //
  532. // Set the offsets for the range.
  533. // Offsets are in WORDS.
  534. //
  535. for (Ctr2 = Low; Ctr2 <= High; Ctr2++)
  536. {
  537. pCP->pDBCSOff[Ctr2] = (WORD)Offset;
  538. Offset += DBCS_TABLE_SIZE;
  539. //
  540. // This shouldn't happen, but check it just in case.
  541. // ( 254 tables max - (65536/256) - 2 )
  542. //
  543. if (Offset > 65536)
  544. {
  545. printf("FATAL Error: Too many DBCS tables - 254 max allowed.\n");
  546. return (1);
  547. }
  548. }
  549. //
  550. // Save the LeadByte values in pCP structure again for easy
  551. // writing to file.
  552. //
  553. (pCP->LeadBytes)[Ctr * 2] = (BYTE)Low;
  554. (pCP->LeadBytes)[(Ctr * 2) + 1] = (BYTE)High;
  555. }
  556. //
  557. // Return success.
  558. //
  559. return (0);
  560. }
  561. ////////////////////////////////////////////////////////////////////////////
  562. //
  563. // GetAllDBCSTables
  564. //
  565. // This routine gets the DBCS tables (for one range) from the input file
  566. // and places them in the appropriate structures.
  567. //
  568. // 07-30-91 JulieB Created.
  569. ////////////////////////////////////////////////////////////////////////////
  570. int GetAllDBCSTables(
  571. int NumTables,
  572. PDBCS_TBL_ARRAY pArray)
  573. {
  574. int Ctr; // loop counter
  575. char pszKeyWord[MAX]; // input token
  576. int size; // size of table to follow
  577. //
  578. // Read each table.
  579. //
  580. for (Ctr = 0; Ctr < NumTables; Ctr++)
  581. {
  582. //
  583. // Get DBCSTABLE keyword.
  584. //
  585. if ((fscanf(pInputFile, "%s", pszKeyWord) != 1) ||
  586. (_stricmp(pszKeyWord, "DBCSTABLE") != 0))
  587. {
  588. printf("Parse Error: Error reading DBCSTABLE keyword.\n");
  589. return (1);
  590. }
  591. if (Verbose)
  592. printf("\n Found DBCSTABLE keyword.\n");
  593. //
  594. // Get size parameter.
  595. //
  596. if (GetSize(&size))
  597. return (1);
  598. //
  599. // Get DBCS Table.
  600. //
  601. if (GetDBCSTable(size, pArray[Ctr]))
  602. {
  603. return (1);
  604. }
  605. }
  606. //
  607. // Return success.
  608. //
  609. return (0);
  610. }
  611. ////////////////////////////////////////////////////////////////////////////
  612. //
  613. // GetDBCSTable
  614. //
  615. // This routine gets the DBCS table from the input file. It uses the
  616. // size parameter to know when to stop reading from the file. If an error
  617. // is encountered, a message is printed and an error is returned.
  618. //
  619. // 07-30-91 JulieB Created.
  620. ////////////////////////////////////////////////////////////////////////////
  621. int GetDBCSTable(
  622. int Size,
  623. PDBCS_TBL pTable)
  624. {
  625. int Ctr; // loop counter
  626. int Index; // index into array - single byte char
  627. int Value; // value - WC translation
  628. int NumItems; // number of items returned from fscanf
  629. //
  630. // For each table entry, read the MB char and the wide char
  631. // from the input file and store the wide char in the array.
  632. //
  633. for (Ctr = 0; Ctr < Size; Ctr++)
  634. {
  635. //
  636. // Get the index and the value to store from the file.
  637. //
  638. NumItems = fscanf( pInputFile,
  639. "%x %x ;%*[^\n]",
  640. &Index,
  641. &Value );
  642. if (NumItems != 2)
  643. {
  644. printf("Parse Error: Error reading DBCSTABLE values.\n");
  645. return (1);
  646. }
  647. if (Index > DBCS_TABLE_SIZE)
  648. {
  649. printf("Parse Error: DBCS character value too large.\n");
  650. printf(" Value must be less than 0x%x.\n", DBCS_TABLE_SIZE);
  651. return (1);
  652. }
  653. //
  654. // Store the wide character value in the array.
  655. //
  656. pTable[Index] = (WORD)Value;
  657. if (Verbose)
  658. printf(" MB = %x\tWC = %x\n", Index, Value);
  659. }
  660. //
  661. // Return success.
  662. //
  663. return (0);
  664. }
  665. ////////////////////////////////////////////////////////////////////////////
  666. //
  667. // GetWCTable
  668. //
  669. // This routine gets the wide character table from the input file. It uses
  670. // the size parameter to know when to stop reading from the file. If an
  671. // error is encountered, a message is printed and an error is returned.
  672. //
  673. // 07-30-91 JulieB Created.
  674. // 12-10-91 JulieB Modified for new table format.
  675. ////////////////////////////////////////////////////////////////////////////
  676. int GetWCTable(
  677. PCODEPAGE pCP,
  678. int Size,
  679. BOOL IsMBCodePage)
  680. {
  681. int WChar; // wide character value
  682. int MBChar; // multibyte character value
  683. register int Ctr; // loop counter
  684. BYTE *pBytePtr; // ptr to byte table
  685. WORD *pWordPtr; // ptr to word table
  686. int NumItems; // number of items returned from fscanf
  687. //
  688. // Allocate buffer for 1-to-1 mapping table.
  689. //
  690. if (IsMBCodePage)
  691. {
  692. if (AllocateWCTable(pCP, sizeof(WORD)))
  693. {
  694. return (1);
  695. }
  696. pWordPtr = (WORD *)(pCP->pWC);
  697. }
  698. else
  699. {
  700. if (AllocateWCTable(pCP, sizeof(BYTE)))
  701. {
  702. return (1);
  703. }
  704. pBytePtr = (BYTE *)(pCP->pWC);
  705. }
  706. //
  707. // For each entry in table, read in wide character and multibyte
  708. // character from input file.
  709. //
  710. for (Ctr = 0; Ctr < Size; Ctr++)
  711. {
  712. //
  713. // Read in wide character and multibyte character.
  714. //
  715. NumItems = fscanf( pInputFile,
  716. "%x %x ;%*[^\n]",
  717. &WChar,
  718. &MBChar );
  719. if (NumItems != 2)
  720. {
  721. printf("Parse Error: Error reading WCTABLE values.\n");
  722. return (1);
  723. }
  724. if (Verbose)
  725. printf(" WC = %x\tMB = %x\n", WChar, MBChar);
  726. //
  727. // Insert MBChar into the appropriate translation table buffer.
  728. //
  729. if (IsMBCodePage)
  730. {
  731. pWordPtr[WChar] = (WORD)MBChar;
  732. }
  733. else
  734. {
  735. pBytePtr[WChar] = (BYTE)MBChar;
  736. }
  737. }
  738. //
  739. // Return success.
  740. //
  741. return (0);
  742. }
  743. ////////////////////////////////////////////////////////////////////////////
  744. //
  745. // WriteCPInfo
  746. //
  747. // This routine writes the CP information to the output file.
  748. //
  749. // 12-10-91 JulieB Created.
  750. ////////////////////////////////////////////////////////////////////////////
  751. int WriteCPInfo(
  752. PCODEPAGE pCP,
  753. FILE *pOutputFile)
  754. {
  755. int Size = CP_INFO_SIZE; // size of CPINFO information
  756. WORD wValue; // temp storage value
  757. //
  758. // Get the translation of the MB default char and the
  759. // Unicode default char.
  760. //
  761. if (GetTransDefaultChars(pCP))
  762. {
  763. return (1);
  764. }
  765. if (Verbose)
  766. printf("\nWriting CP Info...\n");
  767. //
  768. // Write size of CPInfo to file.
  769. //
  770. wValue = (WORD)Size;
  771. if (FileWrite( pOutputFile,
  772. &wValue,
  773. sizeof(WORD),
  774. 1,
  775. "CPINFO Table Size" ))
  776. {
  777. return (1);
  778. }
  779. //
  780. // Write CodePageValue to file.
  781. //
  782. wValue = (WORD)(pCP->CodePageValue);
  783. if (FileWrite( pOutputFile,
  784. &wValue,
  785. sizeof(WORD),
  786. 1,
  787. "CPINFO Code Page Value" ))
  788. {
  789. return (1);
  790. }
  791. //
  792. // Write MaxCharSize to file.
  793. //
  794. wValue = (WORD)(pCP->MaxCharSize);
  795. if (FileWrite( pOutputFile,
  796. &wValue,
  797. sizeof(WORD),
  798. 1,
  799. "CPINFO Max Char Size" ))
  800. {
  801. return (1);
  802. }
  803. //
  804. // Write Default Char to file.
  805. //
  806. if (FileWrite( pOutputFile,
  807. &(pCP->DefaultChar),
  808. sizeof(WORD),
  809. 1,
  810. "CPINFO Default Char" ))
  811. {
  812. return (1);
  813. }
  814. //
  815. // Write Unicode Default Char to file.
  816. //
  817. if (FileWrite( pOutputFile,
  818. &(pCP->UniDefaultChar),
  819. sizeof(WORD),
  820. 1,
  821. "CPINFO Unicode Default Char" ))
  822. {
  823. return (1);
  824. }
  825. //
  826. // Write Translation of Default Char to file.
  827. //
  828. if (FileWrite( pOutputFile,
  829. &(pCP->TransDefChar),
  830. sizeof(WORD),
  831. 1,
  832. "CPINFO Translation of Default Char" ))
  833. {
  834. return (1);
  835. }
  836. //
  837. // Write Translation of Unicode Default Char to file.
  838. //
  839. if (FileWrite( pOutputFile,
  840. &(pCP->TransUniDefChar),
  841. sizeof(WORD),
  842. 1,
  843. "CPINFO Translation of Unicode Default Char" ))
  844. {
  845. return (1);
  846. }
  847. //
  848. // Write DBCS LeadByte Ranges to file.
  849. //
  850. if (FileWrite( pOutputFile,
  851. &(pCP->LeadBytes),
  852. sizeof(BYTE),
  853. MAX_NUM_LEADBYTE,
  854. "CPINFO LeadBytes" ))
  855. {
  856. return (1);
  857. }
  858. //
  859. // Return success.
  860. //
  861. return (0);
  862. }
  863. ////////////////////////////////////////////////////////////////////////////
  864. //
  865. // WriteMB
  866. //
  867. // This routine writes the MB table, GLYPH table (if it exists), and
  868. // DBCS table (if it exists) to the output file.
  869. //
  870. // 07-30-91 JulieB Created.
  871. ////////////////////////////////////////////////////////////////////////////
  872. int WriteMB(
  873. PCODEPAGE pCP,
  874. FILE *pOutputFile)
  875. {
  876. int TblSize; // size of table
  877. int Ctr; // loop counter
  878. int Ctr2; // loop counter
  879. PDBCS_ARRAY pDBCSArray; // ptr to DBCS array
  880. PDBCS_RANGE pRange; // ptr to range structure
  881. register int NumRanges; // number of DBCS ranges
  882. register int NumTables; // number of tables for range
  883. WORD wValue; // temp storage value
  884. if (Verbose)
  885. printf("\nWriting MB Table...\n");
  886. //
  887. // Compute size of table and write it to the output file.
  888. //
  889. TblSize = ComputeMBSize(pCP);
  890. wValue = (WORD)TblSize;
  891. if (FileWrite( pOutputFile,
  892. &wValue,
  893. sizeof(WORD),
  894. 1,
  895. "MB size" ))
  896. {
  897. return (1);
  898. }
  899. //
  900. // Write MB Table to output file.
  901. //
  902. if (FileWrite( pOutputFile,
  903. pCP->pMB,
  904. sizeof(WORD),
  905. MB_TABLE_SIZE,
  906. "MB table" ))
  907. {
  908. return (1);
  909. }
  910. //
  911. // Write Glyph Table to output file (if it exists).
  912. //
  913. if (pCP->WriteFlags & F_GLYPH)
  914. {
  915. wValue = GLYPH_TABLE_SIZE;
  916. if (FileWrite( pOutputFile,
  917. &wValue,
  918. sizeof(WORD),
  919. 1,
  920. "GLYPH table size" ))
  921. {
  922. return (1);
  923. }
  924. if (FileWrite( pOutputFile,
  925. pCP->pGlyph,
  926. sizeof(WORD),
  927. GLYPH_TABLE_SIZE,
  928. "GLYPH table" ))
  929. {
  930. return (1);
  931. }
  932. }
  933. else
  934. {
  935. wValue = 0;
  936. if (FileWrite( pOutputFile,
  937. &wValue,
  938. sizeof(WORD),
  939. 1,
  940. "GLYPH table size" ))
  941. {
  942. return (1);
  943. }
  944. }
  945. //
  946. // Write number of DBCS ranges to output file.
  947. //
  948. wValue = (WORD)(pCP->NumDBCSRanges);
  949. if (FileWrite( pOutputFile,
  950. &wValue,
  951. sizeof(WORD),
  952. 1,
  953. "DBCS Ranges" ))
  954. {
  955. return (1);
  956. }
  957. //
  958. // Write the DBCS tables to the file (if any exist).
  959. //
  960. NumRanges = pCP->NumDBCSRanges;
  961. if ((NumRanges > 0) && (pCP->WriteFlags & F_DBCS))
  962. {
  963. if (Verbose)
  964. printf("\n Writing DBCS Table...\n");
  965. //
  966. // Write the offsets.
  967. //
  968. if (FileWrite( pOutputFile,
  969. pCP->pDBCSOff,
  970. sizeof(WORD),
  971. DBCS_OFFSET_SIZE,
  972. "DBCS Offsets" ))
  973. {
  974. return (1);
  975. }
  976. //
  977. // Write the tables.
  978. //
  979. pDBCSArray = pCP->pDBCS;
  980. for (Ctr = 0; Ctr < NumRanges; Ctr++)
  981. {
  982. pRange = pDBCSArray[Ctr];
  983. if (Verbose)
  984. printf(" Writing DBCS range %x to %x\n",
  985. pRange->LowRange, pRange->HighRange);
  986. NumTables = pRange->HighRange - pRange->LowRange + 1;
  987. for (Ctr2 = 0; Ctr2 < NumTables; Ctr2++)
  988. {
  989. if (FileWrite( pOutputFile,
  990. pRange->pDBCSTbls[Ctr2],
  991. sizeof(WORD),
  992. DBCS_TABLE_SIZE,
  993. "DBCS Table" ))
  994. {
  995. return (1);
  996. }
  997. if (Verbose)
  998. printf(" Writing DBCS table %d\n", Ctr2 + 1);
  999. }
  1000. }
  1001. }
  1002. //
  1003. // Return success.
  1004. //
  1005. return (0);
  1006. }
  1007. ////////////////////////////////////////////////////////////////////////////
  1008. //
  1009. // WriteWC
  1010. //
  1011. // This routine writes the WC information to the output file.
  1012. //
  1013. // 07-30-91 JulieB Created.
  1014. ////////////////////////////////////////////////////////////////////////////
  1015. int WriteWC(
  1016. PCODEPAGE pCP,
  1017. BOOL IsMBCodePage,
  1018. FILE *pOutputFile)
  1019. {
  1020. WORD wValue; // temp storage value
  1021. if (Verbose)
  1022. printf("\nWriting WC Table...\n");
  1023. //
  1024. // Write 0 for SB or 1 for DB code page to the output file.
  1025. //
  1026. wValue = (WORD)IsMBCodePage;
  1027. if (FileWrite( pOutputFile,
  1028. &wValue,
  1029. sizeof(WORD),
  1030. 1,
  1031. "SB or DB flag" ))
  1032. {
  1033. return (1);
  1034. }
  1035. //
  1036. // Write WC translation table to the output file.
  1037. //
  1038. if (FileWrite( pOutputFile,
  1039. pCP->pWC,
  1040. (IsMBCodePage) ? sizeof(WORD) : sizeof(BYTE),
  1041. WC_TABLE_SIZE,
  1042. "WC Table" ))
  1043. {
  1044. return (1);
  1045. }
  1046. //
  1047. // Return success.
  1048. //
  1049. return (0);
  1050. }
  1051. ////////////////////////////////////////////////////////////////////////////
  1052. //
  1053. // FreeMB
  1054. //
  1055. // This routine frees the memory used to build the MB table and the DBCS
  1056. // table.
  1057. //
  1058. // 07-30-91 JulieB Created.
  1059. ////////////////////////////////////////////////////////////////////////////
  1060. void FreeMB(
  1061. PCODEPAGE pCP)
  1062. {
  1063. int Ctr; // loop counter
  1064. int Ctr2; // loop counter
  1065. PDBCS_ARRAY pDBCSArray; // ptr to DBCS array
  1066. PDBCS_RANGE pRange; // ptr to DBCS Range structure
  1067. PDBCS_TBL_ARRAY pTbls; // ptr to DBCS table array
  1068. register int NumRanges; // number of DBCS ranges
  1069. register int NumTables; // number of tables in range
  1070. //
  1071. // Free Multibyte Table structures.
  1072. //
  1073. if (pCP->pMB != NULL)
  1074. {
  1075. free(pCP->pMB);
  1076. }
  1077. //
  1078. // Free Glyph Table structures.
  1079. //
  1080. if (pCP->pGlyph != NULL)
  1081. {
  1082. free(pCP->pGlyph);
  1083. }
  1084. //
  1085. // Free DBCS Table structures.
  1086. //
  1087. if ((pDBCSArray = pCP->pDBCS) != NULL)
  1088. {
  1089. NumRanges = pCP->NumDBCSRanges;
  1090. for (Ctr = 0; Ctr < NumRanges; Ctr++)
  1091. {
  1092. if ((pRange = pDBCSArray[Ctr]) != NULL)
  1093. {
  1094. if ((pTbls = pRange->pDBCSTbls) != NULL)
  1095. {
  1096. NumTables = pRange->HighRange - pRange->LowRange + 1;
  1097. for (Ctr2 = 0; Ctr2 < NumTables; Ctr2++)
  1098. {
  1099. if (pTbls[Ctr2] != NULL)
  1100. {
  1101. free(pTbls[Ctr2]);
  1102. }
  1103. }
  1104. free(pTbls);
  1105. }
  1106. free(pRange);
  1107. }
  1108. }
  1109. free(pDBCSArray);
  1110. }
  1111. if (pCP->pDBCSOff != NULL)
  1112. {
  1113. free(pCP->pDBCSOff);
  1114. }
  1115. }
  1116. ////////////////////////////////////////////////////////////////////////////
  1117. //
  1118. // GetTransDefaultChars
  1119. //
  1120. // Gets the MB translation for the Unicode default char and
  1121. // the Unicode translation for the MB default char.
  1122. //
  1123. // This allows the multi byte default char and the Unicode default char
  1124. // to be different in the data file.
  1125. //
  1126. // 09-01-93 JulieB Created.
  1127. ////////////////////////////////////////////////////////////////////////////
  1128. int GetTransDefaultChars(
  1129. PCODEPAGE pCP)
  1130. {
  1131. WORD wDefChar; // default char to translate
  1132. WORD Lead; // lead byte of DBCS char
  1133. WORD Low; // low part of DBCS range
  1134. WORD High; // high part of DBCS range
  1135. int ctr; // loop counter
  1136. PDBCS_TBL pDBCSTable; // ptr to appropriate DBCS table
  1137. //
  1138. // Get the MB translation for the Unicode Default Char.
  1139. //
  1140. wDefChar = pCP->UniDefaultChar;
  1141. if (pCP->MaxCharSize == 1)
  1142. {
  1143. //
  1144. // Single byte code page.
  1145. //
  1146. pCP->TransUniDefChar = ((WORD)(((BYTE *)(pCP->pWC))[wDefChar]));
  1147. }
  1148. else
  1149. {
  1150. //
  1151. // Double byte code page.
  1152. //
  1153. pCP->TransUniDefChar = ((WORD)(((WORD *)(pCP->pWC))[wDefChar]));
  1154. }
  1155. //
  1156. // Get the Unicode translation for the MB Default Char.
  1157. //
  1158. wDefChar = pCP->DefaultChar;
  1159. if (Lead = (WORD)HIBYTE(wDefChar))
  1160. {
  1161. //
  1162. // Make sure the DBCS tables exist.
  1163. //
  1164. if (!(pCP->pDBCS))
  1165. {
  1166. printf("Parse Error: Invalid default char '%x'.\n", wDefChar);
  1167. return (1);
  1168. }
  1169. //
  1170. // Search for the correct range.
  1171. //
  1172. for (ctr = 0; ctr < pCP->NumDBCSRanges; ctr++)
  1173. {
  1174. Low = ((pCP->pDBCS)[ctr])->LowRange;
  1175. High = ((pCP->pDBCS)[ctr])->HighRange;
  1176. if ((Lead >= Low) && (Lead <= High))
  1177. {
  1178. break;
  1179. }
  1180. }
  1181. //
  1182. // Make sure the lead byte is valid.
  1183. //
  1184. if (ctr == pCP->NumDBCSRanges)
  1185. {
  1186. printf("Parse Error: Invalid default char '%x'.\n", wDefChar);
  1187. return (1);
  1188. }
  1189. //
  1190. // Get the Unicode translation of the DBCS char.
  1191. //
  1192. pDBCSTable = (((pCP->pDBCS)[ctr])->pDBCSTbls)[Lead - Low];
  1193. pCP->TransDefChar = ((WORD)(pDBCSTable[LOBYTE(wDefChar)]));
  1194. //
  1195. // Make sure the trail byte is valid.
  1196. //
  1197. if ((pCP->TransDefChar == pCP->UniDefaultChar) &&
  1198. (wDefChar != pCP->TransUniDefChar))
  1199. {
  1200. printf("Parse Error: Invalid default char '%x'.\n", wDefChar);
  1201. return (1);
  1202. }
  1203. }
  1204. else
  1205. {
  1206. pCP->TransDefChar = ((WORD)((pCP->pMB)[LOBYTE(wDefChar)]));
  1207. }
  1208. //
  1209. // Return success.
  1210. //
  1211. return (0);
  1212. }