예제 #1
0
        /// <summary>
        /// Tries to parse a version from a header such as Mime-Version.
        /// </summary>
        /// <remarks>
        /// Parses a MIME version string from the supplied buffer starting at the given index
        /// and spanning across the specified number of bytes.
        /// </remarks>
        /// <returns><c>true</c>, if the version was successfully parsed, <c>false</c> otherwise.</returns>
        /// <param name="buffer">The raw byte buffer to parse.</param>
        /// <param name="startIndex">The index into the buffer to start parsing.</param>
        /// <param name="length">The length of the buffer to parse.</param>
        /// <param name="version">The parsed version.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="buffer"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// <paramref name="startIndex"/> and <paramref name="length"/> do not specify
        /// a valid range in the byte array.
        /// </exception>
        public static bool TryParse(byte[] buffer, int startIndex, int length, out Version version)
        {
            ParseUtils.ValidateArguments(buffer, startIndex, length);

            var values   = new List <int> ();
            int endIndex = startIndex + length;
            int index    = startIndex;
            int value;

            version = null;

            do
            {
                if (!ParseUtils.SkipCommentsAndWhiteSpace(buffer, ref index, endIndex, false) || index >= endIndex)
                {
                    return(false);
                }

                if (!ParseUtils.TryParseInt32(buffer, ref index, endIndex, out value))
                {
                    return(false);
                }

                values.Add(value);

                if (!ParseUtils.SkipCommentsAndWhiteSpace(buffer, ref index, endIndex, false))
                {
                    return(false);
                }

                if (index >= endIndex)
                {
                    break;
                }

                if (buffer[index++] != (byte)'.')
                {
                    return(false);
                }
            } while (index < endIndex);

            switch (values.Count)
            {
            case 4: version = new Version(values[0], values[1], values[2], values[3]); break;

            case 3: version = new Version(values[0], values[1], values[2]); break;

            case 2: version = new Version(values[0], values[1]); break;

            default: return(false);
            }

            return(true);
        }
예제 #2
0
        /// <summary>
        /// Parses a Message-Id header value.
        /// </summary>
        /// <remarks>
        /// Parses the Message-Id value, returning the addr-spec portion of the msg-id token.
        /// </remarks>
        /// <returns>The addr-spec portion of the msg-id token.</returns>
        /// <param name="buffer">The raw byte buffer to parse.</param>
        /// <param name="startIndex">The index into the buffer to start parsing.</param>
        /// <param name="length">The length of the buffer to parse.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="buffer"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// <paramref name="startIndex"/> and <paramref name="length"/> do not specify
        /// a valid range in the byte array.
        /// </exception>
        public static string ParseMessageId(byte[] buffer, int startIndex, int length)
        {
            ParseUtils.ValidateArguments(buffer, startIndex, length);

            int    endIndex = startIndex + length;
            int    index    = startIndex;
            string msgid;

            ParseUtils.TryParseMsgId(buffer, ref index, endIndex, false, false, out msgid);

            return(msgid);
        }
예제 #3
0
        /// <summary>
        /// Parses a Message-Id header value.
        /// </summary>
        /// <remarks>
        /// Parses the Message-Id value, returning the addr-spec portion of the msg-id token.
        /// </remarks>
        /// <returns>The addr-spec portion of the msg-id token.</returns>
        /// <param name="buffer">The raw byte buffer to parse.</param>
        /// <param name="startIndex">The index into the buffer to start parsing.</param>
        /// <param name="length">The length of the buffer to parse.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="buffer"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// <paramref name="startIndex"/> and <paramref name="length"/> do not specify
        /// a valid range in the byte array.
        /// </exception>
        public static string ParseMessageId(byte[] buffer, int startIndex, int length)
        {
            ParseUtils.ValidateArguments(buffer, startIndex, length);

            byte[] sentinels = { (byte)'>' };
            int    endIndex  = startIndex + length;
            int    index     = startIndex;
            string msgid;

            if (!ParseUtils.SkipCommentsAndWhiteSpace(buffer, ref index, endIndex, false))
            {
                return(null);
            }

            if (index >= endIndex)
            {
                return(null);
            }

            if (buffer[index] == '<')
            {
                // skip over the '<'
                index++;

                if (index >= endIndex)
                {
                    return(null);
                }
            }

            string localpart;

            if (!InternetAddress.TryParseLocalPart(buffer, ref index, endIndex, false, out localpart))
            {
                return(null);
            }

            if (index >= endIndex)
            {
                return(null);
            }

            if (buffer[index] == (byte)'>')
            {
                // The msgid token did not contain an @domain. Technically this is illegal, but for the
                // sake of maximum compatibility, I guess we have no choice but to accept it...
                return(localpart);
            }

            if (buffer[index] != (byte)'@')
            {
                // who the hell knows what we have here...
                return(null);
            }

            // skip over the '@'
            index++;

            if (!ParseUtils.SkipCommentsAndWhiteSpace(buffer, ref index, endIndex, false))
            {
                return(null);
            }

            if (index >= endIndex)
            {
                return(null);
            }

            if (buffer[index] == (byte)'>')
            {
                // The msgid token was in the form "<local-part@>". Technically this is illegal, but for
                // the sake of maximum compatibility, I guess we have no choice but to accept it...
                // https://github.com/jstedfast/MimeKit/issues/102
                return(localpart + "@");
            }

            string domain;

            if (!ParseUtils.TryParseDomain(buffer, ref index, endIndex, sentinels, false, out domain))
            {
                return(null);
            }

            msgid = localpart + "@" + domain;

            // Note: some Message-Id's are broken and in the form "<local-part@domain@domain>"
            // https://github.com/jstedfast/MailKit/issues/138
            while (index < endIndex && buffer[index] == (byte)'@')
            {
                index++;

                if (!ParseUtils.TryParseDomain(buffer, ref index, endIndex, sentinels, false, out domain))
                {
                    break;
                }

                msgid += "@" + domain;
            }

            return(msgid);
        }