xref: /JGit/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/MutableLongObjectId.java (revision 4cc13297ccf1fa3e982bbb5638162b3bad63f93c)
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