Simplified serialisation format: removed compact encodings.

This commit is contained in:
akwizgran
2013-10-11 15:16:16 +01:00
parent 38c1b4eb97
commit e0d313a28c
7 changed files with 70 additions and 246 deletions

View File

@@ -250,8 +250,7 @@ class ReaderImpl implements Reader {
public boolean hasString() throws IOException { public boolean hasString() throws IOException {
if(!hasLookahead) readLookahead(true); if(!hasLookahead) readLookahead(true);
if(eof) return false; if(eof) return false;
return next == Tag.STRING return next == Tag.STRING;
|| (next & Tag.SHORT_MASK) == Tag.SHORT_STRING;
} }
public String readString() throws IOException { public String readString() throws IOException {
@@ -261,9 +260,7 @@ class ReaderImpl implements Reader {
public String readString(int maxLength) throws IOException { public String readString(int maxLength) throws IOException {
if(!hasString()) throw new FormatException(); if(!hasString()) throw new FormatException();
consumeLookahead(); consumeLookahead();
int length; int length = readLength();
if(next == Tag.STRING) length = readLength();
else length = 0xFF & next ^ Tag.SHORT_STRING;
if(length > maxLength) throw new FormatException(); if(length > maxLength) throw new FormatException();
if(length == 0) return ""; if(length == 0) return "";
readIntoBuffer(length); readIntoBuffer(length);
@@ -289,7 +286,7 @@ class ReaderImpl implements Reader {
public boolean hasBytes() throws IOException { public boolean hasBytes() throws IOException {
if(!hasLookahead) readLookahead(true); if(!hasLookahead) readLookahead(true);
if(eof) return false; if(eof) return false;
return next == Tag.BYTES || (next & Tag.SHORT_MASK) == Tag.SHORT_BYTES; return next == Tag.BYTES;
} }
public byte[] readBytes() throws IOException { public byte[] readBytes() throws IOException {
@@ -299,9 +296,7 @@ class ReaderImpl implements Reader {
public byte[] readBytes(int maxLength) throws IOException { public byte[] readBytes(int maxLength) throws IOException {
if(!hasBytes()) throw new FormatException(); if(!hasBytes()) throw new FormatException();
consumeLookahead(); consumeLookahead();
int length; int length = readLength();
if(next == Tag.BYTES) length = readLength();
else length = 0xFF & next ^ Tag.SHORT_BYTES;
if(length > maxLength) throw new FormatException(); if(length > maxLength) throw new FormatException();
if(length == 0) return EMPTY_BUFFER; if(length == 0) return EMPTY_BUFFER;
byte[] b = new byte[length]; byte[] b = new byte[length];
@@ -312,29 +307,15 @@ class ReaderImpl implements Reader {
public boolean hasList() throws IOException { public boolean hasList() throws IOException {
if(!hasLookahead) readLookahead(true); if(!hasLookahead) readLookahead(true);
if(eof) return false; if(eof) return false;
return next == Tag.LIST return next == Tag.LIST;
|| (next & Tag.SHORT_MASK) == Tag.SHORT_LIST;
} }
public <E> List<E> readList(Class<E> e) throws IOException { public <E> List<E> readList(Class<E> e) throws IOException {
if(!hasList()) throw new FormatException(); if(!hasList()) throw new FormatException();
consumeLookahead(); consumeLookahead();
if(next == Tag.LIST) {
List<E> list = new ArrayList<E>();
while(!hasEnd()) list.add(readObject(e));
readEnd();
return Collections.unmodifiableList(list);
} else {
int length = 0xFF & next ^ Tag.SHORT_LIST;
return readList(e, length);
}
}
private <E> List<E> readList(Class<E> e, int length) throws IOException {
assert length >= 0;
if(length == 0) return Collections.emptyList();
List<E> list = new ArrayList<E>(); List<E> list = new ArrayList<E>();
for(int i = 0; i < length; i++) list.add(readObject(e)); while(!hasEnd()) list.add(readObject(e));
readEnd();
return Collections.unmodifiableList(list); return Collections.unmodifiableList(list);
} }
@@ -419,36 +400,18 @@ class ReaderImpl implements Reader {
public boolean hasMap() throws IOException { public boolean hasMap() throws IOException {
if(!hasLookahead) readLookahead(true); if(!hasLookahead) readLookahead(true);
if(eof) return false; if(eof) return false;
return next == Tag.MAP return next == Tag.MAP;
|| (next & Tag.SHORT_MASK) == Tag.SHORT_MAP;
} }
public <K, V> Map<K, V> readMap(Class<K> k, Class<V> v) throws IOException { public <K, V> Map<K, V> readMap(Class<K> k, Class<V> v) throws IOException {
if(!hasMap()) throw new FormatException(); if(!hasMap()) throw new FormatException();
consumeLookahead(); consumeLookahead();
if(next == Tag.MAP) {
Map<K, V> m = new HashMap<K, V>();
while(!hasEnd()) {
if(m.put(readObject(k), readObject(v)) != null)
throw new FormatException(); // Duplicate key
}
readEnd();
return Collections.unmodifiableMap(m);
} else {
int size = 0xFF & next ^ Tag.SHORT_MAP;
return readMap(k, v, size);
}
}
private <K, V> Map<K, V> readMap(Class<K> k, Class<V> v, int size)
throws IOException {
assert size >= 0;
if(size == 0) return Collections.emptyMap();
Map<K, V> m = new HashMap<K, V>(); Map<K, V> m = new HashMap<K, V>();
for(int i = 0; i < size; i++) { while(!hasEnd()) {
if(m.put(readObject(k), readObject(v)) != null) if(m.put(readObject(k), readObject(v)) != null)
throw new FormatException(); // Duplicate key throw new FormatException(); // Duplicate key
} }
readEnd();
return Collections.unmodifiableMap(m); return Collections.unmodifiableMap(m);
} }
@@ -486,11 +449,7 @@ class ReaderImpl implements Reader {
if(id < 0 || id > 255) throw new IllegalArgumentException(); if(id < 0 || id > 255) throw new IllegalArgumentException();
if(!hasLookahead) readLookahead(true); if(!hasLookahead) readLookahead(true);
if(eof) return false; if(eof) return false;
if(next == Tag.STRUCT) return id == (0xFF & nextNext);
return id == (0xFF & nextNext);
else if((next & Tag.SHORT_STRUCT_MASK) == Tag.SHORT_STRUCT)
return id == (0xFF & next ^ Tag.SHORT_STRUCT);
else return false;
} }
public void readStructId(int id) throws IOException { public void readStructId(int id) throws IOException {

View File

@@ -17,13 +17,4 @@ interface Tag {
byte END = (byte) 0xF3; // 1111 0011 byte END = (byte) 0xF3; // 1111 0011
byte NULL = (byte) 0xF2; // 1111 0010 byte NULL = (byte) 0xF2; // 1111 0010
byte STRUCT = (byte) 0xF1; // 1111 0001 byte STRUCT = (byte) 0xF1; // 1111 0001
int SHORT_STRING = 0x80; // 1000 xxxx
int SHORT_BYTES = 0x90; // 1001 xxxx
int SHORT_LIST = 0xA0; // 1010 xxxx
int SHORT_MAP = 0xB0; // 1011 xxxx
int SHORT_STRUCT = 0xC0; // 110x xxxx
int SHORT_MASK = 0xF0; // Match first four bits
int SHORT_STRUCT_MASK = 0xE0; // Match first three bits
} }

View File

@@ -111,12 +111,8 @@ class WriterImpl implements Writer {
public void writeString(String s) throws IOException { public void writeString(String s) throws IOException {
byte[] b = s.getBytes("UTF-8"); byte[] b = s.getBytes("UTF-8");
if(b.length < 16) { write(Tag.STRING);
write((byte) (Tag.SHORT_STRING | b.length)); writeLength(b.length);
} else {
write(Tag.STRING);
writeLength(b.length);
}
write(b); write(b);
} }
@@ -129,25 +125,15 @@ class WriterImpl implements Writer {
} }
public void writeBytes(byte[] b) throws IOException { public void writeBytes(byte[] b) throws IOException {
if(b.length < 16) { write(Tag.BYTES);
write((byte) (Tag.SHORT_BYTES | b.length)); writeLength(b.length);
} else {
write(Tag.BYTES);
writeLength(b.length);
}
write(b); write(b);
} }
public void writeList(Collection<?> c) throws IOException { public void writeList(Collection<?> c) throws IOException {
int length = c.size(); write(Tag.LIST);
if(length < 16) { for(Object o : c) writeObject(o);
write((byte) (Tag.SHORT_LIST | length)); write(Tag.END);
for(Object o : c) writeObject(o);
} else {
write(Tag.LIST);
for(Object o : c) writeObject(o);
write(Tag.END);
}
} }
private void writeObject(Object o) throws IOException { private void writeObject(Object o) throws IOException {
@@ -175,21 +161,12 @@ class WriterImpl implements Writer {
} }
public void writeMap(Map<?, ?> m) throws IOException { public void writeMap(Map<?, ?> m) throws IOException {
int length = m.size(); write(Tag.MAP);
if(length < 16) { for(Entry<?, ?> e : m.entrySet()) {
write((byte) (Tag.SHORT_MAP | length)); writeObject(e.getKey());
for(Entry<?, ?> e : m.entrySet()) { writeObject(e.getValue());
writeObject(e.getKey());
writeObject(e.getValue());
}
} else {
write(Tag.MAP);
for(Entry<?, ?> e : m.entrySet()) {
writeObject(e.getKey());
writeObject(e.getValue());
}
write(Tag.END);
} }
write(Tag.END);
} }
public void writeMapStart() throws IOException { public void writeMapStart() throws IOException {
@@ -206,12 +183,8 @@ class WriterImpl implements Writer {
public void writeStructId(int id) throws IOException { public void writeStructId(int id) throws IOException {
if(id < 0 || id > 255) throw new IllegalArgumentException(); if(id < 0 || id > 255) throw new IllegalArgumentException();
if(id < 32) { write(Tag.STRUCT);
write((byte) (Tag.SHORT_STRUCT | id)); write((byte) id);
} else {
write(Tag.STRUCT);
write((byte) id);
}
} }
private void write(byte b) throws IOException { private void write(byte b) throws IOException {

View File

@@ -214,10 +214,10 @@ public class PacketReaderImplTest extends BriarTestCase {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer w = writerFactory.createWriter(out); Writer w = writerFactory.createWriter(out);
w.writeStructId(REQUEST); w.writeStructId(REQUEST);
// Allow one byte for the REQUEST tag, one byte for the padding length // Allow one byte for the STRUCT tag, one byte for the REQUEST tag,
// as a uint7, one byte for the BYTES tag, and five bytes for the // one byte for the padding length as a uint7, one byte for the BYTES
// length of the byte array as an int32 // tag, and five bytes for the length of the byte array as an int32
int size = MAX_PACKET_LENGTH - 8; int size = MAX_PACKET_LENGTH - 9;
if(tooBig) size++; if(tooBig) size++;
assertTrue(size > Short.MAX_VALUE); assertTrue(size > Short.MAX_VALUE);
w.writeUint7((byte) 0); w.writeUint7((byte) 0);

View File

@@ -60,9 +60,10 @@ public class PacketWriterImplTest extends BriarTestCase {
b.set(12); b.set(12);
b.set(15); b.set(15);
w.writeRequest(new Request(b, 16)); w.writeRequest(new Request(b, 16));
// Short user tag 5, 0 as uint7, short bytes with length 2, 0xD959 // STRUCT tag, struct ID 5, 0 as uint7, BYTES tag, length 2 as uint7,
// 0xD959
byte[] output = out.toByteArray(); byte[] output = out.toByteArray();
assertEquals("C5" + "00" + "92" + "D959", assertEquals("F1" + "05" + "00" + "F6" + "02" + "D959",
StringUtils.toHexString(output)); StringUtils.toHexString(output));
} }
@@ -83,9 +84,10 @@ public class PacketWriterImplTest extends BriarTestCase {
b.set(11); b.set(11);
b.set(12); b.set(12);
w.writeRequest(new Request(b, 13)); w.writeRequest(new Request(b, 13));
// Short user tag 5, 3 as uint7, short bytes with length 2, 0x59D8 // STRUCT tag, struct ID 5, 3 as uint7, BYTES tag, length 2 as uint7,
// 0xD959
byte[] output = out.toByteArray(); byte[] output = out.toByteArray();
assertEquals("C5" + "03" + "92" + "59D8", assertEquals("F1" + "05" + "03" + "F6" + "02" + "59D8",
StringUtils.toHexString(output)); StringUtils.toHexString(output));
} }
} }

View File

@@ -121,17 +121,15 @@ public class ReaderImplTest extends BriarTestCase {
@Test @Test
public void testReadString() throws Exception { public void testReadString() throws Exception {
setContents("F703666F6F" + "83666F6F" + "F700" + "80"); setContents("F703666F6F" + "F700");
assertEquals("foo", r.readString()); assertEquals("foo", r.readString());
assertEquals("foo", r.readString());
assertEquals("", r.readString());
assertEquals("", r.readString()); assertEquals("", r.readString());
assertTrue(r.eof()); assertTrue(r.eof());
} }
@Test @Test
public void testReadStringMaxLength() throws Exception { public void testReadStringMaxLength() throws Exception {
setContents("83666F6F" + "83666F6F"); setContents("F703666F6F" + "F703666F6F");
assertEquals("foo", r.readString(3)); assertEquals("foo", r.readString(3));
try { try {
r.readString(2); r.readString(2);
@@ -141,17 +139,15 @@ public class ReaderImplTest extends BriarTestCase {
@Test @Test
public void testReadBytes() throws Exception { public void testReadBytes() throws Exception {
setContents("F603010203" + "93010203" + "F600" + "90"); setContents("F603010203" + "F600");
assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes()); assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes());
assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes());
assertArrayEquals(new byte[] {}, r.readBytes());
assertArrayEquals(new byte[] {}, r.readBytes()); assertArrayEquals(new byte[] {}, r.readBytes());
assertTrue(r.eof()); assertTrue(r.eof());
} }
@Test @Test
public void testReadBytesMaxLength() throws Exception { public void testReadBytesMaxLength() throws Exception {
setContents("93010203" + "93010203"); setContents("F603010203" + "F603010203");
assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes(3)); assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes(3));
try { try {
r.readBytes(2); r.readBytes(2);
@@ -159,21 +155,9 @@ public class ReaderImplTest extends BriarTestCase {
} catch(FormatException expected) {} } catch(FormatException expected) {}
} }
@Test
public void testReadShortList() throws Exception {
setContents("A" + "3" + "01" + "83666F6F" + "FC0080");
List<Object> l = r.readList(Object.class);
assertNotNull(l);
assertEquals(3, l.size());
assertEquals((byte) 1, l.get(0));
assertEquals("foo", l.get(1));
assertEquals((short) 128, l.get(2));
assertTrue(r.eof());
}
@Test @Test
public void testReadList() throws Exception { public void testReadList() throws Exception {
setContents("F5" + "01" + "83666F6F" + "FC0080" + "F3"); setContents("F5" + "01" + "F703666F6F" + "FC0080" + "F3");
List<Object> l = r.readList(Object.class); List<Object> l = r.readList(Object.class);
assertNotNull(l); assertNotNull(l);
assertEquals(3, l.size()); assertEquals(3, l.size());
@@ -185,7 +169,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test @Test
public void testReadListTypeSafe() throws Exception { public void testReadListTypeSafe() throws Exception {
setContents("A" + "3" + "01" + "02" + "03"); setContents("F5" + "01" + "02" + "03" + "F3");
List<Byte> l = r.readList(Byte.class); List<Byte> l = r.readList(Byte.class);
assertNotNull(l); assertNotNull(l);
assertEquals(3, l.size()); assertEquals(3, l.size());
@@ -197,7 +181,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test @Test
public void testReadListTypeSafeThrowsFormatException() throws Exception { public void testReadListTypeSafeThrowsFormatException() throws Exception {
setContents("A" + "3" + "01" + "83666F6F" + "03"); setContents("F5" + "01" + "F703666F6F" + "03" + "F3");
// Trying to read a mixed list as a list of bytes should throw a // Trying to read a mixed list as a list of bytes should throw a
// FormatException // FormatException
try { try {
@@ -206,22 +190,9 @@ public class ReaderImplTest extends BriarTestCase {
} catch(FormatException expected) {} } catch(FormatException expected) {}
} }
@Test
public void testReadShortMap() throws Exception {
setContents("B" + "2" + "83666F6F" + "7B" + "90" + "F2");
Map<Object, Object> m = r.readMap(Object.class, Object.class);
assertNotNull(m);
assertEquals(2, m.size());
assertEquals((byte) 123, m.get("foo"));
Bytes b = new Bytes(new byte[] {});
assertTrue(m.containsKey(b));
assertNull(m.get(b));
assertTrue(r.eof());
}
@Test @Test
public void testReadMap() throws Exception { public void testReadMap() throws Exception {
setContents("F4" + "83666F6F" + "7B" + "90" + "F2" + "F3"); setContents("F4" + "F703666F6F" + "7B" + "F600" + "F2" + "F3");
Map<Object, Object> m = r.readMap(Object.class, Object.class); Map<Object, Object> m = r.readMap(Object.class, Object.class);
assertNotNull(m); assertNotNull(m);
assertEquals(2, m.size()); assertEquals(2, m.size());
@@ -234,7 +205,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test @Test
public void testReadMapTypeSafe() throws Exception { public void testReadMapTypeSafe() throws Exception {
setContents("B" + "2" + "83666F6F" + "7B" + "80" + "F2"); setContents("F4" + "F703666F6F" + "7B" + "F700" + "F2" + "F3");
Map<String, Byte> m = r.readMap(String.class, Byte.class); Map<String, Byte> m = r.readMap(String.class, Byte.class);
assertNotNull(m); assertNotNull(m);
assertEquals(2, m.size()); assertEquals(2, m.size());
@@ -246,8 +217,8 @@ public class ReaderImplTest extends BriarTestCase {
@Test @Test
public void testMapKeysMustBeUnique() throws Exception { public void testMapKeysMustBeUnique() throws Exception {
setContents("B" + "2" + "83666F6F" + "01" + "83626172" + "02" setContents("F4" + "F703666F6F" + "01" + "F703626172" + "02" + "F3"
+ "B" + "2" + "83666F6F" + "01" + "83666F6F" + "02"); + "F4" + "F703666F6F" + "01" + "F703666F6F" + "02" + "F3");
// The first map has unique keys // The first map has unique keys
Map<String, Byte> m = r.readMap(String.class, Byte.class); Map<String, Byte> m = r.readMap(String.class, Byte.class);
assertNotNull(m); assertNotNull(m);
@@ -261,21 +232,9 @@ public class ReaderImplTest extends BriarTestCase {
} catch(FormatException expected) {} } catch(FormatException expected) {}
} }
@Test
public void testReadDelimitedList() throws Exception {
setContents("F5" + "01" + "83666F6F" + "FC0080" + "F3");
List<Object> l = r.readList(Object.class);
assertNotNull(l);
assertEquals(3, l.size());
assertEquals((byte) 1, l.get(0));
assertEquals("foo", l.get(1));
assertEquals((short) 128, l.get(2));
assertTrue(r.eof());
}
@Test @Test
public void testReadDelimitedListElements() throws Exception { public void testReadDelimitedListElements() throws Exception {
setContents("F5" + "01" + "83666F6F" + "FC0080" + "F3"); setContents("F5" + "01" + "F703666F6F" + "FC0080" + "F3");
assertTrue(r.hasListStart()); assertTrue(r.hasListStart());
r.readListStart(); r.readListStart();
assertFalse(r.hasListEnd()); assertFalse(r.hasListEnd());
@@ -301,22 +260,9 @@ public class ReaderImplTest extends BriarTestCase {
assertTrue(r.eof()); assertTrue(r.eof());
} }
@Test
public void testReadDelimitedMap() throws Exception {
setContents("F4" + "83666F6F" + "7B" + "90" + "F2" + "F3");
Map<Object, Object> m = r.readMap(Object.class, Object.class);
assertNotNull(m);
assertEquals(2, m.size());
assertEquals((byte) 123, m.get("foo"));
Bytes b = new Bytes(new byte[] {});
assertTrue(m.containsKey(b));
assertNull(m.get(b));
assertTrue(r.eof());
}
@Test @Test
public void testReadDelimitedMapEntries() throws Exception { public void testReadDelimitedMapEntries() throws Exception {
setContents("F4" + "83666F6F" + "7B" + "90" + "F2" + "F3"); setContents("F4" + "F703666F6F" + "7B" + "F600" + "F2" + "F3");
assertTrue(r.hasMapStart()); assertTrue(r.hasMapStart());
r.readMapStart(); r.readMapStart();
assertFalse(r.hasMapEnd()); assertFalse(r.hasMapEnd());
@@ -335,7 +281,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test @Test
public void testReadDelimitedMapTypeSafe() throws Exception { public void testReadDelimitedMapTypeSafe() throws Exception {
setContents("F4" + "83666F6F" + "7B" + "80" + "F2" + "F3"); setContents("F4" + "F703666F6F" + "7B" + "F700" + "F2" + "F3");
Map<String, Byte> m = r.readMap(String.class, Byte.class); Map<String, Byte> m = r.readMap(String.class, Byte.class);
assertNotNull(m); assertNotNull(m);
assertEquals(2, m.size()); assertEquals(2, m.size());
@@ -348,8 +294,8 @@ public class ReaderImplTest extends BriarTestCase {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void testReadNestedMapsAndLists() throws Exception { public void testReadNestedMapsAndLists() throws Exception {
setContents("B" + "1" + "B" + "1" + "83666F6F" + "7B" setContents("F4" + "F4" + "F703666F6F" + "7B" + "F3"
+ "A" + "1" + "01"); + "F5" + "01" + "F3" + "F3");
Map<Object, Object> m = r.readMap(Object.class, Object.class); Map<Object, Object> m = r.readMap(Object.class, Object.class);
assertNotNull(m); assertNotNull(m);
assertEquals(1, m.size()); assertEquals(1, m.size());
@@ -368,7 +314,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test @Test
public void testMaxLengthAppliesInsideMap() throws Exception { public void testMaxLengthAppliesInsideMap() throws Exception {
setContents("B" + "1" + "83666F6F" + "93010203"); setContents("F4" + "F703666F6F" + "F603010203" + "F3");
r.setMaxStringLength(3); r.setMaxStringLength(3);
r.setMaxBytesLength(3); r.setMaxBytesLength(3);
Map<String, Bytes> m = r.readMap(String.class, Bytes.class); Map<String, Bytes> m = r.readMap(String.class, Bytes.class);
@@ -376,14 +322,14 @@ public class ReaderImplTest extends BriarTestCase {
Bytes value = new Bytes(new byte[] {1, 2, 3}); Bytes value = new Bytes(new byte[] {1, 2, 3});
assertEquals(Collections.singletonMap(key, value), m); assertEquals(Collections.singletonMap(key, value), m);
// The max string length should be applied inside the map // The max string length should be applied inside the map
setContents("B" + "1" + "83666F6F" + "93010203"); setContents("F4" + "F703666F6F" + "F603010203" + "F3");
r.setMaxStringLength(2); r.setMaxStringLength(2);
try { try {
r.readMap(String.class, Bytes.class); r.readMap(String.class, Bytes.class);
fail(); fail();
} catch(FormatException expected) {} } catch(FormatException expected) {}
// The max bytes length should be applied inside the map // The max bytes length should be applied inside the map
setContents("B" + "1" + "83666F6F" + "93010203"); setContents("F4" + "F703666F6F" + "F603010203" + "F3");
r.setMaxBytesLength(2); r.setMaxBytesLength(2);
try { try {
r.readMap(String.class, Bytes.class); r.readMap(String.class, Bytes.class);

View File

@@ -133,13 +133,6 @@ public class WriterImplTest extends BriarTestCase {
+ "F8" + "7FF0000000000000" + "F8" + "7FF8000000000000"); + "F8" + "7FF0000000000000" + "F8" + "7FF8000000000000");
} }
@Test
public void testWriteShortString() throws IOException {
w.writeString("foo bar baz bam");
// SHORT_STRING tag, length 15, UTF-8 bytes
checkContents("8" + "F" + "666F6F206261722062617A2062616D");
}
@Test @Test
public void testWriteString() throws IOException { public void testWriteString() throws IOException {
w.writeString("foo bar baz bam "); w.writeString("foo bar baz bam ");
@@ -147,15 +140,6 @@ public class WriterImplTest extends BriarTestCase {
checkContents("F7" + "10" + "666F6F206261722062617A2062616D20"); checkContents("F7" + "10" + "666F6F206261722062617A2062616D20");
} }
@Test
public void testWriteShortBytes() throws IOException {
w.writeBytes(new byte[] {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
});
// SHORT_BYTES tag, length 15, bytes
checkContents("9" + "F" + "000102030405060708090A0B0C0D0E");
}
@Test @Test
public void testWriteBytes() throws IOException { public void testWriteBytes() throws IOException {
w.writeBytes(new byte[] { w.writeBytes(new byte[] {
@@ -165,15 +149,6 @@ public class WriterImplTest extends BriarTestCase {
checkContents("F6" + "10" + "000102030405060708090A0B0C0D0E0F"); checkContents("F6" + "10" + "000102030405060708090A0B0C0D0E0F");
} }
@Test
public void testWriteShortList() throws IOException {
List<Object> l = new ArrayList<Object>();
for(int i = 0; i < 15; i++) l.add(i);
w.writeList(l);
// SHORT_LIST tag, length, elements as uint7
checkContents("A" + "F" + "000102030405060708090A0B0C0D0E");
}
@Test @Test
public void testWriteList() throws IOException { public void testWriteList() throws IOException {
List<Object> l = new ArrayList<Object>(); List<Object> l = new ArrayList<Object>();
@@ -190,20 +165,8 @@ public class WriterImplTest extends BriarTestCase {
l.add(null); l.add(null);
l.add(2); l.add(2);
w.writeList(l); w.writeList(l);
// SHORT_LIST tag, length, 1 as uint7, null, 2 as uint7 // LIST tag, 1 as uint7, null, 2 as uint7, END tag
checkContents("A" + "3" + "01" + "F2" + "02"); checkContents("F5" + "01" + "F2" + "02" + "F3");
}
@Test
public void testWriteShortMap() throws IOException {
// Use LinkedHashMap to get predictable iteration order
Map<Object, Object> m = new LinkedHashMap<Object, Object>();
for(int i = 0; i < 15; i++) m.put(i, i + 1);
w.writeMap(m);
// SHORT_MAP tag, size, entries as uint7
checkContents("B" + "F" + "0001" + "0102" + "0203" + "0304" + "0405"
+ "0506" + "0607" + "0708" + "0809" + "090A" + "0A0B" + "0B0C"
+ "0C0D" + "0D0E" + "0E0F");
} }
@Test @Test
@@ -222,25 +185,24 @@ public class WriterImplTest extends BriarTestCase {
public void testWriteDelimitedList() throws IOException { public void testWriteDelimitedList() throws IOException {
w.writeListStart(); w.writeListStart();
w.writeIntAny((byte) 1); // Written as uint7 w.writeIntAny((byte) 1); // Written as uint7
w.writeString("foo"); // Written as short string w.writeString("foo"); // Written as string
w.writeIntAny(128L); // Written as an int16 w.writeIntAny(128L); // Written as int16
w.writeListEnd(); w.writeListEnd();
// LIST tag, 1 as uint7, "foo" as short string, 128 as int16, // LIST tag, 1 as uint7, "foo" as string, 128 as int16, END tag
// END tag checkContents("F5" + "01" + "F703666F6F" + "FC0080" + "F3");
checkContents("F5" + "01" + "83666F6F" + "FC0080" + "F3");
} }
@Test @Test
public void testWriteDelimitedMap() throws IOException { public void testWriteDelimitedMap() throws IOException {
w.writeMapStart(); w.writeMapStart();
w.writeString("foo"); // Written as short string w.writeString("foo"); // Written as string
w.writeIntAny(123); // Written as a uint7 w.writeIntAny(123); // Written as uint7
w.writeBytes(new byte[] {}); // Written as short bytes w.writeBytes(new byte[0]); // Written as bytes
w.writeNull(); w.writeNull();
w.writeMapEnd(); w.writeMapEnd();
// MAP tag, "foo" as short string, 123 as uint7, // MAP tag, "foo" as string, 123 as uint7, byte[0] as bytes,
// byte[] {} as short bytes, NULL tag, END tag // NULL tag, END tag
checkContents("F4" + "83666F6F" + "7B" + "90" + "F2" + "F3"); checkContents("F4" + "F703666F6F" + "7B" + "F600" + "F2" + "F3");
} }
@Test @Test
@@ -252,10 +214,10 @@ public class WriterImplTest extends BriarTestCase {
Map<Object, Object> m1 = new LinkedHashMap<Object, Object>(); Map<Object, Object> m1 = new LinkedHashMap<Object, Object>();
m1.put(m, l); m1.put(m, l);
w.writeMap(m1); w.writeMap(m1);
// SHORT_MAP tag, length 1, SHORT_MAP tag, length 1, // MAP tag, MAP tag, "foo" as string, 123 as uint7, END tag,
// "foo" as short string, 123 as uint7, SHORT_LIST tag, length 1, // LIST tag, 1 as uint7, END tag, END tag
// 1 as uint7 checkContents("F4" + "F4" + "F703666F6F" + "7B" + "F3"
checkContents("B" + "1" + "B" + "1" + "83666F6F" + "7B" + "A1" + "01"); + "F5" + "01" + "F3" + "F3");
} }
@Test @Test
@@ -264,15 +226,6 @@ public class WriterImplTest extends BriarTestCase {
checkContents("F2"); checkContents("F2");
} }
@Test
public void testWriteShortStructId() throws IOException {
w.writeStructId(0);
w.writeStructId(31);
// SHORT_STRUCT tag (3 bits), 0 (5 bits), SHORT_STRUCT tag (3 bits),
// 31 (5 bits)
checkContents("C0" + "DF");
}
@Test @Test
public void testWriteStructId() throws IOException { public void testWriteStructId() throws IOException {
w.writeStructId(32); w.writeStructId(32);