/// <summary>
 /// Resets the decoder.
 /// </summary>
 /// <remarks>
 /// Resets the state of the decoder.
 /// </remarks>
 public void Reset()
 {
     state = QpDecoderState.PassThrough;
     saved = 0;
 }
        /// <summary>
        /// Decodes the specified input into the output buffer.
        /// </summary>
        /// <remarks>
        /// <para>Decodes the specified input into the output buffer.</para>
        /// <para>The output buffer should be large enough to hold all of the
        /// decoded input. For estimating the size needed for the output buffer,
        /// see <see cref="EstimateOutputLength"/>.</para>
        /// </remarks>
        /// <returns>The number of bytes written to the output buffer.</returns>
        /// <param name="input">A pointer to the beginning of the input buffer.</param>
        /// <param name="length">The length of the input buffer.</param>
        /// <param name="output">A pointer to the beginning of the output buffer.</param>
        public unsafe int Decode(byte *input, int length, byte *output)
        {
            byte *inend  = input + length;
            byte *outptr = output;
            byte *inptr  = input;
            byte  c;

            while (inptr < inend)
            {
                switch (state)
                {
                case QpDecoderState.PassThrough:
                    while (inptr < inend)
                    {
                        c = *inptr++;

                        if (c == '=')
                        {
                            state = QpDecoderState.EqualSign;
                            break;
                        }
                        else if (rfc2047 && c == '_')
                        {
                            *outptr++ = (byte)' ';
                        }
                        else
                        {
                            *outptr++ = c;
                        }
                    }
                    break;

                case QpDecoderState.EqualSign:
                    c = *inptr++;
                    if (c == '\n')
                    {
                        // this is a soft break ("=\n")
                        state = QpDecoderState.PassThrough;
                    }
                    else
                    {
                        state = QpDecoderState.DecodeByte;
                        saved = c;
                    }
                    break;

                case QpDecoderState.DecodeByte:
                    c = *inptr++;
                    if (c.IsXDigit() && saved.IsXDigit())
                    {
                        saved = saved.ToXDigit();
                        c     = c.ToXDigit();

                        *outptr++ = (byte)((saved << 4) | c);
                    }
                    else if (saved == '\r' && c == '\n')
                    {
                        // end-of-line
                    }
                    else
                    {
                        // invalid encoded sequence - pass it through undecoded
                        *outptr++ = (byte)'=';
                        *outptr++ = saved;
                        *outptr++ = c;
                    }

                    state = QpDecoderState.PassThrough;
                    break;
                }
            }

            return((int)(outptr - output));
        }
示例#3
0
        /// <summary>
        /// Decodes the specified input into the output buffer.
        /// </summary>
        /// <returns>The number of bytes written to the output buffer.</returns>
        /// <param name='input'>A pointer to the beginning of the input buffer.</param>
        /// <param name='length'>The length of the input buffer.</param>
        /// <param name='output'>A pointer to the beginning of the output buffer.</param>
        public unsafe int Decode(byte* input, int length, byte* output)
        {
            byte* inend = input + length;
            byte* outptr = output;
            byte* inptr = input;
            byte c;

            while (inptr < inend) {
                switch (state) {
                case QpDecoderState.PassThrough:
                    while (inptr < inend) {
                        c = *inptr++;

                        if (c == '=') {
                            state = QpDecoderState.EqualSign;
                            break;
                        } else if (rfc2047 && c == '_') {
                            *outptr++ = (byte) ' ';
                        } else {
                            *outptr++ = c;
                        }
                    }
                    break;
                case QpDecoderState.EqualSign:
                    c = *inptr++;
                    if (c == '\n') {
                        // this is a soft break ("=\n")
                        state = QpDecoderState.PassThrough;
                    } else {
                        state = QpDecoderState.DecodeByte;
                        saved = c;
                    }
                    break;
                case QpDecoderState.DecodeByte:
                    c = *inptr++;
                    if (c.IsXDigit () && saved.IsXDigit ()) {
                        saved = saved.ToXDigit ();
                        c = c.ToXDigit ();

                        *outptr++ = (byte) ((saved << 4) | c);
                    } else if (saved == '\r' && c == '\n') {
                        // end-of-line
                    } else {
                        // invalid encoded sequence - pass it through undecoded
                        *outptr++ = (byte) '=';
                        *outptr++ = saved;
                        *outptr++ = c;
                    }

                    state = QpDecoderState.PassThrough;
                    break;
                }
            }

            return (int) (outptr - output);
        }
示例#4
0
 /// <summary>
 /// Resets the decoder.
 /// </summary>
 public void Reset()
 {
     state = QpDecoderState.PassThrough;
     saved = 0;
 }
示例#5
0
        /// <summary>
        /// Decodes the specified input into the output buffer.
        /// </summary>
        /// <remarks>
        /// <para>Decodes the specified input into the output buffer.</para>
        /// <para>The output buffer should be large enough to hold all of the
        /// decoded input. For estimating the size needed for the output buffer,
        /// see <see cref="M:MimeKit.Encodings.QuotedPrintableDecoder.EstimateOutputLength(System.Int32)" />.</para>
        /// </remarks>
        /// <returns>The number of bytes written to the output buffer.</returns>
        /// <param name="input">A pointer to the beginning of the input buffer.</param>
        /// <param name="length">The length of the input buffer.</param>
        /// <param name="output">A pointer to the beginning of the output buffer.</param>
        public unsafe int Decode(byte *input, int length, byte *output)
        {
            byte *ptr  = input + length;
            byte *ptr2 = output;
            byte *ptr3 = input;

            while (ptr3 < ptr)
            {
                switch (state)
                {
                case QpDecoderState.PassThrough:
                    while (ptr3 < ptr)
                    {
                        byte *intPtr6 = ptr3;
                        ptr3 = intPtr6 + 1;
                        byte b = *intPtr6;
                        if (b == 61)
                        {
                            state = QpDecoderState.EqualSign;
                            break;
                        }
                        if (rfc2047 && b == 95)
                        {
                            byte *intPtr7 = ptr2;
                            ptr2 = intPtr7 + 1;
                            *intPtr7 = 32;
                        }
                        else
                        {
                            byte *intPtr8 = ptr2;
                            ptr2 = intPtr8 + 1;
                            *intPtr8 = b;
                        }
                    }
                    break;

                case QpDecoderState.EqualSign:
                {
                    byte *intPtr9 = ptr3;
                    ptr3 = intPtr9 + 1;
                    byte b = *intPtr9;
                    if (b.IsXDigit())
                    {
                        state = QpDecoderState.DecodeByte;
                        saved = b;
                        break;
                    }
                    switch (b)
                    {
                    case 61:
                    {
                        byte *intPtr12 = ptr2;
                        ptr2 = intPtr12 + 1;
                        *intPtr12 = 61;
                        break;
                    }

                    case 13:
                        state = QpDecoderState.SoftBreak;
                        break;

                    case 10:
                        state = QpDecoderState.PassThrough;
                        break;

                    default:
                    {
                        state = QpDecoderState.PassThrough;
                        byte *intPtr10 = ptr2;
                        ptr2 = intPtr10 + 1;
                        *     intPtr10 = 61;
                        byte *intPtr11 = ptr2;
                        ptr2 = intPtr11 + 1;
                        *intPtr11 = b;
                        break;
                    }
                    }
                    break;
                }

                case QpDecoderState.SoftBreak:
                {
                    state = QpDecoderState.PassThrough;
                    byte *intPtr13 = ptr3;
                    ptr3 = intPtr13 + 1;
                    byte b = *intPtr13;
                    if (b != 10)
                    {
                        byte *intPtr14 = ptr2;
                        ptr2 = intPtr14 + 1;
                        *     intPtr14 = 61;
                        byte *intPtr15 = ptr2;
                        ptr2 = intPtr15 + 1;
                        *     intPtr15 = 13;
                        byte *intPtr16 = ptr2;
                        ptr2 = intPtr16 + 1;
                        *intPtr16 = b;
                    }
                    break;
                }

                case QpDecoderState.DecodeByte:
                {
                    byte *intPtr = ptr3;
                    ptr3 = intPtr + 1;
                    byte b = *intPtr;
                    if (b.IsXDigit())
                    {
                        saved = saved.ToXDigit();
                        b     = b.ToXDigit();
                        byte *intPtr2 = ptr2;
                        ptr2 = intPtr2 + 1;
                        *intPtr2 = (byte)((saved << 4) | b);
                    }
                    else
                    {
                        byte *intPtr3 = ptr2;
                        ptr2 = intPtr3 + 1;
                        *     intPtr3 = 61;
                        byte *intPtr4 = ptr2;
                        ptr2 = intPtr4 + 1;
                        *     intPtr4 = saved;
                        byte *intPtr5 = ptr2;
                        ptr2 = intPtr5 + 1;
                        *intPtr5 = b;
                    }
                    state = QpDecoderState.PassThrough;
                    break;
                }
                }
            }
            return((int)(ptr2 - output));
        }