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, {@link Constants#OBJECT_ID_LENGTH}). 83 * @param value 84 * the value of the specified byte at {@code index}. Values are 85 * unsigned and thus are in the range [0,255] rather than the 86 * signed byte range of [-128, 127]. 87 * @throws ArrayIndexOutOfBoundsException 88 * {@code index} is less than 0, equal to 89 * {@link Constants#OBJECT_ID_LENGTH}, or greater than 90 * {@link Constants#OBJECT_ID_LENGTH}. 91 */ 92 public void setByte(int index, int value) { 93 switch (index >> 2) { 94 case 0: 95 w1 = set(w1, index & 3, value); 96 break; 97 case 1: 98 w2 = set(w2, index & 3, value); 99 break; 100 case 2: 101 w3 = set(w3, index & 3, value); 102 break; 103 case 3: 104 w4 = set(w4, index & 3, value); 105 break; 106 case 4: 107 w5 = set(w5, index & 3, value); 108 break; 109 default: 110 throw new ArrayIndexOutOfBoundsException(index); 111 } 112 } 113 114 private static int set(int w, int index, int value) { 115 value &= 0xff; 116 117 switch (index) { 118 case 0: 119 return (w & 0x00ffffff) | (value << 24); 120 case 1: 121 return (w & 0xff00ffff) | (value << 16); 122 case 2: 123 return (w & 0xffff00ff) | (value << 8); 124 case 3: 125 return (w & 0xffffff00) | value; 126 default: 127 throw new ArrayIndexOutOfBoundsException(); 128 } 129 } 130 131 /** Make this id match {@link ObjectId#zeroId()}. */ 132 public void clear() { 133 w1 = 0; 134 w2 = 0; 135 w3 = 0; 136 w4 = 0; 137 w5 = 0; 138 } 139 140 /** 141 * Copy an ObjectId into this mutable buffer. 142 * 143 * @param src 144 * the source id to copy from. 145 */ 146 public void fromObjectId(AnyObjectId src) { 147 this.w1 = src.w1; 148 this.w2 = src.w2; 149 this.w3 = src.w3; 150 this.w4 = src.w4; 151 this.w5 = src.w5; 152 } 153 154 /** 155 * Convert an ObjectId from raw binary representation. 156 * 157 * @param bs 158 * the raw byte buffer to read from. At least 20 bytes must be 159 * available within this byte array. 160 */ 161 public void fromRaw(final byte[] bs) { 162 fromRaw(bs, 0); 163 } 164 165 /** 166 * Convert an ObjectId from raw binary representation. 167 * 168 * @param bs 169 * the raw byte buffer to read from. At least 20 bytes after p 170 * must be available within this byte array. 171 * @param p 172 * position to read the first byte of data from. 173 */ 174 public void fromRaw(final byte[] bs, final int p) { 175 w1 = NB.decodeInt32(bs, p); 176 w2 = NB.decodeInt32(bs, p + 4); 177 w3 = NB.decodeInt32(bs, p + 8); 178 w4 = NB.decodeInt32(bs, p + 12); 179 w5 = NB.decodeInt32(bs, p + 16); 180 } 181 182 /** 183 * Convert an ObjectId from binary representation expressed in integers. 184 * 185 * @param ints 186 * the raw int buffer to read from. At least 5 integers must be 187 * available within this integers array. 188 */ 189 public void fromRaw(final int[] ints) { 190 fromRaw(ints, 0); 191 } 192 193 /** 194 * Convert an ObjectId from binary representation expressed in integers. 195 * 196 * @param ints 197 * the raw int buffer to read from. At least 5 integers after p 198 * must be available within this integers array. 199 * @param p 200 * position to read the first integer of data from. 201 * 202 */ 203 public void fromRaw(final int[] ints, final int p) { 204 w1 = ints[p]; 205 w2 = ints[p + 1]; 206 w3 = ints[p + 2]; 207 w4 = ints[p + 3]; 208 w5 = ints[p + 4]; 209 } 210 211 /** 212 * Convert an ObjectId from hex characters (US-ASCII). 213 * 214 * @param buf 215 * the US-ASCII buffer to read from. At least 40 bytes after 216 * offset must be available within this byte array. 217 * @param offset 218 * position to read the first character from. 219 */ 220 public void fromString(final byte[] buf, final int offset) { 221 fromHexString(buf, offset); 222 } 223 224 /** 225 * Convert an ObjectId from hex characters. 226 * 227 * @param str 228 * the string to read from. Must be 40 characters long. 229 */ 230 public void fromString(final String str) { 231 if (str.length() != Constants.OBJECT_ID_STRING_LENGTH) 232 throw new IllegalArgumentException(MessageFormat.format( 233 JGitText.get().invalidId, str)); 234 fromHexString(Constants.encodeASCII(str), 0); 235 } 236 237 private void fromHexString(final byte[] bs, int p) { 238 try { 239 w1 = RawParseUtils.parseHexInt32(bs, p); 240 w2 = RawParseUtils.parseHexInt32(bs, p + 8); 241 w3 = RawParseUtils.parseHexInt32(bs, p + 16); 242 w4 = RawParseUtils.parseHexInt32(bs, p + 24); 243 w5 = RawParseUtils.parseHexInt32(bs, p + 32); 244 } catch (ArrayIndexOutOfBoundsException e1) { 245 throw new InvalidObjectIdException(bs, p, 246 Constants.OBJECT_ID_STRING_LENGTH); 247 } 248 } 249 250 @Override 251 public ObjectId toObjectId() { 252 return new ObjectId(this); 253 } 254 }