Ejemplo n.º 1
0
        /// <summary>
        /// Parses set of <see cref="StringSegment"/> supplying the individual lines of a <c>multipart</c> body, returning contituent parts.
        /// </summary>
        /// <param name="bodyLines">The <c>multipart</c> body lines</param>
        /// <param name="boundary">The <c>multipart</c> boundary string</param>
        /// <returns>The constituent body parts.</returns>

        public static IEnumerable <MimePart> ReadBodyParts(IEnumerable <StringSegment> bodyLines, string boundary)
        {
            if (bodyLines == null)
            {
                throw new ArgumentNullException("bodyLines");
            }

            if (string.IsNullOrEmpty(boundary))
            {
                throw new MimeException(MimeError.MissingBoundarySeparator);
            }

            IEnumerator <StringSegment> lineEnumerator = bodyLines.GetEnumerator();
            StringSegment part         = StringSegment.Null;
            StringSegment prevLine     = StringSegment.Null;
            MimePartType  expectedPart = MimePartType.BodyPrologue;

            //
            // As per the Multipart Spec:
            //  The boundary delimiter is actually CRLF--boundary
            // So we must maintain a stack (prevLine)..
            //
            while (expectedPart != MimePartType.BodyEpilogue && lineEnumerator.MoveNext())
            {
                StringSegment line = lineEnumerator.Current;
                if (IsBoundary(line, boundary))
                {
                    if (!part.IsNull)
                    {
                        part.Union(prevLine);
                    }
                    //
                    // When we hit a boundary, we yield the part we've collected so far
                    //
                    MimePartType partType = expectedPart;
                    switch (expectedPart)
                    {
                    default:
                        throw new MimeException(MimeError.InvalidBodySubpart);

                    case MimePartType.BodyPrologue:
                        expectedPart = MimePartType.BodyPart;
                        break;

                    case MimePartType.BodyPart:
                        if (IsBoundaryEnd(line))
                        {
                            expectedPart = MimePartType.BodyEpilogue;
                        }
                        break;
                    }

                    if (!part.IsNull)
                    {
                        yield return(new MimePart(partType, part));
                    }

                    prevLine = StringSegment.Null;
                    part     = StringSegment.Null;
                }
                else
                {
                    if (!prevLine.IsNull)
                    {
                        part.Union(prevLine);
                    }

                    prevLine = line;
                }
            }

            if (expectedPart != MimePartType.BodyEpilogue)
            {
                throw new MimeException(MimeError.InvalidBodySubpart);
            }

            // Epilogue
            part = StringSegment.Null;
            while (lineEnumerator.MoveNext())
            {
                part.Union(lineEnumerator.Current);
            }
            if (!part.IsEmpty)
            {
                yield return(new MimePart(MimePartType.BodyEpilogue, part));
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Expands the source segment for this entity
 /// </summary>
 internal virtual void AppendSourceText(StringSegment segment)
 {
     m_sourceText.Union(segment);
 }