Merge pull request #337 from robwilkens/IdleThreadsFixes
[mono.git] / mcs / class / I18N / CJK / dbcs-table-generator.cs
1 //
2 // dbcs-table-generator.cs : generates big5.table or gb2312-new.table
3 //
4 // Author:
5 //      Atsushi Enomoto  <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc. http://www.novell.com
8 //
9 // where CP936.TXT and CP950.TXT is found at:
10 // http://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT
11 //
12 // (don't use BIG5.TXT - it is obsoleted. GB2312.TXT does not exist anymore.)
13 //
14 using System;
15 using System.Globalization;
16 using System.IO;
17
18 public class DbcsTableGenerator
19 {
20         public static void Main (string [] args)
21         {
22                 if (args.Length == 1) {
23                         switch (args [0]) {
24                         case "BIG5":
25                                 Main (new string [] {
26                                         "CP950.TXT", "big5.table", "A1", "43"});
27                                 return;
28                         case "GB2312":
29                                 Main (new string [] {
30                                         "CP936.TXT", "gb2312-new.table", "81", "5E"});
31                                 return;
32                         }
33                 }
34
35                 if (args.Length < 3) {
36                         Console.Error.WriteLine (@"
37 usage1: dbcs-table-generator.exe BIG5
38
39 usage2: dbcs-table-generator.exe GB2312
40
41 usage3: dbcs-table-generator.exe CPxxx.TXT xxx.table from [len]
42
43 from: BIG5 (CP950) = A1, GB2312 (CP936) = 81
44 len: optional. length of array. BIG5: 43");
45                         return;
46                 }
47                 byte upper = byte.Parse (args [2], NumberStyles.HexNumber);
48
49                 int [] n2u = new int [0x10000];
50                 int [] u2n = new int [0x10000];
51
52                 StreamReader reader = new StreamReader (args [0]);
53                 int native_min = upper << 8 + 0x40;
54                 int native_max = 0x10000;
55                 int native_count = native_max - native_min;
56
57                 if (args.Length > 3) {
58                         native_count = int.Parse (args [3], NumberStyles.HexNumber) << 8;
59                         native_max = native_min + native_count;
60                         Console.Error.WriteLine ("adjusted as count = {0:X04} max = {1:X04}", native_count, native_max);
61                 }
62
63                 int map_count = 0;
64                 for (int line = 1; reader.Peek () > 0; line++) {
65                         string s = reader.ReadLine ();
66                         int idx = s.IndexOf ('#');
67                         if (idx >= 0)
68                                 s = s.Substring (0, idx).Trim ();
69                         if (s.Length == 0)
70                                 continue;
71                         idx = s.IndexOf ('\t');
72                         if (idx < 0)
73                                 continue;
74                         if (s.Length < 2 || s [0] != '0' || s [1] != 'x')
75                                 throw new ArgumentException ("Unexpected line at " + line + " : " + s);
76                         int native = int.Parse (s.Substring (2, idx - 2).Trim (), NumberStyles.HexNumber);
77                         if (native < native_min)
78                                 continue;
79                         int ordinal = ((int) (native / 0x100 - upper)) * 191 +
80                                 (native % 0x100 - 0x40);
81
82                         s = s.Substring (idx + 1).Trim ();
83                         if (s.Length < 2 || s [0] != '0' || s [1] != 'x')
84                                 throw new ArgumentException ("Unexpected line at " + line + " : " + s);
85                         int uni = int.Parse (s.Substring (2), NumberStyles.HexNumber);
86                         u2n [uni] = native;
87                         n2u [ordinal] = uni;
88                         map_count++;
89                 }
90
91                 FileStream output = File.OpenWrite (args [1]);
92                 output.Seek (0, SeekOrigin.Begin);
93
94                 WriteInt32 (output, 1);
95                 WriteInt32 (output, native_count * 2);
96                 for (int i = 0; i < native_count; i++) {
97                         output.WriteByte ((byte) (n2u [i] % 256));
98                         output.WriteByte ((byte) (n2u [i] / 256));
99                 }
100
101                 int uni_max = 0x10000;
102                 WriteInt32 (output, 2);
103                 WriteInt32 (output, uni_max * 2);
104                 for (int i = 0; i < uni_max; i++) {
105                         output.WriteByte ((byte) (u2n [i] % 256));
106                         output.WriteByte ((byte) (u2n [i] / 256));
107                 }
108
109                 output.Close ();
110         }
111
112         static void WriteInt32 (Stream s, int value)
113         {
114                 for (int i = 0; i < 4; i++) {
115                         s.WriteByte ((byte) (value % 0x100));
116                         value /= 0x100;
117                 }
118         }
119 }
120