System.Text.ISO2022Encoding.GetBytesCP50225KR C# (CSharp) Method

GetBytesCP50225KR() private method

private GetBytesCP50225KR ( char chars, int charCount, byte bytes, int byteCount, ISO2022Encoder encoder ) : int
chars char
charCount int
bytes byte
byteCount int
encoder ISO2022Encoder
return int
        private unsafe int GetBytesCP50225KR(char* chars, int charCount,
                                                    byte* bytes, int byteCount, ISO2022Encoder encoder)
        {
            // prepare our helpers
            EncodingByteBuffer buffer = new 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)
                {
                    Debug.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.fallbackBufferHelper.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
                    Debug.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;
        }