示例#1
0
        /// <summary>
        /// Reads RFC 2047 (section 5) 'phrase' from source stream.
        /// </summary>
        /// <returns>Returns RFC 2047 (section 5) 'phrase' or null if end of stream reached.</returns>
        public string Phrase()
        {
            /* RFC 2047 5.
             *  phrase = 1*( encoded-word / word )
             *  word   = atom / quoted-string
             */

            int peek = Peek(true);

            if (peek == -1)
            {
                return(null);
            }
            else if (peek == '"')
            {
                return("\"" + QuotedString() + "\"");
            }
            else if (peek == '=')
            {
                return(EncodedWord());
            }
            else
            {
                string word = Atom();
                if (word == null)
                {
                    return(null);
                }

                // Try to encode invalid encoded-words if any mixed in text.
                word = encodedword_regex.Replace(word, delegate(Match m){
                    string encodedWord = m.Value;
                    try{
                        if (string.Equals(m.Groups["encoding"].Value, "Q", StringComparison.InvariantCultureIgnoreCase))
                        {
                            return(Mimes.QDecode(Encoding.GetEncoding(m.Groups["charset"].Value), m.Groups["value"].Value));
                        }
                        else if (string.Equals(m.Groups["encoding"].Value, "B", StringComparison.InvariantCultureIgnoreCase))
                        {
                            return(Encoding.GetEncoding(m.Groups["charset"].Value).GetString(Net.FromBase64(Encoding.Default.GetBytes(m.Groups["value"].Value))));
                        }
                        // Failed to parse encoded-word, leave it as is. RFC 2047 6.3.
                        else
                        {
                            return(encodedWord);
                        }
                    }
                    catch {
                        // Failed to parse encoded-word, leave it as is. RFC 2047 6.3.
                        return(encodedWord);
                    }
                });

                return(word);
            }
        }
示例#2
0
        /// <summary>
        /// Reads RFC 2047 'encoded-word' from source stream.
        /// </summary>
        /// <returns>Returns RFC 2047 'encoded-word' or null if end of stream reached.</returns>
        /// <exception cref="InvalidOperationException">Is raised when source stream has no encoded-word at current position.</exception>
        public string EncodedWord()
        {
            /* RFC 2047 2.
             *  encoded-word = "=?" charset "?" encoding "?" encoded-text "?="
             *
             *  encoded-text = 1*<Any printable ASCII character other than "?" or SPACE>
             *                 ; (but see "Use of encoded-words in message
             *                 ; headers", section 5)
             *
             *  An 'encoded-word' may not be more than 75 characters long, including
             *  'charset', 'encoding', 'encoded-text', and delimiters.  If it is
             *  desirable to encode more text than will fit in an 'encoded-word' of
             *  75 characters, multiple 'encoded-word's (separated by CRLF SPACE) may
             *  be used.
             */

            ToFirstChar();

            if (Peek(false) != '=')
            {
                throw new InvalidOperationException("No encoded-word available.");
            }

            StringBuilder retVal = new StringBuilder();

            while (true)
            {
                Match match = encodedword_regex.Match(m_Source, m_Offset);
                if (match.Success && match.Index == m_Offset)
                {
                    string encodedWord = m_Source.Substring(m_Offset, match.Length);
                    // Move index over encoded-word.
                    m_Offset += match.Length;

                    try{
                        if (string.Equals(match.Groups["encoding"].Value, "Q", StringComparison.InvariantCultureIgnoreCase))
                        {
                            retVal.Append(Mimes.QDecode(Encoding.GetEncoding(match.Groups["charset"].Value), match.Groups["value"].Value));
                        }
                        else if (string.Equals(match.Groups["encoding"].Value, "B", StringComparison.InvariantCultureIgnoreCase))
                        {
                            retVal.Append(Encoding.GetEncoding(match.Groups["charset"].Value).GetString(Net.FromBase64(Encoding.Default.GetBytes(match.Groups["value"].Value))));
                        }
                        // Failed to parse encoded-word, leave it as is. RFC 2047 6.3.
                        else
                        {
                            retVal.Append(encodedWord);
                        }
                    }
                    catch {
                        // Failed to parse encoded-word, leave it as is. RFC 2047 6.3.
                        retVal.Append(encodedWord);
                    }
                }
                else
                {
                    retVal.Append(Atom());
                }

                // We have continuos encoded-word.
                match = encodedword_regex.Match(m_Source, m_Offset);
                if (match.Success && match.Index == m_Offset)
                {
                    ToFirstChar();
                }
                // encoded-word does not continue.
                else
                {
                    break;
                }
            }

            return(retVal.ToString());
        }