blocxx
UTF8Utils.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 * Copyright (C) 2005, Vintela, Inc. All rights reserved.
3 * Copyright (C) 2006, Novell, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of
14 * Vintela, Inc.,
15 * nor Novell, Inc.,
16 * nor the names of its contributors or employees may be used to
17 * endorse or promote products derived from this software without
18 * specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 *******************************************************************************/
32 
33 
38 // Portions of this file based on utf/detail/utf8_algo.hpp
39 //
40 // Copyright (c) 2003 Alberto Barbati
41 //
42 // Permission to copy, use, modify, sell and distribute this software
43 // is granted provided this copyright notice appears in all copies.
44 // This software is provided "as is" without express or implied
45 // warranty, and with no claim as to its suitability for any purpose.
46 #include "blocxx/BLOCXX_config.h"
47 #include "blocxx/UTF8Utils.hpp"
48 #include "blocxx/String.hpp"
49 #include "blocxx/Assertion.hpp"
50 #include "blocxx/Array.hpp"
51 #include "blocxx/Format.hpp"
52 #include "blocxx/ExceptionIds.hpp"
53 
54 #include <string.h> // for strlen
55 #include <algorithm> // for std::lower_bound
56 
57 namespace BLOCXX_NAMESPACE
58 {
59 
61 
62 namespace UTF8Utils
63 {
64 namespace {
65 /*
66  UTF-8 sequence length table.
67  This table gives the sequence length according to the value of the
68  sequence leading character.
69  Notice: this table is different from the one found in the official
70  UTF-8 conversion program, found here
71  http://www.unicode.org/Public/PROGRAMS/CVTUTF/
72  This table encodes only the sequence lenghts of UTF-8 sequences
73  that can encode (or possibly encode) a Unicode character according
74  to Unicode 3.2 requirements.
75  In particular:
76  - lines from 0x80 to 0xb0 (inclusive) contains "0" because those
77  values do not represent a valid leading character
78  - line 0xc0 begins with two "0" because values 0xc0 and 0xc1 lead
79  non-shortest sequences, that are illegal since Unicode 3.1
80  - line 0xf0 has only five "4" instead of eight and lacks values
81  "5" and "6" because values above 0xf4 lead sequences that cannot
82  encode a Unicode character.
83 */
84 UInt8 SequenceLengthTable[256] =
85 {
86  /* 0x00 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x0f */
87  /* 0x10 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x1f */
88  /* 0x20 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x2f */
89  /* 0x30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x3f */
90  /* 0x40 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4f */
91  /* 0x50 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5f */
92  /* 0x60 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x6f */
93  /* 0x70 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x7f */
94  /* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8f */
95  /* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9f */
96  /* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xaf */
97  /* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xbf */
98  /* 0xc0 */ 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xcf */
99  /* 0xd0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xdf */
100  /* 0xe0 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xef */
101  /* 0xf0 */ 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xff */
102 };
103 } // end unnamed namespace
104 size_t charCount(const char* utf8str)
105 {
106  BLOCXX_ASSERT(utf8str != 0);
107  const char* p = utf8str;
108  size_t count = 0;
109  while (*p)
110  {
111  // any chars 0x80-0xBF are extension bytes. Anything else signals a new char
112  UInt8 c = static_cast<UInt8>(*p);
113  if (c < 0x80 || c > 0xBF)
114  {
115  ++count;
116  }
117  ++p;
118  }
119  return count;
120 }
122 UInt16 UTF8toUCS2(const char* utf8char)
123 {
124  UInt32 c = UTF8toUCS4(utf8char);
125  if (c > 0xFFFF)
126  {
127  return 0xFFFF;
128  }
129  else
130  {
131  return static_cast<UInt16>(c);
132  }
133 }
135 String UCS2toUTF8(UInt16 ucs2char)
136 {
137  // UCS2 and UCS4 are the same, only different sizes.
138  return UCS4toUTF8(ucs2char);
139 }
141 UInt32 UTF8toUCS4(const char* utf8char)
142 {
143  BLOCXX_ASSERT(utf8char != 0);
144  BLOCXX_ASSERT(utf8char[0] != '\0');
145  const char* p = utf8char;
146  const UInt32 c0 = static_cast<UInt8>(p[0]);
147  const UInt32 bad = 0xFFFFFFFF;
148  switch (SequenceLengthTable[c0])
149  {
150  case 1:
151  {
152  return c0;
153  }
154  case 2:
155  {
156  // check for short (invalid) utf8 sequence
157  if (p[1] == '\0')
158  {
159  return bad;
160  }
161  const UInt32 c1 = static_cast<UInt8>(p[1]);
162  return ((c0 & 0x1fu) << 6) | (c1 & 0x3fu);
163  }
164  case 3:
165  {
166  // check for short (invalid) utf8 sequence
167  if (p[1] == '\0' || p[2] == '\0')
168  {
169  return bad;
170  }
171  const UInt32 c1 = static_cast<UInt8>(p[1]);
172  const UInt32 c2 = static_cast<UInt8>(p[2]);
173  return ((c0 & 0x0fu) << 12) | ((c1 & 0x3fu) << 6) | (c2 & 0x3fu);
174  }
175  case 4:
176  {
177  // check for short (invalid) utf8 sequence
178  if (p[1] == '\0' || p[2] == '\0' || p[3] == '\0')
179  {
180  return bad;
181  }
182 
183  const UInt32 c1 = static_cast<UInt8>(p[1]);
184  const UInt32 c2 = static_cast<UInt8>(p[2]);
185  const UInt32 c3 = static_cast<UInt8>(p[3]);
186 
187  return ((c0 & 0x03u) << 18) | ((c1 & 0x3fu) << 12) | ((c2 & 0x3fu) << 6) | (c3 & 0x3fu);
188  }
189  default:
190  {
191  // invalid, just skip it
192  break;
193  }
194  }
195  return bad;
196 }
197 
199 String UCS4toUTF8(UInt32 ucs4char)
200 {
201  StringBuffer sb(5); // max 4 chars + null
202  UCS4toUTF8(ucs4char, sb);
203  return sb.releaseString();
204 }
205 
207 void UCS4toUTF8(UInt32 ucs4char, StringBuffer& sb)
208 {
209  if (ucs4char < 0x80u)
210  {
211  // one byte
212  sb += static_cast<char>(static_cast<UInt8>(ucs4char));
213  }
214  else if (ucs4char < 0x800u)
215  {
216  sb += static_cast<char>(static_cast<UInt8>(0xc0u | (ucs4char >> 6)));
217  sb += static_cast<char>(static_cast<UInt8>(0x80u | (ucs4char & 0x3fu)));
218  }
219  else if (ucs4char < 0x10000u)
220  {
221  sb += static_cast<char>(static_cast<UInt8>(0xe0u | (ucs4char >> 12)));
222  sb += static_cast<char>(static_cast<UInt8>(0x80u | ((ucs4char >> 6) & 0x3fu)));
223  sb += static_cast<char>(static_cast<UInt8>(0x80u | (ucs4char & 0x3fu)));
224  }
225  else
226  {
227  sb += static_cast<char>(static_cast<UInt8>(0xf0u | (ucs4char >> 18)));
228  sb += static_cast<char>(static_cast<UInt8>(0x80u | ((ucs4char >> 12) & 0x3fu)));
229  sb += static_cast<char>(static_cast<UInt8>(0x80u | ((ucs4char >> 6) & 0x3fu)));
230  sb += static_cast<char>(static_cast<UInt8>(0x80u | (ucs4char & 0x3fu)));
231  }
232 }
233 
234 namespace
235 {
237 void UCS4toUTF8(UInt32 ucs4char, char* p)
238 {
239  if (ucs4char < 0x80u)
240  {
241  // one byte
242  p[0] = static_cast<char>(static_cast<UInt8>(ucs4char));
243  }
244  else if (ucs4char < 0x800u)
245  {
246  p[0] = static_cast<char>(static_cast<UInt8>(0xc0u | (ucs4char >> 6)));
247  p[1] = static_cast<char>(static_cast<UInt8>(0x80u | (ucs4char & 0x3fu)));
248  }
249  else if (ucs4char < 0x10000u)
250  {
251  p[0] = static_cast<char>(static_cast<UInt8>(0xe0u | (ucs4char >> 12)));
252  p[1] = static_cast<char>(static_cast<UInt8>(0x80u | ((ucs4char >> 6) & 0x3fu)));
253  p[2] = static_cast<char>(static_cast<UInt8>(0x80u | (ucs4char & 0x3fu)));
254  }
255  else
256  {
257  p[0] = static_cast<char>(static_cast<UInt8>(0xf0u | (ucs4char >> 18)));
258  p[1] = static_cast<char>(static_cast<UInt8>(0x80u | ((ucs4char >> 12) & 0x3fu)));
259  p[2] = static_cast<char>(static_cast<UInt8>(0x80u | ((ucs4char >> 6) & 0x3fu)));
260  p[3] = static_cast<char>(static_cast<UInt8>(0x80u | (ucs4char & 0x3fu)));
261  }
262 }
263 
265 Array<UInt16> StringToUCS2Common(const String& input, bool throwException)
266 {
267  // TODO: Remove the duplication between this function and UTF8toUCS2()
268  Array<UInt16> rval;
269  BLOCXX_ASSERT(input.length() == ::strlen(input.c_str()));
270  const UInt16 UCS2ReplacementChar = 0xFFFD;
271  const char* begin = input.c_str();
272  const char* end = begin + input.length();
273 
274  const char* p = begin;
275  while (p < end)
276  {
277  const UInt32 c0 = static_cast<UInt8>(p[0]);
278  switch (SequenceLengthTable[c0])
279  {
280  case 1:
281  {
282  rval.push_back(c0);
283  ++p;
284  }
285  break;
286  case 2:
287  {
288  // check for short (invalid) utf8 sequence
289  if (p[1] == '\0')
290  {
291  if (throwException)
292  {
293  BLOCXX_THROW(InvalidUTF8Exception, Format("Length: %1, input = %2, p = %3",
294  static_cast<int>(SequenceLengthTable[c0]), input.c_str(), p).c_str());
295  }
296  else
297  {
298  rval.push_back(UCS2ReplacementChar);
299  p += 2;
300  }
301  }
302  const UInt32 c1 = static_cast<UInt8>(p[1]);
303  rval.push_back(((c0 & 0x1fu) << 6) | (c1 & 0x3fu));
304  p += 2;
305  }
306  break;
307  case 3:
308  {
309  // check for short (invalid) utf8 sequence
310  if (p[1] == '\0' || p[2] == '\0')
311  {
312  if (throwException)
313  {
314  BLOCXX_THROW(InvalidUTF8Exception, Format("Length: %1, input = %2, p = %3",
315  static_cast<int>(SequenceLengthTable[c0]), input.c_str(), p).c_str());
316  }
317  else
318  {
319  rval.push_back(UCS2ReplacementChar);
320  p += 3;
321  }
322 
323  }
324  const UInt32 c1 = static_cast<UInt8>(p[1]);
325  const UInt32 c2 = static_cast<UInt8>(p[2]);
326  rval.push_back(((c0 & 0x0fu) << 12) | ((c1 & 0x3fu) << 6) | (c2 & 0x3fu));
327  p += 3;
328  }
329  break;
330  case 4:
331  {
332  // UCS2 can't hold a value this big
333  if (throwException)
334  {
335  BLOCXX_THROW(InvalidUTF8Exception, Format("Length: %1, input = %2, p = %3",
336  static_cast<int>(SequenceLengthTable[c0]), input.c_str(), p).c_str());
337  }
338  else
339  {
340  rval.push_back(UCS2ReplacementChar);
341  p += 4;
342  }
343 
344  }
345  break;
346  default:
347  {
348  if (throwException)
349  {
350  BLOCXX_THROW(InvalidUTF8Exception, Format("Length: %1, input = %2, p = %3",
351  static_cast<int>(SequenceLengthTable[c0]), input.c_str(), p).c_str());
352  }
353  else
354  {
355  rval.push_back(UCS2ReplacementChar);
356  ++p;
357  }
358  }
359  }
360  }
361  return rval;
362 }
363 
364 } // end anonymous namespace
365 
368 {
369  return StringToUCS2Common(input, false);
370 }
371 
374 {
375  return StringToUCS2Common(input, true);
376 }
377 
379 String UCS2ToString(const void* input, size_t inputLength)
380 {
381  // start out with 1 byte/char in input, this is just big enough for a
382  // standard ASCII string. If any chars are bigger, we'll only incur 1 or
383  // 2 (worse case) reallocations of the buffer.
384  size_t numchars = inputLength/2;
385  StringBuffer sb(numchars + 1);
386  for (size_t i = 0; i < numchars; ++i)
387  {
388  UCS4toUTF8(reinterpret_cast<const UInt16*>(input)[i], sb);
389  }
390  return sb.releaseString();
391 }
392 
395 {
396  if (input.empty())
397  {
398  return String();
399  }
400  return UCS2ToString(&input[0], input.size() * sizeof(UInt16));
401 }
404 {
405  if (input.empty())
406  {
407  return String();
408  }
409  return UCS2ToString(&input[0], input.size());
410 }
411 
413 namespace
414 {
415 
416 int UTF8CharLen(UInt32 ucs4char)
417 {
418  if (ucs4char < 0x80u)
419  {
420  return 1;
421  }
422  else if (ucs4char < 0x800u)
423  {
424  return 2;
425  }
426  else if (ucs4char < 0x10000u)
427  {
428  return 3;
429  }
430  else
431  {
432  return 4;
433  }
434 }
435 
436 template <typename TransformT>
437 bool transformInPlace(char* input, TransformT transformer)
438 {
439  char* p = input;
440  char* output = input;
441  while (*p)
442  {
443  UInt32 ucs4char = UTF8toUCS4(p);
444  if (ucs4char == 0xFFFFFFFF)
445  {
446  ++p;
447  ++output;
448  continue;
449  }
450  UInt32 newUcs4Char = transformer(ucs4char);
451 
452  const UInt32 c0 = static_cast<UInt8>(p[0]);
453  int prevCharLen = SequenceLengthTable[c0];
454  int newCharLen = UTF8CharLen(newUcs4Char);
455 
456  // can't grow the string, only shrink it. This can't happen with valid UTF8, but with invalid stuff it could.
457  if (p > output)
458  {
459  return false;
460  }
461 
462  // This is commented out, because, given the current set of data from Unicode 4.0.1, there are no
463  // chars that grow when either upper or lower-cased.
464  //if ((p + prevCharLen) < (output + newCharLen))
465  //{
466  // return false;
467  //}
468  UCS4toUTF8(newUcs4Char, output);
469  p += prevCharLen;
470  output += newCharLen;
471  }
472  *output = '\0'; // null terminate in case the string shrunk
473  return true;
474 }
475 
476 template <typename TransformT>
477 String transform(const char* input, TransformT transformer)
478 {
479  StringBuffer rval(strlen(input));
480  const char* p = input;
481  while (*p)
482  {
483  UInt32 ucs4char = UTF8toUCS4(p);
484  if (ucs4char == 0xFFFFFFFF)
485  {
486  rval += *p;
487  ++p;
488  continue;
489  }
490 
491  UTF8Utils::UCS4toUTF8(transformer(ucs4char), rval);
492 
493  const UInt32 c0 = static_cast<UInt8>(p[0]);
494  int prevCharLen = SequenceLengthTable[c0];
495  p += prevCharLen;
496  }
497  return rval.releaseString();
498 }
499 
500 // These mappings were generated by GenCaseMappings.cpp with UnicodeData.txt
501 // from unicode 4.0.1 and downloaded from http://www.unicode.org/Public/UNIDATA/
502 // Don't modify it by hand, re-run the generator if something needs to change.
503 struct CaseMapping
504 {
505  UInt32 codePoint;
506  UInt32 mapping;
507 };
508 const CaseMapping lowerMappings[] =
509 {
510  {0x41, 0x61},
511  {0x42, 0x62},
512  {0x43, 0x63},
513  {0x44, 0x64},
514  {0x45, 0x65},
515  {0x46, 0x66},
516  {0x47, 0x67},
517  {0x48, 0x68},
518  {0x49, 0x69},
519  {0x4a, 0x6a},
520  {0x4b, 0x6b},
521  {0x4c, 0x6c},
522  {0x4d, 0x6d},
523  {0x4e, 0x6e},
524  {0x4f, 0x6f},
525  {0x50, 0x70},
526  {0x51, 0x71},
527  {0x52, 0x72},
528  {0x53, 0x73},
529  {0x54, 0x74},
530  {0x55, 0x75},
531  {0x56, 0x76},
532  {0x57, 0x77},
533  {0x58, 0x78},
534  {0x59, 0x79},
535  {0x5a, 0x7a},
536  {0xc0, 0xe0},
537  {0xc1, 0xe1},
538  {0xc2, 0xe2},
539  {0xc3, 0xe3},
540  {0xc4, 0xe4},
541  {0xc5, 0xe5},
542  {0xc6, 0xe6},
543  {0xc7, 0xe7},
544  {0xc8, 0xe8},
545  {0xc9, 0xe9},
546  {0xca, 0xea},
547  {0xcb, 0xeb},
548  {0xcc, 0xec},
549  {0xcd, 0xed},
550  {0xce, 0xee},
551  {0xcf, 0xef},
552  {0xd0, 0xf0},
553  {0xd1, 0xf1},
554  {0xd2, 0xf2},
555  {0xd3, 0xf3},
556  {0xd4, 0xf4},
557  {0xd5, 0xf5},
558  {0xd6, 0xf6},
559  {0xd8, 0xf8},
560  {0xd9, 0xf9},
561  {0xda, 0xfa},
562  {0xdb, 0xfb},
563  {0xdc, 0xfc},
564  {0xdd, 0xfd},
565  {0xde, 0xfe},
566  {0x100, 0x101},
567  {0x102, 0x103},
568  {0x104, 0x105},
569  {0x106, 0x107},
570  {0x108, 0x109},
571  {0x10a, 0x10b},
572  {0x10c, 0x10d},
573  {0x10e, 0x10f},
574  {0x110, 0x111},
575  {0x112, 0x113},
576  {0x114, 0x115},
577  {0x116, 0x117},
578  {0x118, 0x119},
579  {0x11a, 0x11b},
580  {0x11c, 0x11d},
581  {0x11e, 0x11f},
582  {0x120, 0x121},
583  {0x122, 0x123},
584  {0x124, 0x125},
585  {0x126, 0x127},
586  {0x128, 0x129},
587  {0x12a, 0x12b},
588  {0x12c, 0x12d},
589  {0x12e, 0x12f},
590  {0x130, 0x69},
591  {0x132, 0x133},
592  {0x134, 0x135},
593  {0x136, 0x137},
594  {0x139, 0x13a},
595  {0x13b, 0x13c},
596  {0x13d, 0x13e},
597  {0x13f, 0x140},
598  {0x141, 0x142},
599  {0x143, 0x144},
600  {0x145, 0x146},
601  {0x147, 0x148},
602  {0x14a, 0x14b},
603  {0x14c, 0x14d},
604  {0x14e, 0x14f},
605  {0x150, 0x151},
606  {0x152, 0x153},
607  {0x154, 0x155},
608  {0x156, 0x157},
609  {0x158, 0x159},
610  {0x15a, 0x15b},
611  {0x15c, 0x15d},
612  {0x15e, 0x15f},
613  {0x160, 0x161},
614  {0x162, 0x163},
615  {0x164, 0x165},
616  {0x166, 0x167},
617  {0x168, 0x169},
618  {0x16a, 0x16b},
619  {0x16c, 0x16d},
620  {0x16e, 0x16f},
621  {0x170, 0x171},
622  {0x172, 0x173},
623  {0x174, 0x175},
624  {0x176, 0x177},
625  {0x178, 0xff},
626  {0x179, 0x17a},
627  {0x17b, 0x17c},
628  {0x17d, 0x17e},
629  {0x181, 0x253},
630  {0x182, 0x183},
631  {0x184, 0x185},
632  {0x186, 0x254},
633  {0x187, 0x188},
634  {0x189, 0x256},
635  {0x18a, 0x257},
636  {0x18b, 0x18c},
637  {0x18e, 0x1dd},
638  {0x18f, 0x259},
639  {0x190, 0x25b},
640  {0x191, 0x192},
641  {0x193, 0x260},
642  {0x194, 0x263},
643  {0x196, 0x269},
644  {0x197, 0x268},
645  {0x198, 0x199},
646  {0x19c, 0x26f},
647  {0x19d, 0x272},
648  {0x19f, 0x275},
649  {0x1a0, 0x1a1},
650  {0x1a2, 0x1a3},
651  {0x1a4, 0x1a5},
652  {0x1a6, 0x280},
653  {0x1a7, 0x1a8},
654  {0x1a9, 0x283},
655  {0x1ac, 0x1ad},
656  {0x1ae, 0x288},
657  {0x1af, 0x1b0},
658  {0x1b1, 0x28a},
659  {0x1b2, 0x28b},
660  {0x1b3, 0x1b4},
661  {0x1b5, 0x1b6},
662  {0x1b7, 0x292},
663  {0x1b8, 0x1b9},
664  {0x1bc, 0x1bd},
665  {0x1c4, 0x1c6},
666  {0x1c5, 0x1c6},
667  {0x1c7, 0x1c9},
668  {0x1c8, 0x1c9},
669  {0x1ca, 0x1cc},
670  {0x1cb, 0x1cc},
671  {0x1cd, 0x1ce},
672  {0x1cf, 0x1d0},
673  {0x1d1, 0x1d2},
674  {0x1d3, 0x1d4},
675  {0x1d5, 0x1d6},
676  {0x1d7, 0x1d8},
677  {0x1d9, 0x1da},
678  {0x1db, 0x1dc},
679  {0x1de, 0x1df},
680  {0x1e0, 0x1e1},
681  {0x1e2, 0x1e3},
682  {0x1e4, 0x1e5},
683  {0x1e6, 0x1e7},
684  {0x1e8, 0x1e9},
685  {0x1ea, 0x1eb},
686  {0x1ec, 0x1ed},
687  {0x1ee, 0x1ef},
688  {0x1f1, 0x1f3},
689  {0x1f2, 0x1f3},
690  {0x1f4, 0x1f5},
691  {0x1f6, 0x195},
692  {0x1f7, 0x1bf},
693  {0x1f8, 0x1f9},
694  {0x1fa, 0x1fb},
695  {0x1fc, 0x1fd},
696  {0x1fe, 0x1ff},
697  {0x200, 0x201},
698  {0x202, 0x203},
699  {0x204, 0x205},
700  {0x206, 0x207},
701  {0x208, 0x209},
702  {0x20a, 0x20b},
703  {0x20c, 0x20d},
704  {0x20e, 0x20f},
705  {0x210, 0x211},
706  {0x212, 0x213},
707  {0x214, 0x215},
708  {0x216, 0x217},
709  {0x218, 0x219},
710  {0x21a, 0x21b},
711  {0x21c, 0x21d},
712  {0x21e, 0x21f},
713  {0x220, 0x19e},
714  {0x222, 0x223},
715  {0x224, 0x225},
716  {0x226, 0x227},
717  {0x228, 0x229},
718  {0x22a, 0x22b},
719  {0x22c, 0x22d},
720  {0x22e, 0x22f},
721  {0x230, 0x231},
722  {0x232, 0x233},
723  {0x386, 0x3ac},
724  {0x388, 0x3ad},
725  {0x389, 0x3ae},
726  {0x38a, 0x3af},
727  {0x38c, 0x3cc},
728  {0x38e, 0x3cd},
729  {0x38f, 0x3ce},
730  {0x391, 0x3b1},
731  {0x392, 0x3b2},
732  {0x393, 0x3b3},
733  {0x394, 0x3b4},
734  {0x395, 0x3b5},
735  {0x396, 0x3b6},
736  {0x397, 0x3b7},
737  {0x398, 0x3b8},
738  {0x399, 0x3b9},
739  {0x39a, 0x3ba},
740  {0x39b, 0x3bb},
741  {0x39c, 0x3bc},
742  {0x39d, 0x3bd},
743  {0x39e, 0x3be},
744  {0x39f, 0x3bf},
745  {0x3a0, 0x3c0},
746  {0x3a1, 0x3c1},
747  {0x3a3, 0x3c3},
748  {0x3a4, 0x3c4},
749  {0x3a5, 0x3c5},
750  {0x3a6, 0x3c6},
751  {0x3a7, 0x3c7},
752  {0x3a8, 0x3c8},
753  {0x3a9, 0x3c9},
754  {0x3aa, 0x3ca},
755  {0x3ab, 0x3cb},
756  {0x3d8, 0x3d9},
757  {0x3da, 0x3db},
758  {0x3dc, 0x3dd},
759  {0x3de, 0x3df},
760  {0x3e0, 0x3e1},
761  {0x3e2, 0x3e3},
762  {0x3e4, 0x3e5},
763  {0x3e6, 0x3e7},
764  {0x3e8, 0x3e9},
765  {0x3ea, 0x3eb},
766  {0x3ec, 0x3ed},
767  {0x3ee, 0x3ef},
768  {0x3f4, 0x3b8},
769  {0x3f7, 0x3f8},
770  {0x3f9, 0x3f2},
771  {0x3fa, 0x3fb},
772  {0x400, 0x450},
773  {0x401, 0x451},
774  {0x402, 0x452},
775  {0x403, 0x453},
776  {0x404, 0x454},
777  {0x405, 0x455},
778  {0x406, 0x456},
779  {0x407, 0x457},
780  {0x408, 0x458},
781  {0x409, 0x459},
782  {0x40a, 0x45a},
783  {0x40b, 0x45b},
784  {0x40c, 0x45c},
785  {0x40d, 0x45d},
786  {0x40e, 0x45e},
787  {0x40f, 0x45f},
788  {0x410, 0x430},
789  {0x411, 0x431},
790  {0x412, 0x432},
791  {0x413, 0x433},
792  {0x414, 0x434},
793  {0x415, 0x435},
794  {0x416, 0x436},
795  {0x417, 0x437},
796  {0x418, 0x438},
797  {0x419, 0x439},
798  {0x41a, 0x43a},
799  {0x41b, 0x43b},
800  {0x41c, 0x43c},
801  {0x41d, 0x43d},
802  {0x41e, 0x43e},
803  {0x41f, 0x43f},
804  {0x420, 0x440},
805  {0x421, 0x441},
806  {0x422, 0x442},
807  {0x423, 0x443},
808  {0x424, 0x444},
809  {0x425, 0x445},
810  {0x426, 0x446},
811  {0x427, 0x447},
812  {0x428, 0x448},
813  {0x429, 0x449},
814  {0x42a, 0x44a},
815  {0x42b, 0x44b},
816  {0x42c, 0x44c},
817  {0x42d, 0x44d},
818  {0x42e, 0x44e},
819  {0x42f, 0x44f},
820  {0x460, 0x461},
821  {0x462, 0x463},
822  {0x464, 0x465},
823  {0x466, 0x467},
824  {0x468, 0x469},
825  {0x46a, 0x46b},
826  {0x46c, 0x46d},
827  {0x46e, 0x46f},
828  {0x470, 0x471},
829  {0x472, 0x473},
830  {0x474, 0x475},
831  {0x476, 0x477},
832  {0x478, 0x479},
833  {0x47a, 0x47b},
834  {0x47c, 0x47d},
835  {0x47e, 0x47f},
836  {0x480, 0x481},
837  {0x48a, 0x48b},
838  {0x48c, 0x48d},
839  {0x48e, 0x48f},
840  {0x490, 0x491},
841  {0x492, 0x493},
842  {0x494, 0x495},
843  {0x496, 0x497},
844  {0x498, 0x499},
845  {0x49a, 0x49b},
846  {0x49c, 0x49d},
847  {0x49e, 0x49f},
848  {0x4a0, 0x4a1},
849  {0x4a2, 0x4a3},
850  {0x4a4, 0x4a5},
851  {0x4a6, 0x4a7},
852  {0x4a8, 0x4a9},
853  {0x4aa, 0x4ab},
854  {0x4ac, 0x4ad},
855  {0x4ae, 0x4af},
856  {0x4b0, 0x4b1},
857  {0x4b2, 0x4b3},
858  {0x4b4, 0x4b5},
859  {0x4b6, 0x4b7},
860  {0x4b8, 0x4b9},
861  {0x4ba, 0x4bb},
862  {0x4bc, 0x4bd},
863  {0x4be, 0x4bf},
864  {0x4c1, 0x4c2},
865  {0x4c3, 0x4c4},
866  {0x4c5, 0x4c6},
867  {0x4c7, 0x4c8},
868  {0x4c9, 0x4ca},
869  {0x4cb, 0x4cc},
870  {0x4cd, 0x4ce},
871  {0x4d0, 0x4d1},
872  {0x4d2, 0x4d3},
873  {0x4d4, 0x4d5},
874  {0x4d6, 0x4d7},
875  {0x4d8, 0x4d9},
876  {0x4da, 0x4db},
877  {0x4dc, 0x4dd},
878  {0x4de, 0x4df},
879  {0x4e0, 0x4e1},
880  {0x4e2, 0x4e3},
881  {0x4e4, 0x4e5},
882  {0x4e6, 0x4e7},
883  {0x4e8, 0x4e9},
884  {0x4ea, 0x4eb},
885  {0x4ec, 0x4ed},
886  {0x4ee, 0x4ef},
887  {0x4f0, 0x4f1},
888  {0x4f2, 0x4f3},
889  {0x4f4, 0x4f5},
890  {0x4f8, 0x4f9},
891  {0x500, 0x501},
892  {0x502, 0x503},
893  {0x504, 0x505},
894  {0x506, 0x507},
895  {0x508, 0x509},
896  {0x50a, 0x50b},
897  {0x50c, 0x50d},
898  {0x50e, 0x50f},
899  {0x531, 0x561},
900  {0x532, 0x562},
901  {0x533, 0x563},
902  {0x534, 0x564},
903  {0x535, 0x565},
904  {0x536, 0x566},
905  {0x537, 0x567},
906  {0x538, 0x568},
907  {0x539, 0x569},
908  {0x53a, 0x56a},
909  {0x53b, 0x56b},
910  {0x53c, 0x56c},
911  {0x53d, 0x56d},
912  {0x53e, 0x56e},
913  {0x53f, 0x56f},
914  {0x540, 0x570},
915  {0x541, 0x571},
916  {0x542, 0x572},
917  {0x543, 0x573},
918  {0x544, 0x574},
919  {0x545, 0x575},
920  {0x546, 0x576},
921  {0x547, 0x577},
922  {0x548, 0x578},
923  {0x549, 0x579},
924  {0x54a, 0x57a},
925  {0x54b, 0x57b},
926  {0x54c, 0x57c},
927  {0x54d, 0x57d},
928  {0x54e, 0x57e},
929  {0x54f, 0x57f},
930  {0x550, 0x580},
931  {0x551, 0x581},
932  {0x552, 0x582},
933  {0x553, 0x583},
934  {0x554, 0x584},
935  {0x555, 0x585},
936  {0x556, 0x586},
937  {0x1e00, 0x1e01},
938  {0x1e02, 0x1e03},
939  {0x1e04, 0x1e05},
940  {0x1e06, 0x1e07},
941  {0x1e08, 0x1e09},
942  {0x1e0a, 0x1e0b},
943  {0x1e0c, 0x1e0d},
944  {0x1e0e, 0x1e0f},
945  {0x1e10, 0x1e11},
946  {0x1e12, 0x1e13},
947  {0x1e14, 0x1e15},
948  {0x1e16, 0x1e17},
949  {0x1e18, 0x1e19},
950  {0x1e1a, 0x1e1b},
951  {0x1e1c, 0x1e1d},
952  {0x1e1e, 0x1e1f},
953  {0x1e20, 0x1e21},
954  {0x1e22, 0x1e23},
955  {0x1e24, 0x1e25},
956  {0x1e26, 0x1e27},
957  {0x1e28, 0x1e29},
958  {0x1e2a, 0x1e2b},
959  {0x1e2c, 0x1e2d},
960  {0x1e2e, 0x1e2f},
961  {0x1e30, 0x1e31},
962  {0x1e32, 0x1e33},
963  {0x1e34, 0x1e35},
964  {0x1e36, 0x1e37},
965  {0x1e38, 0x1e39},
966  {0x1e3a, 0x1e3b},
967  {0x1e3c, 0x1e3d},
968  {0x1e3e, 0x1e3f},
969  {0x1e40, 0x1e41},
970  {0x1e42, 0x1e43},
971  {0x1e44, 0x1e45},
972  {0x1e46, 0x1e47},
973  {0x1e48, 0x1e49},
974  {0x1e4a, 0x1e4b},
975  {0x1e4c, 0x1e4d},
976  {0x1e4e, 0x1e4f},
977  {0x1e50, 0x1e51},
978  {0x1e52, 0x1e53},
979  {0x1e54, 0x1e55},
980  {0x1e56, 0x1e57},
981  {0x1e58, 0x1e59},
982  {0x1e5a, 0x1e5b},
983  {0x1e5c, 0x1e5d},
984  {0x1e5e, 0x1e5f},
985  {0x1e60, 0x1e61},
986  {0x1e62, 0x1e63},
987  {0x1e64, 0x1e65},
988  {0x1e66, 0x1e67},
989  {0x1e68, 0x1e69},
990  {0x1e6a, 0x1e6b},
991  {0x1e6c, 0x1e6d},
992  {0x1e6e, 0x1e6f},
993  {0x1e70, 0x1e71},
994  {0x1e72, 0x1e73},
995  {0x1e74, 0x1e75},
996  {0x1e76, 0x1e77},
997  {0x1e78, 0x1e79},
998  {0x1e7a, 0x1e7b},
999  {0x1e7c, 0x1e7d},
1000  {0x1e7e, 0x1e7f},
1001  {0x1e80, 0x1e81},
1002  {0x1e82, 0x1e83},
1003  {0x1e84, 0x1e85},
1004  {0x1e86, 0x1e87},
1005  {0x1e88, 0x1e89},
1006  {0x1e8a, 0x1e8b},
1007  {0x1e8c, 0x1e8d},
1008  {0x1e8e, 0x1e8f},
1009  {0x1e90, 0x1e91},
1010  {0x1e92, 0x1e93},
1011  {0x1e94, 0x1e95},
1012  {0x1ea0, 0x1ea1},
1013  {0x1ea2, 0x1ea3},
1014  {0x1ea4, 0x1ea5},
1015  {0x1ea6, 0x1ea7},
1016  {0x1ea8, 0x1ea9},
1017  {0x1eaa, 0x1eab},
1018  {0x1eac, 0x1ead},
1019  {0x1eae, 0x1eaf},
1020  {0x1eb0, 0x1eb1},
1021  {0x1eb2, 0x1eb3},
1022  {0x1eb4, 0x1eb5},
1023  {0x1eb6, 0x1eb7},
1024  {0x1eb8, 0x1eb9},
1025  {0x1eba, 0x1ebb},
1026  {0x1ebc, 0x1ebd},
1027  {0x1ebe, 0x1ebf},
1028  {0x1ec0, 0x1ec1},
1029  {0x1ec2, 0x1ec3},
1030  {0x1ec4, 0x1ec5},
1031  {0x1ec6, 0x1ec7},
1032  {0x1ec8, 0x1ec9},
1033  {0x1eca, 0x1ecb},
1034  {0x1ecc, 0x1ecd},
1035  {0x1ece, 0x1ecf},
1036  {0x1ed0, 0x1ed1},
1037  {0x1ed2, 0x1ed3},
1038  {0x1ed4, 0x1ed5},
1039  {0x1ed6, 0x1ed7},
1040  {0x1ed8, 0x1ed9},
1041  {0x1eda, 0x1edb},
1042  {0x1edc, 0x1edd},
1043  {0x1ede, 0x1edf},
1044  {0x1ee0, 0x1ee1},
1045  {0x1ee2, 0x1ee3},
1046  {0x1ee4, 0x1ee5},
1047  {0x1ee6, 0x1ee7},
1048  {0x1ee8, 0x1ee9},
1049  {0x1eea, 0x1eeb},
1050  {0x1eec, 0x1eed},
1051  {0x1eee, 0x1eef},
1052  {0x1ef0, 0x1ef1},
1053  {0x1ef2, 0x1ef3},
1054  {0x1ef4, 0x1ef5},
1055  {0x1ef6, 0x1ef7},
1056  {0x1ef8, 0x1ef9},
1057  {0x1f08, 0x1f00},
1058  {0x1f09, 0x1f01},
1059  {0x1f0a, 0x1f02},
1060  {0x1f0b, 0x1f03},
1061  {0x1f0c, 0x1f04},
1062  {0x1f0d, 0x1f05},
1063  {0x1f0e, 0x1f06},
1064  {0x1f0f, 0x1f07},
1065  {0x1f18, 0x1f10},
1066  {0x1f19, 0x1f11},
1067  {0x1f1a, 0x1f12},
1068  {0x1f1b, 0x1f13},
1069  {0x1f1c, 0x1f14},
1070  {0x1f1d, 0x1f15},
1071  {0x1f28, 0x1f20},
1072  {0x1f29, 0x1f21},
1073  {0x1f2a, 0x1f22},
1074  {0x1f2b, 0x1f23},
1075  {0x1f2c, 0x1f24},
1076  {0x1f2d, 0x1f25},
1077  {0x1f2e, 0x1f26},
1078  {0x1f2f, 0x1f27},
1079  {0x1f38, 0x1f30},
1080  {0x1f39, 0x1f31},
1081  {0x1f3a, 0x1f32},
1082  {0x1f3b, 0x1f33},
1083  {0x1f3c, 0x1f34},
1084  {0x1f3d, 0x1f35},
1085  {0x1f3e, 0x1f36},
1086  {0x1f3f, 0x1f37},
1087  {0x1f48, 0x1f40},
1088  {0x1f49, 0x1f41},
1089  {0x1f4a, 0x1f42},
1090  {0x1f4b, 0x1f43},
1091  {0x1f4c, 0x1f44},
1092  {0x1f4d, 0x1f45},
1093  {0x1f59, 0x1f51},
1094  {0x1f5b, 0x1f53},
1095  {0x1f5d, 0x1f55},
1096  {0x1f5f, 0x1f57},
1097  {0x1f68, 0x1f60},
1098  {0x1f69, 0x1f61},
1099  {0x1f6a, 0x1f62},
1100  {0x1f6b, 0x1f63},
1101  {0x1f6c, 0x1f64},
1102  {0x1f6d, 0x1f65},
1103  {0x1f6e, 0x1f66},
1104  {0x1f6f, 0x1f67},
1105  {0x1f88, 0x1f80},
1106  {0x1f89, 0x1f81},
1107  {0x1f8a, 0x1f82},
1108  {0x1f8b, 0x1f83},
1109  {0x1f8c, 0x1f84},
1110  {0x1f8d, 0x1f85},
1111  {0x1f8e, 0x1f86},
1112  {0x1f8f, 0x1f87},
1113  {0x1f98, 0x1f90},
1114  {0x1f99, 0x1f91},
1115  {0x1f9a, 0x1f92},
1116  {0x1f9b, 0x1f93},
1117  {0x1f9c, 0x1f94},
1118  {0x1f9d, 0x1f95},
1119  {0x1f9e, 0x1f96},
1120  {0x1f9f, 0x1f97},
1121  {0x1fa8, 0x1fa0},
1122  {0x1fa9, 0x1fa1},
1123  {0x1faa, 0x1fa2},
1124  {0x1fab, 0x1fa3},
1125  {0x1fac, 0x1fa4},
1126  {0x1fad, 0x1fa5},
1127  {0x1fae, 0x1fa6},
1128  {0x1faf, 0x1fa7},
1129  {0x1fb8, 0x1fb0},
1130  {0x1fb9, 0x1fb1},
1131  {0x1fba, 0x1f70},
1132  {0x1fbb, 0x1f71},
1133  {0x1fbc, 0x1fb3},
1134  {0x1fc8, 0x1f72},
1135  {0x1fc9, 0x1f73},
1136  {0x1fca, 0x1f74},
1137  {0x1fcb, 0x1f75},
1138  {0x1fcc, 0x1fc3},
1139  {0x1fd8, 0x1fd0},
1140  {0x1fd9, 0x1fd1},
1141  {0x1fda, 0x1f76},
1142  {0x1fdb, 0x1f77},
1143  {0x1fe8, 0x1fe0},
1144  {0x1fe9, 0x1fe1},
1145  {0x1fea, 0x1f7a},
1146  {0x1feb, 0x1f7b},
1147  {0x1fec, 0x1fe5},
1148  {0x1ff8, 0x1f78},
1149  {0x1ff9, 0x1f79},
1150  {0x1ffa, 0x1f7c},
1151  {0x1ffb, 0x1f7d},
1152  {0x1ffc, 0x1ff3},
1153  {0x2126, 0x3c9},
1154  {0x212a, 0x6b},
1155  {0x212b, 0xe5},
1156  {0x2160, 0x2170},
1157  {0x2161, 0x2171},
1158  {0x2162, 0x2172},
1159  {0x2163, 0x2173},
1160  {0x2164, 0x2174},
1161  {0x2165, 0x2175},
1162  {0x2166, 0x2176},
1163  {0x2167, 0x2177},
1164  {0x2168, 0x2178},
1165  {0x2169, 0x2179},
1166  {0x216a, 0x217a},
1167  {0x216b, 0x217b},
1168  {0x216c, 0x217c},
1169  {0x216d, 0x217d},
1170  {0x216e, 0x217e},
1171  {0x216f, 0x217f},
1172  {0x24b6, 0x24d0},
1173  {0x24b7, 0x24d1},
1174  {0x24b8, 0x24d2},
1175  {0x24b9, 0x24d3},
1176  {0x24ba, 0x24d4},
1177  {0x24bb, 0x24d5},
1178  {0x24bc, 0x24d6},
1179  {0x24bd, 0x24d7},
1180  {0x24be, 0x24d8},
1181  {0x24bf, 0x24d9},
1182  {0x24c0, 0x24da},
1183  {0x24c1, 0x24db},
1184  {0x24c2, 0x24dc},
1185  {0x24c3, 0x24dd},
1186  {0x24c4, 0x24de},
1187  {0x24c5, 0x24df},
1188  {0x24c6, 0x24e0},
1189  {0x24c7, 0x24e1},
1190  {0x24c8, 0x24e2},
1191  {0x24c9, 0x24e3},
1192  {0x24ca, 0x24e4},
1193  {0x24cb, 0x24e5},
1194  {0x24cc, 0x24e6},
1195  {0x24cd, 0x24e7},
1196  {0x24ce, 0x24e8},
1197  {0x24cf, 0x24e9},
1198  {0xff21, 0xff41},
1199  {0xff22, 0xff42},
1200  {0xff23, 0xff43},
1201  {0xff24, 0xff44},
1202  {0xff25, 0xff45},
1203  {0xff26, 0xff46},
1204  {0xff27, 0xff47},
1205  {0xff28, 0xff48},
1206  {0xff29, 0xff49},
1207  {0xff2a, 0xff4a},
1208  {0xff2b, 0xff4b},
1209  {0xff2c, 0xff4c},
1210  {0xff2d, 0xff4d},
1211  {0xff2e, 0xff4e},
1212  {0xff2f, 0xff4f},
1213  {0xff30, 0xff50},
1214  {0xff31, 0xff51},
1215  {0xff32, 0xff52},
1216  {0xff33, 0xff53},
1217  {0xff34, 0xff54},
1218  {0xff35, 0xff55},
1219  {0xff36, 0xff56},
1220  {0xff37, 0xff57},
1221  {0xff38, 0xff58},
1222  {0xff39, 0xff59},
1223  {0xff3a, 0xff5a},
1224  {0x10400, 0x10428},
1225  {0x10401, 0x10429},
1226  {0x10402, 0x1042a},
1227  {0x10403, 0x1042b},
1228  {0x10404, 0x1042c},
1229  {0x10405, 0x1042d},
1230  {0x10406, 0x1042e},
1231  {0x10407, 0x1042f},
1232  {0x10408, 0x10430},
1233  {0x10409, 0x10431},
1234  {0x1040a, 0x10432},
1235  {0x1040b, 0x10433},
1236  {0x1040c, 0x10434},
1237  {0x1040d, 0x10435},
1238  {0x1040e, 0x10436},
1239  {0x1040f, 0x10437},
1240  {0x10410, 0x10438},
1241  {0x10411, 0x10439},
1242  {0x10412, 0x1043a},
1243  {0x10413, 0x1043b},
1244  {0x10414, 0x1043c},
1245  {0x10415, 0x1043d},
1246  {0x10416, 0x1043e},
1247  {0x10417, 0x1043f},
1248  {0x10418, 0x10440},
1249  {0x10419, 0x10441},
1250  {0x1041a, 0x10442},
1251  {0x1041b, 0x10443},
1252  {0x1041c, 0x10444},
1253  {0x1041d, 0x10445},
1254  {0x1041e, 0x10446},
1255  {0x1041f, 0x10447},
1256  {0x10420, 0x10448},
1257  {0x10421, 0x10449},
1258  {0x10422, 0x1044a},
1259  {0x10423, 0x1044b},
1260  {0x10424, 0x1044c},
1261  {0x10425, 0x1044d},
1262  {0x10426, 0x1044e},
1263  {0x10427, 0x1044f},
1264 };
1265 
1266 const CaseMapping upperMappings[] =
1267 {
1268  {0x61, 0x41},
1269  {0x62, 0x42},
1270  {0x63, 0x43},
1271  {0x64, 0x44},
1272  {0x65, 0x45},
1273  {0x66, 0x46},
1274  {0x67, 0x47},
1275  {0x68, 0x48},
1276  {0x69, 0x49},
1277  {0x6a, 0x4a},
1278  {0x6b, 0x4b},
1279  {0x6c, 0x4c},
1280  {0x6d, 0x4d},
1281  {0x6e, 0x4e},
1282  {0x6f, 0x4f},
1283  {0x70, 0x50},
1284  {0x71, 0x51},
1285  {0x72, 0x52},
1286  {0x73, 0x53},
1287  {0x74, 0x54},
1288  {0x75, 0x55},
1289  {0x76, 0x56},
1290  {0x77, 0x57},
1291  {0x78, 0x58},
1292  {0x79, 0x59},
1293  {0x7a, 0x5a},
1294  {0xb5, 0x39c},
1295  {0xe0, 0xc0},
1296  {0xe1, 0xc1},
1297  {0xe2, 0xc2},
1298  {0xe3, 0xc3},
1299  {0xe4, 0xc4},
1300  {0xe5, 0xc5},
1301  {0xe6, 0xc6},
1302  {0xe7, 0xc7},
1303  {0xe8, 0xc8},
1304  {0xe9, 0xc9},
1305  {0xea, 0xca},
1306  {0xeb, 0xcb},
1307  {0xec, 0xcc},
1308  {0xed, 0xcd},
1309  {0xee, 0xce},
1310  {0xef, 0xcf},
1311  {0xf0, 0xd0},
1312  {0xf1, 0xd1},
1313  {0xf2, 0xd2},
1314  {0xf3, 0xd3},
1315  {0xf4, 0xd4},
1316  {0xf5, 0xd5},
1317  {0xf6, 0xd6},
1318  {0xf8, 0xd8},
1319  {0xf9, 0xd9},
1320  {0xfa, 0xda},
1321  {0xfb, 0xdb},
1322  {0xfc, 0xdc},
1323  {0xfd, 0xdd},
1324  {0xfe, 0xde},
1325  {0xff, 0x178},
1326  {0x101, 0x100},
1327  {0x103, 0x102},
1328  {0x105, 0x104},
1329  {0x107, 0x106},
1330  {0x109, 0x108},
1331  {0x10b, 0x10a},
1332  {0x10d, 0x10c},
1333  {0x10f, 0x10e},
1334  {0x111, 0x110},
1335  {0x113, 0x112},
1336  {0x115, 0x114},
1337  {0x117, 0x116},
1338  {0x119, 0x118},
1339  {0x11b, 0x11a},
1340  {0x11d, 0x11c},
1341  {0x11f, 0x11e},
1342  {0x121, 0x120},
1343  {0x123, 0x122},
1344  {0x125, 0x124},
1345  {0x127, 0x126},
1346  {0x129, 0x128},
1347  {0x12b, 0x12a},
1348  {0x12d, 0x12c},
1349  {0x12f, 0x12e},
1350  {0x131, 0x49},
1351  {0x133, 0x132},
1352  {0x135, 0x134},
1353  {0x137, 0x136},
1354  {0x13a, 0x139},
1355  {0x13c, 0x13b},
1356  {0x13e, 0x13d},
1357  {0x140, 0x13f},
1358  {0x142, 0x141},
1359  {0x144, 0x143},
1360  {0x146, 0x145},
1361  {0x148, 0x147},
1362  {0x14b, 0x14a},
1363  {0x14d, 0x14c},
1364  {0x14f, 0x14e},
1365  {0x151, 0x150},
1366  {0x153, 0x152},
1367  {0x155, 0x154},
1368  {0x157, 0x156},
1369  {0x159, 0x158},
1370  {0x15b, 0x15a},
1371  {0x15d, 0x15c},
1372  {0x15f, 0x15e},
1373  {0x161, 0x160},
1374  {0x163, 0x162},
1375  {0x165, 0x164},
1376  {0x167, 0x166},
1377  {0x169, 0x168},
1378  {0x16b, 0x16a},
1379  {0x16d, 0x16c},
1380  {0x16f, 0x16e},
1381  {0x171, 0x170},
1382  {0x173, 0x172},
1383  {0x175, 0x174},
1384  {0x177, 0x176},
1385  {0x17a, 0x179},
1386  {0x17c, 0x17b},
1387  {0x17e, 0x17d},
1388  {0x17f, 0x53},
1389  {0x183, 0x182},
1390  {0x185, 0x184},
1391  {0x188, 0x187},
1392  {0x18c, 0x18b},
1393  {0x192, 0x191},
1394  {0x195, 0x1f6},
1395  {0x199, 0x198},
1396  {0x19e, 0x220},
1397  {0x1a1, 0x1a0},
1398  {0x1a3, 0x1a2},
1399  {0x1a5, 0x1a4},
1400  {0x1a8, 0x1a7},
1401  {0x1ad, 0x1ac},
1402  {0x1b0, 0x1af},
1403  {0x1b4, 0x1b3},
1404  {0x1b6, 0x1b5},
1405  {0x1b9, 0x1b8},
1406  {0x1bd, 0x1bc},
1407  {0x1bf, 0x1f7},
1408  {0x1c5, 0x1c4},
1409  {0x1c6, 0x1c4},
1410  {0x1c8, 0x1c7},
1411  {0x1c9, 0x1c7},
1412  {0x1cb, 0x1ca},
1413  {0x1cc, 0x1ca},
1414  {0x1ce, 0x1cd},
1415  {0x1d0, 0x1cf},
1416  {0x1d2, 0x1d1},
1417  {0x1d4, 0x1d3},
1418  {0x1d6, 0x1d5},
1419  {0x1d8, 0x1d7},
1420  {0x1da, 0x1d9},
1421  {0x1dc, 0x1db},
1422  {0x1dd, 0x18e},
1423  {0x1df, 0x1de},
1424  {0x1e1, 0x1e0},
1425  {0x1e3, 0x1e2},
1426  {0x1e5, 0x1e4},
1427  {0x1e7, 0x1e6},
1428  {0x1e9, 0x1e8},
1429  {0x1eb, 0x1ea},
1430  {0x1ed, 0x1ec},
1431  {0x1ef, 0x1ee},
1432  {0x1f2, 0x1f1},
1433  {0x1f3, 0x1f1},
1434  {0x1f5, 0x1f4},
1435  {0x1f9, 0x1f8},
1436  {0x1fb, 0x1fa},
1437  {0x1fd, 0x1fc},
1438  {0x1ff, 0x1fe},
1439  {0x201, 0x200},
1440  {0x203, 0x202},
1441  {0x205, 0x204},
1442  {0x207, 0x206},
1443  {0x209, 0x208},
1444  {0x20b, 0x20a},
1445  {0x20d, 0x20c},
1446  {0x20f, 0x20e},
1447  {0x211, 0x210},
1448  {0x213, 0x212},
1449  {0x215, 0x214},
1450  {0x217, 0x216},
1451  {0x219, 0x218},
1452  {0x21b, 0x21a},
1453  {0x21d, 0x21c},
1454  {0x21f, 0x21e},
1455  {0x223, 0x222},
1456  {0x225, 0x224},
1457  {0x227, 0x226},
1458  {0x229, 0x228},
1459  {0x22b, 0x22a},
1460  {0x22d, 0x22c},
1461  {0x22f, 0x22e},
1462  {0x231, 0x230},
1463  {0x233, 0x232},
1464  {0x253, 0x181},
1465  {0x254, 0x186},
1466  {0x256, 0x189},
1467  {0x257, 0x18a},
1468  {0x259, 0x18f},
1469  {0x25b, 0x190},
1470  {0x260, 0x193},
1471  {0x263, 0x194},
1472  {0x268, 0x197},
1473  {0x269, 0x196},
1474  {0x26f, 0x19c},
1475  {0x272, 0x19d},
1476  {0x275, 0x19f},
1477  {0x280, 0x1a6},
1478  {0x283, 0x1a9},
1479  {0x288, 0x1ae},
1480  {0x28a, 0x1b1},
1481  {0x28b, 0x1b2},
1482  {0x292, 0x1b7},
1483  {0x345, 0x399},
1484  {0x3ac, 0x386},
1485  {0x3ad, 0x388},
1486  {0x3ae, 0x389},
1487  {0x3af, 0x38a},
1488  {0x3b1, 0x391},
1489  {0x3b2, 0x392},
1490  {0x3b3, 0x393},
1491  {0x3b4, 0x394},
1492  {0x3b5, 0x395},
1493  {0x3b6, 0x396},
1494  {0x3b7, 0x397},
1495  {0x3b8, 0x398},
1496  {0x3b9, 0x399},
1497  {0x3ba, 0x39a},
1498  {0x3bb, 0x39b},
1499  {0x3bc, 0x39c},
1500  {0x3bd, 0x39d},
1501  {0x3be, 0x39e},
1502  {0x3bf, 0x39f},
1503  {0x3c0, 0x3a0},
1504  {0x3c1, 0x3a1},
1505  {0x3c2, 0x3a3},
1506  {0x3c3, 0x3a3},
1507  {0x3c4, 0x3a4},
1508  {0x3c5, 0x3a5},
1509  {0x3c6, 0x3a6},
1510  {0x3c7, 0x3a7},
1511  {0x3c8, 0x3a8},
1512  {0x3c9, 0x3a9},
1513  {0x3ca, 0x3aa},
1514  {0x3cb, 0x3ab},
1515  {0x3cc, 0x38c},
1516  {0x3cd, 0x38e},
1517  {0x3ce, 0x38f},
1518  {0x3d0, 0x392},
1519  {0x3d1, 0x398},
1520  {0x3d5, 0x3a6},
1521  {0x3d6, 0x3a0},
1522  {0x3d9, 0x3d8},
1523  {0x3db, 0x3da},
1524  {0x3dd, 0x3dc},
1525  {0x3df, 0x3de},
1526  {0x3e1, 0x3e0},
1527  {0x3e3, 0x3e2},
1528  {0x3e5, 0x3e4},
1529  {0x3e7, 0x3e6},
1530  {0x3e9, 0x3e8},
1531  {0x3eb, 0x3ea},
1532  {0x3ed, 0x3ec},
1533  {0x3ef, 0x3ee},
1534  {0x3f0, 0x39a},
1535  {0x3f1, 0x3a1},
1536  {0x3f2, 0x3f9},
1537  {0x3f5, 0x395},
1538  {0x3f8, 0x3f7},
1539  {0x3fb, 0x3fa},
1540  {0x430, 0x410},
1541  {0x431, 0x411},
1542  {0x432, 0x412},
1543  {0x433, 0x413},
1544  {0x434, 0x414},
1545  {0x435, 0x415},
1546  {0x436, 0x416},
1547  {0x437, 0x417},
1548  {0x438, 0x418},
1549  {0x439, 0x419},
1550  {0x43a, 0x41a},
1551  {0x43b, 0x41b},
1552  {0x43c, 0x41c},
1553  {0x43d, 0x41d},
1554  {0x43e, 0x41e},
1555  {0x43f, 0x41f},
1556  {0x440, 0x420},
1557  {0x441, 0x421},
1558  {0x442, 0x422},
1559  {0x443, 0x423},
1560  {0x444, 0x424},
1561  {0x445, 0x425},
1562  {0x446, 0x426},
1563  {0x447, 0x427},
1564  {0x448, 0x428},
1565  {0x449, 0x429},
1566  {0x44a, 0x42a},
1567  {0x44b, 0x42b},
1568  {0x44c, 0x42c},
1569  {0x44d, 0x42d},
1570  {0x44e, 0x42e},
1571  {0x44f, 0x42f},
1572  {0x450, 0x400},
1573  {0x451, 0x401},
1574  {0x452, 0x402},
1575  {0x453, 0x403},
1576  {0x454, 0x404},
1577  {0x455, 0x405},
1578  {0x456, 0x406},
1579  {0x457, 0x407},
1580  {0x458, 0x408},
1581  {0x459, 0x409},
1582  {0x45a, 0x40a},
1583  {0x45b, 0x40b},
1584  {0x45c, 0x40c},
1585  {0x45d, 0x40d},
1586  {0x45e, 0x40e},
1587  {0x45f, 0x40f},
1588  {0x461, 0x460},
1589  {0x463, 0x462},
1590  {0x465, 0x464},
1591  {0x467, 0x466},
1592  {0x469, 0x468},
1593  {0x46b, 0x46a},
1594  {0x46d, 0x46c},
1595  {0x46f, 0x46e},
1596  {0x471, 0x470},
1597  {0x473, 0x472},
1598  {0x475, 0x474},
1599  {0x477, 0x476},
1600  {0x479, 0x478},
1601  {0x47b, 0x47a},
1602  {0x47d, 0x47c},
1603  {0x47f, 0x47e},
1604  {0x481, 0x480},
1605  {0x48b, 0x48a},
1606  {0x48d, 0x48c},
1607  {0x48f, 0x48e},
1608  {0x491, 0x490},
1609  {0x493, 0x492},
1610  {0x495, 0x494},
1611  {0x497, 0x496},
1612  {0x499, 0x498},
1613  {0x49b, 0x49a},
1614  {0x49d, 0x49c},
1615  {0x49f, 0x49e},
1616  {0x4a1, 0x4a0},
1617  {0x4a3, 0x4a2},
1618  {0x4a5, 0x4a4},
1619  {0x4a7, 0x4a6},
1620  {0x4a9, 0x4a8},
1621  {0x4ab, 0x4aa},
1622  {0x4ad, 0x4ac},
1623  {0x4af, 0x4ae},
1624  {0x4b1, 0x4b0},
1625  {0x4b3, 0x4b2},
1626  {0x4b5, 0x4b4},
1627  {0x4b7, 0x4b6},
1628  {0x4b9, 0x4b8},
1629  {0x4bb, 0x4ba},
1630  {0x4bd, 0x4bc},
1631  {0x4bf, 0x4be},
1632  {0x4c2, 0x4c1},
1633  {0x4c4, 0x4c3},
1634  {0x4c6, 0x4c5},
1635  {0x4c8, 0x4c7},
1636  {0x4ca, 0x4c9},
1637  {0x4cc, 0x4cb},
1638  {0x4ce, 0x4cd},
1639  {0x4d1, 0x4d0},
1640  {0x4d3, 0x4d2},
1641  {0x4d5, 0x4d4},
1642  {0x4d7, 0x4d6},
1643  {0x4d9, 0x4d8},
1644  {0x4db, 0x4da},
1645  {0x4dd, 0x4dc},
1646  {0x4df, 0x4de},
1647  {0x4e1, 0x4e0},
1648  {0x4e3, 0x4e2},
1649  {0x4e5, 0x4e4},
1650  {0x4e7, 0x4e6},
1651  {0x4e9, 0x4e8},
1652  {0x4eb, 0x4ea},
1653  {0x4ed, 0x4ec},
1654  {0x4ef, 0x4ee},
1655  {0x4f1, 0x4f0},
1656  {0x4f3, 0x4f2},
1657  {0x4f5, 0x4f4},
1658  {0x4f9, 0x4f8},
1659  {0x501, 0x500},
1660  {0x503, 0x502},
1661  {0x505, 0x504},
1662  {0x507, 0x506},
1663  {0x509, 0x508},
1664  {0x50b, 0x50a},
1665  {0x50d, 0x50c},
1666  {0x50f, 0x50e},
1667  {0x561, 0x531},
1668  {0x562, 0x532},
1669  {0x563, 0x533},
1670  {0x564, 0x534},
1671  {0x565, 0x535},
1672  {0x566, 0x536},
1673  {0x567, 0x537},
1674  {0x568, 0x538},
1675  {0x569, 0x539},
1676  {0x56a, 0x53a},
1677  {0x56b, 0x53b},
1678  {0x56c, 0x53c},
1679  {0x56d, 0x53d},
1680  {0x56e, 0x53e},
1681  {0x56f, 0x53f},
1682  {0x570, 0x540},
1683  {0x571, 0x541},
1684  {0x572, 0x542},
1685  {0x573, 0x543},
1686  {0x574, 0x544},
1687  {0x575, 0x545},
1688  {0x576, 0x546},
1689  {0x577, 0x547},
1690  {0x578, 0x548},
1691  {0x579, 0x549},
1692  {0x57a, 0x54a},
1693  {0x57b, 0x54b},
1694  {0x57c, 0x54c},
1695  {0x57d, 0x54d},
1696  {0x57e, 0x54e},
1697  {0x57f, 0x54f},
1698  {0x580, 0x550},
1699  {0x581, 0x551},
1700  {0x582, 0x552},
1701  {0x583, 0x553},
1702  {0x584, 0x554},
1703  {0x585, 0x555},
1704  {0x586, 0x556},
1705  {0x1e01, 0x1e00},
1706  {0x1e03, 0x1e02},
1707  {0x1e05, 0x1e04},
1708  {0x1e07, 0x1e06},
1709  {0x1e09, 0x1e08},
1710  {0x1e0b, 0x1e0a},
1711  {0x1e0d, 0x1e0c},
1712  {0x1e0f, 0x1e0e},
1713  {0x1e11, 0x1e10},
1714  {0x1e13, 0x1e12},
1715  {0x1e15, 0x1e14},
1716  {0x1e17, 0x1e16},
1717  {0x1e19, 0x1e18},
1718  {0x1e1b, 0x1e1a},
1719  {0x1e1d, 0x1e1c},
1720  {0x1e1f, 0x1e1e},
1721  {0x1e21, 0x1e20},
1722  {0x1e23, 0x1e22},
1723  {0x1e25, 0x1e24},
1724  {0x1e27, 0x1e26},
1725  {0x1e29, 0x1e28},
1726  {0x1e2b, 0x1e2a},
1727  {0x1e2d, 0x1e2c},
1728  {0x1e2f, 0x1e2e},
1729  {0x1e31, 0x1e30},
1730  {0x1e33, 0x1e32},
1731  {0x1e35, 0x1e34},
1732  {0x1e37, 0x1e36},
1733  {0x1e39, 0x1e38},
1734  {0x1e3b, 0x1e3a},
1735  {0x1e3d, 0x1e3c},
1736  {0x1e3f, 0x1e3e},
1737  {0x1e41, 0x1e40},
1738  {0x1e43, 0x1e42},
1739  {0x1e45, 0x1e44},
1740  {0x1e47, 0x1e46},
1741  {0x1e49, 0x1e48},
1742  {0x1e4b, 0x1e4a},
1743  {0x1e4d, 0x1e4c},
1744  {0x1e4f, 0x1e4e},
1745  {0x1e51, 0x1e50},
1746  {0x1e53, 0x1e52},
1747  {0x1e55, 0x1e54},
1748  {0x1e57, 0x1e56},
1749  {0x1e59, 0x1e58},
1750  {0x1e5b, 0x1e5a},
1751  {0x1e5d, 0x1e5c},
1752  {0x1e5f, 0x1e5e},
1753  {0x1e61, 0x1e60},
1754  {0x1e63, 0x1e62},
1755  {0x1e65, 0x1e64},
1756  {0x1e67, 0x1e66},
1757  {0x1e69, 0x1e68},
1758  {0x1e6b, 0x1e6a},
1759  {0x1e6d, 0x1e6c},
1760  {0x1e6f, 0x1e6e},
1761  {0x1e71, 0x1e70},
1762  {0x1e73, 0x1e72},
1763  {0x1e75, 0x1e74},
1764  {0x1e77, 0x1e76},
1765  {0x1e79, 0x1e78},
1766  {0x1e7b, 0x1e7a},
1767  {0x1e7d, 0x1e7c},
1768  {0x1e7f, 0x1e7e},
1769  {0x1e81, 0x1e80},
1770  {0x1e83, 0x1e82},
1771  {0x1e85, 0x1e84},
1772  {0x1e87, 0x1e86},
1773  {0x1e89, 0x1e88},
1774  {0x1e8b, 0x1e8a},
1775  {0x1e8d, 0x1e8c},
1776  {0x1e8f, 0x1e8e},
1777  {0x1e91, 0x1e90},
1778  {0x1e93, 0x1e92},
1779  {0x1e95, 0x1e94},
1780  {0x1e9b, 0x1e60},
1781  {0x1ea1, 0x1ea0},
1782  {0x1ea3, 0x1ea2},
1783  {0x1ea5, 0x1ea4},
1784  {0x1ea7, 0x1ea6},
1785  {0x1ea9, 0x1ea8},
1786  {0x1eab, 0x1eaa},
1787  {0x1ead, 0x1eac},
1788  {0x1eaf, 0x1eae},
1789  {0x1eb1, 0x1eb0},
1790  {0x1eb3, 0x1eb2},
1791  {0x1eb5, 0x1eb4},
1792  {0x1eb7, 0x1eb6},
1793  {0x1eb9, 0x1eb8},
1794  {0x1ebb, 0x1eba},
1795  {0x1ebd, 0x1ebc},
1796  {0x1ebf, 0x1ebe},
1797  {0x1ec1, 0x1ec0},
1798  {0x1ec3, 0x1ec2},
1799  {0x1ec5, 0x1ec4},
1800  {0x1ec7, 0x1ec6},
1801  {0x1ec9, 0x1ec8},
1802  {0x1ecb, 0x1eca},
1803  {0x1ecd, 0x1ecc},
1804  {0x1ecf, 0x1ece},
1805  {0x1ed1, 0x1ed0},
1806  {0x1ed3, 0x1ed2},
1807  {0x1ed5, 0x1ed4},
1808  {0x1ed7, 0x1ed6},
1809  {0x1ed9, 0x1ed8},
1810  {0x1edb, 0x1eda},
1811  {0x1edd, 0x1edc},
1812  {0x1edf, 0x1ede},
1813  {0x1ee1, 0x1ee0},
1814  {0x1ee3, 0x1ee2},
1815  {0x1ee5, 0x1ee4},
1816  {0x1ee7, 0x1ee6},
1817  {0x1ee9, 0x1ee8},
1818  {0x1eeb, 0x1eea},
1819  {0x1eed, 0x1eec},
1820  {0x1eef, 0x1eee},
1821  {0x1ef1, 0x1ef0},
1822  {0x1ef3, 0x1ef2},
1823  {0x1ef5, 0x1ef4},
1824  {0x1ef7, 0x1ef6},
1825  {0x1ef9, 0x1ef8},
1826  {0x1f00, 0x1f08},
1827  {0x1f01, 0x1f09},
1828  {0x1f02, 0x1f0a},
1829  {0x1f03, 0x1f0b},
1830  {0x1f04, 0x1f0c},
1831  {0x1f05, 0x1f0d},
1832  {0x1f06, 0x1f0e},
1833  {0x1f07, 0x1f0f},
1834  {0x1f10, 0x1f18},
1835  {0x1f11, 0x1f19},
1836  {0x1f12, 0x1f1a},
1837  {0x1f13, 0x1f1b},
1838  {0x1f14, 0x1f1c},
1839  {0x1f15, 0x1f1d},
1840  {0x1f20, 0x1f28},
1841  {0x1f21, 0x1f29},
1842  {0x1f22, 0x1f2a},
1843  {0x1f23, 0x1f2b},
1844  {0x1f24, 0x1f2c},
1845  {0x1f25, 0x1f2d},
1846  {0x1f26, 0x1f2e},
1847  {0x1f27, 0x1f2f},
1848  {0x1f30, 0x1f38},
1849  {0x1f31, 0x1f39},
1850  {0x1f32, 0x1f3a},
1851  {0x1f33, 0x1f3b},
1852  {0x1f34, 0x1f3c},
1853  {0x1f35, 0x1f3d},
1854  {0x1f36, 0x1f3e},
1855  {0x1f37, 0x1f3f},
1856  {0x1f40, 0x1f48},
1857  {0x1f41, 0x1f49},
1858  {0x1f42, 0x1f4a},
1859  {0x1f43, 0x1f4b},
1860  {0x1f44, 0x1f4c},
1861  {0x1f45, 0x1f4d},
1862  {0x1f51, 0x1f59},
1863  {0x1f53, 0x1f5b},
1864  {0x1f55, 0x1f5d},
1865  {0x1f57, 0x1f5f},
1866  {0x1f60, 0x1f68},
1867  {0x1f61, 0x1f69},
1868  {0x1f62, 0x1f6a},
1869  {0x1f63, 0x1f6b},
1870  {0x1f64, 0x1f6c},
1871  {0x1f65, 0x1f6d},
1872  {0x1f66, 0x1f6e},
1873  {0x1f67, 0x1f6f},
1874  {0x1f70, 0x1fba},
1875  {0x1f71, 0x1fbb},
1876  {0x1f72, 0x1fc8},
1877  {0x1f73, 0x1fc9},
1878  {0x1f74, 0x1fca},
1879  {0x1f75, 0x1fcb},
1880  {0x1f76, 0x1fda},
1881  {0x1f77, 0x1fdb},
1882  {0x1f78, 0x1ff8},
1883  {0x1f79, 0x1ff9},
1884  {0x1f7a, 0x1fea},
1885  {0x1f7b, 0x1feb},
1886  {0x1f7c, 0x1ffa},
1887  {0x1f7d, 0x1ffb},
1888  {0x1f80, 0x1f88},
1889  {0x1f81, 0x1f89},
1890  {0x1f82, 0x1f8a},
1891  {0x1f83, 0x1f8b},
1892  {0x1f84, 0x1f8c},
1893  {0x1f85, 0x1f8d},
1894  {0x1f86, 0x1f8e},
1895  {0x1f87, 0x1f8f},
1896  {0x1f90, 0x1f98},
1897  {0x1f91, 0x1f99},
1898  {0x1f92, 0x1f9a},
1899  {0x1f93, 0x1f9b},
1900  {0x1f94, 0x1f9c},
1901  {0x1f95, 0x1f9d},
1902  {0x1f96, 0x1f9e},
1903  {0x1f97, 0x1f9f},
1904  {0x1fa0, 0x1fa8},
1905  {0x1fa1, 0x1fa9},
1906  {0x1fa2, 0x1faa},
1907  {0x1fa3, 0x1fab},
1908  {0x1fa4, 0x1fac},
1909  {0x1fa5, 0x1fad},
1910  {0x1fa6, 0x1fae},
1911  {0x1fa7, 0x1faf},
1912  {0x1fb0, 0x1fb8},
1913  {0x1fb1, 0x1fb9},
1914  {0x1fb3, 0x1fbc},
1915  {0x1fbe, 0x399},
1916  {0x1fc3, 0x1fcc},
1917  {0x1fd0, 0x1fd8},
1918  {0x1fd1, 0x1fd9},
1919  {0x1fe0, 0x1fe8},
1920  {0x1fe1, 0x1fe9},
1921  {0x1fe5, 0x1fec},
1922  {0x1ff3, 0x1ffc},
1923  {0x2170, 0x2160},
1924  {0x2171, 0x2161},
1925  {0x2172, 0x2162},
1926  {0x2173, 0x2163},
1927  {0x2174, 0x2164},
1928  {0x2175, 0x2165},
1929  {0x2176, 0x2166},
1930  {0x2177, 0x2167},
1931  {0x2178, 0x2168},
1932  {0x2179, 0x2169},
1933  {0x217a, 0x216a},
1934  {0x217b, 0x216b},
1935  {0x217c, 0x216c},
1936  {0x217d, 0x216d},
1937  {0x217e, 0x216e},
1938  {0x217f, 0x216f},
1939  {0x24d0, 0x24b6},
1940  {0x24d1, 0x24b7},
1941  {0x24d2, 0x24b8},
1942  {0x24d3, 0x24b9},
1943  {0x24d4, 0x24ba},
1944  {0x24d5, 0x24bb},
1945  {0x24d6, 0x24bc},
1946  {0x24d7, 0x24bd},
1947  {0x24d8, 0x24be},
1948  {0x24d9, 0x24bf},
1949  {0x24da, 0x24c0},
1950  {0x24db, 0x24c1},
1951  {0x24dc, 0x24c2},
1952  {0x24dd, 0x24c3},
1953  {0x24de, 0x24c4},
1954  {0x24df, 0x24c5},
1955  {0x24e0, 0x24c6},
1956  {0x24e1, 0x24c7},
1957  {0x24e2, 0x24c8},
1958  {0x24e3, 0x24c9},
1959  {0x24e4, 0x24ca},
1960  {0x24e5, 0x24cb},
1961  {0x24e6, 0x24cc},
1962  {0x24e7, 0x24cd},
1963  {0x24e8, 0x24ce},
1964  {0x24e9, 0x24cf},
1965  {0xff41, 0xff21},
1966  {0xff42, 0xff22},
1967  {0xff43, 0xff23},
1968  {0xff44, 0xff24},
1969  {0xff45, 0xff25},
1970  {0xff46, 0xff26},
1971  {0xff47, 0xff27},
1972  {0xff48, 0xff28},
1973  {0xff49, 0xff29},
1974  {0xff4a, 0xff2a},
1975  {0xff4b, 0xff2b},
1976  {0xff4c, 0xff2c},
1977  {0xff4d, 0xff2d},
1978  {0xff4e, 0xff2e},
1979  {0xff4f, 0xff2f},
1980  {0xff50, 0xff30},
1981  {0xff51, 0xff31},
1982  {0xff52, 0xff32},
1983  {0xff53, 0xff33},
1984  {0xff54, 0xff34},
1985  {0xff55, 0xff35},
1986  {0xff56, 0xff36},
1987  {0xff57, 0xff37},
1988  {0xff58, 0xff38},
1989  {0xff59, 0xff39},
1990  {0xff5a, 0xff3a},
1991  {0x10428, 0x10400},
1992  {0x10429, 0x10401},
1993  {0x1042a, 0x10402},
1994  {0x1042b, 0x10403},
1995  {0x1042c, 0x10404},
1996  {0x1042d, 0x10405},
1997  {0x1042e, 0x10406},
1998  {0x1042f, 0x10407},
1999  {0x10430, 0x10408},
2000  {0x10431, 0x10409},
2001  {0x10432, 0x1040a},
2002  {0x10433, 0x1040b},
2003  {0x10434, 0x1040c},
2004  {0x10435, 0x1040d},
2005  {0x10436, 0x1040e},
2006  {0x10437, 0x1040f},
2007  {0x10438, 0x10410},
2008  {0x10439, 0x10411},
2009  {0x1043a, 0x10412},
2010  {0x1043b, 0x10413},
2011  {0x1043c, 0x10414},
2012  {0x1043d, 0x10415},
2013  {0x1043e, 0x10416},
2014  {0x1043f, 0x10417},
2015  {0x10440, 0x10418},
2016  {0x10441, 0x10419},
2017  {0x10442, 0x1041a},
2018  {0x10443, 0x1041b},
2019  {0x10444, 0x1041c},
2020  {0x10445, 0x1041d},
2021  {0x10446, 0x1041e},
2022  {0x10447, 0x1041f},
2023  {0x10448, 0x10420},
2024  {0x10449, 0x10421},
2025  {0x1044a, 0x10422},
2026  {0x1044b, 0x10423},
2027  {0x1044c, 0x10424},
2028  {0x1044d, 0x10425},
2029  {0x1044e, 0x10426},
2030  {0x1044f, 0x10427},
2031 };
2032 
2033 const CaseMapping* const lowerMappingsEnd = lowerMappings +
2034  (sizeof(lowerMappings)/sizeof(lowerMappings[0]));
2035 
2036 const CaseMapping* const upperMappingsEnd = upperMappings +
2037  (sizeof(upperMappings)/sizeof(upperMappings[0]));
2038 
2039 struct MappingOrdering
2040 {
2041  bool operator()(const CaseMapping& x, const CaseMapping& y)
2042  {
2043  return x.codePoint < y.codePoint;
2044  }
2045 };
2046 
2047 struct Transformer
2048 {
2049  Transformer(const CaseMapping* const begin, const CaseMapping* const end)
2050  : m_begin(begin)
2051  , m_end(end)
2052  {
2053  }
2054 
2055  UInt32 operator()(UInt32 in) const
2056  {
2057  CaseMapping val = { in, 0 };
2058  const CaseMapping* i = std::lower_bound(m_begin, m_end, val, MappingOrdering());
2059  if (i == m_end || i->codePoint != in)
2060  {
2061  return in;
2062  }
2063  else
2064  {
2065  return i->mapping;
2066  }
2067  }
2068  const CaseMapping* const m_begin;
2069  const CaseMapping* const m_end;
2070 };
2071 
2072 } // end unnamed namespace
2073 
2075 bool toUpperCaseInPlace(char* input)
2076 {
2077  return transformInPlace(input, Transformer(upperMappings, upperMappingsEnd));
2078 }
2079 
2081 String toUpperCase(const char* input)
2082 {
2083  return transform(input, Transformer(upperMappings, upperMappingsEnd));
2084 }
2085 
2087 bool toLowerCaseInPlace(char* input)
2088 {
2089  return transformInPlace(input, Transformer(lowerMappings, lowerMappingsEnd));
2090 }
2091 
2093 String toLowerCase(const char* input)
2094 {
2095  return transform(input, Transformer(lowerMappings, lowerMappingsEnd));
2096 }
2097 
2098 } // end namespace UTF8Utils
2099 
2100 } // end namespace BLOCXX_NAMESPACE
2101 
2102