View Javadoc
1   /*
2    * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
3    * and other copyright owners as documented in the project's IP log.
4    *
5    * This program and the accompanying materials are made available
6    * under the terms of the Eclipse Distribution License v1.0 which
7    * accompanies this distribution, is reproduced below, and is
8    * available at http://www.eclipse.org/org/documents/edl-v10.php
9    *
10   * All rights reserved.
11   *
12   * Redistribution and use in source and binary forms, with or
13   * without modification, are permitted provided that the following
14   * conditions are met:
15   *
16   * - Redistributions of source code must retain the above copyright
17   *   notice, this list of conditions and the following disclaimer.
18   *
19   * - Redistributions in binary form must reproduce the above
20   *   copyright notice, this list of conditions and the following
21   *   disclaimer in the documentation and/or other materials provided
22   *   with the distribution.
23   *
24   * - Neither the name of the Eclipse Foundation, Inc. nor the
25   *   names of its contributors may be used to endorse or promote
26   *   products derived from this software without specific prior
27   *   written permission.
28   *
29   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42   */
43  
44  package org.eclipse.jgit.lfs.lib;
45  
46  import java.text.MessageFormat;
47  
48  import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException;
49  import org.eclipse.jgit.lfs.internal.LfsText;
50  import org.eclipse.jgit.util.NB;
51  import org.eclipse.jgit.util.RawParseUtils;
52  
53  /**
54   * A mutable SHA-256 abstraction.
55   *
56   * Ported to SHA-256 from {@link org.eclipse.jgit.lib.MutableObjectId}
57   *
58   * @since 4.3
59   */
60  public class MutableLongObjectId extends AnyLongObjectId {
61  	/**
62  	 * Empty constructor. Initialize object with default (zeros) value.
63  	 */
64  	public MutableLongObjectId() {
65  		super();
66  	}
67  
68  	/**
69  	 * Copying constructor.
70  	 *
71  	 * @param src
72  	 *            original entry, to copy id from
73  	 */
74  	MutableLongObjectId(MutableLongObjectId src) {
75  		fromObjectId(src);
76  	}
77  
78  	/**
79  	 * Set any byte in the id.
80  	 *
81  	 * @param index
82  	 *            index of the byte to set in the raw form of the ObjectId. Must
83  	 *            be in range [0,
84  	 *            {@link org.eclipse.jgit.lfs.lib.Constants#LONG_OBJECT_ID_LENGTH}).
85  	 * @param value
86  	 *            the value of the specified byte at {@code index}. Values are
87  	 *            unsigned and thus are in the range [0,255] rather than the
88  	 *            signed byte range of [-128, 127].
89  	 * @throws java.lang.ArrayIndexOutOfBoundsException
90  	 *             {@code index} is less than 0, equal to
91  	 *             {@link org.eclipse.jgit.lfs.lib.Constants#LONG_OBJECT_ID_LENGTH},
92  	 *             or greater than
93  	 *             {@link org.eclipse.jgit.lfs.lib.Constants#LONG_OBJECT_ID_LENGTH}.
94  	 */
95  	public void setByte(int index, int value) {
96  		switch (index >> 3) {
97  		case 0:
98  			w1 = set(w1, index & 7, value);
99  			break;
100 		case 1:
101 			w2 = set(w2, index & 7, value);
102 			break;
103 		case 2:
104 			w3 = set(w3, index & 7, value);
105 			break;
106 		case 3:
107 			w4 = set(w4, index & 7, value);
108 			break;
109 		default:
110 			throw new ArrayIndexOutOfBoundsException(index);
111 		}
112 	}
113 
114 	private static long set(long w, int index, long value) {
115 		value &= 0xff;
116 
117 		switch (index) {
118 		case 0:
119 			return (w & 0x00ffffffffffffffL) | (value << 56);
120 		case 1:
121 			return (w & 0xff00ffffffffffffL) | (value << 48);
122 		case 2:
123 			return (w & 0xffff00ffffffffffL) | (value << 40);
124 		case 3:
125 			return (w & 0xffffff00ffffffffL) | (value << 32);
126 		case 4:
127 			return (w & 0xffffffff00ffffffL) | (value << 24);
128 		case 5:
129 			return (w & 0xffffffffff00ffffL) | (value << 16);
130 		case 6:
131 			return (w & 0xffffffffffff00ffL) | (value << 8);
132 		case 7:
133 			return (w & 0xffffffffffffff00L) | value;
134 		default:
135 			throw new ArrayIndexOutOfBoundsException();
136 		}
137 	}
138 
139 	/**
140 	 * Make this id match
141 	 * {@link org.eclipse.jgit.lfs.lib.LongObjectId#zeroId()}.
142 	 */
143 	public void clear() {
144 		w1 = 0;
145 		w2 = 0;
146 		w3 = 0;
147 		w4 = 0;
148 	}
149 
150 	/**
151 	 * Copy a LongObjectId into this mutable buffer.
152 	 *
153 	 * @param src
154 	 *            the source id to copy from.
155 	 */
156 	public void fromObjectId(AnyLongObjectId src) {
157 		this.w1 = src.w1;
158 		this.w2 = src.w2;
159 		this.w3 = src.w3;
160 		this.w4 = src.w4;
161 	}
162 
163 	/**
164 	 * Convert a LongObjectId from raw binary representation.
165 	 *
166 	 * @param bs
167 	 *            the raw byte buffer to read from. At least 32 bytes must be
168 	 *            available within this byte array.
169 	 */
170 	public void fromRaw(byte[] bs) {
171 		fromRaw(bs, 0);
172 	}
173 
174 	/**
175 	 * Convert a LongObjectId from raw binary representation.
176 	 *
177 	 * @param bs
178 	 *            the raw byte buffer to read from. At least 32 bytes after p
179 	 *            must be available within this byte array.
180 	 * @param p
181 	 *            position to read the first byte of data from.
182 	 */
183 	public void fromRaw(byte[] bs, int p) {
184 		w1 = NB.decodeInt64(bs, p);
185 		w2 = NB.decodeInt64(bs, p + 8);
186 		w3 = NB.decodeInt64(bs, p + 16);
187 		w4 = NB.decodeInt64(bs, p + 24);
188 	}
189 
190 	/**
191 	 * Convert a LongObjectId from binary representation expressed in integers.
192 	 *
193 	 * @param longs
194 	 *            the raw long buffer to read from. At least 4 longs must be
195 	 *            available within this longs array.
196 	 */
197 	public void fromRaw(long[] longs) {
198 		fromRaw(longs, 0);
199 	}
200 
201 	/**
202 	 * Convert a LongObjectId from binary representation expressed in longs.
203 	 *
204 	 * @param longs
205 	 *            the raw int buffer to read from. At least 4 longs after p must
206 	 *            be available within this longs array.
207 	 * @param p
208 	 *            position to read the first integer of data from.
209 	 */
210 	public void fromRaw(long[] longs, int p) {
211 		w1 = longs[p];
212 		w2 = longs[p + 1];
213 		w3 = longs[p + 2];
214 		w4 = longs[p + 3];
215 	}
216 
217 	/**
218 	 * Convert a LongObjectId from hex characters (US-ASCII).
219 	 *
220 	 * @param buf
221 	 *            the US-ASCII buffer to read from. At least 32 bytes after
222 	 *            offset must be available within this byte array.
223 	 * @param offset
224 	 *            position to read the first character from.
225 	 */
226 	public void fromString(byte[] buf, int offset) {
227 		fromHexString(buf, offset);
228 	}
229 
230 	/**
231 	 * Convert a LongObjectId from hex characters.
232 	 *
233 	 * @param str
234 	 *            the string to read from. Must be 64 characters long.
235 	 */
236 	public void fromString(String str) {
237 		if (str.length() != Constants.LONG_OBJECT_ID_STRING_LENGTH)
238 			throw new IllegalArgumentException(
239 					MessageFormat.format(LfsText.get().invalidLongId, str));
240 		fromHexString(org.eclipse.jgit.lib.Constants.encodeASCII(str), 0);
241 	}
242 
243 	private void fromHexString(byte[] bs, int p) {
244 		try {
245 			w1 = RawParseUtils.parseHexInt64(bs, p);
246 			w2 = RawParseUtils.parseHexInt64(bs, p + 16);
247 			w3 = RawParseUtils.parseHexInt64(bs, p + 32);
248 			w4 = RawParseUtils.parseHexInt64(bs, p + 48);
249 		} catch (ArrayIndexOutOfBoundsException e1) {
250 			throw new InvalidLongObjectIdException(bs, p,
251 					Constants.LONG_OBJECT_ID_STRING_LENGTH);
252 		}
253 	}
254 
255 	/** {@inheritDoc} */
256 	@Override
257 	public LongObjectId toObjectId() {
258 		return new LongObjectId(this);
259 	}
260 }