/// <summary>
        /// Creates a new mime entity to the end of the collection.
        /// </summary>
        /// <returns></returns>
        public MimeEntity Add()
        {
            MimeEntity entity = new MimeEntity();
            Add(entity);

            return entity;
        }
예제 #2
0
        /// <summary>
        /// Parses mime entity from stream.
        /// </summary>
        /// <param name="stream">Data stream from where to read data.</param>
        /// <param name="toBoundary">Entity data is readed to specified boundary.</param>
        /// <returns>Returns false if last entity. Returns true for mulipart entity, if there are more entities.</returns>
        internal bool Parse(SmartStream stream, string toBoundary)
        {
            // Clear header fields
            m_pHeader.Clear();
            m_pHeaderFieldCache.Clear();

            // Parse header
            m_pHeader.Parse(stream);

            // Parse entity and child entities if any (Conent-Type: multipart/xxx...)

            // Multipart entity
            if ((ContentType & MediaType_enum.Multipart) != 0)
            {
                // There must be be boundary ID (rfc 1341 7.2.1  The Content-Type field for multipart entities requires one parameter,
                // "boundary", which is used to specify the encapsulation boundary.)
                string boundaryID = ContentType_Boundary;
                if (boundaryID == null)
                {
                    // This is invalid message, just skip this mime entity
                }
                else
                {
                    // There is one or more mime entities

                    // Find first boundary start position
                    SmartStream.ReadLineAsyncOP args = new SmartStream.ReadLineAsyncOP(new byte[8000],
                                                                                       SizeExceededAction.
                                                                                           JunkAndThrowException);
                    stream.ReadLine(args, false);
                    if (args.Error != null)
                    {
                        throw args.Error;
                    }
                    string lineString = args.LineUtf8;

                    while (lineString != null)
                    {
                        if (lineString.StartsWith("--" + boundaryID))
                        {
                            break;
                        }

                        stream.ReadLine(args, false);
                        if (args.Error != null)
                        {
                            throw args.Error;
                        }
                        lineString = args.LineUtf8;
                    }
                    // This is invalid entity, boundary start not found. Skip that entity.
                    if (string.IsNullOrEmpty(lineString))
                    {
                        return false;
                    }

                    // Start parsing child entities of this entity
                    while (true)
                    {
                        // Parse and add child entity
                        MimeEntity childEntity = new MimeEntity();
                        ChildEntities.Add(childEntity);

                        // This is last entity, stop parsing
                        if (childEntity.Parse(stream, boundaryID) == false)
                        {
                            break;
                        }
                        // else{
                        // There are more entities, parse them
                    }

                    // This entity is child of mulipart entity.
                    // All this entity child entities are parsed,
                    // we need to move stream position to next entity start.
                    if (!string.IsNullOrEmpty(toBoundary))
                    {
                        stream.ReadLine(args, false);
                        if (args.Error != null)
                        {
                            throw args.Error;
                        }
                        lineString = args.LineUtf8;

                        while (lineString != null)
                        {
                            if (lineString.StartsWith("--" + toBoundary))
                            {
                                break;
                            }

                            stream.ReadLine(args, false);
                            if (args.Error != null)
                            {
                                throw args.Error;
                            }
                            lineString = args.LineUtf8;
                        }

                        // Invalid boundary end, there can't be more entities 
                        if (string.IsNullOrEmpty(lineString))
                        {
                            return false;
                        }

                        // See if last boundary or there is more. Last boundary ends with --
                        if (lineString.EndsWith(toBoundary + "--"))
                        {
                            return false;
                        }
                        // else{
                        // There are more entities					
                        return true;
                    }
                }
            }
                // Singlepart entity.
            else
            {
                // Boundary is specified, read data to specified boundary.
                if (!string.IsNullOrEmpty(toBoundary))
                {
                    MemoryStream entityData = new MemoryStream();
                    SmartStream.ReadLineAsyncOP readLineOP = new SmartStream.ReadLineAsyncOP(new byte[Workaround.Definitions.MaxStreamLineLength],
                                                                                             SizeExceededAction
                                                                                                 .
                                                                                                 JunkAndThrowException);

                    // Read entity data while get boundary end tag --boundaryID-- or EOS.
                    while (true)
                    {
                        stream.ReadLine(readLineOP, false);
                        if (readLineOP.Error != null)
                        {
                            throw readLineOP.Error;
                        }
                        // End of stream reached. Normally we should get boundary end tag --boundaryID--, but some x mailers won't add it, so
                        // if we reach EOS, consider boundary closed.
                        if (readLineOP.BytesInBuffer == 0)
                        {
                            // Just return data what was readed.
                            m_EncodedData = entityData.ToArray();
                            return false;
                        }
                            // We readed a line.
                        else
                        {
                            // We have boundary start/end tag or just "--" at the beginning of line.
                            if (readLineOP.LineBytesInBuffer >= 2 && readLineOP.Buffer[0] == '-' &&
                                readLineOP.Buffer[1] == '-')
                            {
                                string lineString = readLineOP.LineUtf8;
                                // We have boundary end tag, no more boundaries.
                                if (lineString == "--" + toBoundary + "--")
                                {
                                    m_EncodedData = entityData.ToArray();
                                    return false;
                                }
                                    // We have new boundary start.
                                else if (lineString == "--" + toBoundary)
                                {
                                    m_EncodedData = entityData.ToArray();
                                    return true;
                                }
                                else
                                {
                                    // Just skip
                                }
                            }

                            // Write readed line.
                            entityData.Write(readLineOP.Buffer, 0, readLineOP.BytesInBuffer);
                        }
                    }
                }
                    // Boundary isn't specified, read data to the stream end. 
                else
                {
                    MemoryStream ms = new MemoryStream();
                    stream.ReadAll(ms);
                    m_EncodedData = ms.ToArray();
                }
            }

            return false;
        }
        /// <summary>
        /// Adds specified mime entity to the end of the collection.
        /// </summary>
        /// <param name="entity">Mime entity to add to the collection.</param>
        public void Add(MimeEntity entity)
        {
            // Allow to add only for multipart/xxx...
            if ((m_pOwnerEntity.ContentType & MediaType_enum.Multipart) == 0)
            {
                throw new Exception(
                    "You don't have Content-Type: multipart/xxx. Only Content-Type: multipart/xxx can have nested mime entities !");
            }
            // Check boundary, this is required parameter for multipart/xx
            if (m_pOwnerEntity.ContentType_Boundary == null || m_pOwnerEntity.ContentType_Boundary.Length == 0)
            {
                throw new Exception("Please specify Boundary property first !");
            }

            m_pEntities.Add(entity);
        }
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="ownerEntity">Mime entity what owns this collection.</param>
        internal MimeEntityCollection(MimeEntity ownerEntity)
        {
            m_pOwnerEntity = ownerEntity;

            m_pEntities = new List<MimeEntity>();
        }
 /// <summary>
 /// Gets if collection contains specified mime entity.
 /// </summary>
 /// <param name="entity">Mime entity.</param>
 /// <returns></returns>
 public bool Contains(MimeEntity entity)
 {
     return m_pEntities.Contains(entity);
 }
 /// <summary>
 /// Removes specified mime entity from the collection.
 /// </summary>
 /// <param name="entity">Mime entity to remove.</param>
 public void Remove(MimeEntity entity)
 {
     m_pEntities.Remove(entity);
 }
예제 #7
0
        /// <summary>
        /// Default constructor.
        /// </summary>
        public Mime()
        {
            m_pMainEntity = new MimeEntity();

            // Add default header fields
            m_pMainEntity.MessageID = MimeUtils.CreateMessageID();
            m_pMainEntity.Date = DateTime.Now;
            m_pMainEntity.MimeVersion = "1.0";
        }