QEncoder

Namespace: MimeKit
We found 10 examples in language CSharp for this search. You will see 50 fragments of code.

Other methods


		/// <summary>
		/// Clone the <see cref="QEncoder"/> with its current state.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="QEncoder"/> with exactly the same state as the current encoder.
		/// </remarks>
		/// <returns>A new <see cref="QEncoder"/> with identical state.</returns>
		public IMimeEncoder Clone ()
		{
			return new QEncoder (mask == CharType.IsEncodedPhraseSafe ? QEncodeMode.Phrase : QEncodeMode.Text);
		}


		/// <summary>
		/// Clone the <see cref="QEncoder"/> with its current state.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="QEncoder"/> with exactly the same state as the current encoder.
		/// </remarks>
		/// <returns>A new <see cref="QEncoder"/> with identical state.</returns>
		public IMimeEncoder Clone ()
		{
			return new QEncoder (mask == CharType.IsEncodedPhraseSafe ? QEncodeMode.Phrase : QEncodeMode.Text);
		}


        protected override void AppendEncodedCRLF()
        {
            //the encoding for CRLF is =0D=0A
            WriteState.Append((byte)'=', (byte)'0', (byte)'D', (byte)'=', (byte)'0', (byte)'A');
        }

        protected override bool LineBreakNeeded(byte b)
        {
            // Fold if we're before a whitespace and encoding another character would be too long
            int lengthAfterAddingCharAndFooter = WriteState.CurrentLineLength + SizeOfQEncodedChar + WriteState.FooterLength;
            bool isWhitespace = b == ' ' || b == '\t' || b == '\r' || b == '\n';
            if (lengthAfterAddingCharAndFooter >= WriteState.MaxLineLength && isWhitespace)
            {
                return true;
            }

            // Or just adding the footer would be too long.
            int lengthAfterAddingFooter = WriteState.CurrentLineLength + WriteState.FooterLength;
            if (lengthAfterAddingFooter >= WriteState.MaxLineLength)
            {
                return true;
            }

            return false;
        }

        protected override bool LineBreakNeeded(byte[] bytes, int count)
        {
            if (count == 1 || IsCRLF(bytes, count)) // preserve same behavior as in EncodeBytes
            {
                return LineBreakNeeded(bytes[0]);
            }

            int numberOfCharsToAppend = count * SizeOfQEncodedChar;
            return WriteState.CurrentLineLength + numberOfCharsToAppend + _writeState.FooterLength > WriteState.MaxLineLength;
        }

        protected override int GetCodepointSize(string value, int i)
        {
            // specific encoding for CRLF
            if (value[i] == '\r' && i + 1 < value.Length && value[i + 1] == '\n')
            {
                return 2;
            }

            if (IsSurrogatePair(value, i))
            {
                return 2;
            }

            return 1;
        }

        protected override void ApppendEncodedByte(byte b)
        {
            if (b == ' ')
            {
                //spaces should be escaped as either '_' or '=20' and
                //we have chosen '_' for parity with other email client
                //behavior
                WriteState.Append((byte)'_');
            }
            // RFC 2047 Section 5 part 3 also allows for !*+-/ but these arn't required in headers.
            // Conservatively encode anything but letters or digits.
            else if (IsAsciiLetterOrDigit((char)b))
            {
                // Just a regular printable ascii char.
                WriteState.Append(b);
            }
            else
            {
                //append an = to indicate an encoded character
                WriteState.Append((byte)'=');
                //shift 4 to get the first four bytes only and look up the hex digit
                WriteState.Append((byte)HexConverter.ToCharUpper(b >> 4));
                //clear the first four bytes to get the last four and look up the hex digit
                WriteState.Append((byte)HexConverter.ToCharUpper(b));
            }
        }

        private static bool IsAsciiLetterOrDigit(char character) =>
            IsAsciiLetter(character) || (character >= '0' && character <= '9');


		/// <summary>
		/// Clone the <see cref="QEncoder"/> with its current state.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="QEncoder"/> with exactly the same state as the current encoder.
		/// </remarks>
		/// <returns>A new <see cref="QEncoder"/> with identical state.</returns>
		public IMimeEncoder Clone ()
		{
			return new QEncoder (mask == CharType.IsEncodedPhraseSafe ? QEncodeMode.Phrase : QEncodeMode.Text);
		}

		/// <summary>
		/// Estimates the length of the output.
		/// </summary>
		/// <remarks>
		/// Estimates the number of bytes needed to encode the specified number of input bytes.
		/// </remarks>
		/// <returns>The estimated output length.</returns>
		/// <param name="inputLength">The input length.</param>
		public int EstimateOutputLength (int inputLength)
		{
			return inputLength * 3;
		}

		void ValidateArguments (byte[] input, int startIndex, int length, byte[] output)
		{
			if (input == null)
				throw new ArgumentNullException ("input");

			if (startIndex < 0 || startIndex > input.Length)
				throw new ArgumentOutOfRangeException ("startIndex");

			if (length < 0 || length > (input.Length - startIndex))
				throw new ArgumentOutOfRangeException ("length");

			if (output == null)
				throw new ArgumentNullException ("output");

			if (output.Length < EstimateOutputLength (length))
				throw new ArgumentException ("The output buffer is not large enough to contain the encoded input.", "output");
		}

		unsafe int Encode (byte* input, int length, byte* output)
		{
			if (length == 0)
				return 0;

			byte* inend = input + length;
			byte* outptr = output;
			byte* inptr = input;

			while (inptr < inend) {
				byte c = *inptr++;

				if (c == ' ') {
					*outptr++ = (byte) '_';
				} else if (c != '_' && c.IsType (mask)) {
					*outptr++ = c;
				} else {
					*outptr++ = (byte) '=';
					*outptr++ = hex_alphabet[(c >> 4) & 0x0f];
					*outptr++ = hex_alphabet[c & 0x0f];
				}
			}

			return (int) (outptr - output);
		}

		/// <summary>
		/// Encodes the specified input into the output buffer.
		/// </summary>
		/// <remarks>
		/// <para>Encodes the specified input into the output buffer.</para>
		/// <para>The output buffer should be large enough to hold all of the
		/// encoded 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">The input buffer.</param>
		/// <param name="startIndex">The starting index of the input buffer.</param>
		/// <param name="length">The length of the input buffer.</param>
		/// <param name="output">The output buffer.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="input"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="output"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="startIndex"/> and <paramref name="length"/> do not specify
		/// a valid range in the <paramref name="input"/> byte array.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="output"/> is not large enough to contain the encoded content.</para>
		/// <para>Use the <see cref="EstimateOutputLength"/> method to properly determine the 
		/// necessary length of the <paramref name="output"/> byte array.</para>
		/// </exception>
		public int Encode (byte[] input, int startIndex, int length, byte[] output)
		{
			ValidateArguments (input, startIndex, length, output);

			unsafe {
				fixed (byte* inptr = input, outptr = output) {
					return Encode (inptr + startIndex, length, outptr);
				}
			}
		}

		unsafe int Flush (byte* input, int length, byte* output)
		{
			byte* outptr = output;

			if (length > 0)
				outptr += Encode (input, length, output);

			Reset ();

			return (int) (outptr - output);
		}


        protected override void AppendEncodedCRLF()
        {
            //the encoding for CRLF is =0D=0A
            WriteState.Append((byte)'=', (byte)'0', (byte)'D', (byte)'=', (byte)'0', (byte)'A');
        }

        protected override bool LineBreakNeeded(byte b)
        {
            // Fold if we're before a whitespace and encoding another character would be too long
            int lengthAfterAddingCharAndFooter = WriteState.CurrentLineLength + SizeOfQEncodedChar + WriteState.FooterLength;
            bool isWhitespace = b == ' ' || b == '\t' || b == '\r' || b == '\n';
            if (lengthAfterAddingCharAndFooter >= WriteState.MaxLineLength && isWhitespace)
            {
                return true;
            }

            // Or just adding the footer would be too long.
            int lengthAfterAddingFooter = WriteState.CurrentLineLength + WriteState.FooterLength;
            if (lengthAfterAddingFooter >= WriteState.MaxLineLength)
            {
                return true;
            }

            return false;
        }

        protected override bool LineBreakNeeded(byte[] bytes, int count)
        {
            if (count == 1 || IsCRLF(bytes, count)) // preserve same behavior as in EncodeBytes
            {
                return LineBreakNeeded(bytes[0]);
            }

            int numberOfCharsToAppend = count * SizeOfQEncodedChar;
            return WriteState.CurrentLineLength + numberOfCharsToAppend + _writeState.FooterLength > WriteState.MaxLineLength;
        }

        protected override int GetCodepointSize(string value, int i)
        {
            // specific encoding for CRLF
            if (value[i] == '\r' && i + 1 < value.Length && value[i + 1] == '\n')
            {
                return 2;
            }

            if (IsSurrogatePair(value, i))
            {
                return 2;
            }

            return 1;
        }

        protected override void ApppendEncodedByte(byte b)
        {
            if (b == ' ')
            {
                //spaces should be escaped as either '_' or '=20' and
                //we have chosen '_' for parity with other email client
                //behavior
                WriteState.Append((byte)'_');
            }
            // RFC 2047 Section 5 part 3 also allows for !*+-/ but these arn't required in headers.
            // Conservatively encode anything but letters or digits.
            else if (IsAsciiLetterOrDigit((char)b))
            {
                // Just a regular printable ascii char.
                WriteState.Append(b);
            }
            else
            {
                //append an = to indicate an encoded character
                WriteState.Append((byte)'=');
                //shift 4 to get the first four bytes only and look up the hex digit
                WriteState.Append((byte)HexConverter.ToCharUpper(b >> 4));
                //clear the first four bytes to get the last four and look up the hex digit
                WriteState.Append((byte)HexConverter.ToCharUpper(b));
            }
        }

        private static bool IsAsciiLetterOrDigit(char character) =>
            IsAsciiLetter(character) || (character >= '0' && character <= '9');


        protected override void AppendEncodedCRLF()
        {
            //the encoding for CRLF is =0D=0A
            WriteState.Append((byte)'=', (byte)'0', (byte)'D', (byte)'=', (byte)'0', (byte)'A');
        }

        protected override bool LineBreakNeeded(byte b)
        {
            // Fold if we're before a whitespace and encoding another character would be too long
            int lengthAfterAddingCharAndFooter = WriteState.CurrentLineLength + SizeOfQEncodedChar + WriteState.FooterLength;
            bool isWhitespace = b == ' ' || b == '\t' || b == '\r' || b == '\n';
            if (lengthAfterAddingCharAndFooter >= WriteState.MaxLineLength && isWhitespace)
            {
                return true;
            }

            // Or just adding the footer would be too long.
            int lengthAfterAddingFooter = WriteState.CurrentLineLength + WriteState.FooterLength;
            if (lengthAfterAddingFooter >= WriteState.MaxLineLength)
            {
                return true;
            }

            return false;
        }

        protected override bool LineBreakNeeded(byte[] bytes, int count)
        {
            if (count == 1 || IsCRLF(bytes, count)) // preserve same behavior as in EncodeBytes
            {
                return LineBreakNeeded(bytes[0]);
            }

            int numberOfCharsToAppend = count * SizeOfQEncodedChar;
            return WriteState.CurrentLineLength + numberOfCharsToAppend + _writeState.FooterLength > WriteState.MaxLineLength;
        }

        protected override int GetCodepointSize(string value, int i)
        {
            // specific encoding for CRLF
            if (value[i] == '\r' && i + 1 < value.Length && value[i + 1] == '\n')
            {
                return 2;
            }

            if (IsSurrogatePair(value, i))
            {
                return 2;
            }

            return 1;
        }

        protected override void ApppendEncodedByte(byte b)
        {
            if (b == ' ')
            {
                //spaces should be escaped as either '_' or '=20' and
                //we have chosen '_' for parity with other email client
                //behavior
                WriteState.Append((byte)'_');
            }
            // RFC 2047 Section 5 part 3 also allows for !*+-/ but these arn't required in headers.
            // Conservatively encode anything but letters or digits.
            else if (IsAsciiLetterOrDigit((char)b))
            {
                // Just a regular printable ascii char.
                WriteState.Append(b);
            }
            else
            {
                //append an = to indicate an encoded character
                WriteState.Append((byte)'=');
                //shift 4 to get the first four bytes only and look up the hex digit
                WriteState.Append((byte)HexConverter.ToCharUpper(b >> 4));
                //clear the first four bytes to get the last four and look up the hex digit
                WriteState.Append((byte)HexConverter.ToCharUpper(b));
            }
        }

        private static bool IsAsciiLetterOrDigit(char character) =>
            IsAsciiLetter(character) || (character >= '0' && character <= '9');


		/// <summary>
		/// Clone the <see cref="QEncoder"/> with its current state.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="QEncoder"/> with exactly the same state as the current encoder.
		/// </remarks>
		/// <returns>A new <see cref="QEncoder"/> with identical state.</returns>
		public IMimeEncoder Clone ()
		{
			return new QEncoder (mask == CharType.IsEncodedPhraseSafe ? QEncodeMode.Phrase : QEncodeMode.Text);
		}

		/// <summary>
		/// Estimates the length of the output.
		/// </summary>
		/// <remarks>
		/// Estimates the number of bytes needed to encode the specified number of input bytes.
		/// </remarks>
		/// <returns>The estimated output length.</returns>
		/// <param name="inputLength">The input length.</param>
		public int EstimateOutputLength (int inputLength)
		{
			return inputLength * 3;
		}

		void ValidateArguments (byte[] input, int startIndex, int length, byte[] output)
		{
			if (input == null)
				throw new ArgumentNullException (nameof (input));

			if (startIndex < 0 || startIndex > input.Length)
				throw new ArgumentOutOfRangeException (nameof (startIndex));

			if (length < 0 || length > (input.Length - startIndex))
				throw new ArgumentOutOfRangeException (nameof (length));

			if (output == null)
				throw new ArgumentNullException (nameof (output));

			if (output.Length < EstimateOutputLength (length))
				throw new ArgumentException ("The output buffer is not large enough to contain the encoded input.", nameof (output));
		}

		unsafe int Encode (byte* input, int length, byte* output)
		{
			if (length == 0)
				return 0;

			byte* inend = input + length;
			byte* outptr = output;
			byte* inptr = input;

			while (inptr < inend) {
				byte c = *inptr++;

				if (c == ' ') {
					*outptr++ = (byte) '_';
				} else if (c != '_' && c.IsType (mask)) {
					*outptr++ = c;
				} else {
					*outptr++ = (byte) '=';
					*outptr++ = hex_alphabet[(c >> 4) & 0x0f];
					*outptr++ = hex_alphabet[c & 0x0f];
				}
			}

			return (int) (outptr - output);
		}

		/// <summary>
		/// Encodes the specified input into the output buffer.
		/// </summary>
		/// <remarks>
		/// <para>Encodes the specified input into the output buffer.</para>
		/// <para>The output buffer should be large enough to hold all of the
		/// encoded 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">The input buffer.</param>
		/// <param name="startIndex">The starting index of the input buffer.</param>
		/// <param name="length">The length of the input buffer.</param>
		/// <param name="output">The output buffer.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="input"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="output"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="startIndex"/> and <paramref name="length"/> do not specify
		/// a valid range in the <paramref name="input"/> byte array.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="output"/> is not large enough to contain the encoded content.</para>
		/// <para>Use the <see cref="EstimateOutputLength"/> method to properly determine the 
		/// necessary length of the <paramref name="output"/> byte array.</para>
		/// </exception>
		public int Encode (byte[] input, int startIndex, int length, byte[] output)
		{
			ValidateArguments (input, startIndex, length, output);

			unsafe {
				fixed (byte* inptr = input, outptr = output) {
					return Encode (inptr + startIndex, length, outptr);
				}
			}
		}

		unsafe int Flush (byte* input, int length, byte* output)
		{
			byte* outptr = output;

			if (length > 0)
				outptr += Encode (input, length, output);

			Reset ();

			return (int) (outptr - output);
		}


		/// <summary>
		/// Clone the <see cref="QEncoder"/> with its current state.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="QEncoder"/> with exactly the same state as the current encoder.
		/// </remarks>
		/// <returns>A new <see cref="QEncoder"/> with identical state.</returns>
		public IMimeEncoder Clone ()
		{
			return new QEncoder (mask == CharType.IsEncodedPhraseSafe ? QEncodeMode.Phrase : QEncodeMode.Text);
		}

		/// <summary>
		/// Estimates the length of the output.
		/// </summary>
		/// <remarks>
		/// Estimates the number of bytes needed to encode the specified number of input bytes.
		/// </remarks>
		/// <returns>The estimated output length.</returns>
		/// <param name="inputLength">The input length.</param>
		public int EstimateOutputLength (int inputLength)
		{
			return inputLength * 3;
		}

		void ValidateArguments (byte[] input, int startIndex, int length, byte[] output)
		{
			if (input == null)
				throw new ArgumentNullException (nameof (input));

			if (startIndex < 0 || startIndex > input.Length)
				throw new ArgumentOutOfRangeException (nameof (startIndex));

			if (length < 0 || length > (input.Length - startIndex))
				throw new ArgumentOutOfRangeException (nameof (length));

			if (output == null)
				throw new ArgumentNullException (nameof (output));

			if (output.Length < EstimateOutputLength (length))
				throw new ArgumentException ("The output buffer is not large enough to contain the encoded input.", nameof (output));
		}

		unsafe int Encode (byte* input, int length, byte* output)
		{
			if (length == 0)
				return 0;

			byte* inend = input + length;
			byte* outptr = output;
			byte* inptr = input;

			while (inptr < inend) {
				byte c = *inptr++;

				if (c == ' ') {
					*outptr++ = (byte) '_';
				} else if (c != '_' && c.IsType (mask)) {
					*outptr++ = c;
				} else {
					*outptr++ = (byte) '=';
					*outptr++ = hex_alphabet[(c >> 4) & 0x0f];
					*outptr++ = hex_alphabet[c & 0x0f];
				}
			}

			return (int) (outptr - output);
		}

		/// <summary>
		/// Encodes the specified input into the output buffer.
		/// </summary>
		/// <remarks>
		/// <para>Encodes the specified input into the output buffer.</para>
		/// <para>The output buffer should be large enough to hold all of the
		/// encoded 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">The input buffer.</param>
		/// <param name="startIndex">The starting index of the input buffer.</param>
		/// <param name="length">The length of the input buffer.</param>
		/// <param name="output">The output buffer.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="input"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="output"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="startIndex"/> and <paramref name="length"/> do not specify
		/// a valid range in the <paramref name="input"/> byte array.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="output"/> is not large enough to contain the encoded content.</para>
		/// <para>Use the <see cref="EstimateOutputLength"/> method to properly determine the 
		/// necessary length of the <paramref name="output"/> byte array.</para>
		/// </exception>
		public int Encode (byte[] input, int startIndex, int length, byte[] output)
		{
			ValidateArguments (input, startIndex, length, output);

			unsafe {
				fixed (byte* inptr = input, outptr = output) {
					return Encode (inptr + startIndex, length, outptr);
				}
			}
		}

		unsafe int Flush (byte* input, int length, byte* output)
		{
			byte* outptr = output;

			if (length > 0)
				outptr += Encode (input, length, output);

			Reset ();

			return (int) (outptr - output);
		}


		/// <summary>
		/// Clone the <see cref="QEncoder"/> with its current state.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="QEncoder"/> with exactly the same state as the current encoder.
		/// </remarks>
		/// <returns>A new <see cref="QEncoder"/> with identical state.</returns>
		public IMimeEncoder Clone ()
		{
			return new QEncoder (mask == CharType.IsEncodedPhraseSafe ? QEncodeMode.Phrase : QEncodeMode.Text);
		}

		/// <summary>
		/// Estimates the length of the output.
		/// </summary>
		/// <remarks>
		/// Estimates the number of bytes needed to encode the specified number of input bytes.
		/// </remarks>
		/// <returns>The estimated output length.</returns>
		/// <param name="inputLength">The input length.</param>
		public int EstimateOutputLength (int inputLength)
		{
			return inputLength * 3;
		}

		void ValidateArguments (byte[] input, int startIndex, int length, byte[] output)
		{
			if (input == null)
				throw new ArgumentNullException (nameof (input));

			if (startIndex < 0 || startIndex > input.Length)
				throw new ArgumentOutOfRangeException (nameof (startIndex));

			if (length < 0 || length > (input.Length - startIndex))
				throw new ArgumentOutOfRangeException (nameof (length));

			if (output == null)
				throw new ArgumentNullException (nameof (output));

			if (output.Length < EstimateOutputLength (length))
				throw new ArgumentException ("The output buffer is not large enough to contain the encoded input.", nameof (output));
		}

		unsafe int Encode (byte* input, int length, byte* output)
		{
			if (length == 0)
				return 0;

			byte* inend = input + length;
			byte* outptr = output;
			byte* inptr = input;

			while (inptr < inend) {
				byte c = *inptr++;

				if (c == ' ') {
					*outptr++ = (byte) '_';
				} else if (c != '_' && c.IsType (mask)) {
					*outptr++ = c;
				} else {
					*outptr++ = (byte) '=';
					*outptr++ = hex_alphabet[(c >> 4) & 0x0f];
					*outptr++ = hex_alphabet[c & 0x0f];
				}
			}

			return (int) (outptr - output);
		}

		/// <summary>
		/// Encodes the specified input into the output buffer.
		/// </summary>
		/// <remarks>
		/// <para>Encodes the specified input into the output buffer.</para>
		/// <para>The output buffer should be large enough to hold all of the
		/// encoded 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">The input buffer.</param>
		/// <param name="startIndex">The starting index of the input buffer.</param>
		/// <param name="length">The length of the input buffer.</param>
		/// <param name="output">The output buffer.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="input"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="output"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="startIndex"/> and <paramref name="length"/> do not specify
		/// a valid range in the <paramref name="input"/> byte array.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="output"/> is not large enough to contain the encoded content.</para>
		/// <para>Use the <see cref="EstimateOutputLength"/> method to properly determine the 
		/// necessary length of the <paramref name="output"/> byte array.</para>
		/// </exception>
		public int Encode (byte[] input, int startIndex, int length, byte[] output)
		{
			ValidateArguments (input, startIndex, length, output);

			unsafe {
				fixed (byte* inptr = input, outptr = output) {
					return Encode (inptr + startIndex, length, outptr);
				}
			}
		}

		unsafe int Flush (byte* input, int length, byte* output)
		{
			byte* outptr = output;

			if (length > 0)
				outptr += Encode (input, length, output);

			Reset ();

			return (int) (outptr - output);
		}


		/// <summary>
		/// Clone the <see cref="QEncoder"/> with its current state.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="QEncoder"/> with exactly the same state as the current encoder.
		/// </remarks>
		/// <returns>A new <see cref="QEncoder"/> with identical state.</returns>
		public IMimeEncoder Clone ()
		{
			return new QEncoder (mask == CharType.IsEncodedPhraseSafe ? QEncodeMode.Phrase : QEncodeMode.Text);
		}

		/// <summary>
		/// Estimates the length of the output.
		/// </summary>
		/// <remarks>
		/// Estimates the number of bytes needed to encode the specified number of input bytes.
		/// </remarks>
		/// <returns>The estimated output length.</returns>
		/// <param name="inputLength">The input length.</param>
		public int EstimateOutputLength (int inputLength)
		{
			return inputLength * 3;
		}

		void ValidateArguments (byte[] input, int startIndex, int length, byte[] output)
		{
			if (input == null)
				throw new ArgumentNullException ("input");

			if (startIndex < 0 || startIndex > input.Length)
				throw new ArgumentOutOfRangeException ("startIndex");

			if (length < 0 || length > (input.Length - startIndex))
				throw new ArgumentOutOfRangeException ("length");

			if (output == null)
				throw new ArgumentNullException ("output");

			if (output.Length < EstimateOutputLength (length))
				throw new ArgumentException ("The output buffer is not large enough to contain the encoded input.", "output");
		}

		unsafe int Encode (byte* input, int length, byte* output)
		{
			if (length == 0)
				return 0;

			byte* inend = input + length;
			byte* outptr = output;
			byte* inptr = input;

			while (inptr < inend) {
				byte c = *inptr++;

				if (c == ' ') {
					*outptr++ = (byte) '_';
				} else if (c != '_' && c.IsType (mask)) {
					*outptr++ = c;
				} else {
					*outptr++ = (byte) '=';
					*outptr++ = hex_alphabet[(c >> 4) & 0x0f];
					*outptr++ = hex_alphabet[c & 0x0f];
				}
			}

			return (int) (outptr - output);
		}

		/// <summary>
		/// Encodes the specified input into the output buffer.
		/// </summary>
		/// <remarks>
		/// <para>Encodes the specified input into the output buffer.</para>
		/// <para>The output buffer should be large enough to hold all of the
		/// encoded 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">The input buffer.</param>
		/// <param name="startIndex">The starting index of the input buffer.</param>
		/// <param name="length">The length of the input buffer.</param>
		/// <param name="output">The output buffer.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="input"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="output"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="startIndex"/> and <paramref name="length"/> do not specify
		/// a valid range in the <paramref name="input"/> byte array.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="output"/> is not large enough to contain the encoded content.</para>
		/// <para>Use the <see cref="EstimateOutputLength"/> method to properly determine the 
		/// necessary length of the <paramref name="output"/> byte array.</para>
		/// </exception>
		public int Encode (byte[] input, int startIndex, int length, byte[] output)
		{
			ValidateArguments (input, startIndex, length, output);

			unsafe {
				fixed (byte* inptr = input, outptr = output) {
					return Encode (inptr + startIndex, length, outptr);
				}
			}
		}

		unsafe int Flush (byte* input, int length, byte* output)
		{
			byte* outptr = output;

			if (length > 0)
				outptr += Encode (input, length, output);

			Reset ();

			return (int) (outptr - output);
		}

MimeKit.Encodings.QEncoder : IMimeEncoder

Constructors :

public QEncoder(QEncodeMode mode = )

Methods :

public IMimeEncoder Clone()
public ContentEncoding get_Encoding()
public Int32 EstimateOutputLength(Int32 inputLength = )
public Int32 Encode(Byte[] input = , Int32 startIndex = , Int32 length = , Byte[] output = )
public Int32 Flush(Byte[] input = , Int32 startIndex = , Int32 length = , Byte[] output = )
public Void Reset()
public Type GetType()
public String ToString()
public Boolean Equals(Object obj = )
public Int32 GetHashCode()