public MimePart(MimeFields fields, byte[] content)
        {
            if (fields is null)
            {
                throw new ArgumentNullException(nameof(fields));
            }
            if (content is null)
            {
                throw new ArgumentNullException(nameof(content));
            }

            _fields        = fields;
            _content       = content;
            _contentLength = content.Length;
        }
        public MimeFields      ReadFields()
        {
            bool       xheader = true;
            MimeFields fields  = new MimeFields();

            while (ReadLine(true) && _curLength > 0)
            {
                int i = _curLineIndexOf(':');
                if (i < 0)
                {
                    throw new MimeException("Syntax error in field ':' not found).");
                }

                if (i < _curLength - 1 && _curLine[i + 1] != ' ')
                {
                    throw new MimeException("Syntax error in field ': ' not found).");
                }

                string Name  = _curLineToString(0, i);
                string Value = _curLineToString(i + 2, _curLength - (i + 2));

                if (xheader)
                {
                    if (Name.StartsWith("x-", StringComparison.Ordinal))
                    {
                        _positionBeginMessage = _position;
                    }
                    else
                    {
                        xheader = false;
                    }
                }

                fields.Add(new MimeField(Name, Value, true));
            }

            return(fields);
        }
        protected void                MimeParse(string mimeValue, bool readOnly)
        {
            int Position = 0;

            if (mimeValue is null)
            {
                if (readOnly)
                {
                    throw new ArgumentNullException(nameof(mimeValue));
                }

                return;
            }

            try {
                MimeLexicalToken typeToken;
                MimeLexicalToken sepToken;
                MimeLexicalToken nameToken;
                MimeLexicalToken valueToken;

                typeToken = MimeLexicalToken.Parse(mimeValue, ref Position);

                if (typeToken.Type != MimeLexicalTokenType.Atom)
                {
                    throw new Exception("invalid type");
                }

                _type = typeToken.GetString(mimeValue);

                while ((sepToken = MimeLexicalToken.ParseSkipWhiteSpaceComment(mimeValue, ref Position)).Type == MimeLexicalTokenType.SemiColon)
                {
                    nameToken = MimeLexicalToken.ParseSkipWhiteSpaceComment(mimeValue, ref Position);
                    if (nameToken.Type != MimeLexicalTokenType.Atom)
                    {
                        throw new Exception("invalid paramater name.");
                    }

                    if (MimeLexicalToken.ParseSkipWhiteSpaceComment(mimeValue, ref Position).Type != MimeLexicalTokenType.Assign)
                    {
                        throw new Exception("invalid paramater name.");
                    }

                    valueToken = MimeLexicalToken.ParseSkipWhiteSpaceComment(mimeValue, ref Position);
                    if (valueToken.Type != MimeLexicalTokenType.Atom && valueToken.Type != MimeLexicalTokenType.QuotedString)
                    {
                        throw new Exception("invalid paramater value.");
                    }

                    if (_parameters == null)
                    {
                        _parameters = new MimeFields();
                    }

                    _parameters.Add(new MimeField(nameToken.GetString(mimeValue), valueToken.GetString(mimeValue)));
                }

                if (sepToken.Type != MimeLexicalTokenType.EOL)
                {
                    throw new Exception("extra data.");
                }

                if (readOnly)
                {
                    _readOnly = true;

                    if (_parameters != null)
                    {
                        _parameters.SetCollectionReadOnly();
                    }
                }
            }
            catch (Exception Err) {
                throw new MimeException("Invalid mime field value '" + mimeValue + "'," + Err.Message);
            }
        }
 protected void                    SetFields(MimeFields fields)
 {
     _fields = fields;
 }
 public MimePart()
 {
     _fields  = new MimeFields();
     _content = null;
 }
        protected void                ParseMultiPart(MimeContentType contentType, MimeReader reader, StringWriter bodyWriter)
        {
            if (contentType is null)
            {
                throw new ArgumentNullException(nameof(contentType));
            }
            if (reader is null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            _parts = new MimeParts();

            string Boundary = contentType.Boundary;

            if (Boundary == null)
            {
                throw new MimeException("Invalid multipart-mime-message, missing 'Boundary'.");
            }

            while (true)
            {
                if (!reader.ReadLine(false))
                {
                    throw new MimeException("Invalid multipart-mime-message, missing begin-boundary.");
                }

                if (reader.TestBoundary(Boundary) == 1)
                {
                    break;
                }

                if (bodyWriter != null)
                {
                    reader.WriteLineTo(bodyWriter);
                }
            }

            while (reader.TestBoundary(Boundary) != -1)
            {
                if (reader.TestBoundary(Boundary) == 1)
                {
                    MimeFields      PartFields = reader.ReadFields();
                    MimeField       FldContentTransferEncoding = PartFields["Content-Transfer-Encoding"];
                    byte[]          PartContent        = reader.ReadData(MimePart.StringToMimeEncoding(FldContentTransferEncoding?.Value), Boundary);
                    MimeField       FldPartContentType = PartFields["Content-Type"];
                    MimeContentType PartContentType    = FldPartContentType?.ValueContentType;

                    if (PartContentType != null && PartContentType.isMultipart)
                    {
                        _parts.Add(new MimeMultiPart(PartContentType, PartFields, PartContent));
                    }
                    else
                    {
                        _parts.Add(new MimePart(PartFields, PartContent));
                    }

                    PartFields.SetCollectionReadOnly();
                }
                else
                {
                    if (!reader.isLineEmpty)
                    {
                        throw new MimeException("Invalid multipart-mime-message, garbage in between parts.");
                    }

                    if (!reader.ReadLine(false))
                    {
                        throw new MimeException("Invalid multipart-mime-message, missing end-boundary.");
                    }
                }
            }


            _parts.SetCollectionReadOnly();
        }
 protected MimeMultiPart(MimeContentType contentType, MimeFields fields, byte[] content) : base(fields, content)
 {
     ParseMultiPart(contentType, new MimeReader(new MemoryStream(content)), null);
 }