Exemplo n.º 1
0
  String getScriptText(Charset[] charsetGuess) {
    if (getHunks().isEmpty()) {
      // If we have no hunks then we can safely assume the entire
      // patch is a binary style patch, or a meta-data only style
      // patch. Either way the encoding of the headers should be
      // strictly 7-bit US-ASCII and the body is either 7-bit ASCII
      // (due to the base 85 encoding used for a BinaryHunk) or is
      // arbitrary noise we have chosen to ignore and not understand
      // (e.g. the message "Binary files ... differ").
      //
      return extractBinaryString(buf, startOffset, endOffset);
    }

    if (charsetGuess != null && charsetGuess.length != getParentCount() + 1)
      throw new IllegalArgumentException(
          MessageFormat.format(
              JGitText.get().expectedCharacterEncodingGuesses,
              Integer.valueOf(getParentCount() + 1)));

    if (trySimpleConversion(charsetGuess)) {
      Charset cs = charsetGuess != null ? charsetGuess[0] : null;
      if (cs == null) cs = Constants.CHARSET;
      try {
        return decodeNoFallback(cs, buf, startOffset, endOffset);
      } catch (CharacterCodingException cee) {
        // Try the much slower, more-memory intensive version which
        // can handle a character set conversion patch.
      }
    }

    final StringBuilder r = new StringBuilder(endOffset - startOffset);

    // Always treat the headers as US-ASCII; Git file names are encoded
    // in a C style escape if any character has the high-bit set.
    //
    final int hdrEnd = getHunks().get(0).getStartOffset();
    for (int ptr = startOffset; ptr < hdrEnd; ) {
      final int eol = Math.min(hdrEnd, nextLF(buf, ptr));
      r.append(extractBinaryString(buf, ptr, eol));
      ptr = eol;
    }

    final String[] files = extractFileLines(charsetGuess);
    final int[] offsets = new int[files.length];
    for (final HunkHeader h : getHunks()) h.extractFileLines(r, files, offsets);
    return r.toString();
  }
Exemplo n.º 2
0
  private String[] extractFileLines(final Charset[] csGuess) {
    final TemporaryBuffer[] tmp = new TemporaryBuffer[getParentCount() + 1];
    try {
      for (int i = 0; i < tmp.length; i++) tmp[i] = new TemporaryBuffer.LocalFile();
      for (final HunkHeader h : getHunks()) h.extractFileLines(tmp);

      final String[] r = new String[tmp.length];
      for (int i = 0; i < tmp.length; i++) {
        Charset cs = csGuess != null ? csGuess[i] : null;
        if (cs == null) cs = Constants.CHARSET;
        r[i] = RawParseUtils.decode(cs, tmp[i].toByteArray());
      }
      return r;
    } catch (IOException ioe) {
      throw new RuntimeException(JGitText.get().cannotConvertScriptToText, ioe);
    } finally {
      for (final TemporaryBuffer b : tmp) {
        if (b != null) b.destroy();
      }
    }
  }
Exemplo n.º 3
0
  private int parseHunks(final FileHeader fh, int c, final int end) {
    final 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 (match(buf, c, DIFF_GIT) >= 0) break;
      if (match(buf, c, DIFF_CC) >= 0) break;
      if (match(buf, c, DIFF_COMBINED) >= 0) break;
      if (match(buf, c, OLD_NAME) >= 0) break;
      if (match(buf, c, NEW_NAME) >= 0) break;

      if (isHunkHdr(buf, c, end) == fh.getParentCount()) {
        final 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 '@':
            case 'd':
            case '\n':
              break;
            default:
              if (match(buf, c, SIG_FOOTER) < 0) warn(buf, c, JGitText.get().unexpectedHunkTrailer);
          }
        }
        continue;
      }

      final int eol = nextLF(buf, c);
      if (fh.getHunks().isEmpty() && match(buf, c, GIT_BINARY) >= 0) {
        fh.patchType = FileHeader.PatchType.GIT_BINARY;
        return parseGitBinary(fh, eol, end);
      }

      if (fh.getHunks().isEmpty()
          && BIN_TRAILER.length < eol - c
          && match(buf, eol - BIN_TRAILER.length, BIN_TRAILER) >= 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;
  }
Exemplo n.º 4
0
 /** @return a list describing the content edits performed on this file. */
 public EditList toEditList() {
   final EditList r = new EditList();
   for (final HunkHeader hunk : hunks) r.addAll(hunk.toEditList());
   return r;
 }
Exemplo n.º 5
0
 void addHunk(final HunkHeader h) {
   if (h.getFileHeader() != this)
     throw new IllegalArgumentException(JGitText.get().hunkBelongsToAnotherFile);
   if (hunks == null) hunks = new ArrayList<HunkHeader>();
   hunks.add(h);
 }