1536db18cSMatthias Sohn /* 25c5f7c6bSMatthias Sohn * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com> and others 3536db18cSMatthias Sohn * 45c5f7c6bSMatthias Sohn * This program and the accompanying materials are made available under the 55c5f7c6bSMatthias Sohn * terms of the Eclipse Distribution License v. 1.0 which is available at 65c5f7c6bSMatthias Sohn * https://www.eclipse.org/org/documents/edl-v10.php. 7536db18cSMatthias Sohn * 85c5f7c6bSMatthias Sohn * SPDX-License-Identifier: BSD-3-Clause 9536db18cSMatthias Sohn */ 10536db18cSMatthias Sohn 11536db18cSMatthias Sohn package org.eclipse.jgit.lfs.lib; 12536db18cSMatthias Sohn 13536db18cSMatthias Sohn import java.text.MessageFormat; 14536db18cSMatthias Sohn 15536db18cSMatthias Sohn import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException; 16536db18cSMatthias Sohn import org.eclipse.jgit.lfs.internal.LfsText; 17536db18cSMatthias Sohn import org.eclipse.jgit.util.NB; 18536db18cSMatthias Sohn import org.eclipse.jgit.util.RawParseUtils; 19536db18cSMatthias Sohn 20536db18cSMatthias Sohn /** 21536db18cSMatthias Sohn * A mutable SHA-256 abstraction. 22536db18cSMatthias Sohn * 23e0332bfbSMatthias Sohn * Ported to SHA-256 from {@link org.eclipse.jgit.lib.MutableObjectId} 24536db18cSMatthias Sohn * 25536db18cSMatthias Sohn * @since 4.3 26536db18cSMatthias Sohn */ 27536db18cSMatthias Sohn public class MutableLongObjectId extends AnyLongObjectId { 28536db18cSMatthias Sohn /** 29536db18cSMatthias Sohn * Empty constructor. Initialize object with default (zeros) value. 30536db18cSMatthias Sohn */ MutableLongObjectId()31536db18cSMatthias Sohn public MutableLongObjectId() { 32536db18cSMatthias Sohn super(); 33536db18cSMatthias Sohn } 34536db18cSMatthias Sohn 35536db18cSMatthias Sohn /** 36536db18cSMatthias Sohn * Copying constructor. 37536db18cSMatthias Sohn * 38536db18cSMatthias Sohn * @param src 39536db18cSMatthias Sohn * original entry, to copy id from 40536db18cSMatthias Sohn */ MutableLongObjectId(MutableLongObjectId src)41536db18cSMatthias Sohn MutableLongObjectId(MutableLongObjectId src) { 42536db18cSMatthias Sohn fromObjectId(src); 43536db18cSMatthias Sohn } 44536db18cSMatthias Sohn 45536db18cSMatthias Sohn /** 46536db18cSMatthias Sohn * Set any byte in the id. 47536db18cSMatthias Sohn * 48536db18cSMatthias Sohn * @param index 49536db18cSMatthias Sohn * index of the byte to set in the raw form of the ObjectId. Must 50e0332bfbSMatthias Sohn * be in range [0, 51e0332bfbSMatthias Sohn * {@link org.eclipse.jgit.lfs.lib.Constants#LONG_OBJECT_ID_LENGTH}). 52536db18cSMatthias Sohn * @param value 53536db18cSMatthias Sohn * the value of the specified byte at {@code index}. Values are 54536db18cSMatthias Sohn * unsigned and thus are in the range [0,255] rather than the 55536db18cSMatthias Sohn * signed byte range of [-128, 127]. 56e0332bfbSMatthias Sohn * @throws java.lang.ArrayIndexOutOfBoundsException 57536db18cSMatthias Sohn * {@code index} is less than 0, equal to 58e0332bfbSMatthias Sohn * {@link org.eclipse.jgit.lfs.lib.Constants#LONG_OBJECT_ID_LENGTH}, 59e0332bfbSMatthias Sohn * or greater than 60e0332bfbSMatthias Sohn * {@link org.eclipse.jgit.lfs.lib.Constants#LONG_OBJECT_ID_LENGTH}. 61536db18cSMatthias Sohn */ setByte(int index, int value)62536db18cSMatthias Sohn public void setByte(int index, int value) { 63536db18cSMatthias Sohn switch (index >> 3) { 64536db18cSMatthias Sohn case 0: 65536db18cSMatthias Sohn w1 = set(w1, index & 7, value); 66536db18cSMatthias Sohn break; 67536db18cSMatthias Sohn case 1: 68536db18cSMatthias Sohn w2 = set(w2, index & 7, value); 69536db18cSMatthias Sohn break; 70536db18cSMatthias Sohn case 2: 71536db18cSMatthias Sohn w3 = set(w3, index & 7, value); 72536db18cSMatthias Sohn break; 73536db18cSMatthias Sohn case 3: 74536db18cSMatthias Sohn w4 = set(w4, index & 7, value); 75536db18cSMatthias Sohn break; 76536db18cSMatthias Sohn default: 77536db18cSMatthias Sohn throw new ArrayIndexOutOfBoundsException(index); 78536db18cSMatthias Sohn } 79536db18cSMatthias Sohn } 80536db18cSMatthias Sohn set(long w, int index, long value)81536db18cSMatthias Sohn private static long set(long w, int index, long value) { 82536db18cSMatthias Sohn value &= 0xff; 83536db18cSMatthias Sohn 84536db18cSMatthias Sohn switch (index) { 85536db18cSMatthias Sohn case 0: 86536db18cSMatthias Sohn return (w & 0x00ffffffffffffffL) | (value << 56); 87536db18cSMatthias Sohn case 1: 88536db18cSMatthias Sohn return (w & 0xff00ffffffffffffL) | (value << 48); 89536db18cSMatthias Sohn case 2: 90536db18cSMatthias Sohn return (w & 0xffff00ffffffffffL) | (value << 40); 91536db18cSMatthias Sohn case 3: 92536db18cSMatthias Sohn return (w & 0xffffff00ffffffffL) | (value << 32); 93536db18cSMatthias Sohn case 4: 94536db18cSMatthias Sohn return (w & 0xffffffff00ffffffL) | (value << 24); 95536db18cSMatthias Sohn case 5: 96536db18cSMatthias Sohn return (w & 0xffffffffff00ffffL) | (value << 16); 97536db18cSMatthias Sohn case 6: 98536db18cSMatthias Sohn return (w & 0xffffffffffff00ffL) | (value << 8); 99536db18cSMatthias Sohn case 7: 100536db18cSMatthias Sohn return (w & 0xffffffffffffff00L) | value; 101536db18cSMatthias Sohn default: 102536db18cSMatthias Sohn throw new ArrayIndexOutOfBoundsException(); 103536db18cSMatthias Sohn } 104536db18cSMatthias Sohn } 105536db18cSMatthias Sohn 106e0332bfbSMatthias Sohn /** 107e0332bfbSMatthias Sohn * Make this id match 108e0332bfbSMatthias Sohn * {@link org.eclipse.jgit.lfs.lib.LongObjectId#zeroId()}. 109e0332bfbSMatthias Sohn */ clear()110536db18cSMatthias Sohn public void clear() { 111536db18cSMatthias Sohn w1 = 0; 112536db18cSMatthias Sohn w2 = 0; 113536db18cSMatthias Sohn w3 = 0; 114536db18cSMatthias Sohn w4 = 0; 115536db18cSMatthias Sohn } 116536db18cSMatthias Sohn 117536db18cSMatthias Sohn /** 118e0332bfbSMatthias Sohn * Copy a LongObjectId into this mutable buffer. 119536db18cSMatthias Sohn * 120536db18cSMatthias Sohn * @param src 121536db18cSMatthias Sohn * the source id to copy from. 122536db18cSMatthias Sohn */ fromObjectId(AnyLongObjectId src)123536db18cSMatthias Sohn public void fromObjectId(AnyLongObjectId src) { 124536db18cSMatthias Sohn this.w1 = src.w1; 125536db18cSMatthias Sohn this.w2 = src.w2; 126536db18cSMatthias Sohn this.w3 = src.w3; 127536db18cSMatthias Sohn this.w4 = src.w4; 128536db18cSMatthias Sohn } 129536db18cSMatthias Sohn 130536db18cSMatthias Sohn /** 131e0332bfbSMatthias Sohn * Convert a LongObjectId from raw binary representation. 132536db18cSMatthias Sohn * 133536db18cSMatthias Sohn * @param bs 134536db18cSMatthias Sohn * the raw byte buffer to read from. At least 32 bytes must be 135536db18cSMatthias Sohn * available within this byte array. 136536db18cSMatthias Sohn */ fromRaw(byte[] bs)1376d370d83SHan-Wen Nienhuys public void fromRaw(byte[] bs) { 138536db18cSMatthias Sohn fromRaw(bs, 0); 139536db18cSMatthias Sohn } 140536db18cSMatthias Sohn 141536db18cSMatthias Sohn /** 142e0332bfbSMatthias Sohn * Convert a LongObjectId from raw binary representation. 143536db18cSMatthias Sohn * 144536db18cSMatthias Sohn * @param bs 145536db18cSMatthias Sohn * the raw byte buffer to read from. At least 32 bytes after p 146536db18cSMatthias Sohn * must be available within this byte array. 147536db18cSMatthias Sohn * @param p 148536db18cSMatthias Sohn * position to read the first byte of data from. 149536db18cSMatthias Sohn */ fromRaw(byte[] bs, int p)1506d370d83SHan-Wen Nienhuys public void fromRaw(byte[] bs, int p) { 151536db18cSMatthias Sohn w1 = NB.decodeInt64(bs, p); 152536db18cSMatthias Sohn w2 = NB.decodeInt64(bs, p + 8); 153536db18cSMatthias Sohn w3 = NB.decodeInt64(bs, p + 16); 154536db18cSMatthias Sohn w4 = NB.decodeInt64(bs, p + 24); 155536db18cSMatthias Sohn } 156536db18cSMatthias Sohn 157536db18cSMatthias Sohn /** 158e0332bfbSMatthias Sohn * Convert a LongObjectId from binary representation expressed in integers. 159536db18cSMatthias Sohn * 160536db18cSMatthias Sohn * @param longs 161536db18cSMatthias Sohn * the raw long buffer to read from. At least 4 longs must be 162536db18cSMatthias Sohn * available within this longs array. 163536db18cSMatthias Sohn */ fromRaw(long[] longs)1646d370d83SHan-Wen Nienhuys public void fromRaw(long[] longs) { 165536db18cSMatthias Sohn fromRaw(longs, 0); 166536db18cSMatthias Sohn } 167536db18cSMatthias Sohn 168536db18cSMatthias Sohn /** 169e0332bfbSMatthias Sohn * Convert a LongObjectId from binary representation expressed in longs. 170536db18cSMatthias Sohn * 171536db18cSMatthias Sohn * @param longs 172536db18cSMatthias Sohn * the raw int buffer to read from. At least 4 longs after p must 173536db18cSMatthias Sohn * be available within this longs array. 174536db18cSMatthias Sohn * @param p 175536db18cSMatthias Sohn * position to read the first integer of data from. 176536db18cSMatthias Sohn */ fromRaw(long[] longs, int p)1776d370d83SHan-Wen Nienhuys public void fromRaw(long[] longs, int p) { 178536db18cSMatthias Sohn w1 = longs[p]; 179536db18cSMatthias Sohn w2 = longs[p + 1]; 180536db18cSMatthias Sohn w3 = longs[p + 2]; 181536db18cSMatthias Sohn w4 = longs[p + 3]; 182536db18cSMatthias Sohn } 183536db18cSMatthias Sohn 184536db18cSMatthias Sohn /** 185e0332bfbSMatthias Sohn * Convert a LongObjectId from hex characters (US-ASCII). 186536db18cSMatthias Sohn * 187536db18cSMatthias Sohn * @param buf 188536db18cSMatthias Sohn * the US-ASCII buffer to read from. At least 32 bytes after 189536db18cSMatthias Sohn * offset must be available within this byte array. 190536db18cSMatthias Sohn * @param offset 191536db18cSMatthias Sohn * position to read the first character from. 192536db18cSMatthias Sohn */ fromString(byte[] buf, int offset)1936d370d83SHan-Wen Nienhuys public void fromString(byte[] buf, int offset) { 194536db18cSMatthias Sohn fromHexString(buf, offset); 195536db18cSMatthias Sohn } 196536db18cSMatthias Sohn 197536db18cSMatthias Sohn /** 198e0332bfbSMatthias Sohn * Convert a LongObjectId from hex characters. 199536db18cSMatthias Sohn * 200536db18cSMatthias Sohn * @param str 201536db18cSMatthias Sohn * the string to read from. Must be 64 characters long. 202536db18cSMatthias Sohn */ fromString(String str)2036d370d83SHan-Wen Nienhuys public void fromString(String str) { 204536db18cSMatthias Sohn if (str.length() != Constants.LONG_OBJECT_ID_STRING_LENGTH) 205536db18cSMatthias Sohn throw new IllegalArgumentException( 206536db18cSMatthias Sohn MessageFormat.format(LfsText.get().invalidLongId, str)); 207536db18cSMatthias Sohn fromHexString(org.eclipse.jgit.lib.Constants.encodeASCII(str), 0); 208536db18cSMatthias Sohn } 209536db18cSMatthias Sohn fromHexString(byte[] bs, int p)2106d370d83SHan-Wen Nienhuys private void fromHexString(byte[] bs, int p) { 211536db18cSMatthias Sohn try { 212536db18cSMatthias Sohn w1 = RawParseUtils.parseHexInt64(bs, p); 213536db18cSMatthias Sohn w2 = RawParseUtils.parseHexInt64(bs, p + 16); 214536db18cSMatthias Sohn w3 = RawParseUtils.parseHexInt64(bs, p + 32); 215536db18cSMatthias Sohn w4 = RawParseUtils.parseHexInt64(bs, p + 48); 216*4cc13297SDavid Pursehouse } catch (ArrayIndexOutOfBoundsException e) { 217*4cc13297SDavid Pursehouse InvalidLongObjectIdException e1 = new InvalidLongObjectIdException( 218*4cc13297SDavid Pursehouse bs, p, Constants.LONG_OBJECT_ID_STRING_LENGTH); 219*4cc13297SDavid Pursehouse e1.initCause(e); 220*4cc13297SDavid Pursehouse throw e1; 221536db18cSMatthias Sohn } 222536db18cSMatthias Sohn } 223536db18cSMatthias Sohn 224e0332bfbSMatthias Sohn /** {@inheritDoc} */ 225536db18cSMatthias Sohn @Override toObjectId()226536db18cSMatthias Sohn public LongObjectId toObjectId() { 227536db18cSMatthias Sohn return new LongObjectId(this); 228536db18cSMatthias Sohn } 229536db18cSMatthias Sohn } 230