1
2
3
4
5
6 using System;
7 using System.Collections;
8 using System.IO;
9
10 namespace System.Unicode
11 {
12 public class UnicodeException : Exception
13 {
14 public nothrow UnicodeException(const string& message_) : base(message_)
15 {
16 }
17 }
18
19 public void ThrowUnicodeException(const string& message)
20 {
21 throw UnicodeException(message);
22 }
23
24 public string PathToUnicodeDirectory()
25 {
26 return "/mnt/cmajor/unicode";
27 }
28
29 public string PathToUcdBinFile()
30 {
31 return Path.Combine(PathToUnicodeDirectory(), "cmajor_ucd.bin");
32 }
33
34 public string MakeCanonicalPropertyName(const string& s)
35 {
36 string result;
37 for (char c : s)
38 {
39 if (c != '_' && c != ' ' && c != '-')
40 {
41 result.Append(c);
42 }
43 }
44 return ToLower(result);
45 }
46
47 public enum BinaryPropertyId : byte
48 {
49 asciiHexDigit,
50 alphabetic,
51 bidiControl,
52 bidiMirrored,
53 cased,
54 compositionExclusion,
55 caseIgnorable,
56 fullCompositionExclusion,
57 changesWhenCasefolded,
58 changesWhenCaseMapped,
59 changesWhenNFKCCasefolded,
60 changesWhenLowercased,
61 changesWhenTitlecased,
62 changesWhenUppercased,
63 dash,
64 deprecated,
65 defaultIgnorableCodePoint,
66 diacritic,
67 extender,
68 graphemeBase,
69 graphemeExtend,
70 graphemeLink,
71 hexDigit,
72 hyphen,
73 idContinue,
74 ideographic,
75 idStart,
76 idsBinaryOperator,
77 idsTrinaryOperator,
78 joinControl,
79 logicalOrderException,
80 lowercase,
81 math,
82 noncharacterCodePoint,
83 otherAlphabetic,
84 otherDefaultIgnorableCodePoint,
85 otherGraphemeExtend,
86 otherIdContinue,
87 otherIdStart,
88 otherLowercase,
89 otherMath,
90 otherUppercase,
91 patternSyntax,
92 patternWhiteSpace,
93 prependedConcatenationMark,
94 quotationMark,
95 radical,
96 softDotted,
97 sentenceterminal,
98 terminalPunctuation,
99 unifiedIdeograph,
100 uppercase,
101 variationSelector,
102 whiteSpace,
103 xidContinue,
104 xidStart,
105 expandsOnNFC,
106 expandsOnNFD,
107 expandsOnNFKC,
108 expandsOnNFKD
109 }
110
111 public class BinaryProperty
112 {
113 public nothrow BinaryProperty(BinaryPropertyId id_, const string& shortName_, const string& longName_) : id(id_), shortName(shortName_), longName(longName_)
114 {
115 }
116 public inline nothrow BinaryPropertyId Id()
117 {
118 return id;
119 }
120 public inline nothrow const string& ShortName()
121 {
122 return shortName;
123 }
124 public inline nothrow const string& LongName()
125 {
126 return longName;
127 }
128 private BinaryPropertyId id;
129 private string shortName;
130 private string longName;
131 }
132
133 public class BinaryPropertyTable
134 {
135 static BinaryPropertyTable() : instance(new BinaryPropertyTable())
136 {
137 }
138 public static nothrow BinaryPropertyTable& Instance()
139 {
140 return *instance;
141 }
142 public nothrow const BinaryProperty* GetBinaryProperty(BinaryPropertyId id) const
143 {
144 HashMap<uint, void*>.ConstIterator it = binaryPropertyIdMap.CFind(cast<uint>(cast<byte>(id)));
145 if (it != binaryPropertyIdMap.CEnd())
146 {
147 return cast<BinaryProperty*>(it->second);
148 }
149 return null;
150 }
151 public const BinaryProperty* GetBinaryPropertyByShortName(const string& shortName) const
152 {
153 HashMap<string, void*>.ConstIterator it = shortNameMap.CFind(MakeCanonicalPropertyName(shortName));
154 if (it != shortNameMap.CEnd())
155 {
156 return cast<BinaryProperty*>(it->second);
157 }
158 return null;
159 }
160 public const BinaryProperty* GetBinaryPropertyByLongName(const string& longName) const
161 {
162 HashMap<string, void*>.ConstIterator it = longNameMap.CFind(MakeCanonicalPropertyName(longName));
163 if (it != longNameMap.CEnd())
164 {
165 return cast<BinaryProperty*>(it->second);
166 }
167 return null;
168 }
169 private BinaryPropertyTable() : binaryProperties(), binaryPropertyIdMap(), shortNameMap(), longNameMap()
170 {
171 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.asciiHexDigit, "AHex", "Ascii Hex Digit"));
172 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.alphabetic, "Alpha", "Alphabetic"));
173 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.bidiControl, "Bidi C", "Bidi Control"));
174 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.bidiMirrored, "Bidi M", "Bidi Mirrored"));
175 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.cased, "Cased", "Cased"));
176 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.compositionExclusion, "CE", "Composition Exclusion"));
177 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.caseIgnorable, "CI", "Case Ignorable"));
178 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.fullCompositionExclusion, "Comp Ex", "Full Composition Exclusion"));
179 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.changesWhenCasefolded, "CWCF", "Changes When Casefolded"));
180 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.changesWhenCaseMapped, "CWCM", "Changes When Casemapped"));
181 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.changesWhenNFKCCasefolded, "CWKCF", "Changes When NFKC Casefolded"));
182 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.changesWhenLowercased, "CWL", "Changes When Lowercased"));
183 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.changesWhenTitlecased, "CWT", "Changes When Titlecased"));
184 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.changesWhenUppercased, "CWU", "Changes When Uppercased"));
185 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.dash, "Dash", "Dash"));
186 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.deprecated, "Dep", "Deprecated"));
187 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.defaultIgnorableCodePoint, "DI", "Default Ignorable Code Point"));
188 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.diacritic, "Dia", "Diacritic"));
189 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.extender, "Ext", "Extender"));
190 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.graphemeBase, "Gr Base", "Grapheme Base"));
191 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.graphemeExtend, "Gr Ext", "Grapheme Extend"));
192 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.graphemeLink, "Gr Link", "Grapheme Link"));
193 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.hexDigit, "Hex", "Hex Digit"));
194 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.hyphen, "Hyphen", "Hyphen"));
195 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.idContinue, "IDC", "ID Continue"));
196 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.ideographic, "Ideo", "Ideographic"));
197 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.idStart, "IDS", "ID Start"));
198 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.idsBinaryOperator, "IDSB", "IDS Binary Operator"));
199 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.idsTrinaryOperator, "IDST", "IDS Trinary Operator"));
200 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.joinControl, "Join C", "Join Control"));
201 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.logicalOrderException, "LOE", "Logical Order Exception"));
202 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.lowercase, "Lower", "Lowercase"));
203 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.math, "Math", "Math"));
204 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.noncharacterCodePoint, "NChar", "Noncharacter Code Point"));
205 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.otherAlphabetic, "OAlpha", "Other Alphabetic"));
206 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.otherDefaultIgnorableCodePoint, "ODI", "Other Default Ignorable Code Point"));
207 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.otherGraphemeExtend, "OGr Ext", "Other Grapheme Extend"));
208 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.otherIdContinue, "OIDC", "Other ID Continue"));
209 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.otherIdStart, "OIDS", "Other ID Start"));
210 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.otherLowercase, "OLower", "Other Lowercase"));
211 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.otherMath, "OMath", "Other Math"));
212 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.otherUppercase, "OUpper", "Other Uppercase"));
213 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.patternSyntax, "Pat Syn", "Pattern Syntax"));
214 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.patternWhiteSpace, "Pat WS", "Pattern White Space"));
215 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.prependedConcatenationMark, "PCM", "Prepended Concatenation Mark"));
216 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.quotationMark, "QMark", "Quotation Mark"));
217 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.radical, "Radical", "Radical"));
218 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.softDotted, "SD", "Soft Dotted"));
219 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.sentenceterminal, "STerm", "Sentence Terminal"));
220 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.terminalPunctuation, "Term", "Terminal Punctuation"));
221 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.unifiedIdeograph, "UIdeo", "Unified Ideograph"));
222 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.uppercase, "Upper", "Uppercase"));
223 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.variationSelector, "VS", "Variation Selector"));
224 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.whiteSpace, "WSpace", "White Space"));
225 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.xidContinue, "XIDC", "XID Continue"));
226 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.xidStart, "XIDS", "XID Start"));
227 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.expandsOnNFC, "XO NFC", "Expands On NFC"));
228 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.expandsOnNFD, "XO NFD", "Expands On NFD"));
229 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.expandsOnNFKC, "XO NFKC", "Expands On NFKC"));
230 binaryProperties.Add(new BinaryProperty(BinaryPropertyId.expandsOnNFKD, "XO NFKD", "Expands On NFKD"));
231 for (BinaryProperty* binaryProperty : binaryProperties)
232 {
233 binaryPropertyIdMap[cast<uint>(cast<byte>(binaryProperty->Id()))] = binaryProperty;
234 shortNameMap[MakeCanonicalPropertyName(binaryProperty->ShortName())] = binaryProperty;
235 longNameMap[MakeCanonicalPropertyName(binaryProperty->LongName())] = binaryProperty;
236 }
237 }
238 public ~BinaryPropertyTable()
239 {
240 for (BinaryProperty* binaryProperty : binaryProperties)
241 {
242 delete binaryProperty;
243 }
244 }
245 private List<BinaryProperty*> binaryProperties;
246 private HashMap<uint, void*> binaryPropertyIdMap;
247 private HashMap<string, void*> shortNameMap;
248 private HashMap<string, void*> longNameMap;
249 private static UniquePtr<BinaryPropertyTable> instance;
250 }
251
252 public nothrow const BinaryProperty* GetBinaryProperty(BinaryPropertyId id)
253 {
254 return BinaryPropertyTable.Instance().GetBinaryProperty(id);
255 }
256
257 public const BinaryProperty* GetBinaryPropertyByShortName(const string& shortName)
258 {
259 return BinaryPropertyTable.Instance().GetBinaryPropertyByShortName(shortName);
260 }
261
262 public const BinaryProperty* GetBinaryPropertyByLongName(const string& longName)
263 {
264 return BinaryPropertyTable.Instance().GetBinaryPropertyByLongName(longName);
265 }
266
267 public enum BlockId : ushort
268 {
269 none = 0u,
270 adlam, aegeanNumbers, ahom, alchemical, alphabeticPf, anatolianHieroglyphs, ancientGreekMusic, ancientGreekNumbers, ancientSymbols,
271 arabic, arabicExtA, arabicMath, arabicPfA, arabicPfB, arabicSup, armenian, arrows, ascii, avestan,
272 balinese, bamum, bamumSup, bassaVah, batak, bengali, bhaisuki, blockElements, bopomofo, bopomofoExt, boxDrawing,
273 brahmi, braille, buginese, buhid, byzantineMusic,
274 carian, caucasianAlbanian, chakma, cham, cherokee, cherokeeSup, chessSymbols,
275 cjk, cjkCompat, cjkCompatForms, cjkCompatIdeographs, cjkCompatIdeographsSup, cjkExtA, cjkExtB, cjkExtC, cjkExtD, cjkExtE, cjkExtF,
276 cjkRadicalsSup, cjkStrokes, cjkSymbols, compatJamo, controlPictures, coptic, copticEpactNumbers, countingRod, cuneiform,
277 cuneiformNumbers, currencySymbols, cypriotSyllabary, cyrillic, cyrillicExtA, cyrillicExtB, cyrillicExtC, cyrillicSup,
278 deseret, devanagari, devanagariExt, diacriticals, diariticalsForSymbols, diacriticalsSup, diacriticalsExt, dingbats, dogra, domino, duployan,
279 earlyDynasticCuneiform, egyptianHieroglyphs, egyptianHieroglyphFormatControls, elbasan, elymaic, emoticons, enclosedAlphanum, enclosedAlphanumSup, enclosedCjk, enclosedIdeographicSup,
280 ethiopic, ethiopicExt, ethiopicExtA, ethiopicSup,
281 geometricShapes, geometricShapesExt, georgian, georgianExt, georgianSup, glagolitic, glagoliticSup, gothic, grantha, greek, greekExt, gujarati, gunjalaGondi, gurmukhi,
282 halfAndFullForms, halfMarks, hangul, hanifiRohingya, hanunoo, hatran, hebrew, highPuSurrogates, highSurrogates, hiragana,
283 idc, ideographicSymbols, imperialAramaic, indicNumberForms, inscriptionalPahlavi, inscriptionalParthian, ipaExt, indicSiyaqNumbers,
284 jamo, jamoExtA, jamoExtB, javanese, kaithi, kanaExtA, smallKanaExt, kanaSup, kanbun, kangxi, kannada, katakana, katakanaExt, kayahLi, kharoshthi, khmer, khmerSymbols, khojki, khudawadi,
285 lao, latin1Sup, latinExtA, latinExtAdditional, latinExtB, latinExtC, latinExtD, latinExtE, lepcha, letterlikeSymbols, limbu,
286 linearA, linearBIdeograms, linearBSyllabary, lisu, lowSurrogates, lycian, lydian,
287 mahajani, mahjong, makasar, malayalam, mandaic, manichean, marchen, masaramGondi, mathAlphanum, mathOperators, mayanNumerals, medefaidrin, meeteiMayek, meeteiMayekExt, mendeKikakui, meroiticCursive, meroiticHieroglyphs,
288 miao, miscArrows, miscMathSymbolsA, miscMathSymbolsB, miscPictographs, miscSymbols, miscTechnical, modi, modifierLetters, modifierToneLetters, mongolian, mongolianSup,
289 mro, music, multani, myanmar, myanmarExtA, myanmarExtB,
290 nabataean, nb, nandinagari, newTaiLue, newa, nko, numberForms, nushu, nyiakengPuachueHmong,
291 ocr, ogham, olChiki, oldHungarian, oldItalic, oldNorthArabian, oldPermic, oldPersian, oldSogdian, oldSouthArabian, oldTurkic, oriya, ornamentalDingbats, osage, osmanya, ottomanSiyaqNumbers,
292 pahawhHmong, palmyrene, pauCinHau, phagsPa, phaistos, phoenician, phoneticExt, phoneticExtSup, playingCards, psalterPahlavi, pua, punctuation,
293 rejang, rumi, runic,
294 samaritan, saurashtra, sharada, shavian, shorthandFormatControls, siddham, sinhala, sinhalaArchaicNumbers, smallForms, sogdian, soraSompeng, soyombo, specials, sundanese, sundaneseSup,
295 supArrowsA, supArrowsB, supArrowsC, supMathOperators, supPuaA, supPuaB, supPunctuation, supSymbolsAndPictographs, superAndSub, suttonSignWriting, sylotiNagri, symbolsAndPictographsExtA, syriac,
296 syriacSup,
297 tagalog, tagbanwa, tags, taiLe, taiTham, taiViet, taiXuanJing, takri, tamil, tamilSup, tangut, tangutComponents, telugu, thaana, thai, tibetan, tifinagh, tirhuta, transportAndMap,
298 ucas, ucasExt, ugaritic, vai, vedicExt, verticalForms, vs, vsSup, wancho, warangCiti, yiRadicals, yiSyllables, yijing, zanabazarSquare
299 }
300
301 public class Block
302 {
303 public nothrow Block(BlockId id_, const string& shortName_, const string& longName_, uchar start_, uchar end_) :
304 id(id_), shortName(shortName_), longName(longName_), start(start_), end(end_)
305 {
306 }
307 public inline nothrow BlockId Id()
308 {
309 return id;
310 }
311 public inline nothrow const string& ShortName()
312 {
313 return shortName;
314 }
315 public inline nothrow const string& LongName()
316 {
317 return longName;
318 }
319 public inline nothrow uchar Start()
320 {
321 return start;
322 }
323 public inline nothrow uchar End()
324 {
325 return end;
326 }
327 private BlockId id;
328 private string shortName;
329 private string longName;
330 private uchar start;
331 private uchar end;
332 }
333
334 public class BlockTable
335 {
336 static BlockTable() : instance(new BlockTable())
337 {
338 }
339 public static BlockTable& Instance()
340 {
341 return *instance;
342 }
343 public inline nothrow const Block* GetBlock(BlockId id) const
344 {
345 HashMap<uint, void*>.ConstIterator it = blockIdMap.CFind(cast<uint>(cast<ushort>(id)));
346 if (it != blockIdMap.CEnd())
347 {
348 return cast<Block*>(it->second);
349 }
350 return null;
351 }
352 public inline const Block* GetBlockByShortName(const string& shortName) const
353 {
354 HashMap<string, void*>.ConstIterator it = shortNameMap.CFind(MakeCanonicalPropertyName(shortName));
355 if (it != shortNameMap.CEnd())
356 {
357 return cast<Block*>(it->second);
358 }
359 return null;
360 }
361 public inline const Block* GetBlockByLongName(const string& longName) const
362 {
363 HashMap<string, void*>.ConstIterator it = longNameMap.CFind(MakeCanonicalPropertyName(longName));
364 if (it != longNameMap.CEnd())
365 {
366 return cast<Block*>(it->second);
367 }
368 return null;
369 }
370 private BlockTable() : blocks(), blockIdMap(), shortNameMap(), longNameMap()
371 {
372 blocks.Add(new Block(BlockId.ascii, "ASCII", "Basic Latin", cast<uchar>(0x0000u), cast<uchar>(0x007Fu)));
373 blocks.Add(new Block(BlockId.latin1Sup, "Latin 1 Sup", "Latin-1 Supplement", cast<uchar>(0x0080u), cast<uchar>(0x00FFu)));
374 blocks.Add(new Block(BlockId.latinExtA, "Latin Ext A", "Latin Extended-A", cast<uchar>(0x0100u), cast<uchar>(0x017Fu)));
375 blocks.Add(new Block(BlockId.latinExtB, "Latin Ext B", "Latin Extended-B", cast<uchar>(0x0180u), cast<uchar>(0x0024Fu)));
376 blocks.Add(new Block(BlockId.ipaExt, "IPA Ext", "IPA Extensions", cast<uchar>(0x0250u), cast<uchar>(0x02AFu)));
377 blocks.Add(new Block(BlockId.modifierLetters, "Modifier Letters", "Spacing Modifier Letters", cast<uchar>(0x02B0u), cast<uchar>(0x02FFu)));
378 blocks.Add(new Block(BlockId.diacriticals, "Diacriticals", "Combining Diacritical Marks", cast<uchar>(0x0300u), cast<uchar>(0x036Fu)));
379 blocks.Add(new Block(BlockId.greek, "Greek", "Greek and Coptic", cast<uchar>(0x0370u), cast<uchar>(0x03FFu)));
380 blocks.Add(new Block(BlockId.cyrillic, "Cyrillic", "Cyrillic", cast<uchar>(0x0400u), cast<uchar>(0x04FFu)));
381 blocks.Add(new Block(BlockId.cyrillicSup, "Cyrillic Sup", "Cyrillic Supplement", cast<uchar>(0x0500u), cast<uchar>(0x052Fu)));
382 blocks.Add(new Block(BlockId.armenian, "Armenian", "Armenian", cast<uchar>(0x0530u), cast<uchar>(0x058Fu)));
383 blocks.Add(new Block(BlockId.hebrew, "Hebrew", "Hebrew", cast<uchar>(0x0590u), cast<uchar>(0x05FFu)));
384 blocks.Add(new Block(BlockId.arabic, "Arabic", "Arabic", cast<uchar>(0x0600u), cast<uchar>(0x06FFu)));
385 blocks.Add(new Block(BlockId.syriac, "Syriac", "Syriac", cast<uchar>(0x0700u), cast<uchar>(0x074Fu)));
386 blocks.Add(new Block(BlockId.arabicSup, "Arabic Sup", "Arabic Supplement", cast<uchar>(0x0750u), cast<uchar>(0x077Fu)));
387 blocks.Add(new Block(BlockId.thaana, "Thaana", "Thaana", cast<uchar>(0x0780u), cast<uchar>(0x07BFu)));
388 blocks.Add(new Block(BlockId.nko, "Nko", "Nko", cast<uchar>(0x07C0u), cast<uchar>(0x07FFu)));
389 blocks.Add(new Block(BlockId.samaritan, "Samaritan", "Samaritan", cast<uchar>(0x0800u), cast<uchar>(0x083Fu)));
390 blocks.Add(new Block(BlockId.mandaic, "Mandaic", "Mandaic", cast<uchar>(0x0840u), cast<uchar>(0x085Fu)));
391 blocks.Add(new Block(BlockId.syriacSup, "Syriac Sup", "Syriac Supplement", cast<uchar>(0x0860), cast<uchar>(0x086F)));
392 blocks.Add(new Block(BlockId.arabicExtA, "Arabic Ext A", "Arabic Extended-A", cast<uchar>(0x08A0u), cast<uchar>(0x08FFu)));
393 blocks.Add(new Block(BlockId.devanagari, "Devanagari", "Devanagari", cast<uchar>(0x0900u), cast<uchar>(0x097Fu)));
394 blocks.Add(new Block(BlockId.bengali, "Bengali", "Bengali", cast<uchar>(0x0980u), cast<uchar>(0x09FFu)));
395 blocks.Add(new Block(BlockId.gurmukhi, "Gurmukhi", "Gurmukhi", cast<uchar>(0x0A00u), cast<uchar>(0x0A7Fu)));
396 blocks.Add(new Block(BlockId.gujarati, "Gujarati", "Gujarati", cast<uchar>(0x0A80u), cast<uchar>(0x0AFFu)));
397 blocks.Add(new Block(BlockId.oriya, "Oriya", "Oriya", cast<uchar>(0x0B00u), cast<uchar>(0x0B7Fu)));
398 blocks.Add(new Block(BlockId.tamil, "Tamil", "Tamil", cast<uchar>(0x0B80u), cast<uchar>(0x0BFFu)));
399 blocks.Add(new Block(BlockId.telugu, "Telugu", "Telugu", cast<uchar>(0x0C00u), cast<uchar>(0x0C7Fu)));
400 blocks.Add(new Block(BlockId.kannada, "Kannada", "Kannada", cast<uchar>(0x0C80u), cast<uchar>(0x0CFFu)));
401 blocks.Add(new Block(BlockId.malayalam, "Malayalam", "Malayalam", cast<uchar>(0x0D00u), cast<uchar>(0x0D7Fu)));
402 blocks.Add(new Block(BlockId.sinhala, "Sinhala", "Sinhala", cast<uchar>(0x0D80u), cast<uchar>(0x0DFFu)));
403 blocks.Add(new Block(BlockId.thai, "Thai", "Thai", cast<uchar>(0x0E00u), cast<uchar>(0x0E7Fu)));
404 blocks.Add(new Block(BlockId.lao, "Lao", "Lao", cast<uchar>(0x0E80u), cast<uchar>(0x0EFFu)));
405 blocks.Add(new Block(BlockId.tibetan, "Tibetan", "Tibetan", cast<uchar>(0x0F00u), cast<uchar>(0x0FFFu)));
406 blocks.Add(new Block(BlockId.myanmar, "Myanmar", "Myanmar", cast<uchar>(0x1000u), cast<uchar>(0x109Fu)));
407 blocks.Add(new Block(BlockId.georgian, "Georgian", "Georgian", cast<uchar>(0x10A0u), cast<uchar>(0x10FFu)));
408 blocks.Add(new Block(BlockId.jamo, "Jamo", "Hangul Jamo", cast<uchar>(0x1100u), cast<uchar>(0x11FFu)));
409 blocks.Add(new Block(BlockId.ethiopic, "Ethiopic", "Ethiopic", cast<uchar>(0x1200u), cast<uchar>(0x137Fu)));
410 blocks.Add(new Block(BlockId.ethiopicSup, "Ethiopic Sup", "Ethiopic Supplement", cast<uchar>(0x1380u), cast<uchar>(0x139Fu)));
411 blocks.Add(new Block(BlockId.cherokee, "Cherokee", "Cherokee", cast<uchar>(0x13A0u), cast<uchar>(0x13FFu)));
412 blocks.Add(new Block(BlockId.ucas, "UCAS", "Unified Canadian Aboriginal Syllabics", cast<uchar>(0x1400u), cast<uchar>(0x167Fu)));
413 blocks.Add(new Block(BlockId.ogham, "Ogham", "Ogham", cast<uchar>(0x1680u), cast<uchar>(0x169Fu)));
414 blocks.Add(new Block(BlockId.runic, "Runic", "Runic", cast<uchar>(0x16A0u), cast<uchar>(0x16FFu)));
415 blocks.Add(new Block(BlockId.tagalog, "Tagalog", "Tagalog", cast<uchar>(0x1700u), cast<uchar>(0x171Fu)));
416 blocks.Add(new Block(BlockId.hanunoo, "Hanunoo", "Hanunoo", cast<uchar>(0x1720u), cast<uchar>(0x173Fu)));
417 blocks.Add(new Block(BlockId.buhid, "Buhid", "Buhid", cast<uchar>(0x1740u), cast<uchar>(0x175Fu)));
418 blocks.Add(new Block(BlockId.tagbanwa, "Tagbanwa", "Tagbanwa", cast<uchar>(0x1760u), cast<uchar>(0x177Fu)));
419 blocks.Add(new Block(BlockId.khmer, "Khmer", "Khmer", cast<uchar>(0x1780u), cast<uchar>(0x17FFu)));
420 blocks.Add(new Block(BlockId.mongolian, "Mongolian", "Mongolian", cast<uchar>(0x1800u), cast<uchar>(0x18AFu)));
421 blocks.Add(new Block(BlockId.ucasExt, "UCAS Ext", "Unified Canadian Aboriginal Syllabics Extended", cast<uchar>(0x18B0u), cast<uchar>(0x18FFu)));
422 blocks.Add(new Block(BlockId.limbu, "Limbu", "Limbu", cast<uchar>(0x1900u), cast<uchar>(0x194Fu)));
423 blocks.Add(new Block(BlockId.taiLe, "Tai Le", "Tai Le", cast<uchar>(0x1950u), cast<uchar>(0x197Fu)));
424 blocks.Add(new Block(BlockId.newTaiLue, "New Tai Lue", "New Tai Lue", cast<uchar>(0x1980u), cast<uchar>(0x19DFu)));
425 blocks.Add(new Block(BlockId.khmerSymbols, "Khmer Symbols", "Khmer Symbols", cast<uchar>(0x19E0u), cast<uchar>(0x19FFu)));
426 blocks.Add(new Block(BlockId.buginese, "Buginese", "Buginese", cast<uchar>(0x1A00u), cast<uchar>(0x1A1Fu)));
427 blocks.Add(new Block(BlockId.taiTham, "Tai Tham", "Tai Tham", cast<uchar>(0x1A20u), cast<uchar>(0x1AAFu)));
428 blocks.Add(new Block(BlockId.diacriticalsExt, "Diacriticals Ext", "Combining Diacritical Marks Extended", cast<uchar>(0x1AB0u), cast<uchar>(0x1AFFu)));
429 blocks.Add(new Block(BlockId.balinese, "Balinese", "Balinese", cast<uchar>(0x1B00u), cast<uchar>(0x1B7Fu)));
430 blocks.Add(new Block(BlockId.sundanese, "Sundanese", "Sundanese", cast<uchar>(0x1B80u), cast<uchar>(0x1BBFu)));
431 blocks.Add(new Block(BlockId.batak, "Batak", "Batak", cast<uchar>(0x1BC0u), cast<uchar>(0x1BFFu)));
432 blocks.Add(new Block(BlockId.lepcha, "Lepcha", "Lepcha", cast<uchar>(0x1C00u), cast<uchar>(0x1C4Fu)));
433 blocks.Add(new Block(BlockId.olChiki, "Ol Chiki", "Ol Chiki", cast<uchar>(0x1C50u), cast<uchar>(0x1C7Fu)));
434 blocks.Add(new Block(BlockId.cyrillicExtC, "Cyrillic Ext C", "Cyrillic Extended-C", cast<uchar>(0x1C80u), cast<uchar>(0x1C8Fu)));
435 blocks.Add(new Block(BlockId.georgianExt, "Georgian Ext", "Georgian Extended", cast<uchar>(0x1C90), cast<uchar>(0x1CBF)));
436 blocks.Add(new Block(BlockId.sundaneseSup, "Sundanese Sup", "Sundanese Supplement", cast<uchar>(0x1CC0u), cast<uchar>(0x1CCFu)));
437 blocks.Add(new Block(BlockId.vedicExt, "Vedic Ext", "Vedic Extensions", cast<uchar>(0x1CD0u), cast<uchar>(0x1CFFu)));
438 blocks.Add(new Block(BlockId.phoneticExt, "Phonetic Ext", "Phonetic Extensions", cast<uchar>(0x1D00u), cast<uchar>(0x1D7Fu)));
439 blocks.Add(new Block(BlockId.phoneticExtSup, "Phonetic Ext Sup", "Phonetic Extensions Supplement", cast<uchar>(0x1D80u), cast<uchar>(0x1DBFu)));
440 blocks.Add(new Block(BlockId.diacriticalsSup, "Diacriticals Sup", "Combining Diacritical Marks Supplement", cast<uchar>(0x1DC0u), cast<uchar>(0x1DFFu)));
441 blocks.Add(new Block(BlockId.latinExtAdditional, "Latin Ext Additional", "Latin Extended Additional", cast<uchar>(0x1E00u), cast<uchar>(0x1EFFu)));
442 blocks.Add(new Block(BlockId.greekExt, "Greek Ext", "Greek Extended", cast<uchar>(0x1F00u), cast<uchar>(0x1FFFu)));
443 blocks.Add(new Block(BlockId.punctuation, "Punctuation", "General Punctuation", cast<uchar>(0x2000u), cast<uchar>(0x206Fu)));
444 blocks.Add(new Block(BlockId.superAndSub, "Super And Sub", "Superscripts and Subscripts", cast<uchar>(0x2070u), cast<uchar>(0x209Fu)));
445 blocks.Add(new Block(BlockId.currencySymbols, "Currency Symbols", "Currency Symbols", cast<uchar>(0x20A0u), cast<uchar>(0x20CFu)));
446 blocks.Add(new Block(BlockId.diariticalsForSymbols, "Diacriticals For Symbols", "Combining Diacritical Marks for Symbols", cast<uchar>(0x20D0u), cast<uchar>(0x20FFu)));
447 blocks.Add(new Block(BlockId.letterlikeSymbols, "Letterlike Symbols", "Letterlike Symbols", cast<uchar>(0x2100u), cast<uchar>(0x214Fu)));
448 blocks.Add(new Block(BlockId.numberForms, "Number Forms", "Number Forms", cast<uchar>(0x2150u), cast<uchar>(0x218Fu)));
449 blocks.Add(new Block(BlockId.arrows, "Arrows", "Arrows", cast<uchar>(0x2190u), cast<uchar>(0x21FFu)));
450 blocks.Add(new Block(BlockId.mathOperators, "Math Operators", "Mathematical Operators", cast<uchar>(0x2200u), cast<uchar>(0x22FFu)));
451 blocks.Add(new Block(BlockId.miscTechnical, "Misc Technical", "Miscellaneous Technical", cast<uchar>(0x2300u), cast<uchar>(0x23FFu)));
452 blocks.Add(new Block(BlockId.controlPictures, "Control Pictures", "Control Pictures", cast<uchar>(0x2400u), cast<uchar>(0x243Fu)));
453 blocks.Add(new Block(BlockId.ocr, "OCR", "Optical Character Regognition", cast<uchar>(0x2440u), cast<uchar>(0x245Fu)));
454 blocks.Add(new Block(BlockId.enclosedAlphanum, "Enclosed Alphanum", "Enclosed Alphanumerics", cast<uchar>(0x2460u), cast<uchar>(0x24FFu)));
455 blocks.Add(new Block(BlockId.boxDrawing, "Box Drawing", "Box Drawing", cast<uchar>(0x2500u), cast<uchar>(0x257Fu)));
456 blocks.Add(new Block(BlockId.blockElements, "Block Elements", "Block Elements", cast<uchar>(0x2580u), cast<uchar>(0x259Fu)));
457 blocks.Add(new Block(BlockId.geometricShapes, "Geometric Shapes", "Geometric Shapes", cast<uchar>(0x25A0u), cast<uchar>(0x25FFu)));
458 blocks.Add(new Block(BlockId.miscSymbols, "Misc Symbols", "Miscellaneous Symbols", cast<uchar>(0x2600u), cast<uchar>(0x26FFu)));
459 blocks.Add(new Block(BlockId.dingbats, "Dingbats", "Dingbats", cast<uchar>(0x2700u), cast<uchar>(0x27BFu)));
460 blocks.Add(new Block(BlockId.miscMathSymbolsA, "Misc Math Symbols A", "Miscellaneous Mathematical Symbols - A", cast<uchar>(0x27C0u), cast<uchar>(0x27EFu)));
461 blocks.Add(new Block(BlockId.supArrowsA, "Sup Arrows A", "Supplemental Arrows-A", cast<uchar>(0x27F0u), cast<uchar>(0x27FFu)));
462 blocks.Add(new Block(BlockId.braille, "Braille", "Braille Patterns", cast<uchar>(0x2800u), cast<uchar>(0x28FFu)));
463 blocks.Add(new Block(BlockId.supArrowsB, "Sup Arrows B", "Supplemental Arrows-B", cast<uchar>(0x2900u), cast<uchar>(0x297Fu)));
464 blocks.Add(new Block(BlockId.miscMathSymbolsB, "Misc Math Symbols B", "Miscellaneous Mathematical Symbols-B", cast<uchar>(0x2980u), cast<uchar>(0x29FFu)));
465 blocks.Add(new Block(BlockId.supMathOperators, "Sup Math Operators", "Supplemental Mathematical Operators", cast<uchar>(0x2A00u), cast<uchar>(0x2AFFu)));
466 blocks.Add(new Block(BlockId.miscArrows, "Misc Arrows", "Miscellaneous Symbols and Arrows", cast<uchar>(0x2B00u), cast<uchar>(0x2BFFu)));
467 blocks.Add(new Block(BlockId.glagolitic, "Glagolitic", "Glagolitic", cast<uchar>(0x2C00u), cast<uchar>(0x2C5Fu)));
468 blocks.Add(new Block(BlockId.latinExtC, "Latin Ext C", "Latin Extended-C", cast<uchar>(0x2C60u), cast<uchar>(0x2C7Fu)));
469 blocks.Add(new Block(BlockId.coptic, "Coptic", "Coptic", cast<uchar>(0x2C80u), cast<uchar>(0x2CFFu)));
470 blocks.Add(new Block(BlockId.georgianSup, "Georgian Sup", "Georgian Supplement", cast<uchar>(0x2D00u), cast<uchar>(0x2D2Fu)));
471 blocks.Add(new Block(BlockId.tifinagh, "Tifinagh", "Tifinagh", cast<uchar>(0x2D30u), cast<uchar>(0x2D7Fu)));
472 blocks.Add(new Block(BlockId.ethiopicExt, "Ethiopic Ext", "Ethiopic Extended", cast<uchar>(0x2D80u), cast<uchar>(0x2DDFu)));
473 blocks.Add(new Block(BlockId.cyrillicExtA, "Cyrillic Ext A", "Cyrillic Extended-A", cast<uchar>(0x2DE0u), cast<uchar>(0x2DFFu)));
474 blocks.Add(new Block(BlockId.supPunctuation, "Sup Punctuation", "Supplemental Punctuation", cast<uchar>(0x2E00u), cast<uchar>(0x2E7Fu)));
475 blocks.Add(new Block(BlockId.cjkRadicalsSup, "CJK Radicals Sup", "CJK Radicals Supplement", cast<uchar>(0x2E80u), cast<uchar>(0x2EFFu)));
476 blocks.Add(new Block(BlockId.kangxi, "Kangxi", "Kangxi Radicals", cast<uchar>(0x2F00u), cast<uchar>(0x2FDFu)));
477 blocks.Add(new Block(BlockId.idc, "IDC", "Ideographic Description Characters", cast<uchar>(0x2FF0u), cast<uchar>(0x2FFFu)));
478 blocks.Add(new Block(BlockId.cjkSymbols, "CJK Symbols", "CJK Symbols and Punctuation", cast<uchar>(0x3000u), cast<uchar>(0x303Fu)));
479 blocks.Add(new Block(BlockId.hiragana, "Hiragana", "Hiragana", cast<uchar>(0x3040u), cast<uchar>(0x309Fu)));
480 blocks.Add(new Block(BlockId.katakana, "Katakana", "Katakana", cast<uchar>(0x30A0u), cast<uchar>(0x30FFu)));
481 blocks.Add(new Block(BlockId.bopomofo, "Bopomofo", "Bopomofo", cast<uchar>(0x3100u), cast<uchar>(0x312Fu)));
482 blocks.Add(new Block(BlockId.compatJamo, "Compat Jamo", "Hangul Compatibility Jamo", cast<uchar>(0x3130u), cast<uchar>(0x318Fu)));
483 blocks.Add(new Block(BlockId.kanbun, "Kanbun", "Kanbun", cast<uchar>(0x3190u), cast<uchar>(0x319Fu)));
484 blocks.Add(new Block(BlockId.bopomofoExt, "Bopomofo Ext", "Bopomofo Extended", cast<uchar>(0x31A0u), cast<uchar>(0x31BFu)));
485 blocks.Add(new Block(BlockId.cjkStrokes, "CJK Strokes", "CJK Strokes", cast<uchar>(0x31C0u), cast<uchar>(0x31EFu)));
486 blocks.Add(new Block(BlockId.katakanaExt, "Katakana Ext", "Katakana Phonetic Extensions", cast<uchar>(0x31F0u), cast<uchar>(0x31FFu)));
487 blocks.Add(new Block(BlockId.enclosedCjk, "Enclosed CJK", "Enclosed CJK Letters and Months", cast<uchar>(0x3200u), cast<uchar>(0x32FFu)));
488 blocks.Add(new Block(BlockId.cjkCompat, "CJK Compat", "CJK Compatibility", cast<uchar>(0x3300u), cast<uchar>(0x33FFu)));
489 blocks.Add(new Block(BlockId.cjkExtA, "CJK Ext A", "CJK Unified Ideographic Extension A", cast<uchar>(0x3400u), cast<uchar>(0x4DBFu)));
490 blocks.Add(new Block(BlockId.yijing, "Yijing", "Yijing Hexagram Symbols", cast<uchar>(0x4DC0u), cast<uchar>(0x4DFFu)));
491 blocks.Add(new Block(BlockId.cjk, "CJK", "CJK Unified Ideographs", cast<uchar>(0x4E00u), cast<uchar>(0x9FFFu)));
492 blocks.Add(new Block(BlockId.yiSyllables, "Yi Syllables", "Yi Syllables", cast<uchar>(0xA000u), cast<uchar>(0xA48Fu)));
493 blocks.Add(new Block(BlockId.yiRadicals, "Yi Radicals", "Yi Radicals", cast<uchar>(0xA090u), cast<uchar>(0xA4CFu)));
494 blocks.Add(new Block(BlockId.lisu, "Lisu", "Lisu", cast<uchar>(0xA0D0u), cast<uchar>(0xA4FFu)));
495 blocks.Add(new Block(BlockId.vai, "Vai", "Vai", cast<uchar>(0xA500u), cast<uchar>(0xA63Fu)));
496 blocks.Add(new Block(BlockId.cyrillicExtB, "Cyrillic Ext B", "Cyrillic Extended-B", cast<uchar>(0xA640u), cast<uchar>(0xA69Fu)));
497 blocks.Add(new Block(BlockId.bamum, "Bamum", "Bamum", cast<uchar>(0xA6A0u), cast<uchar>(0xA6FFu)));
498 blocks.Add(new Block(BlockId.modifierToneLetters, "Modifier Tone Letters", "Modifier Tone Letters", cast<uchar>(0xA700u), cast<uchar>(0xA71Fu)));
499 blocks.Add(new Block(BlockId.latinExtD, "Latin Ext D", "Latin Extended-D", cast<uchar>(0xA720u), cast<uchar>(0xA7FFu)));
500 blocks.Add(new Block(BlockId.sylotiNagri, "Syloti Nagri", "Syloti Nagri", cast<uchar>(0xA800u), cast<uchar>(0xA82Fu)));
501 blocks.Add(new Block(BlockId.indicNumberForms, "Indic Number Forms", "Common Indic Number Forms", cast<uchar>(0xA830u), cast<uchar>(0xA83Fu)));
502 blocks.Add(new Block(BlockId.phagsPa, "Phags Pa", "Phags-Pa", cast<uchar>(0xA840u), cast<uchar>(0xA87Fu)));
503 blocks.Add(new Block(BlockId.saurashtra, "Saurashtra", "Saurashtra", cast<uchar>(0xA880u), cast<uchar>(0xA8DFu)));
504 blocks.Add(new Block(BlockId.devanagariExt, "Devanagari Ext", "Devanagari Extended", cast<uchar>(0xA8E0u), cast<uchar>(0xA8FFu)));
505 blocks.Add(new Block(BlockId.kayahLi, "Kayah Li", "Kayah Li", cast<uchar>(0xA900u), cast<uchar>(0xA92Fu)));
506 blocks.Add(new Block(BlockId.rejang, "Rejang", "Rejang", cast<uchar>(0xA930u), cast<uchar>(0xA95Fu)));
507 blocks.Add(new Block(BlockId.jamoExtA, "Jamo Ext A", "Hangul Jamo Extended-A", cast<uchar>(0xA960u), cast<uchar>(0xA97Fu)));
508 blocks.Add(new Block(BlockId.javanese, "Javanese", "Javanese", cast<uchar>(0xA980u), cast<uchar>(0xA9DFu)));
509 blocks.Add(new Block(BlockId.myanmarExtB, "Myanmar Ext B", "Myanmar Extended - B", cast<uchar>(0xA9E0u), cast<uchar>(0xA9FFu)));
510 blocks.Add(new Block(BlockId.cham, "Cham", "Cham", cast<uchar>(0xAA00u), cast<uchar>(0xAA5Fu)));
511 blocks.Add(new Block(BlockId.myanmarExtA, "Myanmar Ext A", "Myanmar Extended-A", cast<uchar>(0xAA60u), cast<uchar>(0xAA7Fu)));
512 blocks.Add(new Block(BlockId.taiViet, "Tai Viet", "Tai Viet", cast<uchar>(0xAA80u), cast<uchar>(0xAADFu)));
513 blocks.Add(new Block(BlockId.meeteiMayekExt, "Meetei Mayek Ext", "Meetei Mayek Extensions", cast<uchar>(0xAAE0u), cast<uchar>(0xAAFFu)));
514 blocks.Add(new Block(BlockId.ethiopicExtA, "Ethiopic Ext A", "Ethiopic Extended-A", cast<uchar>(0xAB00u), cast<uchar>(0xAB2Fu)));
515 blocks.Add(new Block(BlockId.latinExtE, "Latin Ext E", "Latin Extended-E", cast<uchar>(0xAB30u), cast<uchar>(0xAB6Fu)));
516 blocks.Add(new Block(BlockId.cherokeeSup, "Cherokee Sup", "Cherokee Supplement", cast<uchar>(0xAB70u), cast<uchar>(0xABBFu)));
517 blocks.Add(new Block(BlockId.meeteiMayek, "Meetei Mayek", "Meetei Mayek", cast<uchar>(0xABC0u), cast<uchar>(0xABFFu)));
518 blocks.Add(new Block(BlockId.hangul, "Hangul", "Hangul Syllables", cast<uchar>(0xAC00u), cast<uchar>(0xD7AFu)));
519 blocks.Add(new Block(BlockId.jamoExtB, "Jamo Ext B", "Hangul Jamo Extended-B", cast<uchar>(0xD7B0u), cast<uchar>(0xD7FFu)));
520 blocks.Add(new Block(BlockId.highSurrogates, "High Surrogates", "High Surrogates", cast<uchar>(0xD800u), cast<uchar>(0xDB7Fu)));
521 blocks.Add(new Block(BlockId.highPuSurrogates, "High PU Surrogates", "High Private Use Surrogates", cast<uchar>(0xDB80u), cast<uchar>(0xDBFFu)));
522 blocks.Add(new Block(BlockId.lowSurrogates, "Low Surrogates", "Low Surrogates", cast<uchar>(0xDC00u), cast<uchar>(0xDFFFu)));
523 blocks.Add(new Block(BlockId.pua, "PUA", "Private Use Area", cast<uchar>(0xE000u), cast<uchar>(0xF8FFu)));
524 blocks.Add(new Block(BlockId.cjkCompatIdeographs, "CJK Compat Ideographs", "CJK Compatibility Ideographs", cast<uchar>(0xF900u), cast<uchar>(0xFAFFu)));
525 blocks.Add(new Block(BlockId.alphabeticPf, "Alphabetic PF", "Alphabetic Presentations Forms", cast<uchar>(0xFB00u), cast<uchar>(0xFB4Fu)));
526 blocks.Add(new Block(BlockId.arabicPfA, "Arabic PF A", "Arabic Presentation Forms-A", cast<uchar>(0xFB50u), cast<uchar>(0xFDFFu)));
527 blocks.Add(new Block(BlockId.vs, "VS", "Variation Selectors", cast<uchar>(0xFE00u), cast<uchar>(0xFE0Fu)));
528 blocks.Add(new Block(BlockId.verticalForms, "Vertical Forms", "Vertical Forms", cast<uchar>(0xFE10u), cast<uchar>(0xFE1Fu)));
529 blocks.Add(new Block(BlockId.halfMarks, "Half Marks", "Combining Half Marks", cast<uchar>(0xFE20u), cast<uchar>(0xFE2Fu)));
530 blocks.Add(new Block(BlockId.cjkCompatForms, "CJK Compat Forms", "CJK Compatibility Forms", cast<uchar>(0xFE30u), cast<uchar>(0xFE4Fu)));
531 blocks.Add(new Block(BlockId.smallForms, "Small Forms", "Small Form Variants", cast<uchar>(0xFE50u), cast<uchar>(0xFE6Fu)));
532 blocks.Add(new Block(BlockId.arabicPfB, "Arabic PF B", "Arabic Presentation Forms-B", cast<uchar>(0xFE70u), cast<uchar>(0xFEFFu)));
533 blocks.Add(new Block(BlockId.halfAndFullForms, "Half And Full Forms", "Halfwidth and Fullwidth Forms", cast<uchar>(0xFF00u), cast<uchar>(0xFFEFu)));
534 blocks.Add(new Block(BlockId.specials, "Specials", "Specials", cast<uchar>(0xFFF0u), cast<uchar>(0xFFFFu)));
535 blocks.Add(new Block(BlockId.linearBSyllabary, "Linear B Syllabary", "Linear B Syllabary", cast<uchar>(0x10000u), cast<uchar>(0x1007Fu)));
536 blocks.Add(new Block(BlockId.linearBIdeograms, "Linear B Ideograms", "Linear B Ideograms", cast<uchar>(0x10080u), cast<uchar>(0x100FFu)));
537 blocks.Add(new Block(BlockId.aegeanNumbers, "Aegean Numbers", "Aegean Numbers", cast<uchar>(0x10100u), cast<uchar>(0x1013Fu)));
538 blocks.Add(new Block(BlockId.ancientGreekNumbers, "Ancient Greek Numbers", "Ancient Greek Numbers", cast<uchar>(0x10140u), cast<uchar>(0x1018Fu)));
539 blocks.Add(new Block(BlockId.ancientSymbols, "Ancient Symbols", "Ancient Symbols", cast<uchar>(0x10190u), cast<uchar>(0x101CFu)));
540 blocks.Add(new Block(BlockId.phaistos, "Phaistos", "Phaistos Disc", cast<uchar>(0x101D0u), cast<uchar>(0x101FFu)));
541 blocks.Add(new Block(BlockId.lycian, "Lycian", "Lycian", cast<uchar>(0x10280u), cast<uchar>(0x1029Fu)));
542 blocks.Add(new Block(BlockId.carian, "Carian", "Carian", cast<uchar>(0x102A0u), cast<uchar>(0x102DFu)));
543 blocks.Add(new Block(BlockId.copticEpactNumbers, "Coptic Epact Numbers", "Coptic Epact Numbers", cast<uchar>(0x102E0u), cast<uchar>(0x102FFu)));
544 blocks.Add(new Block(BlockId.oldItalic, "Old Italic", "Old Italic", cast<uchar>(0x10300u), cast<uchar>(0x1032Fu)));
545 blocks.Add(new Block(BlockId.gothic, "Gothic", "Gothic", cast<uchar>(0x10330u), cast<uchar>(0x1034Fu)));
546 blocks.Add(new Block(BlockId.oldPermic, "Old Permic", "Old Permic", cast<uchar>(0x10350u), cast<uchar>(0x1037Fu)));
547 blocks.Add(new Block(BlockId.ugaritic, "Ugaritic", "Ugaritic", cast<uchar>(0x10380u), cast<uchar>(0x1039Fu)));
548 blocks.Add(new Block(BlockId.oldPersian, "Old Persian", "Old Persian", cast<uchar>(0x103A0u), cast<uchar>(0x103DFu)));
549 blocks.Add(new Block(BlockId.deseret, "Deseret", "Deseret", cast<uchar>(0x10400u), cast<uchar>(0x1044Fu)));
550 blocks.Add(new Block(BlockId.shavian, "Shavian", "Shavian", cast<uchar>(0x10450u), cast<uchar>(0x1047Fu)));
551 blocks.Add(new Block(BlockId.osmanya, "Osmanya", "Osmanya", cast<uchar>(0x10480u), cast<uchar>(0x104AFu)));
552 blocks.Add(new Block(BlockId.osage, "Osage", "Osage", cast<uchar>(0x104B0u), cast<uchar>(0x104FFu)));
553 blocks.Add(new Block(BlockId.elbasan, "Elbasan", "Elbasan", cast<uchar>(0x10500u), cast<uchar>(0x1052Fu)));
554 blocks.Add(new Block(BlockId.caucasianAlbanian, "Caucasian Albanian", "Caucasian Albanian", cast<uchar>(0x10530u), cast<uchar>(0x1056Fu)));
555 blocks.Add(new Block(BlockId.linearA, "Linear A", "Linear A", cast<uchar>(0x10600u), cast<uchar>(0x1077Fu)));
556 blocks.Add(new Block(BlockId.cypriotSyllabary, "Cypriot Syllabary", "Cypriot Syllabary", cast<uchar>(0x10800u), cast<uchar>(0x1083Fu)));
557 blocks.Add(new Block(BlockId.imperialAramaic, "Imperial Aramaic", "Imperial Aramaic", cast<uchar>(0x10840u), cast<uchar>(0x1085Fu)));
558 blocks.Add(new Block(BlockId.palmyrene, "Palmyrene", "Palmyrene", cast<uchar>(0x10860u), cast<uchar>(0x1087Fu)));
559 blocks.Add(new Block(BlockId.nabataean, "Nabataean", "Nabataean", cast<uchar>(0x10880u), cast<uchar>(0x108AFu)));
560 blocks.Add(new Block(BlockId.hatran, "Hatran", "Hatran", cast<uchar>(0x108E0u), cast<uchar>(0x108FFu)));
561 blocks.Add(new Block(BlockId.phoenician, "Phoenician", "Phoenician", cast<uchar>(0x10900u), cast<uchar>(0x1091Fu)));
562 blocks.Add(new Block(BlockId.lydian, "Lydian", "Lydian", cast<uchar>(0x10920u), cast<uchar>(0x1093Fu)));
563 blocks.Add(new Block(BlockId.meroiticHieroglyphs, "Meroitic Hieroglyphs", "Meroitic Hieroglyphs", cast<uchar>(0x10980u), cast<uchar>(0x1099Fu)));
564 blocks.Add(new Block(BlockId.meroiticCursive, "Meroitic Cursive", "Meroitic Cursive", cast<uchar>(0x109A0u), cast<uchar>(0x109FFu)));
565 blocks.Add(new Block(BlockId.kharoshthi, "Kharoshthi", "Kharoshthi", cast<uchar>(0x10A00u), cast<uchar>(0x10A5Fu)));
566 blocks.Add(new Block(BlockId.oldSouthArabian, "Old South Arabian", "Old South Arabian", cast<uchar>(0x10A60u), cast<uchar>(0x10A7Fu)));
567 blocks.Add(new Block(BlockId.oldNorthArabian, "Old North Arabian", "Old North Arabian", cast<uchar>(0x10A80u), cast<uchar>(0x10A9Fu)));
568 blocks.Add(new Block(BlockId.manichean, "Manichaean", "Manichaean", cast<uchar>(0x10AC0u), cast<uchar>(0x10AFFu)));
569 blocks.Add(new Block(BlockId.avestan, "Avestan", "Avestan", cast<uchar>(0x10B00u), cast<uchar>(0x10B3Fu)));
570 blocks.Add(new Block(BlockId.inscriptionalParthian, "Inscriptional Parthian", "Inscriptional Parthian", cast<uchar>(0x10B40u), cast<uchar>(0x10B5Fu)));
571 blocks.Add(new Block(BlockId.inscriptionalPahlavi, "Inscriptional Pahlavi", "Inscriptional Pahlavi", cast<uchar>(0x10B60u), cast<uchar>(0x10B7Fu)));
572 blocks.Add(new Block(BlockId.psalterPahlavi, "Psalter Pahlavi", "Psalter Pahlavi", cast<uchar>(0x10B80u), cast<uchar>(0x10BAFu)));
573 blocks.Add(new Block(BlockId.oldTurkic, "Old Turkic", "Old Turkic", cast<uchar>(0x10C00u), cast<uchar>(0x10C4Fu)));
574 blocks.Add(new Block(BlockId.oldHungarian, "Old Hungarian", "Old Hungarian", cast<uchar>(0x10C80u), cast<uchar>(0x10CFFu)));
575 blocks.Add(new Block(BlockId.hanifiRohingya, "Hanifi Rohingya", "Hanifi Rohingya", cast<uchar>(0x10D00u), cast<uchar>(0x10D3Fu)));
576 blocks.Add(new Block(BlockId.rumi, "Rumi", "Rumi Numeral Symbols", cast<uchar>(0x10E60u), cast<uchar>(0x10E7Fu)));
577 blocks.Add(new Block(BlockId.oldSogdian, "Old Sogdian", "Old Sogdian", cast<uchar>(0x10F00u), cast<uchar>(0x10F2Fu)));
578 blocks.Add(new Block(BlockId.sogdian, "Sogdian", "Sogdian", cast<uchar>(0x10F30u), cast<uchar>(0x10F6Fu)));
579 blocks.Add(new Block(BlockId.elymaic, "Elymaic", "Elymaic", cast<uchar>(0x10FE0), cast<uchar>(0x10FFF)));
580 blocks.Add(new Block(BlockId.brahmi, "Brahmi", "Brahmi", cast<uchar>(0x11000u), cast<uchar>(0x1107Fu)));
581 blocks.Add(new Block(BlockId.kaithi, "Kaithi", "Kaithi", cast<uchar>(0x11080u), cast<uchar>(0x110CFu)));
582 blocks.Add(new Block(BlockId.soraSompeng, "Sora Sompeng", "Sora Sompeng", cast<uchar>(0x110D0u), cast<uchar>(0x110FFu)));
583 blocks.Add(new Block(BlockId.chakma, "Chakma", "Chakma", cast<uchar>(0x11100u), cast<uchar>(0x1114Fu)));
584 blocks.Add(new Block(BlockId.mahajani, "Mahajani", "Mahajani", cast<uchar>(0x11150u), cast<uchar>(0x1117Fu)));
585 blocks.Add(new Block(BlockId.sharada, "Sharada", "Sharada", cast<uchar>(0x11180u), cast<uchar>(0x111DFu)));
586 blocks.Add(new Block(BlockId.sinhalaArchaicNumbers, "Sinhala Archaic Numbers", "Sinhala Archaic Numbers", cast<uchar>(0x111E0u), cast<uchar>(0x111FFu)));
587 blocks.Add(new Block(BlockId.khojki, "Khojki", "Khojki", cast<uchar>(0x11200u), cast<uchar>(0x1124Fu)));
588 blocks.Add(new Block(BlockId.multani, "Multani", "Multani", cast<uchar>(0x11280u), cast<uchar>(0x112AFu)));
589 blocks.Add(new Block(BlockId.khudawadi, "Khudawadi", "Khudawadi", cast<uchar>(0x112B0u), cast<uchar>(0x112FFu)));
590 blocks.Add(new Block(BlockId.grantha, "Grantha", "Grantha", cast<uchar>(0x11300u), cast<uchar>(0x1137Fu)));
591 blocks.Add(new Block(BlockId.newa, "Newa", "Newa", cast<uchar>(0x11400u), cast<uchar>(0x1147Fu)));
592 blocks.Add(new Block(BlockId.tirhuta, "Tirhuta", "Tirhuta", cast<uchar>(0x11480u), cast<uchar>(0x114DFu)));
593 blocks.Add(new Block(BlockId.siddham, "Siddham", "Siddham", cast<uchar>(0x11580u), cast<uchar>(0x115FFu)));
594 blocks.Add(new Block(BlockId.modi, "Modi", "Modi", cast<uchar>(0x11600u), cast<uchar>(0x1165Fu)));
595 blocks.Add(new Block(BlockId.mongolianSup, "Mongolian Sup", "Mongolian Supplement", cast<uchar>(0x11660u), cast<uchar>(0x1167Fu)));
596 blocks.Add(new Block(BlockId.takri, "Takri", "Takri", cast<uchar>(0x11680u), cast<uchar>(0x116CFu)));
597 blocks.Add(new Block(BlockId.ahom, "Ahom", "Ahom", cast<uchar>(0x11700u), cast<uchar>(0x1173Fu)));
598 blocks.Add(new Block(BlockId.dogra, "Dogra", "Dogra", cast<uchar>(0x11800u), cast<uchar>(0x1184Fu)));
599 blocks.Add(new Block(BlockId.warangCiti, "Warang Citi", "Warang Citi", cast<uchar>(0x118A0u), cast<uchar>(0x118FFu)));
600 blocks.Add(new Block(BlockId.nandinagari, "Nandinagari", "Nandinagari", cast<uchar>(0x119A0), cast<uchar>(0x119FF)));
601 blocks.Add(new Block(BlockId.zanabazarSquare, "Zanabazar Square", "Zanabazar Square", cast<uchar>(0x11A00u), cast<uchar>(0x11A4FFu)));
602 blocks.Add(new Block(BlockId.soyombo, "Soyombo", "Soyombo", cast<uchar>(0x11A50u), cast<uchar>(0x11AAFu)));
603 blocks.Add(new Block(BlockId.pauCinHau, "Pau Cin Hau", "Pau Cin Hau", cast<uchar>(0x11AC0u), cast<uchar>(0x11AFFu)));
604 blocks.Add(new Block(BlockId.bhaisuki, "Bhaiksuki", "Bhaiksuki", cast<uchar>(0x11C00u), cast<uchar>(0x11C6Fu)));
605 blocks.Add(new Block(BlockId.marchen, "Marchen", "Marchen", cast<uchar>(0x11C70u), cast<uchar>(0x11CBFu)));
606 blocks.Add(new Block(BlockId.masaramGondi, "Masaram Gondi", "Masaram Gondi", cast<uchar>(0x11D00), cast<uchar>(0x11D5F)));
607 blocks.Add(new Block(BlockId.gunjalaGondi, "Gunjala Gondi", "Gunjala Gondi", cast<uchar>(0x11D60), cast<uchar>(0x11DAF)));
608 blocks.Add(new Block(BlockId.makasar, "Makasar", "Makasar", cast<uchar>(0x11EE0), cast<uchar>(0x11EFF)));
609 blocks.Add(new Block(BlockId.tamilSup, "Tamil Sup", "Tamil Sup", cast<uchar>(0x11FC0), cast<uchar>(0x11FFE)));
610 blocks.Add(new Block(BlockId.cuneiform, "Cuneiform", "Cuneiform", cast<uchar>(0x12000u), cast<uchar>(0x123FFu)));
611 blocks.Add(new Block(BlockId.cuneiformNumbers, "Cuneiform Numbers", "Cuneiform Numbers and Punctuation", cast<uchar>(0x12400u), cast<uchar>(0x1247Fu)));
612 blocks.Add(new Block(BlockId.earlyDynasticCuneiform, "Early Dynastic Cuneiform", "Early Dynastic Cuneiform", cast<uchar>(0x12480u), cast<uchar>(0x1254Fu)));
613 blocks.Add(new Block(BlockId.egyptianHieroglyphs, "Egyptian Hieroglyphs", "Egyptian Hieroglyphs", cast<uchar>(0x13000u), cast<uchar>(0x1342Fu)));
614 blocks.Add(new Block(BlockId.egyptianHieroglyphFormatControls, "Egyptian Hieroglyph Format Controls", "Egyptian Hieroglyph Format Controls", cast<uchar>(0x13430), cast<uchar>(0x1343F)));
615 blocks.Add(new Block(BlockId.anatolianHieroglyphs, "Anatolian Hieroglyphs", "Anatolian Hieroglyphs", cast<uchar>(0x14400u), cast<uchar>(0x1467Fu)));
616 blocks.Add(new Block(BlockId.bamumSup, "Bamum Sup", "Bamum Supplement", cast<uchar>(0x16800u), cast<uchar>(0x16A3Fu)));
617 blocks.Add(new Block(BlockId.mro, "Mro", "Mro", cast<uchar>(0x16A40u), cast<uchar>(0x16A6Fu)));
618 blocks.Add(new Block(BlockId.bassaVah, "Bassa Vah", "Bassa Vah", cast<uchar>(0x16AD0u), cast<uchar>(0x16AFFu)));
619 blocks.Add(new Block(BlockId.pahawhHmong, "Pahawh Hmong", "Pahawh Hmong", cast<uchar>(0x16B00u), cast<uchar>(0x16B8Fu)));
620 blocks.Add(new Block(BlockId.medefaidrin, "Medefaidrin", "Medefaidrin", cast<uchar>(0x16E40u), cast<uchar>(0x16E9Fu)));
621 blocks.Add(new Block(BlockId.miao, "Miao", "Miao", cast<uchar>(0x16F00u), cast<uchar>(0x16F9Fu)));
622 blocks.Add(new Block(BlockId.ideographicSymbols, "Ideographic Symbols", "Ideographic Symbols and Punctuation", cast<uchar>(0x16FE0u), cast<uchar>(0x16FFFu)));
623 blocks.Add(new Block(BlockId.tangut, "Tangut", "Tangut", cast<uchar>(0x17000u), cast<uchar>(0x187FFu)));
624 blocks.Add(new Block(BlockId.tangutComponents, "Tangut Components", "Tangut Components", cast<uchar>(0x18800u), cast<uchar>(0x18AFFu)));
625 blocks.Add(new Block(BlockId.kanaSup, "Kana Sup", "Kana Supplement", cast<uchar>(0x1B000u), cast<uchar>(0x1B0FFu)));
626 blocks.Add(new Block(BlockId.kanaExtA, "Kana Ext A", "Kana Extended-A", cast<uchar>(0x1B100u), cast<uchar>(0x1B12Fu)));
627 blocks.Add(new Block(BlockId.smallKanaExt, "Small Kana Ext", "Small Kana Extension", cast<uchar>(0x1B130), cast<uchar>(0x1B16F)));
628 blocks.Add(new Block(BlockId.nushu, "Nushu", "Nushu", cast<uchar>(0x1B170u), cast<uchar>(0x1B2FFu)));
629 blocks.Add(new Block(BlockId.duployan, "Duployan", "Duployan", cast<uchar>(0x1BC00u), cast<uchar>(0x1BC9Fu)));
630 blocks.Add(new Block(BlockId.shorthandFormatControls, "Shorthand Format Controls", "Shorthand Format Controls", cast<uchar>(0x1BCA0u), cast<uchar>(0x1BCAFu)));
631 blocks.Add(new Block(BlockId.byzantineMusic, "Byzantine Music", "Byzantine Musical Symbols", cast<uchar>(0x1D000u), cast<uchar>(0x1D0FFu)));
632 blocks.Add(new Block(BlockId.music, "Music", "Musical Symbols", cast<uchar>(0x1D100u), cast<uchar>(0x1D1FFu)));
633 blocks.Add(new Block(BlockId.ancientGreekMusic, "Ancient Greek Music", "Ancient Greek Musical Notation", cast<uchar>(0x1D200u), cast<uchar>(0x1D24Fu)));
634 blocks.Add(new Block(BlockId.mayanNumerals, "Mayan Numerals", "Mayan Numerals", cast<uchar>(0x1D2E0u), cast<uchar>(0x1D2FFu)));
635 blocks.Add(new Block(BlockId.taiXuanJing, "Tai Xuan Jing", "Tai Xuan Jing Symbols", cast<uchar>(0x1D300u), cast<uchar>(0x1D35Fu)));
636 blocks.Add(new Block(BlockId.countingRod, "Counting Rod", "Counting Rod Numerals", cast<uchar>(0x1D360u), cast<uchar>(0x1D37Fu)));
637 blocks.Add(new Block(BlockId.mathAlphanum, "Math Alphanum", "Mathematical Alphanumeric Symbols", cast<uchar>(0x1D400u), cast<uchar>(0x1D7FFu)));
638 blocks.Add(new Block(BlockId.suttonSignWriting, "Sutton SignWriting", "Sutton SignWriting", cast<uchar>(0x1D800u), cast<uchar>(0x1DAAFu)));
639 blocks.Add(new Block(BlockId.glagoliticSup, "Glagolitic Sup", "Glagolitic Supplement", cast<uchar>(0x1E000u), cast<uchar>(0x1E02Fu)));
640 blocks.Add(new Block(BlockId.nyiakengPuachueHmong, "Nyiakeng Puachue Hmong", "Nyiakeng Puachue Hmong", cast<uchar>(0x1E100), cast<uchar>(0x1E14F)));
641 blocks.Add(new Block(BlockId.wancho, "Wancho", "Wancho", cast<uchar>(0x1E2C0), cast<uchar>(0x1E2FF)));
642 blocks.Add(new Block(BlockId.mendeKikakui, "Mende Kikakui", "Mende Kikakui", cast<uchar>(0x1E800u), cast<uchar>(0x1E8DFu)));
643 blocks.Add(new Block(BlockId.adlam, "Adlam", "Adlam", cast<uchar>(0x1E900u), cast<uchar>(0x1E95Fu)));
644 blocks.Add(new Block(BlockId.indicSiyaqNumbers, "Indic Siyaq Numbers", "Indic Siyaq Numbers", cast<uchar>(0x1EC70), cast<uchar>(0x1ECBF)));
645 blocks.Add(new Block(BlockId.ottomanSiyaqNumbers, "Ottoman Siyaq Numbers", "Ottoman Siyaq Numbers", cast<uchar>(0x1ED00), cast<uchar>(0x1ED4F)));
646 blocks.Add(new Block(BlockId.arabicMath, "Arabic Math", "Arabic Mathematical Alphabetic Symbols", cast<uchar>(0x1EE00u), cast<uchar>(0x1EEFFu)));
647 blocks.Add(new Block(BlockId.mahjong, "Mahjong", "Mahjong Tiles", cast<uchar>(0x1F000u), cast<uchar>(0x1F02Fu)));
648 blocks.Add(new Block(BlockId.domino, "Domino", "Domino Tiles", cast<uchar>(0x1F030u), cast<uchar>(0x1F09Fu)));
649 blocks.Add(new Block(BlockId.playingCards, "Playing Cards", "Playing Cards", cast<uchar>(0x1F0A0u), cast<uchar>(0x1F0FFu)));
650 blocks.Add(new Block(BlockId.enclosedAlphanumSup, "Enclosed Alphanum Sup", "Enclosed Alphanumeric Supplement", cast<uchar>(0x1F100u), cast<uchar>(0x1F1FFu)));
651 blocks.Add(new Block(BlockId.enclosedIdeographicSup, "Enclosed Ideographic Sup", "Enclosed Ideographic Supplement", cast<uchar>(0x1F200u), cast<uchar>(0x1F2FFu)));
652 blocks.Add(new Block(BlockId.miscPictographs, "Misc Pictographs", "Miscellaneous Symbols and Pictographs", cast<uchar>(0x1F300u), cast<uchar>(0x1F5FFu)));
653 blocks.Add(new Block(BlockId.emoticons, "Emoticons", "Emoticons", cast<uchar>(0x1F600u), cast<uchar>(0x1F64Fu)));
654 blocks.Add(new Block(BlockId.ornamentalDingbats, "Ornamental Dingbats", "Ornamental Dingbats", cast<uchar>(0x1F650u), cast<uchar>(0x1F67Fu)));
655 blocks.Add(new Block(BlockId.transportAndMap, "Transport And Map", "Transport and Map Symbols", cast<uchar>(0x1F680u), cast<uchar>(0x1F6FFu)));
656 blocks.Add(new Block(BlockId.alchemical, "Alchemical", "Alchemical Symbols", cast<uchar>(0x1F700u), cast<uchar>(0x1F77Fu)));
657 blocks.Add(new Block(BlockId.geometricShapesExt, "Geometric Shapes Ext", "Geometric Shapes Extended", cast<uchar>(0x1F780u), cast<uchar>(0x1F7FFu)));
658 blocks.Add(new Block(BlockId.supArrowsC, "Sup Arrows C", "Supplemental Arrows-C", cast<uchar>(0x1F800u), cast<uchar>(0x1F8FFu)));
659 blocks.Add(new Block(BlockId.supSymbolsAndPictographs, "Sup Symbols And Pictographs", "Supplemental Symbols and Pictographs", cast<uchar>(0x1F900u), cast<uchar>(0x1F9FFu)));
660 blocks.Add(new Block(BlockId.chessSymbols, "Chess Symbols", "Chess Symbols", cast<uchar>(0x1FA00u), cast<uchar>(0x1FA6Fu)));
661 blocks.Add(new Block(BlockId.symbolsAndPictographsExtA, "Symbols And Pictographs Ext A", "Symbols And Pictographs Extended A", cast<uchar>(0x1FA70), cast<uchar>(0x1FAFF)));
662 blocks.Add(new Block(BlockId.cjkExtB, "CJK Ext B", "CJK Unified Ideographs Extension B", cast<uchar>(0x20000u), cast<uchar>(0x2A6DFu)));
663 blocks.Add(new Block(BlockId.cjkExtC, "CJK Ext C", "CJK Unified Ideographs Extension C", cast<uchar>(0x2A700u), cast<uchar>(0x2B73Fu)));
664 blocks.Add(new Block(BlockId.cjkExtD, "CJK Ext D", "CJK Unified Ideographs Extension D", cast<uchar>(0x2B740u), cast<uchar>(0x2B81Fu)));
665 blocks.Add(new Block(BlockId.cjkExtE, "CJK Ext E", "CJK Unified Ideographs Extension E", cast<uchar>(0x2B820u), cast<uchar>(0x2CEAFu)));
666 blocks.Add(new Block(BlockId.cjkExtF, "CJK Ext F", "CJK Unified Ideographs Extension F", cast<uchar>(0x2CEB0u), cast<uchar>(0x2EBEFu)));
667 blocks.Add(new Block(BlockId.cjkCompatIdeographsSup, "CJK Compat Ideographs Sup", "CJK Compatibility Ideographs Supplement", cast<uchar>(0x2F800u), cast<uchar>(0x2FA1Fu)));
668 blocks.Add(new Block(BlockId.tags, "Tags", "Tags", cast<uchar>(0xE0000u), cast<uchar>(0xE007Fu)));
669 blocks.Add(new Block(BlockId.vsSup, "VS Sup", "Variation Selectors Supplement", cast<uchar>(0xE0100u), cast<uchar>(0xE01EFu)));
670 blocks.Add(new Block(BlockId.supPuaA, "Sup PUA A", "Supplementary Private Use Area-A", cast<uchar>(0xF0000u), cast<uchar>(0xFFFFFu)));
671 blocks.Add(new Block(BlockId.supPuaB, "Sup PUA B", "Supplementary Private Use Area-B", cast<uchar>(0x100000u), cast<uchar>(0x10FFFFu)));
672 for (Block* block : blocks)
673 {
674 blockIdMap[cast<uint>(cast<ushort>(block->Id()))] = block;
675 shortNameMap[MakeCanonicalPropertyName(block->ShortName())] = block;
676 longNameMap[MakeCanonicalPropertyName(block->LongName())] = block;
677 }
678 }
679 public ~BlockTable()
680 {
681 for (Block* block : blocks)
682 {
683 delete block;
684 }
685 }
686 private static UniquePtr<BlockTable> instance;
687 private List<Block*> blocks;
688 private HashMap<uint, void*> blockIdMap;
689 private HashMap<string, void*> shortNameMap;
690 private HashMap<string, void*> longNameMap;
691 }
692
693 public const Block* GetBlock(BlockId id)
694 {
695 return BlockTable.Instance().GetBlock(id);
696 }
697
698 public const Block* GetBlockByShortName(const string& shortName)
699 {
700 return BlockTable.Instance().GetBlockByShortName(shortName);
701 }
702
703 public const Block* GetBlockByLongName(const string& longName)
704 {
705 return BlockTable.Instance().GetBlockByLongName(longName);
706 }
707
708 public enum GeneralCategoryId : uint
709 {
710 none = 0u,
711 Lu = 1u << 0u, Ll = 1u << 1u, Lt = 1u << 2u, Lm = 1u << 3u, Lo = 1u << 4u,
712 LC = Lu | Ll | Lt,
713 L = Lu | Ll | Lt | Lm | Lo,
714 Mn = 1u << 5u, Mc = 1u << 6u, Me = 1u << 7u,
715 M = Mn | Mc | Me,
716 Nd = 1u << 8u, Nl = 1u << 9u, No = 1u << 10u,
717 N = Nd | Nl | No,
718 Pc = 1u << 11u, Pd = 1u << 12u, Ps = 1u << 13u, Pe = 1u << 14u, Pi = 1u << 15u, Pf = 1u << 16u, Po = 1u << 17u,
719 P = Pc | Pd | Ps | Pe | Pi | Pf | Po,
720 Sm = 1u << 18u, Sc = 1u << 19u, Sk = 1u << 20u, So = 1u << 21u,
721 S = Sm | Sc | Sk | So,
722 Zs = 1u << 22u, Zl = 1u << 23u, Zp = 1u << 24u,
723 Z = Zs | Zl | Zp,
724 Cc = 1u << 25u, Cf = 1u << 26u, Cs = 1u << 27u, Co = 1u << 28u, Cn = 1u << 29u,
725 C = Cc | Cf | Cs | Co | Cn,
726 G = L | M | N | P | S | Zs,
727 B = L | N | P | S | Zs
728 }
729
730 public class GeneralCategory
731 {
732 public nothrow GeneralCategory(GeneralCategoryId id_, const string& shortName_, const string& longName_) : id(id_), shortName(shortName_), longName(longName_)
733 {
734 }
735 public inline nothrow GeneralCategoryId Id()
736 {
737 return id;
738 }
739 public inline nothrow const string& ShortName()
740 {
741 return shortName;
742 }
743 public inline nothrow const string& LongName()
744 {
745 return longName;
746 }
747 private GeneralCategoryId id;
748 private string shortName;
749 private string longName;
750 }
751
752 public class GeneralCategoryTable
753 {
754 static GeneralCategoryTable() : instance(new GeneralCategoryTable())
755 {
756 }
757 public static GeneralCategoryTable& Instance()
758 {
759 return *instance;
760 }
761 public nothrow const GeneralCategory* GetGeneralCategory(GeneralCategoryId id) const
762 {
763 HashMap<uint, void*>.ConstIterator it = generalCategoryIdMap.CFind(cast<uint>(id));
764 if (it != generalCategoryIdMap.CEnd())
765 {
766 return cast<GeneralCategory*>(it->second);
767 }
768 return null;
769 }
770 public const GeneralCategory* GetGeneralCategoryByShortName(const string& shortName) const
771 {
772 HashMap<string, void*>.ConstIterator it = shortNameMap.CFind(MakeCanonicalPropertyName(shortName));
773 if (it != shortNameMap.CEnd())
774 {
775 return cast<GeneralCategory*>(it->second);
776 }
777 return null;
778 }
779 public const GeneralCategory* GetGeneralCategoryByLongName(const string& longName) const
780 {
781 HashMap<string, void*>.ConstIterator it = longNameMap.CFind(MakeCanonicalPropertyName(longName));
782 if (it != longNameMap.CEnd())
783 {
784 return cast<GeneralCategory*>(it->second);
785 }
786 return null;
787 }
788 private GeneralCategoryTable() : generalCategories(), generalCategoryIdMap(), shortNameMap(), longNameMap()
789 {
790 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Lu, "Lu", "Uppercase Letter"));
791 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Lu, "Ll", "Lowercase Letter"));
792 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Lt, "Lt", "Titlecase Letter"));
793 generalCategories.Add(new GeneralCategory(GeneralCategoryId.LC, "LC", "Cased Letter"));
794 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Lm, "Lm", "Modifier Letter"));
795 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Lo, "Lo", "Other Letter"));
796 generalCategories.Add(new GeneralCategory(GeneralCategoryId.L, "L", "Letter"));
797 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Mn, "Mn", "Nonspacing Mark"));
798 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Mc, "Mc", "Spacing Mark"));
799 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Me, "Me", "Enclosing Mark"));
800 generalCategories.Add(new GeneralCategory(GeneralCategoryId.M, "M", "Mark"));
801 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Nd, "Nd", "Decimal Number"));
802 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Nl, "Nl", "Letter Number"));
803 generalCategories.Add(new GeneralCategory(GeneralCategoryId.No, "No", "Other Number"));
804 generalCategories.Add(new GeneralCategory(GeneralCategoryId.N, "N", "Number"));
805 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Pc, "Pc", "Connector Punctuation"));
806 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Pd, "Pd", "Dash Punctuation"));
807 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Ps, "Ps", "Open Punctuation"));
808 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Pe, "Pe", "Close Punctuation"));
809 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Pi, "Pi", "Initial Punctuation"));
810 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Pf, "Pf", "Final Punctuation"));
811 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Po, "Po", "Other Punctuation"));
812 generalCategories.Add(new GeneralCategory(GeneralCategoryId.P, "P", "Punctuation"));
813 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Sm, "Sm", "Math Symbol"));
814 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Sc, "Sc", "Currency Symbol"));
815 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Sk, "Sk", "Modifier Symbol"));
816 generalCategories.Add(new GeneralCategory(GeneralCategoryId.So, "So", "Other Symbol"));
817 generalCategories.Add(new GeneralCategory(GeneralCategoryId.S, "S", "Symbol"));
818 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Zs, "Zs", "Space Separator"));
819 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Zl, "Zl", "Line Separator"));
820 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Zp, "Zp", "Paragraph Separator"));
821 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Z, "Z", "Separator"));
822 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Cc, "Cc", "Control"));
823 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Cf, "Cf", "Format"));
824 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Cs, "Cs", "Surrogate"));
825 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Co, "Co", "Private Use"));
826 generalCategories.Add(new GeneralCategory(GeneralCategoryId.Cn, "Cn", "Unassigned"));
827 generalCategories.Add(new GeneralCategory(GeneralCategoryId.C, "C", "Other"));
828 generalCategories.Add(new GeneralCategory(GeneralCategoryId.G, "G", "Graphic"));
829 generalCategories.Add(new GeneralCategory(GeneralCategoryId.B, "B", "Base"));
830 for (GeneralCategory* generalCategory : generalCategories)
831 {
832 generalCategoryIdMap[generalCategory->Id()] = generalCategory;
833 shortNameMap[MakeCanonicalPropertyName(generalCategory->ShortName())] = generalCategory;
834 longNameMap[MakeCanonicalPropertyName(generalCategory->LongName())] = generalCategory;
835 }
836 }
837 public ~GeneralCategoryTable()
838 {
839 for (GeneralCategory* generalCategory : generalCategories)
840 {
841 delete generalCategory;
842 }
843 }
844 private static UniquePtr<GeneralCategoryTable> instance;
845 private List<GeneralCategory*> generalCategories;
846 private HashMap<uint, void*> generalCategoryIdMap;
847 private HashMap<string, void*> shortNameMap;
848 private HashMap<string, void*> longNameMap;
849 }
850
851 public const GeneralCategory* GetGeneralCategory(GeneralCategoryId id)
852 {
853 return GeneralCategoryTable.Instance().GetGeneralCategory(id);
854 }
855
856 public const GeneralCategory* GetGeneralCategoryByShortName(const string& shortName)
857 {
858 return GeneralCategoryTable.Instance().GetGeneralCategoryByShortName(shortName);
859 }
860
861 public const GeneralCategory* GetGeneralCategoryByLongName(const string& longName)
862 {
863 return GeneralCategoryTable.Instance().GetGeneralCategoryByLongName(longName);
864 }
865
866 public enum AgeId : byte
867 {
868 age_unassigned = 0u,
869 age_1_1,
870 age_2_0, age_2_1,
871 age_3_0, age_3_1, age_3_2,
872 age_4_0, age_4_1,
873 age_5_0, age_5_1, age_5_2,
874 age_6_0, age_6_1, age_6_2, age_6_3,
875 age_7_0,
876 age_8_0,
877 age_9_0,
878 age_10_0,
879 age_11_0,
880 age_12_0, age_12_1
881 }
882
883 public class Age
884 {
885 public nothrow Age(AgeId id_, const string& version_) : id(id_), version(version_)
886 {
887 }
888 public inline nothrow AgeId Id() const
889 {
890 return id;
891 }
892 public inline nothrow const string& Version() const
893 {
894 return version;
895 }
896 private AgeId id;
897 private string version;
898 }
899
900 public class AgeTable
901 {
902 static AgeTable() : instance(new AgeTable())
903 {
904 }
905 public static AgeTable& Instance()
906 {
907 return *instance;
908 }
909 public const Age* GetAge(AgeId id) const
910 {
911 HashMap<uint, void*>.ConstIterator it = ageIdMap.CFind(cast<uint>(cast<byte>(id)));
912 if (it != ageIdMap.CEnd())
913 {
914 return cast<Age*>(it->second);
915 }
916 return null;
917 }
918 public const Age* GetAge(const string& version) const
919 {
920 HashMap<string, void*>.ConstIterator it = versionMap.CFind(version);
921 if (it != versionMap.CEnd())
922 {
923 return cast<Age*>(it->second);
924 }
925 return null;
926 }
927 private AgeTable() : ages(), ageIdMap(), versionMap()
928 {
929 ages.Add(new Age(AgeId.age_1_1, "1.1"));
930 ages.Add(new Age(AgeId.age_2_0, "2.0"));
931 ages.Add(new Age(AgeId.age_2_1, "2.1"));
932 ages.Add(new Age(AgeId.age_3_0, "3.0"));
933 ages.Add(new Age(AgeId.age_3_1, "3.1"));
934 ages.Add(new Age(AgeId.age_3_2, "3.2"));
935 ages.Add(new Age(AgeId.age_4_0, "4.0"));
936 ages.Add(new Age(AgeId.age_4_1, "4.1"));
937 ages.Add(new Age(AgeId.age_5_0, "5.0"));
938 ages.Add(new Age(AgeId.age_5_1, "5.1"));
939 ages.Add(new Age(AgeId.age_5_2, "5.2"));
940 ages.Add(new Age(AgeId.age_6_0, "6.0"));
941 ages.Add(new Age(AgeId.age_6_1, "6.1"));
942 ages.Add(new Age(AgeId.age_6_2, "6.2"));
943 ages.Add(new Age(AgeId.age_6_3, "6.3"));
944 ages.Add(new Age(AgeId.age_7_0, "7.0"));
945 ages.Add(new Age(AgeId.age_8_0, "8.0"));
946 ages.Add(new Age(AgeId.age_9_0, "9.0"));
947 ages.Add(new Age(AgeId.age_10_0, "10.0"));
948 ages.Add(new Age(AgeId.age_11_0, "11.0"));
949 ages.Add(new Age(AgeId.age_12_0, "12.0"));
950 ages.Add(new Age(AgeId.age_12_1, "12.1"));
951 for (Age* age : ages)
952 {
953 ageIdMap[cast<uint>(cast<byte>(age->Id()))] = age;
954 versionMap[age->Version()] = age;
955 }
956 }
957 public ~AgeTable()
958 {
959 for (Age* age : ages)
960 {
961 delete age;
962 }
963 }
964 private static UniquePtr<AgeTable> instance;
965 private List<Age*> ages;
966 private HashMap<uint, void*> ageIdMap;
967 private HashMap<string, void*> versionMap;
968 }
969
970 public const Age* GetAge(AgeId id)
971 {
972 return AgeTable.Instance().GetAge(id);
973 }
974
975 public const Age* GetAge(const string& version)
976 {
977 return AgeTable.Instance().GetAge(version);
978 }
979
980 public enum ScriptId : byte
981 {
982 none = 0u,
983 adlm, aghb, ahom, arab, armi, armn, avst,
984 bali, bamu, bass, batk, beng, bhks, bopo, brah, brai, bugi, buhd,
985 cakm, cans, cari, cham, cher, copt, cprt, cyrl,
986 deva, dogr, dsrt, dupl,
987 elba, elym, egyp, ethi,
988 geor, glag, gong, gonm, goth, gran, grek, gujr, guru,
989 hang, hani, hano, hatr, hebr, hira, hluw, hmng, hmnp, hrkt, hung,
990 ital,
991 java,
992 kali, kana, khar, khmr, khoj, knda, kthi,
993 lana, laoo, latn, lepc, limb, lina, linb, lisu, lyci, lydi,
994 mahj, maka, mand, mani, marc, medf, mend, merc, mero, mlym, modi, mong, mroo, mtei, mult, mymr,
995 nand, narb, nbat, newa, nkoo, nshu,
996 ogam, olck, orkh, orya, osge, osma,
997 palm, pauc, perm, phag, phli, phlp, phnx, plrd, prti,
998 qaai,
999 rjng, rohg, runr,
1000 samr, sarb, saur, sgnw, shaw, shrd, sidd, sind, sinh, sogd, sogo, sora, soyo, sund, sylo, syrc,
1001 tagb, takr, tale, talu, taml, tang, tavt, telu, tfng, tglg, thaa, thai, tibt, tirh,
1002 ugar,
1003 vaii,
1004 wara,
1005 wcho,
1006 xpeo, xsux,
1007 yiii, zanb,
1008 zinh, zyyy, zzzz
1009 }
1010
1011 public class Script
1012 {
1013 public nothrow Script(ScriptId id_, const string& shortName_, const string& longName_) : id(id_), shortName(shortName_), longName(longName_)
1014 {
1015 }
1016 public inline nothrow ScriptId Id() const
1017 {
1018 return id;
1019 }
1020 public inline nothrow const string& ShortName() const
1021 {
1022 return shortName;
1023 }
1024 public inline nothrow const string& LongName() const
1025 {
1026 return longName;
1027 }
1028 private ScriptId id;
1029 private string shortName;
1030 private string longName;
1031 }
1032
1033 public class ScriptTable
1034 {
1035 static ScriptTable() : instance(new ScriptTable())
1036 {
1037 }
1038 public static ScriptTable& Instance()
1039 {
1040 return *instance;
1041 }
1042 public const Script* GetScript(ScriptId id) const
1043 {
1044 HashMap<uint, void*>.ConstIterator it = scriptIdMap.CFind(cast<uint>(cast<byte>(id)));
1045 if (it != scriptIdMap.CEnd())
1046 {
1047 return cast<Script*>(it->second);
1048 }
1049 return null;
1050 }
1051 public const Script* GetScriptByShortName(const string& shortName) const
1052 {
1053 HashMap<string, void*>.ConstIterator it = shortNameMap.CFind(MakeCanonicalPropertyName(shortName));
1054 if (it != shortNameMap.CEnd())
1055 {
1056 return cast<Script*>(it->second);
1057 }
1058 return null;
1059 }
1060 public const Script* GetScriptByLongName(const string& longName) const
1061 {
1062 HashMap<string, void*>.ConstIterator it = longNameMap.CFind(MakeCanonicalPropertyName(longName));
1063 if (it != longNameMap.CEnd())
1064 {
1065 return cast<Script*>(it->second);
1066 }
1067 return null;
1068 }
1069 private ScriptTable() : scripts(), scriptIdMap(), shortNameMap(), longNameMap()
1070 {
1071 scripts.Add(new Script(ScriptId.adlm, "Adlm", "Adlam"));
1072 scripts.Add(new Script(ScriptId.aghb, "Aghb", "Caucasian Albanian"));
1073 scripts.Add(new Script(ScriptId.ahom, "Ahom", "Ahom"));
1074 scripts.Add(new Script(ScriptId.arab, "Arab", "Arabic"));
1075 scripts.Add(new Script(ScriptId.armi, "Armi", "Imperial Aramaic"));
1076 scripts.Add(new Script(ScriptId.armn, "Armn", "Armenian"));
1077 scripts.Add(new Script(ScriptId.avst, "Avst", "Avestan"));
1078 scripts.Add(new Script(ScriptId.bali, "Bali", "Balinese"));
1079 scripts.Add(new Script(ScriptId.bamu, "Bamu", "Bamum"));
1080 scripts.Add(new Script(ScriptId.bass, "Bass", "Bassa Vah"));
1081 scripts.Add(new Script(ScriptId.batk, "Batk", "Batak"));
1082 scripts.Add(new Script(ScriptId.beng, "Beng", "Bengali"));
1083 scripts.Add(new Script(ScriptId.bhks, "Bhks", "Bhaisuki"));
1084 scripts.Add(new Script(ScriptId.bopo, "Bopo", "Bopomofo"));
1085 scripts.Add(new Script(ScriptId.brah, "Brah", "Brahmi"));
1086 scripts.Add(new Script(ScriptId.brai, "Brai", "Braille"));
1087 scripts.Add(new Script(ScriptId.bugi, "Bugi", "Buginese"));
1088 scripts.Add(new Script(ScriptId.buhd, "Buhd", "Buhid"));
1089 scripts.Add(new Script(ScriptId.cakm, "Cakm", "Chakma"));
1090 scripts.Add(new Script(ScriptId.cans, "Cans", "Canadian Aboriginal"));
1091 scripts.Add(new Script(ScriptId.cari, "Cari", "Carian"));
1092 scripts.Add(new Script(ScriptId.cham, "Cham", "Cham"));
1093 scripts.Add(new Script(ScriptId.cher, "Cher", "Cherokee"));
1094 scripts.Add(new Script(ScriptId.copt, "Copt", "Coptic"));
1095 scripts.Add(new Script(ScriptId.cprt, "Cprt", "Cypriot"));
1096 scripts.Add(new Script(ScriptId.cyrl, "Cyrl", "Cyrillic"));
1097 scripts.Add(new Script(ScriptId.deva, "Deva", "Devanagari"));
1098 scripts.Add(new Script(ScriptId.dogr, "Dogr", "Dogra"));
1099 scripts.Add(new Script(ScriptId.dsrt, "Dsrt", "Deseret"));
1100 scripts.Add(new Script(ScriptId.dupl, "Dupl", "Duployan"));
1101 scripts.Add(new Script(ScriptId.egyp, "Egyp", "Egyptian Hieroglyphs"));
1102 scripts.Add(new Script(ScriptId.elba, "Elba", "Elbasan"));
1103 scripts.Add(new Script(ScriptId.elym, "Elym", "Elymaic"));
1104 scripts.Add(new Script(ScriptId.ethi, "Ethi", "Ethiopian"));
1105 scripts.Add(new Script(ScriptId.geor, "Geor", "Georgian"));
1106 scripts.Add(new Script(ScriptId.glag, "Glag", "Glagolitic"));
1107 scripts.Add(new Script(ScriptId.gong, "Gong", "Gunjala Gondi"));
1108 scripts.Add(new Script(ScriptId.gonm, "Gonm", "Masaram Gondi"));
1109 scripts.Add(new Script(ScriptId.goth, "Goth", "Gothic"));
1110 scripts.Add(new Script(ScriptId.gran, "Gran", "Grantha"));
1111 scripts.Add(new Script(ScriptId.grek, "Grek", "Greek"));
1112 scripts.Add(new Script(ScriptId.gujr, "Gujr", "Gujarati"));
1113 scripts.Add(new Script(ScriptId.guru, "Guru", "Gurmukhi"));
1114 scripts.Add(new Script(ScriptId.hang, "Hang", "Hangul"));
1115 scripts.Add(new Script(ScriptId.hani, "Hani", "Han"));
1116 scripts.Add(new Script(ScriptId.hano, "Hano", "Hanunoo"));
1117 scripts.Add(new Script(ScriptId.hatr, "Hatr", "Hatran"));
1118 scripts.Add(new Script(ScriptId.hebr, "Hebr", "Hebrew"));
1119 scripts.Add(new Script(ScriptId.hira, "Hira", "Hiragana"));
1120 scripts.Add(new Script(ScriptId.hluw, "Hluw", "Anatolian Hieroglyphs"));
1121 scripts.Add(new Script(ScriptId.hmng, "Hmng", "Pahawh Hmong"));
1122 scripts.Add(new Script(ScriptId.hmnp, "Hmnp", "Nyiakeng Puachue Hmong"));
1123 scripts.Add(new Script(ScriptId.hrkt, "Hrkt", "Katakana Or Hiragana"));
1124 scripts.Add(new Script(ScriptId.hung, "Hung", "Old Hungarian"));
1125 scripts.Add(new Script(ScriptId.ital, "Ital", "Old Italic"));
1126 scripts.Add(new Script(ScriptId.java, "Java", "Javanese"));
1127 scripts.Add(new Script(ScriptId.kali, "Kali", "Kayah Li"));
1128 scripts.Add(new Script(ScriptId.kana, "Kana", "Katakana"));
1129 scripts.Add(new Script(ScriptId.khar, "Khar", "Kharoshthi"));
1130 scripts.Add(new Script(ScriptId.khmr, "Khmr", "Khmer"));
1131 scripts.Add(new Script(ScriptId.khoj, "Khoj", "Khojki"));
1132 scripts.Add(new Script(ScriptId.knda, "Knda", "Kannada"));
1133 scripts.Add(new Script(ScriptId.kthi, "Kthi", "Kaithi"));
1134 scripts.Add(new Script(ScriptId.lana, "Lana", "Tai Tham"));
1135 scripts.Add(new Script(ScriptId.laoo, "Laoo", "Lao"));
1136 scripts.Add(new Script(ScriptId.latn, "Latn", "Latin"));
1137 scripts.Add(new Script(ScriptId.lepc, "Lepc", "Lepcha"));
1138 scripts.Add(new Script(ScriptId.limb, "Limb", "Limbu"));
1139 scripts.Add(new Script(ScriptId.lina, "Lina", "Linear A"));
1140 scripts.Add(new Script(ScriptId.linb, "Linb", "Linear B"));
1141 scripts.Add(new Script(ScriptId.lisu, "Lisu", "Lisu"));
1142 scripts.Add(new Script(ScriptId.lyci, "Lyci", "Lycian"));
1143 scripts.Add(new Script(ScriptId.lydi, "Lydi", "Lydian"));
1144 scripts.Add(new Script(ScriptId.mahj, "Mahj", "Mahajani"));
1145 scripts.Add(new Script(ScriptId.maka, "Maka", "Makasar"));
1146 scripts.Add(new Script(ScriptId.mand, "Mand", "Mandaic"));
1147 scripts.Add(new Script(ScriptId.mani, "Mani", "Manichaean"));
1148 scripts.Add(new Script(ScriptId.marc, "Marc", "Marchen"));
1149 scripts.Add(new Script(ScriptId.medf, "Medf", "Medefaidrin"));
1150 scripts.Add(new Script(ScriptId.mend, "Mend", "Mende Kikakui"));
1151 scripts.Add(new Script(ScriptId.merc, "Merc", "Meroitic Cursive"));
1152 scripts.Add(new Script(ScriptId.mero, "Mero", "Meroitic Hieroglyphs"));
1153 scripts.Add(new Script(ScriptId.mlym, "Mlym", "Malayalam"));
1154 scripts.Add(new Script(ScriptId.modi, "Modi", "Modi"));
1155 scripts.Add(new Script(ScriptId.mong, "Mong", "Mongolian"));
1156 scripts.Add(new Script(ScriptId.mroo, "Mroo", "Mro"));
1157 scripts.Add(new Script(ScriptId.mtei, "Mtei", "Meetei Mayak"));
1158 scripts.Add(new Script(ScriptId.mult, "Mult", "Multani"));
1159 scripts.Add(new Script(ScriptId.mymr, "Mymr", "Myanmar"));
1160 scripts.Add(new Script(ScriptId.nand, "Nand", "Nandinagari"));
1161 scripts.Add(new Script(ScriptId.narb, "Narb", "Old North Arabian"));
1162 scripts.Add(new Script(ScriptId.nbat, "Nbat", "Nabataean"));
1163 scripts.Add(new Script(ScriptId.newa, "Newa", "Newa"));
1164 scripts.Add(new Script(ScriptId.nkoo, "Nkoo", "Nko"));
1165 scripts.Add(new Script(ScriptId.nshu, "Nshu", "Nushu"));
1166 scripts.Add(new Script(ScriptId.ogam, "Ogam", "Ogham"));
1167 scripts.Add(new Script(ScriptId.olck, "Olck", "Ol Chiki"));
1168 scripts.Add(new Script(ScriptId.orkh, "Orkh", "Old Turkic"));
1169 scripts.Add(new Script(ScriptId.orya, "Orya", "Oriya"));
1170 scripts.Add(new Script(ScriptId.osge, "Osge", "Osage"));
1171 scripts.Add(new Script(ScriptId.osma, "Osma", "Osmanya"));
1172 scripts.Add(new Script(ScriptId.palm, "Palm", "Palmyrene"));
1173 scripts.Add(new Script(ScriptId.pauc, "Pauc", "Pau Cin Hau"));
1174 scripts.Add(new Script(ScriptId.perm, "Perm", "Old Permic"));
1175 scripts.Add(new Script(ScriptId.phag, "Phag", "Phags Pa"));
1176 scripts.Add(new Script(ScriptId.phli, "Phli", "Inscriptional Pahlavi"));
1177 scripts.Add(new Script(ScriptId.phlp, "Phlp", "Psalter Pahlavi"));
1178 scripts.Add(new Script(ScriptId.phnx, "Phnx", "Phoenician"));
1179 scripts.Add(new Script(ScriptId.plrd, "Plrd", "Miao"));
1180 scripts.Add(new Script(ScriptId.prti, "Prti", "Inscriptional Parthian"));
1181 scripts.Add(new Script(ScriptId.rjng, "Rjng", "Rejang"));
1182 scripts.Add(new Script(ScriptId.rohg, "Rohg", "Hanifi Rohingya"));
1183 scripts.Add(new Script(ScriptId.runr, "Runr", "Runic"));
1184 scripts.Add(new Script(ScriptId.samr, "Samr", "Samaritan"));
1185 scripts.Add(new Script(ScriptId.sarb, "Sarb", "Old South Arabian"));
1186 scripts.Add(new Script(ScriptId.saur, "Saur", "Saurashtra"));
1187 scripts.Add(new Script(ScriptId.sgnw, "Sgnw", "SignWriting"));
1188 scripts.Add(new Script(ScriptId.shaw, "Shaw", "Shawian"));
1189 scripts.Add(new Script(ScriptId.shrd, "Shrd", "Sharada"));
1190 scripts.Add(new Script(ScriptId.sidd, "Sidd", "Shiddham"));
1191 scripts.Add(new Script(ScriptId.sind, "Sind", "Khudawadi"));
1192 scripts.Add(new Script(ScriptId.sinh, "Sinh", "Sinhala"));
1193 scripts.Add(new Script(ScriptId.sogd, "Sogd", "Sogdian"));
1194 scripts.Add(new Script(ScriptId.sogo, "Sogo", "Old Sogdian"));
1195 scripts.Add(new Script(ScriptId.sora, "Sora", "Sora Sompeng"));
1196 scripts.Add(new Script(ScriptId.soyo, "Soyo", "Soyombo"));
1197 scripts.Add(new Script(ScriptId.sund, "Sund", "Sundanese"));
1198 scripts.Add(new Script(ScriptId.sylo, "Sylo", "Syloti Nagri"));
1199 scripts.Add(new Script(ScriptId.syrc, "Syrc", "Syriac"));
1200 scripts.Add(new Script(ScriptId.tagb, "Tagb", "Tagbanwa"));
1201 scripts.Add(new Script(ScriptId.takr, "Takr", "Takri"));
1202 scripts.Add(new Script(ScriptId.tale, "Tale", "Tai Le"));
1203 scripts.Add(new Script(ScriptId.talu, "Talu", "New Tai Lue"));
1204 scripts.Add(new Script(ScriptId.taml, "Taml", "Tamil"));
1205 scripts.Add(new Script(ScriptId.tang, "Tang", "Tangut"));
1206 scripts.Add(new Script(ScriptId.tavt, "Tavt", "Tai Viet"));
1207 scripts.Add(new Script(ScriptId.telu, "Telu", "Telugu"));
1208 scripts.Add(new Script(ScriptId.tfng, "Tfng", "Tifinag"));
1209 scripts.Add(new Script(ScriptId.tglg, "Tglg", "Tagalog"));
1210 scripts.Add(new Script(ScriptId.thaa, "Thaa", "Thaana"));
1211 scripts.Add(new Script(ScriptId.thai, "Thai", "Thai"));
1212 scripts.Add(new Script(ScriptId.tibt, "Tibt", "Tibetan"));
1213 scripts.Add(new Script(ScriptId.tirh, "Tirh", "Tirhuta"));
1214 scripts.Add(new Script(ScriptId.ugar, "Ugar", "Ugaritic"));
1215 scripts.Add(new Script(ScriptId.vaii, "Vaii", "Vai"));
1216 scripts.Add(new Script(ScriptId.wara, "Wara", "Warang Citi"));
1217 scripts.Add(new Script(ScriptId.wcho, "Wcho", "Wcho"));
1218 scripts.Add(new Script(ScriptId.xpeo, "Xpeo", "Old Persian"));
1219 scripts.Add(new Script(ScriptId.xsux, "Xsux", "Cuneiform"));
1220 scripts.Add(new Script(ScriptId.yiii, "Yiii", "Yi"));
1221 scripts.Add(new Script(ScriptId.zanb, "Zanb", "Zanabazar Square"));
1222 scripts.Add(new Script(ScriptId.zinh, "Zinh", "Inherited"));
1223 scripts.Add(new Script(ScriptId.zyyy, "Zyyy", "Common"));
1224 scripts.Add(new Script(ScriptId.zzzz, "Zzzz", "Unknown"));
1225 for (Script* script : scripts)
1226 {
1227 scriptIdMap[cast<uint>(cast<byte>(script->Id()))] = script;
1228 shortNameMap[MakeCanonicalPropertyName(script->ShortName())] = script;
1229 longNameMap[MakeCanonicalPropertyName(script->LongName())] = script;
1230 }
1231 }
1232 public ~ScriptTable()
1233 {
1234 for (Script* script : scripts)
1235 {
1236 delete script;
1237 }
1238 }
1239 private static UniquePtr<ScriptTable> instance;
1240 private List<Script*> scripts;
1241 private HashMap<uint, void*> scriptIdMap;
1242 private HashMap<string, void*> shortNameMap;
1243 private HashMap<string, void*> longNameMap;
1244 }
1245
1246 public const Script* GetScript(ScriptId id)
1247 {
1248 return ScriptTable.Instance().GetScript(id);
1249 }
1250
1251 public const Script* GetScriptByShortName(const string& shortName)
1252 {
1253 return ScriptTable.Instance().GetScriptByShortName(shortName);
1254 }
1255
1256 public const Script* GetScriptByLongName(const string& longName)
1257 {
1258 return ScriptTable.Instance().GetScriptByLongName(longName);
1259 }
1260
1261 public class CharacterInfo
1262 {
1263 public nothrow CharacterInfo() :
1264 binaryProperties(0u), generalCategory(GeneralCategoryId.none), upper(cast<uchar>(0u)), lower(cast<uchar>(0u)), title(cast<uchar>(0u)),
1265 folding(cast<uchar>(0u)), block(BlockId.none), age(AgeId.age_unassigned), script(ScriptId.none)
1266 {
1267 }
1268 public inline nothrow bool GetBinaryProperty(BinaryPropertyId binaryPropertyId) const
1269 {
1270 ulong mask = cast<ulong>(1u) << cast<ulong>(cast<byte>(binaryPropertyId));
1271 return (binaryProperties & mask) != 0u;
1272 }
1273 public inline nothrow bool HasGeneralCategory(GeneralCategoryId generalCategory_) const
1274 {
1275 return (generalCategory & generalCategory_) != GeneralCategoryId.none;
1276 }
1277 public inline nothrow GeneralCategoryId GeneralCategoryValue() const
1278 {
1279 return generalCategory;
1280 }
1281 public inline nothrow uchar Upper() const
1282 {
1283 return upper;
1284 }
1285 public inline nothrow uchar Lower() const
1286 {
1287 return lower;
1288 }
1289 public inline nothrow uchar Title() const
1290 {
1291 return title;
1292 }
1293 public inline nothrow uchar Folding() const
1294 {
1295 return folding;
1296 }
1297 public inline nothrow BlockId BlockValue() const
1298 {
1299 return block;
1300 }
1301 public inline nothrow AgeId AgeValue() const
1302 {
1303 return age;
1304 }
1305 public inline nothrow ScriptId ScriptValue() const
1306 {
1307 return script;
1308 }
1309 public void Read(BinaryReader& reader)
1310 {
1311 binaryProperties = reader.ReadULong();
1312 generalCategory = cast<GeneralCategoryId>(reader.ReadUInt());
1313 upper = reader.ReadUChar();
1314 lower = reader.ReadUChar();
1315 title = reader.ReadUChar();
1316 folding = reader.ReadUChar();
1317 block = cast<BlockId>(reader.ReadUShort());
1318 age = cast<AgeId>(reader.ReadByte());
1319 script = cast<ScriptId>(reader.ReadByte());
1320 }
1321 private ulong binaryProperties;
1322 private GeneralCategoryId generalCategory;
1323 private uchar upper;
1324 private uchar lower;
1325 private uchar title;
1326 private uchar folding;
1327 private BlockId block;
1328 private AgeId age;
1329 private ScriptId script;
1330 }
1331
1332 public const long numInfosInPage = 128;
1333 public const uint characterInfoSize = 32u;
1334 public const uint characterInfoPageSize = cast<uint>(numInfosInPage) * characterInfoSize;
1335
1336 public enum NumericTypeId : byte
1337 {
1338 none = 0u,
1339 de, di, nu
1340 }
1341
1342 public class NumericType
1343 {
1344 public nothrow NumericType(NumericTypeId id_, const string& shortName_, const string& longName_) : id(id_), shortName(shortName_), longName(longName_)
1345 {
1346 }
1347 public inline nothrow NumericTypeId Id() const
1348 {
1349 return id;
1350 }
1351 public inline nothrow const string& ShortName() const
1352 {
1353 return shortName;
1354 }
1355 public inline nothrow const string& LongName() const
1356 {
1357 return longName;
1358 }
1359 private NumericTypeId id;
1360 private string shortName;
1361 private string longName;
1362 }
1363
1364 public class NumericTypeTable
1365 {
1366 static NumericTypeTable() : instance(new NumericTypeTable())
1367 {
1368 }
1369 public static NumericTypeTable& Instance()
1370 {
1371 return *instance;
1372 }
1373 public const NumericType* GetNumericType(NumericTypeId id) const
1374 {
1375 HashMap<uint, void*>.ConstIterator it = numericTypeIdMap.CFind(cast<uint>(cast<byte>(id)));
1376 if (it != numericTypeIdMap.CEnd())
1377 {
1378 return cast<NumericType*>(it->second);
1379 }
1380 return null;
1381 }
1382 public const NumericType* GetNumericTypeByShortName(const string& shortName) const
1383 {
1384 HashMap<string, void*>.ConstIterator it = shortNameMap.CFind(MakeCanonicalPropertyName(shortName));
1385 if (it != shortNameMap.CEnd())
1386 {
1387 return cast<NumericType*>(it->second);
1388 }
1389 return null;
1390 }
1391 public const NumericType* GetNumericTypeByLongName(const string& longName) const
1392 {
1393 HashMap<string, void*>.ConstIterator it = longNameMap.CFind(MakeCanonicalPropertyName(longName));
1394 if (it != longNameMap.CEnd())
1395 {
1396 return cast<NumericType*>(it->second);
1397 }
1398 return null;
1399 }
1400 private NumericTypeTable() : numericTypes(), numericTypeIdMap(), shortNameMap(), longNameMap()
1401 {
1402 numericTypes.Add(new NumericType(NumericTypeId.none, "None", "None"));
1403 numericTypes.Add(new NumericType(NumericTypeId.de, "De", "Decimal"));
1404 numericTypes.Add(new NumericType(NumericTypeId.di, "Di", "Digit"));
1405 numericTypes.Add(new NumericType(NumericTypeId.nu, "Nu", "Numeric"));
1406 for (NumericType* numericType : numericTypes)
1407 {
1408 numericTypeIdMap[cast<uint>(cast<byte>(numericType->Id()))] = numericType;
1409 shortNameMap[MakeCanonicalPropertyName(numericType->ShortName())] = numericType;
1410 longNameMap[MakeCanonicalPropertyName(numericType->LongName())] = numericType;
1411 }
1412 }
1413 public ~NumericTypeTable()
1414 {
1415 for (NumericType* numericType : numericTypes)
1416 {
1417 delete numericType;
1418 }
1419 }
1420 private List<NumericType*> numericTypes;
1421 private HashMap<uint, void*> numericTypeIdMap;
1422 private HashMap<string, void*> shortNameMap;
1423 private HashMap<string, void*> longNameMap;
1424 private static UniquePtr<NumericTypeTable> instance;
1425 }
1426
1427 public const NumericType* GetNumericType(NumericTypeId id)
1428 {
1429 return NumericTypeTable.Instance().GetNumericType(id);
1430 }
1431
1432 public const NumericType* GetNumericTypeByShortName(const string& shortName)
1433 {
1434 return NumericTypeTable.Instance().GetNumericTypeByShortName(shortName);
1435 }
1436
1437 public const NumericType* GetNumericTypeByLongName(const string& longName)
1438 {
1439 return NumericTypeTable.Instance().GetNumericTypeByLongName(longName);
1440 }
1441
1442 public enum BidiClassId : byte
1443 {
1444 none = 0u,
1445 al, an, b, bn, cs, en, es, et, fsi, l, lre, lri, lro, nsm, on, pdf, pdi, r, rle, rli, rlo, s, ws
1446 }
1447
1448 public class BidiClass
1449 {
1450 public nothrow BidiClass(BidiClassId id_, const string& shortName_, const string& longName_) : id(id_), shortName(shortName_), longName(longName_)
1451 {
1452 }
1453 public inline nothrow BidiClassId Id() const
1454 {
1455 return id;
1456 }
1457 public inline nothrow const string& ShortName() const
1458 {
1459 return shortName;
1460 }
1461 public inline nothrow const string& LongName() const
1462 {
1463 return longName;
1464 }
1465 private BidiClassId id;
1466 private string shortName;
1467 private string longName;
1468 }
1469
1470 public class BidiClassTable
1471 {
1472 static BidiClassTable() : instance(new BidiClassTable())
1473 {
1474 }
1475 public static BidiClassTable& Instance()
1476 {
1477 return *instance;
1478 }
1479 public const BidiClass* GetBidiClass(BidiClassId id) const
1480 {
1481 HashMap<uint, void*>.ConstIterator it = bidiClassIdMap.CFind(cast<uint>(cast<byte>(id)));
1482 if (it != bidiClassIdMap.CEnd())
1483 {
1484 return cast<BidiClass*>(it->second);
1485 }
1486 return null;
1487 }
1488 public const BidiClass* GetBidiClassByShortName(const string& shortName) const
1489 {
1490 HashMap<string, void*>.ConstIterator it = shortNameMap.CFind(MakeCanonicalPropertyName(shortName));
1491 if (it != shortNameMap.CEnd())
1492 {
1493 return cast<BidiClass*>(it->second);
1494 }
1495 return null;
1496 }
1497 public const BidiClass* GetBidiClassByLongName(const string& longName) const
1498 {
1499 HashMap<string, void*>.ConstIterator it = longNameMap.CFind(MakeCanonicalPropertyName(longName));
1500 if (it != longNameMap.CEnd())
1501 {
1502 return cast<BidiClass*>(it->second);
1503 }
1504 return null;
1505 }
1506 private BidiClassTable() : bidiClasses(), bidiClassIdMap(), shortNameMap(), longNameMap()
1507 {
1508 bidiClasses.Add(new BidiClass(BidiClassId.al, "AL", "Arabic Letter"));
1509 bidiClasses.Add(new BidiClass(BidiClassId.an, "AN", "Arabic Number"));
1510 bidiClasses.Add(new BidiClass(BidiClassId.b, "B", "Paragraph Separator"));
1511 bidiClasses.Add(new BidiClass(BidiClassId.bn, "BN", "Boundary Neutral"));
1512 bidiClasses.Add(new BidiClass(BidiClassId.cs, "CS", "Common Separator"));
1513 bidiClasses.Add(new BidiClass(BidiClassId.en, "EN", "European Number"));
1514 bidiClasses.Add(new BidiClass(BidiClassId.es, "ES", "European Separator"));
1515 bidiClasses.Add(new BidiClass(BidiClassId.et, "ET", "European Terminator"));
1516 bidiClasses.Add(new BidiClass(BidiClassId.fsi, "FSI", "First Strong Isolate"));
1517 bidiClasses.Add(new BidiClass(BidiClassId.l, "L", "Left To Right"));
1518 bidiClasses.Add(new BidiClass(BidiClassId.lre, "LRE", "Left To Right Embedding"));
1519 bidiClasses.Add(new BidiClass(BidiClassId.lri, "LRI", "Left To Right Isolate"));
1520 bidiClasses.Add(new BidiClass(BidiClassId.lro, "LRO", "Left To Right Override"));
1521 bidiClasses.Add(new BidiClass(BidiClassId.nsm, "NSM", "Nonspacing Mark"));
1522 bidiClasses.Add(new BidiClass(BidiClassId.on, "ON", "Other Neutral"));
1523 bidiClasses.Add(new BidiClass(BidiClassId.pdf, "PDF", "Pop Directional Format"));
1524 bidiClasses.Add(new BidiClass(BidiClassId.pdi, "PDI", "Pop Directional Isolate"));
1525 bidiClasses.Add(new BidiClass(BidiClassId.r, "R", "Right To Left"));
1526 bidiClasses.Add(new BidiClass(BidiClassId.rle, "RLE", "Right To Left Embedding"));
1527 bidiClasses.Add(new BidiClass(BidiClassId.rli, "RLI", "Right To Left Isolate"));
1528 bidiClasses.Add(new BidiClass(BidiClassId.rlo, "RLO", "Right To Left Override"));
1529 bidiClasses.Add(new BidiClass(BidiClassId.s, "S", "Segment Separator"));
1530 bidiClasses.Add(new BidiClass(BidiClassId.ws, "WS", "White Space"));
1531 for (BidiClass* bidiClass : bidiClasses)
1532 {
1533 bidiClassIdMap[cast<uint>(cast<byte>(bidiClass->Id()))] = bidiClass;
1534 shortNameMap[MakeCanonicalPropertyName(bidiClass->ShortName())] = bidiClass;
1535 longNameMap[MakeCanonicalPropertyName(bidiClass->LongName())] = bidiClass;
1536 }
1537 }
1538 public ~BidiClassTable()
1539 {
1540 for (BidiClass* bidiClass : bidiClasses)
1541 {
1542 delete bidiClass;
1543 }
1544 }
1545 private static UniquePtr<BidiClassTable> instance;
1546 private List<BidiClass*> bidiClasses;
1547 private HashMap<uint, void*> bidiClassIdMap;
1548 private HashMap<string, void*> shortNameMap;
1549 private HashMap<string, void*> longNameMap;
1550 }
1551
1552 public const BidiClass* GetBidiClass(BidiClassId id)
1553 {
1554 return BidiClassTable.Instance().GetBidiClass(id);
1555 }
1556
1557 public const BidiClass* GetBidiClassByShortName(const string& shortName)
1558 {
1559 return BidiClassTable.Instance().GetBidiClassByShortName(shortName);
1560 }
1561
1562 public const BidiClass* GetBidiClassByLongName(const string& longName)
1563 {
1564 return BidiClassTable.Instance().GetBidiClassByLongName(longName);
1565 }
1566
1567 public enum BidiPairedBracketTypeId : byte
1568 {
1569 none = 0u,
1570 o, c
1571 }
1572
1573 public class BidiPairedBracketType
1574 {
1575 public nothrow BidiPairedBracketType(BidiPairedBracketTypeId id_, const string& shortName_, const string& longName_) :
1576 id(id_), shortName(shortName_), longName(longName_)
1577 {
1578 }
1579 public inline nothrow BidiPairedBracketTypeId Id() const
1580 {
1581 return id;
1582 }
1583 public inline nothrow const string& ShortName() const
1584 {
1585 return shortName;
1586 }
1587 public inline nothrow const string& LongName() const
1588 {
1589 return longName;
1590 }
1591 private BidiPairedBracketTypeId id;
1592 private string shortName;
1593 private string longName;
1594 }
1595
1596 public class BidiPairedBracketTypeTable
1597 {
1598 static BidiPairedBracketTypeTable() : instance(new BidiPairedBracketTypeTable())
1599 {
1600 }
1601 public static BidiPairedBracketTypeTable& Instance()
1602 {
1603 return *instance;
1604 }
1605 public const BidiPairedBracketType* GetBidiPairedBracketType(BidiPairedBracketTypeId id) const
1606 {
1607 HashMap<uint, void*>.ConstIterator it = bidiPairedBracketTypeIdMap.CFind(cast<uint>(cast<byte>(id)));
1608 if (it != bidiPairedBracketTypeIdMap.CEnd())
1609 {
1610 return cast<BidiPairedBracketType*>(it->second);
1611 }
1612 return null;
1613 }
1614 public const BidiPairedBracketType* GetBidiPairedBracketTypeByShortName(const string& shortName) const
1615 {
1616 HashMap<string, void*>.ConstIterator it = shortNameMap.CFind(MakeCanonicalPropertyName(shortName));
1617 if (it != shortNameMap.CEnd())
1618 {
1619 return cast<BidiPairedBracketType*>(it->second);
1620 }
1621 return null;
1622 }
1623 public const BidiPairedBracketType* GetBidiPairedBracketTypeByLongName(const string& longName) const
1624 {
1625 HashMap<string, void*>.ConstIterator it = longNameMap.CFind(longName);
1626 if (it != longNameMap.CEnd())
1627 {
1628 return cast<BidiPairedBracketType*>(it->second);
1629 }
1630 return null;
1631 }
1632 private BidiPairedBracketTypeTable() : bidiPairedBracketTypes(), bidiPairedBracketTypeIdMap(), shortNameMap(), longNameMap()
1633 {
1634 bidiPairedBracketTypes.Add(new BidiPairedBracketType(BidiPairedBracketTypeId.o, "O", "Open"));
1635 bidiPairedBracketTypes.Add(new BidiPairedBracketType(BidiPairedBracketTypeId.c, "C", "Close"));
1636 bidiPairedBracketTypes.Add(new BidiPairedBracketType(BidiPairedBracketTypeId.none, "N", "None"));
1637 for (BidiPairedBracketType* bidiPairedBracketType : bidiPairedBracketTypes)
1638 {
1639 bidiPairedBracketTypeIdMap[cast<uint>(cast<byte>(bidiPairedBracketType->Id()))] = bidiPairedBracketType;
1640 shortNameMap[MakeCanonicalPropertyName(bidiPairedBracketType->ShortName())] = bidiPairedBracketType;
1641 longNameMap[MakeCanonicalPropertyName(bidiPairedBracketType->LongName())] = bidiPairedBracketType;
1642 }
1643 }
1644 public ~BidiPairedBracketTypeTable()
1645 {
1646 for (BidiPairedBracketType* bidiPairedBracketType : bidiPairedBracketTypes)
1647 {
1648 delete bidiPairedBracketType;
1649 }
1650 }
1651 private static UniquePtr<BidiPairedBracketTypeTable> instance;
1652 private List<BidiPairedBracketType*> bidiPairedBracketTypes;
1653 private HashMap<uint, void*> bidiPairedBracketTypeIdMap;
1654 private HashMap<string, void*> shortNameMap;
1655 private HashMap<string, void*> longNameMap;
1656 }
1657
1658 public const BidiPairedBracketType* GetBidiPairedBracketType(BidiPairedBracketTypeId id)
1659 {
1660 return BidiPairedBracketTypeTable.Instance().GetBidiPairedBracketType(id);
1661 }
1662
1663 public const BidiPairedBracketType* GetBidiPairedBracketTypeByShortName(const string& shortName)
1664 {
1665 return BidiPairedBracketTypeTable.Instance().GetBidiPairedBracketTypeByShortName(shortName);
1666 }
1667
1668 public const BidiPairedBracketType* GetBidiPairedBracketTypeByLongName(const string& longName)
1669 {
1670 return BidiPairedBracketTypeTable.Instance().GetBidiPairedBracketTypeByLongName(longName);
1671 }
1672
1673 public enum AliasTypeId : byte
1674 {
1675 none = 0u,
1676 correction, control, alternate, figment, abbreviation
1677 }
1678
1679 public class AliasType
1680 {
1681 public nothrow AliasType(AliasTypeId id_, const string& name_) : id(id_), name(name_)
1682 {
1683 }
1684 public inline nothrow AliasTypeId Id() const
1685 {
1686 return id;
1687 }
1688 public inline nothrow const string& Name() const
1689 {
1690 return name;
1691 }
1692 private AliasTypeId id;
1693 private string name;
1694 }
1695
1696 public class AliasTypeTable
1697 {
1698 static AliasTypeTable() : instance(new AliasTypeTable())
1699 {
1700 }
1701 public static AliasTypeTable& Instance()
1702 {
1703 return *instance;
1704 }
1705 public const AliasType* GetAliasType(AliasTypeId id) const
1706 {
1707 HashMap<uint, void*>.ConstIterator it = aliasTypeIdMap.CFind(cast<uint>(cast<byte>(id)));
1708 if (it != aliasTypeIdMap.CEnd())
1709 {
1710 return cast<AliasType*>(it->second);
1711 }
1712 return null;
1713 }
1714 public const AliasType* GetAliasType(const string& name) const
1715 {
1716 HashMap<string, void*>.ConstIterator it = nameMap.CFind(name);
1717 if (it != nameMap.CEnd())
1718 {
1719 return cast<AliasType*>(it->second);
1720 }
1721 return null;
1722 }
1723 private AliasTypeTable() : aliasTypes(), aliasTypeIdMap(), nameMap()
1724 {
1725 aliasTypes.Add(new AliasType(AliasTypeId.abbreviation, "abbreviation"));
1726 aliasTypes.Add(new AliasType(AliasTypeId.alternate, "alternate"));
1727 aliasTypes.Add(new AliasType(AliasTypeId.control, "control"));
1728 aliasTypes.Add(new AliasType(AliasTypeId.correction, "correction"));
1729 aliasTypes.Add(new AliasType(AliasTypeId.figment, "figment"));
1730 for (AliasType* aliasType : aliasTypes)
1731 {
1732 aliasTypeIdMap[cast<uint>(cast<byte>(aliasType->Id()))] = aliasType;
1733 nameMap[aliasType->Name()] = aliasType;
1734 }
1735 }
1736 public ~AliasTypeTable()
1737 {
1738 for (AliasType* aliasType : aliasTypes)
1739 {
1740 delete aliasType;
1741 }
1742 }
1743 private static UniquePtr<AliasTypeTable> instance;
1744 private List<AliasType*> aliasTypes;
1745 private HashMap<uint, void*> aliasTypeIdMap;
1746 private HashMap<string, void*> nameMap;
1747 }
1748
1749 public const AliasType* GetAliasType(AliasTypeId id)
1750 {
1751 return AliasTypeTable.Instance().GetAliasType(id);
1752 }
1753
1754 public const AliasType* GetAliasType(const string& name)
1755 {
1756 return AliasTypeTable.Instance().GetAliasType(name);
1757 }
1758
1759 public class Alias
1760 {
1761 public nothrow Alias() : typeId(AliasTypeId.none), name()
1762 {
1763 }
1764 public nothrow Alias(AliasTypeId typeId_, const string& name_) : typeId(typeId_), name(name_)
1765 {
1766 }
1767 public inline nothrow AliasTypeId TypeId() const
1768 {
1769 return typeId;
1770 }
1771 public inline nothrow const string& Name() const
1772 {
1773 return name;
1774 }
1775 public void Read(BinaryReader& reader)
1776 {
1777 typeId = cast<AliasTypeId>(reader.ReadByte());
1778 name = reader.ReadString();
1779 }
1780 private AliasTypeId typeId;
1781 private string name;
1782 }
1783
1784 public class ExtendedCharacterInfo
1785 {
1786 public nothrow ExtendedCharacterInfo() :
1787 characterName(), unicode1Name(), canonicalCombiningClass(0u), fullUpper(), fullLower(), fullTitle(), fullFolding(), bidiClass(BidiClassId.none),
1788 numericType(NumericTypeId.none), numericValue(), aliases(), bidiMirroringGlyph(cast<uchar>(0u)), bidiPairedBracketType(BidiPairedBracketTypeId.none),
1789 bidiPairedBracket(cast<uchar>(0u))
1790 {
1791 }
1792 public inline nothrow const string& CharacterName() const
1793 {
1794 return characterName;
1795 }
1796 public inline nothrow const string& Unicode1Name() const
1797 {
1798 return unicode1Name;
1799 }
1800 public inline nothrow byte CanonicalCombiningClass() const
1801 {
1802 return canonicalCombiningClass;
1803 }
1804 public inline nothrow const ustring& FullUpper() const
1805 {
1806 return fullUpper;
1807 }
1808 public inline nothrow const ustring& FullLower() const
1809 {
1810 return fullLower;
1811 }
1812 public inline nothrow const ustring& FullTitle() const
1813 {
1814 return fullTitle;
1815 }
1816 public inline nothrow const ustring& FullFolding() const
1817 {
1818 return fullFolding;
1819 }
1820 public inline nothrow BidiClassId BidiClassValue() const
1821 {
1822 return bidiClass;
1823 }
1824 public inline nothrow NumericTypeId NumericTypeValue() const
1825 {
1826 return numericType;
1827 }
1828 public inline nothrow const ustring& NumericValue() const
1829 {
1830 return numericValue;
1831 }
1832 public inline nothrow const List<Alias>& Aliases() const
1833 {
1834 return aliases;
1835 }
1836 public inline nothrow uchar BidiMirroringGlyph() const
1837 {
1838 return bidiMirroringGlyph;
1839 }
1840 public inline nothrow BidiPairedBracketTypeId BidiPairedBracketTypeValue() const
1841 {
1842 return bidiPairedBracketType;
1843 }
1844 public inline nothrow uchar BidiPairedBracket()
1845 {
1846 return bidiPairedBracket;
1847 }
1848 public void Read(BinaryReader& reader)
1849 {
1850 characterName = reader.ReadString();
1851 unicode1Name = reader.ReadString();
1852 canonicalCombiningClass = reader.ReadByte();
1853 byte nu = reader.ReadByte();
1854 for (byte i = 0u; i < nu; ++i;)
1855 {
1856 fullUpper.Append(reader.ReadUChar());
1857 }
1858 byte nl = reader.ReadByte();
1859 for (byte i = 0u; i < nl; ++i;)
1860 {
1861 fullLower.Append(reader.ReadUChar());
1862 }
1863 byte nt = reader.ReadByte();
1864 for (byte i = 0u; i < nt; ++i;)
1865 {
1866 fullTitle.Append(reader.ReadUChar());
1867 }
1868 byte nf = reader.ReadByte();
1869 for (byte i = 0u; i < nf; ++i;)
1870 {
1871 fullFolding.Append(reader.ReadUChar());
1872 }
1873 bidiClass = cast<BidiClassId>(reader.ReadByte());
1874 numericType = cast<NumericTypeId>(reader.ReadByte());
1875 numericValue = reader.ReadUString();
1876 byte na = reader.ReadByte();
1877 for (byte i = 0u; i < na; ++i;)
1878 {
1879 Alias alias;
1880 alias.Read(reader);
1881 aliases.Add(alias);
1882 }
1883 bidiMirroringGlyph = reader.ReadUChar();
1884 bidiPairedBracketType = cast<BidiPairedBracketTypeId>(reader.ReadByte());
1885 bidiPairedBracket = reader.ReadUChar();
1886 }
1887 private string characterName;
1888 private string unicode1Name;
1889 private byte canonicalCombiningClass;
1890 private ustring fullUpper;
1891 private ustring fullLower;
1892 private ustring fullTitle;
1893 private ustring fullFolding;
1894 private BidiClassId bidiClass;
1895 private NumericTypeId numericType;
1896 private ustring numericValue;
1897 private List<Alias> aliases;
1898 private uchar bidiMirroringGlyph;
1899 private BidiPairedBracketTypeId bidiPairedBracketType;
1900 private uchar bidiPairedBracket;
1901 }
1902
1903 public class CharacterInfoPage
1904 {
1905 public CharacterInfoPage() : characterInfos()
1906 {
1907 characterInfos.Resize(numInfosInPage);
1908 }
1909 public const CharacterInfo& operator[](long index) const
1910 {
1911 return *characterInfos[index];
1912 }
1913 public void Read(BinaryReader& reader)
1914 {
1915 for (long i = 0; i < numInfosInPage; ++i;)
1916 {
1917 CharacterInfo* characterInfo = new CharacterInfo();
1918 characterInfo->Read(reader);
1919 characterInfos[i].Reset(characterInfo);
1920 }
1921 }
1922 private List<UniquePtr<CharacterInfo>> characterInfos;
1923 }
1924
1925 public class ExtendedCharacterInfoPage
1926 {
1927 public ExtendedCharacterInfoPage() : extendedCharacterInfos()
1928 {
1929 extendedCharacterInfos.Resize(numInfosInPage);
1930 }
1931 public const ExtendedCharacterInfo& operator[](long index) const
1932 {
1933 return *extendedCharacterInfos[index];
1934 }
1935 public void Read(BinaryReader& reader)
1936 {
1937 for (long i = 0; i < numInfosInPage; ++i;)
1938 {
1939 ExtendedCharacterInfo* extendedCharacterInfo = new ExtendedCharacterInfo();
1940 extendedCharacterInfo->Read(reader);
1941 extendedCharacterInfos[i].Reset(extendedCharacterInfo);
1942 }
1943 }
1944 private List<UniquePtr<ExtendedCharacterInfo>> extendedCharacterInfos;
1945 }
1946
1947 public class ExtendedCharacterInfoHeader
1948 {
1949 public ExtendedCharacterInfoHeader() : extendedPageStarts()
1950 {
1951 }
1952 public uint operator[](long index) const
1953 {
1954 return extendedPageStarts[index];
1955 }
1956 public void Read(BinaryReader& reader)
1957 {
1958 uint n = reader.ReadUInt();
1959 extendedPageStarts.Resize(n);
1960 for (uint i = 0u; i < n; ++i;)
1961 {
1962 extendedPageStarts[i] = reader.ReadUInt();
1963 }
1964 }
1965 private List<uint> extendedPageStarts;
1966 }
1967
1968 public const byte cmajor_ucd_version_1 = cast<byte>('1');
1969 public const byte cmajor_ucd_version_2 = cast<byte>('2');
1970 public const byte cmajor_ucd_version_3 = cast<byte>('3');
1971 public const byte current_cmajor_ucd_version = cmajor_ucd_version_3;
1972
1973 public class CharacterTable
1974 {
1975 static CharacterTable() : instance(new CharacterTable())
1976 {
1977 }
1978 public static CharacterTable& Instance()
1979 {
1980 return *instance;
1981 }
1982 public const CharacterInfo& GetCharacterInfo(uchar codePoint)
1983 {
1984 if (codePoint > cast<uchar>(0x10FFFF))
1985 {
1986 throw UnicodeException("invalid Unicode code point " + ToHexString(cast<uint>(codePoint)));
1987 }
1988 long pageIndex = cast<long>(codePoint) / numInfosInPage;
1989 if (pages.Count() <= pageIndex)
1990 {
1991 while (pages.Count() <= pageIndex)
1992 {
1993 pages.Add(UniquePtr<CharacterInfoPage>());
1994 }
1995 }
1996 CharacterInfoPage* page = pages[pageIndex].Get();
1997 if (page == null)
1998 {
1999 string pathToUcdBinFile = PathToUcdBinFile();
2000 if (!File.Exists(pathToUcdBinFile))
2001 {
2002 throw UnicodeException("Error: Cmajor Unicode database file '" + pathToUcdBinFile + "' does not exist.");
2003 }
2004 BinaryReader reader = File.OpenBinary(pathToUcdBinFile);
2005 if (!headerRead)
2006 {
2007 ReadHeader(reader);
2008 }
2009 uint pageStart = headerSize + characterInfoPageSize * cast<uint>(pageIndex);
2010 reader.Seek(cast<long>(pageStart), Origin.seekSet);
2011 page = new CharacterInfoPage();
2012 page->Read(reader);
2013 pages[pageIndex].Reset(page);
2014 }
2015 long infoIndex = cast<long>(codePoint) % numInfosInPage;
2016 return (*page)[infoIndex];
2017 }
2018 public const ExtendedCharacterInfo& GetExtendedCharacterInfo(uchar codePoint)
2019 {
2020 if (codePoint > cast<uchar>(0x10FFFF))
2021 {
2022 throw UnicodeException("invalid Unicode code point " + ToHexString(cast<uint>(codePoint)));
2023 }
2024 long pageIndex = cast<long>(codePoint) / numInfosInPage;
2025 if (extendedPages.Count() <= pageIndex)
2026 {
2027 while (extendedPages.Count() <= pageIndex)
2028 {
2029 extendedPages.Add(UniquePtr<ExtendedCharacterInfoPage>());
2030 }
2031 }
2032 ExtendedCharacterInfoPage* extendedPage = extendedPages[pageIndex].Get();
2033 if (extendedPage == null)
2034 {
2035 string pathToUcdBinFile = PathToUcdBinFile();
2036 if (!File.Exists(pathToUcdBinFile))
2037 {
2038 throw UnicodeException("Error: Cmajor Unicode database file '" + pathToUcdBinFile + "' does not exist.");
2039 }
2040 BinaryReader reader = File.OpenBinary(pathToUcdBinFile);
2041 if (!headerRead)
2042 {
2043 ReadHeader(reader);
2044 }
2045 if (extendedHeader.IsNull())
2046 {
2047 reader.Seek(cast<long>(extendedHeaderStart), Origin.seekSet);
2048 ReadExtendedHeader(reader);
2049 }
2050 reader.Seek(cast<long>((*extendedHeader)[pageIndex]), Origin.seekSet);
2051 extendedPage = new ExtendedCharacterInfoPage();
2052 extendedPage->Read(reader);
2053 extendedPages[pageIndex].Reset(extendedPage);
2054 }
2055 long infoIndex = cast<long>(codePoint) % numInfosInPage;
2056 return (*extendedPage)[infoIndex];
2057 }
2058 private CharacterTable() : headerRead(false), pages(), extendedHeaderStart(0u), extendedHeaderEnd(0u), extendedHeader(), extendedPages()
2059 {
2060 headerMagic.Resize(8);
2061 string hdrmgc = "CMAJUCD";
2062 for (long i = 0; i < 8; ++i;)
2063 {
2064 if (i < 7)
2065 {
2066 headerMagic[i] = cast<byte>(hdrmgc[i]);
2067 }
2068 else
2069 {
2070 headerMagic[i] = current_cmajor_ucd_version;
2071 }
2072 }
2073 }
2074 private void ReadHeader(BinaryReader& reader)
2075 {
2076 headerRead = true;
2077 List<byte> magic;
2078 magic.Resize(8);
2079 for (long i = 0; i < 8; ++i;)
2080 {
2081 magic[i] = reader.ReadByte();
2082 }
2083 for (long i = 0; i < 7; ++i;)
2084 {
2085 if (magic[i] != cast<byte>(headerMagic[i]))
2086 {
2087 throw UnicodeException("invalid cmajor_ucd.bin header magic: 'CMAJUCD' expected");
2088 }
2089 }
2090 if (magic[7] != headerMagic[7])
2091 {
2092 throw UnicodeException("invalid cmajor_ucd.bin version: version " +
2093 string(cast<char>(headerMagic[7]), 1) + " expected, version " +
2094 string(cast<char>(magic[7]), 1) + " read");
2095 }
2096 extendedHeaderStart = reader.ReadUInt();
2097 extendedHeaderEnd = reader.ReadUInt();
2098 }
2099 private void ReadExtendedHeader(BinaryReader& reader)
2100 {
2101 extendedHeader.Reset(new ExtendedCharacterInfoHeader());
2102 extendedHeader->Read(reader);
2103 }
2104 public ~CharacterTable()
2105 {
2106 }
2107 private const uint headerSize = 4096u;
2108 private static UniquePtr<CharacterTable> instance;
2109 private List<byte> headerMagic;
2110 private bool headerRead;
2111 private List<UniquePtr<CharacterInfoPage>> pages;
2112 private uint extendedHeaderStart;
2113 private uint extendedHeaderEnd;
2114 private UniquePtr<ExtendedCharacterInfoHeader> extendedHeader;
2115 private List<UniquePtr<ExtendedCharacterInfoPage>> extendedPages;
2116 }
2117
2118 public const CharacterInfo& GetCharacterInfo(uchar codePoint)
2119 {
2120 return CharacterTable.Instance().GetCharacterInfo(codePoint);
2121 }
2122
2123 public const ExtendedCharacterInfo& GetExtendedCharacterInfo(uchar codePoint)
2124 {
2125 return CharacterTable.Instance().GetExtendedCharacterInfo(codePoint);
2126 }
2127
2128 public GeneralCategoryId GetGeneralCategory(uchar c)
2129 {
2130 return GetCharacterInfo(c).GeneralCategoryValue();
2131 }
2132
2133 public bool HasGeneralCategory(uchar c, GeneralCategoryId generalCategory)
2134 {
2135 return GetCharacterInfo(c).HasGeneralCategory(generalCategory);
2136 }
2137 }