git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Shawn O. Pearce" <spearce@spearce.org>
To: Robin Rosenberg <robin.rosenberg@dewire.com>
Cc: git@vger.kernel.org
Subject: [JGIT PATCH 1/7] Move hex parsing functions to RawParseUtil, accept upper case
Date: Thu,  4 Jun 2009 14:43:57 -0700	[thread overview]
Message-ID: <1244151843-26954-2-git-send-email-spearce@spearce.org> (raw)
In-Reply-To: <1244151843-26954-1-git-send-email-spearce@spearce.org>

This way we can reuse them beyond just the ObjectId family of classes.

We also now accept upper case hex digits in object ids.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../tst/org/spearce/jgit/lib/T0001_ObjectId.java   |   10 ++-
 .../org/spearce/jgit/lib/AbbreviatedObjectId.java  |    8 +-
 .../src/org/spearce/jgit/lib/AnyObjectId.java      |   36 ---------
 .../src/org/spearce/jgit/lib/MutableObjectId.java  |   11 ++-
 .../src/org/spearce/jgit/lib/ObjectId.java         |   19 +++--
 .../src/org/spearce/jgit/util/RawParseUtils.java   |   80 ++++++++++++++++++--
 6 files changed, 101 insertions(+), 63 deletions(-)

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
-- 
1.6.3.1.333.g3ebba7

  reply	other threads:[~2009-06-04 21:45 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-04 21:43 [JGIT PATCH 0/7] Misc. transport cleanup Shawn O. Pearce
2009-06-04 21:43 ` Shawn O. Pearce [this message]
2009-06-04 21:43   ` [JGIT PATCH 2/7] Disambiguate pkt-line "0000" from "0004" Shawn O. Pearce
2009-06-04 21:43     ` [JGIT PATCH 3/7] Move PacketLineIn hex parsing to RawParseUtils Shawn O. Pearce
2009-06-04 21:44       ` [JGIT PATCH 4/7] Add tests for RawParseUtil's hex string parsing Shawn O. Pearce
2009-06-04 21:44         ` [JGIT PATCH 5/7] Add tests for PacketLineIn Shawn O. Pearce
2009-06-04 21:44           ` [JGIT PATCH 6/7] Add tests for PacketLineOut Shawn O. Pearce
2009-06-04 21:44             ` [JGIT PATCH 7/7] Add tests for SideBandOutputStream Shawn O. Pearce
2009-06-15 14:36   ` [JGIT PATCH 1/7] Move hex parsing functions to RawParseUtil, accept upper case Shawn O. Pearce

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1244151843-26954-2-git-send-email-spearce@spearce.org \
    --to=spearce@spearce.org \
    --cc=git@vger.kernel.org \
    --cc=robin.rosenberg@dewire.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).