Пример #1
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MailKit.Security.SaslMechanismLogin"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a new LOGIN SASL context.
		/// </remarks>
		/// <param name="uri">The URI of the service.</param>
		/// <param name="encoding">The encoding to use for the user's credentials.</param>
		/// <param name="credentials">The user's credentials.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="uri"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="encoding"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="credentials"/> is <c>null</c>.</para>
		/// </exception>
		public SaslMechanismLogin (Uri uri, Encoding encoding, ICredentials credentials) : base (uri, credentials)
		{
			if (encoding == null)
				throw new ArgumentNullException (nameof (encoding));

			this.encoding = encoding;
		}
Пример #2
0
		public Pop3Command (CancellationToken cancellationToken, Pop3CommandHandler handler, Encoding encoding, string format, params object[] args)
		{
			Command = string.Format (format, args);
			CancellationToken = cancellationToken;
			Encoding = encoding;
			Handler = handler;
		}
Пример #3
0
 static SaslMechanismDigestMd5()
 {
     try {
         Latin1 = Encoding.GetEncoding(28591);
     } catch (NotSupportedException) {
         Latin1 = Encoding.GetEncoding(1252);
     }
 }
Пример #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MimeKit.InternetAddress"/> class.
        /// </summary>
        /// <remarks>
        /// Initializes the <see cref="Encoding"/> and <see cref="Name"/> properties of the internet address.
        /// </remarks>
        /// <param name="encoding">The character encoding to be used for encoding the name.</param>
        /// <param name="name">The name of the mailbox or group.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="encoding"/> is <c>null</c>.
        /// </exception>
        protected InternetAddress(Encoding encoding, string name)
        {
            if (encoding == null)
                throw new ArgumentNullException ("encoding");

            Encoding = encoding;
            Name = name;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MailKit.Security.SaslMechanismLogin"/> class.
        /// </summary>
        /// <remarks>
        /// Creates a new LOGIN SASL context.
        /// </remarks>
        /// <param name="encoding">The encoding to use for the user's credentials.</param>
        /// <param name="credentials">The user's credentials.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="encoding"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="credentials"/> is <c>null</c>.</para>
        /// </exception>
        public SaslMechanismLogin(Encoding encoding, NetworkCredential credentials) : base(credentials)
        {
            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }

            this.encoding = encoding;
        }
Пример #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MimeKit.ParserOptions"/> class.
 /// </summary>
 /// <remarks>
 /// By default, new instances of <see cref="ParserOptions"/> enable rfc2047 work-arounds
 /// (which are needed for maximum interoperability with mail software used in the wild)
 /// and do not respect the Content-Length header value.
 /// </remarks>
 public ParserOptions()
 {
     AddressParserComplianceMode = RfcComplianceMode.Loose;
     ParameterComplianceMode     = RfcComplianceMode.Loose;
     Rfc2047ComplianceMode       = RfcComplianceMode.Loose;
     CharsetEncoding             = CharsetUtils.UTF8;
     AllowAddressesWithoutDomain = false;
     RespectContentLength        = false;
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="MailKit.Security.SaslMechanismLogin"/> class.
        /// </summary>
        /// <remarks>
        /// Creates a new LOGIN SASL context.
        /// </remarks>
        /// <param name="encoding">The encoding to use for the user's credentials.</param>
        /// <param name="userName">The user name.</param>
        /// <param name="password">The password.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="encoding"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="userName"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="password"/> is <c>null</c>.</para>
        /// </exception>
        public SaslMechanismLogin(Encoding encoding, string userName, string password) : base(userName, password)
        {
            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }

            this.encoding = encoding;
        }
        public SaslMechanismLogin(Uri uri, Encoding encoding, ICredentials credentials) : base(uri, credentials)
        {
            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }

            this.encoding = encoding;
        }
Пример #9
0
 static bool ProbeCharset(int codepage)
 {
     try {
         Encoding.GetEncoding(codepage);
         return(true);
     } catch {
         return(false);
     }
 }
Пример #10
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.MailboxAddress"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="MailboxAddress"/> with the specified name, address and route. The
		/// specified text encoding is used when encoding the name according to the rules of rfc2047.
		/// </remarks>
		/// <param name="encoding">The character encoding to be used for encoding the name.</param>
		/// <param name="name">The name of the mailbox.</param>
		/// <param name="route">The route of the mailbox.</param>
		/// <param name="address">The address of the mailbox.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="encoding"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="route"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="address"/> is <c>null</c>.</para>
		/// </exception>
		public MailboxAddress (Encoding encoding, string name, IEnumerable<string> route, string address) : base (encoding, name)
		{
			if (address == null)
				throw new ArgumentNullException ("address");

			Route = new DomainList (route);
			Route.Changed += RouteChanged;
			Address = address;
		}
Пример #11
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Text.HtmlWriter"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="HtmlWriter"/>.
		/// </remarks>
		/// <param name="stream">The output stream.</param>
		/// <param name="encoding">The encoding to use for the output.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="stream"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="encoding"/> is <c>null</c>.</para>
		/// </exception>
		public HtmlWriter (Stream stream, Encoding encoding)
		{
			if (stream == null)
				throw new ArgumentNullException ("stream");

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

			html = new StreamWriter (stream, encoding, 4096);
		}
Пример #12
0
		static SmtpStream ()
		{
			UTF8 = Encoding.GetEncoding (65001, new EncoderExceptionFallback (), new DecoderExceptionFallback ());

			try {
				Latin1 = Encoding.GetEncoding (28591);
			} catch (NotSupportedException) {
				Latin1 = Encoding.GetEncoding (1252);
			}
		}
Пример #13
0
        static SmtpStream()
        {
            UTF8 = Encoding.GetEncoding(65001, new EncoderExceptionFallback(), new DecoderExceptionFallback());

            try {
                Latin1 = Encoding.GetEncoding(28591);
            } catch (NotSupportedException) {
                Latin1 = Encoding.GetEncoding(1252);
            }
        }
Пример #14
0
        internal static char[] ConvertToUnicode(Encoding encoding, byte[] input, int startIndex, int length, out int charCount)
        {
            var decoder = encoding.GetDecoder();
            int count   = decoder.GetCharCount(input, startIndex, length, true);
            var output  = new char[count];

            charCount = decoder.GetChars(input, startIndex, length, output, 0, true);

            return(output);
        }
Пример #15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MimeKit.InternetAddress"/> class.
        /// </summary>
        /// <remarks>
        /// Initializes the <see cref="Encoding"/> and <see cref="Name"/> properties of the internet address.
        /// </remarks>
        /// <param name="encoding">The character encoding to be used for encoding the name.</param>
        /// <param name="name">The name of the mailbox or group.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="encoding"/> is <c>null</c>.
        /// </exception>
        protected InternetAddress(Encoding encoding, string name)
        {
            if (encoding == null)
            {
                throw new ArgumentNullException("encoding");
            }

            Encoding = encoding;
            Name     = name;
        }
Пример #16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MimeKit.MailboxAddress"/> class.
        /// </summary>
        /// <remarks>
        /// Creates a new <see cref="MailboxAddress"/> with the specified name, address and route. The
        /// specified text encoding is used when encoding the name according to the rules of rfc2047.
        /// </remarks>
        /// <param name="encoding">The character encoding to be used for encoding the name.</param>
        /// <param name="name">The name of the mailbox.</param>
        /// <param name="route">The route of the mailbox.</param>
        /// <param name="address">The address of the mailbox.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="encoding"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="route"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="address"/> is <c>null</c>.</para>
        /// </exception>
        public MailboxAddress(Encoding encoding, string name, IEnumerable <string> route, string address) : base(encoding, name)
        {
            if (address == null)
            {
                throw new ArgumentNullException("address");
            }

            Route          = new DomainList(route);
            Route.Changed += RouteChanged;
            Address        = address;
        }
Пример #17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MimeKit.MailboxAddress"/> class.
        /// </summary>
        /// <remarks>
        /// Creates a new <see cref="MailboxAddress"/> with the specified name and address. The
        /// specified text encoding is used when encoding the name according to the rules of rfc2047.
        /// </remarks>
        /// <param name="encoding">The character encoding to be used for encoding the name.</param>
        /// <param name="name">The name of the mailbox.</param>
        /// <param name="address">The address of the mailbox.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="encoding"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="address"/> is <c>null</c>.</para>
        /// </exception>
        /// <exception cref="ParseException">
        /// <paramref name="address"/> is malformed.
        /// </exception>
        public MailboxAddress(Encoding encoding, string name, string address) : base(encoding, name)
        {
            if (address == null)
            {
                throw new ArgumentNullException(nameof(address));
            }

            Route          = new DomainList();
            Route.Changed += RouteChanged;
            Address        = address;
        }
Пример #18
0
        internal string Encode(FormatOptions options, Encoding charset)
        {
            int lineLength = "Content-Disposition: ".Length;
            var value      = new StringBuilder(" ");

            value.Append(disposition);
            Parameters.Encode(options, value, ref lineLength, charset);
            value.Append(options.NewLine);

            return(value.ToString());
        }
Пример #19
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MimeKit.ParserOptions"/> class.
 /// </summary>
 /// <remarks>
 /// By default, new instances of <see cref="ParserOptions"/> enable rfc2047 work-arounds
 /// (which are needed for maximum interoperability with mail software used in the wild)
 /// and do not respect the Content-Length header value.
 /// </remarks>
 public ParserOptions()
 {
     AddressParserComplianceMode    = RfcComplianceMode.Loose;
     ParameterComplianceMode        = RfcComplianceMode.Loose;
     Rfc2047ComplianceMode          = RfcComplianceMode.Loose;
     CharsetEncoding                = CharsetUtils.UTF8;
     AllowUnquotedCommasInAddresses = true;
     AllowAddressesWithoutDomain    = true;
     RespectContentLength           = false;
     MaxAddressGroupDepth           = 3;
 }
Пример #20
0
        public static Encoding GetEncoding(string charset)
        {
            int codepage = GetCodePage(charset);

            if (codepage == -1)
            {
                throw new NotSupportedException();
            }

            return(Encoding.GetEncoding(codepage));
        }
Пример #21
0
        internal static char[] ConvertToUnicode(ParserOptions options, byte[] input, int startIndex, int length, out int charCount)
        {
            var invalid       = new InvalidByteCountFallback();
            var userCharset   = options.CharsetEncoding;
            int min           = int.MaxValue;
            int bestCharCount = 0;

            char[]   output = null;
            Encoding encoding;
            Decoder  decoder;

            int[] codepages;
            int   best = -1;
            int   count;

            // Note: 65001 is UTF-8 and 28591 is iso-8859-1
            if (userCharset != null && userCharset.CodePage != 65001 && userCharset.CodePage != 28591)
            {
                codepages = new [] { 65001, userCharset.CodePage, 28591 };
            }
            else
            {
                codepages = new [] { 65001, 28591 };
            }

            for (int i = 0; i < codepages.Length; i++)
            {
                encoding = Encoding.GetEncoding(codepages[i], new EncoderReplacementFallback("?"), invalid);
                decoder  = (Decoder)encoding.GetDecoder();

                count = decoder.GetCharCount(input, startIndex, length, true);
                if (invalid.InvalidByteCount < min)
                {
                    min           = invalid.InvalidByteCount;
                    bestCharCount = count;
                    best          = codepages[i];

                    if (min == 0)
                    {
                        break;
                    }
                }

                invalid.Reset();
            }

            encoding = GetEncoding(best, "?");
            decoder  = (Decoder)encoding.GetDecoder();
            output   = new char[bestCharCount];

            charCount = decoder.GetChars(input, startIndex, length, output, 0, true);

            return(output);
        }
Пример #22
0
        static bool TryParseGroup(ParserOptions options, byte[] text, int startIndex, ref int index, int endIndex, string name, int codepage, bool throwOnError, out InternetAddress address)
        {
            List <InternetAddress> members;
            Encoding encoding;

            try {
                encoding = Encoding.GetEncoding(codepage);
            } catch {
                encoding = Encoding.UTF8;
            }

            address = null;

            // skip over the ':'
            index++;
            if (index >= endIndex)
            {
                if (throwOnError)
                {
                    throw new ParseException(string.Format("Incomplete address group at offset {0}", startIndex), startIndex, index);
                }

                return(false);
            }

            if (InternetAddressList.TryParse(options, text, ref index, endIndex, true, throwOnError, out members))
            {
                address = new GroupAddress(encoding, name, members);
            }
            else
            {
                address = new GroupAddress(encoding, name);
            }

            if (index >= endIndex || text[index] != (byte)';')
            {
                if (throwOnError)
                {
                    throw new ParseException(string.Format("Expected to find ';' at offset {0}", index), startIndex, index);
                }

                while (index < endIndex && text[index] != (byte)';')
                {
                    index++;
                }
            }
            else
            {
                index++;
            }

            return(true);
        }
Пример #23
0
        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            string uri    = @"https://alexeyd.herokuapp.com/mpro5?a=" + a.Text;
            var    client = new HttpClient();

            byte[] request = await client.GetByteArrayAsync(new Uri(uri));

            Portable.Text.Encoding encoding = Portable.Text.Encoding.GetEncoding(1251);
            var s = encoding.GetString(request, 0, request.Length);

            otv.Content = s;
        }
Пример #24
0
 public static byte[] UrlDecodeToBytes(string str, Encoding e)
 {
     if (str == null)
     {
         return(null);
     }
     if (e == null)
     {
         throw new ArgumentNullException("e");
     }
     return(UrlDecodeToBytes(e.GetBytes(str)));
 }
Пример #25
0
		/// <summary>
		/// Sets the text content and the charset parameter in the Content-Type header.
		/// </summary>
		/// <remarks>
		/// This method is similar to setting the <see cref="TextPart.Text"/> property,
		/// but allows specifying a charset encoding to use. Also updates the
		/// <see cref="ContentType.Charset"/> property.
		/// </remarks>
		/// <param name="encoding">The charset encoding.</param>
		/// <param name="text">The text content.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="encoding"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="text"/> is <c>null</c>.</para>
		/// </exception>
		public void SetText (Encoding encoding, string text)
		{
			if (encoding == null)
				throw new ArgumentNullException (nameof (encoding));

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

			ContentType.Parameters["charset"] = CharsetUtils.GetMimeCharset (encoding);
			var content = new MemoryStream (encoding.GetBytes (text));
			Content = new MimeContent (content);
		}
Пример #26
0
        public static Encoding GetEncoding(int codepage, string fallback)
        {
            if (fallback == null)
            {
                throw new ArgumentNullException(nameof(fallback));
            }

            var encoderFallback = new EncoderReplacementFallback(fallback);
            var decoderFallback = new DecoderReplacementFallback(fallback);

            return(Encoding.GetEncoding(codepage, encoderFallback, decoderFallback));
        }
Пример #27
0
        public static int GetCodePage(string charset)
        {
            if (charset == null)
            {
                throw new ArgumentNullException(nameof(charset));
            }

            int codepage;

            lock (aliases) {
                if (!aliases.TryGetValue(charset, out codepage))
                {
                    Encoding encoding;

                    codepage = ParseCodePage(charset);

                    if (codepage == -1)
                    {
                        try {
                            encoding = Encoding.GetEncoding(charset);
                            codepage = encoding.CodePage;

                            if (!aliases.ContainsKey(encoding.WebName))
                            {
                                aliases[encoding.WebName] = codepage;
                            }
                        } catch {
                            codepage = -1;
                        }
                    }
                    else
                    {
                        try {
                            encoding = Encoding.GetEncoding(codepage);
                            if (!aliases.ContainsKey(encoding.WebName))
                            {
                                aliases[encoding.WebName] = codepage;
                            }
                        } catch {
                            codepage = -1;
                        }
                    }

                    if (!aliases.ContainsKey(charset))
                    {
                        aliases[charset] = codepage;
                    }
                }
            }

            return(codepage);
        }
Пример #28
0
 public static byte[] UrlEncodeToBytes(string str, Encoding e)
 {
     if (str == null)
     {
         return(null);
     }
     if (str.Length == 0)
     {
         return(new byte[0]);
     }
     byte[] bytes = e.GetBytes(str);
     return(UrlEncodeToBytes(bytes, 0, bytes.Length));
 }
Пример #29
0
        /// <summary>
        /// Gets the header value using the specified charset.
        /// </summary>
        /// <remarks>
        /// <para>If the raw header value does not properly encode non-ASCII text, the decoder
        /// will fall back to a default charset encoding. Sometimes, however, this
        /// default charset fallback is wrong and the mail client may wish to override
        /// that default charset on a per-header basis.</para>
        /// <para>By using this method, the client is able to override the fallback charset
        /// on a per-header basis.</para>
        /// </remarks>
        /// <returns>The value.</returns>
        /// <param name="charset">Charset.</param>
        public string GetValue(Encoding charset)
        {
            if (charset == null)
            {
                throw new ArgumentNullException("charset");
            }

            var options = Options.Clone();

            options.CharsetEncoding = charset;

            return(Unfold(Rfc2047.DecodeText(options, RawValue)));
        }
Пример #30
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MimeKit.TextPart"/>
        /// class with the specified text subtype.
        /// </summary>
        /// <remarks>
        /// <para>Creates a new <see cref="TextPart"/> with the specified subtype.</para>
        /// <note type="note"><para>Typically the <paramref name="subtype"/> should either be
        /// <c>"plain"</c> for plain text content or <c>"html"</c> for HTML content.</para>
        /// <para>For more options, check the MIME-type registry at
        /// <a href="http://www.iana.org/assignments/media-types/media-types.xhtml#text">
        /// http://www.iana.org/assignments/media-types/media-types.xhtml#text
        /// </a></para></note>
        /// </remarks>
        /// <param name="subtype">The media subtype.</param>
        /// <param name="args">An array of initialization parameters: headers, charset encoding and text.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="subtype"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="args"/> is <c>null</c>.</para>
        /// </exception>
        /// <exception cref="System.ArgumentException">
        /// <para><paramref name="args"/> contains more than one <see cref="System.Text.Encoding"/>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="args"/> contains more than one <see cref="System.String"/>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="args"/> contains one or more arguments of an unknown type.</para>
        /// </exception>
        public TextPart(string subtype, params object[] args) : this(subtype)
        {
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            // Default to UTF8 if not given.
            Encoding encoding = null;
            string   text     = null;

            foreach (object obj in args)
            {
                if (obj == null || TryInit(obj))
                {
                    continue;
                }

                var enc = obj as Encoding;
                if (enc != null)
                {
                    if (encoding != null)
                    {
                        throw new ArgumentException("An encoding should not be specified more than once.");
                    }

                    encoding = enc;
                    continue;
                }

                var str = obj as string;
                if (str != null)
                {
                    if (text != null)
                    {
                        throw new ArgumentException("The text should not be specified more than once.");
                    }

                    text = str;
                    continue;
                }

                throw new ArgumentException("Unknown initialization parameter: " + obj.GetType());
            }

            if (text != null)
            {
                encoding = encoding ?? Encoding.UTF8;
                SetText(encoding, text);
            }
        }
Пример #31
0
 private static void WriteCharBytes(IList buf, char ch, Encoding e)
 {
     if (ch > '\x00ff')
     {
         foreach (byte num in e.GetBytes(new char[] { ch }))
         {
             buf.Add(num);
         }
     }
     else
     {
         buf.Add((byte)ch);
     }
 }
Пример #32
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MimeKit.Text.HtmlWriter"/> class.
        /// </summary>
        /// <remarks>
        /// Creates a new <see cref="HtmlWriter"/>.
        /// </remarks>
        /// <param name="stream">The output stream.</param>
        /// <param name="encoding">The encoding to use for the output.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="stream"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="encoding"/> is <c>null</c>.</para>
        /// </exception>
        public HtmlWriter(Stream stream, Encoding encoding)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            if (encoding == null)
            {
                throw new ArgumentNullException("encoding");
            }

            html = new StreamWriter(stream, encoding, 4096);
        }
Пример #33
0
        public static Encoding GetEncoding(string charset)
        {
            int codepage;

            if ((codepage = GetCodePage(charset)) == -1)
            {
                throw new NotSupportedException(string.Format("The '{0}' encoding is not supported.", charset));
            }

            try {
                return(Encoding.GetEncoding(codepage));
            } catch (Exception ex) {
                throw new NotSupportedException(string.Format("The '{0}' encoding is not supported.", charset), ex);
            }
        }
Пример #34
0
        public static string GetMimeCharset(Encoding encoding)
        {
            if (encoding == null)
            {
                throw new ArgumentNullException("encoding");
            }

            switch (encoding.CodePage)
            {
            case 949:             // ks_c_5601-1987
                return("euc-kr");

            default:
                return(encoding.HeaderName.ToLowerInvariant());
            }
        }
Пример #35
0
        /// <summary>
        /// Returns a <see cref="System.String"/> that represents the current <see cref="MimeKit.MimeEntity"/>.
        /// </summary>
        /// <remarks>
        /// Returns a <see cref="System.String"/> that represents the current <see cref="MimeKit.MimeEntity"/>.
        /// </remarks>
        /// <returns>A <see cref="System.String"/> that represents the current <see cref="MimeKit.MimeEntity"/>.</returns>
        public override string ToString()
        {
            using (var memory = new MemoryStream()) {
                WriteTo(memory);

                var latin1 = Encoding.GetEncoding(28591);
                                #if !PORTABLE
                var buffer = memory.GetBuffer();
                                #else
                var buffer = memory.ToArray();
                                #endif
                int count = (int)memory.Length;

                return(latin1.GetString(buffer, 0, count));
            }
        }
Пример #36
0
        internal string Encode(FormatOptions options, Encoding charset)
        {
            int lineLength = "Content-Type:".Length;
            var value      = new StringBuilder(" ");

            value.Append(MediaType);
            value.Append('/');
            value.Append(MediaSubtype);

            lineLength += value.Length;

            Parameters.Encode(options, value, ref lineLength, charset);
            value.Append(options.NewLine);

            return(value.ToString());
        }
Пример #37
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Header"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a new message or entity header for the specified field and
		/// value pair. The encoding is used to determine which charset to use
		/// when encoding the value according to the rules of rfc2047.
		/// </remarks>
		/// <param name="charset">The charset that should be used to encode the
		/// header value.</param>
		/// <param name="id">The header identifier.</param>
		/// <param name="value">The value of the header.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="charset"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="value"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="id"/> is not a valid <see cref="HeaderId"/>.
		/// </exception>
		public Header (Encoding charset, HeaderId id, string value)
		{
			if (charset == null)
				throw new ArgumentNullException ("charset");

			if (id == HeaderId.Unknown)
				throw new ArgumentOutOfRangeException ("id");

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

			Options = ParserOptions.Default.Clone ();
			Field = id.ToHeaderName ();
			Id = id;

			SetValue (charset, value);
		}
Пример #38
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Header"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a new message or entity header for the specified field and
		/// value pair. The encoding is used to determine which charset to use
		/// when encoding the value according to the rules of rfc2047.
		/// </remarks>
		/// <param name="encoding">The character encoding that should be used to
		/// encode the header value.</param>
		/// <param name="id">The header identifier.</param>
		/// <param name="value">The value of the header.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="encoding"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="value"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="id"/> is not a valid <see cref="HeaderId"/>.
		/// </exception>
		public Header (Encoding encoding, HeaderId id, string value)
		{
			if (encoding == null)
				throw new ArgumentNullException ("encoding");

			if (id == HeaderId.Unknown)
				throw new ArgumentOutOfRangeException ("id");

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

			Options = ParserOptions.Default.Clone ();
			Field = id.ToHeaderName ();
			Id = id;

			rawField = Encoding.ASCII.GetBytes (Field);
			SetValue (encoding, value);
		}
Пример #39
0
		/// <summary>
		/// Sets the text content and the charset parameter in the Content-Type header.
		/// </summary>
		/// <remarks>
		/// This method is similar to setting the <see cref="Text"/> property, but allows
		/// specifying a charset encoding to use. Also updates the
		/// <see cref="ContentType.Charset"/> property.
		/// </remarks>
		/// <param name="encoding">The charset encoding.</param>
		/// <param name="text">The text content.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="encoding"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="text"/> is <c>null</c>.</para>
		/// </exception>
		public void SetText (Encoding encoding, string text)
		{
			if (encoding == null)
				throw new ArgumentNullException ("encoding");

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

			ContentType.Parameters["charset"] = CharsetUtils.GetMimeCharset (encoding);
			var content = new MemoryStream (encoding.GetBytes (text));
			ContentObject = new ContentObject (content);
		}
Пример #40
0
		/// <summary>
		/// Asynchronously authenticates using the specified user name and password.
		/// </summary>
		/// <remarks>
		/// <para>If the server supports one or more SASL authentication mechanisms,
		/// then the SASL mechanisms that both the client and server support are tried
		/// in order of greatest security to weakest security. Once a SASL
		/// authentication mechanism is found that both client and server support,
		/// the credentials are used to authenticate.</para>
		/// <para>If the server does not support SASL or if no common SASL mechanisms
		/// can be found, then the default login command is used as a fallback.</para>
		/// <note type="tip">To prevent the usage of certain authentication mechanisms,
		/// simply remove them from the <see cref="AuthenticationMechanisms"/> hash set
		/// before calling this method.</note>
		/// </remarks>
		/// <returns>An asynchronous task context.</returns>
		/// <param name="encoding">The encoding to use for the user's credentials.</param>
		/// <param name="userName">The user name.</param>
		/// <param name="password">The password.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="encoding"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="userName"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="password"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="MailService"/> has been disposed.
		/// </exception>
		/// <exception cref="System.InvalidOperationException">
		/// The <see cref="MailService"/> is not connected or is already authenticated.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </exception>
		/// <exception cref="MailKit.Security.AuthenticationException">
		/// Authentication using the supplied credentials has failed.
		/// </exception>
		/// <exception cref="MailKit.Security.SaslException">
		/// A SASL authentication error occurred.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="ProtocolException">
		/// A protocol error occurred.
		/// </exception>
		public Task AuthenticateAsync (Encoding encoding, string userName, string password, CancellationToken cancellationToken = default (CancellationToken))
		{
			if (encoding == null)
				throw new ArgumentNullException ("encoding");

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

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

			var credentials = new NetworkCredential (userName, password);

			return AuthenticateAsync (encoding, credentials, cancellationToken);
		}
Пример #41
0
		/// <summary>
		/// Asynchronously authenticates using the supplied credentials.
		/// </summary>
		/// <remarks>
		/// <para>If the server supports one or more SASL authentication mechanisms,
		/// then the SASL mechanisms that both the client and server support are tried
		/// in order of greatest security to weakest security. Once a SASL
		/// authentication mechanism is found that both client and server support,
		/// the credentials are used to authenticate.</para>
		/// <para>If the server does not support SASL or if no common SASL mechanisms
		/// can be found, then the default login command is used as a fallback.</para>
		/// <note type="tip">To prevent the usage of certain authentication mechanisms,
		/// simply remove them from the <see cref="AuthenticationMechanisms"/> hash set
		/// before calling this method.</note>
		/// </remarks>
		/// <returns>An asynchronous task context.</returns>
		/// <param name="encoding">The encoding to use for the user's credentials.</param>
		/// <param name="credentials">The user's credentials.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="encoding"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="credentials"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="MailService"/> has been disposed.
		/// </exception>
		/// <exception cref="System.InvalidOperationException">
		/// The <see cref="MailService"/> is not connected or is already authenticated.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </exception>
		/// <exception cref="MailKit.Security.AuthenticationException">
		/// Authentication using the supplied credentials has failed.
		/// </exception>
		/// <exception cref="MailKit.Security.SaslException">
		/// A SASL authentication error occurred.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="ProtocolException">
		/// A protocol error occurred.
		/// </exception>
		public virtual Task AuthenticateAsync (Encoding encoding, ICredentials credentials, CancellationToken cancellationToken = default (CancellationToken))
		{
			if (encoding == null)
				throw new ArgumentNullException ("encoding");

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

			return Task.Factory.StartNew (() => {
				lock (SyncRoot) {
					Authenticate (encoding, credentials, cancellationToken);
				}
			}, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default);
		}
Пример #42
0
		/// <summary>
		/// Authenticates using the supplied credentials.
		/// </summary>
		/// <remarks>
		/// <para>If the server supports one or more SASL authentication mechanisms,
		/// then the SASL mechanisms that both the client and server support are tried
		/// in order of greatest security to weakest security. Once a SASL
		/// authentication mechanism is found that both client and server support,
		/// the credentials are used to authenticate.</para>
		/// <para>If the server does not support SASL or if no common SASL mechanisms
		/// can be found, then the default login command is used as a fallback.</para>
		/// <note type="tip">To prevent the usage of certain authentication mechanisms,
		/// simply remove them from the <see cref="AuthenticationMechanisms"/> hash set
		/// before calling this method.</note>
		/// </remarks>
		/// <param name="encoding">The encoding to use for the user's credentials.</param>
		/// <param name="credentials">The user's credentials.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="encoding"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="credentials"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="MailService"/> has been disposed.
		/// </exception>
		/// <exception cref="System.InvalidOperationException">
		/// The <see cref="MailService"/> is not connected or is already authenticated.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </exception>
		/// <exception cref="MailKit.Security.AuthenticationException">
		/// Authentication using the supplied credentials has failed.
		/// </exception>
		/// <exception cref="MailKit.Security.SaslException">
		/// A SASL authentication error occurred.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="ProtocolException">
		/// A protocol error occurred.
		/// </exception>
		public abstract void Authenticate (Encoding encoding, ICredentials credentials, CancellationToken cancellationToken = default (CancellationToken));
Пример #43
0
		/// <summary>
		/// Encodes the phrase.
		/// </summary>
		/// <remarks>
		/// Encodes the phrase according to the rules of rfc2047 using
		/// the specified charset encoding and formatting options.
		/// </remarks>
		/// <returns>The encoded phrase.</returns>
		/// <param name="options">The formatting options</param>
		/// <param name="charset">The charset encoding.</param>
		/// <param name="phrase">The phrase to encode.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="options"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="charset"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="phrase"/> is <c>null</c>.</para>
		/// </exception>
		public static byte[] EncodePhrase (FormatOptions options, Encoding charset, string phrase)
		{
			if (options == null)
				throw new ArgumentNullException ("options");

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

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

			return Encode (options, charset, phrase, true);
		}
Пример #44
0
		static void AppendEncodedWord (StringBuilder str, Encoding charset, string text, int startIndex, int length, QEncodeMode mode)
		{
			var chars = new char[length];
			IMimeEncoder encoder;
			byte[] word, encoded;
			char encoding;
			int len;

			text.CopyTo (startIndex, chars, 0, length);

			try {
				word = CharsetConvert (charset, chars, length, out len);
			} catch {
				charset = Encoding.UTF8;
				word = CharsetConvert (charset, chars, length, out len);
			}

			if (CharsetRequiresBase64 (charset) || GetBestContentEncoding (word, 0, len) == ContentEncoding.Base64) {
				encoder = new Base64Encoder (true);
				encoding = 'b';
			} else {
				encoder = new QEncoder (mode);
				encoding = 'q';
			}

			encoded = new byte[encoder.EstimateOutputLength (len)];
			len = encoder.Flush (word, 0, len, encoded);

			str.AppendFormat ("=?{0}?{1}?", CharsetUtils.GetMimeCharset (charset), encoding);
			for (int i = 0; i < len; i++)
				str.Append ((char) encoded[i]);
			str.Append ("?=");
		}
Пример #45
0
		static byte[] EncodeUnstructuredHeader (ParserOptions options, FormatOptions format, Encoding charset, string field, string value)
		{
			if (format.International) {
				var folded = Fold (format, field, value);

				return Encoding.UTF8.GetBytes (folded);
			}

			var encoded = Rfc2047.EncodeText (format, charset, value);

			return Rfc2047.FoldUnstructuredHeader (format, field, encoded);
		}
Пример #46
0
		static byte[] CharsetConvert (Encoding charset, char[] word, int length, out int converted)
		{
			var encoder = charset.GetEncoder ();
			int count = encoder.GetByteCount (word, 0, length, true);
			var encoded = new byte[count];

			converted = encoder.GetBytes (word, 0, length, encoded, 0, true);

			return encoded;
		}
Пример #47
0
		static bool CharsetRequiresBase64 (Encoding encoding)
		{
			// https://tools.ietf.org/rfc/rfc1468.txt
			//
			// ISO-2022-JP may also be used in MIME Part 2 headers.  The "B"
			// encoding should be used with ISO-2022-JP text.
			return encoding.CodePage == 50220 || encoding.CodePage == 50222;
		}
Пример #48
0
		/// <summary>
		/// Encodes the unstructured text.
		/// </summary>
		/// <remarks>
		/// Encodes the unstructured text according to the rules of rfc2047
		/// using the specified charset encoding.
		/// </remarks>
		/// <returns>The encoded text.</returns>
		/// <param name="charset">The charset encoding.</param>
		/// <param name="text">The text to encode.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="charset"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="text"/> is <c>null</c>.</para>
		/// </exception>
		public static byte[] EncodeText (Encoding charset, string text)
		{
			return EncodeText (FormatOptions.Default, charset, text);
		}
Пример #49
0
		/// <summary>
		/// Encodes the unstructured text.
		/// </summary>
		/// <remarks>
		/// Encodes the unstructured text according to the rules of rfc2047
		/// using the specified charset encoding and formatting options.
		/// </remarks>
		/// <returns>The encoded text.</returns>
		/// <param name="options">The formatting options</param>
		/// <param name="charset">The charset encoding.</param>
		/// <param name="text">The text to encode.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="options"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="charset"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="text"/> is <c>null</c>.</para>
		/// </exception>
		public static byte[] EncodeText (FormatOptions options, Encoding charset, string text)
		{
			if (options == null)
				throw new ArgumentNullException ("options");

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

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

			return Encode (options, charset, text, false);
		}
Пример #50
0
		/// <summary>
		/// Encodes the phrase.
		/// </summary>
		/// <remarks>
		/// Encodes the phrase according to the rules of rfc2047 using
		/// the specified charset encoding.
		/// </remarks>
		/// <returns>The encoded phrase.</returns>
		/// <param name="charset">The charset encoding.</param>
		/// <param name="phrase">The phrase to encode.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="charset"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="phrase"/> is <c>null</c>.</para>
		/// </exception>
		public static byte[] EncodePhrase (Encoding charset, string phrase)
		{
			return EncodePhrase (FormatOptions.Default, charset, phrase);
		}
Пример #51
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.IO.Filters.CharsetFilter"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="CharsetFilter"/> to convert text from the specified
		/// source encoding into the target charset encoding.
		/// </remarks>
		/// <param name="sourceEncoding">Source encoding.</param>
		/// <param name="targetEncoding">Target encoding.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="sourceEncoding"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="targetEncoding"/> is <c>null</c>.</para>
		/// </exception>
		public CharsetFilter (Encoding sourceEncoding, Encoding targetEncoding)
		{
			if (sourceEncoding == null)
				throw new ArgumentNullException ("sourceEncoding");

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

			SourceEncoding = sourceEncoding;
			TargetEncoding = targetEncoding;

			decoder = (Decoder) SourceEncoding.GetDecoder ();
			encoder = (Encoder) TargetEncoding.GetEncoder ();
		}
Пример #52
0
		static IList<Word> GetRfc822Words (FormatOptions options, Encoding charset, string text, bool phrase)
		{
			var encoder = charset.GetEncoder ();
			var words = new List<Word> ();
			var chars = new char[2];
			var saved = new Word ();
			var word = new Word ();
			int nchars, n, i = 0;
			char c;

			while (i < text.Length) {
				c = text[i++];

				if (c < 256 && IsBlank (c)) {
					if (word.ByteCount > 0) {
						words.Add (word);
						word = new Word ();
					}

					word.StartIndex = i;
				} else {
					// save state in case adding this character exceeds the max line length
					word.CopyTo (saved);

					if (c < 127) {
						if (IsCtrl (c)) {
							word.Encoding = options.AllowMixedHeaderCharsets ? Math.Max (word.Encoding, 1) : 2;
							word.Type = WordType.EncodedWord;
							word.EncodeCount++;
						} else if (phrase && !IsAtom (c)) {
							// phrases can have quoted strings
							if (word.Type == WordType.Atom)
								word.Type = WordType.QuotedString;
						}

						if (c == '"' || c == '\\')
							word.QuotedPairs++;

						word.ByteCount++;
						word.CharCount++;
						nchars = 1;
					} else if (c < 256) {
						// iso-8859-1
						word.Encoding = options.AllowMixedHeaderCharsets ? Math.Max (word.Encoding, 1) : 2;
						word.Type = WordType.EncodedWord;
						word.EncodeCount++;
						word.ByteCount++;
						word.CharCount++;
						nchars = 1;
					} else {
						if (char.IsSurrogatePair (text, i - 1)) {
							chars[1] = text[i++];
							nchars = 2;
						} else {
							nchars = 1;
						}

						chars[0] = c;

						try {
							n = encoder.GetByteCount (chars, 0, nchars, true);
						} catch {
							n = 3;
						}

						word.Type = WordType.EncodedWord;
						word.CharCount += nchars;
						word.EncodeCount += n;
						word.ByteCount += n;
						word.Encoding = 2;
					}

					if (ExceedsMaxLineLength (options, charset, word)) {
						// restore our previous state
						saved.CopyTo (word);
						i -= nchars;

						// Note: if the word is longer than what we can fit on
						// one line, then we need to encode it.
						if (word.Type == WordType.Atom) {
							word.Type = WordType.EncodedWord;

							// in order to fit this long atom under MaxLineLength, we need to
							// account for the added length of =?us-ascii?q?...?=
							n = "us-ascii".Length + 7;
							word.CharCount -= n;
							word.ByteCount -= n;
							i -= n;
						}

						words.Add (word);

						saved.Type = word.Type;
						word = new Word ();

						// Note: the word-type needs to be preserved when breaking long words.
						word.Type = saved.Type;
						word.StartIndex = i;
					}
				}
			}

			if (word.ByteCount > 0)
				words.Add (word);

			return words;
		}
Пример #53
0
		byte[] FormatRawValue (FormatOptions format, Encoding encoding)
		{
			switch (Id) {
			case HeaderId.DispositionNotificationTo:
			case HeaderId.ResentFrom:
			case HeaderId.ResentBcc:
			case HeaderId.ResentCc:
			case HeaderId.ResentTo:
			case HeaderId.From:
			case HeaderId.Bcc:
			case HeaderId.Cc:
			case HeaderId.To:
				return EncodeAddressHeader (Options, format, encoding, Field, textValue);
			case HeaderId.Received:
				return EncodeReceivedHeader (Options, format, encoding, Field, textValue);
			case HeaderId.ResentMessageId:
			case HeaderId.MessageId:
			case HeaderId.ContentId:
				return EncodeMessageIdHeader (Options, format, encoding, Field, textValue);
			case HeaderId.References:
				return EncodeReferencesHeader (Options, format, encoding, Field, textValue);
			case HeaderId.ContentDisposition:
				return EncodeContentDisposition (Options, format, encoding, Field, textValue);
			case HeaderId.ContentType:
				return EncodeContentType (Options, format, encoding, Field, textValue);
			case HeaderId.DkimSignature:
				return EncodeDkimSignatureHeader (Options, format, encoding, Field, textValue);
			default:
				return EncodeUnstructuredHeader (Options, format, encoding, Field, textValue);
			}
		}
Пример #54
0
		static bool ExceedsMaxLineLength (FormatOptions options, Encoding charset, Word word)
		{
			int length;

			switch (word.Type) {
			case WordType.EncodedWord:
				switch (word.Encoding) {
				case 1:
					length = EstimateEncodedWordLength ("iso-8859-1", word.ByteCount, word.EncodeCount);
					break;
				case 0:
					length = EstimateEncodedWordLength ("us-ascii", word.ByteCount, word.EncodeCount);
					break;
				default:
					length = EstimateEncodedWordLength (charset, word.ByteCount, word.EncodeCount);
					break;
				}
				break;
			case WordType.QuotedString:
				length = word.ByteCount + word.QuotedPairs + 2;
				break;
			default:
				length = word.ByteCount;
				break;
			}

			return length + 1 >= options.MaxLineLength;
		}
Пример #55
0
		static byte[] EncodeContentType (ParserOptions options, FormatOptions format, Encoding charset, string field, string value)
		{
			var contentType = ContentType.Parse (options, value);
			var encoded = contentType.Encode (format, charset);

			return Encoding.UTF8.GetBytes (encoded);
		}
Пример #56
0
		static int EstimateEncodedWordLength (Encoding charset, int byteCount, int encodeCount)
		{
			return EstimateEncodedWordLength (CharsetUtils.GetMimeCharset (charset), byteCount, encodeCount);
		}
Пример #57
0
		static bool ShouldMergeWords (FormatOptions options, Encoding charset, IList<Word> words, Word word, int i)
		{
			Word next = words[i];

			int lwspCount = next.StartIndex - (word.StartIndex + word.CharCount);
			int length = word.ByteCount + lwspCount + next.ByteCount;
			int encoded = word.EncodeCount + next.EncodeCount;
			int quoted = word.QuotedPairs + next.QuotedPairs;

			switch (word.Type) {
			case WordType.Atom:
				if (next.Type == WordType.EncodedWord)
					return false;

				return length + 1 < options.MaxLineLength;
			case WordType.QuotedString:
				if (next.Type == WordType.EncodedWord)
					return false;

				return length + quoted + 3 < options.MaxLineLength;
			case WordType.EncodedWord:
				if (next.Type == WordType.Atom) {
					// whether we merge or not is dependent upon:
					// 1. the number of atoms in a row after 'word'
					// 2. if there is another encoded-word after
					//    the string of atoms.
					bool merge = false;
					int natoms = 0;

					for (int j = i + 1; j < words.Count && natoms < 3; j++) {
						if (words[j].Type != WordType.Atom) {
							merge = true;
							break;
						}

						natoms++;
					}

					// if all the words after the encoded-word are atoms, don't merge
					if (!merge)
						return false;
				}

				// avoid merging with qstrings
				if (next.Type == WordType.QuotedString)
					return false;

				switch (Math.Max (word.Encoding, next.Encoding)) {
				case 1:
					length = EstimateEncodedWordLength ("iso-8859-1", length, encoded);
					break;
				case 0:
					length = EstimateEncodedWordLength ("us-ascii", length, encoded);
					break;
				default:
					length = EstimateEncodedWordLength (charset, length, encoded);
					break;
				}

				return length + 1 < options.MaxLineLength;
			default:
				return false;
			}
		}
Пример #58
0
		static byte[] Encode (FormatOptions options, Encoding charset, string text, bool phrase)
		{
			var mode = phrase ? QEncodeMode.Phrase : QEncodeMode.Text;
			var words = Merge (options, charset, GetRfc822Words (options, charset, text, phrase));
			var str = new StringBuilder ();
			int start, length;
			Word prev = null;
			byte[] encoded;

			foreach (var word in words) {
				// append the correct number of spaces between words...
				if (prev != null && !(prev.Type == WordType.EncodedWord && word.Type == WordType.EncodedWord)) {
					start = prev.StartIndex + prev.CharCount;
					length = word.StartIndex - start;
					str.Append (text, start, length);
				}

				switch (word.Type) {
				case WordType.Atom:
					str.Append (text, word.StartIndex, word.CharCount);
					break;
				case WordType.QuotedString:
					AppendQuoted (str, text, word.StartIndex, word.CharCount);
					break;
				case WordType.EncodedWord:
					if (prev != null && prev.Type == WordType.EncodedWord) {
						// include the whitespace between these 2 words in the
						// resulting rfc2047 encoded-word.
						start = prev.StartIndex + prev.CharCount;
						length = (word.StartIndex + word.CharCount) - start;

						str.Append (phrase ? '\t' : ' ');
					} else {
						start = word.StartIndex;
						length = word.CharCount;
					}

					switch (word.Encoding) {
					case 0: // us-ascii
						AppendEncodedWord (str, Encoding.ASCII, text, start, length, mode);
						break;
					case 1: // iso-8859-1
						AppendEncodedWord (str, CharsetUtils.Latin1, text, start, length, mode);
						break;
					default: // custom charset
						AppendEncodedWord (str, charset, text, start, length, mode);
						break;
					}
					break;
				}

				prev = word;
			}

			encoded = new byte[str.Length];
			for (int i = 0; i < str.Length; i++)
				encoded[i] = (byte) str[i];

			return encoded;
		}
Пример #59
0
		/// <summary>
		/// Gets the decoded text content using the provided charset encoding to
		/// override the charset specified in the Content-Type parameters.
		/// </summary>
		/// <remarks>
		/// Uses the provided charset encoding to convert the raw text content
		/// into a unicode string, overriding any charset specified in the
		/// Content-Type header.
		/// </remarks>
		/// <returns>The decoded text.</returns>
		/// <param name="encoding">The charset encoding to use.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="encoding"/> is <c>null</c>.
		/// </exception>
		public string GetText (Encoding encoding)
		{
			if (encoding == null)
				throw new ArgumentNullException ("encoding");

			if (ContentObject == null)
				return string.Empty;

			using (var memory = new MemoryStream ()) {
				ContentObject.DecodeTo (memory);

#if PORTABLE
				var buffer = memory.ToArray ();
#else
				var buffer = memory.GetBuffer ();
#endif

				return encoding.GetString (buffer, 0, (int) memory.Length);
			}
		}
Пример #60
0
		static IList<Word> Merge (FormatOptions options, Encoding charset, IList<Word> words)
		{
			if (words.Count < 2)
				return words;

			int lwspCount, encoding, encoded, quoted, byteCount, length;
			var merged = new List<Word> ();
			Word word, next;

			word = words[0];
			merged.Add (word);

			// first pass: merge qstrings with adjacent qstrings and encoded-words with adjacent encoded-words
			for (int i = 1; i < words.Count; i++) {
				next = words[i];

				if (word.Type != WordType.Atom && word.Type == next.Type) {
					lwspCount = next.StartIndex - (word.StartIndex + word.CharCount);
					byteCount = word.ByteCount + lwspCount + next.ByteCount;
					encoding = Math.Max (word.Encoding, next.Encoding);
					encoded = word.EncodeCount + next.EncodeCount;
					quoted = word.QuotedPairs + next.QuotedPairs;

					if (word.Type == WordType.EncodedWord) {
						switch (encoding) {
						case 1:
							length = EstimateEncodedWordLength ("iso-8859-1", byteCount, encoded);
							break;
						case 0:
							length = EstimateEncodedWordLength ("us-ascii", byteCount, encoded);
							break;
						default:
							length = EstimateEncodedWordLength (charset, byteCount, encoded);
							break;
						}
					} else {
						length = byteCount + quoted + 2;
					}

					if (length + 1 < options.MaxLineLength) {
						word.CharCount = (next.StartIndex + next.CharCount) - word.StartIndex;
						word.ByteCount = byteCount;
						word.EncodeCount = encoded;
						word.QuotedPairs = quoted;
						word.Encoding = encoding;
						continue;
					}
				}

				merged.Add (next);
				word = next;
			}

			words = merged;
			merged = new List<Word> ();

			word = words[0];
			merged.Add (word);

			// second pass: now merge atoms with the other words
			for (int i = 1; i < words.Count; i++) {
				next = words[i];

				if (ShouldMergeWords (options, charset, words, word, i)) {
					// the resulting word is the max of the 2 types
					lwspCount = next.StartIndex - (word.StartIndex + word.CharCount);

					word.Type = (WordType) Math.Max ((int) word.Type, (int) next.Type);
					word.CharCount = (next.StartIndex + next.CharCount) - word.StartIndex;
					word.ByteCount = word.ByteCount + lwspCount + next.ByteCount;
					word.Encoding = Math.Max (word.Encoding, next.Encoding);
					word.EncodeCount = word.EncodeCount + next.EncodeCount;
					word.QuotedPairs = word.QuotedPairs + next.QuotedPairs;
				} else {
					merged.Add (next);
					word = next;
				}
			}

			return merged;
		}