internal static bool TrySplitMimePart(MimePartData<byte[]> part, Encoding encoding, out MultipartMimeData<MimePartData<byte[]>> multipart) { string boundary; if (!part.TryGetMimeBoundary(out boundary)) { multipart = null; return false; } multipart = new MultipartMimeData<MimePartData<byte[]>>(); multipart.Headers.AddRange(part.Headers); var body = part.Body; ExceptionUtilities.CheckObjectNotNull(body, "Body cannot be null"); byte[] boundaryBytes = encoding.GetBytes(boundary); byte[] newlineBytes = encoding.GetBytes("\r\n"); byte[] controlBytes = encoding.GetBytes("--"); while (EndsWithPattern(body, newlineBytes)) { body = body.Take(body.Length - newlineBytes.Length).ToArray(); } byte[] firstBoundaryBytes = controlBytes.Concat(boundaryBytes).Concat(newlineBytes).ToArray(); byte[] innerBoundaryBytes = newlineBytes.Concat(controlBytes).Concat(boundaryBytes).Concat(newlineBytes).ToArray(); byte[] finalBoundaryBytesWithoutFirstNewLine = controlBytes.Concat(boundaryBytes).Concat(controlBytes).ToArray(); byte[] finalBoundaryBytes = newlineBytes.Concat(finalBoundaryBytesWithoutFirstNewLine).ToArray(); int firstBoundaryStart = IndexOfPattern(body, firstBoundaryBytes, 0); if (firstBoundaryStart == -1) { // Possibly an empty changeset - empty multipart can be represented as just the end boundary int finalBoundaryStart = IndexOfPattern(body, finalBoundaryBytesWithoutFirstNewLine, 0); ExceptionUtilities.Assert(finalBoundaryStart == 0, "Malformed"); ExceptionUtilities.Assert(EndsWithPattern(body, finalBoundaryBytesWithoutFirstNewLine), "Malformed"); return true; } ExceptionUtilities.Assert(firstBoundaryStart == 0, "Malformed"); ExceptionUtilities.Assert(EndsWithPattern(body, finalBoundaryBytes), "Malformed"); int currentBoundaryEnd = firstBoundaryStart + firstBoundaryBytes.Length; while (currentBoundaryEnd < body.Length) { int nextBoundaryStart = IndexOfPattern(body, innerBoundaryBytes, currentBoundaryEnd); int nextBoundaryEnd = nextBoundaryStart + innerBoundaryBytes.Length; if (nextBoundaryStart < 0) { nextBoundaryStart = IndexOfPattern(body, finalBoundaryBytes, currentBoundaryEnd); nextBoundaryEnd = nextBoundaryStart + finalBoundaryBytes.Length; ExceptionUtilities.Assert(nextBoundaryStart != 0, "Malformed"); ExceptionUtilities.Assert(nextBoundaryStart + finalBoundaryBytes.Length == body.Length, "Malformed"); } var fragment = body.Skip(currentBoundaryEnd).Take(nextBoundaryStart - currentBoundaryEnd).ToArray(); var subPart = new MimePartData<byte[]>(); if (fragment.Length > 0) { PopulateHeadersAndBody(subPart, fragment, encoding); multipart.Add(subPart); } currentBoundaryEnd = nextBoundaryEnd; } return true; }
internal static bool TrySplitMimePart(MimePartData <byte[]> part, Encoding encoding, out MultipartMimeData <MimePartData <byte[]> > multipart) { string boundary; if (!part.TryGetMimeBoundary(out boundary)) { multipart = null; return(false); } multipart = new MultipartMimeData <MimePartData <byte[]> >(); multipart.Headers.AddRange(part.Headers); var body = part.Body; ExceptionUtilities.CheckObjectNotNull(body, "Body cannot be null"); byte[] boundaryBytes = encoding.GetBytes(boundary); byte[] newlineBytes = encoding.GetBytes("\r\n"); byte[] controlBytes = encoding.GetBytes("--"); while (EndsWithPattern(body, newlineBytes)) { body = body.Take(body.Length - newlineBytes.Length).ToArray(); } byte[] firstBoundaryBytes = controlBytes.Concat(boundaryBytes).Concat(newlineBytes).ToArray(); byte[] innerBoundaryBytes = newlineBytes.Concat(controlBytes).Concat(boundaryBytes).Concat(newlineBytes).ToArray(); byte[] finalBoundaryBytesWithoutFirstNewLine = controlBytes.Concat(boundaryBytes).Concat(controlBytes).ToArray(); byte[] finalBoundaryBytes = newlineBytes.Concat(finalBoundaryBytesWithoutFirstNewLine).ToArray(); int firstBoundaryStart = IndexOfPattern(body, firstBoundaryBytes, 0); if (firstBoundaryStart == -1) { // Possibly an empty changeset - empty multipart can be represented as just the end boundary int finalBoundaryStart = IndexOfPattern(body, finalBoundaryBytesWithoutFirstNewLine, 0); ExceptionUtilities.Assert(finalBoundaryStart == 0, "Malformed"); ExceptionUtilities.Assert(EndsWithPattern(body, finalBoundaryBytesWithoutFirstNewLine), "Malformed"); return(true); } ExceptionUtilities.Assert(firstBoundaryStart == 0, "Malformed"); ExceptionUtilities.Assert(EndsWithPattern(body, finalBoundaryBytes), "Malformed"); int currentBoundaryEnd = firstBoundaryStart + firstBoundaryBytes.Length; while (currentBoundaryEnd < body.Length) { int nextBoundaryStart = IndexOfPattern(body, innerBoundaryBytes, currentBoundaryEnd); int nextBoundaryEnd = nextBoundaryStart + innerBoundaryBytes.Length; if (nextBoundaryStart < 0) { nextBoundaryStart = IndexOfPattern(body, finalBoundaryBytes, currentBoundaryEnd); nextBoundaryEnd = nextBoundaryStart + finalBoundaryBytes.Length; ExceptionUtilities.Assert(nextBoundaryStart != 0, "Malformed"); ExceptionUtilities.Assert(nextBoundaryStart + finalBoundaryBytes.Length == body.Length, "Malformed"); } var fragment = body.Skip(currentBoundaryEnd).Take(nextBoundaryStart - currentBoundaryEnd).ToArray(); var subPart = new MimePartData <byte[]>(); if (fragment.Length > 0) { PopulateHeadersAndBody(subPart, fragment, encoding); multipart.Add(subPart); } currentBoundaryEnd = nextBoundaryEnd; } return(true); }