View Javadoc
1   /*
2    * Copyright (C) 2008-2009, Google Inc.
3    * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
4    * Copyright (C) 2007-2009, Robin Rosenberg <robin.rosenberg@dewire.com>
5    * Copyright (C) 2006-2008, Shawn O. Pearce <spearce@spearce.org> and others
6    *
7    * This program and the accompanying materials are made available under the
8    * terms of the Eclipse Distribution License v. 1.0 which is available at
9    * https://www.eclipse.org/org/documents/edl-v10.php.
10   *
11   * SPDX-License-Identifier: BSD-3-Clause
12   */
13  
14  package org.eclipse.jgit.lib;
15  
16  import java.text.MessageFormat;
17  
18  import org.eclipse.jgit.errors.InvalidObjectIdException;
19  import org.eclipse.jgit.internal.JGitText;
20  import org.eclipse.jgit.util.NB;
21  import org.eclipse.jgit.util.RawParseUtils;
22  
23  /**
24   * A mutable SHA-1 abstraction.
25   */
26  public class MutableObjectId extends AnyObjectId {
27  	/**
28  	 * Empty constructor. Initialize object with default (zeros) value.
29  	 */
30  	public MutableObjectId() {
31  		super();
32  	}
33  
34  	/**
35  	 * Copying constructor.
36  	 *
37  	 * @param src
38  	 *            original entry, to copy id from
39  	 */
40  	MutableObjectId(MutableObjectId src) {
41  		fromObjectId(src);
42  	}
43  
44  	/**
45  	 * Set any byte in the id.
46  	 *
47  	 * @param index
48  	 *            index of the byte to set in the raw form of the ObjectId. Must
49  	 *            be in range [0,
50  	 *            {@link org.eclipse.jgit.lib.Constants#OBJECT_ID_LENGTH}).
51  	 * @param value
52  	 *            the value of the specified byte at {@code index}. Values are
53  	 *            unsigned and thus are in the range [0,255] rather than the
54  	 *            signed byte range of [-128, 127].
55  	 * @throws java.lang.ArrayIndexOutOfBoundsException
56  	 *             {@code index} is less than 0, equal to
57  	 *             {@link org.eclipse.jgit.lib.Constants#OBJECT_ID_LENGTH}, or
58  	 *             greater than
59  	 *             {@link org.eclipse.jgit.lib.Constants#OBJECT_ID_LENGTH}.
60  	 */
61  	public void setByte(int index, int value) {
62  		switch (index >> 2) {
63  		case 0:
64  			w1 = set(w1, index & 3, value);
65  			break;
66  		case 1:
67  			w2 = set(w2, index & 3, value);
68  			break;
69  		case 2:
70  			w3 = set(w3, index & 3, value);
71  			break;
72  		case 3:
73  			w4 = set(w4, index & 3, value);
74  			break;
75  		case 4:
76  			w5 = set(w5, index & 3, value);
77  			break;
78  		default:
79  			throw new ArrayIndexOutOfBoundsException(index);
80  		}
81  	}
82  
83  	private static int set(int w, int index, int value) {
84  		value &= 0xff;
85  
86  		switch (index) {
87  		case 0:
88  			return (w & 0x00ffffff) | (value << 24);
89  		case 1:
90  			return (w & 0xff00ffff) | (value << 16);
91  		case 2:
92  			return (w & 0xffff00ff) | (value << 8);
93  		case 3:
94  			return (w & 0xffffff00) | value;
95  		default:
96  			throw new ArrayIndexOutOfBoundsException();
97  		}
98  	}
99  
100 	/**
101 	 * Make this id match {@link org.eclipse.jgit.lib.ObjectId#zeroId()}.
102 	 */
103 	public void clear() {
104 		w1 = 0;
105 		w2 = 0;
106 		w3 = 0;
107 		w4 = 0;
108 		w5 = 0;
109 	}
110 
111 	/**
112 	 * Copy an ObjectId into this mutable buffer.
113 	 *
114 	 * @param src
115 	 *            the source id to copy from.
116 	 */
117 	public void fromObjectId(AnyObjectId src) {
118 		this.w1 = src.w1;
119 		this.w2 = src.w2;
120 		this.w3 = src.w3;
121 		this.w4 = src.w4;
122 		this.w5 = src.w5;
123 	}
124 
125 	/**
126 	 * Convert an ObjectId from raw binary representation.
127 	 *
128 	 * @param bs
129 	 *            the raw byte buffer to read from. At least 20 bytes must be
130 	 *            available within this byte array.
131 	 */
132 	public void fromRaw(byte[] bs) {
133 		fromRaw(bs, 0);
134 	}
135 
136 	/**
137 	 * Convert an ObjectId from raw binary representation.
138 	 *
139 	 * @param bs
140 	 *            the raw byte buffer to read from. At least 20 bytes after p
141 	 *            must be available within this byte array.
142 	 * @param p
143 	 *            position to read the first byte of data from.
144 	 */
145 	public void fromRaw(byte[] bs, int p) {
146 		w1 = NB.decodeInt32(bs, p);
147 		w2 = NB.decodeInt32(bs, p + 4);
148 		w3 = NB.decodeInt32(bs, p + 8);
149 		w4 = NB.decodeInt32(bs, p + 12);
150 		w5 = NB.decodeInt32(bs, p + 16);
151 	}
152 
153 	/**
154 	 * Convert an ObjectId from binary representation expressed in integers.
155 	 *
156 	 * @param ints
157 	 *            the raw int buffer to read from. At least 5 integers must be
158 	 *            available within this integers array.
159 	 */
160 	public void fromRaw(int[] ints) {
161 		fromRaw(ints, 0);
162 	}
163 
164 	/**
165 	 * Convert an ObjectId from binary representation expressed in integers.
166 	 *
167 	 * @param ints
168 	 *            the raw int buffer to read from. At least 5 integers after p
169 	 *            must be available within this integers array.
170 	 * @param p
171 	 *            position to read the first integer of data from.
172 	 */
173 	public void fromRaw(int[] ints, int p) {
174 		w1 = ints[p];
175 		w2 = ints[p + 1];
176 		w3 = ints[p + 2];
177 		w4 = ints[p + 3];
178 		w5 = ints[p + 4];
179 	}
180 
181 	/**
182 	 * Convert an ObjectId from binary representation expressed in integers.
183 	 *
184 	 * @param a
185 	 *            an int.
186 	 * @param b
187 	 *            an int.
188 	 * @param c
189 	 *            an int.
190 	 * @param d
191 	 *            an int.
192 	 * @param e
193 	 *            an int.
194 	 * @since 4.7
195 	 */
196 	public void set(int a, int b, int c, int d, int e) {
197 		w1 = a;
198 		w2 = b;
199 		w3 = c;
200 		w4 = d;
201 		w5 = e;
202 	}
203 
204 	/**
205 	 * Convert an ObjectId from hex characters (US-ASCII).
206 	 *
207 	 * @param buf
208 	 *            the US-ASCII buffer to read from. At least 40 bytes after
209 	 *            offset must be available within this byte array.
210 	 * @param offset
211 	 *            position to read the first character from.
212 	 */
213 	public void fromString(byte[] buf, int offset) {
214 		fromHexString(buf, offset);
215 	}
216 
217 	/**
218 	 * Convert an ObjectId from hex characters.
219 	 *
220 	 * @param str
221 	 *            the string to read from. Must be 40 characters long.
222 	 */
223 	public void fromString(String str) {
224 		if (str.length() != Constants.OBJECT_ID_STRING_LENGTH)
225 			throw new IllegalArgumentException(MessageFormat.format(
226 					JGitText.get().invalidId, str));
227 		fromHexString(Constants.encodeASCII(str), 0);
228 	}
229 
230 	private void fromHexString(byte[] bs, int p) {
231 		try {
232 			w1 = RawParseUtils.parseHexInt32(bs, p);
233 			w2 = RawParseUtils.parseHexInt32(bs, p + 8);
234 			w3 = RawParseUtils.parseHexInt32(bs, p + 16);
235 			w4 = RawParseUtils.parseHexInt32(bs, p + 24);
236 			w5 = RawParseUtils.parseHexInt32(bs, p + 32);
237 		} catch (ArrayIndexOutOfBoundsException e) {
238 			InvalidObjectIdException e1 = new InvalidObjectIdException(bs, p,
239 					Constants.OBJECT_ID_STRING_LENGTH);
240 			e1.initCause(e);
241 			throw e1;
242 		}
243 	}
244 
245 	/** {@inheritDoc} */
246 	@Override
247 	public ObjectId toObjectId() {
248 		return new ObjectId(this);
249 	}
250 }