mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-11 18:29:05 +01:00
Refactored readers and writers.
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
package net.sf.briar.api.serial;
|
||||
|
||||
public class FormatRuntimeException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -6548900875808933998L;
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
package net.sf.briar.api.serial;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public interface Reader {
|
||||
|
||||
boolean eof() throws IOException;
|
||||
void setReadLimit(long limit);
|
||||
void resetReadLimit();
|
||||
|
||||
boolean hasBoolean() throws IOException;
|
||||
boolean readBoolean() throws IOException;
|
||||
@@ -33,23 +33,24 @@ public interface Reader {
|
||||
|
||||
boolean hasUtf8() throws IOException;
|
||||
String readUtf8() throws IOException;
|
||||
String readUtf8(int maxLength) throws IOException;
|
||||
|
||||
boolean hasRaw() throws IOException;
|
||||
byte[] readRaw() throws IOException;
|
||||
byte[] readRaw(int maxLength) throws IOException;
|
||||
|
||||
boolean hasList() throws IOException;
|
||||
List<Object> readList() throws IOException;
|
||||
Iterator<Object> readListElements() throws IOException;
|
||||
<E> List<E> readList(Class<E> e) throws IOException;
|
||||
<E> Iterator<E> readListElements(Class<E> e) throws IOException;
|
||||
boolean hasListStart() throws IOException;
|
||||
void readListStart() throws IOException;
|
||||
boolean hasListEnd() throws IOException;
|
||||
void readListEnd() throws IOException;
|
||||
|
||||
boolean hasMap() throws IOException;
|
||||
Map<Object, Object> readMap() throws IOException;
|
||||
Iterator<Entry<Object, Object>> readMapEntries() throws IOException;
|
||||
<K, V> Map<K, V> readMap(Class<K> k, Class<V> v) throws IOException;
|
||||
<K, V> Iterator<Entry<K, V>> readMapEntries(Class<K> k, Class<V> v) throws IOException;
|
||||
boolean hasMapStart() throws IOException;
|
||||
void readMapStart() throws IOException;
|
||||
boolean hasMapEnd() throws IOException;
|
||||
void readMapEnd() throws IOException;
|
||||
|
||||
boolean hasNull() throws IOException;
|
||||
void readNull() throws IOException;
|
||||
|
||||
@@ -2,7 +2,6 @@ package net.sf.briar.api.serial;
|
||||
|
||||
public interface Tag {
|
||||
|
||||
// FIXME: Definite lists and maps
|
||||
public static final byte FALSE = -1, TRUE = -2;
|
||||
public static final byte INT8 = -3, INT16 = -4, INT32 = -5, INT64 = -6;
|
||||
public static final byte FLOAT32 = -7, FLOAT64 = -8;
|
||||
|
||||
@@ -31,4 +31,6 @@ public interface Writer {
|
||||
void writeMapEnd() throws IOException;
|
||||
|
||||
void writeNull() throws IOException;
|
||||
|
||||
void close() throws IOException;
|
||||
}
|
||||
|
||||
@@ -4,14 +4,10 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import net.sf.briar.api.serial.FormatException;
|
||||
import net.sf.briar.api.serial.FormatRuntimeException;
|
||||
import net.sf.briar.api.serial.Reader;
|
||||
import net.sf.briar.api.serial.Tag;
|
||||
|
||||
@@ -20,14 +16,20 @@ class ReaderImpl implements Reader {
|
||||
private static final int TOO_LARGE_TO_KEEP = 4096;
|
||||
|
||||
private final InputStream in;
|
||||
private boolean started = false, eof = false;
|
||||
private boolean started = false, eof = false, readLimited = false;
|
||||
private byte next;
|
||||
private byte[] stringBuffer = null;
|
||||
private long readLimit = 0L;
|
||||
private byte[] buf = null;
|
||||
|
||||
ReaderImpl(InputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
public boolean eof() throws IOException {
|
||||
if(!started) readNext(true);
|
||||
return eof;
|
||||
}
|
||||
|
||||
private byte readNext(boolean eofAcceptable) throws IOException {
|
||||
started = true;
|
||||
int i = in.read();
|
||||
@@ -40,9 +42,15 @@ class ReaderImpl implements Reader {
|
||||
return next;
|
||||
}
|
||||
|
||||
public boolean eof() throws IOException {
|
||||
if(!started) readNext(true);
|
||||
return eof;
|
||||
public void setReadLimit(long limit) {
|
||||
assert limit >= 0L && limit < Long.MAX_VALUE;
|
||||
readLimited = true;
|
||||
readLimit = limit;
|
||||
}
|
||||
|
||||
public void resetReadLimit() {
|
||||
readLimited = false;
|
||||
readLimit = 0L;
|
||||
}
|
||||
|
||||
public boolean hasBoolean() throws IOException {
|
||||
@@ -107,17 +115,27 @@ class ReaderImpl implements Reader {
|
||||
|
||||
public int readInt32() throws IOException {
|
||||
if(!hasInt32()) throw new FormatException();
|
||||
readNext(false);
|
||||
return readInt32Bits();
|
||||
}
|
||||
|
||||
private int readInt32Bits() throws IOException {
|
||||
byte b1 = readNext(false);
|
||||
byte b2 = readNext(false);
|
||||
byte b3 = readNext(false);
|
||||
byte b4 = readNext(false);
|
||||
readIntoBuffer(4);
|
||||
return ((buf[0] & 0xFF) << 24) | ((buf[1] & 0xFF) << 16) |
|
||||
((buf[2] & 0xFF) << 8) | (buf[3] & 0xFF);
|
||||
}
|
||||
|
||||
private void readIntoBuffer(int length) throws IOException {
|
||||
assert length > 0;
|
||||
if(buf == null || buf.length < length) buf = new byte[length];
|
||||
buf[0] = next;
|
||||
int offset = 1, read = 0;
|
||||
while(offset < length && read != -1) {
|
||||
read = in.read(buf, offset, length - offset);
|
||||
if(read != -1) offset += read;
|
||||
}
|
||||
if(offset < length) throw new FormatException();
|
||||
readNext(true);
|
||||
return ((b1 & 0xFF) << 24) | ((b2 & 0xFF) << 16) |
|
||||
((b3 & 0xFF) << 8) | (b4 & 0xFF);
|
||||
}
|
||||
|
||||
public boolean hasInt64() throws IOException {
|
||||
@@ -128,23 +146,16 @@ class ReaderImpl implements Reader {
|
||||
|
||||
public long readInt64() throws IOException {
|
||||
if(!hasInt64()) throw new FormatException();
|
||||
readNext(false);
|
||||
return readInt64Bits();
|
||||
}
|
||||
|
||||
private long readInt64Bits() throws IOException {
|
||||
byte b1 = readNext(false);
|
||||
byte b2 = readNext(false);
|
||||
byte b3 = readNext(false);
|
||||
byte b4 = readNext(false);
|
||||
byte b5 = readNext(false);
|
||||
byte b6 = readNext(false);
|
||||
byte b7 = readNext(false);
|
||||
byte b8 = readNext(false);
|
||||
readNext(true);
|
||||
return ((b1 & 0xFFL) << 56) | ((b2 & 0xFFL) << 48) |
|
||||
((b3 & 0xFFL) << 40) | ((b4 & 0xFFL) << 32) |
|
||||
((b5 & 0xFFL) << 24) | ((b6 & 0xFFL) << 16) |
|
||||
((b7 & 0xFFL) << 8) | (b8 & 0xFFL);
|
||||
readIntoBuffer(8);
|
||||
return ((buf[0] & 0xFFL) << 56) | ((buf[1] & 0xFFL) << 48) |
|
||||
((buf[2] & 0xFFL) << 40) | ((buf[3] & 0xFFL) << 32) |
|
||||
((buf[4] & 0xFFL) << 24) | ((buf[5] & 0xFFL) << 16) |
|
||||
((buf[6] & 0xFFL) << 8) | (buf[7] & 0xFFL);
|
||||
}
|
||||
|
||||
public boolean hasIntAny() throws IOException {
|
||||
@@ -172,6 +183,7 @@ class ReaderImpl implements Reader {
|
||||
|
||||
public float readFloat32() throws IOException {
|
||||
if(!hasFloat32()) throw new FormatException();
|
||||
readNext(false);
|
||||
return Float.intBitsToFloat(readInt32Bits());
|
||||
}
|
||||
|
||||
@@ -183,6 +195,7 @@ class ReaderImpl implements Reader {
|
||||
|
||||
public double readFloat64() throws IOException {
|
||||
if(!hasFloat64()) throw new FormatException();
|
||||
readNext(false);
|
||||
return Double.longBitsToDouble(readInt64Bits());
|
||||
}
|
||||
|
||||
@@ -193,31 +206,26 @@ class ReaderImpl implements Reader {
|
||||
}
|
||||
|
||||
public String readUtf8() throws IOException {
|
||||
return readUtf8(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public String readUtf8(int maxLength) throws IOException {
|
||||
if(!hasUtf8()) throw new FormatException();
|
||||
readNext(false);
|
||||
long l = readIntAny();
|
||||
if(l < 0 || l > maxLength) throw new FormatException();
|
||||
if(l < 0 || l > Integer.MAX_VALUE) throw new FormatException();
|
||||
int length = (int) l;
|
||||
if(length == 0) return "";
|
||||
if(stringBuffer == null || stringBuffer.length < length)
|
||||
stringBuffer = new byte[length];
|
||||
stringBuffer[0] = next;
|
||||
int offset = 1, read = 0;
|
||||
while(offset < length && read != -1) {
|
||||
read = in.read(stringBuffer, offset, length - offset);
|
||||
if(read != -1) offset += read;
|
||||
}
|
||||
if(offset < length) throw new FormatException();
|
||||
String s = new String(stringBuffer, 0, length, "UTF-8");
|
||||
if(length >= TOO_LARGE_TO_KEEP) stringBuffer = null;
|
||||
readNext(true);
|
||||
checkLimit(length);
|
||||
readIntoBuffer(length);
|
||||
String s = new String(buf, 0, length, "UTF-8");
|
||||
if(length >= TOO_LARGE_TO_KEEP) buf = null;
|
||||
return s;
|
||||
}
|
||||
|
||||
private void checkLimit(long bytes) throws FormatException {
|
||||
if(readLimited) {
|
||||
if(bytes > readLimit) throw new FormatException();
|
||||
readLimit -= bytes;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasRaw() throws IOException {
|
||||
if(!started) readNext(true);
|
||||
if(eof) return false;
|
||||
@@ -225,25 +233,16 @@ class ReaderImpl implements Reader {
|
||||
}
|
||||
|
||||
public byte[] readRaw() throws IOException {
|
||||
return readRaw(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public byte[] readRaw(int maxLength) throws IOException {
|
||||
if(!hasRaw()) throw new FormatException();
|
||||
readNext(false);
|
||||
long l = readIntAny();
|
||||
if(l < 0 || l > maxLength) throw new FormatException();
|
||||
if(l < 0 || l > Integer.MAX_VALUE) throw new FormatException();
|
||||
int length = (int) l;
|
||||
if(length == 0) return new byte[] {};
|
||||
byte[] b = new byte[length];
|
||||
b[0] = next;
|
||||
int offset = 1, read = 0;
|
||||
while(offset < length && read != -1) {
|
||||
read = in.read(b, offset, length - offset);
|
||||
if(read != -1) offset += read;
|
||||
}
|
||||
if(offset < length) throw new FormatException();
|
||||
readNext(true);
|
||||
checkLimit(length);
|
||||
readIntoBuffer(length);
|
||||
byte[] b = buf;
|
||||
buf = null;
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -257,10 +256,6 @@ class ReaderImpl implements Reader {
|
||||
return readList(Object.class);
|
||||
}
|
||||
|
||||
public Iterator<Object> readListElements() throws IOException {
|
||||
return readListElements(Object.class);
|
||||
}
|
||||
|
||||
public <E> List<E> readList(Class<E> e) throws IOException {
|
||||
if(!hasList()) throw new FormatException();
|
||||
boolean definite = next == Tag.LIST_DEF;
|
||||
@@ -278,14 +273,6 @@ class ReaderImpl implements Reader {
|
||||
return list;
|
||||
}
|
||||
|
||||
public <E> Iterator<E> readListElements(Class<E> e) throws IOException {
|
||||
if(!hasList()) throw new FormatException();
|
||||
boolean definite = next == Tag.LIST_DEF;
|
||||
readNext(false);
|
||||
if(definite) return new DefiniteListIterator<E>(e);
|
||||
else return new IndefiniteListIterator<E>(e);
|
||||
}
|
||||
|
||||
private boolean hasEnd() throws IOException {
|
||||
if(!started) readNext(true);
|
||||
if(eof) return false;
|
||||
@@ -293,6 +280,7 @@ class ReaderImpl implements Reader {
|
||||
}
|
||||
|
||||
private void readEnd() throws IOException {
|
||||
if(!started) throw new IllegalStateException();
|
||||
if(!hasEnd()) throw new FormatException();
|
||||
readNext(true);
|
||||
}
|
||||
@@ -327,6 +315,25 @@ class ReaderImpl implements Reader {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasListStart() throws IOException {
|
||||
if(!started) readNext(true);
|
||||
if(eof) return false;
|
||||
return next == Tag.LIST_INDEF;
|
||||
}
|
||||
|
||||
public void readListStart() throws IOException {
|
||||
if(!hasListStart()) throw new FormatException();
|
||||
readNext(false);
|
||||
}
|
||||
|
||||
public boolean hasListEnd() throws IOException {
|
||||
return hasEnd();
|
||||
}
|
||||
|
||||
public void readListEnd() throws IOException {
|
||||
readEnd();
|
||||
}
|
||||
|
||||
public boolean hasMap() throws IOException {
|
||||
if(!started) readNext(true);
|
||||
if(eof) return false;
|
||||
@@ -337,10 +344,6 @@ class ReaderImpl implements Reader {
|
||||
return readMap(Object.class, Object.class);
|
||||
}
|
||||
|
||||
public Iterator<Entry<Object, Object>> readMapEntries() throws IOException {
|
||||
return readMapEntries(Object.class, Object.class);
|
||||
}
|
||||
|
||||
public <K, V> Map<K, V> readMap(Class<K> k, Class<V> v) throws IOException {
|
||||
if(!hasMap()) throw new FormatException();
|
||||
boolean definite = next == Tag.MAP_DEF;
|
||||
@@ -358,13 +361,23 @@ class ReaderImpl implements Reader {
|
||||
return m;
|
||||
}
|
||||
|
||||
public <K, V> Iterator<Entry<K, V>> readMapEntries(Class<K> k, Class<V> v)
|
||||
throws IOException {
|
||||
if(!hasMap()) throw new FormatException();
|
||||
boolean definite = next == Tag.MAP_DEF;
|
||||
public boolean hasMapStart() throws IOException {
|
||||
if(!started) readNext(true);
|
||||
if(eof) return false;
|
||||
return next == Tag.MAP_INDEF;
|
||||
}
|
||||
|
||||
public void readMapStart() throws IOException {
|
||||
if(!hasMapStart()) throw new FormatException();
|
||||
readNext(false);
|
||||
if(definite) return new DefiniteMapIterator<K, V>(k, v);
|
||||
else return new IndefiniteMapIterator<K, V>(k, v);
|
||||
}
|
||||
|
||||
public boolean hasMapEnd() throws IOException {
|
||||
return hasEnd();
|
||||
}
|
||||
|
||||
public void readMapEnd() throws IOException {
|
||||
readEnd();
|
||||
}
|
||||
|
||||
public boolean hasNull() throws IOException {
|
||||
@@ -377,175 +390,4 @@ class ReaderImpl implements Reader {
|
||||
if(!hasNull()) throw new FormatException();
|
||||
readNext(true);
|
||||
}
|
||||
|
||||
private class DefiniteListIterator<E> implements Iterator<E> {
|
||||
|
||||
private final Class<E> e;
|
||||
private int remaining;
|
||||
|
||||
private DefiniteListIterator(Class<E> e) throws IOException {
|
||||
this.e = e;
|
||||
long l = readIntAny();
|
||||
if(l < 0 || l > Integer.MAX_VALUE) throw new FormatException();
|
||||
remaining = (int) l;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return remaining > 0;
|
||||
}
|
||||
|
||||
public E next() {
|
||||
if(remaining == 0) throw new NoSuchElementException();
|
||||
remaining--;
|
||||
try {
|
||||
return readObject(e);
|
||||
} catch(FormatException ex) {
|
||||
throw new FormatRuntimeException();
|
||||
} catch(IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private class IndefiniteListIterator<E> implements Iterator<E> {
|
||||
|
||||
private final Class<E> e;
|
||||
private boolean hasNext = true;
|
||||
|
||||
private IndefiniteListIterator(Class<E> e) throws IOException {
|
||||
this.e = e;
|
||||
if(hasEnd()) {
|
||||
readEnd();
|
||||
hasNext = false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
public E next() {
|
||||
if(!hasNext) throw new NoSuchElementException();
|
||||
try {
|
||||
E next = readObject(e);
|
||||
if(hasEnd()) {
|
||||
readEnd();
|
||||
hasNext = false;
|
||||
}
|
||||
return next;
|
||||
} catch(FormatException ex) {
|
||||
throw new FormatRuntimeException();
|
||||
} catch(IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private class DefiniteMapIterator<K, V> implements Iterator<Entry<K, V>> {
|
||||
|
||||
private final Class<K> k;
|
||||
private final Class<V> v;
|
||||
private int remaining;
|
||||
|
||||
private DefiniteMapIterator(Class<K> k, Class<V> v) throws IOException {
|
||||
this.k = k;
|
||||
this.v = v;
|
||||
long l = readIntAny();
|
||||
if(l < 0 || l > Integer.MAX_VALUE) throw new FormatException();
|
||||
remaining = (int) l;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return remaining > 0;
|
||||
}
|
||||
|
||||
public Entry<K, V> next() {
|
||||
if(remaining == 0) throw new NoSuchElementException();
|
||||
remaining--;
|
||||
try {
|
||||
return new MapEntry<K, V>(readObject(k), readObject(v));
|
||||
} catch(FormatException ex) {
|
||||
throw new FormatRuntimeException();
|
||||
} catch(IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private class IndefiniteMapIterator<K, V> implements Iterator<Entry<K, V>> {
|
||||
|
||||
private final Class<K> k;
|
||||
private final Class<V> v;
|
||||
private boolean hasNext = true;
|
||||
|
||||
private IndefiniteMapIterator(Class<K> k, Class<V> v)
|
||||
throws IOException {
|
||||
this.k = k;
|
||||
this.v = v;
|
||||
if(hasEnd()) {
|
||||
readEnd();
|
||||
hasNext = false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
public Entry<K, V> next() {
|
||||
if(!hasNext) throw new NoSuchElementException();
|
||||
try {
|
||||
Entry<K, V> next =
|
||||
new MapEntry<K, V>(readObject(k), readObject(v));
|
||||
if(hasEnd()) {
|
||||
readEnd();
|
||||
hasNext = false;
|
||||
}
|
||||
return next;
|
||||
} catch(FormatException ex) {
|
||||
throw new FormatRuntimeException();
|
||||
} catch(IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private static class MapEntry<K, V> implements Entry<K, V> {
|
||||
|
||||
private final K k;
|
||||
private final V v;
|
||||
|
||||
MapEntry(K k, V v) {
|
||||
this.k = k;
|
||||
this.v = v;
|
||||
}
|
||||
|
||||
public K getKey() {
|
||||
return k;
|
||||
}
|
||||
|
||||
public V getValue() {
|
||||
return v;
|
||||
}
|
||||
|
||||
public V setValue(V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,4 +156,9 @@ class WriterImpl implements Writer {
|
||||
public void writeNull() throws IOException {
|
||||
out.write(Tag.NULL);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package net.sf.briar.serial;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -129,21 +128,32 @@ public class ReaderImplTest extends TestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadUtf8MaxLengthNotExceeded() throws IOException {
|
||||
public void testReadUtf8LimitNotExceeded() throws IOException {
|
||||
setContents("F703666F6F");
|
||||
assertEquals("foo", r.readUtf8(3));
|
||||
r.setReadLimit(3);
|
||||
assertEquals("foo", r.readUtf8());
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadUtf8MaxLengthExceeded() throws IOException {
|
||||
public void testReadUtf8LimitExceeded() throws IOException {
|
||||
setContents("F703666F6F");
|
||||
r.setReadLimit(2);
|
||||
try {
|
||||
r.readUtf8(2);
|
||||
r.readUtf8();
|
||||
assertTrue(false);
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadUtf8LimitReset() throws IOException {
|
||||
setContents("F703666F6F");
|
||||
r.setReadLimit(2);
|
||||
r.resetReadLimit();
|
||||
assertEquals("foo", r.readUtf8());
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadRaw() throws IOException {
|
||||
setContents("F603010203" + "F603010203" + "F600");
|
||||
@@ -154,25 +164,36 @@ public class ReaderImplTest extends TestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadRawMaxLengthNotExceeded() throws IOException {
|
||||
public void testReadRawLimitNotExceeded() throws IOException {
|
||||
setContents("F603010203");
|
||||
assertTrue(Arrays.equals(new byte[] {1, 2, 3}, r.readRaw(3)));
|
||||
r.setReadLimit(3);
|
||||
assertTrue(Arrays.equals(new byte[] {1, 2, 3}, r.readRaw()));
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadRawMaxLengthExceeded() throws IOException {
|
||||
setContents("F603010203");
|
||||
r.setReadLimit(2);
|
||||
try {
|
||||
r.readRaw(2);
|
||||
r.readRaw();
|
||||
assertTrue(false);
|
||||
} catch(FormatException expected) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadRawLimitReset() throws IOException {
|
||||
setContents("F603010203");
|
||||
r.setReadLimit(2);
|
||||
r.resetReadLimit();
|
||||
assertTrue(Arrays.equals(new byte[] {1, 2, 3}, r.readRaw()));
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadDefiniteList() throws IOException {
|
||||
setContents("F5" + "03" + "01" + "F703666F6F" + "FC0080");
|
||||
List<Object> l = r.readList();
|
||||
List<Object> l = r.readList(Object.class);
|
||||
assertNotNull(l);
|
||||
assertEquals(3, l.size());
|
||||
assertEquals((byte) 1, l.get(0));
|
||||
@@ -181,21 +202,6 @@ public class ReaderImplTest extends TestCase {
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadDefiniteListElements() throws IOException {
|
||||
setContents("F5" + "03" + "01" + "F703666F6F" + "FC0080");
|
||||
Iterator<Object> i = r.readListElements();
|
||||
assertNotNull(i);
|
||||
assertTrue(i.hasNext());
|
||||
assertEquals((byte) 1, i.next());
|
||||
assertTrue(i.hasNext());
|
||||
assertEquals("foo", i.next());
|
||||
assertTrue(i.hasNext());
|
||||
assertEquals((short) 128, i.next());
|
||||
assertFalse(i.hasNext());
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadDefiniteListTypeSafe() throws IOException {
|
||||
setContents("F5" + "03" + "01" + "02" + "03");
|
||||
@@ -208,25 +214,10 @@ public class ReaderImplTest extends TestCase {
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadDefiniteListElementsTypeSafe() throws IOException {
|
||||
setContents("F5" + "03" + "01" + "02" + "03");
|
||||
Iterator<Byte> i = r.readListElements(Byte.class);
|
||||
assertNotNull(i);
|
||||
assertTrue(i.hasNext());
|
||||
assertEquals(Byte.valueOf((byte) 1), i.next());
|
||||
assertTrue(i.hasNext());
|
||||
assertEquals(Byte.valueOf((byte) 2), i.next());
|
||||
assertTrue(i.hasNext());
|
||||
assertEquals(Byte.valueOf((byte) 3), i.next());
|
||||
assertFalse(i.hasNext());
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadDefiniteMap() throws IOException {
|
||||
setContents("F4" + "02" + "F703666F6F" + "7B" + "F600" + "F0");
|
||||
Map<Object, Object> m = r.readMap();
|
||||
Map<Object, Object> m = r.readMap(Object.class, Object.class);
|
||||
assertNotNull(m);
|
||||
assertEquals(2, m.size());
|
||||
assertEquals((byte) 123, m.get("foo"));
|
||||
@@ -236,24 +227,6 @@ public class ReaderImplTest extends TestCase {
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadDefiniteMapEntries() throws IOException {
|
||||
setContents("F4" + "02" + "F703666F6F" + "7B" + "F600" + "F0");
|
||||
Iterator<Entry<Object, Object>> i = r.readMapEntries();
|
||||
assertNotNull(i);
|
||||
assertTrue(i.hasNext());
|
||||
Entry<Object, Object> e = i.next();
|
||||
assertNotNull(e);
|
||||
assertEquals("foo", e.getKey());
|
||||
assertEquals((byte) 123, e.getValue());
|
||||
assertTrue(i.hasNext());
|
||||
e = i.next();
|
||||
assertNotNull(e);
|
||||
assertEquals(new RawImpl(new byte[] {}), e.getKey());
|
||||
assertNull(e.getValue());
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadDefiniteMapTypeSafe() throws IOException {
|
||||
setContents("F4" + "02" + "F703666F6F" + "7B" + "F700" + "F0");
|
||||
@@ -266,29 +239,10 @@ public class ReaderImplTest extends TestCase {
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadDefiniteMapEntriesTypeSafe() throws IOException {
|
||||
setContents("F4" + "02" + "F703666F6F" + "7B" + "F700" + "F0");
|
||||
Iterator<Entry<String, Byte>> i =
|
||||
r.readMapEntries(String.class, Byte.class);
|
||||
assertNotNull(i);
|
||||
assertTrue(i.hasNext());
|
||||
Entry<String, Byte> e = i.next();
|
||||
assertNotNull(e);
|
||||
assertEquals("foo", e.getKey());
|
||||
assertEquals(Byte.valueOf((byte) 123), e.getValue());
|
||||
assertTrue(i.hasNext());
|
||||
e = i.next();
|
||||
assertNotNull(e);
|
||||
assertEquals("", e.getKey());
|
||||
assertNull(e.getValue());
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadIndefiniteList() throws IOException {
|
||||
setContents("F3" + "01" + "F703666F6F" + "FC0080" + "F1");
|
||||
List<Object> l = r.readList();
|
||||
List<Object> l = r.readList(Object.class);
|
||||
assertNotNull(l);
|
||||
assertEquals(3, l.size());
|
||||
assertEquals((byte) 1, l.get(0));
|
||||
@@ -300,15 +254,16 @@ public class ReaderImplTest extends TestCase {
|
||||
@Test
|
||||
public void testReadIndfiniteListElements() throws IOException {
|
||||
setContents("F3" + "01" + "F703666F6F" + "FC0080" + "F1");
|
||||
Iterator<Object> i = r.readListElements();
|
||||
assertNotNull(i);
|
||||
assertTrue(i.hasNext());
|
||||
assertEquals((byte) 1, i.next());
|
||||
assertTrue(i.hasNext());
|
||||
assertEquals("foo", i.next());
|
||||
assertTrue(i.hasNext());
|
||||
assertEquals((short) 128, i.next());
|
||||
assertFalse(i.hasNext());
|
||||
assertTrue(r.hasListStart());
|
||||
r.readListStart();
|
||||
assertFalse(r.hasListEnd());
|
||||
assertEquals((byte) 1, r.readIntAny());
|
||||
assertFalse(r.hasListEnd());
|
||||
assertEquals("foo", r.readUtf8());
|
||||
assertFalse(r.hasListEnd());
|
||||
assertEquals((short) 128, r.readIntAny());
|
||||
assertTrue(r.hasListEnd());
|
||||
r.readListEnd();
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@@ -324,25 +279,10 @@ public class ReaderImplTest extends TestCase {
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadIndefiniteListElementsTypeSafe() throws IOException {
|
||||
setContents("F3" + "01" + "02" + "03" + "F1");
|
||||
Iterator<Byte> i = r.readListElements(Byte.class);
|
||||
assertNotNull(i);
|
||||
assertTrue(i.hasNext());
|
||||
assertEquals(Byte.valueOf((byte) 1), i.next());
|
||||
assertTrue(i.hasNext());
|
||||
assertEquals(Byte.valueOf((byte) 2), i.next());
|
||||
assertTrue(i.hasNext());
|
||||
assertEquals(Byte.valueOf((byte) 3), i.next());
|
||||
assertFalse(i.hasNext());
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadIndefiniteMap() throws IOException {
|
||||
setContents("F2" + "F703666F6F" + "7B" + "F600" + "F0" + "F1");
|
||||
Map<Object, Object> m = r.readMap();
|
||||
Map<Object, Object> m = r.readMap(Object.class, Object.class);
|
||||
assertNotNull(m);
|
||||
assertEquals(2, m.size());
|
||||
assertEquals((byte) 123, m.get("foo"));
|
||||
@@ -355,19 +295,19 @@ public class ReaderImplTest extends TestCase {
|
||||
@Test
|
||||
public void testReadIndefiniteMapEntries() throws IOException {
|
||||
setContents("F2" + "F703666F6F" + "7B" + "F600" + "F0" + "F1");
|
||||
Iterator<Entry<Object, Object>> i = r.readMapEntries();
|
||||
assertNotNull(i);
|
||||
assertTrue(i.hasNext());
|
||||
Entry<Object, Object> e = i.next();
|
||||
assertNotNull(e);
|
||||
assertEquals("foo", e.getKey());
|
||||
assertEquals((byte) 123, e.getValue());
|
||||
assertTrue(i.hasNext());
|
||||
e = i.next();
|
||||
assertNotNull(e);
|
||||
assertEquals(new RawImpl(new byte[] {}), e.getKey());
|
||||
assertNull(e.getValue());
|
||||
assertFalse(i.hasNext());
|
||||
assertTrue(r.hasMapStart());
|
||||
r.readMapStart();
|
||||
assertFalse(r.hasMapEnd());
|
||||
assertEquals("foo", r.readUtf8());
|
||||
assertFalse(r.hasMapEnd());
|
||||
assertEquals((byte) 123, r.readIntAny());
|
||||
assertFalse(r.hasMapEnd());
|
||||
assertTrue(Arrays.equals(new byte[] {}, r.readRaw()));
|
||||
assertFalse(r.hasMapEnd());
|
||||
assertTrue(r.hasNull());
|
||||
r.readNull();
|
||||
assertTrue(r.hasMapEnd());
|
||||
r.readMapEnd();
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@@ -383,32 +323,12 @@ public class ReaderImplTest extends TestCase {
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadIndefiniteMapEntriesTypeSafe() throws IOException {
|
||||
setContents("F2" + "F703666F6F" + "7B" + "F700" + "F0" + "F1");
|
||||
Iterator<Entry<String, Byte>> i =
|
||||
r.readMapEntries(String.class, Byte.class);
|
||||
assertNotNull(i);
|
||||
assertTrue(i.hasNext());
|
||||
Entry<String, Byte> e = i.next();
|
||||
assertNotNull(e);
|
||||
assertEquals("foo", e.getKey());
|
||||
assertEquals(Byte.valueOf((byte) 123), e.getValue());
|
||||
assertTrue(i.hasNext());
|
||||
e = i.next();
|
||||
assertNotNull(e);
|
||||
assertEquals("", e.getKey());
|
||||
assertNull(e.getValue());
|
||||
assertFalse(i.hasNext());
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReadNestedMapsAndLists() throws IOException {
|
||||
setContents("F4" + "01" + "F4" + "01" + "F703666F6F" + "7B" +
|
||||
"F5" + "01" + "01");
|
||||
Map<Object, Object> m = r.readMap();
|
||||
Map<Object, Object> m = r.readMap(Object.class, Object.class);
|
||||
assertNotNull(m);
|
||||
assertEquals(1, m.size());
|
||||
Entry<Object, Object> e = m.entrySet().iterator().next();
|
||||
|
||||
Reference in New Issue
Block a user