private int ParseHunks(FileHeader fh, int c, int end) { byte[] buf = fh.buf; while (c < end) { // If we see a file header at this point, we have all of the // hunks for our current file. We should stop and report back // with this position so it can be parsed again later. // if (RawParseUtils.Match(buf, c, DIFF_GIT) >= 0) { break; } if (RawParseUtils.Match(buf, c, DIFF_CC) >= 0) { break; } if (RawParseUtils.Match(buf, c, DIFF_COMBINED) >= 0) { break; } if (RawParseUtils.Match(buf, c, FileHeader.OLD_NAME) >= 0) { break; } if (RawParseUtils.Match(buf, c, FileHeader.NEW_NAME) >= 0) { break; } if (FileHeader.IsHunkHdr(buf, c, end) == fh.GetParentCount()) { HunkHeader h = fh.NewHunkHeader(c); h.ParseHeader(); c = h.ParseBody(this, end); h.endOffset = c; fh.AddHunk(h); if (c < end) { switch (buf[c]) { case (byte)('@'): case (byte)('d'): case (byte)('\n'): { break; } default: { if (RawParseUtils.Match(buf, c, SIG_FOOTER) < 0 && RawParseUtils.Match(buf, c, SIG_FOOTER_WINDOWS) < 0) { Warn(buf, c, JGitText.Get().unexpectedHunkTrailer); } break; } } } continue; } int eol = RawParseUtils.NextLF(buf, c); if (fh.GetHunks().IsEmpty() && (RawParseUtils.Match(buf, c, GIT_BINARY) >= 0 || RawParseUtils.Match(buf, c, GIT_BINARY_WINDOWS) >= 0)) { fh.patchType = FileHeader.PatchType.GIT_BINARY; return(ParseGitBinary(fh, eol, end)); } if (fh.GetHunks().IsEmpty() && ((BIN_TRAILER.Length < eol - c && RawParseUtils.Match(buf, eol - BIN_TRAILER.Length, BIN_TRAILER) >= 0) || (BIN_TRAILER_WINDOWS.Length < eol - c && RawParseUtils.Match(buf, eol - BIN_TRAILER_WINDOWS.Length, BIN_TRAILER_WINDOWS) >= 0)) && MatchAny(buf, c, BIN_HEADERS )) { // The patch is a binary file diff, with no deltas. // fh.patchType = FileHeader.PatchType.BINARY; return(eol); } // Skip this line and move to the next. Its probably garbage // after the last hunk of a file. // c = eol; } if (fh.GetHunks().IsEmpty() && fh.GetPatchType() == FileHeader.PatchType.UNIFIED && !fh.HasMetaDataChanges()) { // Hmm, an empty patch? If there is no metadata here we // really have a binary patch that we didn't notice above. // fh.patchType = FileHeader.PatchType.BINARY; } return(c); }
private int ParseFile(byte[] buf, int c, int end) { while (c < end) { if (FileHeader.IsHunkHdr(buf, c, end) >= 1) { // If we find a disconnected hunk header we might // have missed a file header previously. The hunk // isn't valid without knowing where it comes from. // Error(buf, c, JGitText.Get().hunkDisconnectedFromFile); c = RawParseUtils.NextLF(buf, c); continue; } // Valid git style patch? // if (RawParseUtils.Match(buf, c, DIFF_GIT) >= 0) { return(ParseDiffGit(buf, c, end)); } if (RawParseUtils.Match(buf, c, DIFF_CC) >= 0) { return(ParseDiffCombined(DIFF_CC, buf, c, end)); } if (RawParseUtils.Match(buf, c, DIFF_COMBINED) >= 0) { return(ParseDiffCombined(DIFF_COMBINED, buf, c, end)); } // Junk between files? Leading junk? Traditional // (non-git generated) patch? // int n = RawParseUtils.NextLF(buf, c); if (n >= end) { // Patches cannot be only one line long. This must be // trailing junk that we should ignore. // return(end); } if (n - c < 6) { // A valid header must be at least 6 bytes on the // first line, e.g. "--- a/b\n". // c = n; continue; } if (RawParseUtils.Match(buf, c, FileHeader.OLD_NAME) >= 0 && RawParseUtils.Match( buf, n, FileHeader.NEW_NAME) >= 0) { // Probably a traditional patch. Ensure we have at least // a "@@ -0,0" smelling line next. We only check the "@@ -". // int f = RawParseUtils.NextLF(buf, n); if (f >= end) { return(end); } if (FileHeader.IsHunkHdr(buf, f, end) == 1) { return(ParseTraditionalPatch(buf, c, end)); } } c = n; } return(c); }