xref: /JGit/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/MutableLongObjectId.java (revision 4cc13297ccf1fa3e982bbb5638162b3bad63f93c)
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 
11 package org.eclipse.jgit.lfs.lib;
12 
13 import java.text.MessageFormat;
14 
15 import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException;
16 import org.eclipse.jgit.lfs.internal.LfsText;
17 import org.eclipse.jgit.util.NB;
18 import org.eclipse.jgit.util.RawParseUtils;
19 
20 /**
21  * A mutable SHA-256 abstraction.
22  *
23  * Ported to SHA-256 from {@link org.eclipse.jgit.lib.MutableObjectId}
24  *
25  * @since 4.3
26  */
27 public class MutableLongObjectId extends AnyLongObjectId {
28 	/**
29 	 * Empty constructor. Initialize object with default (zeros) value.
30 	 */
MutableLongObjectId()31 	public MutableLongObjectId() {
32 		super();
33 	}
34 
35 	/**
36 	 * Copying constructor.
37 	 *
38 	 * @param src
39 	 *            original entry, to copy id from
40 	 */
MutableLongObjectId(MutableLongObjectId src)41 	MutableLongObjectId(MutableLongObjectId src) {
42 		fromObjectId(src);
43 	}
44 
45 	/**
46 	 * Set any byte in the id.
47 	 *
48 	 * @param index
49 	 *            index of the byte to set in the raw form of the ObjectId. Must
50 	 *            be in range [0,
51 	 *            {@link org.eclipse.jgit.lfs.lib.Constants#LONG_OBJECT_ID_LENGTH}).
52 	 * @param value
53 	 *            the value of the specified byte at {@code index}. Values are
54 	 *            unsigned and thus are in the range [0,255] rather than the
55 	 *            signed byte range of [-128, 127].
56 	 * @throws java.lang.ArrayIndexOutOfBoundsException
57 	 *             {@code index} is less than 0, equal to
58 	 *             {@link org.eclipse.jgit.lfs.lib.Constants#LONG_OBJECT_ID_LENGTH},
59 	 *             or greater than
60 	 *             {@link org.eclipse.jgit.lfs.lib.Constants#LONG_OBJECT_ID_LENGTH}.
61 	 */
setByte(int index, int value)62 	public void setByte(int index, int value) {
63 		switch (index >> 3) {
64 		case 0:
65 			w1 = set(w1, index & 7, value);
66 			break;
67 		case 1:
68 			w2 = set(w2, index & 7, value);
69 			break;
70 		case 2:
71 			w3 = set(w3, index & 7, value);
72 			break;
73 		case 3:
74 			w4 = set(w4, index & 7, value);
75 			break;
76 		default:
77 			throw new ArrayIndexOutOfBoundsException(index);
78 		}
79 	}
80 
set(long w, int index, long value)81 	private static long set(long w, int index, long value) {
82 		value &= 0xff;
83 
84 		switch (index) {
85 		case 0:
86 			return (w & 0x00ffffffffffffffL) | (value << 56);
87 		case 1:
88 			return (w & 0xff00ffffffffffffL) | (value << 48);
89 		case 2:
90 			return (w & 0xffff00ffffffffffL) | (value << 40);
91 		case 3:
92 			return (w & 0xffffff00ffffffffL) | (value << 32);
93 		case 4:
94 			return (w & 0xffffffff00ffffffL) | (value << 24);
95 		case 5:
96 			return (w & 0xffffffffff00ffffL) | (value << 16);
97 		case 6:
98 			return (w & 0xffffffffffff00ffL) | (value << 8);
99 		case 7:
100 			return (w & 0xffffffffffffff00L) | value;
101 		default:
102 			throw new ArrayIndexOutOfBoundsException();
103 		}
104 	}
105 
106 	/**
107 	 * Make this id match
108 	 * {@link org.eclipse.jgit.lfs.lib.LongObjectId#zeroId()}.
109 	 */
clear()110 	public void clear() {
111 		w1 = 0;
112 		w2 = 0;
113 		w3 = 0;
114 		w4 = 0;
115 	}
116 
117 	/**
118 	 * Copy a LongObjectId into this mutable buffer.
119 	 *
120 	 * @param src
121 	 *            the source id to copy from.
122 	 */
fromObjectId(AnyLongObjectId src)123 	public void fromObjectId(AnyLongObjectId src) {
124 		this.w1 = src.w1;
125 		this.w2 = src.w2;
126 		this.w3 = src.w3;
127 		this.w4 = src.w4;
128 	}
129 
130 	/**
131 	 * Convert a LongObjectId from raw binary representation.
132 	 *
133 	 * @param bs
134 	 *            the raw byte buffer to read from. At least 32 bytes must be
135 	 *            available within this byte array.
136 	 */
fromRaw(byte[] bs)137 	public void fromRaw(byte[] bs) {
138 		fromRaw(bs, 0);
139 	}
140 
141 	/**
142 	 * Convert a LongObjectId from raw binary representation.
143 	 *
144 	 * @param bs
145 	 *            the raw byte buffer to read from. At least 32 bytes after p
146 	 *            must be available within this byte array.
147 	 * @param p
148 	 *            position to read the first byte of data from.
149 	 */
fromRaw(byte[] bs, int p)150 	public void fromRaw(byte[] bs, int p) {
151 		w1 = NB.decodeInt64(bs, p);
152 		w2 = NB.decodeInt64(bs, p + 8);
153 		w3 = NB.decodeInt64(bs, p + 16);
154 		w4 = NB.decodeInt64(bs, p + 24);
155 	}
156 
157 	/**
158 	 * Convert a LongObjectId from binary representation expressed in integers.
159 	 *
160 	 * @param longs
161 	 *            the raw long buffer to read from. At least 4 longs must be
162 	 *            available within this longs array.
163 	 */
fromRaw(long[] longs)164 	public void fromRaw(long[] longs) {
165 		fromRaw(longs, 0);
166 	}
167 
168 	/**
169 	 * Convert a LongObjectId from binary representation expressed in longs.
170 	 *
171 	 * @param longs
172 	 *            the raw int buffer to read from. At least 4 longs after p must
173 	 *            be available within this longs array.
174 	 * @param p
175 	 *            position to read the first integer of data from.
176 	 */
fromRaw(long[] longs, int p)177 	public void fromRaw(long[] longs, int p) {
178 		w1 = longs[p];
179 		w2 = longs[p + 1];
180 		w3 = longs[p + 2];
181 		w4 = longs[p + 3];
182 	}
183 
184 	/**
185 	 * Convert a LongObjectId from hex characters (US-ASCII).
186 	 *
187 	 * @param buf
188 	 *            the US-ASCII buffer to read from. At least 32 bytes after
189 	 *            offset must be available within this byte array.
190 	 * @param offset
191 	 *            position to read the first character from.
192 	 */
fromString(byte[] buf, int offset)193 	public void fromString(byte[] buf, int offset) {
194 		fromHexString(buf, offset);
195 	}
196 
197 	/**
198 	 * Convert a LongObjectId from hex characters.
199 	 *
200 	 * @param str
201 	 *            the string to read from. Must be 64 characters long.
202 	 */
fromString(String str)203 	public void fromString(String str) {
204 		if (str.length() != Constants.LONG_OBJECT_ID_STRING_LENGTH)
205 			throw new IllegalArgumentException(
206 					MessageFormat.format(LfsText.get().invalidLongId, str));
207 		fromHexString(org.eclipse.jgit.lib.Constants.encodeASCII(str), 0);
208 	}
209 
fromHexString(byte[] bs, int p)210 	private void fromHexString(byte[] bs, int p) {
211 		try {
212 			w1 = RawParseUtils.parseHexInt64(bs, p);
213 			w2 = RawParseUtils.parseHexInt64(bs, p + 16);
214 			w3 = RawParseUtils.parseHexInt64(bs, p + 32);
215 			w4 = RawParseUtils.parseHexInt64(bs, p + 48);
216 		} catch (ArrayIndexOutOfBoundsException e) {
217 			InvalidLongObjectIdException e1 = new InvalidLongObjectIdException(
218 					bs, p, Constants.LONG_OBJECT_ID_STRING_LENGTH);
219 			e1.initCause(e);
220 			throw e1;
221 		}
222 	}
223 
224 	/** {@inheritDoc} */
225 	@Override
toObjectId()226 	public LongObjectId toObjectId() {
227 		return new LongObjectId(this);
228 	}
229 }
230