Add MutableObjectId setByte to modify a mutable id
This mirrors the getByte() API in ObjectId and allows the caller to modify a single byte, which is useful when updating it as part of a loop walking through 0x00..0xff inside of a range of objects. Change-Id: I57fa8420011fe5ed5fc6bfeb26f87a02b3197dab Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
b22a4e8488
commit
e488f1cacd
|
@ -122,4 +122,33 @@ public void testGetByte() {
|
|||
for (int i = 2; i < 20; i++)
|
||||
assertEquals("index " + i, raw[i] & 0xff, id.getByte(i));
|
||||
}
|
||||
|
||||
public void testSetByte() {
|
||||
byte[] exp = new byte[20];
|
||||
for (int i = 0; i < 20; i++)
|
||||
exp[i] = (byte) (0xa0 + i);
|
||||
|
||||
MutableObjectId id = new MutableObjectId();
|
||||
id.fromRaw(exp);
|
||||
assertEquals(ObjectId.fromRaw(exp).name(), id.name());
|
||||
|
||||
id.setByte(0, 0x10);
|
||||
assertEquals(0x10, id.getByte(0));
|
||||
exp[0] = 0x10;
|
||||
assertEquals(ObjectId.fromRaw(exp).name(), id.name());
|
||||
|
||||
for (int p = 1; p < 20; p++) {
|
||||
id.setByte(p, 0x10 + p);
|
||||
assertEquals(0x10 + p, id.getByte(p));
|
||||
exp[p] = (byte) (0x10 + p);
|
||||
assertEquals(ObjectId.fromRaw(exp).name(), id.name());
|
||||
}
|
||||
|
||||
for (int p = 0; p < 20; p++) {
|
||||
id.setByte(p, 0x80 + p);
|
||||
assertEquals(0x80 + p, id.getByte(p));
|
||||
exp[p] = (byte) (0x80 + p);
|
||||
assertEquals(ObjectId.fromRaw(exp).name(), id.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,60 @@ public MutableObjectId() {
|
|||
fromObjectId(src);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set any byte in the id.
|
||||
*
|
||||
* @param index
|
||||
* index of the byte to set in the raw form of the ObjectId. Must
|
||||
* be in range [0, {@link Constants#OBJECT_ID_LENGTH}).
|
||||
* @param value
|
||||
* the value of the specified byte at {@code index}. Values are
|
||||
* unsigned and thus are in the range [0,255] rather than the
|
||||
* signed byte range of [-128, 127].
|
||||
* @throws ArrayIndexOutOfBoundsException
|
||||
* {@code index} is less than 0, equal to
|
||||
* {@link Constants#OBJECT_ID_LENGTH}, or greater than
|
||||
* {@link Constants#OBJECT_ID_LENGTH}.
|
||||
*/
|
||||
public void setByte(int index, int value) {
|
||||
switch (index >> 2) {
|
||||
case 0:
|
||||
w1 = set(w1, index & 3, value);
|
||||
break;
|
||||
case 1:
|
||||
w2 = set(w2, index & 3, value);
|
||||
break;
|
||||
case 2:
|
||||
w3 = set(w3, index & 3, value);
|
||||
break;
|
||||
case 3:
|
||||
w4 = set(w4, index & 3, value);
|
||||
break;
|
||||
case 4:
|
||||
w5 = set(w5, index & 3, value);
|
||||
break;
|
||||
default:
|
||||
throw new ArrayIndexOutOfBoundsException(index);
|
||||
}
|
||||
}
|
||||
|
||||
private static int set(int w, int index, int value) {
|
||||
value &= 0xff;
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
return (w & 0x00ffffff) | (value << 24);
|
||||
case 1:
|
||||
return (w & 0xff00ffff) | (value << 16);
|
||||
case 2:
|
||||
return (w & 0xffff00ff) | (value << 8);
|
||||
case 3:
|
||||
return (w & 0xffffff00) | value;
|
||||
default:
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
}
|
||||
|
||||
/** Make this id match {@link ObjectId#zeroId()}. */
|
||||
public void clear() {
|
||||
w1 = 0;
|
||||
|
|
Loading…
Reference in New Issue