Merge pull request #3274 from Unity-Technologies/fix-path-getfullpath-windows
[mono.git] / mcs / class / corlib / Mono.Globalization.Unicode / ucd.cs
1 //
2 // UCD.cs
3 //
4 // Author:
5 //      Atsushi Enomoto  <atsushi@ximian.com>
6 //
7 // Copyright (C) 2008 Novell, Inc.
8 //
9
10 //
11 // Unicode table generator for eglib.
12 // Note that this code is only for Unicode 5.1.0 or earlier.
13 // (regarding character ranges)
14 //
15 // Some premises:
16 // - lower-band (0000-FFFF) characters never has case mapping to higher-band
17 //   characters. Hence, simple upper/lower mapping is divided into 16-bit and
18 //   32-bit tables.
19 //
20
21 using System;
22 using System.Collections.Generic;
23 using System.Globalization;
24 using System.IO;
25 using System.Reflection;
26
27 namespace Mono.Globalization.Unicode
28 {
29         public class Driver
30         {
31                 public static void Main (string [] args)
32                 {
33                         TextWriter w = Console.Out;
34                         w.NewLine = "\n";
35
36                         w.WriteLine (@"/*
37 DO NOT MODIFY THIS FILE DIRECTLY.
38
39 This file is automatically generated by {0}.exe.
40 The source for this generator should be in Mono repository
41 (mcs/class/corlib/Mono.Globalization.Unicode directory).
42 */
43
44 #ifndef __UNICODE_DATA_H
45 #define __UNICODE_DATA_H
46
47 #include <glib.h>
48
49 ", Assembly.GetEntryAssembly ().GetName ().Name);
50                         var ud = new UnicodeData5_1_0 ();
51                         var ucd = ud.ParseFile (args [0]);
52                         var ucg = new UnicodeDataCodeGeneratorC5_1_0 (ud, w);
53                         ucg.GenerateStructures ();
54                         w.WriteLine ();
55                         ucg.GenerateUnicodeCategoryListC (ucd);
56                         w.WriteLine ();
57                         ucg.GenerateSimpleCaseMappingListC (ucd);
58                         w.WriteLine ();
59                         ucg.GenerateSimpleTitlecaseMappingListC (ucd);
60                         w.WriteLine (@"
61 #endif
62 ");
63                 }
64         }
65
66         public class UnicodeData5_1_0 : UnicodeData
67         {
68                 public override CodePointRange [] SimpleCases {
69                         get { return simple_cases; }
70                 }
71
72                 public override CodePointRange [] CategoryRanges {
73                         get { return category_ranges; }
74                 }
75
76                 static readonly CodePointRange [] simple_cases = {
77                         new CodePointRange (0x0040, 0x0600),
78                         new CodePointRange (0x1000, 0x10D0),
79                         new CodePointRange (0x1D00, 0x2000),
80                         new CodePointRange (0x2100, 0x21C0),
81                         new CodePointRange (0x2480, 0x2500),
82                         new CodePointRange (0x2C00, 0x2D80),
83                         new CodePointRange (0xA640, 0xA7C0),
84                         new CodePointRange (0xFF20, 0xFF80),
85                         new CodePointRange (0x10400, 0x10480),
86                         };
87
88                 static readonly CodePointRange [] category_ranges = {
89                         new CodePointRange (0x0000, 0x3400),
90                         // 3400-4DB5: OtherLetter
91                         new CodePointRange (0x4DC0, 0x4E00),
92                         // 4E00-9FC3: OtherLetter
93                         new CodePointRange (0xA000, 0xAA80),
94                         // AC00-D7A3: OtherLetter
95                         // D800-DFFF: OtherSurrogate
96                         // E000-F8FF: OtherPrivateUse
97                         new CodePointRange (0xF900, 0x10000),
98                         new CodePointRange (0x10000, 0x104C0),
99                         new CodePointRange (0x10800, 0x10A80),
100                         new CodePointRange (0x12000, 0x12480),
101                         new CodePointRange (0x1D000, 0x1D800),
102                         new CodePointRange (0x1F000, 0x1F0C0),
103                         // 20000-2A6D6 OtherLetter
104                         new CodePointRange (0x2F800, 0x2FA40),
105                         new CodePointRange (0xE0000, 0xE0200),
106                         // F0000-FFFFD OtherPrivateUse
107                         // 100000-10FFFD OtherPrivateUse
108                         };
109         }
110
111         public abstract class UnicodeData
112         {
113                 public abstract CodePointRange [] SimpleCases { get; }
114
115                 public abstract CodePointRange [] CategoryRanges { get; }
116
117                 public virtual UcdCharacterProperty [] ParseFile (string file)
118                 {
119                         var d = new List<KeyValuePair<int,UcdCharacterProperty>> ();
120
121                         using (TextReader r = File.OpenText (file)) {
122                                 while (r.Peek () >= 0) {
123                                         var l = r.ReadLine ();
124                                         if (l.Length > 0 && l [0] != '#') {
125                                                 var u = Parse (l);
126                                                 d.Add (new KeyValuePair<int,UcdCharacterProperty> (u.Codepoint, u));
127                                         }
128                                 }
129                         }
130                         var list = new List<UcdCharacterProperty> ();
131                         foreach (var p in d)
132                                 list.Add (p.Value);
133                         return list.ToArray ();
134                 }
135
136                 UcdCharacterProperty Parse (string line)
137                 {
138                         string [] tokens = line.Split (';');
139                         string [] decomp = tokens [5].Length > 0 ? tokens [5].Split (' ') : null;
140                         string decomp_type = decomp != null && decomp [0] [0] == '<' ? decomp [0] : null;
141                         if (decomp_type != null) {
142                                 for (int i = 1; i < decomp.Length; i++)
143                                         decomp [i - 1] = decomp [i];
144                                 Array.Resize (ref decomp, decomp.Length - 1);
145                         }
146
147                         return new UcdCharacterProperty () {
148                                 Codepoint = int.Parse (tokens [0], NumberStyles.HexNumber),
149                                 Name = tokens [1],
150                                 Category = ParseUnicodeCategory (tokens [2]),
151                                 CanonicalCombiningClass = tokens [3].Length > 0 ? (byte?) byte.Parse (tokens [3]) : null,
152                                 BidiClass = tokens [4].Length > 0 ? (UcdBidiClass) Enum.Parse (typeof (UcdBidiClass), tokens [4]) : UcdBidiClass.None,
153                                 DecompositionType = decomp_type != null ? ParseDecompositionType (decomp_type) : UcdDecompositionType.None,
154                                 DecompositionMapping = decomp != null ? Array.ConvertAll<string,int> (decomp, dv => int.Parse (dv, NumberStyles.HexNumber)) : null,
155                                 DecimalDigitValue = tokens [6],
156                                 DigitValue = tokens [7],
157                                 NumericValue = tokens [8],
158                                 BidiMirrored = (tokens [9] == "Y"),
159                                 Unicode1Name = tokens [10],
160                                 IsoComment = tokens [11],
161                                 SimpleUppercaseMapping = tokens [12].Length > 0 ? int.Parse (tokens [12], NumberStyles.HexNumber) : 0,
162                                 SimpleLowercaseMapping = tokens [13].Length > 0 ? int.Parse (tokens [13], NumberStyles.HexNumber) : 0,
163                                 SimpleTitlecaseMapping = tokens [14].Length > 0 ? int.Parse (tokens [14], NumberStyles.HexNumber) : 0,
164                                 };
165                 }
166
167                 UcdDecompositionType ParseDecompositionType (string s)
168                 {
169                         switch (s) {
170                         case "<font>":
171                                 return UcdDecompositionType.Font;
172                         case "<noBreak>":
173                                 return UcdDecompositionType.NoBreak;
174                         case "<initial>":
175                                 return UcdDecompositionType.Initial;
176                         case "<medial>":
177                                 return UcdDecompositionType.Medial;
178                         case "<final>":
179                                 return UcdDecompositionType.Final;
180                         case "<isolated>":
181                                 return UcdDecompositionType.Isolated;
182                         case "<circle>":
183                                 return UcdDecompositionType.Circle;
184                         case "<super>":
185                                 return UcdDecompositionType.Super;
186                         case "<sub>":
187                                 return UcdDecompositionType.Sub;
188                         case "<vertical>":
189                                 return UcdDecompositionType.Vertical;
190                         case "<wide>":
191                                 return UcdDecompositionType.Wide;
192                         case "<narrow>":
193                                 return UcdDecompositionType.Narrow;
194                         case "<small>":
195                                 return UcdDecompositionType.Small;
196                         case "<square>":
197                                 return UcdDecompositionType.Square;
198                         case "<fraction>":
199                                 return UcdDecompositionType.Fraction;
200                         case "<compat>":
201                                 return UcdDecompositionType.Compat;
202                         }
203                         throw new ArgumentException (String.Format ("Unexpected decomposition type '{0}'", s));
204                 }
205
206                 UnicodeCategory ParseUnicodeCategory (string s)
207                 {
208                         switch (s) {
209                         case "Lu":
210                                 return UnicodeCategory.UppercaseLetter;
211                         case "Ll":
212                                 return UnicodeCategory.LowercaseLetter;
213                         case "Lt":
214                                 return UnicodeCategory.TitlecaseLetter;
215                         case "Lm":
216                                 return UnicodeCategory.ModifierLetter;
217                         case "Lo":
218                                 return UnicodeCategory.OtherLetter;
219                         case "Mn":
220                                 return UnicodeCategory.NonSpacingMark;
221                         case "Mc":
222                                 return UnicodeCategory.SpacingCombiningMark;
223                         case "Me":
224                                 return UnicodeCategory.EnclosingMark;
225                         case "Nd":
226                                 return UnicodeCategory.DecimalDigitNumber;
227                         case "Nl":
228                                 return UnicodeCategory.LetterNumber;
229                         case "No":
230                                 return UnicodeCategory.OtherNumber;
231                         case "Pc":
232                                 return UnicodeCategory.ConnectorPunctuation;
233                         case "Pd":
234                                 return UnicodeCategory.DashPunctuation;
235                         case "Ps":
236                                 return UnicodeCategory.OpenPunctuation;
237                         case "Pe":
238                                 return UnicodeCategory.ClosePunctuation;
239                         case "Pi":
240                                 return UnicodeCategory.InitialQuotePunctuation;
241                         case "Pf":
242                                 return UnicodeCategory.FinalQuotePunctuation;
243                         case "Po":
244                                 return UnicodeCategory.OtherPunctuation;
245                         case "Sm":
246                                 return UnicodeCategory.MathSymbol;
247                         case "Sc":
248                                 return UnicodeCategory.CurrencySymbol;
249                         case "Sk":
250                                 return UnicodeCategory.ModifierSymbol;
251                         case "So":
252                                 return UnicodeCategory.OtherSymbol;
253                         case "Zs":
254                                 return UnicodeCategory.SpaceSeparator;
255                         case "Zl":
256                                 return UnicodeCategory.LineSeparator;
257                         case "Zp":
258                                 return UnicodeCategory.ParagraphSeparator;
259                         case "Cc":
260                                 return UnicodeCategory.Control;
261                         case "Cf":
262                                 return UnicodeCategory.Format;
263                         case "Cs":
264                                 return UnicodeCategory.Surrogate;
265                         case "Co":
266                                 return UnicodeCategory.PrivateUse;
267                         case "Cn":
268                                 return UnicodeCategory.OtherNotAssigned;
269                         }
270                         throw new ArgumentException (String.Format ("Unexpected category {0}", s));
271                 }
272         }
273
274         public class UnicodeDataCodeGeneratorC5_1_0
275         {
276                 UnicodeData catalog;
277                 TextWriter w;
278
279                 public UnicodeDataCodeGeneratorC5_1_0 (UnicodeData catalog, TextWriter writer)
280                 {
281                         this.catalog = catalog;
282                         w = writer;
283                 }
284
285                 public void GenerateStructures ()
286                 {
287                         w.WriteLine ("/* ======== Structures ======== */");
288                         w.WriteLine (@"typedef struct {
289         guint32 codepoint;
290         guint32 upper;
291         guint32 title;
292 } SimpleTitlecaseMapping;");
293                         w.WriteLine (@"typedef struct {
294         guint32 start;
295         guint32 end;
296 } CodePointRange;");
297                         w.WriteLine (@"typedef struct {
298         guint32 upper;
299         guint32 lower;
300 } SimpleCaseMapping;");
301                 }
302
303                 void GenerateCodePointRanges (string name, CodePointRange [] ranges)
304                 {
305                         w.WriteLine ("static const guint8 {0}_count = {1};", name, ranges.Length);
306                         w.WriteLine ("static const CodePointRange {0} [] = {{", name);
307                         foreach (var cpr in ranges)
308                                 w.WriteLine ("{{0x{0:X06}, 0x{1:X06}}},", cpr.Start, cpr.End);
309                         w.WriteLine ("{0, 0}};");
310                 }
311
312                 public void GenerateUnicodeCategoryListC (UcdCharacterProperty [] ucd)
313                 {
314                         w.WriteLine ("/* ======== Unicode Categories ======== */");
315                         GenerateCodePointRanges ("unicode_category_ranges", catalog.CategoryRanges);
316
317                         int table = 0;
318                         foreach (var cpr in catalog.CategoryRanges) {
319                                 w.WriteLine ("const GUnicodeType unicode_category_table{0} [] = {{", table);
320                                 w.WriteLine ("\t/* ==== {0:X}-{1:X} ==== */", cpr.Start, cpr.End);
321                                 w.Write ("\t");
322                                 int cp = cpr.Start;
323                                 foreach (var ucp in ucd) {
324                                         if (ucp.Codepoint >= cpr.End)
325                                                 break;
326                                         if (ucp.Codepoint < cp)
327                                                 continue;
328                                         while (cp < ucp.Codepoint) {
329                                                 w.Write ("0,");
330                                                 if (++cp % 16 == 0)
331 //                                                      w.Write ("\n/* ==== {0:X} ==== */\n\t", cp);
332                                                         w.Write ("\n\t", cp);
333                                         }
334                                         w.Write ((int) ToGUnicodeCategory (ucp.Category));
335                                         w.Write (',');
336                                         if (++cp % 16 == 0)
337 //                                              w.Write ("\n/* ==== {0:X} ==== */\n\t", cp);
338                                                 w.Write ("\n\t", cp);
339                                         if (cp >= cpr.End)
340                                                 break;
341                                 }
342                                 w.WriteLine ("0};");
343                                 table++;
344                         }
345
346                         w.WriteLine ("static const GUnicodeType *unicode_category [{0}]  = {{", catalog.CategoryRanges.Length);
347                         for (int i = 0, end = catalog.CategoryRanges.Length; i < end; i++)
348                                 w.WriteLine ("\tunicode_category_table{0}{1}", i, i + 1 < end ? "," : String.Empty);
349                         w.WriteLine ("};");
350                 }
351
352                 public void GenerateSimpleTitlecaseMappingListC (UcdCharacterProperty [] ucd)
353                 {
354                         w.WriteLine ("static const SimpleTitlecaseMapping simple_titlecase_mapping [] = {");
355                         int count = 0;
356                         foreach (var ucp in ucd) {
357                                 if (ucp.SimpleUppercaseMapping == ucp.SimpleTitlecaseMapping)
358                                         continue;
359                                 if (count > 0)
360                                         w.WriteLine (',');
361                                 w.Write ("\t{{0x{0:X06}, 0x{1:X06}, 0x{2:X06}}}", ucp.Codepoint, ucp.SimpleUppercaseMapping, ucp.SimpleTitlecaseMapping);
362                                 count++;
363                         }
364                         w.WriteLine ();
365                         w.WriteLine ("};");
366                         w.WriteLine ("static const guint8 simple_titlecase_mapping_count = {0};", count);
367                 }
368
369                 public void GenerateSimpleCaseMappingListC (UcdCharacterProperty [] ucd)
370                 {
371                         GenerateCodePointRanges ("simple_case_map_ranges", catalog.SimpleCases);
372                         GenerateSimpleCaseMappingListC (ucd, true, true);
373                         GenerateSimpleCaseMappingListC (ucd, true, false);
374                         GenerateSimpleCaseMappingListC (ucd, false, true);
375                         GenerateSimpleCaseMappingListC (ucd, false, false);
376                 }
377
378                 void GenerateSimpleCaseMappingListC (UcdCharacterProperty [] ucd, bool upper, bool small)
379                 {
380                         int nTable = 0;
381                         foreach (var cpr in catalog.SimpleCases) {
382                                 if (small && cpr.Start > 0xFFFF)
383                                         break;
384                                 if (!small && cpr.Start < 0x10000)
385                                         continue;
386
387                                 w.WriteLine ("static const {0} simple_{1}_case_mapping_{2}_table{3} [] = {{", small ? "guint16" : "guint32", upper ? "upper" : "lower", small ? "lowarea" : "higharea", nTable);
388
389
390                                 w.WriteLine ("\t/* ==== {0:X}-{1:X} ==== */", cpr.Start, cpr.End);
391                                 w.Write ("\t");
392                                 int cp = cpr.Start;
393                                 foreach (var ucp in ucd) {
394                                         if (ucp.Codepoint >= cpr.End)
395                                                 break;
396                                         if (ucp.Codepoint < cp)
397                                                 continue;
398                                         while (cp < ucp.Codepoint) {
399                                                 w.Write ("0,");
400                                                 if (++cp % 16 == 0)
401                                                         w.WriteLine ();
402                                         }
403                                         int v = upper ? ucp.SimpleUppercaseMapping : ucp.SimpleLowercaseMapping;
404                                         if (v != 0)
405                                                 w.Write ("0x{0:X},", v);
406                                         else
407                                                 w.Write ("0,");
408
409                                         if (++cp % 16 == 0) {
410                                                 w.WriteLine ();
411                                                 w.Write ("\t");
412                                         }
413                                         if (cp >= cpr.End)
414                                                 break;
415                                 }
416                                 w.WriteLine ("0};");
417
418                                 nTable++;
419                         }
420
421                         w.WriteLine ("static const {0} *simple_{1}_case_mapping_{2} [] = {{", small ? "guint16" : "guint32", upper ? "upper" : "lower", small ? "lowarea" : "higharea");
422
423                         for (int i = 0; i < nTable; i++) {
424                                 if (i > 0)
425                                         w.WriteLine (",");
426                                 w.Write ("\tstatic const guint8 simple_{0}_case_mapping_{1}_table{2}", upper ? "upper" : "lower", small ? "lowarea" : "higharea", i);
427                         }
428
429                         w.WriteLine ("};");
430                         w.WriteLine ();
431                 }
432
433                 enum GUnicodeType
434                 {
435                         G_UNICODE_CONTROL,
436                         G_UNICODE_FORMAT,
437                         G_UNICODE_UNASSIGNED,
438                         G_UNICODE_PRIVATE_USE,
439                         G_UNICODE_SURROGATE,
440                         G_UNICODE_LOWERCASE_LETTER,
441                         G_UNICODE_MODIFIER_LETTER,
442                         G_UNICODE_OTHER_LETTER,
443                         G_UNICODE_TITLECASE_LETTER,
444                         G_UNICODE_UPPERCASE_LETTER,
445                         G_UNICODE_COMBINING_MARK,
446                         G_UNICODE_ENCLOSING_MARK,
447                         G_UNICODE_NON_SPACING_MARK,
448                         G_UNICODE_DECIMAL_NUMBER,
449                         G_UNICODE_LETTER_NUMBER,
450                         G_UNICODE_OTHER_NUMBER,
451                         G_UNICODE_CONNECT_PUNCTUATION,
452                         G_UNICODE_DASH_PUNCTUATION,
453                         G_UNICODE_CLOSE_PUNCTUATION,
454                         G_UNICODE_FINAL_PUNCTUATION,
455                         G_UNICODE_INITIAL_PUNCTUATION,
456                         G_UNICODE_OTHER_PUNCTUATION,
457                         G_UNICODE_OPEN_PUNCTUATION,
458                         G_UNICODE_CURRENCY_SYMBOL,
459                         G_UNICODE_MODIFIER_SYMBOL,
460                         G_UNICODE_MATH_SYMBOL,
461                         G_UNICODE_OTHER_SYMBOL,
462                         G_UNICODE_LINE_SEPARATOR,
463                         G_UNICODE_PARAGRAPH_SEPARATOR,
464                         G_UNICODE_SPACE_SEPARATOR
465                 }
466
467                 GUnicodeType ToGUnicodeCategory (UnicodeCategory v)
468                 {
469                         switch (v) {
470                         case UnicodeCategory.UppercaseLetter:
471                                 return GUnicodeType.G_UNICODE_UPPERCASE_LETTER;
472                         case UnicodeCategory.LowercaseLetter:
473                                 return GUnicodeType.G_UNICODE_LOWERCASE_LETTER;
474                         case UnicodeCategory.TitlecaseLetter:
475                                 return GUnicodeType.G_UNICODE_TITLECASE_LETTER;
476                         case UnicodeCategory.ModifierLetter:
477                                 return GUnicodeType.G_UNICODE_MODIFIER_LETTER;
478                         case UnicodeCategory.OtherLetter:
479                                 return GUnicodeType.G_UNICODE_OTHER_LETTER;
480                         case UnicodeCategory.NonSpacingMark:
481                                 return GUnicodeType.G_UNICODE_NON_SPACING_MARK;
482                         case UnicodeCategory.SpacingCombiningMark:
483                                 return GUnicodeType.G_UNICODE_COMBINING_MARK;
484                         case UnicodeCategory.EnclosingMark:
485                                 return GUnicodeType.G_UNICODE_ENCLOSING_MARK;
486                         case UnicodeCategory.DecimalDigitNumber:
487                                 return GUnicodeType.G_UNICODE_DECIMAL_NUMBER;
488                         case UnicodeCategory.LetterNumber:
489                                 return GUnicodeType.G_UNICODE_LETTER_NUMBER;
490                         case UnicodeCategory.OtherNumber:
491                                 return GUnicodeType.G_UNICODE_OTHER_NUMBER;
492                         case UnicodeCategory.ConnectorPunctuation:
493                                 return GUnicodeType.G_UNICODE_CONNECT_PUNCTUATION;
494                         case UnicodeCategory.DashPunctuation:
495                                 return GUnicodeType.G_UNICODE_DASH_PUNCTUATION;
496                         case UnicodeCategory.OpenPunctuation:
497                                 return GUnicodeType.G_UNICODE_OPEN_PUNCTUATION;
498                         case UnicodeCategory.ClosePunctuation:
499                                 return GUnicodeType.G_UNICODE_CLOSE_PUNCTUATION;
500                         case UnicodeCategory.InitialQuotePunctuation:
501                                 return GUnicodeType.G_UNICODE_INITIAL_PUNCTUATION;
502                         case UnicodeCategory.FinalQuotePunctuation:
503                                 return GUnicodeType.G_UNICODE_FINAL_PUNCTUATION;
504                         case UnicodeCategory.OtherPunctuation:
505                                 return GUnicodeType.G_UNICODE_OTHER_PUNCTUATION;
506                         case UnicodeCategory.MathSymbol:
507                                 return GUnicodeType.G_UNICODE_MATH_SYMBOL;
508                         case UnicodeCategory.CurrencySymbol:
509                                 return GUnicodeType.G_UNICODE_CURRENCY_SYMBOL;
510                         case UnicodeCategory.ModifierSymbol:
511                                 return GUnicodeType.G_UNICODE_MODIFIER_SYMBOL;
512                         case UnicodeCategory.OtherSymbol:
513                                 return GUnicodeType.G_UNICODE_OTHER_SYMBOL;
514                         case UnicodeCategory.SpaceSeparator:
515                                 return GUnicodeType.G_UNICODE_SPACE_SEPARATOR;
516                         case UnicodeCategory.LineSeparator:
517                                 return GUnicodeType.G_UNICODE_LINE_SEPARATOR;
518                         case UnicodeCategory.ParagraphSeparator:
519                                 return GUnicodeType.G_UNICODE_PARAGRAPH_SEPARATOR;
520                         case UnicodeCategory.Control:
521                                 return GUnicodeType.G_UNICODE_CONTROL;
522                         case UnicodeCategory.Format:
523                                 return GUnicodeType.G_UNICODE_FORMAT;
524                         case UnicodeCategory.Surrogate:
525                                 return GUnicodeType.G_UNICODE_SURROGATE;
526                         case UnicodeCategory.PrivateUse:
527                                 return GUnicodeType.G_UNICODE_PRIVATE_USE;
528                         case UnicodeCategory.OtherNotAssigned:
529                                 return GUnicodeType.G_UNICODE_UNASSIGNED;
530                         }
531                         throw new ArgumentException (String.Format ("Unexpected category {0}", v));
532                 }
533         }
534
535         public class CodePointRange
536         {
537                 public CodePointRange (int start, int end)
538                 {
539                         Start = start;
540                         End = end;
541                 }
542
543                 public int Start { get; set; }
544                 public int End { get; set; }
545         }
546
547         public class UcdCharacterProperty
548         {
549                 public int Codepoint { get; set; }
550                 public string Name { get; set; }
551                 public UnicodeCategory Category { get; set; }
552                 public byte? CanonicalCombiningClass { get; set; }
553                 public UcdBidiClass BidiClass { get; set; }
554                 public UcdDecompositionType DecompositionType { get; set; }
555                 public int [] DecompositionMapping { get; set; }
556                 public string DecimalDigitValue { get; set; }
557                 public string DigitValue { get; set; }
558                 public string NumericValue { get; set; }
559                 public bool BidiMirrored { get; set; }
560                 public string Unicode1Name { get; set; }
561                 public string IsoComment { get; set; }
562                 public int SimpleUppercaseMapping { get; set; }
563                 public int SimpleLowercaseMapping { get; set; }
564                 public int SimpleTitlecaseMapping { get; set; }
565         }
566
567         public enum UcdBidiClass
568         {
569                 None,
570                 L,
571                 LRE,
572                 LRO,
573                 R,
574                 AL,
575                 RLE,
576                 RLO,
577                 PDF,
578                 EN,
579                 ES,
580                 ET,
581                 AN,
582                 CS,
583                 NSM,
584                 BN,
585                 B,
586                 S,
587                 WS,
588                 ON
589         }
590
591         public enum UcdDecompositionType
592         {
593                 None,
594                 Font,
595                 NoBreak,
596                 Initial,
597                 Medial,
598                 Final,
599                 Isolated,
600                 Circle,
601                 Super,
602                 Sub,
603                 Vertical,
604                 Wide,
605                 Narrow,
606                 Small,
607                 Square,
608                 Fraction,
609                 Compat
610         }
611 }