BinaryHunk.java

  1. /*
  2.  * Copyright (C) 2008, Google Inc.
  3.  * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com> and others
  4.  *
  5.  * This program and the accompanying materials are made available under the
  6.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  7.  * https://www.eclipse.org/org/documents/edl-v10.php.
  8.  *
  9.  * SPDX-License-Identifier: BSD-3-Clause
  10.  */

  11. package org.eclipse.jgit.patch;

  12. import static org.eclipse.jgit.lib.Constants.encodeASCII;
  13. import static org.eclipse.jgit.util.RawParseUtils.match;
  14. import static org.eclipse.jgit.util.RawParseUtils.nextLF;
  15. import static org.eclipse.jgit.util.RawParseUtils.parseBase10;

  16. /**
  17.  * Part of a "GIT binary patch" to describe the pre-image or post-image
  18.  */
  19. public class BinaryHunk {
  20.     private static final byte[] LITERAL = encodeASCII("literal "); //$NON-NLS-1$

  21.     private static final byte[] DELTA = encodeASCII("delta "); //$NON-NLS-1$

  22.     /** Type of information stored in a binary hunk. */
  23.     public enum Type {
  24.         /** The full content is stored, deflated. */
  25.         LITERAL_DEFLATED,

  26.         /** A Git pack-style delta is stored, deflated. */
  27.         DELTA_DEFLATED;
  28.     }

  29.     private final FileHeader file;

  30.     /** Offset within {@link #file}.buf to the "literal" or "delta " line. */
  31.     final int startOffset;

  32.     /** Position 1 past the end of this hunk within {@link #file}'s buf. */
  33.     int endOffset;

  34.     /** Type of the data meaning. */
  35.     private Type type;

  36.     /** Inflated length of the data. */
  37.     private int length;

  38.     BinaryHunk(FileHeader fh, int offset) {
  39.         file = fh;
  40.         startOffset = offset;
  41.     }

  42.     /**
  43.      * Get header for the file this hunk applies to.
  44.      *
  45.      * @return header for the file this hunk applies to.
  46.      */
  47.     public FileHeader getFileHeader() {
  48.         return file;
  49.     }

  50.     /**
  51.      * Get the byte array holding this hunk's patch script.
  52.      *
  53.      * @return the byte array holding this hunk's patch script.
  54.      */
  55.     public byte[] getBuffer() {
  56.         return file.buf;
  57.     }

  58.     /**
  59.      * Get offset the start of this hunk in {@link #getBuffer()}.
  60.      *
  61.      * @return offset the start of this hunk in {@link #getBuffer()}.
  62.      */
  63.     public int getStartOffset() {
  64.         return startOffset;
  65.     }

  66.     /**
  67.      * Get offset one past the end of the hunk in {@link #getBuffer()}.
  68.      *
  69.      * @return offset one past the end of the hunk in {@link #getBuffer()}.
  70.      */
  71.     public int getEndOffset() {
  72.         return endOffset;
  73.     }

  74.     /**
  75.      * Get type of this binary hunk.
  76.      *
  77.      * @return type of this binary hunk.
  78.      */
  79.     public Type getType() {
  80.         return type;
  81.     }

  82.     /**
  83.      * Get inflated size of this hunk's data.
  84.      *
  85.      * @return inflated size of this hunk's data.
  86.      */
  87.     public int getSize() {
  88.         return length;
  89.     }

  90.     int parseHunk(int ptr, int end) {
  91.         final byte[] buf = file.buf;

  92.         if (match(buf, ptr, LITERAL) >= 0) {
  93.             type = Type.LITERAL_DEFLATED;
  94.             length = parseBase10(buf, ptr + LITERAL.length, null);

  95.         } else if (match(buf, ptr, DELTA) >= 0) {
  96.             type = Type.DELTA_DEFLATED;
  97.             length = parseBase10(buf, ptr + DELTA.length, null);

  98.         } else {
  99.             // Not a valid binary hunk. Signal to the caller that
  100.             // we cannot parse any further and that this line should
  101.             // be treated otherwise.
  102.             //
  103.             return -1;
  104.         }
  105.         ptr = nextLF(buf, ptr);

  106.         // Skip until the first blank line; that is the end of the binary
  107.         // encoded information in this hunk. To save time we don't do a
  108.         // validation of the binary data at this point.
  109.         //
  110.         while (ptr < end) {
  111.             final boolean empty = buf[ptr] == '\n';
  112.             ptr = nextLF(buf, ptr);
  113.             if (empty)
  114.                 break;
  115.         }

  116.         return ptr;
  117.     }
  118. }