Show changes to 6 files +101 −63
org.spearce.jgit.test/tst/org/spearce/jgit/lib/T0001_ObjectId.java, org.spearce.jgit/src/org/spearce/jgit/lib/AbbreviatedObjectId.java, org.spearce.jgit/src/org/spearce/jgit/lib/AnyObjectId.java, org.spearce.jgit/src/org/spearce/jgit/lib/MutableObjectId.java, org.spearce.jgit/src/org/spearce/jgit/lib/ObjectId.java, org.spearce.jgit/src/org/spearce/jgit/util/RawParseUtils.java
diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/T0001_ObjectId.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/T0001_ObjectId.java
index 4c03667..7a53925 100644
--- a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/T0001_ObjectId.java
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/T0001_ObjectId.java
@@ -74,8 +74,8 @@ assertFalse("39 digits is not an id", ObjectId
.isId("def4c620bc3713bb1bb26b808ec9312548e7394"));
}
- public void test007_notIsId() {
- assertFalse("uppercase is not accepted", ObjectId
+ public void test007_isId() {
+ assertTrue("uppercase is accepted", ObjectId
.isId("Def4c620bc3713bb1bb26b808ec9312548e73946"));
}
@@ -94,4 +94,10 @@ public void test010_toString() {
final String x = "0000000000000000000000000000000000000000";
assertEquals(x, ObjectId.toString(null));
}
+
+ public void test011_toString() {
+ final String x = "0123456789ABCDEFabcdef1234567890abcdefAB";
+ final ObjectId oid = ObjectId.fromString(x);
+ assertEquals(x.toLowerCase(), oid.name());
+ }
}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/AbbreviatedObjectId.java b/org.spearce.jgit/src/org/spearce/jgit/lib/AbbreviatedObjectId.java
index ed03fb5..1706e88 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/AbbreviatedObjectId.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/AbbreviatedObjectId.java
@@ -40,6 +40,7 @@
import java.io.UnsupportedEncodingException;
import org.spearce.jgit.util.NB;
+import org.spearce.jgit.util.RawParseUtils;
/**
* A prefix abbreviation of an {@link ObjectId}.
@@ -107,15 +108,12 @@ private static final AbbreviatedObjectId fromHexString(final byte[] bs,
private static final int hexUInt32(final byte[] bs, int p, final int end) {
if (8 <= end - p)
- return AnyObjectId.hexUInt32(bs, p);
+ return RawParseUtils.parseHexInt32(bs, p);
int r = 0, n = 0;
while (n < 8 && p < end) {
- final int v = AnyObjectId.fromhex[bs[p++]];
- if (v < 0)
- throw new ArrayIndexOutOfBoundsException();
r <<= 4;
- r |= v;
+ r |= RawParseUtils.parseHexInt4(bs[p++]);
n++;
}
return r << (8 - n) * 4;
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/AnyObjectId.java b/org.spearce.jgit/src/org/spearce/jgit/lib/AnyObjectId.java
index acb3cb5..0df2768 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/AnyObjectId.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/AnyObjectId.java
@@ -41,7 +41,6 @@
import java.io.OutputStream;
import java.io.Writer;
import java.nio.ByteBuffer;
-import java.util.Arrays;
import org.spearce.jgit.util.NB;
@@ -57,16 +56,7 @@
static final int STR_LEN = RAW_LEN * 2;
- static final byte fromhex[];
-
static {
- fromhex = new byte['f' + 1];
- Arrays.fill(fromhex, (byte) -1);
- for (char i = '0'; i <= '9'; i++)
- fromhex[i] = (byte) (i - '0');
- for (char i = 'a'; i <= 'f'; i++)
- fromhex[i] = (byte) ((i - 'a') + 10);
-
if (RAW_LEN != 20)
throw new LinkageError("ObjectId expects"
+ " Constants.OBJECT_ID_LENGTH = 20; it is " + RAW_LEN
@@ -100,32 +90,6 @@ public static boolean equals(final AnyObjectId firstObjectId,
&& firstObjectId.w1 == secondObjectId.w1;
}
- static final int hexUInt32(final byte[] bs, final int p) {
- int r = fromhex[bs[p]] << 4;
-
- r |= fromhex[bs[p + 1]];
- r <<= 4;
-
- r |= fromhex[bs[p + 2]];
- r <<= 4;
-
- r |= fromhex[bs[p + 3]];
- r <<= 4;
-
- r |= fromhex[bs[p + 4]];
- r <<= 4;
-
- r |= fromhex[bs[p + 5]];
- r <<= 4;
-
- r |= fromhex[bs[p + 6]];
-
- final int last = fromhex[bs[p + 7]];
- if (r < 0 || last < 0)
- throw new ArrayIndexOutOfBoundsException();
- return (r << 4) | last;
- }
-
int w1;
int w2;
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/MutableObjectId.java b/org.spearce.jgit/src/org/spearce/jgit/lib/MutableObjectId.java
index fadebab..805f328 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/MutableObjectId.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/MutableObjectId.java
@@ -40,6 +40,7 @@
import java.io.UnsupportedEncodingException;
import org.spearce.jgit.util.NB;
+import org.spearce.jgit.util.RawParseUtils;
/**
* A mutable SHA-1 abstraction.
@@ -159,11 +160,11 @@ public void fromString(final String str) {
private void fromHexString(final byte[] bs, int p) {
try {
- w1 = hexUInt32(bs, p);
- w2 = hexUInt32(bs, p + 8);
- w3 = hexUInt32(bs, p + 16);
- w4 = hexUInt32(bs, p + 24);
- w5 = hexUInt32(bs, p + 32);
+ w1 = RawParseUtils.parseHexInt32(bs, p);
+ w2 = RawParseUtils.parseHexInt32(bs, p + 8);
+ w3 = RawParseUtils.parseHexInt32(bs, p + 16);
+ w4 = RawParseUtils.parseHexInt32(bs, p + 24);
+ w5 = RawParseUtils.parseHexInt32(bs, p + 32);
} catch (ArrayIndexOutOfBoundsException e1) {
try {
final String str = new String(bs, p, STR_LEN, "US-ASCII");
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectId.java b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectId.java
index fde209b..cdd523f 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectId.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectId.java
@@ -41,6 +41,7 @@
import java.io.UnsupportedEncodingException;
import org.spearce.jgit.util.NB;
+import org.spearce.jgit.util.RawParseUtils;
/**
* A SHA-1 abstraction.
@@ -74,12 +75,12 @@ public static final ObjectId zeroId() {
* @return true if the string can converted into an ObjectId.
*/
public static final boolean isId(final String id) {
- if (id.length() != 2 * Constants.OBJECT_ID_LENGTH)
+ if (id.length() != STR_LEN)
return false;
try {
- for (int k = id.length() - 1; k >= 0; k--)
- if (fromhex[id.charAt(k)] < 0)
- return false;
+ for (int i = 0; i < STR_LEN; i++) {
+ RawParseUtils.parseHexInt4((byte) id.charAt(i));
+ }
return true;
} catch (ArrayIndexOutOfBoundsException e) {
return false;
@@ -222,11 +223,11 @@ public static final ObjectId fromString(final String str) {
private static final ObjectId fromHexString(final byte[] bs, int p) {
try {
- final int a = hexUInt32(bs, p);
- final int b = hexUInt32(bs, p + 8);
- final int c = hexUInt32(bs, p + 16);
- final int d = hexUInt32(bs, p + 24);
- final int e = hexUInt32(bs, p + 32);
+ final int a = RawParseUtils.parseHexInt32(bs, p);
+ final int b = RawParseUtils.parseHexInt32(bs, p + 8);
+ final int c = RawParseUtils.parseHexInt32(bs, p + 16);
+ final int d = RawParseUtils.parseHexInt32(bs, p + 24);
+ final int e = RawParseUtils.parseHexInt32(bs, p + 32);
return new ObjectId(a, b, c, d, e);
} catch (ArrayIndexOutOfBoundsException e1) {
try {
diff --git a/org.spearce.jgit/src/org/spearce/jgit/util/RawParseUtils.java b/org.spearce.jgit/src/org/spearce/jgit/util/RawParseUtils.java
index 79ebe41..0554acb 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/util/RawParseUtils.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/util/RawParseUtils.java
@@ -54,13 +54,24 @@
/** Handy utility functions to parse raw object contents. */
public final class RawParseUtils {
- private static final byte[] digits;
+ private static final byte[] digits10;
+
+ private static final byte[] digits16;
static {
- digits = new byte['9' + 1];
- Arrays.fill(digits, (byte) -1);
+ digits10 = new byte['9' + 1];
+ Arrays.fill(digits10, (byte) -1);
+ for (char i = '0'; i <= '9'; i++)
+ digits10[i] = (byte) (i - '0');
+
+ digits16 = new byte['f' + 1];
+ Arrays.fill(digits16, (byte) -1);
for (char i = '0'; i <= '9'; i++)
- digits[i] = (byte) (i - '0');
+ digits16[i] = (byte) (i - '0');
+ for (char i = 'a'; i <= 'f'; i++)
+ digits16[i] = (byte) ((i - 'a') + 10);
+ for (char i = 'A'; i <= 'F'; i++)
+ digits16[i] = (byte) ((i - 'A') + 10);
}
/**
@@ -175,7 +186,7 @@ public static final int parseBase10(final byte[] b, int ptr,
}
while (ptr < sz) {
- final byte v = digits[b[ptr]];
+ final byte v = digits10[b[ptr]];
if (v < 0)
break;
r = (r * 10) + v;
@@ -229,7 +240,7 @@ public static final long parseLongBase10(final byte[] b, int ptr,
}
while (ptr < sz) {
- final byte v = digits[b[ptr]];
+ final byte v = digits10[b[ptr]];
if (v < 0)
break;
r = (r * 10) + v;
@@ -244,6 +255,63 @@ public static final long parseLongBase10(final byte[] b, int ptr,
}
/**
+ * Parse 8 character base 16 (hex) formatted string to unsigned integer.
+ * <p>
+ * The number is read in network byte order, that is, most significant
+ * nybble first.
+ *
+ * @param bs
+ * buffer to parse digits from; positions {@code [p, p+8)} will
+ * be parsed.
+ * @param p
+ * first position within the buffer to parse.
+ * @return the integer value.
+ * @throws ArrayIndexOutOfBoundsException
+ * if the string is not hex formatted.
+ */
+ public static final int parseHexInt32(final byte[] bs, final int p) {
+ int r = digits16[bs[p]] << 4;
+
+ r |= digits16[bs[p + 1]];
+ r <<= 4;
+
+ r |= digits16[bs[p + 2]];
+ r <<= 4;
+
+ r |= digits16[bs[p + 3]];
+ r <<= 4;
+
+ r |= digits16[bs[p + 4]];
+ r <<= 4;
+
+ r |= digits16[bs[p + 5]];
+ r <<= 4;
+
+ r |= digits16[bs[p + 6]];
+
+ final int last = digits16[bs[p + 7]];
+ if (r < 0 || last < 0)
+ throw new ArrayIndexOutOfBoundsException();
+ return (r << 4) | last;
+ }
+
+ /**
+ * Parse a single hex digit to its numeric value (0-15).
+ *
+ * @param digit
+ * hex character to parse.
+ * @return numeric value, in the range 0-15.
+ * @throws ArrayIndexOutOfBoundsException
+ * if the input digit is not a valid hex digit.
+ */
+ public static final int parseHexInt4(final byte digit) {
+ final byte r = digits16[digit];
+ if (r < 0)
+ throw new ArrayIndexOutOfBoundsException();
+ return r;
+ }
+
+ /**
* Parse a Git style timezone string.
* <p>
* The sequence "-0315" will be parsed as the numeric value -195, as the