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