The Labs \ Source Viewer \ SSCLI \ System.Text \ GB18030Decoder

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

Developer Fusion