// Workhorse
        internal override unsafe int GetBytes(char *chars, int charCount,
                                                byte* bytes, int byteCount, EncoderNLS baseEncoder)
        {
            // Allow null bytes for counting
            BCLDebug.Assert(chars != null, "[ISCIIEncoding.GetBytes]chars!=null");
//            BCLDebug.Assert(bytes != null, "[ISCIIEncoding.GetBytes]bytes!=null");
            BCLDebug.Assert(charCount >=0, "[ISCIIEncoding.GetBytes]charCount >=0");
            BCLDebug.Assert(byteCount >=0, "[ISCIIEncoding.GetBytes]byteCount >=0");

            // Need the ISCII Encoder
            ISCIIEncoder encoder = (ISCIIEncoder) baseEncoder;

            // prepare our helpers
            Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(
                this, encoder, bytes, byteCount, chars, charCount);

            int   currentCodePage = this.defaultCodePage;
            bool  bLastVirama = false;

            // Use encoder info if available
            if (encoder != null)
            {
                // Remember our old state
                currentCodePage = encoder.currentCodePage;
                bLastVirama = encoder.bLastVirama;

                // If we have a high surrogate left over, then fall it back
                if (encoder.charLeftOver > 0)
                {
                    buffer.Fallback(encoder.charLeftOver);
                    bLastVirama = false;        // Redundant
                }
            }

            while (buffer.MoreData)
            {
                // Get our data
                char ch = buffer.GetNextChar();

                // See if its a Multi Byte Character
                if (ch < MultiByteBegin)
                {
                    // Its a boring low character, add it.
                    if (!buffer.AddByte((byte)ch))
                        break;
                    bLastVirama = false;
                    continue;
                }

                // See if its outside of the Indic script Range range
                if ((ch < IndicBegin) || (ch > IndicEnd))
                {
                    // See if its a ZWJ or ZWNJ and if we has bLastVirama;
                    if (bLastVirama && (ch == ZWNJ || ch == ZWJ))
                    {
                        // It was a bLastVirama and ZWNJ || ZWJ
                        if (ch == ZWNJ)
                        {
                            if (!buffer.AddByte(Virama))
                                break;
                        }
                        else // ZWJ
                        {
                            if (!buffer.AddByte(Nukta))
                                break;
                        }

                        // bLastVirama now counts as false
                        bLastVirama = false;
                        continue;
                    }

                    // Have to do our fallback
                    //
                    // Note that this will fallback 2 chars if this is a high surrogate.
                    // Throws if recursive (knows because we called InternalGetNextChar)
                    buffer.Fallback(ch);
                    bLastVirama = false;
                    continue;
                }

                // Its in the Unicode Indic script range
                int indicInfo = UnicodeToIndicChar[ch - IndicBegin];
                byte byteIndic = (byte)indicInfo;
                int indicScript = (0x000f & (indicInfo >> 8));
                int indicTwoBytes = (0xf000 & indicInfo);

                // If IndicInfo is 0 then have to do fallback
                if (indicInfo == 0)
                {
                    // Its some Unicode character we don't have indic for.
                    // Have to do our fallback
                    // Add Fallback Count
                    // Note that chars was preincremented, and GetEncoderFallbackString might add an extra
                    // if chars != charEnd and there's a surrogate.
                    // Throws if recursive (knows because we called InternalGetNextChar)
                    buffer.Fallback(ch);

                    bLastVirama = false;
                    continue;
                }

                // See if our code page ("font" in ISCII spec) has to change
                // (This if doesn't add character, just changes character set)
                BCLDebug.Assert(indicScript!=0, "[ISCIIEncoding.GetBytes]expected an indic script value");
                if (indicScript != currentCodePage)
                {
                    // It changed, spit out the ATR
                    if (!buffer.AddByte(ControlATR, (byte)(indicScript | ControlCodePageStart)))
                        break;

                    // Now spit out the new code page (& remember it) (do this afterwards in case AddByte failed)
                    currentCodePage = indicScript;

                    // We only know how to map from Unicode to pages from Devanagari to Punjabi (2 to 11)
                    BCLDebug.Assert(currentCodePage >= CodeDevanagari && currentCodePage <= CodePunjabi,
                        "[ISCIIEncoding.GetBytes]Code page (" + currentCodePage + " shouldn't appear in ISCII from Unicode table!");
                }

                // Safe to add our byte now
                if (!buffer.AddByte(byteIndic, indicTwoBytes != 0 ? 1:0))
                    break;

                // Remember if this one was a Virama
                bLastVirama = (byteIndic == Virama);

                // Some characters need extra bytes
                if (indicTwoBytes != 0)
                {
                    // This one needs another byte
                    BCLDebug.Assert((indicTwoBytes >> 12) > 0 && (indicTwoBytes >> 12) <= 3,
                        "[ISCIIEncoding.GetBytes]Expected indicTwoBytes from 1-3, not " + (indicTwoBytes >> 12));

                    // Already did buffer checking, but...
                    if (!buffer.AddByte(SecondIndicByte[indicTwoBytes >> 12]))
                        break;
                }
            }

            // May need to switch back to our default code page
            if (currentCodePage != defaultCodePage && (encoder == null || encoder.MustFlush))
            {
                // It changed, spit out the ATR
                if (buffer.AddByte(ControlATR, (byte)(defaultCodePage | ControlCodePageStart)))
                    currentCodePage = defaultCodePage;
                else
                    // If not successful, convert will maintain state for next time, also
                    // AddByte will have decremented our char count, however we need it to remain the same
                    buffer.GetNextChar();
                bLastVirama = false;
            }

            // Make sure we remember our state if necessary
            // Note that we don't care about flush because Virama and code page
            // changes are legal at the end.
            // Don't set encoder if we're just counting
            if (encoder != null && bytes != null)
            {
                // Clear Encoder if necessary.
                if (!buffer.fallbackBuffer.bUsedEncoder)
                {
                    encoder.charLeftOver = (char)0;
                }

                // Remember our code page/virama state
                encoder.currentCodePage = currentCodePage;
                encoder.bLastVirama = bLastVirama;

                // How many chars were used?
                encoder.m_charsUsed = buffer.CharsUsed;
            }

            // Return our length
            return buffer.Count;
       }
        [System.Security.SecurityCritical]  // auto-generated
        private unsafe int GetBytesCP52936(char* chars, int charCount,
                                           byte* bytes, int byteCount, ISO2022Encoder encoder)
        {
            // prepare our helpers
            Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(
                this, encoder, bytes, byteCount, chars, charCount);

            // Mode
            ISO2022Modes currentMode = ISO2022Modes.ModeASCII;

            // Check our encoder
            if (encoder != null)
            {
                char charLeftOver = encoder.charLeftOver;
                currentMode = encoder.currentMode;

                // We may have a left over character from last time, try and process it.
                if (charLeftOver > 0)
                {
                    Contract.Assert(Char.IsHighSurrogate(charLeftOver), "[ISO2022Encoding.GetBytesCP52936]leftover character should be high surrogate");

                    // It has to be a high surrogate, which we don't support, so it has to be a fallback
                    buffer.Fallback(charLeftOver);
                }
            }

            while (buffer.MoreData)
            {
                // Get our char
                char ch = buffer.GetNextChar();

                // Get our bytes
                ushort sChar = mapUnicodeToBytes[ch];
                if (sChar == 0 && ch != 0)
                {
                    // Wasn't a legal byte sequence, its a surrogate or fallback
                    // Throws if recursive (knows because we called InternalGetNextChar)
                    buffer.Fallback(ch);

                    // Done with our char, now process fallback
                    continue;
                }

                // Check for halfwidth bytes
                byte bLeadByte = (byte)(sChar >> 8);
                byte bTrailByte = (byte)(sChar & 0xff);

                // If its a double byte, it has to fit in the lead byte 0xa1 - 0xf7, trail byte 0xa1 - 0xfe range
                // (including the 0x8080 that our codepage or's to the value)
                if ((bLeadByte != 0 &&
                     (bLeadByte < 0xa1 || bLeadByte > 0xf7 || bTrailByte < 0xa1 || bTrailByte > 0xfe)) ||
                    (bLeadByte == 0 && bTrailByte > 0x80 && bTrailByte != 0xff))
                {
                    // Illegal character, in 936 code page, but not in HZ subset, get fallback for it
                    buffer.Fallback(ch);
                    continue;
                }

                // sChar is now either ASCII or has an 0x8080 mask
                if (bLeadByte != 0)
                {
                    // Its a double byte mode
                    if (currentMode != ISO2022Modes.ModeHZ)
                    {
                        // Need to add the double byte mode marker
                        if (!buffer.AddByte((byte)'~', (byte)'{', 2))
                            break;                                      // Stop if no buffer space in convert

                        currentMode = ISO2022Modes.ModeHZ;
                    }

                    // Go ahead and add the 2 bytes
                    if (!buffer.AddByte(unchecked((byte)(bLeadByte & 0x7f)), unchecked((byte)(bTrailByte & 0x7f))))
                        break;                                      // Stop if no buffer space in convert
                }
                else
                {
                    // Its supposed to be ASCII
                    if (currentMode != ISO2022Modes.ModeASCII)
                    {
                        // Need to add the ASCII mode marker
                        // Will have 1 more byte (or 2 if ~)
                        if (!buffer.AddByte((byte)'~', (byte)'}', bTrailByte == '~' ? 2:1))
                            break;

                        currentMode = ISO2022Modes.ModeASCII;
                    }

                    // If its a '~' we'll need an extra one
                    if (bTrailByte == '~')
                    {
                        // Need to add the extra ~
                        if (!buffer.AddByte((byte)'~', 1))
                            break;
                    }

                    // Need to add the character
                    if (!buffer.AddByte(bTrailByte))
                        break;
                }
            }

            // Add ASCII shift out if we're at end of decoder
            if (currentMode != ISO2022Modes.ModeASCII &&
                (encoder == null || encoder.MustFlush))
            {
                // Need to add the ASCII mode marker
                // Only turn off other mode if this works
                if (buffer.AddByte((byte)'~',(byte)'}'))
                    currentMode = ISO2022Modes.ModeASCII;
                else
                    // If not successful, convert will maintain state for next time, also
                    // AddByte will have decremented our char count, however we need it to remain the same
                    buffer.GetNextChar();
            }

            // Need to remember our mode
            if (encoder != null && bytes != null)
            {
                // This is ASCII if we had to flush
                encoder.currentMode = currentMode;

                if (!buffer.fallbackBuffer.bUsedEncoder)
                {
                    encoder.charLeftOver = (char)0;
                }

                encoder.m_charsUsed = buffer.CharsUsed;
            }

            // Return our length
            return buffer.Count;
        }
Exemple #3
0
        [System.Security.SecurityCritical]  // auto-generated
        internal override unsafe int GetBytes(char* chars, int charCount,
                                                byte* bytes, int byteCount, EncoderNLS baseEncoder)
        {
            Contract.Assert(byteCount >=0, "[UTF7Encoding.GetBytes]byteCount >=0");
            Contract.Assert(chars!=null, "[UTF7Encoding.GetBytes]chars!=null");
            Contract.Assert(charCount >=0, "[UTF7Encoding.GetBytes]charCount >=0");

            // Get encoder info
            UTF7Encoding.Encoder encoder = (UTF7Encoding.Encoder)baseEncoder;

            // Default bits & count
            int bits = 0;
            int bitCount = -1;

            // prepare our helpers
            Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(
                this, encoder, bytes, byteCount, chars, charCount);

            if (encoder != null)
            {
                bits = encoder.bits;
                bitCount = encoder.bitCount;

                // May have had too many left over
                while (bitCount >= 6)
                {
                    bitCount -= 6;
                    // If we fail we'll never really have enough room
                    if (!buffer.AddByte(base64Bytes[(bits >> bitCount) & 0x3F]))
                        ThrowBytesOverflow(encoder, buffer.Count == 0);
                }
            }

            while (buffer.MoreData)
            {
                char currentChar = buffer.GetNextChar();

                if (currentChar < 0x80 && directEncode[currentChar])
                {
                    if (bitCount >= 0)
                    {
                        if (bitCount > 0)
                        {
                            // Try to add the next byte
                            if (!buffer.AddByte(base64Bytes[bits << 6 - bitCount & 0x3F]))
                                break;                                          // Stop here, didn't throw

                            bitCount = 0;
                        }

                        // Need to get emit '-' and our char, 2 bytes total
                        if (!buffer.AddByte((byte)'-'))
                            break;                                          // Stop here, didn't throw

                        bitCount = -1;
                    }

                    // Need to emit our char
                    if (!buffer.AddByte((byte)currentChar))
                        break;                                          // Stop here, didn't throw
                }
                else if (bitCount < 0 && currentChar == '+')
                {
                    if (!buffer.AddByte((byte)'+', (byte)'-'))
                        break;                                          // Stop here, didn't throw
                }
                else
                {
                    if (bitCount < 0)
                    {
                        // Need to emit a + and 12 bits (3 bytes)
                        // Only 12 of the 16 bits will be emitted this time, the other 4 wait 'til next time
                        if (!buffer.AddByte((byte)'+'))
                            break;                                          // Stop here, didn't throw

                        // We're now in bit mode, but haven't stored data yet
                        bitCount = 0;
                    }

                    // Add our bits
                    bits = bits << 16 | currentChar;
                    bitCount += 16;

                    while (bitCount >= 6)
                    {
                        bitCount -= 6;
                        if (!buffer.AddByte(base64Bytes[(bits >> bitCount) & 0x3F]))
                        {
                            bitCount += 6;                              // We didn't use these bits
                            currentChar = buffer.GetNextChar();              // We're processing this char still, but AddByte
                                                                        // --'d it when we ran out of space
                            break;                                      // Stop here, not enough room for bytes
                        }
                    }

                    if (bitCount >= 6)
                        break;                  // Didn't have room to encode enough bits
                }
            }

            // Now if we have bits left over we have to encode them.
            // MustFlush may have been cleared by encoding.ThrowBytesOverflow earlier if converting
            if (bitCount >= 0 && (encoder == null || encoder.MustFlush))
            {
                // Do we have bits we have to stick in?
                if (bitCount > 0)
                {
                    if (buffer.AddByte(base64Bytes[(bits << (6 - bitCount)) & 0x3F]))
                    {
                        // Emitted spare bits, 0 bits left
                        bitCount = 0;
                    }
                }

                // If converting and failed bitCount above, then we'll fail this too
                if (buffer.AddByte((byte)'-'))
                {
                    // turned off bit mode';
                    bits = 0;
                    bitCount = -1;
                }
                else
                    // If not successful, convert will maintain state for next time, also
                    // AddByte will have decremented our char count, however we need it to remain the same
                    buffer.GetNextChar();
            }

            // Do we have an encoder we're allowed to use?
            // bytes == null if counting, so don't use encoder then
            if (bytes != null && encoder != null)
            {
                // We already cleared bits & bitcount for mustflush case
                encoder.bits = bits;
                encoder.bitCount = bitCount;
                encoder.m_charsUsed = buffer.CharsUsed;
            }

            return buffer.Count;
        }
        [System.Security.SecurityCritical]  // auto-generated
        private unsafe int GetBytesCP5022xJP(char* chars, int charCount,
                                                  byte* bytes, int byteCount, ISO2022Encoder encoder)
        {
            // prepare our helpers
            Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(
                this, encoder, bytes, byteCount, chars, charCount);

            // Get our mode
            ISO2022Modes currentMode = ISO2022Modes.ModeASCII;      // Mode
            ISO2022Modes shiftInMode = ISO2022Modes.ModeASCII;      // Mode that shift in will go back to (only used by CP 50222)

            // Check our encoder
            if (encoder != null)
            {
                char charLeftOver = encoder.charLeftOver;

                currentMode = encoder.currentMode;
                shiftInMode = encoder.shiftInOutMode;

                // We may have a left over character from last time, try and process it.
                if (charLeftOver > 0)
                {
                    Contract.Assert(Char.IsHighSurrogate(charLeftOver), "[ISO2022Encoding.GetBytesCP5022xJP]leftover character should be high surrogate");

                    // It has to be a high surrogate, which we don't support, so it has to be a fallback
                    buffer.Fallback(charLeftOver);
                }
            }

            while (buffer.MoreData)
            {
                // Get our char
                char ch = buffer.GetNextChar();

                // Get our bytes
                ushort iBytes = mapUnicodeToBytes[ch];

                StartConvert:
                // Check for halfwidth bytes
                byte bLeadByte = (byte)(iBytes >> 8);
                byte bTrailByte = (byte)(iBytes & 0xff);

                if (bLeadByte == LEADBYTE_HALFWIDTH)
                {
                    // Its Halfwidth Katakana
                    if (CodePage == 50220)
                    {
                        // CodePage 50220 doesn't use halfwidth Katakana, convert to fullwidth
                        // See if its out of range, fallback if so, throws if recursive fallback
                        if (bTrailByte < 0x21 || bTrailByte >= 0x21 + HalfToFullWidthKanaTable.Length)
                        {
                            buffer.Fallback(ch);
                            continue;
                        }

                        // Get the full width katakana char to use.
                        iBytes = unchecked((ushort)(HalfToFullWidthKanaTable[bTrailByte - 0x21] & 0x7F7F));

                        // May have to do all sorts of fun stuff for mode, go back to start convert
                        goto StartConvert;
                    }

                    // Can use halfwidth Katakana, make sure we're in right mode

                    // Make sure we're in right mode
                    if (currentMode != ISO2022Modes.ModeHalfwidthKatakana)
                    {
                        // 50222 or 50221, either shift in/out or escape to get to Katakana mode
                        if (CodePage == 50222)
                        {
                            // Shift Out
                            if (!buffer.AddByte(SHIFT_OUT))
                                break;  // convert out of space, stop

                            // Don't change modes until after AddByte in case it fails for convert
                            // We get to shift out to Katakana, make sure we'll go back to the right mode
                            // (This ends up always being ASCII)
                            shiftInMode = currentMode;
                            currentMode = ISO2022Modes.ModeHalfwidthKatakana;
                        }
                        else
                        {
                            // 50221 does halfwidth katakana by escape sequence
                            Contract.Assert(CodePage == 50221, "[ISO2022Encoding.GetBytesCP5022xJP]Expected Code Page 50221");

                            // Add our escape sequence
                            if (!buffer.AddByte(ESCAPE, unchecked((byte)'('), unchecked((byte)'I')))
                                break;  // convert out of space, stop

                            currentMode = ISO2022Modes.ModeHalfwidthKatakana;
                        }
                    }

                    // We know we're in Katakana mode now, so add it.
                    // Go ahead and add the Katakana byte.  Our table tail bytes are 0x80 too big.
                    if (!buffer.AddByte(unchecked((byte)(bTrailByte & 0x7F))))
                        break;  // convert out of space, stop

                    // Done with this one
                    continue;
                }
                else if (bLeadByte != 0)
                {
                    //
                    //  It's a double byte character.
                    //

                    // If we're CP 50222 we may have to shift in from Katakana mode first
                    if (CodePage == 50222 && currentMode == ISO2022Modes.ModeHalfwidthKatakana)
                    {
                        // Shift In
                        if (!buffer.AddByte(SHIFT_IN))
                            break;    // convert out of space, stop

                        // Need to shift in from katakana.  (Still might not be right, but won't be shifted out anyway)
                        currentMode = shiftInMode;
                    }

                    // Make sure we're in the right mode (JIS 0208 or JIS 0212)
                    // Note: Right now we don't use JIS 0212.  Also this table'd be wrong

                    // Its JIS extension 0208
                    if (currentMode != ISO2022Modes.ModeJIS0208)
                    {
                        // Escape sequence, we can fail after this, mode will be correct for convert
                        if (!buffer.AddByte(ESCAPE, unchecked((byte)'$'), unchecked((byte)'B')))
                            break;  // Convert out of space, stop

                        currentMode = ISO2022Modes.ModeJIS0208;
                    }

                    // Add our double bytes
                    if (!buffer.AddByte(unchecked((byte)(bLeadByte)), unchecked((byte)(bTrailByte))))
                        break; // Convert out of space, stop
                    continue;
                }
                else if (iBytes != 0 || ch == 0)
                {
                    // Single byte Char
                    // If we're CP 50222 we may have to shift in from Katakana mode first
                    if (CodePage == 50222 && currentMode == ISO2022Modes.ModeHalfwidthKatakana)
                    {
                        // Shift IN
                        if (!buffer.AddByte(SHIFT_IN))
                            break; // convert ran out of room

                        // Need to shift in from katakana.  (Still might not be right, but won't be shifted out anyway)
                        currentMode = shiftInMode;
                    }

                    // Its a single byte character, switch to ASCII if we have to
                    if (currentMode != ISO2022Modes.ModeASCII)
                    {
                        if (!buffer.AddByte(ESCAPE,unchecked((byte)'('), unchecked((byte)'B')))
                            break; // convert ran out of room

                        currentMode = ISO2022Modes.ModeASCII;
                    }

                    // Add the ASCII char
                    if (!buffer.AddByte(bTrailByte))
                        break; // convert had no room left
                    continue;
                }

                // Its unknown, do fallback, throws if recursive (knows because we called InternalGetNextChar)
                buffer.Fallback(ch);
            }

            // Switch back to ASCII if MustFlush or no encoder
            if (currentMode != ISO2022Modes.ModeASCII &&
                (encoder == null || encoder.MustFlush))
            {
                // If we're CP 50222 we may have to shift in from Katakana mode first
                if (CodePage == 50222 && currentMode == ISO2022Modes.ModeHalfwidthKatakana)
                {
                    // Shift IN, only shift mode if necessary.
                    if (buffer.AddByte(SHIFT_IN))
                        // Need to shift in from katakana.  (Still might not be right, but won't be shifted out anyway)
                        currentMode = shiftInMode;
                    else
                        // If not successful, convert will maintain state for next time, also
                        // AddByte will have decremented our char count, however we need it to remain the same
                        buffer.GetNextChar();
                }

                // switch back to ASCII to finish neatly
                if (currentMode != ISO2022Modes.ModeASCII &&
                    (CodePage != 50222 || currentMode != ISO2022Modes.ModeHalfwidthKatakana))
                {
                    // only shift if it was successful
                    if (buffer.AddByte(ESCAPE, unchecked((byte)'('), unchecked((byte)'B')))
                        currentMode = ISO2022Modes.ModeASCII;
                    else
                        // If not successful, convert will maintain state for next time, also
                        // AddByte will have decremented our char count, however we need it to remain the same
                        buffer.GetNextChar();
                }
            }

            // Remember our encoder state
            if (bytes != null && encoder != null)
            {
                // This is ASCII if we had to flush
                encoder.currentMode = currentMode;
                encoder.shiftInOutMode = shiftInMode;

                if (!buffer.fallbackBuffer.bUsedEncoder)
                {
                    encoder.charLeftOver = (char)0;
                }

                encoder.m_charsUsed = buffer.CharsUsed;
            }

            // Return our length
            return buffer.Count;
        }
        [System.Security.SecurityCritical]  // auto-generated
        private unsafe int GetBytesCP50225KR(char* chars, int charCount,
                                                    byte* bytes, int byteCount, ISO2022Encoder encoder)
        {
            // prepare our helpers
            Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(
                this, encoder, bytes, byteCount, chars, charCount);

            // Get our mode
            ISO2022Modes currentMode = ISO2022Modes.ModeASCII;      // Mode
            ISO2022Modes shiftOutMode = ISO2022Modes.ModeASCII;     // ModeKR if already stamped lead bytes

            // Check our encoder
            if (encoder != null)
            {
                // May have leftover stuff
                char charLeftOver = encoder.charLeftOver;
                currentMode = encoder.currentMode;
                shiftOutMode = encoder.shiftInOutMode;

                // We may have a l left over character from last time, try and process it.
                if (charLeftOver > 0)
                {
                    Contract.Assert(Char.IsHighSurrogate(charLeftOver), "[ISO2022Encoding.GetBytesCP50225KR]leftover character should be high surrogate");

                    // It has to be a high surrogate, which we don't support, so it has to be a fallback
                    buffer.Fallback(charLeftOver);
                }
            }

            while (buffer.MoreData)
            {
                // Get our data
                char ch = buffer.GetNextChar();

                // Get our bytes
                ushort iBytes = mapUnicodeToBytes[ch];

                // Check for double byte bytes
                byte bLeadByte = (byte)(iBytes >> 8);
                byte bTrailByte = (byte)(iBytes & 0xff);

                if (bLeadByte != 0)
                {
                    //
                    //  It's a double byte character.
                    //

                    // If we haven't done our Korean designator, then do so, if we have any input
                    if (shiftOutMode != ISO2022Modes.ModeKR)
                    {
                        // Add our code page designator sequence
                        if (!buffer.AddByte(ESCAPE, unchecked((byte)'$'), unchecked((byte)')'), unchecked((byte)'C')))
                            break; // No room during convert.

                        shiftOutMode = ISO2022Modes.ModeKR;
                    }

                    // May have to switch to ModeKR first
                    if (currentMode != ISO2022Modes.ModeKR)
                    {
                        if (!buffer.AddByte(SHIFT_OUT))
                            break; // No convert room

                        currentMode = ISO2022Modes.ModeKR;
                    }

                    // Add the bytes
                    if (!buffer.AddByte(bLeadByte, bTrailByte))
                        break; // no convert room
                    continue;
                }
                else if (iBytes != 0 || ch == 0)
                {
                    // Its a single byte character, switch to ASCII if we have to
                    if (currentMode != ISO2022Modes.ModeASCII)
                    {
                        if (!buffer.AddByte(SHIFT_IN))
                            break;

                        currentMode = ISO2022Modes.ModeASCII;
                    }

                    // Add the ASCII char
                    if (!buffer.AddByte(bTrailByte))
                        break;
                    continue;
                }

                // Its unknown, do fallback, throws if recursive (knows because we called InternalGetNextChar)
                buffer.Fallback(ch);
            }

            // Switch back to ASCII if MustFlush or no encoder
            if (currentMode != ISO2022Modes.ModeASCII &&
                (encoder == null || encoder.MustFlush))
            {
                // Get back to ASCII to be safe.  Only do it if it success.
                if (buffer.AddByte(SHIFT_IN))
                    currentMode = ISO2022Modes.ModeASCII;
                else
                    // If not successful, convert will maintain state for next time, also
                    // AddByte will have decremented our char count, however we need it to remain the same
                    buffer.GetNextChar();
            }

            // Remember our encoder state
            if (bytes != null && encoder != null)
            {
                // If we didn't use the encoder, then there's no chars left over
                if (!buffer.fallbackBuffer.bUsedEncoder)
                {
                    encoder.charLeftOver = (char)0;
                }
                
                // This is ASCII if we had to flush
                encoder.currentMode = currentMode;

                // We don't use shift out mode, but if we've flushed we need to reset it so it doesn't 
                // get output again.
                if (!encoder.MustFlush || encoder.charLeftOver != (char)0)
                {
                    // We should be not flushing or converting
                    Contract.Assert(!encoder.MustFlush || !encoder.m_throwOnOverflow,
                        "[ISO2022Encoding.GetBytesCP50225KR]Expected no left over data or not flushing or not converting");
                    encoder.shiftInOutMode = shiftOutMode;
                }
                else
                    encoder.shiftInOutMode = ISO2022Modes.ModeASCII;

                encoder.m_charsUsed = buffer.CharsUsed;
            }

            // Return our length
            return buffer.Count;
        }
 internal override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS baseEncoder)
 {
     Encoder inEncoder = (Encoder) baseEncoder;
     int bits = 0;
     int bitCount = -1;
     Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(this, inEncoder, bytes, byteCount, chars, charCount);
     if (inEncoder != null)
     {
         bits = inEncoder.bits;
         bitCount = inEncoder.bitCount;
         while (bitCount >= 6)
         {
             bitCount -= 6;
             if (!buffer.AddByte(this.base64Bytes[(bits >> bitCount) & 0x3f]))
             {
                 base.ThrowBytesOverflow(inEncoder, buffer.Count == 0);
             }
         }
     }
     while (buffer.MoreData)
     {
         char nextChar = buffer.GetNextChar();
         if ((nextChar < '\x0080') && this.directEncode[nextChar])
         {
             if (bitCount >= 0)
             {
                 if (bitCount > 0)
                 {
                     if (!buffer.AddByte(this.base64Bytes[(bits << (6 - bitCount)) & 0x3f]))
                     {
                         break;
                     }
                     bitCount = 0;
                 }
                 if (!buffer.AddByte(0x2d))
                 {
                     break;
                 }
                 bitCount = -1;
             }
             if (buffer.AddByte((byte) nextChar))
             {
                 continue;
             }
             break;
         }
         if ((bitCount < 0) && (nextChar == '+'))
         {
             if (buffer.AddByte(0x2b, (byte) 0x2d))
             {
                 continue;
             }
             break;
         }
         if (bitCount < 0)
         {
             if (!buffer.AddByte(0x2b))
             {
                 break;
             }
             bitCount = 0;
         }
         bits = (bits << 0x10) | nextChar;
         bitCount += 0x10;
         while (bitCount >= 6)
         {
             bitCount -= 6;
             if (!buffer.AddByte(this.base64Bytes[(bits >> bitCount) & 0x3f]))
             {
                 bitCount += 6;
                 nextChar = buffer.GetNextChar();
                 break;
             }
         }
         if (bitCount >= 6)
         {
             break;
         }
     }
     if ((bitCount >= 0) && ((inEncoder == null) || inEncoder.MustFlush))
     {
         if ((bitCount > 0) && buffer.AddByte(this.base64Bytes[(bits << (6 - bitCount)) & 0x3f]))
         {
             bitCount = 0;
         }
         if (buffer.AddByte(0x2d))
         {
             bits = 0;
             bitCount = -1;
         }
         else
         {
             buffer.GetNextChar();
         }
     }
     if ((bytes != null) && (inEncoder != null))
     {
         inEncoder.bits = bits;
         inEncoder.bitCount = bitCount;
         inEncoder.m_charsUsed = buffer.CharsUsed;
     }
     return buffer.Count;
 }
 internal override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS baseEncoder)
 {
     ISCIIEncoder inEncoder = (ISCIIEncoder) baseEncoder;
     Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(this, inEncoder, bytes, byteCount, chars, charCount);
     int defaultCodePage = this.defaultCodePage;
     bool bLastVirama = false;
     if (inEncoder != null)
     {
         defaultCodePage = inEncoder.currentCodePage;
         bLastVirama = inEncoder.bLastVirama;
         if (inEncoder.charLeftOver > '\0')
         {
             buffer.Fallback(inEncoder.charLeftOver);
             bLastVirama = false;
         }
     }
     while (buffer.MoreData)
     {
         char nextChar = buffer.GetNextChar();
         if (nextChar < '\x00a0')
         {
             if (!buffer.AddByte((byte) nextChar))
             {
                 break;
             }
             bLastVirama = false;
             continue;
         }
         if ((nextChar < 'ँ') || (nextChar > '൯'))
         {
             if (bLastVirama && ((nextChar == '‌') || (nextChar == '‍')))
             {
                 if (nextChar == '‌')
                 {
                     if (!buffer.AddByte(0xe8))
                     {
                         break;
                     }
                 }
                 else if (!buffer.AddByte(0xe9))
                 {
                     break;
                 }
                 bLastVirama = false;
                 continue;
             }
             buffer.Fallback(nextChar);
             bLastVirama = false;
             continue;
         }
         int num2 = UnicodeToIndicChar[nextChar - 'ँ'];
         byte b = (byte) num2;
         int num4 = 15 & (num2 >> 8);
         int num5 = 0xf000 & num2;
         if (num2 == 0)
         {
             buffer.Fallback(nextChar);
             bLastVirama = false;
         }
         else
         {
             if (num4 != defaultCodePage)
             {
                 if (!buffer.AddByte(0xef, (byte) (num4 | 0x40)))
                 {
                     break;
                 }
                 defaultCodePage = num4;
             }
             if (!buffer.AddByte(b, (num5 != 0) ? 1 : 0))
             {
                 break;
             }
             bLastVirama = b == 0xe8;
             if ((num5 != 0) && !buffer.AddByte(SecondIndicByte[num5 >> 12]))
             {
                 break;
             }
         }
     }
     if ((defaultCodePage != this.defaultCodePage) && ((inEncoder == null) || inEncoder.MustFlush))
     {
         if (buffer.AddByte(0xef, (byte) (this.defaultCodePage | 0x40)))
         {
             defaultCodePage = this.defaultCodePage;
         }
         else
         {
             buffer.GetNextChar();
         }
         bLastVirama = false;
     }
     if ((inEncoder != null) && (bytes != null))
     {
         if (!buffer.fallbackBuffer.bUsedEncoder)
         {
             inEncoder.charLeftOver = '\0';
         }
         inEncoder.currentCodePage = defaultCodePage;
         inEncoder.bLastVirama = bLastVirama;
         inEncoder.m_charsUsed = buffer.CharsUsed;
     }
     return buffer.Count;
 }
        internal override unsafe int GetBytes(char* chars, int charCount,
                                                byte* bytes, int byteCount, EncoderNLS encoder)
        {
            // Just need to ASSERT, this is called by something else internal that checked parameters already
            // We'll allow null bytes as a count
//            BCLDebug.Assert(bytes != null, "[GB18030Encoding.GetBytes]bytes is null");
            BCLDebug.Assert(byteCount >= 0, "[GB18030Encoding.GetBytes]byteCount is negative");
            BCLDebug.Assert(chars != null, "[GB18030Encoding.GetBytes]chars is null");
            BCLDebug.Assert(charCount >= 0, "[GB18030Encoding.GetBytes]charCount is negative");

            // Assert because we shouldn't be able to have a null encoder.
            BCLDebug.Assert(encoderFallback != null, "[GB18030Encoding.GetBytes]Attempting to use null encoder fallback");

            // Get any left over characters
            char charLeftOver = (char)0;
            if (encoder != null)
                charLeftOver = encoder.charLeftOver;

            // prepare our helpers
            Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(
                this, encoder, bytes, byteCount, chars, charCount);

            // Try again if we were MustFlush
            TryAgain:

            // Go ahead and do it, including the fallback.
            while (buffer.MoreData)
            {
                // Get next char
                char ch = buffer.GetNextChar();

                // Have to check for charLeftOver
                if (charLeftOver != 0)
                {
                    BCLDebug.Assert(Char.IsHighSurrogate(charLeftOver),
                        "[GB18030Encoding.GetBytes] leftover character should be high surrogate, not 0x" + ((int)charLeftOver).ToString("X4", CultureInfo.InvariantCulture));

                    // If our next char isn't a low surrogate, then we need to do fallback.
                    if (!Char.IsLowSurrogate(ch))
                    {
                        // No low surrogate, fallback high surrogate & try this one again
                        buffer.MovePrevious(false);                  // (Ignoring this character, don't thow)
                        if (!buffer.Fallback(charLeftOver))
                        {
                            charLeftOver = (char)0;
                            break;
                        }
                        charLeftOver = (char)0;
                        continue;
                    }
                    else
                    {
                        // Next is a surrogate, add it as surrogate pair

                        // Need 4 bytes for surrogates
                        // Get our offset
                        int offset = ((charLeftOver - 0xd800) << 10) + (ch - 0xdc00);

                        byte byte4 = (byte)((offset % 0x0a) + 0x30);
                        offset /= 0x0a;
                        byte byte3 = (byte)((offset % 0x7e) + 0x81);
                        offset /= 0x7e;
                        byte byte2 = (byte)((offset % 0x0a) + 0x30);
                        offset /= 0x0a;
                        BCLDebug.Assert(offset < 0x6f,
                            "[GB18030Encoding.GetBytes](1) Expected offset < 0x6f, not 0x" + offset.ToString("X2", CultureInfo.InvariantCulture));

                        charLeftOver = (char)0;
                        if (!buffer.AddByte((byte)(offset + 0x90),byte2,byte3,byte4))
                        {
                            buffer.MovePrevious(false);             // (don't throw)
                            break;
                        }
                    }
                    charLeftOver = '\0';
                }
                // ASCII's easiest
                else if (ch <= 0x7f)
                {
                    // Need a byte
                    if (!buffer.AddByte((byte)ch))
                        break;
                }
                // See if its a surrogate pair
                else if (Char.IsHighSurrogate(ch))
                {
                    // Remember it for next time
                    charLeftOver = ch;
                }
                else if (Char.IsLowSurrogate(ch))
                {
                    // Low surrogates should've been found already
                    if (!buffer.Fallback(ch))
                        break;
                }
                else
                {
                    // Not surrogate or ASCII, get value
                    ushort iBytes = mapUnicodeToBytes[ch];

                    // See what kind it is
                    if (Is4Byte(ch))
                    {
                        //
                        // This Unicode character will be converted to four-byte GB18030.
                        //
                        // Need 4 bytes
                        byte byte4 = (byte)((iBytes % 0x0a) + 0x30);
                        iBytes /= 0x0a;
                        byte byte3 = (byte)((iBytes % 0x7e) + 0x81);
                        iBytes /= 0x7e;
                        byte byte2 = (byte)((iBytes % 0x0a) + 0x30);
                        iBytes /= 0x0a;
                        BCLDebug.Assert(iBytes < 0x7e,
                            "[GB18030Encoding.GetBytes]Expected iBytes < 0x7e, not 0x" + iBytes.ToString("X2", CultureInfo.InvariantCulture));
                        if (!buffer.AddByte((byte)(iBytes + 0x81), byte2, byte3, byte4))
                            break;
                    }
                    else
                    {
                        // Its 2 byte, use it
                        if (!buffer.AddByte(unchecked((byte)(iBytes >> 8)), unchecked((byte)(iBytes & 0xff))))
                            break;
                    }
                }
            }

            // Do we need to flush our charLeftOver?
            if ((encoder == null || encoder.MustFlush) && (charLeftOver > 0))
            {
                // Fall it back
                buffer.Fallback(charLeftOver);
                charLeftOver = (char)0;
                goto TryAgain;
            }

            // Fallback stuck it in encoder if necessary, but we have to clear MustFlash cases
            // (Check bytes != null, don't clear it if we're just counting)
            if (encoder != null)
            {
                // Remember our charLeftOver
                if (bytes != null)
                    encoder.charLeftOver = charLeftOver;

                encoder.m_charsUsed = buffer.CharsUsed;
            }

            // Return our length
            return buffer.Count;
        }
 private unsafe int GetBytesCP52936(char* chars, int charCount, byte* bytes, int byteCount, ISO2022Encoder encoder)
 {
     Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(this, encoder, bytes, byteCount, chars, charCount);
     ISO2022Modes modeASCII = ISO2022Modes.ModeASCII;
     if (encoder != null)
     {
         char charLeftOver = encoder.charLeftOver;
         modeASCII = encoder.currentMode;
         if (charLeftOver > '\0')
         {
             buffer.Fallback(charLeftOver);
         }
     }
     while (buffer.MoreData)
     {
         char nextChar = buffer.GetNextChar();
         ushort num = base.mapUnicodeToBytes[nextChar];
         if ((num == 0) && (nextChar != '\0'))
         {
             buffer.Fallback(nextChar);
         }
         else
         {
             byte num2 = (byte) (num >> 8);
             byte num3 = (byte) (num & 0xff);
             if (((num2 != 0) && (((num2 < 0xa1) || (num2 > 0xf7)) || ((num3 < 0xa1) || (num3 > 0xfe)))) || (((num2 == 0) && (num3 > 0x80)) && (num3 != 0xff)))
             {
                 buffer.Fallback(nextChar);
                 continue;
             }
             if (num2 != 0)
             {
                 if (modeASCII != ISO2022Modes.ModeHZ)
                 {
                     if (!buffer.AddByte(0x7e, 0x7b, 2))
                     {
                         break;
                     }
                     modeASCII = ISO2022Modes.ModeHZ;
                 }
                 if (buffer.AddByte((byte) (num2 & 0x7f), (byte) (num3 & 0x7f)))
                 {
                     continue;
                 }
                 break;
             }
             if (modeASCII != ISO2022Modes.ModeASCII)
             {
                 if (!buffer.AddByte(0x7e, 0x7d, (num3 == 0x7e) ? 2 : 1))
                 {
                     break;
                 }
                 modeASCII = ISO2022Modes.ModeASCII;
             }
             if (((num3 == 0x7e) && !buffer.AddByte(0x7e, 1)) || !buffer.AddByte(num3))
             {
                 break;
             }
         }
     }
     if ((modeASCII != ISO2022Modes.ModeASCII) && ((encoder == null) || encoder.MustFlush))
     {
         if (buffer.AddByte(0x7e, (byte) 0x7d))
         {
             modeASCII = ISO2022Modes.ModeASCII;
         }
         else
         {
             buffer.GetNextChar();
         }
     }
     if ((encoder != null) && (bytes != null))
     {
         encoder.currentMode = modeASCII;
         if (!buffer.fallbackBuffer.bUsedEncoder)
         {
             encoder.charLeftOver = '\0';
         }
         encoder.m_charsUsed = buffer.CharsUsed;
     }
     return buffer.Count;
 }
 private unsafe int GetBytesCP5022xJP(char* chars, int charCount, byte* bytes, int byteCount, ISO2022Encoder encoder)
 {
     Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(this, encoder, bytes, byteCount, chars, charCount);
     ISO2022Modes modeASCII = ISO2022Modes.ModeASCII;
     ISO2022Modes shiftInOutMode = ISO2022Modes.ModeASCII;
     if (encoder != null)
     {
         char charLeftOver = encoder.charLeftOver;
         modeASCII = encoder.currentMode;
         shiftInOutMode = encoder.shiftInOutMode;
         if (charLeftOver > '\0')
         {
             buffer.Fallback(charLeftOver);
         }
     }
     while (buffer.MoreData)
     {
         byte num2;
         byte num3;
         char nextChar = buffer.GetNextChar();
         ushort num = base.mapUnicodeToBytes[nextChar];
         while (true)
         {
             num2 = (byte) (num >> 8);
             num3 = (byte) (num & 0xff);
             if (num2 != 0x10)
             {
                 goto Label_010A;
             }
             if (this.CodePage != 0xc42c)
             {
                 break;
             }
             if ((num3 < 0x21) || (num3 >= (0x21 + HalfToFullWidthKanaTable.Length)))
             {
                 buffer.Fallback(nextChar);
                 continue;
             }
             num = (ushort) (HalfToFullWidthKanaTable[num3 - 0x21] & 0x7f7f);
         }
         if (modeASCII != ISO2022Modes.ModeHalfwidthKatakana)
         {
             if (this.CodePage == 0xc42e)
             {
                 if (!buffer.AddByte(14))
                 {
                     break;
                 }
                 shiftInOutMode = modeASCII;
                 modeASCII = ISO2022Modes.ModeHalfwidthKatakana;
             }
             else
             {
                 if (!buffer.AddByte(0x1b, 40, (byte) 0x49))
                 {
                     break;
                 }
                 modeASCII = ISO2022Modes.ModeHalfwidthKatakana;
             }
         }
         if (buffer.AddByte((byte) (num3 & 0x7f)))
         {
             continue;
         }
         break;
     Label_010A:
         if (num2 != 0)
         {
             if ((this.CodePage == 0xc42e) && (modeASCII == ISO2022Modes.ModeHalfwidthKatakana))
             {
                 if (!buffer.AddByte(15))
                 {
                     break;
                 }
                 modeASCII = shiftInOutMode;
             }
             if (modeASCII != ISO2022Modes.ModeJIS0208)
             {
                 if (!buffer.AddByte(0x1b, 0x24, (byte) 0x42))
                 {
                     break;
                 }
                 modeASCII = ISO2022Modes.ModeJIS0208;
             }
             if (buffer.AddByte(num2, num3))
             {
                 continue;
             }
             break;
         }
         if ((num != 0) || (nextChar == '\0'))
         {
             if ((this.CodePage == 0xc42e) && (modeASCII == ISO2022Modes.ModeHalfwidthKatakana))
             {
                 if (!buffer.AddByte(15))
                 {
                     break;
                 }
                 modeASCII = shiftInOutMode;
             }
             if (modeASCII != ISO2022Modes.ModeASCII)
             {
                 if (!buffer.AddByte(0x1b, 40, (byte) 0x42))
                 {
                     break;
                 }
                 modeASCII = ISO2022Modes.ModeASCII;
             }
             if (buffer.AddByte(num3))
             {
                 continue;
             }
             break;
         }
         buffer.Fallback(nextChar);
     }
     if ((modeASCII != ISO2022Modes.ModeASCII) && ((encoder == null) || encoder.MustFlush))
     {
         if ((this.CodePage == 0xc42e) && (modeASCII == ISO2022Modes.ModeHalfwidthKatakana))
         {
             if (buffer.AddByte(15))
             {
                 modeASCII = shiftInOutMode;
             }
             else
             {
                 buffer.GetNextChar();
             }
         }
         if ((modeASCII != ISO2022Modes.ModeASCII) && ((this.CodePage != 0xc42e) || (modeASCII != ISO2022Modes.ModeHalfwidthKatakana)))
         {
             if (buffer.AddByte(0x1b, 40, (byte) 0x42))
             {
                 modeASCII = ISO2022Modes.ModeASCII;
             }
             else
             {
                 buffer.GetNextChar();
             }
         }
     }
     if ((bytes != null) && (encoder != null))
     {
         encoder.currentMode = modeASCII;
         encoder.shiftInOutMode = shiftInOutMode;
         if (!buffer.fallbackBuffer.bUsedEncoder)
         {
             encoder.charLeftOver = '\0';
         }
         encoder.m_charsUsed = buffer.CharsUsed;
     }
     return buffer.Count;
 }
 private unsafe int GetBytesCP50225KR(char* chars, int charCount, byte* bytes, int byteCount, ISO2022Encoder encoder)
 {
     Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(this, encoder, bytes, byteCount, chars, charCount);
     ISO2022Modes modeASCII = ISO2022Modes.ModeASCII;
     ISO2022Modes shiftInOutMode = ISO2022Modes.ModeASCII;
     if (encoder != null)
     {
         char charLeftOver = encoder.charLeftOver;
         modeASCII = encoder.currentMode;
         shiftInOutMode = encoder.shiftInOutMode;
         if (charLeftOver > '\0')
         {
             buffer.Fallback(charLeftOver);
         }
     }
     while (buffer.MoreData)
     {
         char nextChar = buffer.GetNextChar();
         ushort num = base.mapUnicodeToBytes[nextChar];
         byte num2 = (byte) (num >> 8);
         byte num3 = (byte) (num & 0xff);
         if (num2 != 0)
         {
             if (shiftInOutMode != ISO2022Modes.ModeKR)
             {
                 if (!buffer.AddByte(0x1b, 0x24, 0x29, (byte) 0x43))
                 {
                     break;
                 }
                 shiftInOutMode = ISO2022Modes.ModeKR;
             }
             if (modeASCII != ISO2022Modes.ModeKR)
             {
                 if (!buffer.AddByte(14))
                 {
                     break;
                 }
                 modeASCII = ISO2022Modes.ModeKR;
             }
             if (buffer.AddByte(num2, num3))
             {
                 continue;
             }
             break;
         }
         if ((num != 0) || (nextChar == '\0'))
         {
             if (modeASCII != ISO2022Modes.ModeASCII)
             {
                 if (!buffer.AddByte(15))
                 {
                     break;
                 }
                 modeASCII = ISO2022Modes.ModeASCII;
             }
             if (buffer.AddByte(num3))
             {
                 continue;
             }
             break;
         }
         buffer.Fallback(nextChar);
     }
     if ((modeASCII != ISO2022Modes.ModeASCII) && ((encoder == null) || encoder.MustFlush))
     {
         if (buffer.AddByte(15))
         {
             modeASCII = ISO2022Modes.ModeASCII;
         }
         else
         {
             buffer.GetNextChar();
         }
     }
     if ((bytes != null) && (encoder != null))
     {
         if (!buffer.fallbackBuffer.bUsedEncoder)
         {
             encoder.charLeftOver = '\0';
         }
         encoder.currentMode = modeASCII;
         if (!encoder.MustFlush || (encoder.charLeftOver != '\0'))
         {
             encoder.shiftInOutMode = shiftInOutMode;
         }
         else
         {
             encoder.shiftInOutMode = ISO2022Modes.ModeASCII;
         }
         encoder.m_charsUsed = buffer.CharsUsed;
     }
     return buffer.Count;
 }
 internal override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS encoder)
 {
     char charFallback = '\0';
     if (encoder != null)
     {
         charFallback = encoder.charLeftOver;
     }
     Encoding.EncodingByteBuffer buffer = new Encoding.EncodingByteBuffer(this, encoder, bytes, byteCount, chars, charCount);
 Label_0183:
     while (buffer.MoreData)
     {
         char nextChar = buffer.GetNextChar();
         if (charFallback != '\0')
         {
             if (!char.IsLowSurrogate(nextChar))
             {
                 buffer.MovePrevious(false);
                 if (!buffer.Fallback(charFallback))
                 {
                     charFallback = '\0';
                     break;
                 }
                 charFallback = '\0';
             }
             else
             {
                 int num = ((charFallback - 0xd800) << 10) + (nextChar - 0xdc00);
                 byte num2 = (byte) ((num % 10) + 0x30);
                 num /= 10;
                 byte num3 = (byte) ((num % 0x7e) + 0x81);
                 num /= 0x7e;
                 byte num4 = (byte) ((num % 10) + 0x30);
                 num /= 10;
                 charFallback = '\0';
                 if (!buffer.AddByte((byte) (num + 0x90), num4, num3, num2))
                 {
                     buffer.MovePrevious(false);
                     break;
                 }
                 charFallback = '\0';
             }
         }
         else
         {
             if (nextChar <= '\x007f')
             {
                 if (buffer.AddByte((byte) nextChar))
                 {
                     continue;
                 }
                 break;
             }
             if (char.IsHighSurrogate(nextChar))
             {
                 charFallback = nextChar;
             }
             else
             {
                 if (char.IsLowSurrogate(nextChar))
                 {
                     if (buffer.Fallback(nextChar))
                     {
                         continue;
                     }
                     break;
                 }
                 ushort num5 = base.mapUnicodeToBytes[nextChar];
                 if (this.Is4Byte(nextChar))
                 {
                     byte num6 = (byte) ((num5 % 10) + 0x30);
                     num5 = (ushort) (num5 / 10);
                     byte num7 = (byte) ((num5 % 0x7e) + 0x81);
                     num5 = (ushort) (num5 / 0x7e);
                     byte num8 = (byte) ((num5 % 10) + 0x30);
                     num5 = (ushort) (num5 / 10);
                     if (buffer.AddByte((byte) (num5 + 0x81), num8, num7, num6))
                     {
                         continue;
                     }
                     break;
                 }
                 if (!buffer.AddByte((byte) (num5 >> 8), (byte) (num5 & 0xff)))
                 {
                     break;
                 }
             }
         }
     }
     if (((encoder == null) || encoder.MustFlush) && (charFallback > '\0'))
     {
         buffer.Fallback(charFallback);
         charFallback = '\0';
         goto Label_0183;
     }
     if (encoder != null)
     {
         if (bytes != null)
         {
             encoder.charLeftOver = charFallback;
         }
         encoder.m_charsUsed = buffer.CharsUsed;
     }
     return buffer.Count;
 }