* [JGIT PATCH 0/7] Misc. transport cleanup
@ 2009-06-04 21:43 Shawn O. Pearce
2009-06-04 21:43 ` [JGIT PATCH 1/7] Move hex parsing functions to RawParseUtil, accept upper case Shawn O. Pearce
0 siblings, 1 reply; 9+ messages in thread
From: Shawn O. Pearce @ 2009-06-04 21:43 UTC (permalink / raw)
To: Robin Rosenberg; +Cc: git
After the dicussions with Jakub Narebski I realized we aren't as
lenient in parsing hex strings as C Git is. So make it so.
I also added some tests for the lower level parts of the native
protocol, the pkt-line format. Testing is still far from complete
in this area of the code, but we're slightly better now.
Shawn O. Pearce (7):
Move hex parsing functions to RawParseUtil, accept upper case
Disambiguate pkt-line "0000" from "0004"
Move PacketLineIn hex parsing to RawParseUtils
Add tests for RawParseUtil's hex string parsing
Add tests for PacketLineIn
Add tests for PacketLineOut
Add tests for SideBandOutputStream
.../tst/org/spearce/jgit/lib/T0001_ObjectId.java | 10 +-
.../spearce/jgit/transport/PacketLineInTest.java | 262 ++++++++++++++++++++
.../spearce/jgit/transport/PacketLineOutTest.java | 175 +++++++++++++
.../jgit/transport/SideBandOutputStreamTest.java | 146 +++++++++++
.../jgit/util/RawParseUtils_HexParseTest.java | 158 ++++++++++++
.../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 +-
.../spearce/jgit/transport/BasePackConnection.java | 5 +-
.../jgit/transport/BasePackPushConnection.java | 2 +-
.../org/spearce/jgit/transport/DaemonClient.java | 5 +-
.../org/spearce/jgit/transport/PacketLineIn.java | 44 +---
.../org/spearce/jgit/transport/ReceivePack.java | 6 +-
.../src/org/spearce/jgit/transport/UploadPack.java | 4 +-
.../src/org/spearce/jgit/util/RawParseUtils.java | 110 ++++++++-
16 files changed, 893 insertions(+), 108 deletions(-)
create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/transport/PacketLineInTest.java
create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/transport/PacketLineOutTest.java
create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/transport/SideBandOutputStreamTest.java
create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/util/RawParseUtils_HexParseTest.java
^ permalink raw reply [flat|nested] 9+ messages in thread
* [JGIT PATCH 1/7] Move hex parsing functions to RawParseUtil, accept upper case
2009-06-04 21:43 [JGIT PATCH 0/7] Misc. transport cleanup Shawn O. Pearce
@ 2009-06-04 21:43 ` Shawn O. Pearce
2009-06-04 21:43 ` [JGIT PATCH 2/7] Disambiguate pkt-line "0000" from "0004" Shawn O. Pearce
2009-06-15 14:36 ` [JGIT PATCH 1/7] Move hex parsing functions to RawParseUtil, accept upper case Shawn O. Pearce
0 siblings, 2 replies; 9+ messages in thread
From: Shawn O. Pearce @ 2009-06-04 21:43 UTC (permalink / raw)
To: Robin Rosenberg; +Cc: git
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
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [JGIT PATCH 2/7] Disambiguate pkt-line "0000" from "0004"
2009-06-04 21:43 ` [JGIT PATCH 1/7] Move hex parsing functions to RawParseUtil, accept upper case Shawn O. Pearce
@ 2009-06-04 21:43 ` Shawn O. Pearce
2009-06-04 21:43 ` [JGIT PATCH 3/7] Move PacketLineIn hex parsing to RawParseUtils Shawn O. Pearce
2009-06-15 14:36 ` [JGIT PATCH 1/7] Move hex parsing functions to RawParseUtil, accept upper case Shawn O. Pearce
1 sibling, 1 reply; 9+ messages in thread
From: Shawn O. Pearce @ 2009-06-04 21:43 UTC (permalink / raw)
To: Robin Rosenberg; +Cc: git
The pkt-line length includes its own 4 bytes. So "0000" is the
magic flush/end marker used as part of the protocols based upon
pkt-line, while "0004" indicates a packet of 0 bytes, but not a
flush/end marker.
Currently there is no need for this distinction in the code, as
the protocol never sends an empty packet, but it reduces the risk
that in the future a "0004" packet is misread as a "0000" flush.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
.../spearce/jgit/transport/BasePackConnection.java | 5 ++---
.../jgit/transport/BasePackPushConnection.java | 2 +-
.../org/spearce/jgit/transport/DaemonClient.java | 5 +----
.../org/spearce/jgit/transport/PacketLineIn.java | 18 +++++++++---------
.../org/spearce/jgit/transport/ReceivePack.java | 6 +++---
.../src/org/spearce/jgit/transport/UploadPack.java | 4 ++--
6 files changed, 18 insertions(+), 22 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java
index c6440c7..0382d2b 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java
@@ -140,6 +140,8 @@ private void readAdvertisedRefsImpl() throws IOException {
throw noRepository();
throw eof;
}
+ if (line == PacketLineIn.END)
+ break;
if (avail.isEmpty()) {
final int nul = line.indexOf('\0');
@@ -152,9 +154,6 @@ private void readAdvertisedRefsImpl() throws IOException {
}
}
- if (line.length() == 0)
- break;
-
String name = line.substring(41, line.length());
if (avail.isEmpty() && name.equals("capabilities^{}")) {
// special line from git-receive-pack to show
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackPushConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackPushConnection.java
index 1117109..712d3c0 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackPushConnection.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackPushConnection.java
@@ -225,7 +225,7 @@ private void readStatusReport(final Map<String, RemoteRefUpdate> refUpdates)
+ unpackStatus);
String refLine;
- while ((refLine = pckIn.readString()).length() > 0) {
+ while ((refLine = pckIn.readString()) != PacketLineIn.END) {
boolean ok = false;
int refNameEnd = -1;
if (refLine.startsWith("ok ")) {
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/DaemonClient.java b/org.spearce.jgit/src/org/spearce/jgit/transport/DaemonClient.java
index 636cf22..e80d86b 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/DaemonClient.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/DaemonClient.java
@@ -85,10 +85,7 @@ void execute(final InputStream in, final OutputStream out)
rawIn = in;
rawOut = out;
- String cmd = new PacketLineIn(rawIn).readStringNoLF();
- if (cmd == null || cmd.length() == 0)
- return;
-
+ String cmd = new PacketLineIn(rawIn).readStringRaw();
final int nul = cmd.indexOf('\0');
if (nul >= 0) {
// Newer clients hide a "host" header behind this byte.
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/PacketLineIn.java b/org.spearce.jgit/src/org/spearce/jgit/transport/PacketLineIn.java
index ef218be..92c7009 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/PacketLineIn.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/PacketLineIn.java
@@ -50,6 +50,7 @@
import org.spearce.jgit.util.RawParseUtils;
class PacketLineIn {
+ static final String END = new String("") /* must not string pool */;
private static final byte fromhex[];
static {
@@ -101,20 +102,23 @@ AckNackResult readACK(final MutableObjectId returnedId) throws IOException {
String readString() throws IOException {
int len = readLength();
if (len == 0)
- return "";
+ return END;
- len -= 5; // length header (4 bytes) and trailing LF.
+ len -= 4; // length header (4 bytes)
+ if (len == 0)
+ return "";
final byte[] raw = new byte[len];
NB.readFully(in, raw, 0, len);
- readLF();
+ if (raw[len - 1] == '\n')
+ len--;
return RawParseUtils.decode(Constants.CHARSET, raw, 0, len);
}
- String readStringNoLF() throws IOException {
+ String readStringRaw() throws IOException {
int len = readLength();
if (len == 0)
- return "";
+ return END;
len -= 4; // length header (4 bytes)
@@ -123,10 +127,6 @@ String readStringNoLF() throws IOException {
return RawParseUtils.decode(Constants.CHARSET, raw, 0, len);
}
- private void readLF() throws IOException {
- if (in.read() != '\n')
- throw new IOException("Protocol error: expected LF");
- }
int readLength() throws IOException {
NB.readFully(in, lenbuffer, 0, 4);
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/ReceivePack.java b/org.spearce.jgit/src/org/spearce/jgit/transport/ReceivePack.java
index eaa1016..abaf876 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/ReceivePack.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/ReceivePack.java
@@ -506,12 +506,14 @@ private void recvCommands() throws IOException {
for (;;) {
String line;
try {
- line = pckIn.readStringNoLF();
+ line = pckIn.readStringRaw();
} catch (EOFException eof) {
if (commands.isEmpty())
return;
throw eof;
}
+ if (line == PacketLineIn.END)
+ break;
if (commands.isEmpty()) {
final int nul = line.indexOf('\0');
@@ -522,8 +524,6 @@ private void recvCommands() throws IOException {
}
}
- if (line.length() == 0)
- break;
if (line.length() < 83) {
final String m = "error: invalid protocol: wanted 'old new ref'";
sendError(m);
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/UploadPack.java b/org.spearce.jgit/src/org/spearce/jgit/transport/UploadPack.java
index 45d57b3..53fbce0 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/UploadPack.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/UploadPack.java
@@ -293,7 +293,7 @@ private void recvWants() throws IOException {
throw eof;
}
- if (line.length() == 0)
+ if (line == PacketLineIn.END)
break;
if (!line.startsWith("want ") || line.length() < 45)
throw new PackProtocolException("expected want; got " + line);
@@ -348,7 +348,7 @@ private void negotiate() throws IOException {
throw eof;
}
- if (line.length() == 0) {
+ if (line == PacketLineIn.END) {
if (commonBase.isEmpty() || multiAck)
pckOut.writeString("NAK\n");
pckOut.flush();
--
1.6.3.1.333.g3ebba7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [JGIT PATCH 3/7] Move PacketLineIn hex parsing to RawParseUtils
2009-06-04 21:43 ` [JGIT PATCH 2/7] Disambiguate pkt-line "0000" from "0004" Shawn O. Pearce
@ 2009-06-04 21:43 ` Shawn O. Pearce
2009-06-04 21:44 ` [JGIT PATCH 4/7] Add tests for RawParseUtil's hex string parsing Shawn O. Pearce
0 siblings, 1 reply; 9+ messages in thread
From: Shawn O. Pearce @ 2009-06-04 21:43 UTC (permalink / raw)
To: Robin Rosenberg; +Cc: git
This way we can reuse the same declaration buffer, and accept
uppercase digits as well as lowercase digits.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
.../org/spearce/jgit/transport/PacketLineIn.java | 26 ++---------------
.../src/org/spearce/jgit/util/RawParseUtils.java | 30 ++++++++++++++++++++
2 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/PacketLineIn.java b/org.spearce.jgit/src/org/spearce/jgit/transport/PacketLineIn.java
index 92c7009..8d2cd18 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/PacketLineIn.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/PacketLineIn.java
@@ -40,7 +40,6 @@
import java.io.IOException;
import java.io.InputStream;
-import java.util.Arrays;
import org.spearce.jgit.errors.PackProtocolException;
import org.spearce.jgit.lib.Constants;
@@ -51,16 +50,6 @@
class PacketLineIn {
static final String END = new String("") /* must not string pool */;
- private 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);
- }
static enum AckNackResult {
/** NAK */
@@ -127,22 +116,13 @@ String readStringRaw() throws IOException {
return RawParseUtils.decode(Constants.CHARSET, raw, 0, len);
}
-
int readLength() throws IOException {
NB.readFully(in, lenbuffer, 0, 4);
try {
- int r = fromhex[lenbuffer[0]] << 4;
-
- r |= fromhex[lenbuffer[1]];
- r <<= 4;
-
- r |= fromhex[lenbuffer[2]];
- r <<= 4;
-
- r |= fromhex[lenbuffer[3]];
- if (r < 0)
+ final int len = RawParseUtils.parseHexInt16(lenbuffer, 0);
+ if (len != 0 && len < 4)
throw new ArrayIndexOutOfBoundsException();
- return r;
+ return len;
} catch (ArrayIndexOutOfBoundsException err) {
throw new IOException("Invalid packet line header: "
+ (char) lenbuffer[0] + (char) lenbuffer[1]
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 0554acb..5fb3d27 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/util/RawParseUtils.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/util/RawParseUtils.java
@@ -255,6 +255,36 @@ public static final long parseLongBase10(final byte[] b, int ptr,
}
/**
+ * Parse 4 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+4)} 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 parseHexInt16(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]];
+ if (r < 0)
+ throw new ArrayIndexOutOfBoundsException();
+ return r;
+ }
+
+ /**
* Parse 8 character base 16 (hex) formatted string to unsigned integer.
* <p>
* The number is read in network byte order, that is, most significant
--
1.6.3.1.333.g3ebba7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [JGIT PATCH 4/7] Add tests for RawParseUtil's hex string parsing
2009-06-04 21:43 ` [JGIT PATCH 3/7] Move PacketLineIn hex parsing to RawParseUtils Shawn O. Pearce
@ 2009-06-04 21:44 ` Shawn O. Pearce
2009-06-04 21:44 ` [JGIT PATCH 5/7] Add tests for PacketLineIn Shawn O. Pearce
0 siblings, 1 reply; 9+ messages in thread
From: Shawn O. Pearce @ 2009-06-04 21:44 UTC (permalink / raw)
To: Robin Rosenberg; +Cc: git
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
.../jgit/util/RawParseUtils_HexParseTest.java | 158 ++++++++++++++++++++
1 files changed, 158 insertions(+), 0 deletions(-)
create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/util/RawParseUtils_HexParseTest.java
diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/util/RawParseUtils_HexParseTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/util/RawParseUtils_HexParseTest.java
new file mode 100644
index 0000000..0f0ddde
--- /dev/null
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/util/RawParseUtils_HexParseTest.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2009, Google Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Git Development Community nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.spearce.jgit.util;
+
+import junit.framework.TestCase;
+
+import org.spearce.jgit.lib.Constants;
+
+public class RawParseUtils_HexParseTest extends TestCase {
+ public void testInt4_1() {
+ assertEquals(0, RawParseUtils.parseHexInt4((byte) '0'));
+ assertEquals(1, RawParseUtils.parseHexInt4((byte) '1'));
+ assertEquals(2, RawParseUtils.parseHexInt4((byte) '2'));
+ assertEquals(3, RawParseUtils.parseHexInt4((byte) '3'));
+ assertEquals(4, RawParseUtils.parseHexInt4((byte) '4'));
+ assertEquals(5, RawParseUtils.parseHexInt4((byte) '5'));
+ assertEquals(6, RawParseUtils.parseHexInt4((byte) '6'));
+ assertEquals(7, RawParseUtils.parseHexInt4((byte) '7'));
+ assertEquals(8, RawParseUtils.parseHexInt4((byte) '8'));
+ assertEquals(9, RawParseUtils.parseHexInt4((byte) '9'));
+ assertEquals(10, RawParseUtils.parseHexInt4((byte) 'a'));
+ assertEquals(11, RawParseUtils.parseHexInt4((byte) 'b'));
+ assertEquals(12, RawParseUtils.parseHexInt4((byte) 'c'));
+ assertEquals(13, RawParseUtils.parseHexInt4((byte) 'd'));
+ assertEquals(14, RawParseUtils.parseHexInt4((byte) 'e'));
+ assertEquals(15, RawParseUtils.parseHexInt4((byte) 'f'));
+
+ assertEquals(10, RawParseUtils.parseHexInt4((byte) 'A'));
+ assertEquals(11, RawParseUtils.parseHexInt4((byte) 'B'));
+ assertEquals(12, RawParseUtils.parseHexInt4((byte) 'C'));
+ assertEquals(13, RawParseUtils.parseHexInt4((byte) 'D'));
+ assertEquals(14, RawParseUtils.parseHexInt4((byte) 'E'));
+ assertEquals(15, RawParseUtils.parseHexInt4((byte) 'F'));
+
+ assertNotHex('q');
+ assertNotHex(' ');
+ assertNotHex('.');
+ }
+
+ private static void assertNotHex(final char c) {
+ try {
+ RawParseUtils.parseHexInt4((byte) c);
+ fail("Incorrectly acccepted " + c);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // pass
+ }
+ }
+
+ public void testInt16() {
+ assertEquals(0x0000, parse16("0000"));
+ assertEquals(0x0001, parse16("0001"));
+ assertEquals(0x1234, parse16("1234"));
+ assertEquals(0xdead, parse16("dead"));
+ assertEquals(0xBEEF, parse16("BEEF"));
+ assertEquals(0x4321, parse16("4321"));
+ assertEquals(0xffff, parse16("ffff"));
+
+ try {
+ parse16("noth");
+ fail("Incorrectly acccepted \"noth\"");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // pass
+ }
+
+ try {
+ parse16("01");
+ fail("Incorrectly acccepted \"01\"");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // pass
+ }
+
+ try {
+ parse16("000.");
+ fail("Incorrectly acccepted \"000.\"");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // pass
+ }
+ }
+
+ private static int parse16(final String str) {
+ return RawParseUtils.parseHexInt16(Constants.encodeASCII(str), 0);
+ }
+
+ public void testInt32() {
+ assertEquals(0x00000000, parse32("00000000"));
+ assertEquals(0x00000001, parse32("00000001"));
+ assertEquals(0xc0ffEE42, parse32("c0ffEE42"));
+ assertEquals(0xffffffff, parse32("ffffffff"));
+ assertEquals(-1, parse32("ffffffff"));
+
+ try {
+ parse32("noth");
+ fail("Incorrectly acccepted \"noth\"");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // pass
+ }
+
+ try {
+ parse32("notahexs");
+ fail("Incorrectly acccepted \"notahexs\"");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // pass
+ }
+
+ try {
+ parse32("01");
+ fail("Incorrectly acccepted \"01\"");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // pass
+ }
+
+ try {
+ parse32("0000000.");
+ fail("Incorrectly acccepted \"0000000.\"");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // pass
+ }
+ }
+
+ private static int parse32(final String str) {
+ return RawParseUtils.parseHexInt32(Constants.encodeASCII(str), 0);
+ }
+}
--
1.6.3.1.333.g3ebba7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [JGIT PATCH 5/7] Add tests for PacketLineIn
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 ` Shawn O. Pearce
2009-06-04 21:44 ` [JGIT PATCH 6/7] Add tests for PacketLineOut Shawn O. Pearce
0 siblings, 1 reply; 9+ messages in thread
From: Shawn O. Pearce @ 2009-06-04 21:44 UTC (permalink / raw)
To: Robin Rosenberg; +Cc: git
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
.../spearce/jgit/transport/PacketLineInTest.java | 262 ++++++++++++++++++++
1 files changed, 262 insertions(+), 0 deletions(-)
create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/transport/PacketLineInTest.java
diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/transport/PacketLineInTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/transport/PacketLineInTest.java
new file mode 100644
index 0000000..b9ab50e
--- /dev/null
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/transport/PacketLineInTest.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2009, Google Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Git Development Community nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.spearce.jgit.transport;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.spearce.jgit.lib.Constants;
+import org.spearce.jgit.lib.MutableObjectId;
+import org.spearce.jgit.lib.ObjectId;
+
+// Note, test vectors created with:
+//
+// perl -e 'printf "%4.4x%s\n", 4+length($ARGV[0]),$ARGV[0]'
+
+public class PacketLineInTest extends TestCase {
+ private ByteArrayInputStream rawIn;
+
+ private PacketLineIn in;
+
+ // readString
+
+ public void testReadString1() throws IOException {
+ init("0006a\n0007bc\n");
+ assertEquals("a", in.readString());
+ assertEquals("bc", in.readString());
+ assertEOF();
+ }
+
+ public void testReadString2() throws IOException {
+ init("0032want fcfcfb1fd94829c1a1704f894fc111d14770d34e\n");
+ final String act = in.readString();
+ assertEquals("want fcfcfb1fd94829c1a1704f894fc111d14770d34e", act);
+ assertEOF();
+ }
+
+ public void testReadString4() throws IOException {
+ init("0005a0006bc");
+ assertEquals("a", in.readString());
+ assertEquals("bc", in.readString());
+ assertEOF();
+ }
+
+ public void testReadString5() throws IOException {
+ // accept both upper and lower case
+ init("000Fhi i am a s");
+ assertEquals("hi i am a s", in.readString());
+ assertEOF();
+
+ init("000fhi i am a s");
+ assertEquals("hi i am a s", in.readString());
+ assertEOF();
+ }
+
+ public void testReadString_LenHELO() {
+ init("HELO");
+ try {
+ in.readString();
+ fail("incorrectly accepted invalid packet header");
+ } catch (IOException e) {
+ assertEquals("Invalid packet line header: HELO", e.getMessage());
+ }
+ }
+
+ public void testReadString_Len0001() {
+ init("0001");
+ try {
+ in.readString();
+ fail("incorrectly accepted invalid packet header");
+ } catch (IOException e) {
+ assertEquals("Invalid packet line header: 0001", e.getMessage());
+ }
+ }
+
+ public void testReadString_Len0002() {
+ init("0002");
+ try {
+ in.readString();
+ fail("incorrectly accepted invalid packet header");
+ } catch (IOException e) {
+ assertEquals("Invalid packet line header: 0002", e.getMessage());
+ }
+ }
+
+ public void testReadString_Len0003() {
+ init("0003");
+ try {
+ in.readString();
+ fail("incorrectly accepted invalid packet header");
+ } catch (IOException e) {
+ assertEquals("Invalid packet line header: 0003", e.getMessage());
+ }
+ }
+
+ public void testReadString_Len0004() throws IOException {
+ init("0004");
+ final String act = in.readString();
+ assertEquals("", act);
+ assertNotSame(PacketLineIn.END, act);
+ assertEOF();
+ }
+
+ public void testReadString_End() throws IOException {
+ init("0000");
+ assertSame(PacketLineIn.END, in.readString());
+ assertEOF();
+ }
+
+ // readStringNoLF
+
+ public void testReadStringRaw1() throws IOException {
+ init("0005a0006bc");
+ assertEquals("a", in.readStringRaw());
+ assertEquals("bc", in.readStringRaw());
+ assertEOF();
+ }
+
+ public void testReadStringRaw2() throws IOException {
+ init("0031want fcfcfb1fd94829c1a1704f894fc111d14770d34e");
+ final String act = in.readStringRaw();
+ assertEquals("want fcfcfb1fd94829c1a1704f894fc111d14770d34e", act);
+ assertEOF();
+ }
+
+ public void testReadStringRaw3() throws IOException {
+ init("0004");
+ final String act = in.readStringRaw();
+ assertEquals("", act);
+ assertNotSame(PacketLineIn.END, act);
+ assertEOF();
+ }
+
+ public void testReadStringRaw_End() throws IOException {
+ init("0000");
+ assertSame(PacketLineIn.END, in.readStringRaw());
+ assertEOF();
+ }
+
+ public void testReadStringRaw4() {
+ init("HELO");
+ try {
+ in.readStringRaw();
+ fail("incorrectly accepted invalid packet header");
+ } catch (IOException e) {
+ assertEquals("Invalid packet line header: HELO", e.getMessage());
+ }
+ }
+
+ // readACK
+
+ public void testReadACK_NAK() throws IOException {
+ final ObjectId expid = ObjectId
+ .fromString("fcfcfb1fd94829c1a1704f894fc111d14770d34e");
+ final MutableObjectId actid = new MutableObjectId();
+ actid.fromString(expid.name());
+
+ init("0008NAK\n");
+ assertSame(PacketLineIn.AckNackResult.NAK, in.readACK(actid));
+ assertTrue(actid.equals(expid));
+ assertEOF();
+ }
+
+ public void testReadACK_ACK1() throws IOException {
+ final ObjectId expid = ObjectId
+ .fromString("fcfcfb1fd94829c1a1704f894fc111d14770d34e");
+ final MutableObjectId actid = new MutableObjectId();
+
+ init("0031ACK fcfcfb1fd94829c1a1704f894fc111d14770d34e\n");
+ assertSame(PacketLineIn.AckNackResult.ACK, in.readACK(actid));
+ assertTrue(actid.equals(expid));
+ assertEOF();
+ }
+
+ public void testReadACK_ACKcontinue1() throws IOException {
+ final ObjectId expid = ObjectId
+ .fromString("fcfcfb1fd94829c1a1704f894fc111d14770d34e");
+ final MutableObjectId actid = new MutableObjectId();
+
+ init("003aACK fcfcfb1fd94829c1a1704f894fc111d14770d34e continue\n");
+ assertSame(PacketLineIn.AckNackResult.ACK_CONTINUE, in.readACK(actid));
+ assertTrue(actid.equals(expid));
+ assertEOF();
+ }
+
+ public void testReadACK_Invalid1() {
+ init("HELO");
+ try {
+ in.readACK(new MutableObjectId());
+ fail("incorrectly accepted invalid packet header");
+ } catch (IOException e) {
+ assertEquals("Invalid packet line header: HELO", e.getMessage());
+ }
+ }
+
+ public void testReadACK_Invalid2() {
+ init("0009HELO\n");
+ try {
+ in.readACK(new MutableObjectId());
+ fail("incorrectly accepted invalid ACK/NAK");
+ } catch (IOException e) {
+ assertEquals("Expected ACK/NAK, got: HELO", e.getMessage());
+ }
+ }
+
+ public void testReadACK_Invalid3() {
+ init("0000");
+ try {
+ in.readACK(new MutableObjectId());
+ fail("incorrectly accepted no ACK/NAK");
+ } catch (IOException e) {
+ assertEquals("Expected ACK/NAK, found EOF", e.getMessage());
+ }
+ }
+
+ // test support
+
+ private void init(final String msg) {
+ rawIn = new ByteArrayInputStream(Constants.encodeASCII(msg));
+ in = new PacketLineIn(rawIn);
+ }
+
+ private void assertEOF() {
+ assertEquals(-1, rawIn.read());
+ }
+}
--
1.6.3.1.333.g3ebba7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [JGIT PATCH 6/7] Add tests for PacketLineOut
2009-06-04 21:44 ` [JGIT PATCH 5/7] Add tests for PacketLineIn Shawn O. Pearce
@ 2009-06-04 21:44 ` Shawn O. Pearce
2009-06-04 21:44 ` [JGIT PATCH 7/7] Add tests for SideBandOutputStream Shawn O. Pearce
0 siblings, 1 reply; 9+ messages in thread
From: Shawn O. Pearce @ 2009-06-04 21:44 UTC (permalink / raw)
To: Robin Rosenberg; +Cc: git
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
.../spearce/jgit/transport/PacketLineOutTest.java | 175 ++++++++++++++++++++
1 files changed, 175 insertions(+), 0 deletions(-)
create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/transport/PacketLineOutTest.java
diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/transport/PacketLineOutTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/transport/PacketLineOutTest.java
new file mode 100644
index 0000000..de0f222
--- /dev/null
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/transport/PacketLineOutTest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2009, Google Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Git Development Community nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.spearce.jgit.transport;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import junit.framework.TestCase;
+
+import org.spearce.jgit.lib.Constants;
+
+// Note, test vectors created with:
+//
+// perl -e 'printf "%4.4x%s\n", 4+length($ARGV[0]),$ARGV[0]'
+
+public class PacketLineOutTest extends TestCase {
+ private ByteArrayOutputStream rawOut;
+
+ private PacketLineOut out;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ rawOut = new ByteArrayOutputStream();
+ out = new PacketLineOut(rawOut);
+ }
+
+ // writeString
+
+ public void testWriteString1() throws IOException {
+ out.writeString("a");
+ out.writeString("bc");
+ assertBuffer("0005a0006bc");
+ }
+
+ public void testWriteString2() throws IOException {
+ out.writeString("a\n");
+ out.writeString("bc\n");
+ assertBuffer("0006a\n0007bc\n");
+ }
+
+ public void testWriteString3() throws IOException {
+ out.writeString("");
+ assertBuffer("0004");
+ }
+
+ // end
+
+ public void testWriteEnd() throws IOException {
+ final int[] flushCnt = new int[1];
+ final OutputStream mockout = new OutputStream() {
+ @Override
+ public void write(int arg0) throws IOException {
+ rawOut.write(arg0);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ flushCnt[0]++;
+ }
+ };
+
+ new PacketLineOut(mockout).end();
+ assertBuffer("0000");
+ assertEquals(1, flushCnt[0]);
+ }
+
+ // writePacket
+
+ public void testWritePacket1() throws IOException {
+ out.writePacket(new byte[] { 'a' });
+ assertBuffer("0005a");
+ }
+
+ public void testWritePacket2() throws IOException {
+ out.writePacket(new byte[] { 'a', 'b', 'c', 'd' });
+ assertBuffer("0008abcd");
+ }
+
+ public void testWritePacket3() throws IOException {
+ final int buflen = SideBandOutputStream.MAX_BUF
+ - SideBandOutputStream.HDR_SIZE;
+ final byte[] buf = new byte[buflen];
+ for (int i = 0; i < buf.length; i++) {
+ buf[i] = (byte) i;
+ }
+ out.writePacket(buf);
+ out.flush();
+
+ final byte[] act = rawOut.toByteArray();
+ final String explen = Integer.toString(buf.length + 4, 16);
+ assertEquals(4 + buf.length, act.length);
+ assertEquals(new String(act, 0, 4, "UTF-8"), explen);
+ for (int i = 0, j = 4; i < buf.length; i++, j++) {
+ assertEquals(buf[i], act[j]);
+ }
+ }
+
+ // writeChannelPacket
+
+ public void testWriteChannelPacket1() throws IOException {
+ out.writeChannelPacket(1, new byte[] { 'a' }, 0, 1);
+ assertBuffer("0006\001a");
+ }
+
+ public void testWriteChannelPacket2() throws IOException {
+ out.writeChannelPacket(2, new byte[] { 'b' }, 0, 1);
+ assertBuffer("0006\002b");
+ }
+
+ public void testWriteChannelPacket3() throws IOException {
+ out.writeChannelPacket(3, new byte[] { 'c' }, 0, 1);
+ assertBuffer("0006\003c");
+ }
+
+ // flush
+
+ public void testFlush() throws IOException {
+ final int[] flushCnt = new int[1];
+ final OutputStream mockout = new OutputStream() {
+ @Override
+ public void write(int arg0) throws IOException {
+ fail("should not write");
+ }
+
+ @Override
+ public void flush() throws IOException {
+ flushCnt[0]++;
+ }
+ };
+
+ new PacketLineOut(mockout).flush();
+ assertEquals(1, flushCnt[0]);
+ }
+
+ private void assertBuffer(final String exp) throws IOException {
+ assertEquals(exp, new String(rawOut.toByteArray(),
+ Constants.CHARACTER_ENCODING));
+ }
+}
--
1.6.3.1.333.g3ebba7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [JGIT PATCH 7/7] Add tests for SideBandOutputStream
2009-06-04 21:44 ` [JGIT PATCH 6/7] Add tests for PacketLineOut Shawn O. Pearce
@ 2009-06-04 21:44 ` Shawn O. Pearce
0 siblings, 0 replies; 9+ messages in thread
From: Shawn O. Pearce @ 2009-06-04 21:44 UTC (permalink / raw)
To: Robin Rosenberg; +Cc: git
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
.../jgit/transport/SideBandOutputStreamTest.java | 146 ++++++++++++++++++++
1 files changed, 146 insertions(+), 0 deletions(-)
create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/transport/SideBandOutputStreamTest.java
diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/transport/SideBandOutputStreamTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/transport/SideBandOutputStreamTest.java
new file mode 100644
index 0000000..59e55dc
--- /dev/null
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/transport/SideBandOutputStreamTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2009, Google Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Git Development Community nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.spearce.jgit.transport;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import junit.framework.TestCase;
+
+import org.spearce.jgit.lib.Constants;
+
+// Note, test vectors created with:
+//
+// perl -e 'printf "%4.4x%s\n", 4+length($ARGV[0]),$ARGV[0]'
+
+public class SideBandOutputStreamTest extends TestCase {
+ private ByteArrayOutputStream rawOut;
+
+ private PacketLineOut pckOut;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ rawOut = new ByteArrayOutputStream();
+ pckOut = new PacketLineOut(rawOut);
+ }
+
+ public void testWrite_CH_DATA() throws IOException {
+ final SideBandOutputStream out;
+ out = new SideBandOutputStream(SideBandOutputStream.CH_DATA, pckOut);
+ out.write(new byte[] { 'a', 'b', 'c' });
+ assertBuffer("0008\001abc");
+ }
+
+ public void testWrite_CH_PROGRESS() throws IOException {
+ final SideBandOutputStream out;
+ out = new SideBandOutputStream(SideBandOutputStream.CH_PROGRESS, pckOut);
+ out.write(new byte[] { 'a', 'b', 'c' });
+ assertBuffer("0008\002abc");
+ }
+
+ public void testWrite_CH_ERROR() throws IOException {
+ final SideBandOutputStream out;
+ out = new SideBandOutputStream(SideBandOutputStream.CH_ERROR, pckOut);
+ out.write(new byte[] { 'a', 'b', 'c' });
+ assertBuffer("0008\003abc");
+ }
+
+ public void testWrite_Small() throws IOException {
+ final SideBandOutputStream out;
+ out = new SideBandOutputStream(SideBandOutputStream.CH_DATA, pckOut);
+ out.write('a');
+ out.write('b');
+ out.write('c');
+ assertBuffer("0006\001a0006\001b0006\001c");
+ }
+
+ public void testWrite_Large() throws IOException {
+ final int buflen = SideBandOutputStream.MAX_BUF
+ - SideBandOutputStream.HDR_SIZE;
+ final byte[] buf = new byte[buflen];
+ for (int i = 0; i < buf.length; i++) {
+ buf[i] = (byte) i;
+ }
+
+ final SideBandOutputStream out;
+ out = new SideBandOutputStream(SideBandOutputStream.CH_DATA, pckOut);
+ out.write(buf);
+
+ final byte[] act = rawOut.toByteArray();
+ final String explen = Integer.toString(buf.length + 5, 16);
+ assertEquals(5 + buf.length, act.length);
+ assertEquals(new String(act, 0, 4, "UTF-8"), explen);
+ assertEquals(1, act[4]);
+ for (int i = 0, j = 5; i < buf.length; i++, j++) {
+ assertEquals(buf[i], act[j]);
+ }
+ }
+
+ public void testFlush() throws IOException {
+ final int[] flushCnt = new int[1];
+ final OutputStream mockout = new OutputStream() {
+ @Override
+ public void write(int arg0) throws IOException {
+ fail("should not write");
+ }
+
+ @Override
+ public void flush() throws IOException {
+ flushCnt[0]++;
+ }
+ };
+
+ new SideBandOutputStream(SideBandOutputStream.CH_DATA,
+ new PacketLineOut(mockout)).flush();
+ assertEquals(0, flushCnt[0]);
+
+ new SideBandOutputStream(SideBandOutputStream.CH_ERROR,
+ new PacketLineOut(mockout)).flush();
+ assertEquals(1, flushCnt[0]);
+
+ new SideBandOutputStream(SideBandOutputStream.CH_PROGRESS,
+ new PacketLineOut(mockout)).flush();
+ assertEquals(2, flushCnt[0]);
+ }
+
+ private void assertBuffer(final String exp) throws IOException {
+ assertEquals(exp, new String(rawOut.toByteArray(),
+ Constants.CHARACTER_ENCODING));
+ }
+}
--
1.6.3.1.333.g3ebba7
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [JGIT PATCH 1/7] Move hex parsing functions to RawParseUtil, accept upper case
2009-06-04 21:43 ` [JGIT PATCH 1/7] Move hex parsing functions to RawParseUtil, accept upper case Shawn O. Pearce
2009-06-04 21:43 ` [JGIT PATCH 2/7] Disambiguate pkt-line "0000" from "0004" Shawn O. Pearce
@ 2009-06-15 14:36 ` Shawn O. Pearce
1 sibling, 0 replies; 9+ messages in thread
From: Shawn O. Pearce @ 2009-06-15 14:36 UTC (permalink / raw)
To: Robin Rosenberg; +Cc: git
"Shawn O. Pearce" <spearce@spearce.org> wrote:
> 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(-)
Ping on this 7 patch series? Looks like it got dropped? Its the
last outstanding current work I have that I think is ready for
merging to master.
--
Shawn.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2009-06-15 14:36 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-04 21:43 [JGIT PATCH 0/7] Misc. transport cleanup Shawn O. Pearce
2009-06-04 21:43 ` [JGIT PATCH 1/7] Move hex parsing functions to RawParseUtil, accept upper case Shawn O. Pearce
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
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
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 read-only IMAP folder(s) and NNTP newsgroup(s).