/// <summary> /// Parses header field from the specified value. /// </summary> /// <param name="value">Header field value. Header field name must be included. For example: 'Content-Type: text/plain'.</param> /// <returns>Returns parsed header field.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>value</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when header field parsing errors.</exception> public static MIME_h_Unstructured Parse(string value) { if (value == null) { throw new ArgumentNullException("value"); } MIME_h_Unstructured retVal = new MIME_h_Unstructured(); string[] name_value = value.Split(new char[] { ':' }, 2); if (name_value[0].Trim() == string.Empty) { throw new ParseException("Invalid header field '" + value + "' syntax."); } retVal.m_Name = name_value[0]; // There may be multiple encoded-words and they can be mixed with atom/quoted-string ... . try{ StringBuilder v = new StringBuilder(); MIME_Reader r = new MIME_Reader(MIME_Utils.UnfoldHeader(name_value.Length == 2 ? name_value[1].TrimStart() : "")); while (true) { string whiteSpaces = r.ToFirstChar(); if (!string.IsNullOrEmpty(whiteSpaces)) { v.Append(whiteSpaces); } string phrase = r.Phrase(); if (phrase == null) { if (r.Available == 0) { retVal.m_Value = v.ToString().TrimStart(); break; } // Some special char(like :,{ ...) just read it. else { v.Append((char)r.Char(false)); } } else { v.Append(phrase); } } } catch { // Parsing failed, leave raw unparsed value. retVal.m_Value = MIME_Utils.UnfoldHeader(name_value.Length == 2 ? name_value[1].TrimStart() : ""); } retVal.m_ParseValue = value; return(retVal); }
/// <summary> /// Parses header field from the specified value. /// </summary> /// <param name="value">Header field value. Header field name must be included. For example: 'Content-Type: text/plain'.</param> /// <returns>Returns parsed header field.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>value</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when header field parsing errors.</exception> public static MIME_h_Unstructured Parse(string value) { if (value == null) { throw new ArgumentNullException("value"); } MIME_h_Unstructured retVal = new MIME_h_Unstructured(); string[] name_value = value.Split(new char[] { ':' }, 2); if (name_value[0].Trim() == string.Empty) { throw new ParseException("Invalid header field '" + value + "' syntax."); } retVal.m_Name = name_value[0]; retVal.m_Value = MIME_Encoding_EncodedWord.DecodeS(MIME_Utils.UnfoldHeader(name_value.Length == 2 ? name_value[1].TrimStart() : "")); retVal.m_ParseValue = value; return(retVal); }
/// <summary> /// Parses parameters from the specified reader. /// </summary> /// <param name="reader">MIME reader.</param> /// <exception cref="ArgumentNullException">Is raised when <b>reader</b> is null reference.</exception> public void Parse(MIME_Reader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } /* RFC 2231. * Asterisks ("*") are reused to provide the indicator that language and * character set information is present and encoding is being used. A * single quote ("'") is used to delimit the character set and language * information at the beginning of the parameter value. Percent signs * ("%") are used as the encoding flag, which agrees with RFC 2047. * * Character set and language information may be combined with the * parameter continuation mechanism. For example: * * Content-Type: application/x-stuff * title*0*=us-ascii'en'This%20is%20even%20more%20 * title*1*=%2A%2A%2Afun%2A%2A%2A%20 * title*2="isn't it!" * * Note that: * * (1) Language and character set information only appear at * the beginning of a given parameter value. * * (2) Continuations do not provide a facility for using more * than one character set or language in the same * parameter value. * * (3) A value presented using multiple continuations may * contain a mixture of encoded and unencoded segments. * * (4) The first segment of a continuation MUST be encoded if * language and character set information are given. * * (5) If the first segment of a continued parameter value is * encoded the language and character set field delimiters * MUST be present even when the fields are left blank. */ KeyValueCollection <string, _ParameterBuilder> parameters = new KeyValueCollection <string, _ParameterBuilder>(); // Parse all parameter parts. string[] parameterParts = TextUtils.SplitQuotedString(reader.ToEnd(), ';'); foreach (string part in parameterParts) { if (string.IsNullOrEmpty(part)) { continue; } string[] name_value = part.Trim().Split(new char[] { '=' }, 2); string paramName = name_value[0].Trim(); string paramValue = null; if (name_value.Length == 2) { paramValue = TextUtils.UnQuoteString(MIME_Utils.UnfoldHeader(name_value[1].Trim())); } // Valueless parameter. //else{ string[] nameParts = paramName.Split('*'); int index = 0; bool encoded = nameParts.Length == 3; // Get multi value parameter index. if (nameParts.Length >= 2) { try{ index = Convert.ToInt32(nameParts[1]); } catch { } } // Single value parameter and we already have parameter with such name, skip it. if (nameParts.Length < 2 && parameters.ContainsKey(nameParts[0])) { continue; } // Parameter builder doesn't exist for the specified parameter, create it. if (!parameters.ContainsKey(nameParts[0])) { parameters.Add(nameParts[0], new _ParameterBuilder(nameParts[0])); } parameters[nameParts[0]].AddPart(index, encoded, paramValue); } // Build parameters from parts. foreach (_ParameterBuilder b in parameters) { m_pParameters.Add(b.Name, b.GetParamter()); } m_IsModified = false; }