root/apps/outlook/branches/1.5/DotTelSystem/Punycode/generate/GenerateNFKC.cs
@
580
| Revision 580, 27.7 kB (checked in by jonmaycock, 10 months ago) |
|---|
| Line | |
|---|---|
| 1 | /// <summary> Copyright (C) 2004, 2007 Free Software Foundation, Inc. |
| 2 | /// * |
| 3 | /// Author: Alexander Gnauck AG-Software |
| 4 | /// * |
| 5 | /// This file is part of GNU Libidn. |
| 6 | /// * |
| 7 | /// This library is free software; you can redistribute it and/or |
| 8 | /// modify it under the terms of the GNU Lesser General Public License |
| 9 | /// as published by the Free Software Foundation; either version 2.1 of |
| 10 | /// the License, or (at your option) any later version. |
| 11 | /// * |
| 12 | /// This library is distributed in the hope that it will be useful, but |
| 13 | /// WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | /// Lesser General Public License for more details. |
| 16 | /// * |
| 17 | /// You should have received a copy of the GNU Lesser General Public |
| 18 | /// License along with this library; if not, write to the Free Software |
| 19 | /// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 |
| 20 | /// USA |
| 21 | /// </summary> |
| 22 | using System; |
| 23 | using System.IO; |
| 24 | using System.Collections; |
| 25 | using System.Text; |
| 26 | |
| 27 | namespace gnu.inet.encoding.misc |
| 28 | { |
| 29 | public class GenerateNFKC |
| 30 | { |
| 31 | internal static string stripComment(string sIn) |
| 32 | { |
| 33 | int c = sIn.IndexOf('#'); |
| 34 | if (c == -1) |
| 35 | { |
| 36 | return sIn; |
| 37 | } |
| 38 | else |
| 39 | { |
| 40 | return sIn.Substring(0, (c) - (0)); |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | internal static string[] split(string sIn, char sep) |
| 45 | { |
| 46 | StringBuilder sb = new StringBuilder(sIn); |
| 47 | int c = 0; |
| 48 | for (int i = 0; i < sb.Length; i++) |
| 49 | { |
| 50 | if (sb[i] == sep) |
| 51 | { |
| 52 | c++; |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | string[] sOut = new string[c + 1]; |
| 57 | c = 0; |
| 58 | int l = 0; |
| 59 | for (int i = 0; i < sb.Length; i++) |
| 60 | { |
| 61 | if (sb[i] == sep) |
| 62 | { |
| 63 | if (l >= i) |
| 64 | { |
| 65 | sOut[c] = ""; |
| 66 | } |
| 67 | else |
| 68 | { |
| 69 | // TODO, check this |
| 70 | sOut[c] = sb.ToString(l, i-l); |
| 71 | } |
| 72 | l = i + 1; |
| 73 | c++; |
| 74 | } |
| 75 | } |
| 76 | if (l < sb.Length) |
| 77 | { |
| 78 | sOut[c] = sb.ToString(l, sb.Length - l); |
| 79 | } |
| 80 | return sOut; |
| 81 | } |
| 82 | |
| 83 | internal static bool isCompatibilityMapping(string sIn) |
| 84 | { |
| 85 | return sIn.Length > 0 && sIn[0] == '<'; |
| 86 | } |
| 87 | |
| 88 | internal static string stripCompatibilityTag(string sIn) |
| 89 | { |
| 90 | return sIn.Substring(sIn.IndexOf('>') + 2); |
| 91 | } |
| 92 | |
| 93 | internal static string toString(string sIn) |
| 94 | { |
| 95 | StringBuilder sOut = new StringBuilder(); |
| 96 | string[] chars = split(sIn, ' '); |
| 97 | for (int i = 0; i < chars.Length; i++) |
| 98 | { |
| 99 | if (chars[i].Equals("005C")) |
| 100 | { |
| 101 | sOut.Append("\\\\"); |
| 102 | } |
| 103 | else if (chars[i].Equals("0022")) |
| 104 | { |
| 105 | sOut.Append("\\\""); |
| 106 | } |
| 107 | else |
| 108 | { |
| 109 | sOut.Append("\\u"); |
| 110 | sOut.Append(chars[i]); |
| 111 | } |
| 112 | } |
| 113 | return sOut.ToString(); |
| 114 | } |
| 115 | |
| 116 | internal static string decompose(string sIn, SortedList mappings) |
| 117 | { |
| 118 | StringBuilder sOut = new StringBuilder(); |
| 119 | string[] c = split(sIn, ' '); |
| 120 | |
| 121 | for (int i = 0; i < c.Length; i++) |
| 122 | { |
| 123 | if (mappings.ContainsKey(c[i])) |
| 124 | { |
| 125 | if (sOut.Length > 0) |
| 126 | { |
| 127 | sOut.Append(" "); |
| 128 | } |
| 129 | sOut.Append(decompose((string)mappings[c[i]], mappings)); |
| 130 | } |
| 131 | else |
| 132 | { |
| 133 | if (sOut.Length > 0) |
| 134 | { |
| 135 | sOut.Append(" "); |
| 136 | } |
| 137 | sOut.Append(c[i]); |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | return sOut.ToString(); |
| 142 | } |
| 143 | |
| 144 | public static void Generate() |
| 145 | { |
| 146 | // Check if the unicode files exist |
| 147 | { |
| 148 | FileInfo f1 = new FileInfo("CompositionExclusions.txt"); |
| 149 | FileInfo f2 = new FileInfo("UnicodeData.txt"); |
| 150 | bool tmpBool; |
| 151 | if (File.Exists(f1.FullName)) |
| 152 | tmpBool = true; |
| 153 | else |
| 154 | tmpBool = Directory.Exists(f1.FullName); |
| 155 | bool tmpBool2; |
| 156 | if (File.Exists(f2.FullName)) |
| 157 | tmpBool2 = true; |
| 158 | else |
| 159 | tmpBool2 = Directory.Exists(f2.FullName); |
| 160 | if (!tmpBool || !tmpBool2) |
| 161 | { |
| 162 | Console.WriteLine("Unable to find UnicodeData.txt or CompositionExclusions.txt."); |
| 163 | Console.WriteLine("Please download the latest version of these file from:"); |
| 164 | Console.WriteLine("http://www.unicode.org/Public/UNIDATA/"); |
| 165 | System.Environment.Exit(1); |
| 166 | } |
| 167 | } |
| 168 | |
| 169 | ArrayList exclusions = new ArrayList(); |
| 170 | { |
| 171 | StreamReader r = new StreamReader("CompositionExclusions.txt", System.Text.Encoding.Default); |
| 172 | string line; |
| 173 | while (null != (line = r.ReadLine())) |
| 174 | { |
| 175 | line = stripComment(line); |
| 176 | line = line.Trim(); |
| 177 | if (line.Length == 0) |
| 178 | { |
| 179 | // Empty line |
| 180 | } |
| 181 | else if (line.Length == 4) |
| 182 | { |
| 183 | exclusions.Add(line); |
| 184 | } |
| 185 | else |
| 186 | { |
| 187 | // Skip code points > 0xffff |
| 188 | } |
| 189 | } |
| 190 | r.Close(); |
| 191 | } |
| 192 | |
| 193 | // Read UnicodeData |
| 194 | |
| 195 | SortedList canonical = new SortedList(); |
| 196 | SortedList compatibility = new SortedList(); |
| 197 | SortedList combiningClasses = new SortedList(); |
| 198 | { |
| 199 | StreamReader r = new StreamReader("UnicodeData.txt", Encoding.Default); |
| 200 | string line; |
| 201 | while (null != (line = r.ReadLine())) |
| 202 | { |
| 203 | line = stripComment(line); |
| 204 | line = line.Trim(); |
| 205 | |
| 206 | if (line.Length == 0) |
| 207 | { |
| 208 | // Empty line |
| 209 | } |
| 210 | else |
| 211 | { |
| 212 | string[] f = split(line, ';'); |
| 213 | |
| 214 | if (f[0].Length == 4) |
| 215 | { |
| 216 | if (!f[5].Equals("")) |
| 217 | { |
| 218 | if (isCompatibilityMapping(f[5])) |
| 219 | { |
| 220 | compatibility[f[0]] = stripCompatibilityTag(f[5]); |
| 221 | } |
| 222 | else |
| 223 | { |
| 224 | compatibility[f[0]] = f[5]; |
| 225 | if (!exclusions.Contains(f[0])) |
| 226 | { |
| 227 | canonical[f[0]] = f[5]; |
| 228 | } |
| 229 | } |
| 230 | } |
| 231 | if (!f[3].Equals("0")) |
| 232 | { |
| 233 | //UPGRADE_TODO: Method 'java.lang.Integer.parseInt' was converted to 'System.Convert.ToInt32' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073'" |
| 234 | combiningClasses[(int)System.Convert.ToInt32(f[0], 16)] = f[3]; |
| 235 | } |
| 236 | } |
| 237 | else |
| 238 | { |
| 239 | // Skip code points > 0xffff |
| 240 | } |
| 241 | } |
| 242 | } |
| 243 | r.Close(); |
| 244 | } |
| 245 | |
| 246 | // Recursively apply compatibility mappings |
| 247 | while (true) |
| 248 | { |
| 249 | bool replaced = false; |
| 250 | |
| 251 | IEnumerator i = new HashSet(compatibility.Keys).GetEnumerator(); |
| 252 | while (i.MoveNext()) |
| 253 | { |
| 254 | string k = (string)i.Current; |
| 255 | string v = (string)compatibility[k]; |
| 256 | |
| 257 | string d = decompose(v, compatibility); |
| 258 | if (!d.Equals(v)) |
| 259 | { |
| 260 | replaced = true; |
| 261 | compatibility[k] = d; |
| 262 | } |
| 263 | } |
| 264 | |
| 265 | if (!replaced) |
| 266 | { |
| 267 | break; |
| 268 | } |
| 269 | } |
| 270 | |
| 271 | // Eliminate duplicate mappings |
| 272 | SortedList compatibilityKeys = new SortedList(); |
| 273 | ArrayList compatibilityMappings = new ArrayList(); |
| 274 | { |
| 275 | IEnumerator i = new HashSet(compatibility.Keys).GetEnumerator(); |
| 276 | while (i.MoveNext()) |
| 277 | { |
| 278 | string k = (string)i.Current; |
| 279 | string v = (string)compatibility[k]; |
| 280 | |
| 281 | int index = compatibilityMappings.IndexOf(v); |
| 282 | if (index == -1) |
| 283 | { |
| 284 | index = compatibilityMappings.Count; |
| 285 | compatibilityMappings.Add(v); |
| 286 | } |
| 287 | compatibilityKeys[k] = (int)index; |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | // Create composition tables |
| 292 | SortedList firstMap = new SortedList(); |
| 293 | SortedList secondMap = new SortedList(); |
| 294 | { |
| 295 | IEnumerator i = new HashSet(canonical.Keys).GetEnumerator(); |
| 296 | while (i.MoveNext()) |
| 297 | { |
| 298 | string k = (string)i.Current; |
| 299 | string v = (string)canonical[k]; |
| 300 | |
| 301 | string[] s = split(v, ' '); |
| 302 | |
| 303 | if (s.Length == 2) |
| 304 | { |
| 305 | // If both characters have the same combining class, they |
| 306 | // won't be combined (in the sequence AB, B is blocked from |
| 307 | // A if both have the same combining class) |
| 308 | string cc1 = (string)combiningClasses[(int)System.Convert.ToInt32(s[0], 16)]; |
| 309 | string cc2 = (string)combiningClasses[(int)System.Convert.ToInt32(s[1], 16)]; |
| 310 | if (cc1 != null || (cc1 != null && cc1.Equals(cc2))) |
| 311 | { |
| 312 | // Ignore this composition |
| 313 | // TODO check this |
| 314 | //i.remove(); |
| 315 | canonical.Remove(k); |
| 316 | continue; |
| 317 | } |
| 318 | |
| 319 | if (firstMap.ContainsKey(s[0])) |
| 320 | { |
| 321 | int c = (int)firstMap[s[0]]; |
| 322 | firstMap[s[0]] = (int)(c + 1); |
| 323 | } |
| 324 | else |
| 325 | { |
| 326 | firstMap[s[0]] = 1; |
| 327 | } |
| 328 | |
| 329 | if (secondMap.ContainsKey(s[1])) |
| 330 | { |
| 331 | int c = (int)secondMap[s[1]]; |
| 332 | secondMap[s[1]] = (int)(c + 1); |
| 333 | } |
| 334 | else |
| 335 | { |
| 336 | secondMap[s[1]] = 1; |
| 337 | } |
| 338 | } |
| 339 | else if (s.Length > 2) |
| 340 | { |
| 341 | Console.WriteLine("? wrong canonical mapping for " + k); |
| 342 | System.Environment.Exit(1); |
| 343 | } |
| 344 | } |
| 345 | } |
| 346 | |
| 347 | SortedList singleFirstComposition = new SortedList(); |
| 348 | SortedList singleSecondComposition = new SortedList(); |
| 349 | SortedList complexComposition = new SortedList(); |
| 350 | |
| 351 | int composeLookupMax = 0; |
| 352 | { |
| 353 | IEnumerator i = new HashSet(canonical.Keys).GetEnumerator(); |
| 354 | while (i.MoveNext()) |
| 355 | { |
| 356 | string k = (string) i.Current; |
| 357 | string v = (string) canonical[k]; |
| 358 | |
| 359 | string[] s = split(v, ' '); |
| 360 | |
| 361 | if (s.Length == 2) |
| 362 | { |
| 363 | // TODO, check this |
| 364 | int first = 0; |
| 365 | if(firstMap.Contains(s[0])) |
| 366 | first = (int) firstMap[s[0]]; |
| 367 | |
| 368 | int second = 0; |
| 369 | if (secondMap.Contains(s[1])) |
| 370 | second = (int) secondMap[s[1]]; |
| 371 | // TODO, check this |
| 372 | |
| 373 | if (first == 1) |
| 374 | { |
| 375 | singleFirstComposition[s[0]] = new string[] { s[1], k }; |
| 376 | composeLookupMax = System.Math.Max(composeLookupMax, System.Convert.ToInt32(s[0], 16)); |
| 377 | } |
| 378 | else if (second == 1) |
| 379 | { |
| 380 | singleSecondComposition[s[1]] = new string[] { s[0], k }; |
| 381 | composeLookupMax = System.Math.Max(composeLookupMax, System.Convert.ToInt32(s[1], 16)); |
| 382 | } |
| 383 | else |
| 384 | { |
| 385 | if (complexComposition.ContainsKey(s[0])) |
| 386 | { |
| 387 | SortedList m = (SortedList)complexComposition[s[0]]; |
| 388 | if (m.ContainsKey(s[1])) |
| 389 | { |
| 390 | Console.WriteLine("? ambiguous canonical mapping for " + s[0]); |
| 391 | System.Environment.Exit(1); |
| 392 | } |
| 393 | m[s[1]] = k; |
| 394 | } |
| 395 | else |
| 396 | { |
| 397 | SortedList m = new SortedList(); |
| 398 | m[s[1]] = k; |
| 399 | complexComposition[s[0]] = m; |
| 400 | } |
| 401 | composeLookupMax = System.Math.Max(composeLookupMax, System.Convert.ToInt32(s[0], 16)); |
| 402 | composeLookupMax = System.Math.Max(composeLookupMax, System.Convert.ToInt32(s[1], 16)); |
| 403 | } |
| 404 | } |
| 405 | } |
| 406 | } |
| 407 | |
| 408 | Console.WriteLine("Generating CombiningClass.cs file..."); |
| 409 | |
| 410 | // Dump combining classes |
| 411 | { |
| 412 | StreamWriter w = new StreamWriter("CombiningClass.cs", false, Encoding.Default); |
| 413 | w.WriteLine("// Do not edit !!!"); |
| 414 | w.WriteLine("// this file is generated automatically"); |
| 415 | w.WriteLine(); |
| 416 | w.WriteLine("public class CombiningClass"); |
| 417 | w.WriteLine("{"); |
| 418 | w.WriteLine("\tpublic static readonly int[,] c = new int[,] {"); |
| 419 | System.Text.StringBuilder index = new System.Text.StringBuilder(); |
| 420 | |
| 421 | int count = 0; |
| 422 | |
| 423 | for (int i = 0; i < 256; i++) |
| 424 | { |
| 425 | bool empty = true; |
| 426 | |
| 427 | StringBuilder page = new StringBuilder(); |
| 428 | page.Append(" { /* Page " + i + " */"); |
| 429 | |
| 430 | for (int j = 0; j < 256; j++) |
| 431 | { |
| 432 | int c = (int)((i << 8) + j); |
| 433 | string cc = (string)combiningClasses[c]; |
| 434 | |
| 435 | if (0 == (j & 31)) |
| 436 | { |
| 437 | page.Append("\r\n "); |
| 438 | } |
| 439 | if (cc == null) |
| 440 | { |
| 441 | page.Append("0, "); |
| 442 | } |
| 443 | else |
| 444 | { |
| 445 | page.Append(cc + ", "); |
| 446 | empty = false; |
| 447 | } |
| 448 | } |
| 449 | page.Append("\r\n },"); |
| 450 | |
| 451 | index.Append(" "); |
| 452 | |
| 453 | if (!empty) |
| 454 | { |
| 455 | w.WriteLine(page.ToString()); |
| 456 | index.Append(count++); |
| 457 | index.Append(",\r\n"); |
| 458 | } |
| 459 | else |
| 460 | { |
| 461 | index.Append("-1,\r\n"); |
| 462 | } |
| 463 | } |
| 464 | w.WriteLine(" };\r\n"); |
| 465 | |
| 466 | w.WriteLine("\tpublic static readonly int[] i = new int[] {"); |
| 467 | w.Write(index.ToString()); |
| 468 | w.WriteLine(" };"); |
| 469 | w.WriteLine("}"); |
| 470 | w.Close(); |
| 471 | } |
| 472 | |
| 473 | //Console.WriteLine(" Ok."); |
| 474 | Console.WriteLine("Generating DecompositionKeys.cs file..."); |
| 475 | |
| 476 | // Dump compatibility decomposition |
| 477 | { |
| 478 | StreamWriter w = new StreamWriter("DecompositionKeys.cs", false, Encoding.Default); |
| 479 | w.WriteLine("// Do not edit !!!"); |
| 480 | w.WriteLine("// this file is generated automatically"); |
| 481 | w.WriteLine(); |
| 482 | w.WriteLine("public class DecompositionKeys"); |
| 483 | w.WriteLine("{"); |
| 484 | |
| 485 | w.WriteLine("\tpublic static readonly int[] k = new int[] {"); |
| 486 | IEnumerator i = new HashSet(compatibilityKeys.Keys).GetEnumerator(); |
| 487 | while (i.MoveNext()) |
| 488 | { |
| 489 | string k = (string)i.Current; |
| 490 | int index = ((int)compatibilityKeys[k]); |
| 491 | w.WriteLine(" '\\u" + k + "', " + index + ","); |
| 492 | } |
| 493 | w.WriteLine(" };"); |
| 494 | w.WriteLine("}"); |
| 495 | w.Close(); |
| 496 | } |
| 497 | |
| 498 | //Console.WriteLine(" Ok."); |
| 499 | Console.WriteLine("Generating DecompositionMappings.cs file..."); |
| 500 | |
| 501 | { |
| 502 | StreamWriter w = new StreamWriter("DecompositionMappings.cs", false, Encoding.Default); |
| 503 | w.WriteLine("// Do not edit !!!"); |
| 504 | w.WriteLine("// this file is generated automatically"); |
| 505 | w.WriteLine(); |
| 506 | w.WriteLine("public class DecompositionMappings"); |
| 507 | w.WriteLine("{"); |
| 508 | w.WriteLine("\tpublic static readonly string[] m = new string[] {"); |
| 509 | IEnumerator i = compatibilityMappings.GetEnumerator(); |
| 510 | while (i.MoveNext()) |
| 511 | { |
| 512 | string m = (string)i.Current; |
| 513 | w.WriteLine(" \"" + toString(m) + "\","); |
| 514 | } |
| 515 | w.WriteLine(" };"); |
| 516 | w.WriteLine("}"); |
| 517 | w.Close(); |
| 518 | } |
| 519 | |
| 520 | //Console.WriteLine(" Ok."); |
| 521 | Console.WriteLine("Generating Composition.cs file..."); |
| 522 | |
| 523 | // Dump canonical composition |
| 524 | { |
| 525 | StreamWriter w = new StreamWriter("Composition.cs", false, Encoding.Default); |
| 526 | w.WriteLine("// Do not edit !!!"); |
| 527 | w.WriteLine("// this file is generated automatically"); |
| 528 | w.WriteLine(); |
| 529 | w.WriteLine("public class Composition"); |
| 530 | w.WriteLine("{"); |
| 531 | |
| 532 | IEnumerator i; |
| 533 | int index = 0; |
| 534 | |
| 535 | SortedList indices = new SortedList(); |
| 536 | |
| 537 | i = new HashSet(complexComposition.Keys).GetEnumerator(); |
| 538 | while (i.MoveNext()) |
| 539 | { |
| 540 | string s0 = (string)i.Current; |
| 541 | indices[(int)System.Convert.ToInt32(s0, 16)] = (int)index; |
| 542 | index++; |
| 543 | } |
| 544 | |
| 545 | int multiSecondStart = index; |
| 546 | w.WriteLine("\t/* jagged Array */"); |
| 547 | w.WriteLine("\tpublic static readonly char[][] multiFirst = new char[][] {"); |
| 548 | //w.WriteLine(" public final static char[][] multiFirst = new char[][] {"); |
| 549 | i = new HashSet(complexComposition.Keys).GetEnumerator(); |
| 550 | while (i.MoveNext()) |
| 551 | { |
| 552 | string s0 = (string)i.Current; |
| 553 | SortedList m = (SortedList)complexComposition[s0]; |
| 554 | |
| 555 | SortedList line = new SortedList(); |
| 556 | int maxIndex = 1; |
| 557 | |
| 558 | System.Collections.IEnumerator i2 = new HashSet(m.Keys).GetEnumerator(); |
| 559 | while (i2.MoveNext()) |
| 560 | { |
| 561 | string s1 = (string)i2.Current; |
| 562 | string k = (string)m[s1]; |
| 563 | |
| 564 | int s1i = (int)System.Convert.ToInt32(s1, 16); |
| 565 | |
| 566 | if (!indices.ContainsKey(s1i)) |
| 567 | { |
| 568 | indices[s1i] = (int)index; |
| 569 | index++; |
| 570 | } |
| 571 | line[indices[s1i]] = k; |
| 572 | maxIndex = System.Math.Max(maxIndex, ((int)indices[s1i])); |
| 573 | } |
| 574 | |
| 575 | w.Write("\tnew char[] { "); |
| 576 | for (int j = multiSecondStart; j <= maxIndex; j++) |
| 577 | { |
| 578 | if (line.ContainsKey((int)j)) |
| 579 | { |
| 580 | string s = (string)line[(int)j]; |
| 581 | w.Write("'" + toString(s) + "', "); |
| 582 | } |
| 583 | else |
| 584 | { |
| 585 | //w.Write(" 0, "); |
| 586 | w.Write("'" + toString("0000") + "', "); |
| 587 | } |
| 588 | } |
| 589 | w.WriteLine("},"); |
| 590 | } |
| 591 | w.WriteLine(" };"); |
| 592 | |
| 593 | int singleFirstStart = index; |
| 594 | |
| 595 | w.WriteLine("\tpublic static readonly char[,] singleFirst = new char[,] {"); |
| 596 | i = new HashSet(singleFirstComposition.Keys).GetEnumerator(); |
| 597 | while (i.MoveNext()) |
| 598 | { |
| 599 | string k = (string)i.Current; |
| 600 | string[] v = ((string[])singleFirstComposition[k]); |
| 601 | w.WriteLine(" { '" + toString(v[0]) + "', '" + toString(v[1]) + "' },"); |
| 602 | |
| 603 | if (indices.ContainsKey((int)System.Convert.ToInt32(k, 16))) |
| 604 | { |
| 605 | Console.WriteLine(k + " already indexed!"); |
| 606 | } |
| 607 | |
| 608 | indices[(int)System.Convert.ToInt32(k, 16)] = (int)index; |
| 609 | index++; |
| 610 | } |
| 611 | w.WriteLine(" };"); |
| 612 | |
| 613 | int singleSecondStart = index; |
| 614 | |
| 615 | w.WriteLine("\tpublic static readonly char[,] singleSecond = new char[,] {"); |
| 616 | i = new HashSet(singleSecondComposition.Keys).GetEnumerator(); |
| 617 | while (i.MoveNext()) |
| 618 | { |
| 619 | string k = (string)i.Current; |
| 620 | string[] v = ((string[])singleSecondComposition[k]); |
| 621 | w.WriteLine(" { '" + toString(v[0]) + "', '" + toString(v[1]) + "' },"); |
| 622 | |
| 623 | indices[(int)System.Convert.ToInt32(k, 16)] = (int)index; |
| 624 | index++; |
| 625 | } |
| 626 | w.WriteLine(" };"); |
| 627 | |
| 628 | w.WriteLine("\tpublic static readonly int multiSecondStart = " + multiSecondStart + ";"); |
| 629 | w.WriteLine("\tpublic static readonly int singleFirstStart = " + singleFirstStart + ";"); |
| 630 | w.WriteLine("\tpublic static readonly int singleSecondStart = " + singleSecondStart + ";"); |
| 631 | |
| 632 | System.Text.StringBuilder compositionPages = new System.Text.StringBuilder(); |
| 633 | |
| 634 | w.WriteLine("\tpublic static readonly int[] composePage = new int[] {"); |
| 635 | int pageCount = 0; |
| 636 | for (int j = 0; j * 256 < composeLookupMax + 255; j++) |
| 637 | { |
| 638 | bool empty = true; |
| 639 | StringBuilder page = new StringBuilder(); |
| 640 | for (int k = 0; k < 256; k++) |
| 641 | { |
| 642 | if (k % 16 == 0) |
| 643 | { |
| 644 | page.Append("\r\n "); |
| 645 | } |
| 646 | if (indices.ContainsKey((int)(j * 256 + k))) |
| 647 | { |
| 648 | page.Append(indices[(int)(j * 256 + k)]); |
| 649 | page.Append(", "); |
| 650 | empty = false; |
| 651 | } |
| 652 | else |
| 653 | { |
| 654 | page.Append("-1, "); |
| 655 | } |
| 656 | } |
| 657 | |
| 658 | if (empty) |
| 659 | { |
| 660 | w.WriteLine(" -1,"); |
| 661 | } |
| 662 | else |
| 663 | { |
| 664 | w.WriteLine(" " + pageCount + ","); |
| 665 | compositionPages.Append("\t{"); |
| 666 | compositionPages.Append(page); |
| 667 | compositionPages.Append("\r\n },\r\n"); |
| 668 | pageCount++; |
| 669 | } |
| 670 | } |
| 671 | w.WriteLine(" };"); |
| 672 | //w.WriteLine("\t/* jagged Array */"); |
| 673 | w.WriteLine("\tpublic static readonly int[,] composeData = new int[,] {"); |
| 674 | w.Write(compositionPages); |
| 675 | w.WriteLine(" };"); |
| 676 | w.WriteLine("}"); |
| 677 | w.Close(); |
| 678 | } |
| 679 | |
| 680 | //Console.WriteLine(" Ok."); |
| 681 | Console.WriteLine("Finished!"); |
| 682 | } |
| 683 | } |
| 684 | } |
Note: See TracBrowser
for help on using the browser.








