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 }