Example #1
0
        /// <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;
        }
Example #2
0
        /// <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);
        }
Example #3
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";
        }
Example #4
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((this.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 = this.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();
                        this.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[32000],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;
        }
Example #5
0
        /// <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>();
        }
Example #6
0
 /// <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);
 }
Example #7
0
 /// <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);
 }