/// <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)); }
/// <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); }
/// <summary> /// Resets the decoder. /// </summary> 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="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)); }