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