LongObjectId.java

  1. /*
  2.  * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com> and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */

  10. package org.eclipse.jgit.lfs.lib;

  11. import java.io.IOException;
  12. import java.io.ObjectInputStream;
  13. import java.io.ObjectOutputStream;
  14. import java.io.Serializable;

  15. import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException;
  16. import org.eclipse.jgit.util.NB;
  17. import org.eclipse.jgit.util.RawParseUtils;

  18. /**
  19.  * A SHA-256 abstraction.
  20.  *
  21.  * Ported to SHA-256 from {@link org.eclipse.jgit.lib.ObjectId}
  22.  *
  23.  * @since 4.3
  24.  */
  25. public class LongObjectId extends AnyLongObjectId implements Serializable {
  26.     private static final long serialVersionUID = 1L;

  27.     private static final LongObjectId ZEROID;

  28.     private static final String ZEROID_STR;

  29.     static {
  30.         ZEROID = new LongObjectId(0L, 0L, 0L, 0L);
  31.         ZEROID_STR = ZEROID.name();
  32.     }

  33.     /**
  34.      * Get the special all-zero LongObjectId.
  35.      *
  36.      * @return the all-zero LongObjectId, often used to stand-in for no object.
  37.      */
  38.     public static final LongObjectId zeroId() {
  39.         return ZEROID;
  40.     }

  41.     /**
  42.      * Test a string of characters to verify that it can be interpreted as
  43.      * LongObjectId.
  44.      * <p>
  45.      * If true the string can be parsed with {@link #fromString(String)}.
  46.      *
  47.      * @param id
  48.      *            the string to test.
  49.      * @return true if the string can converted into an LongObjectId.
  50.      */
  51.     public static final boolean isId(String id) {
  52.         if (id.length() != Constants.LONG_OBJECT_ID_STRING_LENGTH)
  53.             return false;
  54.         try {
  55.             for (int i = 0; i < Constants.LONG_OBJECT_ID_STRING_LENGTH; i++) {
  56.                 RawParseUtils.parseHexInt4((byte) id.charAt(i));
  57.             }
  58.             return true;
  59.         } catch (ArrayIndexOutOfBoundsException e) {
  60.             return false;
  61.         }
  62.     }

  63.     /**
  64.      * Convert a LongObjectId into a hex string representation.
  65.      *
  66.      * @param i
  67.      *            the id to convert. May be null.
  68.      * @return the hex string conversion of this id's content.
  69.      */
  70.     public static final String toString(LongObjectId i) {
  71.         return i != null ? i.name() : ZEROID_STR;
  72.     }

  73.     /**
  74.      * Compare two object identifier byte sequences for equality.
  75.      *
  76.      * @param firstBuffer
  77.      *            the first buffer to compare against. Must have at least 32
  78.      *            bytes from position fi through the end of the buffer.
  79.      * @param fi
  80.      *            first offset within firstBuffer to begin testing.
  81.      * @param secondBuffer
  82.      *            the second buffer to compare against. Must have at least 32
  83.      *            bytes from position si through the end of the buffer.
  84.      * @param si
  85.      *            first offset within secondBuffer to begin testing.
  86.      * @return true if the two identifiers are the same.
  87.      */
  88.     public static boolean equals(final byte[] firstBuffer, final int fi,
  89.             final byte[] secondBuffer, final int si) {
  90.         return firstBuffer[fi] == secondBuffer[si]
  91.                 && firstBuffer[fi + 1] == secondBuffer[si + 1]
  92.                 && firstBuffer[fi + 2] == secondBuffer[si + 2]
  93.                 && firstBuffer[fi + 3] == secondBuffer[si + 3]
  94.                 && firstBuffer[fi + 4] == secondBuffer[si + 4]
  95.                 && firstBuffer[fi + 5] == secondBuffer[si + 5]
  96.                 && firstBuffer[fi + 6] == secondBuffer[si + 6]
  97.                 && firstBuffer[fi + 7] == secondBuffer[si + 7]
  98.                 && firstBuffer[fi + 8] == secondBuffer[si + 8]
  99.                 && firstBuffer[fi + 9] == secondBuffer[si + 9]
  100.                 && firstBuffer[fi + 10] == secondBuffer[si + 10]
  101.                 && firstBuffer[fi + 11] == secondBuffer[si + 11]
  102.                 && firstBuffer[fi + 12] == secondBuffer[si + 12]
  103.                 && firstBuffer[fi + 13] == secondBuffer[si + 13]
  104.                 && firstBuffer[fi + 14] == secondBuffer[si + 14]
  105.                 && firstBuffer[fi + 15] == secondBuffer[si + 15]
  106.                 && firstBuffer[fi + 16] == secondBuffer[si + 16]
  107.                 && firstBuffer[fi + 17] == secondBuffer[si + 17]
  108.                 && firstBuffer[fi + 18] == secondBuffer[si + 18]
  109.                 && firstBuffer[fi + 19] == secondBuffer[si + 19]
  110.                 && firstBuffer[fi + 20] == secondBuffer[si + 20]
  111.                 && firstBuffer[fi + 21] == secondBuffer[si + 21]
  112.                 && firstBuffer[fi + 22] == secondBuffer[si + 22]
  113.                 && firstBuffer[fi + 23] == secondBuffer[si + 23]
  114.                 && firstBuffer[fi + 24] == secondBuffer[si + 24]
  115.                 && firstBuffer[fi + 25] == secondBuffer[si + 25]
  116.                 && firstBuffer[fi + 26] == secondBuffer[si + 26]
  117.                 && firstBuffer[fi + 27] == secondBuffer[si + 27]
  118.                 && firstBuffer[fi + 28] == secondBuffer[si + 28]
  119.                 && firstBuffer[fi + 29] == secondBuffer[si + 29]
  120.                 && firstBuffer[fi + 30] == secondBuffer[si + 30]
  121.                 && firstBuffer[fi + 31] == secondBuffer[si + 31];
  122.     }

  123.     /**
  124.      * Convert a LongObjectId from raw binary representation.
  125.      *
  126.      * @param bs
  127.      *            the raw byte buffer to read from. At least 32 bytes must be
  128.      *            available within this byte array.
  129.      * @return the converted object id.
  130.      */
  131.     public static final LongObjectId fromRaw(byte[] bs) {
  132.         return fromRaw(bs, 0);
  133.     }

  134.     /**
  135.      * Convert a LongObjectId from raw binary representation.
  136.      *
  137.      * @param bs
  138.      *            the raw byte buffer to read from. At least 32 bytes after p
  139.      *            must be available within this byte array.
  140.      * @param p
  141.      *            position to read the first byte of data from.
  142.      * @return the converted object id.
  143.      */
  144.     public static final LongObjectId fromRaw(byte[] bs, int p) {
  145.         final long a = NB.decodeInt64(bs, p);
  146.         final long b = NB.decodeInt64(bs, p + 8);
  147.         final long c = NB.decodeInt64(bs, p + 16);
  148.         final long d = NB.decodeInt64(bs, p + 24);
  149.         return new LongObjectId(a, b, c, d);
  150.     }

  151.     /**
  152.      * Convert a LongObjectId from raw binary representation.
  153.      *
  154.      * @param is
  155.      *            the raw long buffer to read from. At least 4 longs must be
  156.      *            available within this long array.
  157.      * @return the converted object id.
  158.      */
  159.     public static final LongObjectId fromRaw(long[] is) {
  160.         return fromRaw(is, 0);
  161.     }

  162.     /**
  163.      * Convert a LongObjectId from raw binary representation.
  164.      *
  165.      * @param is
  166.      *            the raw long buffer to read from. At least 4 longs after p
  167.      *            must be available within this long array.
  168.      * @param p
  169.      *            position to read the first long of data from.
  170.      * @return the converted object id.
  171.      */
  172.     public static final LongObjectId fromRaw(long[] is, int p) {
  173.         return new LongObjectId(is[p], is[p + 1], is[p + 2], is[p + 3]);
  174.     }

  175.     /**
  176.      * Convert a LongObjectId from hex characters (US-ASCII).
  177.      *
  178.      * @param buf
  179.      *            the US-ASCII buffer to read from. At least 64 bytes after
  180.      *            offset must be available within this byte array.
  181.      * @param offset
  182.      *            position to read the first character from.
  183.      * @return the converted object id.
  184.      */
  185.     public static final LongObjectId fromString(byte[] buf, int offset) {
  186.         return fromHexString(buf, offset);
  187.     }

  188.     /**
  189.      * Convert a LongObjectId from hex characters.
  190.      *
  191.      * @param str
  192.      *            the string to read from. Must be 64 characters long.
  193.      * @return the converted object id.
  194.      */
  195.     public static LongObjectId fromString(String str) {
  196.         if (str.length() != Constants.LONG_OBJECT_ID_STRING_LENGTH)
  197.             throw new InvalidLongObjectIdException(str);
  198.         return fromHexString(org.eclipse.jgit.lib.Constants.encodeASCII(str),
  199.                 0);
  200.     }

  201.     private static final LongObjectId fromHexString(byte[] bs, int p) {
  202.         try {
  203.             final long a = RawParseUtils.parseHexInt64(bs, p);
  204.             final long b = RawParseUtils.parseHexInt64(bs, p + 16);
  205.             final long c = RawParseUtils.parseHexInt64(bs, p + 32);
  206.             final long d = RawParseUtils.parseHexInt64(bs, p + 48);
  207.             return new LongObjectId(a, b, c, d);
  208.         } catch (ArrayIndexOutOfBoundsException e) {
  209.             InvalidLongObjectIdException e1 = new InvalidLongObjectIdException(
  210.                     bs, p, Constants.LONG_OBJECT_ID_STRING_LENGTH);
  211.             e1.initCause(e);
  212.             throw e1;
  213.         }
  214.     }

  215.     LongObjectId(final long new_1, final long new_2, final long new_3,
  216.             final long new_4) {
  217.         w1 = new_1;
  218.         w2 = new_2;
  219.         w3 = new_3;
  220.         w4 = new_4;
  221.     }

  222.     /**
  223.      * Initialize this instance by copying another existing LongObjectId.
  224.      * <p>
  225.      * This constructor is mostly useful for subclasses which want to extend a
  226.      * LongObjectId with more properties, but initialize from an existing
  227.      * LongObjectId instance acquired by other means.
  228.      *
  229.      * @param src
  230.      *            another already parsed LongObjectId to copy the value out of.
  231.      */
  232.     protected LongObjectId(AnyLongObjectId src) {
  233.         w1 = src.w1;
  234.         w2 = src.w2;
  235.         w3 = src.w3;
  236.         w4 = src.w4;
  237.     }

  238.     /** {@inheritDoc} */
  239.     @Override
  240.     public LongObjectId toObjectId() {
  241.         return this;
  242.     }

  243.     private void writeObject(ObjectOutputStream os) throws IOException {
  244.         os.writeLong(w1);
  245.         os.writeLong(w2);
  246.         os.writeLong(w3);
  247.         os.writeLong(w4);
  248.     }

  249.     private void readObject(ObjectInputStream ois) throws IOException {
  250.         w1 = ois.readLong();
  251.         w2 = ois.readLong();
  252.         w3 = ois.readLong();
  253.         w4 = ois.readLong();
  254.     }
  255. }