Initial commit
[mono.git] / mcs / class / referencesource / mscorlib / system / text / gb18030encoding.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6
7 //  GB18030Encoding.cs
8 //
9 //  Ported to managed code from c_gb18030.c and related gb18030 dll files
10 //
11 //
12 //  Abstract:
13 //
14 //      Managed implimentation of GB18030-2000 (code page 54936) ported from implimentation in c_g18030.dll
15 //      If you find a bug here you should check there (in windows) as well and visa versa.
16 //      This file contains functions to convert GB18030-2000 (code page 54936) into Unicode, and vice versa.
17 //
18 //  Notes:
19 //      GB18030-2000 (aka GBK2K) is designed to be mostly compatible with GBK (codepage 936),
20 //      while supports the full range of Unicode code points (BMP + 16 supplementary planes).
21 //
22 //      The structure for GB18030 is:
23 //          * Single byte:
24 //              0x00 ~ 0x7f
25 //          * Two-byte:
26 //              0x81 ~ 0xfe, 0x40 ~ 0x7e    (leading byte, trailing byte)
27 //              0x81 ~ 0xfe, 0x80 ~ 0xfe    (leading byte, trailing byte)
28 //          * Four-byte:
29 //              0x81 ~ 0xfe, 0x30 ~ 0x39, 0x81 ~ 0xfe, 0x30 ~ 0x39.
30 //              The surrogare pair will be encoded from 0x90, 0x30, 0x81, 0x30
31 //
32 //      The BMP range is fully supported in GB18030 using 1-byte, 2-byte and 4-byte sequences.
33 //      In valid 4-byte GB18030, there are two gaps that can not be mapped to Unicode characters.
34 //          0x84, 0x31, 0xa5, 0x30 (just after the GB18030 bytes for U+FFFF(*)) ~ 0x8f, 0x39, 0xfe, 0x39 (just before the first GB18030 bytes for U+D800,U+DC00)
35 //          0xe3, 0x32, 0x9a, 0x36 (just after the GB18030 bytes for U+DBFF U+DFFF(**)) ~ 0xfe, 0x39, 0xfe, 0x39
36 //
37 //
38 //          Note1: U+FFFF = 0x84, 0x31, 0xa4, 0x39
39 //          Note2: U+DBFF U+DFFF = 0xe3, 0x32, 0x9a, 0x35
40 //
41 //      Tables used in GB18030Encoding:
42 //
43 //          Our data is similar to the 936 Code Page, so we start from there to build our tables.  We build the
44 //          normal double byte mapUnicodeToBytes and mapBytesToUnicode tables by applying differences from 936.
45 //          We also build a map4BytesToUnicode table and a mapUnicodeTo4BytesFlags
46 //
47 //          * mapUnicodeTo4BytesFlags
48 //              This is an array of bytes, so we have to do a / 8 and << %8 to check the appropriate bit (see Is4Byte())
49 //              If the bit is set its true.
50 //
51 //              true    - If set/true this is a 4 byte code.  The value in mapUnicodeToBytes will be the 4 byte offset
52 //              false   - If cleared/false this is a 1 or 2 byte code.  The value in mapUnicodeToBytes will be the 2 bytes.
53 //
54 //          * mapUnicodeToBytes
55 //              Contains either the 2 byte value of double byte GB18030 or the 4 byte offset for 4 byte GB18030,
56 //              depending on the value of the flag in mapUnicodeTo4BytesFlags
57 //
58 //          * mapBytesToUnicode
59 //              mapBytesToUnicode maps 2 byte GB 18030 to Unicode like other DBCS code pages.
60 //
61 //          * map4BytesToUnicode
62 //              map4BytesToUnicode is indexed by the 4 byte offset and contains the unicode value for each 4 byte offset
63 //
64 //
65 //      4 Byte sequences
66 //          We generally use the offset for the 4 byte sequence, such as:
67 //
68 //          The index value is the offset of the 4-byte GB18030.
69 //
70 //          4-byte GB18030      Index value
71 //          ==============      ===========
72 //          81,30,81,30         0
73 //          81,30,81,31         1
74 //          81,30,81,32         2
75 //          ...                 ...
76 //
77 //          The value of map4BytesToUnicode cotains the Unicode codepoint for the offset of the
78 //          corresponding 4-byte GB18030.
79 //
80 //          E.g. map4BytesToUnicode[0] = 0x0080.  This means that GB18030 0x81, 0x30, 0x81, 0x30 will be converted to Unicode U+0800.
81 //
82 //      4 Byte Surrogate Sequences
83 //          Those work similarly to the normal 4 byte sequences, but start at a different offset
84 //
85 //  We don't override IsAlwaysNormalized because GB18030 covers all of the unicode space, so isn't guaranteed to be normal.
86 //
87 #if FEATURE_CODEPAGES_FILE // requires BaseCodePageEncooding
88 namespace System.Text
89 {
90     using System;
91     using System.Diagnostics.Contracts;
92     using System.Text;
93     using System.Runtime.InteropServices;
94     using System.Security;
95     using System.Runtime.CompilerServices;
96     using System.Runtime.Serialization;
97     using System.Runtime.Versioning;
98     using System.Security.Permissions;
99     using System.Globalization;
100
101     /*=================================GB18030Encoding============================
102     **
103     ** This is used to support GB18030-2000 encoding (code page 54936).
104     **
105     ==============================================================================*/
106
107     [Serializable]
108     internal sealed class GB18030Encoding : DBCSCodePageEncoding, ISerializable
109     {
110         // This is the table of 4 byte conversions.
111         private const int GBLast4ByteCode = 0x99FB;
112         [NonSerialized]
113         [SecurityCritical]
114         unsafe internal char* map4BytesToUnicode = null;       // new char[GBLast4ByteCode + 1]; // Need to map all 4 byte sequences to Unicode
115         [NonSerialized]
116         [SecurityCritical]
117         unsafe internal byte* mapUnicodeTo4BytesFlags = null;  // new byte[0x10000 / 8];         // Need 1 bit for each code point to say if its 4 byte or not
118
119         private const int GB18030       = 54936;
120
121         // First and last character of surrogate range as offset from 4 byte GB18030 GB81308130
122         private const int GBSurrogateOffset = 0x2E248;      // GB90308130
123         private const int GBLastSurrogateOffset = 0x12E247; // GBE3329A35
124
125         // We have to load the 936 code page tables, so impersonate 936 as our base
126         [System.Security.SecurityCritical]  // auto-generated
127         internal GB18030Encoding() : base(GB18030, 936)
128         {
129         }
130
131         // Constructor called by serialization.
132         [System.Security.SecurityCritical]  // auto-generated
133         internal GB18030Encoding(SerializationInfo info, StreamingContext context) :
134                                           base(GB18030, 936)
135         {
136             // Set up our base, also throws if info was empty
137             DeserializeEncoding(info, context);
138             Contract.Assert(info!=null, "[GB18030Encoding(Serialization...)] Expected null info to throw");
139
140             // Already build our code page, fallbacks & read only, so we're good to go!
141         }
142
143 #if FEATURE_SERIALIZATION
144         // ISerializable implementation
145         [System.Security.SecurityCritical]  // auto-generated_required
146         void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
147         {
148             // Make sure to get teh base stuff too This throws if info is null
149             SerializeEncoding(info, context);
150             Contract.Assert(info!=null, "[GB18030.GetObjectData] Expected null info to throw");
151
152             // Everett doesn't need more than the basics
153         }
154 #endif
155
156         // This loads our base 936 code page and then applys the changes from the tableUnicodeToGBDiffs table.
157         // See table comments for table format.
158         [System.Security.SecurityCritical]  // auto-generated
159         [ResourceExposure(ResourceScope.None)]
160         [ResourceConsumption(ResourceScope.Machine, ResourceScope.Process)]
161         protected override unsafe void LoadManagedCodePage()
162         {
163             // Use base code page loading algorithm.
164             // We need to use our main CP as our flag.
165             this.bFlagDataTable = false;
166             this.iExtraBytes = (GBLast4ByteCode + 1) * 2 + 0x10000 / 8;
167
168             // Load most of our code page
169             base.LoadManagedCodePage();
170
171             // Point to our new data sections
172             byte *pMemorySection = (byte *) safeMemorySectionHandle.DangerousGetHandle();
173             mapUnicodeTo4BytesFlags = pMemorySection + 65536 * 2 * 2;
174             map4BytesToUnicode = (char*)(pMemorySection + 65536 * 2 * 2 + 0x10000 / 8);
175
176             // Need to check our pointer to see if we're loaded, return if we're built already
177             if (*mapCodePageCached == this.CodePage)
178                 return;
179
180             // Once we've done our base LoadManagedCodePage, we'll have to add our fixes
181             char unicodeCount = (char)0;
182             ushort count4Byte = 0;
183             for (int index = 0; index < tableUnicodeToGBDiffs.Length; index++)
184             {
185                 ushort data = tableUnicodeToGBDiffs[index];
186
187                 // Check high bit
188                 if ((data & 0x8000) != 0)
189                 {
190                     // Make be exact value
191                     if (data > 0x9000 && data != 0xD1A6)
192                     {
193                         // It was an exact value (gb18040[data] = unicode)
194                         mapBytesToUnicode[data] = unicodeCount;
195                         mapUnicodeToBytes[unicodeCount] = data;
196                         unicodeCount++;
197                     }
198                     else
199                     {
200                         // It was a CP 936 compatible data, that table's already loaded, just increment our pointer
201                         unicodeCount += unchecked((char)(data & 0x7FFF));
202                     }
203                 }
204                 else
205                 {
206                     // It was GB 18030 4 byte data, next <data> characters are 4 byte sequences.
207                     while (data > 0)
208                     {
209                         Contract.Assert(count4Byte <= GBLast4ByteCode,
210                             "[GB18030Encoding.LoadManagedCodePage] Found too many 4 byte codes in data table.");
211
212                         // Set the 4 byte -> Unicode value
213                         map4BytesToUnicode[count4Byte] = unicodeCount;
214                         // Set the unicode -> 4 bytes value, including flag that its a 4 byte sequence
215                         mapUnicodeToBytes[unicodeCount] = count4Byte;
216                         // Set the flag saying its a 4 byte sequence
217                         mapUnicodeTo4BytesFlags[unicodeCount / 8] |= unchecked((byte)(1 << (unicodeCount % 8)));
218                         unicodeCount++;
219                         count4Byte++;
220                         data--;
221                     }
222
223                 }
224             }
225
226             // unicodeCount should've wrapped back to 0
227             Contract.Assert(unicodeCount == 0,
228                 "[GB18030Encoding.LoadManagedCodePage] Expected unicodeCount to wrap around to 0 as all chars were processed");
229
230             // We should've read in GBLast4ByteCode 4 byte sequences
231             Contract.Assert(count4Byte == GBLast4ByteCode + 1,
232                 "[GB18030Encoding.LoadManagedCodePage] Expected 0x99FB to be last 4 byte offset, found 0x" + count4Byte.ToString("X4", CultureInfo.InvariantCulture));
233
234             // Need to flag ourselves saying we've built this CP.
235             *mapCodePageCached = this.CodePage;
236         }
237
238         internal override void SetDefaultFallbacks()
239         {
240             // For GB18030Encoding just use default replacement fallbacks because its only for bad surrogates
241             this.encoderFallback = EncoderFallback.ReplacementFallback;
242             this.decoderFallback = DecoderFallback.ReplacementFallback;
243         }
244
245         // Is4Byte
246         // Checks the 4 byte table and returns true if this is a 4 byte code.
247         // Its a 4 byte code if the flag is set in mapUnicodeTo4BytesFlags
248         [System.Security.SecurityCritical]  // auto-generated
249         internal unsafe bool Is4Byte(char charTest)
250         {
251             // See what kind it is
252             byte b4Byte = mapUnicodeTo4BytesFlags[charTest / 8];
253             return (b4Byte != 0 && (b4Byte & (1 << (charTest % 8))) != 0);
254         }
255
256         // GetByteCount
257         [System.Security.SecurityCritical]  // auto-generated
258         internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS encoder)
259         {
260             // Just call GetBytes() with null bytes
261             return GetBytes(chars, count, null, 0, encoder);
262         }
263
264         [System.Security.SecurityCritical]  // auto-generated
265         internal override unsafe int GetBytes(char* chars, int charCount,
266                                                 byte* bytes, int byteCount, EncoderNLS encoder)
267         {
268             // Just need to ASSERT, this is called by something else internal that checked parameters already
269             // We'll allow null bytes as a count
270 //            Contract.Assert(bytes != null, "[GB18030Encoding.GetBytes]bytes is null");
271             Contract.Assert(byteCount >= 0, "[GB18030Encoding.GetBytes]byteCount is negative");
272             Contract.Assert(chars != null, "[GB18030Encoding.GetBytes]chars is null");
273             Contract.Assert(charCount >= 0, "[GB18030Encoding.GetBytes]charCount is negative");
274
275             // Assert because we shouldn't be able to have a null encoder.
276             Contract.Assert(encoderFallback != null, "[GB18030Encoding.GetBytes]Attempting to use null encoder fallback");
277
278             // Get any left over characters
279             char charLeftOver = (char)0;
280             if (encoder != null)
281                 charLeftOver = encoder.charLeftOver;
282
283             // prepare our helpers
284             Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(
285                 this, encoder, bytes, byteCount, chars, charCount);
286
287             // Try again if we were MustFlush
288             TryAgain:
289
290             // Go ahead and do it, including the fallback.
291             while (buffer.MoreData)
292             {
293                 // Get next char
294                 char ch = buffer.GetNextChar();
295
296                 // Have to check for charLeftOver
297                 if (charLeftOver != 0)
298                 {
299                     Contract.Assert(Char.IsHighSurrogate(charLeftOver),
300                         "[GB18030Encoding.GetBytes] leftover character should be high surrogate, not 0x" + ((int)charLeftOver).ToString("X4", CultureInfo.InvariantCulture));
301
302                     // If our next char isn't a low surrogate, then we need to do fallback.
303                     if (!Char.IsLowSurrogate(ch))
304                     {
305                         // No low surrogate, fallback high surrogate & try this one again
306                         buffer.MovePrevious(false);                  // (Ignoring this character, don't thow)
307                         if (!buffer.Fallback(charLeftOver))
308                         {
309                             charLeftOver = (char)0;
310                             break;
311                         }
312                         charLeftOver = (char)0;
313                         continue;
314                     }
315                     else
316                     {
317                         // Next is a surrogate, add it as surrogate pair
318
319                         // Need 4 bytes for surrogates
320                         // Get our offset
321                         int offset = ((charLeftOver - 0xd800) << 10) + (ch - 0xdc00);
322
323                         byte byte4 = (byte)((offset % 0x0a) + 0x30);
324                         offset /= 0x0a;
325                         byte byte3 = (byte)((offset % 0x7e) + 0x81);
326                         offset /= 0x7e;
327                         byte byte2 = (byte)((offset % 0x0a) + 0x30);
328                         offset /= 0x0a;
329                         Contract.Assert(offset < 0x6f,
330                             "[GB18030Encoding.GetBytes](1) Expected offset < 0x6f, not 0x" + offset.ToString("X2", CultureInfo.InvariantCulture));
331
332                         charLeftOver = (char)0;
333                         if (!buffer.AddByte((byte)(offset + 0x90),byte2,byte3,byte4))
334                         {
335                             // Didn't work, need to back up for both surrogates (AddByte already backed up one)
336                             buffer.MovePrevious(false);             // (don't throw)
337                             break;
338                         }
339                     }
340                     charLeftOver = '\0';
341                 }
342                 // ASCII's easiest
343                 else if (ch <= 0x7f)
344                 {
345                     // Need a byte
346                     if (!buffer.AddByte((byte)ch))
347                         break;
348                 }
349                 // See if its a surrogate pair
350                 else if (Char.IsHighSurrogate(ch))
351                 {
352                     // Remember it for next time
353                     charLeftOver = ch;
354                 }
355                 else if (Char.IsLowSurrogate(ch))
356                 {
357                     // Low surrogates should've been found already
358                     if (!buffer.Fallback(ch))
359                         break;
360                 }
361                 else
362                 {
363                     // Not surrogate or ASCII, get value
364                     ushort iBytes = mapUnicodeToBytes[ch];
365
366                     // See what kind it is
367                     if (Is4Byte(ch))
368                     {
369                         //
370                         // This Unicode character will be converted to four-byte GB18030.
371                         //
372                         // Need 4 bytes
373                         byte byte4 = (byte)((iBytes % 0x0a) + 0x30);
374                         iBytes /= 0x0a;
375                         byte byte3 = (byte)((iBytes % 0x7e) + 0x81);
376                         iBytes /= 0x7e;
377                         byte byte2 = (byte)((iBytes % 0x0a) + 0x30);
378                         iBytes /= 0x0a;
379                         Contract.Assert(iBytes < 0x7e,
380                             "[GB18030Encoding.GetBytes]Expected iBytes < 0x7e, not 0x" + iBytes.ToString("X2", CultureInfo.InvariantCulture));
381                         if (!buffer.AddByte((byte)(iBytes + 0x81), byte2, byte3, byte4))
382                             break;
383                     }
384                     else
385                     {
386                         // Its 2 byte, use it
387                         if (!buffer.AddByte(unchecked((byte)(iBytes >> 8)), unchecked((byte)(iBytes & 0xff))))
388                             break;
389                     }
390                 }
391             }
392
393             // Do we need to flush our charLeftOver?
394             if ((encoder == null || encoder.MustFlush) && (charLeftOver > 0))
395             {
396                 // Fall it back
397                 buffer.Fallback(charLeftOver);
398                 charLeftOver = (char)0;
399                 goto TryAgain;
400             }
401
402             // Fallback stuck it in encoder if necessary, but we have to clear MustFlash cases
403             // (Check bytes != null, don't clear it if we're just counting)
404             if (encoder != null)
405             {
406                 // Remember our charLeftOver
407                 if (bytes != null)
408                     encoder.charLeftOver = charLeftOver;
409
410                 encoder.m_charsUsed = buffer.CharsUsed;
411             }
412
413             // Return our length
414             return buffer.Count;
415         }
416
417         // Helper methods
418         internal bool IsGBLeadByte(short ch)
419         {
420             // return true if we're in the lead byte range
421             return ((ch) >= 0x81 && (ch) <= 0xfe);
422         }
423
424         internal bool IsGBTwoByteTrailing(short ch)
425         {
426             // Return true if we are in range for the trailing byte of a 2 byte sequence
427             return (((ch) >= 0x40 && (ch) <= 0x7e) ||
428                     ((ch) >= 0x80 && (ch) <= 0xfe));
429         }
430
431         internal bool IsGBFourByteTrailing(short ch)
432         {
433             // Return true if we are in range for the trailing byte of a 4 byte sequence
434             return ((ch) >= 0x30 && (ch) <= 0x39);
435         }
436
437         internal int GetFourBytesOffset(short offset1, short offset2, short offset3, short offset4)
438         {
439             return ((offset1 - 0x81) * 0x0a * 0x7e * 0x0a +
440                     (offset2 - 0x30) * 0x7e * 0x0a +
441                     (offset3 - 0x81) * 0x0a +
442                      offset4 - 0x30);
443         }
444
445         // This is internal and called by something else,
446         [System.Security.SecurityCritical]  // auto-generated
447         internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
448         {
449             // Just call GetChars() with null chars to count
450             return GetChars(bytes, count, null, 0, baseDecoder);
451         }
452
453         [System.Security.SecurityCritical]  // auto-generated
454         internal override unsafe int GetChars(byte* bytes, int byteCount,
455                                                 char* chars, int charCount, DecoderNLS baseDecoder)
456         {
457             // Just need to ASSERT, this is called by something else internal that checked parameters already
458             // We'll allow null chars as a count
459             Contract.Assert(bytes != null, "[GB18030Encoding.GetChars]bytes is null");
460             Contract.Assert(byteCount >= 0, "[GB18030Encoding.GetChars]byteCount is negative");
461 //            Contract.Assert(chars != null, "[GB18030Encoding.GetChars]chars is null");
462             Contract.Assert(charCount >= 0, "[GB18030Encoding.GetChars]charCount is negative");
463
464             // Fix our decoder
465             GB18030Decoder decoder = (GB18030Decoder)baseDecoder;
466
467             // Get our info.
468             Encoding.EncodingCharBuffer buffer = new Encoding.EncodingCharBuffer(
469                 this, decoder, chars, charCount, bytes, byteCount);
470
471             // Need temp bytes because we can't muss up decoder
472             short byte1 = -1;
473             short byte2 = -1;
474             short byte3 = -1;
475             short byte4 = -1;
476
477             // See if there was anything to get out of the decoder
478             if (decoder != null && decoder.bLeftOver1 != -1)
479             {
480                 // Need temp bytes because we can't muss up decoder
481                 byte1 = decoder.bLeftOver1;
482                 byte2 = decoder.bLeftOver2;
483                 byte3 = decoder.bLeftOver3;
484                 byte4 = decoder.bLeftOver4;
485
486                 // Loop because we might have too many in buffer
487                 // This could happen if we are working on a 4 byte sequence, but it isn't valid.
488                 while (byte1 != -1)
489                 {
490                     // If its not a lead byte, use ? or its value, then scoot them down & try again
491                     // This could happen if we previously had a bad 4 byte sequence and this is a trail byte
492                     if (!IsGBLeadByte(byte1))
493                     {
494                         // This is either a ? or ASCII, need 1 char output
495                         if (byte1 <= 0x7f)
496                         {
497                             if (!buffer.AddChar((char)byte1))      // Its ASCII
498                                 break;
499                         }
500                         else
501                         {
502                             if (!buffer.Fallback((byte)byte1))     // Not a valid byte
503                                 break;
504                         }
505
506                         byte1 = byte2;
507                         byte2 = byte3;
508                         byte3 = byte4;
509                         byte4 = -1;
510                         continue;
511                     }
512
513                     // Read in more bytes as needed
514                     while (byte2 == -1 ||
515                            (IsGBFourByteTrailing(byte2) && byte4 == -1))
516                     {
517                         // Do we have room?
518                         if (!buffer.MoreData)
519                         {
520                             // No input left to read, do we have to flush?
521                             if (!decoder.MustFlush)
522                             {
523                                 // Don't stick stuff in decoder when counting
524                                 if (chars != null)
525                                 {
526                                     // Don't have to flush, won't have any chars
527                                     // Decoder is correct, just return
528                                     decoder.bLeftOver1 = byte1;
529                                     decoder.bLeftOver2 = byte2;
530                                     decoder.bLeftOver3 = byte3;
531                                     decoder.bLeftOver4 = byte4;
532                                 }
533
534                                 decoder.m_bytesUsed = buffer.BytesUsed;
535                                 return buffer.Count;
536                             }
537
538                             // We'll have to flush, add a ? and scoot them down to try again
539                             // We could be trying for a 4 byte sequence but byte 3 could be ascii and should be spit out
540                             // Breaking will do this because we have zeros
541                             break;
542                         }
543
544                         // Read them in
545                         if (byte2 == -1) byte2 = buffer.GetNextByte();
546                         else if (byte3 == -1) byte3 = buffer.GetNextByte();
547                         else byte4 = buffer.GetNextByte();
548                     }
549
550                     // Now we have our 2 or 4 bytes
551                     if (IsGBTwoByteTrailing(byte2))
552                     {
553                         //
554                         // The trailing byte is a GB18030 two-byte sequence trailing byte.
555                         //
556                         int iTwoBytes = byte1 << 8;
557                         iTwoBytes |= unchecked((byte)byte2);
558                         if (!buffer.AddChar(this.mapBytesToUnicode[iTwoBytes], 2))
559                             break;
560
561                         // We're done with it
562                         byte1 = -1;
563                         byte2 = -1;
564                     }
565                     else if (IsGBFourByteTrailing(byte2) &&
566                              IsGBLeadByte(byte3) &&
567                              IsGBFourByteTrailing(byte4))
568                     {
569                         //
570                         // Four-byte GB18030
571                         //
572
573                         int sFourBytesOffset = GetFourBytesOffset(
574                             byte1, byte2, byte3, byte4);
575
576                         // What kind is it?
577                         if (sFourBytesOffset <= GBLast4ByteCode)
578                         {
579                             //
580                             // The Unicode will be in the BMP range.
581                             //
582                             if (!buffer.AddChar(map4BytesToUnicode[sFourBytesOffset], 4))
583                                 break;
584                         }
585                         else if (sFourBytesOffset >= GBSurrogateOffset &&
586                                  sFourBytesOffset <= GBLastSurrogateOffset)
587                         {
588                             //
589                             // This will be converted to a surrogate pair, need another char
590                             //
591
592                             // Use our surrogate
593                             sFourBytesOffset -= GBSurrogateOffset;
594                             if (!buffer.AddChar(unchecked((char)(0xd800 + (sFourBytesOffset / 0x400))),
595                                                 unchecked((char)(0xdc00 + (sFourBytesOffset % 0x400))), 4))
596                                 break;
597                         }
598                         else
599                         {
600                             // Real GB18030 codepoint, but can't be mapped to unicode
601                             // We already checked our buffer space.
602                             // Do fallback here if we impliment decoderfallbacks.
603                             if (!buffer.Fallback((byte)byte1, (byte)byte2, (byte)byte3, (byte)byte4))
604                                 break;
605                         }
606
607                         // We're done with this one
608                         byte1 = -1;
609                         byte2 = -1;
610                         byte3 = -1;
611                         byte4 = -1;
612                     }
613                     else
614                     {
615                         // Not a valid sequence, use '?' for 1st byte & scoot them all down 1
616                         if (!buffer.Fallback((byte)byte1))
617                             break;
618
619                         // Move all bytes down 1
620                         byte1 = byte2;
621                         byte2 = byte3;
622                         byte3 = byte4;
623                         byte4 = -1;
624                     }
625                 }
626             }
627
628             // Loop, just do '?' replacement because we don't have fallbacks for decodings.
629             while (buffer.MoreData)
630             {
631                 byte ch = buffer.GetNextByte();
632
633                 // ASCII case is easy
634                 if (ch <= 0x7f)
635                 {
636                     // ASCII, have room?
637                     if (!buffer.AddChar((char)ch))
638                         break;              // No room in convert buffer, so stop
639                 }
640                 // See if its a lead byte
641                 else if (IsGBLeadByte(ch))
642                 {
643                     // ch is a lead byte, have room for more?
644                     if (buffer.MoreData)
645                     {
646                         byte ch2 = buffer.GetNextByte();
647                         if (IsGBTwoByteTrailing(ch2))
648                         {
649                             //
650                             // The trailing byte is a GB18030 two-byte sequence trailing byte.
651                             //
652
653                             //
654                             // Two-byte GB18030
655                             //
656                             int iTwoBytes = ch << 8;
657                             iTwoBytes |= ch2;
658                             if (!buffer.AddChar(this.mapBytesToUnicode[iTwoBytes], 2))
659                                 break;
660                         }
661                         else if (IsGBFourByteTrailing(ch2))
662                         {
663                             // Do we have room for Four Byte Sequence? (already have 1 byte)
664                             if (buffer.EvenMoreData(2))
665                             {
666                                 // Is it a valid 4 byte sequence?
667                                 byte ch3 = buffer.GetNextByte();
668                                 byte ch4 = buffer.GetNextByte();
669                                 if (IsGBLeadByte(ch3) &&
670                                     IsGBFourByteTrailing(ch4))
671                                 {
672                                     //
673                                     // Four-byte GB18030
674                                     //
675                                     int sFourBytesOffset = GetFourBytesOffset(ch, ch2, ch3, ch4);
676
677                                     // What kind is it?
678                                     // We'll be at least 1 BMP char or a '?' char.
679
680                                     if (sFourBytesOffset <= GBLast4ByteCode)
681                                     {
682                                         //
683                                         // The Unicode will be in the BMP range.
684                                         //
685                                         if (!buffer.AddChar(map4BytesToUnicode[sFourBytesOffset],4))
686                                             break;
687                                     }
688                                     else if (sFourBytesOffset >= GBSurrogateOffset &&
689                                              sFourBytesOffset <= GBLastSurrogateOffset)
690                                     {
691                                         //
692                                         // This will be converted to a surrogate pair, need another char
693                                         //
694
695                                         // Use our surrogate
696                                         sFourBytesOffset -= GBSurrogateOffset;
697                                         if (!buffer.AddChar(unchecked((char)(0xd800 + (sFourBytesOffset / 0x400))),
698                                                              unchecked((char)(0xdc00 + (sFourBytesOffset % 0x400))),4))
699                                             break;
700                                     }
701                                     else
702                                     {
703                                         // Real GB18030 codepoint, but can't be mapped to unicode
704                                         if (!buffer.Fallback(ch, ch2, ch3, ch4))
705                                             break;
706                                     }
707                                 }
708                                 else
709                                 {
710                                     // Not a valid 2 or 4 byte sequence, use '?' for ch and try other 3 again
711                                     buffer.AdjustBytes(-3);
712                                     if (!buffer.Fallback(ch))
713                                         break;
714                                 }
715                             }
716                             else
717                             {
718                                 // No room for 4 bytes, have 2 already, may be one more
719                                 // Lead byte but no place to stick it
720                                 if (decoder != null && !decoder.MustFlush)
721                                 {
722                                     // (make sure not to set decoder if counting, so check chars)
723                                     if (chars != null)
724                                     {
725                                         // We'll be able to stick the remainder in the decoder
726                                         byte1 = ch;
727                                         byte2 = ch2;
728
729                                         if (buffer.MoreData)
730                                             byte3 = buffer.GetNextByte();
731                                         else
732                                             byte3 = -1;
733
734                                         byte4=-1;
735                                     }
736                                     break;
737                                 }
738
739                                 // Won't go in decoder, we'll use '?' for it.
740                                 if (!buffer.Fallback(ch, ch2))
741                                     break;
742                             }
743                         }
744                         else
745                         {
746                             // Unknown byte sequence, fall back lead byte and try 2nd one again
747                             buffer.AdjustBytes(-1);
748                             if (!buffer.Fallback(ch))
749                                 break;
750                         }
751                     }
752                     else
753                     {
754                         // Lead byte but don't know about trail byte
755                         // (make sure not to set decoder if counting, so check bytes)
756                         if (decoder != null && !decoder.MustFlush)
757                         {
758                             // We'll be able to stick it in the decoder
759                             // (don't actually do it when counting though)
760                             if (chars != null)
761                             {
762                                 byte1 = ch;
763                                 byte2 = -1;
764                                 byte3 = -1;
765                                 byte4 = -1;
766                             }
767                             break;
768                         }
769
770                         if (!buffer.Fallback(ch))
771                             break;
772                     }
773                 }
774                 else
775                 {
776                     // Not ASCII and not a lead byte, we'll use '?' for it if we have room
777                     if (!buffer.Fallback(ch))
778                         break;
779                 }
780             }
781
782             // Need to flush the decoder if necessary
783             // (make sure not to set decoder if counting, so check bytes)
784             if (decoder != null)
785             {
786                 if (chars != null)
787                 {
788                     decoder.bLeftOver1 = byte1;
789                     decoder.bLeftOver2 = byte2;
790                     decoder.bLeftOver3 = byte3;
791                     decoder.bLeftOver4 = byte4;
792                 }
793                 decoder.m_bytesUsed = buffer.BytesUsed;
794             }
795
796             // Return the # of characters we found
797             return buffer.Count;
798         }
799
800         public override int GetMaxByteCount(int charCount)
801         {
802             if (charCount < 0)
803                throw new ArgumentOutOfRangeException("charCount",
804                     Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
805             Contract.EndContractBlock();
806
807             // Characters would be # of characters + 1 in case high surrogate is ? * max fallback
808             long byteCount = (long)charCount + 1;
809
810             if (EncoderFallback.MaxCharCount > 1)
811                 byteCount *= EncoderFallback.MaxCharCount;
812
813             // We could have 4 bytes for each char, no extra for surrogates because 18030 can do whole unicode range.
814             byteCount *= 4;
815
816             if (byteCount > 0x7fffffff)
817                 throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
818
819             return (int)byteCount;
820         }
821
822         public override int GetMaxCharCount(int byteCount)
823         {
824             if (byteCount < 0)
825                throw new ArgumentOutOfRangeException("byteCount",
826                     Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
827             Contract.EndContractBlock();
828
829             // Just return length, we could have a single char for each byte + whatever extra our decoder could do to us.
830             // If decoder is messed up it could spit out 3 ?s.
831             long charCount = ((long)byteCount) + 3;
832
833             // Take fallback size into consideration
834             if (DecoderFallback.MaxCharCount > 1)
835                 charCount *= DecoderFallback.MaxCharCount;
836
837             if (charCount > 0x7fffffff)
838                 throw new ArgumentOutOfRangeException("byteCount", Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
839
840             return (int)charCount;
841         }
842
843         public override Decoder GetDecoder()
844         {
845             return new GB18030Decoder(this);
846         }
847
848         [Serializable]
849         internal sealed class GB18030Decoder : System.Text.DecoderNLS, ISerializable
850         {
851             internal short bLeftOver1 = -1;
852             internal short bLeftOver2 = -1;
853             internal short bLeftOver3 = -1;
854             internal short bLeftOver4 = -1;
855
856             internal GB18030Decoder(EncodingNLS encoding) : base(encoding)
857             {
858                 // DecoderNLS Calls reset
859             }
860
861             // Constructor called by serialization, have to handle deserializing from Everett
862             [System.Security.SecurityCritical]  // auto-generated
863             internal GB18030Decoder(SerializationInfo info, StreamingContext context)
864             {
865                 // Any info?
866                 if (info==null) throw new ArgumentNullException("info");
867                 Contract.EndContractBlock();
868
869                 try
870                 {
871                     //
872                     // Try Whidbey V2.0 Fields
873                     //
874                     this.m_encoding = (Encoding)info.GetValue("m_encoding", typeof(Encoding));
875                     this.m_fallback = (DecoderFallback)info.GetValue("m_fallback", typeof(DecoderFallback));
876                     this.bLeftOver1 = (short)info.GetValue("bLeftOver1", typeof(short));
877                     this.bLeftOver2 = (short)info.GetValue("bLeftOver2", typeof(short));
878                     this.bLeftOver3 = (short)info.GetValue("bLeftOver3", typeof(short));
879                     this.bLeftOver4 = (short)info.GetValue("bLeftOver4", typeof(short));
880                 }
881                 catch (SerializationException)
882                 {
883                     // Didn't have Whidbey stuff, try Everett (DecoderNLS already called Reset())
884                     this.m_encoding = new GB18030Encoding();
885                 }
886             }
887
888 #if FEATURE_SERIALIZATION
889             // ISerializable implementation, get data for this object
890             [System.Security.SecurityCritical]  // auto-generated_required
891             void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
892             {
893                 // Any info?
894                 if (info==null) throw new ArgumentNullException("info");
895                 Contract.EndContractBlock();
896
897                 // Save Whidbey data
898                 // Just need Everett maxCharSize (BaseCodePageEncoding) or m_maxByteSize (MLangBaseCodePageEncoding)
899                 info.AddValue("m_encoding", this.m_encoding);
900                 info.AddValue("m_fallback", this.m_fallback);
901                 info.AddValue("bLeftOver1", this.bLeftOver1);
902                 info.AddValue("bLeftOver2", this.bLeftOver2);
903                 info.AddValue("bLeftOver3", this.bLeftOver3);
904                 info.AddValue("bLeftOver4", this.bLeftOver4);
905
906                 // Everett needs different data (this is just empty for Everett)
907                 info.AddValue("m_leftOverBytes", (int)0);
908                 info.AddValue("leftOver", new byte[8]);
909             }
910 #endif
911
912             public override void Reset()
913             {
914                 bLeftOver1 = -1;
915                 bLeftOver2 = -1;
916                 bLeftOver3 = -1;
917                 bLeftOver4 = -1;
918                 if (m_fallbackBuffer != null)
919                     m_fallbackBuffer.Reset();
920             }
921
922             // Anything left in our decoder?
923             internal override bool HasState
924             {
925                 get
926                 {
927                     return (this.bLeftOver1 >= 0);
928                 }
929             }
930         }
931
932         // tableUnicodeToGBDiffs
933         //
934         // This compressed data enumerates the differences between gb18030 and the 936 code page as follows:
935         //
936         // <count> & 0x8000 == 0x8000      The next count <count> characters are identical to 936 characters.
937         // <count> & 0x8000 == 0x0000      The next count <count> characters are 4 byte gb18030 characters.
938         // Except for:
939         // <count> >= 0x9000 && <count> != 0xD1A6     This character is this 2 byte GB18030 value.
940         //
941         readonly ushort[] tableUnicodeToGBDiffs =
942         {
943             0x8080, // U+0000 - U+007F (  128 chars) use CP 936 conversion.
944             0x0024, // U+0080 - U+00A3 (   36 chars) are GB18030 81 30 81 30 - 81 30 84 35 (offset 0000 - 0023)
945             0x8001, // U+00A4 - U+00A4 (    1 chars) use CP 936 conversion.
946             0x0002, // U+00A5 - U+00A6 (    2 chars) are GB18030 81 30 84 36 - 81 30 84 37 (offset 0024 - 0025)
947             0x8002, // U+00A7 - U+00A8 (    2 chars) use CP 936 conversion.
948             0x0007, // U+00A9 - U+00AF (    7 chars) are GB18030 81 30 84 38 - 81 30 85 34 (offset 0026 - 002C)
949             0x8002, // U+00B0 - U+00B1 (    2 chars) use CP 936 conversion.
950             0x0005, // U+00B2 - U+00B6 (    5 chars) are GB18030 81 30 85 35 - 81 30 85 39 (offset 002D - 0031)
951             0x8001, // U+00B7 - U+00B7 (    1 chars) use CP 936 conversion.
952             0x001F, // U+00B8 - U+00D6 (   31 chars) are GB18030 81 30 86 30 - 81 30 89 30 (offset 0032 - 0050)
953             0x8001, // U+00D7 - U+00D7 (    1 chars) use CP 936 conversion.
954             0x0008, // U+00D8 - U+00DF (    8 chars) are GB18030 81 30 89 31 - 81 30 89 38 (offset 0051 - 0058)
955             0x8002, // U+00E0 - U+00E1 (    2 chars) use CP 936 conversion.
956             0x0006, // U+00E2 - U+00E7 (    6 chars) are GB18030 81 30 89 39 - 81 30 8A 34 (offset 0059 - 005E)
957             0x8003, // U+00E8 - U+00EA (    3 chars) use CP 936 conversion.
958             0x0001, // U+00EB - U+00EB (    1 chars) are GB18030 81 30 8A 35 - 81 30 8A 35 (offset 005F - 005F)
959             0x8002, // U+00EC - U+00ED (    2 chars) use CP 936 conversion.
960             0x0004, // U+00EE - U+00F1 (    4 chars) are GB18030 81 30 8A 36 - 81 30 8A 39 (offset 0060 - 0063)
961             0x8002, // U+00F2 - U+00F3 (    2 chars) use CP 936 conversion.
962             0x0003, // U+00F4 - U+00F6 (    3 chars) are GB18030 81 30 8B 30 - 81 30 8B 32 (offset 0064 - 0066)
963             0x8001, // U+00F7 - U+00F7 (    1 chars) use CP 936 conversion.
964             0x0001, // U+00F8 - U+00F8 (    1 chars) are GB18030 81 30 8B 33 - 81 30 8B 33 (offset 0067 - 0067)
965             0x8002, // U+00F9 - U+00FA (    2 chars) use CP 936 conversion.
966             0x0001, // U+00FB - U+00FB (    1 chars) are GB18030 81 30 8B 34 - 81 30 8B 34 (offset 0068 - 0068)
967             0x8001, // U+00FC - U+00FC (    1 chars) use CP 936 conversion.
968             0x0004, // U+00FD - U+0100 (    4 chars) are GB18030 81 30 8B 35 - 81 30 8B 38 (offset 0069 - 006C)
969             0x8001, // U+0101 - U+0101 (    1 chars) use CP 936 conversion.
970             0x0011, // U+0102 - U+0112 (   17 chars) are GB18030 81 30 8B 39 - 81 30 8D 35 (offset 006D - 007D)
971             0x8001, // U+0113 - U+0113 (    1 chars) use CP 936 conversion.
972             0x0007, // U+0114 - U+011A (    7 chars) are GB18030 81 30 8D 36 - 81 30 8E 32 (offset 007E - 0084)
973             0x8001, // U+011B - U+011B (    1 chars) use CP 936 conversion.
974             0x000F, // U+011C - U+012A (   15 chars) are GB18030 81 30 8E 33 - 81 30 8F 37 (offset 0085 - 0093)
975             0x8001, // U+012B - U+012B (    1 chars) use CP 936 conversion.
976             0x0018, // U+012C - U+0143 (   24 chars) are GB18030 81 30 8F 38 - 81 30 92 31 (offset 0094 - 00AB)
977             0x8001, // U+0144 - U+0144 (    1 chars) use CP 936 conversion.
978             0x0003, // U+0145 - U+0147 (    3 chars) are GB18030 81 30 92 32 - 81 30 92 34 (offset 00AC - 00AE)
979             0x8001, // U+0148 - U+0148 (    1 chars) use CP 936 conversion.
980             0x0004, // U+0149 - U+014C (    4 chars) are GB18030 81 30 92 35 - 81 30 92 38 (offset 00AF - 00B2)
981             0x8001, // U+014D - U+014D (    1 chars) use CP 936 conversion.
982             0x001D, // U+014E - U+016A (   29 chars) are GB18030 81 30 92 39 - 81 30 95 37 (offset 00B3 - 00CF)
983             0x8001, // U+016B - U+016B (    1 chars) use CP 936 conversion.
984             0x0062, // U+016C - U+01CD (   98 chars) are GB18030 81 30 95 38 - 81 30 9F 35 (offset 00D0 - 0131)
985             0x8001, // U+01CE - U+01CE (    1 chars) use CP 936 conversion.
986             0x0001, // U+01CF - U+01CF (    1 chars) are GB18030 81 30 9F 36 - 81 30 9F 36 (offset 0132 - 0132)
987             0x8001, // U+01D0 - U+01D0 (    1 chars) use CP 936 conversion.
988             0x0001, // U+01D1 - U+01D1 (    1 chars) are GB18030 81 30 9F 37 - 81 30 9F 37 (offset 0133 - 0133)
989             0x8001, // U+01D2 - U+01D2 (    1 chars) use CP 936 conversion.
990             0x0001, // U+01D3 - U+01D3 (    1 chars) are GB18030 81 30 9F 38 - 81 30 9F 38 (offset 0134 - 0134)
991             0x8001, // U+01D4 - U+01D4 (    1 chars) use CP 936 conversion.
992             0x0001, // U+01D5 - U+01D5 (    1 chars) are GB18030 81 30 9F 39 - 81 30 9F 39 (offset 0135 - 0135)
993             0x8001, // U+01D6 - U+01D6 (    1 chars) use CP 936 conversion.
994             0x0001, // U+01D7 - U+01D7 (    1 chars) are GB18030 81 30 A0 30 - 81 30 A0 30 (offset 0136 - 0136)
995             0x8001, // U+01D8 - U+01D8 (    1 chars) use CP 936 conversion.
996             0x0001, // U+01D9 - U+01D9 (    1 chars) are GB18030 81 30 A0 31 - 81 30 A0 31 (offset 0137 - 0137)
997             0x8001, // U+01DA - U+01DA (    1 chars) use CP 936 conversion.
998             0x0001, // U+01DB - U+01DB (    1 chars) are GB18030 81 30 A0 32 - 81 30 A0 32 (offset 0138 - 0138)
999             0x8001, // U+01DC - U+01DC (    1 chars) use CP 936 conversion.
1000             0x001C, // U+01DD - U+01F8 (   28 chars) are GB18030 81 30 A0 33 - 81 30 A3 30 (offset 0139 - 0154)
1001             0xA8BF, // U+01F9 is non-936 GB18030 value A8 BF.
1002             0x0057, // U+01FA - U+0250 (   87 chars) are GB18030 81 30 A3 31 - 81 30 AB 37 (offset 0155 - 01AB)
1003             0x8001, // U+0251 - U+0251 (    1 chars) use CP 936 conversion.
1004             0x000F, // U+0252 - U+0260 (   15 chars) are GB18030 81 30 AB 38 - 81 30 AD 32 (offset 01AC - 01BA)
1005             0x8001, // U+0261 - U+0261 (    1 chars) use CP 936 conversion.
1006             0x0065, // U+0262 - U+02C6 (  101 chars) are GB18030 81 30 AD 33 - 81 30 B7 33 (offset 01BB - 021F)
1007             0x8001, // U+02C7 - U+02C7 (    1 chars) use CP 936 conversion.
1008             0x0001, // U+02C8 - U+02C8 (    1 chars) are GB18030 81 30 B7 34 - 81 30 B7 34 (offset 0220 - 0220)
1009             0x8003, // U+02C9 - U+02CB (    3 chars) use CP 936 conversion.
1010             0x000D, // U+02CC - U+02D8 (   13 chars) are GB18030 81 30 B7 35 - 81 30 B8 37 (offset 0221 - 022D)
1011             0x8001, // U+02D9 - U+02D9 (    1 chars) use CP 936 conversion.
1012             0x00B7, // U+02DA - U+0390 (  183 chars) are GB18030 81 30 B8 38 - 81 30 CB 30 (offset 022E - 02E4)
1013             0x8011, // U+0391 - U+03A1 (   17 chars) use CP 936 conversion.
1014             0x0001, // U+03A2 - U+03A2 (    1 chars) are GB18030 81 30 CB 31 - 81 30 CB 31 (offset 02E5 - 02E5)
1015             0x8007, // U+03A3 - U+03A9 (    7 chars) use CP 936 conversion.
1016             0x0007, // U+03AA - U+03B0 (    7 chars) are GB18030 81 30 CB 32 - 81 30 CB 38 (offset 02E6 - 02EC)
1017             0x8011, // U+03B1 - U+03C1 (   17 chars) use CP 936 conversion.
1018             0x0001, // U+03C2 - U+03C2 (    1 chars) are GB18030 81 30 CB 39 - 81 30 CB 39 (offset 02ED - 02ED)
1019             0x8007, // U+03C3 - U+03C9 (    7 chars) use CP 936 conversion.
1020             0x0037, // U+03CA - U+0400 (   55 chars) are GB18030 81 30 CC 30 - 81 30 D1 34 (offset 02EE - 0324)
1021             0x8001, // U+0401 - U+0401 (    1 chars) use CP 936 conversion.
1022             0x000E, // U+0402 - U+040F (   14 chars) are GB18030 81 30 D1 35 - 81 30 D2 38 (offset 0325 - 0332)
1023             0x8040, // U+0410 - U+044F (   64 chars) use CP 936 conversion.
1024             0x0001, // U+0450 - U+0450 (    1 chars) are GB18030 81 30 D2 39 - 81 30 D2 39 (offset 0333 - 0333)
1025             0x8001, // U+0451 - U+0451 (    1 chars) use CP 936 conversion.
1026             0x1BBE, // U+0452 - U+200F ( 7102 chars) are GB18030 81 30 D3 30 - 81 36 A5 31 (offset 0334 - 1EF1)
1027             0x8001, // U+2010 - U+2010 (    1 chars) use CP 936 conversion.
1028             0x0002, // U+2011 - U+2012 (    2 chars) are GB18030 81 36 A5 32 - 81 36 A5 33 (offset 1EF2 - 1EF3)
1029             0x8004, // U+2013 - U+2016 (    4 chars) use CP 936 conversion.
1030             0x0001, // U+2017 - U+2017 (    1 chars) are GB18030 81 36 A5 34 - 81 36 A5 34 (offset 1EF4 - 1EF4)
1031             0x8002, // U+2018 - U+2019 (    2 chars) use CP 936 conversion.
1032             0x0002, // U+201A - U+201B (    2 chars) are GB18030 81 36 A5 35 - 81 36 A5 36 (offset 1EF5 - 1EF6)
1033             0x8002, // U+201C - U+201D (    2 chars) use CP 936 conversion.
1034             0x0007, // U+201E - U+2024 (    7 chars) are GB18030 81 36 A5 37 - 81 36 A6 33 (offset 1EF7 - 1EFD)
1035             0x8002, // U+2025 - U+2026 (    2 chars) use CP 936 conversion.
1036             0x0009, // U+2027 - U+202F (    9 chars) are GB18030 81 36 A6 34 - 81 36 A7 32 (offset 1EFE - 1F06)
1037             0x8001, // U+2030 - U+2030 (    1 chars) use CP 936 conversion.
1038             0x0001, // U+2031 - U+2031 (    1 chars) are GB18030 81 36 A7 33 - 81 36 A7 33 (offset 1F07 - 1F07)
1039             0x8002, // U+2032 - U+2033 (    2 chars) use CP 936 conversion.
1040             0x0001, // U+2034 - U+2034 (    1 chars) are GB18030 81 36 A7 34 - 81 36 A7 34 (offset 1F08 - 1F08)
1041             0x8001, // U+2035 - U+2035 (    1 chars) use CP 936 conversion.
1042             0x0005, // U+2036 - U+203A (    5 chars) are GB18030 81 36 A7 35 - 81 36 A7 39 (offset 1F09 - 1F0D)
1043             0x8001, // U+203B - U+203B (    1 chars) use CP 936 conversion.
1044             0x0070, // U+203C - U+20AB (  112 chars) are GB18030 81 36 A8 30 - 81 36 B3 31 (offset 1F0E - 1F7D)
1045             0xA2E3, // U+20AC is non-936 GB18030 value A2 E3.
1046             0x0056, // U+20AD - U+2102 (   86 chars) are GB18030 81 36 B3 32 - 81 36 BB 37 (offset 1F7E - 1FD3)
1047             0x8001, // U+2103 - U+2103 (    1 chars) use CP 936 conversion.
1048             0x0001, // U+2104 - U+2104 (    1 chars) are GB18030 81 36 BB 38 - 81 36 BB 38 (offset 1FD4 - 1FD4)
1049             0x8001, // U+2105 - U+2105 (    1 chars) use CP 936 conversion.
1050             0x0003, // U+2106 - U+2108 (    3 chars) are GB18030 81 36 BB 39 - 81 36 BC 31 (offset 1FD5 - 1FD7)
1051             0x8001, // U+2109 - U+2109 (    1 chars) use CP 936 conversion.
1052             0x000C, // U+210A - U+2115 (   12 chars) are GB18030 81 36 BC 32 - 81 36 BD 33 (offset 1FD8 - 1FE3)
1053             0x8001, // U+2116 - U+2116 (    1 chars) use CP 936 conversion.
1054             0x000A, // U+2117 - U+2120 (   10 chars) are GB18030 81 36 BD 34 - 81 36 BE 33 (offset 1FE4 - 1FED)
1055             0x8001, // U+2121 - U+2121 (    1 chars) use CP 936 conversion.
1056             0x003E, // U+2122 - U+215F (   62 chars) are GB18030 81 36 BE 34 - 81 36 C4 35 (offset 1FEE - 202B)
1057             0x800C, // U+2160 - U+216B (   12 chars) use CP 936 conversion.
1058             0x0004, // U+216C - U+216F (    4 chars) are GB18030 81 36 C4 36 - 81 36 C4 39 (offset 202C - 202F)
1059             0x800A, // U+2170 - U+2179 (   10 chars) use CP 936 conversion.
1060             0x0016, // U+217A - U+218F (   22 chars) are GB18030 81 36 C5 30 - 81 36 C7 31 (offset 2030 - 2045)
1061             0x8004, // U+2190 - U+2193 (    4 chars) use CP 936 conversion.
1062             0x0002, // U+2194 - U+2195 (    2 chars) are GB18030 81 36 C7 32 - 81 36 C7 33 (offset 2046 - 2047)
1063             0x8004, // U+2196 - U+2199 (    4 chars) use CP 936 conversion.
1064             0x006E, // U+219A - U+2207 (  110 chars) are GB18030 81 36 C7 34 - 81 36 D2 33 (offset 2048 - 20B5)
1065             0x8001, // U+2208 - U+2208 (    1 chars) use CP 936 conversion.
1066             0x0006, // U+2209 - U+220E (    6 chars) are GB18030 81 36 D2 34 - 81 36 D2 39 (offset 20B6 - 20BB)
1067             0x8001, // U+220F - U+220F (    1 chars) use CP 936 conversion.
1068             0x0001, // U+2210 - U+2210 (    1 chars) are GB18030 81 36 D3 30 - 81 36 D3 30 (offset 20BC - 20BC)
1069             0x8001, // U+2211 - U+2211 (    1 chars) use CP 936 conversion.
1070             0x0003, // U+2212 - U+2214 (    3 chars) are GB18030 81 36 D3 31 - 81 36 D3 33 (offset 20BD - 20BF)
1071             0x8001, // U+2215 - U+2215 (    1 chars) use CP 936 conversion.
1072             0x0004, // U+2216 - U+2219 (    4 chars) are GB18030 81 36 D3 34 - 81 36 D3 37 (offset 20C0 - 20C3)
1073             0x8001, // U+221A - U+221A (    1 chars) use CP 936 conversion.
1074             0x0002, // U+221B - U+221C (    2 chars) are GB18030 81 36 D3 38 - 81 36 D3 39 (offset 20C4 - 20C5)
1075             0x8004, // U+221D - U+2220 (    4 chars) use CP 936 conversion.
1076             0x0002, // U+2221 - U+2222 (    2 chars) are GB18030 81 36 D4 30 - 81 36 D4 31 (offset 20C6 - 20C7)
1077             0x8001, // U+2223 - U+2223 (    1 chars) use CP 936 conversion.
1078             0x0001, // U+2224 - U+2224 (    1 chars) are GB18030 81 36 D4 32 - 81 36 D4 32 (offset 20C8 - 20C8)
1079             0x8001, // U+2225 - U+2225 (    1 chars) use CP 936 conversion.
1080             0x0001, // U+2226 - U+2226 (    1 chars) are GB18030 81 36 D4 33 - 81 36 D4 33 (offset 20C9 - 20C9)
1081             0x8005, // U+2227 - U+222B (    5 chars) use CP 936 conversion.
1082             0x0002, // U+222C - U+222D (    2 chars) are GB18030 81 36 D4 34 - 81 36 D4 35 (offset 20CA - 20CB)
1083             0x8001, // U+222E - U+222E (    1 chars) use CP 936 conversion.
1084             0x0005, // U+222F - U+2233 (    5 chars) are GB18030 81 36 D4 36 - 81 36 D5 30 (offset 20CC - 20D0)
1085             0x8004, // U+2234 - U+2237 (    4 chars) use CP 936 conversion.
1086             0x0005, // U+2238 - U+223C (    5 chars) are GB18030 81 36 D5 31 - 81 36 D5 35 (offset 20D1 - 20D5)
1087             0x8001, // U+223D - U+223D (    1 chars) use CP 936 conversion.
1088             0x000A, // U+223E - U+2247 (   10 chars) are GB18030 81 36 D5 36 - 81 36 D6 35 (offset 20D6 - 20DF)
1089             0x8001, // U+2248 - U+2248 (    1 chars) use CP 936 conversion.
1090             0x0003, // U+2249 - U+224B (    3 chars) are GB18030 81 36 D6 36 - 81 36 D6 38 (offset 20E0 - 20E2)
1091             0x8001, // U+224C - U+224C (    1 chars) use CP 936 conversion.
1092             0x0005, // U+224D - U+2251 (    5 chars) are GB18030 81 36 D6 39 - 81 36 D7 33 (offset 20E3 - 20E7)
1093             0x8001, // U+2252 - U+2252 (    1 chars) use CP 936 conversion.
1094             0x000D, // U+2253 - U+225F (   13 chars) are GB18030 81 36 D7 34 - 81 36 D8 36 (offset 20E8 - 20F4)
1095             0x8002, // U+2260 - U+2261 (    2 chars) use CP 936 conversion.
1096             0x0002, // U+2262 - U+2263 (    2 chars) are GB18030 81 36 D8 37 - 81 36 D8 38 (offset 20F5 - 20F6)
1097             0x8004, // U+2264 - U+2267 (    4 chars) use CP 936 conversion.
1098             0x0006, // U+2268 - U+226D (    6 chars) are GB18030 81 36 D8 39 - 81 36 D9 34 (offset 20F7 - 20FC)
1099             0x8002, // U+226E - U+226F (    2 chars) use CP 936 conversion.
1100             0x0025, // U+2270 - U+2294 (   37 chars) are GB18030 81 36 D9 35 - 81 36 DD 31 (offset 20FD - 2121)
1101             0x8001, // U+2295 - U+2295 (    1 chars) use CP 936 conversion.
1102             0x0003, // U+2296 - U+2298 (    3 chars) are GB18030 81 36 DD 32 - 81 36 DD 34 (offset 2122 - 2124)
1103             0x8001, // U+2299 - U+2299 (    1 chars) use CP 936 conversion.
1104             0x000B, // U+229A - U+22A4 (   11 chars) are GB18030 81 36 DD 35 - 81 36 DE 35 (offset 2125 - 212F)
1105             0x8001, // U+22A5 - U+22A5 (    1 chars) use CP 936 conversion.
1106             0x0019, // U+22A6 - U+22BE (   25 chars) are GB18030 81 36 DE 36 - 81 36 E1 30 (offset 2130 - 2148)
1107             0x8001, // U+22BF - U+22BF (    1 chars) use CP 936 conversion.
1108             0x0052, // U+22C0 - U+2311 (   82 chars) are GB18030 81 36 E1 31 - 81 36 E9 32 (offset 2149 - 219A)
1109             0x8001, // U+2312 - U+2312 (    1 chars) use CP 936 conversion.
1110             0x014D, // U+2313 - U+245F (  333 chars) are GB18030 81 36 E9 33 - 81 37 8C 35 (offset 219B - 22E7)
1111             0x800A, // U+2460 - U+2469 (   10 chars) use CP 936 conversion.
1112             0x000A, // U+246A - U+2473 (   10 chars) are GB18030 81 37 8C 36 - 81 37 8D 35 (offset 22E8 - 22F1)
1113             0x8028, // U+2474 - U+249B (   40 chars) use CP 936 conversion.
1114             0x0064, // U+249C - U+24FF (  100 chars) are GB18030 81 37 8D 36 - 81 37 97 35 (offset 22F2 - 2355)
1115             0x804C, // U+2500 - U+254B (   76 chars) use CP 936 conversion.
1116             0x0004, // U+254C - U+254F (    4 chars) are GB18030 81 37 97 36 - 81 37 97 39 (offset 2356 - 2359)
1117             0x8024, // U+2550 - U+2573 (   36 chars) use CP 936 conversion.
1118             0x000D, // U+2574 - U+2580 (   13 chars) are GB18030 81 37 98 30 - 81 37 99 32 (offset 235A - 2366)
1119             0x800F, // U+2581 - U+258F (   15 chars) use CP 936 conversion.
1120             0x0003, // U+2590 - U+2592 (    3 chars) are GB18030 81 37 99 33 - 81 37 99 35 (offset 2367 - 2369)
1121             0x8003, // U+2593 - U+2595 (    3 chars) use CP 936 conversion.
1122             0x000A, // U+2596 - U+259F (   10 chars) are GB18030 81 37 99 36 - 81 37 9A 35 (offset 236A - 2373)
1123             0x8002, // U+25A0 - U+25A1 (    2 chars) use CP 936 conversion.
1124             0x0010, // U+25A2 - U+25B1 (   16 chars) are GB18030 81 37 9A 36 - 81 37 9C 31 (offset 2374 - 2383)
1125             0x8002, // U+25B2 - U+25B3 (    2 chars) use CP 936 conversion.
1126             0x0008, // U+25B4 - U+25BB (    8 chars) are GB18030 81 37 9C 32 - 81 37 9C 39 (offset 2384 - 238B)
1127             0x8002, // U+25BC - U+25BD (    2 chars) use CP 936 conversion.
1128             0x0008, // U+25BE - U+25C5 (    8 chars) are GB18030 81 37 9D 30 - 81 37 9D 37 (offset 238C - 2393)
1129             0x8002, // U+25C6 - U+25C7 (    2 chars) use CP 936 conversion.
1130             0x0003, // U+25C8 - U+25CA (    3 chars) are GB18030 81 37 9D 38 - 81 37 9E 30 (offset 2394 - 2396)
1131             0x8001, // U+25CB - U+25CB (    1 chars) use CP 936 conversion.
1132             0x0002, // U+25CC - U+25CD (    2 chars) are GB18030 81 37 9E 31 - 81 37 9E 32 (offset 2397 - 2398)
1133             0x8002, // U+25CE - U+25CF (    2 chars) use CP 936 conversion.
1134             0x0012, // U+25D0 - U+25E1 (   18 chars) are GB18030 81 37 9E 33 - 81 37 A0 30 (offset 2399 - 23AA)
1135             0x8004, // U+25E2 - U+25E5 (    4 chars) use CP 936 conversion.
1136             0x001F, // U+25E6 - U+2604 (   31 chars) are GB18030 81 37 A0 31 - 81 37 A3 31 (offset 23AB - 23C9)
1137             0x8002, // U+2605 - U+2606 (    2 chars) use CP 936 conversion.
1138             0x0002, // U+2607 - U+2608 (    2 chars) are GB18030 81 37 A3 32 - 81 37 A3 33 (offset 23CA - 23CB)
1139             0x8001, // U+2609 - U+2609 (    1 chars) use CP 936 conversion.
1140             0x0036, // U+260A - U+263F (   54 chars) are GB18030 81 37 A3 34 - 81 37 A8 37 (offset 23CC - 2401)
1141             0x8001, // U+2640 - U+2640 (    1 chars) use CP 936 conversion.
1142             0x0001, // U+2641 - U+2641 (    1 chars) are GB18030 81 37 A8 38 - 81 37 A8 38 (offset 2402 - 2402)
1143             0x8001, // U+2642 - U+2642 (    1 chars) use CP 936 conversion.
1144             0x083E, // U+2643 - U+2E80 ( 2110 chars) are GB18030 81 37 A8 39 - 81 38 FD 38 (offset 2403 - 2C40)
1145             0xFE50, // U+2E81 is non-936 GB18030 value FE 50.
1146             0x0002, // U+2E82 - U+2E83 (    2 chars) are GB18030 81 38 FD 39 - 81 38 FE 30 (offset 2C41 - 2C42)
1147             0xFE54, // U+2E84 is non-936 GB18030 value FE 54.
1148             0x0003, // U+2E85 - U+2E87 (    3 chars) are GB18030 81 38 FE 31 - 81 38 FE 33 (offset 2C43 - 2C45)
1149             0xFE57, // U+2E88 is non-936 GB18030 value FE 57.
1150             0x0002, // U+2E89 - U+2E8A (    2 chars) are GB18030 81 38 FE 34 - 81 38 FE 35 (offset 2C46 - 2C47)
1151             0xFE58, // U+2E8B is non-936 GB18030 value FE 58.
1152             0xFE5D, // U+2E8C is non-936 GB18030 value FE 5D.
1153             0x000A, // U+2E8D - U+2E96 (   10 chars) are GB18030 81 38 FE 36 - 81 39 81 35 (offset 2C48 - 2C51)
1154             0xFE5E, // U+2E97 is non-936 GB18030 value FE 5E.
1155             0x000F, // U+2E98 - U+2EA6 (   15 chars) are GB18030 81 39 81 36 - 81 39 83 30 (offset 2C52 - 2C60)
1156             0xFE6B, // U+2EA7 is non-936 GB18030 value FE 6B.
1157             0x0002, // U+2EA8 - U+2EA9 (    2 chars) are GB18030 81 39 83 31 - 81 39 83 32 (offset 2C61 - 2C62)
1158             0xFE6E, // U+2EAA is non-936 GB18030 value FE 6E.
1159             0x0003, // U+2EAB - U+2EAD (    3 chars) are GB18030 81 39 83 33 - 81 39 83 35 (offset 2C63 - 2C65)
1160             0xFE71, // U+2EAE is non-936 GB18030 value FE 71.
1161             0x0004, // U+2EAF - U+2EB2 (    4 chars) are GB18030 81 39 83 36 - 81 39 83 39 (offset 2C66 - 2C69)
1162             0xFE73, // U+2EB3 is non-936 GB18030 value FE 73.
1163             0x0002, // U+2EB4 - U+2EB5 (    2 chars) are GB18030 81 39 84 30 - 81 39 84 31 (offset 2C6A - 2C6B)
1164             0xFE74, // U+2EB6 is non-936 GB18030 value FE 74.
1165             0xFE75, // U+2EB7 is non-936 GB18030 value FE 75.
1166             0x0003, // U+2EB8 - U+2EBA (    3 chars) are GB18030 81 39 84 32 - 81 39 84 34 (offset 2C6C - 2C6E)
1167             0xFE79, // U+2EBB is non-936 GB18030 value FE 79.
1168             0x000E, // U+2EBC - U+2EC9 (   14 chars) are GB18030 81 39 84 35 - 81 39 85 38 (offset 2C6F - 2C7C)
1169             0xFE84, // U+2ECA is non-936 GB18030 value FE 84.
1170             0x0125, // U+2ECB - U+2FEF (  293 chars) are GB18030 81 39 85 39 - 81 39 A3 31 (offset 2C7D - 2DA1)
1171             0xA98A, // U+2FF0 is non-936 GB18030 value A9 8A.
1172             0xA98B, // U+2FF1 is non-936 GB18030 value A9 8B.
1173             0xA98C, // U+2FF2 is non-936 GB18030 value A9 8C.
1174             0xA98D, // U+2FF3 is non-936 GB18030 value A9 8D.
1175             0xA98E, // U+2FF4 is non-936 GB18030 value A9 8E.
1176             0xA98F, // U+2FF5 is non-936 GB18030 value A9 8F.
1177             0xA990, // U+2FF6 is non-936 GB18030 value A9 90.
1178             0xA991, // U+2FF7 is non-936 GB18030 value A9 91.
1179             0xA992, // U+2FF8 is non-936 GB18030 value A9 92.
1180             0xA993, // U+2FF9 is non-936 GB18030 value A9 93.
1181             0xA994, // U+2FFA is non-936 GB18030 value A9 94.
1182             0xA995, // U+2FFB is non-936 GB18030 value A9 95.
1183             0x0004, // U+2FFC - U+2FFF (    4 chars) are GB18030 81 39 A3 32 - 81 39 A3 35 (offset 2DA2 - 2DA5)
1184             0x8004, // U+3000 - U+3003 (    4 chars) use CP 936 conversion.
1185             0x0001, // U+3004 - U+3004 (    1 chars) are GB18030 81 39 A3 36 - 81 39 A3 36 (offset 2DA6 - 2DA6)
1186             0x8013, // U+3005 - U+3017 (   19 chars) use CP 936 conversion.
1187             0x0005, // U+3018 - U+301C (    5 chars) are GB18030 81 39 A3 37 - 81 39 A4 31 (offset 2DA7 - 2DAB)
1188             0x8002, // U+301D - U+301E (    2 chars) use CP 936 conversion.
1189             0x0002, // U+301F - U+3020 (    2 chars) are GB18030 81 39 A4 32 - 81 39 A4 33 (offset 2DAC - 2DAD)
1190             0x8009, // U+3021 - U+3029 (    9 chars) use CP 936 conversion.
1191             0x0014, // U+302A - U+303D (   20 chars) are GB18030 81 39 A4 34 - 81 39 A6 33 (offset 2DAE - 2DC1)
1192             0xA989, // U+303E is non-936 GB18030 value A9 89.
1193             0x0002, // U+303F - U+3040 (    2 chars) are GB18030 81 39 A6 34 - 81 39 A6 35 (offset 2DC2 - 2DC3)
1194             0x8053, // U+3041 - U+3093 (   83 chars) use CP 936 conversion.
1195             0x0007, // U+3094 - U+309A (    7 chars) are GB18030 81 39 A6 36 - 81 39 A7 32 (offset 2DC4 - 2DCA)
1196             0x8004, // U+309B - U+309E (    4 chars) use CP 936 conversion.
1197             0x0002, // U+309F - U+30A0 (    2 chars) are GB18030 81 39 A7 33 - 81 39 A7 34 (offset 2DCB - 2DCC)
1198             0x8056, // U+30A1 - U+30F6 (   86 chars) use CP 936 conversion.
1199             0x0005, // U+30F7 - U+30FB (    5 chars) are GB18030 81 39 A7 35 - 81 39 A7 39 (offset 2DCD - 2DD1)
1200             0x8003, // U+30FC - U+30FE (    3 chars) use CP 936 conversion.
1201             0x0006, // U+30FF - U+3104 (    6 chars) are GB18030 81 39 A8 30 - 81 39 A8 35 (offset 2DD2 - 2DD7)
1202             0x8025, // U+3105 - U+3129 (   37 chars) use CP 936 conversion.
1203             0x00F6, // U+312A - U+321F (  246 chars) are GB18030 81 39 A8 36 - 81 39 C1 31 (offset 2DD8 - 2ECD)
1204             0x800A, // U+3220 - U+3229 (   10 chars) use CP 936 conversion.
1205             0x0007, // U+322A - U+3230 (    7 chars) are GB18030 81 39 C1 32 - 81 39 C1 38 (offset 2ECE - 2ED4)
1206             0x8001, // U+3231 - U+3231 (    1 chars) use CP 936 conversion.
1207             0x0071, // U+3232 - U+32A2 (  113 chars) are GB18030 81 39 C1 39 - 81 39 CD 31 (offset 2ED5 - 2F45)
1208             0x8001, // U+32A3 - U+32A3 (    1 chars) use CP 936 conversion.
1209             0x00EA, // U+32A4 - U+338D (  234 chars) are GB18030 81 39 CD 32 - 81 39 E4 35 (offset 2F46 - 302F)
1210             0x8002, // U+338E - U+338F (    2 chars) use CP 936 conversion.
1211             0x000C, // U+3390 - U+339B (   12 chars) are GB18030 81 39 E4 36 - 81 39 E5 37 (offset 3030 - 303B)
1212             0x8003, // U+339C - U+339E (    3 chars) use CP 936 conversion.
1213             0x0002, // U+339F - U+33A0 (    2 chars) are GB18030 81 39 E5 38 - 81 39 E5 39 (offset 303C - 303D)
1214             0x8001, // U+33A1 - U+33A1 (    1 chars) use CP 936 conversion.
1215             0x0022, // U+33A2 - U+33C3 (   34 chars) are GB18030 81 39 E6 30 - 81 39 E9 33 (offset 303E - 305F)
1216             0x8001, // U+33C4 - U+33C4 (    1 chars) use CP 936 conversion.
1217             0x0009, // U+33C5 - U+33CD (    9 chars) are GB18030 81 39 E9 34 - 81 39 EA 32 (offset 3060 - 3068)
1218             0x8001, // U+33CE - U+33CE (    1 chars) use CP 936 conversion.
1219             0x0002, // U+33CF - U+33D0 (    2 chars) are GB18030 81 39 EA 33 - 81 39 EA 34 (offset 3069 - 306A)
1220             0x8002, // U+33D1 - U+33D2 (    2 chars) use CP 936 conversion.
1221             0x0002, // U+33D3 - U+33D4 (    2 chars) are GB18030 81 39 EA 35 - 81 39 EA 36 (offset 306B - 306C)
1222             0x8001, // U+33D5 - U+33D5 (    1 chars) use CP 936 conversion.
1223             0x0071, // U+33D6 - U+3446 (  113 chars) are GB18030 81 39 EA 37 - 81 39 F5 39 (offset 306D - 30DD)
1224             0xFE56, // U+3447 is non-936 GB18030 value FE 56.
1225             0x002B, // U+3448 - U+3472 (   43 chars) are GB18030 81 39 F6 30 - 81 39 FA 32 (offset 30DE - 3108)
1226             0xFE55, // U+3473 is non-936 GB18030 value FE 55.
1227             0x012A, // U+3474 - U+359D (  298 chars) are GB18030 81 39 FA 33 - 82 30 9A 30 (offset 3109 - 3232)
1228             0xFE5A, // U+359E is non-936 GB18030 value FE 5A.
1229             0x006F, // U+359F - U+360D (  111 chars) are GB18030 82 30 9A 31 - 82 30 A5 31 (offset 3233 - 32A1)
1230             0xFE5C, // U+360E is non-936 GB18030 value FE 5C.
1231             0x000B, // U+360F - U+3619 (   11 chars) are GB18030 82 30 A5 32 - 82 30 A6 32 (offset 32A2 - 32AC)
1232             0xFE5B, // U+361A is non-936 GB18030 value FE 5B.
1233             0x02FD, // U+361B - U+3917 (  765 chars) are GB18030 82 30 A6 33 - 82 30 F2 37 (offset 32AD - 35A9)
1234             0xFE60, // U+3918 is non-936 GB18030 value FE 60.
1235             0x0055, // U+3919 - U+396D (   85 chars) are GB18030 82 30 F2 38 - 82 30 FB 32 (offset 35AA - 35FE)
1236             0xFE5F, // U+396E is non-936 GB18030 value FE 5F.
1237             0x0060, // U+396F - U+39CE (   96 chars) are GB18030 82 30 FB 33 - 82 31 86 38 (offset 35FF - 365E)
1238             0xFE62, // U+39CF is non-936 GB18030 value FE 62.
1239             0xFE65, // U+39D0 is non-936 GB18030 value FE 65.
1240             0x000E, // U+39D1 - U+39DE (   14 chars) are GB18030 82 31 86 39 - 82 31 88 32 (offset 365F - 366C)
1241             0xFE63, // U+39DF is non-936 GB18030 value FE 63.
1242             0x0093, // U+39E0 - U+3A72 (  147 chars) are GB18030 82 31 88 33 - 82 31 96 39 (offset 366D - 36FF)
1243             0xFE64, // U+3A73 is non-936 GB18030 value FE 64.
1244             0x00DA, // U+3A74 - U+3B4D (  218 chars) are GB18030 82 31 97 30 - 82 31 AC 37 (offset 3700 - 37D9)
1245             0xFE68, // U+3B4E is non-936 GB18030 value FE 68.
1246             0x011F, // U+3B4F - U+3C6D (  287 chars) are GB18030 82 31 AC 38 - 82 31 C9 34 (offset 37DA - 38F8)
1247             0xFE69, // U+3C6E is non-936 GB18030 value FE 69.
1248             0x0071, // U+3C6F - U+3CDF (  113 chars) are GB18030 82 31 C9 35 - 82 31 D4 37 (offset 38F9 - 3969)
1249             0xFE6A, // U+3CE0 is non-936 GB18030 value FE 6A.
1250             0x0375, // U+3CE1 - U+4055 (  885 chars) are GB18030 82 31 D4 38 - 82 32 AF 32 (offset 396A - 3CDE)
1251             0xFE6F, // U+4056 is non-936 GB18030 value FE 6F.
1252             0x0108, // U+4057 - U+415E (  264 chars) are GB18030 82 32 AF 33 - 82 32 C9 36 (offset 3CDF - 3DE6)
1253             0xFE70, // U+415F is non-936 GB18030 value FE 70.
1254             0x01D7, // U+4160 - U+4336 (  471 chars) are GB18030 82 32 C9 37 - 82 32 F8 37 (offset 3DE7 - 3FBD)
1255             0xFE72, // U+4337 is non-936 GB18030 value FE 72.
1256             0x0074, // U+4338 - U+43AB (  116 chars) are GB18030 82 32 F8 38 - 82 33 86 33 (offset 3FBE - 4031)
1257             0xFE78, // U+43AC is non-936 GB18030 value FE 78.
1258             0x0004, // U+43AD - U+43B0 (    4 chars) are GB18030 82 33 86 34 - 82 33 86 37 (offset 4032 - 4035)
1259             0xFE77, // U+43B1 is non-936 GB18030 value FE 77.
1260             0x002B, // U+43B2 - U+43DC (   43 chars) are GB18030 82 33 86 38 - 82 33 8B 30 (offset 4036 - 4060)
1261             0xFE7A, // U+43DD is non-936 GB18030 value FE 7A.
1262             0x00F8, // U+43DE - U+44D5 (  248 chars) are GB18030 82 33 8B 31 - 82 33 A3 38 (offset 4061 - 4158)
1263             0xFE7B, // U+44D6 is non-936 GB18030 value FE 7B.
1264             0x0175, // U+44D7 - U+464B (  373 chars) are GB18030 82 33 A3 39 - 82 33 C9 31 (offset 4159 - 42CD)
1265             0xFE7D, // U+464C is non-936 GB18030 value FE 7D.
1266             0x0014, // U+464D - U+4660 (   20 chars) are GB18030 82 33 C9 32 - 82 33 CB 31 (offset 42CE - 42E1)
1267             0xFE7C, // U+4661 is non-936 GB18030 value FE 7C.
1268             0x00C1, // U+4662 - U+4722 (  193 chars) are GB18030 82 33 CB 32 - 82 33 DE 34 (offset 42E2 - 43A2)
1269             0xFE80, // U+4723 is non-936 GB18030 value FE 80.
1270             0x0005, // U+4724 - U+4728 (    5 chars) are GB18030 82 33 DE 35 - 82 33 DE 39 (offset 43A3 - 43A7)
1271             0xFE81, // U+4729 is non-936 GB18030 value FE 81.
1272             0x0052, // U+472A - U+477B (   82 chars) are GB18030 82 33 DF 30 - 82 33 E7 31 (offset 43A8 - 43F9)
1273             0xFE82, // U+477C is non-936 GB18030 value FE 82.
1274             0x0010, // U+477D - U+478C (   16 chars) are GB18030 82 33 E7 32 - 82 33 E8 37 (offset 43FA - 4409)
1275             0xFE83, // U+478D is non-936 GB18030 value FE 83.
1276             0x01B9, // U+478E - U+4946 (  441 chars) are GB18030 82 33 E8 38 - 82 34 96 38 (offset 440A - 45C2)
1277             0xFE85, // U+4947 is non-936 GB18030 value FE 85.
1278             0x0032, // U+4948 - U+4979 (   50 chars) are GB18030 82 34 96 39 - 82 34 9B 38 (offset 45C3 - 45F4)
1279             0xFE86, // U+497A is non-936 GB18030 value FE 86.
1280             0x0002, // U+497B - U+497C (    2 chars) are GB18030 82 34 9B 39 - 82 34 9C 30 (offset 45F5 - 45F6)
1281             0xFE87, // U+497D is non-936 GB18030 value FE 87.
1282             0x0004, // U+497E - U+4981 (    4 chars) are GB18030 82 34 9C 31 - 82 34 9C 34 (offset 45F7 - 45FA)
1283             0xFE88, // U+4982 is non-936 GB18030 value FE 88.
1284             0xFE89, // U+4983 is non-936 GB18030 value FE 89.
1285             0x0001, // U+4984 - U+4984 (    1 chars) are GB18030 82 34 9C 35 - 82 34 9C 35 (offset 45FB - 45FB)
1286             0xFE8A, // U+4985 is non-936 GB18030 value FE 8A.
1287             0xFE8B, // U+4986 is non-936 GB18030 value FE 8B.
1288             0x0014, // U+4987 - U+499A (   20 chars) are GB18030 82 34 9C 36 - 82 34 9E 35 (offset 45FC - 460F)
1289             0xFE8D, // U+499B is non-936 GB18030 value FE 8D.
1290             0x0003, // U+499C - U+499E (    3 chars) are GB18030 82 34 9E 36 - 82 34 9E 38 (offset 4610 - 4612)
1291             0xFE8C, // U+499F is non-936 GB18030 value FE 8C.
1292             0x0016, // U+49A0 - U+49B5 (   22 chars) are GB18030 82 34 9E 39 - 82 34 A1 30 (offset 4613 - 4628)
1293             0xFE8F, // U+49B6 is non-936 GB18030 value FE 8F.
1294             0xFE8E, // U+49B7 is non-936 GB18030 value FE 8E.
1295             0x02BF, // U+49B8 - U+4C76 (  703 chars) are GB18030 82 34 A1 31 - 82 34 E7 33 (offset 4629 - 48E7)
1296             0xFE96, // U+4C77 is non-936 GB18030 value FE 96.
1297             0x0027, // U+4C78 - U+4C9E (   39 chars) are GB18030 82 34 E7 34 - 82 34 EB 32 (offset 48E8 - 490E)
1298             0xFE93, // U+4C9F is non-936 GB18030 value FE 93.
1299             0xFE94, // U+4CA0 is non-936 GB18030 value FE 94.
1300             0xFE95, // U+4CA1 is non-936 GB18030 value FE 95.
1301             0xFE97, // U+4CA2 is non-936 GB18030 value FE 97.
1302             0xFE92, // U+4CA3 is non-936 GB18030 value FE 92.
1303             0x006F, // U+4CA4 - U+4D12 (  111 chars) are GB18030 82 34 EB 33 - 82 34 F6 33 (offset 490F - 497D)
1304             0xFE98, // U+4D13 is non-936 GB18030 value FE 98.
1305             0xFE99, // U+4D14 is non-936 GB18030 value FE 99.
1306             0xFE9A, // U+4D15 is non-936 GB18030 value FE 9A.
1307             0xFE9B, // U+4D16 is non-936 GB18030 value FE 9B.
1308             0xFE9C, // U+4D17 is non-936 GB18030 value FE 9C.
1309             0xFE9D, // U+4D18 is non-936 GB18030 value FE 9D.
1310             0xFE9E, // U+4D19 is non-936 GB18030 value FE 9E.
1311             0x0094, // U+4D1A - U+4DAD (  148 chars) are GB18030 82 34 F6 34 - 82 35 87 31 (offset 497E - 4A11)
1312             0xFE9F, // U+4DAE is non-936 GB18030 value FE 9F.
1313             0x0051, // U+4DAF - U+4DFF (   81 chars) are GB18030 82 35 87 32 - 82 35 8F 32 (offset 4A12 - 4A62)
1314             0xD1A6, // U+4E00 - U+9FA5 (20902 chars) use CP 936 conversion.
1315             0x385A, // U+9FA6 - U+D7FF (14426 chars) are GB18030 82 35 8F 33 - 83 36 C7 38 (offset 4A63 - 82BC)
1316             0x8F6C, // U+D800 - U+E76B ( 3948 chars) use CP 936 conversion.
1317             0x0001, // U+E76C - U+E76C (    1 chars) are GB18030 83 36 C7 39 - 83 36 C7 39 (offset 82BD - 82BD)
1318             0x805B, // U+E76D - U+E7C7 (   91 chars) use CP 936 conversion.
1319             0x0001, // U+E7C8 - U+E7C8 (    1 chars) are GB18030 83 36 C8 30 - 83 36 C8 30 (offset 82BE - 82BE)
1320             0x801E, // U+E7C9 - U+E7E6 (   30 chars) use CP 936 conversion.
1321             0x000D, // U+E7E7 - U+E7F3 (   13 chars) are GB18030 83 36 C8 31 - 83 36 C9 33 (offset 82BF - 82CB)
1322             0x8021, // U+E7F4 - U+E814 (   33 chars) use CP 936 conversion.
1323             0x0001, // U+E815 - U+E815 (    1 chars) are GB18030 83 36 C9 34 - 83 36 C9 34 (offset 82CC - 82CC)
1324             0x8003, // U+E816 - U+E818 (    3 chars) use CP 936 conversion.
1325             0x0005, // U+E819 - U+E81D (    5 chars) are GB18030 83 36 C9 35 - 83 36 C9 39 (offset 82CD - 82D1)
1326             0x8001, // U+E81E - U+E81E (    1 chars) use CP 936 conversion.
1327             0x0007, // U+E81F - U+E825 (    7 chars) are GB18030 83 36 CA 30 - 83 36 CA 36 (offset 82D2 - 82D8)
1328             0x8001, // U+E826 - U+E826 (    1 chars) use CP 936 conversion.
1329             0x0004, // U+E827 - U+E82A (    4 chars) are GB18030 83 36 CA 37 - 83 36 CB 30 (offset 82D9 - 82DC)
1330             0x8002, // U+E82B - U+E82C (    2 chars) use CP 936 conversion.
1331             0x0004, // U+E82D - U+E830 (    4 chars) are GB18030 83 36 CB 31 - 83 36 CB 34 (offset 82DD - 82E0)
1332             0x8002, // U+E831 - U+E832 (    2 chars) use CP 936 conversion.
1333             0x0008, // U+E833 - U+E83A (    8 chars) are GB18030 83 36 CB 35 - 83 36 CC 32 (offset 82E1 - 82E8)
1334             0x8001, // U+E83B - U+E83B (    1 chars) use CP 936 conversion.
1335             0x0007, // U+E83C - U+E842 (    7 chars) are GB18030 83 36 CC 33 - 83 36 CC 39 (offset 82E9 - 82EF)
1336             0x8001, // U+E843 - U+E843 (    1 chars) use CP 936 conversion.
1337             0x0010, // U+E844 - U+E853 (   16 chars) are GB18030 83 36 CD 30 - 83 36 CE 35 (offset 82F0 - 82FF)
1338             0x8002, // U+E854 - U+E855 (    2 chars) use CP 936 conversion.
1339             0x000E, // U+E856 - U+E863 (   14 chars) are GB18030 83 36 CE 36 - 83 36 CF 39 (offset 8300 - 830D)
1340             0x8001, // U+E864 - U+E864 (    1 chars) use CP 936 conversion.
1341             0x10C7, // U+E865 - U+F92B ( 4295 chars) are GB18030 83 36 D0 30 - 84 30 85 34 (offset 830E - 93D4)
1342             0x8001, // U+F92C - U+F92C (    1 chars) use CP 936 conversion.
1343             0x004C, // U+F92D - U+F978 (   76 chars) are GB18030 84 30 85 35 - 84 30 8D 30 (offset 93D5 - 9420)
1344             0x8001, // U+F979 - U+F979 (    1 chars) use CP 936 conversion.
1345             0x001B, // U+F97A - U+F994 (   27 chars) are GB18030 84 30 8D 31 - 84 30 8F 37 (offset 9421 - 943B)
1346             0x8001, // U+F995 - U+F995 (    1 chars) use CP 936 conversion.
1347             0x0051, // U+F996 - U+F9E6 (   81 chars) are GB18030 84 30 8F 38 - 84 30 97 38 (offset 943C - 948C)
1348             0x8001, // U+F9E7 - U+F9E7 (    1 chars) use CP 936 conversion.
1349             0x0009, // U+F9E8 - U+F9F0 (    9 chars) are GB18030 84 30 97 39 - 84 30 98 37 (offset 948D - 9495)
1350             0x8001, // U+F9F1 - U+F9F1 (    1 chars) use CP 936 conversion.
1351             0x001A, // U+F9F2 - U+FA0B (   26 chars) are GB18030 84 30 98 38 - 84 30 9B 33 (offset 9496 - 94AF)
1352             0x8004, // U+FA0C - U+FA0F (    4 chars) use CP 936 conversion.
1353             0x0001, // U+FA10 - U+FA10 (    1 chars) are GB18030 84 30 9B 34 - 84 30 9B 34 (offset 94B0 - 94B0)
1354             0x8001, // U+FA11 - U+FA11 (    1 chars) use CP 936 conversion.
1355             0x0001, // U+FA12 - U+FA12 (    1 chars) are GB18030 84 30 9B 35 - 84 30 9B 35 (offset 94B1 - 94B1)
1356             0x8002, // U+FA13 - U+FA14 (    2 chars) use CP 936 conversion.
1357             0x0003, // U+FA15 - U+FA17 (    3 chars) are GB18030 84 30 9B 36 - 84 30 9B 38 (offset 94B2 - 94B4)
1358             0x8001, // U+FA18 - U+FA18 (    1 chars) use CP 936 conversion.
1359             0x0006, // U+FA19 - U+FA1E (    6 chars) are GB18030 84 30 9B 39 - 84 30 9C 34 (offset 94B5 - 94BA)
1360             0x8003, // U+FA1F - U+FA21 (    3 chars) use CP 936 conversion.
1361             0x0001, // U+FA22 - U+FA22 (    1 chars) are GB18030 84 30 9C 35 - 84 30 9C 35 (offset 94BB - 94BB)
1362             0x8002, // U+FA23 - U+FA24 (    2 chars) use CP 936 conversion.
1363             0x0002, // U+FA25 - U+FA26 (    2 chars) are GB18030 84 30 9C 36 - 84 30 9C 37 (offset 94BC - 94BD)
1364             0x8003, // U+FA27 - U+FA29 (    3 chars) use CP 936 conversion.
1365             0x0406, // U+FA2A - U+FE2F ( 1030 chars) are GB18030 84 30 9C 38 - 84 31 85 37 (offset 94BE - 98C3)
1366             0x8002, // U+FE30 - U+FE31 (    2 chars) use CP 936 conversion.
1367             0x0001, // U+FE32 - U+FE32 (    1 chars) are GB18030 84 31 85 38 - 84 31 85 38 (offset 98C4 - 98C4)
1368             0x8012, // U+FE33 - U+FE44 (   18 chars) use CP 936 conversion.
1369             0x0004, // U+FE45 - U+FE48 (    4 chars) are GB18030 84 31 85 39 - 84 31 86 32 (offset 98C5 - 98C8)
1370             0x800A, // U+FE49 - U+FE52 (   10 chars) use CP 936 conversion.
1371             0x0001, // U+FE53 - U+FE53 (    1 chars) are GB18030 84 31 86 33 - 84 31 86 33 (offset 98C9 - 98C9)
1372             0x8004, // U+FE54 - U+FE57 (    4 chars) use CP 936 conversion.
1373             0x0001, // U+FE58 - U+FE58 (    1 chars) are GB18030 84 31 86 34 - 84 31 86 34 (offset 98CA - 98CA)
1374             0x800E, // U+FE59 - U+FE66 (   14 chars) use CP 936 conversion.
1375             0x0001, // U+FE67 - U+FE67 (    1 chars) are GB18030 84 31 86 35 - 84 31 86 35 (offset 98CB - 98CB)
1376             0x8004, // U+FE68 - U+FE6B (    4 chars) use CP 936 conversion.
1377             0x0095, // U+FE6C - U+FF00 (  149 chars) are GB18030 84 31 86 36 - 84 31 95 34 (offset 98CC - 9960)
1378             0x805E, // U+FF01 - U+FF5E (   94 chars) use CP 936 conversion.
1379             0x0081, // U+FF5F - U+FFDF (  129 chars) are GB18030 84 31 95 35 - 84 31 A2 33 (offset 9961 - 99E1)
1380             0x8006, // U+FFE0 - U+FFE5 (    6 chars) use CP 936 conversion.
1381             0x001A, // U+FFE6 - U+FFFF (   26 chars) are GB18030 84 31 A2 34 - 84 31 A4 39 (offset 99E2 - 99FB)
1382         };
1383     }
1384 }
1385 #endif // FEATURE_CODEPAGES_FILE
1386