* [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
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).