mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 03:39:05 +01:00
Compact encodings for integers, strings and byte arrays.
This adds complexity but will save a lot of bandwidth, as most of the strings and byte arrays we want to send are less than 128 bytes. The extra complexity isn't exposed outside of the serial component.
This commit is contained in:
@@ -12,7 +12,7 @@ import org.briarproject.api.UniqueId;
|
||||
public class TestUtils {
|
||||
|
||||
private static final AtomicInteger nextTestDir =
|
||||
new AtomicInteger((int) (Math.random() * 1000 * 1000));
|
||||
new AtomicInteger((int) (Math.random() * 1000 * 1000));
|
||||
private static final Random random = new Random();
|
||||
|
||||
public static void delete(File f) {
|
||||
@@ -45,10 +45,10 @@ public class TestUtils {
|
||||
return b;
|
||||
}
|
||||
|
||||
public static String createRandomString(int length) throws Exception {
|
||||
StringBuilder s = new StringBuilder(length);
|
||||
public static String createRandomString(int length) {
|
||||
char[] c = new char[length];
|
||||
for(int i = 0; i < length; i++)
|
||||
s.append((char) ('a' + random.nextInt(26)));
|
||||
return s.toString();
|
||||
c[i] = (char) ('a' + random.nextInt(26));
|
||||
return new String(c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import static org.junit.Assert.assertArrayEquals;
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import org.briarproject.BriarTestCase;
|
||||
import org.briarproject.TestUtils;
|
||||
import org.briarproject.api.FormatException;
|
||||
import org.briarproject.util.StringUtils;
|
||||
import org.junit.Test;
|
||||
@@ -31,31 +32,128 @@ public class ReaderImplTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadInteger() throws Exception {
|
||||
setContents("02" + "0000000000000000" + "02" + "FFFFFFFFFFFFFFFF"
|
||||
+ "02" + "7FFFFFFFFFFFFFFF" + "02" + "8000000000000000");
|
||||
public void testReadInt8() throws Exception {
|
||||
setContents("02" + "00" + "02" + "FF"
|
||||
+ "02" + "7F" + "02" + "80");
|
||||
assertEquals(0, r.readInteger());
|
||||
assertEquals(-1, r.readInteger());
|
||||
assertEquals(Byte.MAX_VALUE, r.readInteger());
|
||||
assertEquals(Byte.MIN_VALUE, r.readInteger());
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipInt8() throws Exception {
|
||||
setContents("02" + "00");
|
||||
r.skipInteger();
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadInt16() throws Exception {
|
||||
setContents("03" + "0080" + "03" + "FF7F"
|
||||
+ "03" + "7FFF" + "03" + "8000");
|
||||
assertEquals(Byte.MAX_VALUE + 1, r.readInteger());
|
||||
assertEquals(Byte.MIN_VALUE - 1, r.readInteger());
|
||||
assertEquals(Short.MAX_VALUE, r.readInteger());
|
||||
assertEquals(Short.MIN_VALUE, r.readInteger());
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipInt16() throws Exception {
|
||||
setContents("03" + "0080");
|
||||
r.skipInteger();
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadInt32() throws Exception {
|
||||
setContents("04" + "00008000" + "04" + "FFFF7FFF"
|
||||
+ "04" + "7FFFFFFF" + "04" + "80000000");
|
||||
assertEquals(Short.MAX_VALUE + 1, r.readInteger());
|
||||
assertEquals(Short.MIN_VALUE - 1, r.readInteger());
|
||||
assertEquals(Integer.MAX_VALUE, r.readInteger());
|
||||
assertEquals(Integer.MIN_VALUE, r.readInteger());
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipInt32() throws Exception {
|
||||
setContents("04" + "00008000");
|
||||
r.skipInteger();
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadInt64() throws Exception {
|
||||
setContents("05" + "0000000080000000" + "05" + "FFFFFFFF7FFFFFFF"
|
||||
+ "05" + "7FFFFFFFFFFFFFFF" + "05" + "8000000000000000");
|
||||
assertEquals(Integer.MAX_VALUE + 1L, r.readInteger());
|
||||
assertEquals(Integer.MIN_VALUE - 1L, r.readInteger());
|
||||
assertEquals(Long.MAX_VALUE, r.readInteger());
|
||||
assertEquals(Long.MIN_VALUE, r.readInteger());
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipInteger() throws Exception {
|
||||
setContents("02" + "0000000000000000");
|
||||
public void testSkipInt64() throws Exception {
|
||||
setContents("05" + "0000000080000000");
|
||||
r.skipInteger();
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegersMustHaveMinimalLength() throws Exception {
|
||||
// INTEGER_16 could be encoded as INTEGER_8
|
||||
setContents("02" + "7F" + "03" + "007F");
|
||||
assertEquals(Byte.MAX_VALUE, r.readInteger());
|
||||
try {
|
||||
r.readInteger();
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
setContents("02" + "80" + "03" + "FF80");
|
||||
assertEquals(Byte.MIN_VALUE, r.readInteger());
|
||||
try {
|
||||
r.readInteger();
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
// INTEGER_32 could be encoded as INTEGER_16
|
||||
setContents("03" + "7FFF" + "04" + "00007FFF");
|
||||
assertEquals(Short.MAX_VALUE, r.readInteger());
|
||||
try {
|
||||
r.readInteger();
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
setContents("03" + "8000" + "04" + "FFFF8000");
|
||||
assertEquals(Short.MIN_VALUE, r.readInteger());
|
||||
try {
|
||||
r.readInteger();
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
// INTEGER_64 could be encoded as INTEGER_32
|
||||
setContents("04" + "7FFFFFFF" + "05" + "000000007FFFFFFF");
|
||||
assertEquals(Integer.MAX_VALUE, r.readInteger());
|
||||
try {
|
||||
r.readInteger();
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
setContents("04" + "80000000" + "05" + "FFFFFFFF80000000");
|
||||
assertEquals(Integer.MIN_VALUE, r.readInteger());
|
||||
try {
|
||||
r.readInteger();
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFloat() throws Exception {
|
||||
// http://babbage.cs.qc.edu/IEEE-754/Decimal.html
|
||||
// http://steve.hollasch.net/cgindex/coding/ieeefloat.html
|
||||
setContents("03" + "0000000000000000" + "03" + "3FF0000000000000"
|
||||
+ "03" + "4000000000000000" + "03" + "BFF0000000000000"
|
||||
+ "03" + "8000000000000000" + "03" + "FFF0000000000000"
|
||||
+ "03" + "7FF0000000000000" + "03" + "7FF8000000000000");
|
||||
setContents("06" + "0000000000000000" + "06" + "3FF0000000000000"
|
||||
+ "06" + "4000000000000000" + "06" + "BFF0000000000000"
|
||||
+ "06" + "8000000000000000" + "06" + "FFF0000000000000"
|
||||
+ "06" + "7FF0000000000000" + "06" + "7FF8000000000000");
|
||||
assertEquals(0.0, r.readFloat());
|
||||
assertEquals(1.0, r.readFloat());
|
||||
assertEquals(2.0, r.readFloat());
|
||||
@@ -69,25 +167,28 @@ public class ReaderImplTest extends BriarTestCase {
|
||||
|
||||
@Test
|
||||
public void testSkipFloat() throws Exception {
|
||||
setContents("03" + "0000000000000000");
|
||||
setContents("06" + "0000000000000000");
|
||||
r.skipFloat();
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadString() throws Exception {
|
||||
// "foo" and the empty string
|
||||
setContents("04" + "00000003" + "666F6F" + "04" + "00000000");
|
||||
public void testReadString8() throws Exception {
|
||||
String longest = TestUtils.createRandomString(Byte.MAX_VALUE);
|
||||
String longHex = StringUtils.toHexString(longest.getBytes("UTF-8"));
|
||||
// "foo", the empty string, and 127 random letters
|
||||
setContents("07" + "03" + "666F6F" + "07" + "00" +
|
||||
"07" + "7F" + longHex);
|
||||
assertEquals("foo", r.readString(Integer.MAX_VALUE));
|
||||
assertEquals("", r.readString(Integer.MAX_VALUE));
|
||||
assertEquals(longest, r.readString(Integer.MAX_VALUE));
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadStringMaxLength() throws Exception {
|
||||
public void testReadString8ChecksMaxLength() throws Exception {
|
||||
// "foo" twice
|
||||
setContents("04" + "00000003" + "666F6F" +
|
||||
"04" + "00000003" + "666F6F");
|
||||
setContents("07" + "03" + "666F6F" + "07" + "03" + "666F6F");
|
||||
assertEquals("foo", r.readString(3));
|
||||
assertTrue(r.hasString());
|
||||
try {
|
||||
@@ -97,19 +198,22 @@ public class ReaderImplTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipString() throws Exception {
|
||||
// "foo" and the empty string
|
||||
setContents("04" + "00000003" + "666F6F" + "04" + "00000000");
|
||||
public void testSkipString8() throws Exception {
|
||||
String longest = TestUtils.createRandomString(Byte.MAX_VALUE);
|
||||
String longHex = StringUtils.toHexString(longest.getBytes("UTF-8"));
|
||||
// "foo", the empty string, and 127 random letters
|
||||
setContents("07" + "03" + "666F6F" + "07" + "00" +
|
||||
"07" + "7F" + longHex);
|
||||
r.skipString(Integer.MAX_VALUE);
|
||||
r.skipString(Integer.MAX_VALUE);
|
||||
r.skipString(Integer.MAX_VALUE);
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipStringMaxLength() throws Exception {
|
||||
public void testSkipString8ChecksMaxLength() throws Exception {
|
||||
// "foo" twice
|
||||
setContents("04" + "00000003" + "666F6F" +
|
||||
"04" + "00000003" + "666F6F");
|
||||
setContents("07" + "03" + "666F6F" + "07" + "03" + "666F6F");
|
||||
r.skipString(3);
|
||||
assertTrue(r.hasString());
|
||||
try {
|
||||
@@ -119,19 +223,150 @@ public class ReaderImplTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadBytes() throws Exception {
|
||||
// {1, 2, 3} and {}
|
||||
setContents("05" + "00000003" + "010203" + "05" + "00000000");
|
||||
assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes(Integer.MAX_VALUE));
|
||||
assertArrayEquals(new byte[] {}, r.readBytes(Integer.MAX_VALUE));
|
||||
public void testReadString16() throws Exception {
|
||||
String shortest = TestUtils.createRandomString(Byte.MAX_VALUE + 1);
|
||||
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
|
||||
String longest = TestUtils.createRandomString(Short.MAX_VALUE);
|
||||
String longHex = StringUtils.toHexString(longest.getBytes("UTF-8"));
|
||||
// 128 random letters and 2^15 -1 random letters
|
||||
setContents("08" + "0080" + shortHex + "08" + "7FFF" + longHex);
|
||||
assertEquals(shortest, r.readString(Integer.MAX_VALUE));
|
||||
assertEquals(longest, r.readString(Integer.MAX_VALUE));
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadBytesMaxLength() throws Exception {
|
||||
public void testReadString16ChecksMaxLength() throws Exception {
|
||||
String shortest = TestUtils.createRandomString(Byte.MAX_VALUE + 1);
|
||||
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
|
||||
// 128 random letters, twice
|
||||
setContents("08" + "0080" + shortHex + "08" + "0080" + shortHex);
|
||||
assertEquals(shortest, r.readString(Byte.MAX_VALUE + 1));
|
||||
assertTrue(r.hasString());
|
||||
try {
|
||||
r.readString(Byte.MAX_VALUE);
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipString16() throws Exception {
|
||||
String shortest = TestUtils.createRandomString(Byte.MAX_VALUE + 1);
|
||||
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
|
||||
String longest = TestUtils.createRandomString(Short.MAX_VALUE);
|
||||
String longHex = StringUtils.toHexString(longest.getBytes("UTF-8"));
|
||||
// 128 random letters and 2^15 - 1 random letters
|
||||
setContents("08" + "0080" + shortHex + "08" + "7FFF" + longHex);
|
||||
r.skipString(Integer.MAX_VALUE);
|
||||
r.skipString(Integer.MAX_VALUE);
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipString16ChecksMaxLength() throws Exception {
|
||||
String shortest = TestUtils.createRandomString(Byte.MAX_VALUE + 1);
|
||||
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
|
||||
// 128 random letters, twice
|
||||
setContents("08" + "0080" + shortHex + "08" + "0080" + shortHex);
|
||||
r.skipString(Byte.MAX_VALUE + 1);
|
||||
assertTrue(r.hasString());
|
||||
try {
|
||||
r.skipString(Byte.MAX_VALUE);
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadString32() throws Exception {
|
||||
String shortest = TestUtils.createRandomString(Short.MAX_VALUE + 1);
|
||||
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
|
||||
// 2^15 random letters
|
||||
setContents("09" + "00008000" + shortHex);
|
||||
assertEquals(shortest, r.readString(Integer.MAX_VALUE));
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadString32ChecksMaxLength() throws Exception {
|
||||
String shortest = TestUtils.createRandomString(Short.MAX_VALUE + 1);
|
||||
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
|
||||
// 2^15 random letters, twice
|
||||
setContents("09" + "00008000" + shortHex +
|
||||
"09" + "00008000" + shortHex);
|
||||
assertEquals(shortest, r.readString(Short.MAX_VALUE + 1));
|
||||
assertTrue(r.hasString());
|
||||
try {
|
||||
r.readString(Short.MAX_VALUE);
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipString32() throws Exception {
|
||||
String shortest = TestUtils.createRandomString(Short.MAX_VALUE + 1);
|
||||
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
|
||||
// 2^15 random letters, twice
|
||||
setContents("09" + "00008000" + shortHex +
|
||||
"09" + "00008000" + shortHex);
|
||||
r.skipString(Integer.MAX_VALUE);
|
||||
r.skipString(Integer.MAX_VALUE);
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipString32ChecksMaxLength() throws Exception {
|
||||
String shortest = TestUtils.createRandomString(Short.MAX_VALUE + 1);
|
||||
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
|
||||
// 2^15 random letters, twice
|
||||
setContents("09" + "00008000" + shortHex +
|
||||
"09" + "00008000" + shortHex);
|
||||
r.skipString(Short.MAX_VALUE + 1);
|
||||
assertTrue(r.hasString());
|
||||
try {
|
||||
r.skipString(Short.MAX_VALUE);
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringsMustHaveMinimalLength() throws Exception {
|
||||
// STRING_16 could be encoded as STRING_8
|
||||
String longest8 = TestUtils.createRandomString(Byte.MAX_VALUE);
|
||||
String long8Hex = StringUtils.toHexString(longest8.getBytes("UTF-8"));
|
||||
setContents("07" + "7F" + long8Hex + "08" + "007F" + long8Hex);
|
||||
assertEquals(longest8, r.readString(Integer.MAX_VALUE));
|
||||
try {
|
||||
r.readString(Integer.MAX_VALUE);
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
// STRING_32 could be encoded as STRING_16
|
||||
String longest16 = TestUtils.createRandomString(Short.MAX_VALUE);
|
||||
String long16Hex = StringUtils.toHexString(longest16.getBytes("UTF-8"));
|
||||
setContents("08" + "7FFF" + long16Hex + "09" + "00007FFF" + long16Hex);
|
||||
assertEquals(longest16, r.readString(Integer.MAX_VALUE));
|
||||
try {
|
||||
r.readString(Integer.MAX_VALUE);
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadBytes8() throws Exception {
|
||||
byte[] longest = new byte[Byte.MAX_VALUE];
|
||||
String longHex = StringUtils.toHexString(longest);
|
||||
// {1, 2, 3}, {}, and 127 zero bytes
|
||||
setContents("0A" + "03" + "010203" + "0A" + "00" +
|
||||
"0A" + "7F" + longHex);
|
||||
assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes(Integer.MAX_VALUE));
|
||||
assertArrayEquals(new byte[0], r.readBytes(Integer.MAX_VALUE));
|
||||
assertArrayEquals(longest, r.readBytes(Integer.MAX_VALUE));
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadBytes8ChecksMaxLength() throws Exception {
|
||||
// {1, 2, 3} twice
|
||||
setContents("05" + "00000003" + "010203" +
|
||||
"05" + "00000003" + "010203");
|
||||
setContents("0A" + "03" + "010203" + "0A" + "03" + "010203");
|
||||
assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes(3));
|
||||
assertTrue(r.hasBytes());
|
||||
try {
|
||||
@@ -141,19 +376,22 @@ public class ReaderImplTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipBytes() throws Exception {
|
||||
// {1, 2, 3} and {}
|
||||
setContents("05" + "00000003" + "010203" + "05" + "00000000");
|
||||
public void testSkipBytes8() throws Exception {
|
||||
byte[] longest = new byte[Byte.MAX_VALUE];
|
||||
String longHex = StringUtils.toHexString(longest);
|
||||
// {1, 2, 3}, {}, and 127 zero bytes
|
||||
setContents("0A" + "03" + "010203" + "0A" + "00" +
|
||||
"0A" + "7F" + longHex);
|
||||
r.skipBytes(Integer.MAX_VALUE);
|
||||
r.skipBytes(Integer.MAX_VALUE);
|
||||
r.skipBytes(Integer.MAX_VALUE);
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipBytesMaxLength() throws Exception {
|
||||
public void testSkipBytes8ChecksMaxLength() throws Exception {
|
||||
// {1, 2, 3} twice
|
||||
setContents("05" + "00000003" + "010203" +
|
||||
"05" + "00000003" + "010203");
|
||||
setContents("0A" + "03" + "010203" + "0A" + "03" + "010203");
|
||||
r.skipBytes(3);
|
||||
assertTrue(r.hasBytes());
|
||||
try {
|
||||
@@ -162,12 +400,140 @@ public class ReaderImplTest extends BriarTestCase {
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadBytes16() throws Exception {
|
||||
byte[] shortest = new byte[Byte.MAX_VALUE + 1];
|
||||
String shortHex = StringUtils.toHexString(shortest);
|
||||
byte[] longest = new byte[Short.MAX_VALUE];
|
||||
String longHex = StringUtils.toHexString(longest);
|
||||
// 128 zero bytes and 2^15 - 1 zero bytes
|
||||
setContents("0B" + "0080" + shortHex + "0B" + "7FFF" + longHex);
|
||||
assertArrayEquals(shortest, r.readBytes(Integer.MAX_VALUE));
|
||||
assertArrayEquals(longest, r.readBytes(Integer.MAX_VALUE));
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadBytes16ChecksMaxLength() throws Exception {
|
||||
byte[] shortest = new byte[Byte.MAX_VALUE + 1];
|
||||
String shortHex = StringUtils.toHexString(shortest);
|
||||
// 128 zero bytes, twice
|
||||
setContents("0B" + "0080" + shortHex + "0B" + "0080" + shortHex);
|
||||
assertArrayEquals(shortest, r.readBytes(Byte.MAX_VALUE + 1));
|
||||
assertTrue(r.hasBytes());
|
||||
try {
|
||||
r.readBytes(Byte.MAX_VALUE);
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipBytes16() throws Exception {
|
||||
byte[] shortest = new byte[Byte.MAX_VALUE + 1];
|
||||
String shortHex = StringUtils.toHexString(shortest);
|
||||
byte[] longest = new byte[Short.MAX_VALUE];
|
||||
String longHex = StringUtils.toHexString(longest);
|
||||
// 128 zero bytes and 2^15 - 1 zero bytes
|
||||
setContents("0B" + "0080" + shortHex + "0B" + "7FFF" + longHex);
|
||||
r.skipBytes(Integer.MAX_VALUE);
|
||||
r.skipBytes(Integer.MAX_VALUE);
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipBytes16ChecksMaxLength() throws Exception {
|
||||
byte[] shortest = new byte[Byte.MAX_VALUE + 1];
|
||||
String shortHex = StringUtils.toHexString(shortest);
|
||||
// 128 zero bytes, twice
|
||||
setContents("0B" + "0080" + shortHex + "0B" + "0080" + shortHex);
|
||||
r.skipBytes(Byte.MAX_VALUE + 1);
|
||||
assertTrue(r.hasBytes());
|
||||
try {
|
||||
r.skipBytes(Byte.MAX_VALUE);
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadBytes32() throws Exception {
|
||||
byte[] shortest = new byte[Short.MAX_VALUE + 1];
|
||||
String shortHex = StringUtils.toHexString(shortest);
|
||||
// 2^15 zero bytes
|
||||
setContents("0C" + "00008000" + shortHex);
|
||||
assertArrayEquals(shortest, r.readBytes(Integer.MAX_VALUE));
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadBytes32ChecksMaxLength() throws Exception {
|
||||
byte[] shortest = new byte[Short.MAX_VALUE + 1];
|
||||
String shortHex = StringUtils.toHexString(shortest);
|
||||
// 2^15 zero bytes, twice
|
||||
setContents("0C" + "00008000" + shortHex +
|
||||
"0C" + "00008000" + shortHex);
|
||||
assertArrayEquals(shortest, r.readBytes(Short.MAX_VALUE + 1));
|
||||
assertTrue(r.hasBytes());
|
||||
try {
|
||||
r.readBytes(Short.MAX_VALUE);
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipBytes32() throws Exception {
|
||||
byte[] shortest = new byte[Short.MAX_VALUE + 1];
|
||||
String shortHex = StringUtils.toHexString(shortest);
|
||||
// 2^15 zero bytes, twice
|
||||
setContents("0C" + "00008000" + shortHex +
|
||||
"0C" + "00008000" + shortHex);
|
||||
r.skipBytes(Integer.MAX_VALUE);
|
||||
r.skipBytes(Integer.MAX_VALUE);
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipBytes32ChecksMaxLength() throws Exception {
|
||||
byte[] shortest = new byte[Short.MAX_VALUE + 1];
|
||||
String shortHex = StringUtils.toHexString(shortest);
|
||||
// 2^15 zero bytes, twice
|
||||
setContents("0C" + "00008000" + shortHex +
|
||||
"0C" + "00008000" + shortHex);
|
||||
r.skipBytes(Short.MAX_VALUE + 1);
|
||||
assertTrue(r.hasBytes());
|
||||
try {
|
||||
r.skipBytes(Short.MAX_VALUE);
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBytesMustHaveMinimalLength() throws Exception {
|
||||
// BYTES_16 could be encoded as BYTES_8
|
||||
byte[] longest8 = new byte[Byte.MAX_VALUE];
|
||||
String long8Hex = StringUtils.toHexString(longest8);
|
||||
setContents("0A" + "7F" + long8Hex + "0B" + "007F" + long8Hex);
|
||||
assertArrayEquals(longest8, r.readBytes(Integer.MAX_VALUE));
|
||||
try {
|
||||
r.readBytes(Integer.MAX_VALUE);
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
// BYTES_32 could be encoded as BYTES_16
|
||||
byte[] longest16 = new byte[Short.MAX_VALUE];
|
||||
String long16Hex = StringUtils.toHexString(longest16);
|
||||
setContents("0B" + "7FFF" + long16Hex + "0C" + "00007FFF" + long16Hex);
|
||||
assertArrayEquals(longest16, r.readBytes(Integer.MAX_VALUE));
|
||||
try {
|
||||
r.readBytes(Integer.MAX_VALUE);
|
||||
fail();
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadList() throws Exception {
|
||||
// A list containing 2, "foo", and 128
|
||||
setContents("06" + "02" + "0000000000000001" +
|
||||
"04" + "00000003" + "666F6F" +
|
||||
"02" + "0000000000000080" + "09");
|
||||
// A list containing 1, "foo", and 128
|
||||
setContents("0D" + "02" + "01" +
|
||||
"07" + "03" + "666F6F" +
|
||||
"03" + "0080" + "10");
|
||||
r.readListStart();
|
||||
assertFalse(r.hasListEnd());
|
||||
assertEquals(1, r.readInteger());
|
||||
@@ -182,26 +548,26 @@ public class ReaderImplTest extends BriarTestCase {
|
||||
|
||||
@Test
|
||||
public void testSkipList() throws Exception {
|
||||
// A list containing 2, "foo", and 128
|
||||
setContents("06" + "02" + "0000000000000001" +
|
||||
"04" + "00000003" + "666F6F" +
|
||||
"02" + "0000000000000080" + "09");
|
||||
// A list containing 1, "foo", and 128
|
||||
setContents("0D" + "02" + "01" +
|
||||
"07" + "03" + "666F6F" +
|
||||
"03" + "0080" + "10");
|
||||
r.skipList();
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadMap() throws Exception {
|
||||
// A map containing "foo" -> 123 and {} -> null
|
||||
setContents("07" + "04" + "00000003" + "666F6F" +
|
||||
"02" + "000000000000007B" + "05" + "00000000" + "0A" + "09");
|
||||
// A map containing "foo" -> 123 and byte[0] -> null
|
||||
setContents("0E" + "07" + "03" + "666F6F" + "02" + "7B" +
|
||||
"0A" + "00" + "11" + "10");
|
||||
r.readMapStart();
|
||||
assertFalse(r.hasMapEnd());
|
||||
assertEquals("foo", r.readString(1000));
|
||||
assertFalse(r.hasMapEnd());
|
||||
assertEquals(123, r.readInteger());
|
||||
assertFalse(r.hasMapEnd());
|
||||
assertArrayEquals(new byte[] {}, r.readBytes(1000));
|
||||
assertArrayEquals(new byte[0], r.readBytes(1000));
|
||||
assertFalse(r.hasMapEnd());
|
||||
assertTrue(r.hasNull());
|
||||
r.readNull();
|
||||
@@ -212,9 +578,9 @@ public class ReaderImplTest extends BriarTestCase {
|
||||
|
||||
@Test
|
||||
public void testSkipMap() throws Exception {
|
||||
// A map containing "foo" -> 123 and {} -> null
|
||||
setContents("07" + "04" + "00000003" + "666F6F" +
|
||||
"02" + "000000000000007B" + "05" + "00000000" + "0A" + "09");
|
||||
// A map containing "foo" -> 123 and byte[0] -> null
|
||||
setContents("0E" + "07" + "03" + "666F6F" + "02" + "7B" +
|
||||
"0A" + "00" + "11" + "10");
|
||||
r.skipMap();
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
@@ -222,7 +588,7 @@ public class ReaderImplTest extends BriarTestCase {
|
||||
@Test
|
||||
public void testReadStruct() throws Exception {
|
||||
// Two empty structs with IDs 0 and 255
|
||||
setContents("0800" + "09" + "08FF" + "09");
|
||||
setContents("0F00" + "10" + "0FFF" + "10");
|
||||
r.readStructStart(0);
|
||||
r.readStructEnd();
|
||||
r.readStructStart(255);
|
||||
@@ -233,7 +599,7 @@ public class ReaderImplTest extends BriarTestCase {
|
||||
@Test
|
||||
public void testSkipStruct() throws Exception {
|
||||
// Two empty structs with IDs 0 and 255
|
||||
setContents("0800" + "09" + "08FF" + "09");
|
||||
setContents("0F00" + "10" + "0FFF" + "10");
|
||||
r.skipStruct();
|
||||
r.skipStruct();
|
||||
assertTrue(r.eof());
|
||||
@@ -242,21 +608,21 @@ public class ReaderImplTest extends BriarTestCase {
|
||||
@Test
|
||||
public void testSkipNestedStructMapAndList() throws Exception {
|
||||
// A struct containing a map containing two empty lists
|
||||
setContents("0800" + "07" + "06" + "09" + "06" + "09" + "09" + "09");
|
||||
setContents("0F00" + "0E" + "0D" + "10" + "0D" + "10" + "10" + "10");
|
||||
r.skipStruct();
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadNull() throws Exception {
|
||||
setContents("0A");
|
||||
setContents("11");
|
||||
r.readNull();
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipNull() throws Exception {
|
||||
setContents("0A");
|
||||
setContents("11");
|
||||
r.skipNull();
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.briarproject.BriarTestCase;
|
||||
import org.briarproject.TestUtils;
|
||||
import org.briarproject.util.StringUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -36,11 +37,20 @@ public class WriterImplTest extends BriarTestCase {
|
||||
public void testWriteInteger() throws IOException {
|
||||
w.writeInteger(0);
|
||||
w.writeInteger(-1);
|
||||
w.writeInteger(Long.MIN_VALUE);
|
||||
w.writeInteger(Byte.MAX_VALUE);
|
||||
w.writeInteger(Byte.MIN_VALUE);
|
||||
w.writeInteger(Short.MAX_VALUE);
|
||||
w.writeInteger(Short.MIN_VALUE);
|
||||
w.writeInteger(Integer.MAX_VALUE);
|
||||
w.writeInteger(Integer.MIN_VALUE);
|
||||
w.writeInteger(Long.MAX_VALUE);
|
||||
// INTEGER tag, 0, INTEGER tag, -1, etc
|
||||
checkContents("02" + "0000000000000000" + "02" + "FFFFFFFFFFFFFFFF"
|
||||
+ "02" + "8000000000000000" + "02" + "7FFFFFFFFFFFFFFF");
|
||||
w.writeInteger(Long.MIN_VALUE);
|
||||
// INTEGER_8 tag, 0, INTEGER_8 tag, -1, etc
|
||||
checkContents("02" + "00" + "02" + "FF" +
|
||||
"02" + "7F" + "02" + "80" +
|
||||
"03" + "7FFF" + "03" + "8000" +
|
||||
"04" + "7FFFFFFF" + "04" + "80000000" +
|
||||
"05" + "7FFFFFFFFFFFFFFF" + "05" + "8000000000000000");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -55,26 +65,75 @@ public class WriterImplTest extends BriarTestCase {
|
||||
w.writeFloat(Double.NEGATIVE_INFINITY); // 1 2047 0 -> 0xFFF00000...
|
||||
w.writeFloat(Double.POSITIVE_INFINITY); // 0 2047 0 -> 0x7FF00000...
|
||||
w.writeFloat(Double.NaN); // 0 2047 1 -> 0x7FF8000000000000
|
||||
checkContents("03" + "0000000000000000" + "03" + "3FF0000000000000"
|
||||
+ "03" + "4000000000000000" + "03" + "BFF0000000000000"
|
||||
+ "03" + "8000000000000000" + "03" + "FFF0000000000000"
|
||||
+ "03" + "7FF0000000000000" + "03" + "7FF8000000000000");
|
||||
checkContents("06" + "0000000000000000" + "06" + "3FF0000000000000"
|
||||
+ "06" + "4000000000000000" + "06" + "BFF0000000000000"
|
||||
+ "06" + "8000000000000000" + "06" + "FFF0000000000000"
|
||||
+ "06" + "7FF0000000000000" + "06" + "7FF8000000000000");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteString() throws IOException {
|
||||
public void testWriteString8() throws IOException {
|
||||
String longest = TestUtils.createRandomString(Byte.MAX_VALUE);
|
||||
String longHex = StringUtils.toHexString(longest.getBytes("UTF-8"));
|
||||
w.writeString("foo bar baz bam ");
|
||||
// STRING tag, length 16, UTF-8 bytes
|
||||
checkContents("04" + "00000010" + "666F6F206261722062617A2062616D20");
|
||||
w.writeString(longest);
|
||||
// STRING_8 tag, length 16, UTF-8 bytes, STRING_8 tag, length 127,
|
||||
// UTF-8 bytes
|
||||
checkContents("07" + "10" + "666F6F206261722062617A2062616D20" +
|
||||
"07" + "7F" + longHex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteBytes() throws IOException {
|
||||
w.writeBytes(new byte[] {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
});
|
||||
// BYTES tag, length 16, bytes
|
||||
checkContents("05" + "00000010" + "000102030405060708090A0B0C0D0E0F");
|
||||
public void testWriteString16() throws IOException {
|
||||
String shortest = TestUtils.createRandomString(Byte.MAX_VALUE + 1);
|
||||
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
|
||||
String longest = TestUtils.createRandomString(Short.MAX_VALUE);
|
||||
String longHex = StringUtils.toHexString(longest.getBytes("UTF-8"));
|
||||
w.writeString(shortest);
|
||||
w.writeString(longest);
|
||||
// STRING_16 tag, length 128, UTF-8 bytes, STRING_16 tag,
|
||||
// length 2^15 - 1, UTF-8 bytes
|
||||
checkContents("08" + "0080" + shortHex + "08" + "7FFF" + longHex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteString32() throws IOException {
|
||||
String shortest = TestUtils.createRandomString(Short.MAX_VALUE + 1);
|
||||
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
|
||||
w.writeString(shortest);
|
||||
// STRING_32 tag, length 2^15, UTF-8 bytes
|
||||
checkContents("09" + "00008000" + shortHex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteBytes8() throws IOException {
|
||||
byte[] longest = new byte[Byte.MAX_VALUE];
|
||||
String longHex = StringUtils.toHexString(longest);
|
||||
w.writeBytes(new byte[] {1, 2, 3});
|
||||
w.writeBytes(longest);
|
||||
// BYTES_8 tag, length 3, bytes, BYTES_8 tag, length 127, bytes
|
||||
checkContents("0A" + "03" + "010203" + "0A" + "7F" + longHex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteBytes16() throws IOException {
|
||||
byte[] shortest = new byte[Byte.MAX_VALUE + 1];
|
||||
String shortHex = StringUtils.toHexString(shortest);
|
||||
byte[] longest = new byte[Short.MAX_VALUE];
|
||||
String longHex = StringUtils.toHexString(longest);
|
||||
w.writeBytes(shortest);
|
||||
w.writeBytes(longest);
|
||||
// BYTES_16 tag, length 128, bytes, BYTES_16 tag, length 2^15 - 1, bytes
|
||||
checkContents("0B" + "0080" + shortHex + "0B" + "7FFF" + longHex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteBytes32() throws IOException {
|
||||
byte[] shortest = new byte[Short.MAX_VALUE + 1];
|
||||
String shortHex = StringUtils.toHexString(shortest);
|
||||
w.writeBytes(shortest);
|
||||
// BYTES_32 tag, length 2^15, bytes
|
||||
checkContents("0C" + "00008000" + shortHex);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -83,8 +142,7 @@ public class WriterImplTest extends BriarTestCase {
|
||||
for(int i = 0; i < 3; i++) l.add(i);
|
||||
w.writeList(l);
|
||||
// LIST tag, elements as integers, END tag
|
||||
checkContents("06" + "02" + "0000000000000000" +
|
||||
"02" + "0000000000000001" + "02" + "0000000000000002" + "09");
|
||||
checkContents("0D" + "02" + "00" + "02" + "01" + "02" + "02" + "10");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -95,8 +153,7 @@ public class WriterImplTest extends BriarTestCase {
|
||||
l.add(2);
|
||||
w.writeList(l);
|
||||
// LIST tag, 1 as integer, NULL tag, 2 as integer, END tag
|
||||
checkContents("06" + "02" + "0000000000000001" + "0A" +
|
||||
"02" + "0000000000000002" + "09");
|
||||
checkContents("0D" + "02" + "01" + "11" + "02" + "02" + "10");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -106,11 +163,10 @@ public class WriterImplTest extends BriarTestCase {
|
||||
for(int i = 0; i < 4; i++) m.put(i, i + 1);
|
||||
w.writeMap(m);
|
||||
// MAP tag, entries as integers, END tag
|
||||
checkContents("07" + "02" + "0000000000000000" +
|
||||
"02" + "0000000000000001" + "02" + "0000000000000001" +
|
||||
"02" + "0000000000000002" + "02" + "0000000000000002" +
|
||||
"02" + "0000000000000003" + "02" + "0000000000000003" +
|
||||
"02" + "0000000000000004" + "09");
|
||||
checkContents("0E" + "02" + "00" + "02" + "01" +
|
||||
"02" + "01" + "02" + "02" +
|
||||
"02" + "02" + "02" + "03" +
|
||||
"02" + "03" + "02" + "04" + "10");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -121,9 +177,9 @@ public class WriterImplTest extends BriarTestCase {
|
||||
w.writeInteger(128);
|
||||
w.writeListEnd();
|
||||
// LIST tag, 1 as integer, "foo" as string, 128 as integer, END tag
|
||||
checkContents("06" + "02" + "0000000000000001" +
|
||||
"04" + "00000003" + "666F6F" +
|
||||
"02" + "0000000000000080" + "09");
|
||||
checkContents("0D" + "02" + "01" +
|
||||
"07" + "03" + "666F6F" +
|
||||
"03" + "0080" + "10");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -136,8 +192,8 @@ public class WriterImplTest extends BriarTestCase {
|
||||
w.writeMapEnd();
|
||||
// MAP tag, "foo" as string, 123 as integer, {} as bytes, NULL tag,
|
||||
// END tag
|
||||
checkContents("07" + "04" + "00000003" + "666F6F" +
|
||||
"02" + "000000000000007B" + "05" + "00000000" + "0A" + "09");
|
||||
checkContents("0E" + "07" + "03" + "666F6F" +
|
||||
"02" + "7B" + "0A" + "00" + "11" + "10");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -151,9 +207,8 @@ public class WriterImplTest extends BriarTestCase {
|
||||
w.writeMap(m1);
|
||||
// MAP tag, MAP tag, "foo" as string, 123 as integer, END tag,
|
||||
// LIST tag, 1 as integer, END tag, END tag
|
||||
checkContents("07" + "07" + "04" + "00000003" + "666F6F" +
|
||||
"02" + "000000000000007B" + "09" + "06" +
|
||||
"02" + "0000000000000001" + "09" + "09");
|
||||
checkContents("0E" + "0E" + "07" + "03" + "666F6F" +
|
||||
"02" + "7B" + "10" + "0D" + "02" + "01" + "10" + "10");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -161,13 +216,13 @@ public class WriterImplTest extends BriarTestCase {
|
||||
w.writeStructStart(123);
|
||||
w.writeStructEnd();
|
||||
// STRUCT tag, 123 as struct ID, END tag
|
||||
checkContents("08" + "7B" + "09");
|
||||
checkContents("0F" + "7B" + "10");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteNull() throws IOException {
|
||||
w.writeNull();
|
||||
checkContents("0A");
|
||||
checkContents("11");
|
||||
}
|
||||
|
||||
private void checkContents(String hex) throws IOException {
|
||||
|
||||
Reference in New Issue
Block a user