/// <summary> /// Sets body parent. /// </summary> /// <param name="entity">Owner entity.</param> /// <param name="setContentType">If true sets entity.ContentType header value.</param> internal override void SetParent(MIME_Entity entity, bool setContentType) { base.SetParent(entity, setContentType); // Owner entity has no content-type or has different content-type, just add/overwrite it. if (setContentType && (this.Entity.ContentType == null || !string.Equals(this.Entity.ContentType.TypeWithSubtype, this.MediaType, StringComparison.InvariantCultureIgnoreCase))) { this.Entity.ContentType = m_pContentType; } }
/// <summary> /// Inserts a new MIME entity into the collection at the specified location. /// </summary> /// <param name="index">The location in the collection where you want to add the MIME entity.</param> /// <param name="entity">MIME entity.</param> /// <exception cref="IndexOutOfRangeException">Is raised when <b>index</b> is out of range.</exception> /// <exception cref="ArgumentNullException">Is raised when <b>entity</b> is null reference.</exception> public void Insert(int index, MIME_Entity entity) { if (entity == null) { throw new ArgumentNullException("entity"); } m_pCollection.Insert(index, entity); m_IsModified = true; }
/// <summary> /// Removes specified MIME entity from the collection. /// </summary> /// <param name="entity">MIME entity.</param> /// <exception cref="ArgumentNullException">Is raised when <b>field</b> is null reference.</exception> public void Remove(MIME_Entity entity) { if (entity == null) { throw new ArgumentNullException("field"); } m_pCollection.Remove(entity); m_IsModified = true; }
/// <summary> /// Adds specified MIME enity to the collection. /// </summary> /// <param name="entity">MIME entity.</param> /// <exception cref="ArgumentNullException">Is raised when <b>entity</b> is null reference.</exception> public void Add(MIME_Entity entity) { if (entity == null) { throw new ArgumentNullException("entity"); } m_pCollection.Add(entity); m_IsModified = true; }
/// <summary> /// Cleans up any resources being used. This method is thread-safe. /// </summary> public void Dispose() { lock (this){ if (m_IsDisposed) { return; } m_IsDisposed = true; m_pHeader = null; m_pParent = null; } }
/// <summary> /// Parses body from the specified stream /// </summary> /// <param name="owner">Owner MIME entity.</param> /// <param name="defaultContentType">Default content-type for this body.</param> /// <param name="stream">Stream from where to read body.</param> /// <returns>Returns parsed body.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>stream</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when any parsing errors.</exception> protected static MIME_b Parse(MIME_Entity owner, MIME_h_ContentType defaultContentType, SmartStream stream) { if (owner == null) { throw new ArgumentNullException("owner"); } if (defaultContentType == null) { throw new ArgumentNullException("defaultContentType"); } if (stream == null) { throw new ArgumentNullException("stream"); } throw new NotImplementedException("Body provider class does not implement required Parse method."); }
/// <summary> /// Stores MIME entity body to the specified stream. /// </summary> /// <param name="stream">Stream where to store body data.</param> /// <param name="headerWordEncoder">Header 8-bit words ecnoder. Value null means that words are not encoded.</param> /// <param name="headerParmetersCharset">Charset to use to encode 8-bit header parameters. Value null means parameters not encoded.</param> /// <param name="headerReencode">If true always specified encoding is used for header. If false and header field value not modified, /// original encoding is kept.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception> internal protected override void ToStream(Stream stream, MIME_Encoding_EncodedWord headerWordEncoder, Encoding headerParmetersCharset, bool headerReencode) { if (stream == null) { throw new ArgumentNullException("stream"); } /* RFC 2046 5.1.1. * NOTE: The CRLF preceding the boundary delimiter line is conceptually * attached to the boundary so that it is possible to have a part that * does not end with a CRLF (line break). */ // Set "preamble" text if any. if (!string.IsNullOrEmpty(m_TextPreamble)) { byte[] preableBytes = Encoding.UTF8.GetBytes(m_TextPreamble); stream.Write(preableBytes, 0, preableBytes.Length); } for (int i = 0; i < m_pBodyParts.Count; i++) { MIME_Entity bodyPart = m_pBodyParts[i]; // Start new body part. byte[] bStart = Encoding.UTF8.GetBytes("\r\n--" + this.Entity.ContentType.Param_Boundary + "\r\n"); stream.Write(bStart, 0, bStart.Length); bodyPart.ToStream(stream, headerWordEncoder, headerParmetersCharset, headerReencode); // Last body part, close boundary. if (i == (m_pBodyParts.Count - 1)) { byte[] bEnd = Encoding.UTF8.GetBytes("\r\n--" + this.Entity.ContentType.Param_Boundary + "--\r\n"); stream.Write(bEnd, 0, bEnd.Length); } } // Set "epilogoue" text if any. if (!string.IsNullOrEmpty(m_TextEpilogue)) { byte[] epilogoueBytes = Encoding.UTF8.GetBytes(m_TextEpilogue); stream.Write(epilogoueBytes, 0, epilogoueBytes.Length); } }
/// <summary> /// Parses body from the specified stream /// </summary> /// <param name="owner">Owner MIME entity.</param> /// <param name="defaultContentType">Default content-type for this body.</param> /// <param name="stream">Stream from where to read body.</param> /// <returns>Returns parsed body.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>strean</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when any parsing errors.</exception> protected static new MIME_b Parse(MIME_Entity owner, MIME_h_ContentType defaultContentType, SmartStream stream) { if (owner == null) { throw new ArgumentNullException("owner"); } if (defaultContentType == null) { throw new ArgumentNullException("defaultContentType"); } if (stream == null) { throw new ArgumentNullException("stream"); } MIME_b_ApplicationPkcs7Mime retVal = new MIME_b_ApplicationPkcs7Mime(); Net_Utils.StreamCopy(stream, retVal.EncodedStream, 32000); return(retVal); }
/// <summary> /// Parses body from the specified stream /// </summary> /// <param name="owner">Owner MIME entity.</param> /// <param name="defaultContentType">Default content-type for this body.</param> /// <param name="stream">Stream from where to read body.</param> /// <returns>Returns parsed body.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>stream</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when any parsing errors.</exception> protected static new MIME_b Parse(MIME_Entity owner, MIME_h_ContentType defaultContentType, SmartStream stream) { if (owner == null) { throw new ArgumentNullException("owner"); } if (defaultContentType == null) { throw new ArgumentNullException("defaultContentType"); } if (stream == null) { throw new ArgumentNullException("stream"); } MIME_b_MessageRfc822 retVal = new MIME_b_MessageRfc822(); retVal.m_pMessage = Mail_Message.ParseFromStream(stream); return(retVal); }
/// <summary> /// Parses body from the specified stream /// </summary> /// <param name="owner">Owner MIME entity.</param> /// <param name="defaultContentType">Default content-type for this body.</param> /// <param name="stream">Stream from where to read body.</param> /// <returns>Returns parsed body.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>stream</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when any parsing errors.</exception> protected static new MIME_b Parse(MIME_Entity owner, MIME_h_ContentType defaultContentType, SmartStream stream) { if (owner == null) { throw new ArgumentNullException("owner"); } if (defaultContentType == null) { throw new ArgumentNullException("defaultContentType"); } if (stream == null) { throw new ArgumentNullException("stream"); } // We need to buffer all body data, otherwise we don't know if we have readed all data // from stream. MemoryStream msBuffer = new MemoryStream(); Net_Utils.StreamCopy(stream, msBuffer, 32000); msBuffer.Position = 0; SmartStream parseStream = new SmartStream(msBuffer, true); MIME_b_MessageDeliveryStatus retVal = new MIME_b_MessageDeliveryStatus(); //Pare per-message fields. retVal.m_pMessageFields.Parse(parseStream); // Parse per-recipient fields. while (parseStream.Position - parseStream.BytesInReadBuffer < parseStream.Length) { MIME_h_Collection recipientFields = new MIME_h_Collection(new MIME_h_Provider()); recipientFields.Parse(parseStream); retVal.m_pRecipientBlocks.Add(recipientFields); } return(retVal); }
/// <summary> /// Internal body parsing. /// </summary> /// <param name="owner">Owner MIME entity.</param> /// <param name="mediaType">MIME media type. For example: text/plain.</param> /// <param name="stream">Stream from where to read body.</param> /// <param name="body">Multipart body instance.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>mediaType</b>, <b>stream</b> or <b>body</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when any parsing errors.</exception> protected static void ParseInternal(MIME_Entity owner, string mediaType, SmartStream stream, MIME_b_Multipart body) { if (owner == null) { throw new ArgumentNullException("owner"); } if (mediaType == null) { throw new ArgumentNullException("mediaType"); } if (stream == null) { throw new ArgumentNullException("stream"); } if (owner.ContentType == null || owner.ContentType.Param_Boundary == null) { throw new ParseException("Multipart entity has not required 'boundary' parameter."); } if (body == null) { throw new ArgumentNullException("body"); } _MultipartReader multipartReader = new _MultipartReader(stream, owner.ContentType.Param_Boundary); while (multipartReader.Next()) { MIME_Entity entity = new MIME_Entity(); entity.Parse(new SmartStream(multipartReader, false), Encoding.UTF8, body.DefaultBodyPartContentType); body.m_pBodyParts.Add(entity); entity.SetParent(owner); } body.m_TextPreamble = multipartReader.TextPreamble; body.m_TextEpilogue = multipartReader.TextEpilogue; body.BodyParts.SetModified(false); }
/// <summary> /// Gets all MIME entities as list. /// </summary> /// <param name="includeEmbbedMessage">If true, then embbed RFC822 message child entities are included.</param> /// <returns>Returns all MIME entities as list.</returns> /// <exception cref="ObjectDisposedException">Is raised when this class is disposed and this method is accessed.</exception> public MIME_Entity[] GetAllEntities(bool includeEmbbedMessage) { if (m_IsDisposed) { throw new ObjectDisposedException(this.GetType().Name); } List <MIME_Entity> retVal = new List <MIME_Entity>(); List <MIME_Entity> entitiesQueue = new List <MIME_Entity>(); entitiesQueue.Add(this); while (entitiesQueue.Count > 0) { MIME_Entity currentEntity = entitiesQueue[0]; entitiesQueue.RemoveAt(0); retVal.Add(currentEntity); // Current entity is multipart entity, add it's body-parts for processing. if (this.Body != null && currentEntity.Body.GetType().IsSubclassOf(typeof(MIME_b_Multipart))) { MIME_EntityCollection bodyParts = ((MIME_b_Multipart)currentEntity.Body).BodyParts; for (int i = 0; i < bodyParts.Count; i++) { entitiesQueue.Insert(i, bodyParts[i]); } } // Add embbed message for processing (Embbed message entities will be included). else if (includeEmbbedMessage && this.Body != null && currentEntity.Body is MIME_b_MessageRfc822) { entitiesQueue.Add(((MIME_b_MessageRfc822)currentEntity.Body).Message); } } return(retVal.ToArray()); }
/// <summary> /// Parses MIME entity body from specified stream. /// </summary> /// <param name="owner">Owner MIME entity.</param> /// <param name="stream">Stream from where to parse entity body.</param> /// <param name="defaultContentType">Default content type.</param> /// <returns>Returns parsed body.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>owner</b>, <b>strean</b> or <b>defaultContentType</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when header field parsing errors.</exception> public MIME_b Parse(MIME_Entity owner, SmartStream stream, MIME_h_ContentType defaultContentType) { if (owner == null) { throw new ArgumentNullException("owner"); } if (stream == null) { throw new ArgumentNullException("stream"); } if (defaultContentType == null) { throw new ArgumentNullException("defaultContentType"); } string mediaType = defaultContentType.TypeWithSubtype; try{ if (owner.ContentType != null) { mediaType = owner.ContentType.TypeWithSubtype; } } catch { // Do nothing, content will be MIME_b_Unknown. mediaType = "unknown/unknown"; } Type bodyType = null; // We have exact body provider for specified mediaType. if (m_pBodyTypes.ContainsKey(mediaType)) { bodyType = m_pBodyTypes[mediaType]; } // Use default mediaType. else { // Registered list of mediaTypes are available: http://www.iana.org/assignments/media-types/. string mediaRootType = mediaType.Split('/')[0].ToLowerInvariant(); if (mediaRootType == "application") { bodyType = typeof(MIME_b_Application); } else if (mediaRootType == "audio") { bodyType = typeof(MIME_b_Audio); } else if (mediaRootType == "image") { bodyType = typeof(MIME_b_Image); } else if (mediaRootType == "message") { bodyType = typeof(MIME_b_Message); } else if (mediaRootType == "multipart") { bodyType = typeof(MIME_b_Multipart); } else if (mediaRootType == "text") { bodyType = typeof(MIME_b_Text); } else if (mediaRootType == "video") { bodyType = typeof(MIME_b_Video); } else { bodyType = typeof(MIME_b_Unknown); } } return((MIME_b)bodyType.GetMethod("Parse", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy).Invoke(null, new object[] { owner, defaultContentType, stream })); }
/// <summary> /// Sets MIME entity parent entity. /// </summary> /// <param name="parent">Parent entity.</param> internal void SetParent(MIME_Entity parent) { m_pParent = parent; }