mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 11:49:04 +01:00
Renamed serial component to data, moved consumers to briar-core.
This commit is contained in:
13
briar-core/src/org/briarproject/data/ReaderFactoryImpl.java
Normal file
13
briar-core/src/org/briarproject/data/ReaderFactoryImpl.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package org.briarproject.data;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.briarproject.api.data.Reader;
|
||||
import org.briarproject.api.data.ReaderFactory;
|
||||
|
||||
class ReaderFactoryImpl implements ReaderFactory {
|
||||
|
||||
public Reader createReader(InputStream in) {
|
||||
return new ReaderImpl(in);
|
||||
}
|
||||
}
|
||||
362
briar-core/src/org/briarproject/data/ReaderImpl.java
Normal file
362
briar-core/src/org/briarproject/data/ReaderImpl.java
Normal file
@@ -0,0 +1,362 @@
|
||||
package org.briarproject.data;
|
||||
|
||||
import static org.briarproject.data.Types.END;
|
||||
import static org.briarproject.data.Types.FLOAT_64;
|
||||
import static org.briarproject.data.Types.INT_16;
|
||||
import static org.briarproject.data.Types.INT_32;
|
||||
import static org.briarproject.data.Types.INT_64;
|
||||
import static org.briarproject.data.Types.INT_8;
|
||||
import static org.briarproject.data.Types.LIST;
|
||||
import static org.briarproject.data.Types.MAP;
|
||||
import static org.briarproject.data.Types.NULL;
|
||||
import static org.briarproject.data.Types.RAW_16;
|
||||
import static org.briarproject.data.Types.RAW_32;
|
||||
import static org.briarproject.data.Types.RAW_8;
|
||||
import static org.briarproject.data.Types.STRING_16;
|
||||
import static org.briarproject.data.Types.STRING_32;
|
||||
import static org.briarproject.data.Types.STRING_8;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.briarproject.api.FormatException;
|
||||
import org.briarproject.api.data.Consumer;
|
||||
import org.briarproject.api.data.Reader;
|
||||
|
||||
// This class is not thread-safe
|
||||
class ReaderImpl implements Reader {
|
||||
|
||||
private static final byte[] EMPTY_BUFFER = new byte[] {};
|
||||
|
||||
private final InputStream in;
|
||||
private final Collection<Consumer> consumers = new ArrayList<Consumer>(0);
|
||||
|
||||
private boolean hasLookahead = false, eof = false;
|
||||
private byte next;
|
||||
private byte[] buf = new byte[8];
|
||||
|
||||
ReaderImpl(InputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
private void readLookahead() throws IOException {
|
||||
assert !eof;
|
||||
assert !hasLookahead;
|
||||
// Read a lookahead byte
|
||||
int i = in.read();
|
||||
if(i == -1) {
|
||||
eof = true;
|
||||
return;
|
||||
}
|
||||
next = (byte) i;
|
||||
hasLookahead = true;
|
||||
}
|
||||
|
||||
private void consumeLookahead() throws IOException {
|
||||
assert hasLookahead;
|
||||
for(Consumer c : consumers) c.write(next);
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
private void readIntoBuffer(byte[] b, int length, boolean consume)
|
||||
throws IOException {
|
||||
int offset = 0;
|
||||
while(offset < length) {
|
||||
int read = in.read(b, offset, length - offset);
|
||||
if(read == -1) throw new FormatException();
|
||||
offset += read;
|
||||
}
|
||||
if(consume) for(Consumer c : consumers) c.write(b, 0, length);
|
||||
}
|
||||
|
||||
private void readIntoBuffer(int length, boolean consume)
|
||||
throws IOException {
|
||||
if(buf.length < length) buf = new byte[length];
|
||||
readIntoBuffer(buf, length, consume);
|
||||
}
|
||||
|
||||
private void skip(int length) throws IOException {
|
||||
while(length > 0) {
|
||||
int read = in.read(buf, 0, Math.min(length, buf.length));
|
||||
if(read == -1) throw new FormatException();
|
||||
length -= read;
|
||||
}
|
||||
}
|
||||
|
||||
private void skipObject() throws IOException {
|
||||
if(hasBoolean()) skipBoolean();
|
||||
else if(hasInteger()) skipInteger();
|
||||
else if(hasFloat()) skipFloat();
|
||||
else if(hasString()) skipString();
|
||||
else if(hasBytes()) skipBytes();
|
||||
else if(hasList()) skipList();
|
||||
else if(hasMap()) skipMap();
|
||||
else if(hasNull()) skipNull();
|
||||
else throw new FormatException();
|
||||
}
|
||||
|
||||
public boolean eof() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
return eof;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
|
||||
public void addConsumer(Consumer c) {
|
||||
consumers.add(c);
|
||||
}
|
||||
|
||||
public void removeConsumer(Consumer c) {
|
||||
if(!consumers.remove(c)) throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public boolean hasNull() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
return next == NULL;
|
||||
}
|
||||
|
||||
public void readNull() throws IOException {
|
||||
if(!hasNull()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
}
|
||||
|
||||
public void skipNull() throws IOException {
|
||||
if(!hasNull()) throw new FormatException();
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasBoolean() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
return next == Types.BOOLEAN;
|
||||
}
|
||||
|
||||
public boolean readBoolean() throws IOException {
|
||||
if(!hasBoolean()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
return readBoolean(true);
|
||||
}
|
||||
|
||||
private boolean readBoolean(boolean consume) throws IOException {
|
||||
readIntoBuffer(1, consume);
|
||||
if(buf[0] != 0 && buf[0] != 1) throw new FormatException();
|
||||
return buf[0] == 1;
|
||||
}
|
||||
|
||||
public void skipBoolean() throws IOException {
|
||||
if(!hasBoolean()) throw new FormatException();
|
||||
skip(1);
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasInteger() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
return next == INT_8 || next == INT_16 || next == INT_32 ||
|
||||
next == INT_64;
|
||||
}
|
||||
|
||||
public long readInteger() throws IOException {
|
||||
if(!hasInteger()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
if(next == INT_8) return readInt8(true);
|
||||
if(next == INT_16) return readInt16(true);
|
||||
if(next == INT_32) return readInt32(true);
|
||||
return readInt64(true);
|
||||
}
|
||||
|
||||
private int readInt8(boolean consume) throws IOException {
|
||||
readIntoBuffer(1, consume);
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
private short readInt16(boolean consume) throws IOException {
|
||||
readIntoBuffer(2, consume);
|
||||
short value = (short) (((buf[0] & 0xFF) << 8) + (buf[1] & 0xFF));
|
||||
if(value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
|
||||
throw new FormatException();
|
||||
return value;
|
||||
}
|
||||
|
||||
private int readInt32(boolean consume) throws IOException {
|
||||
readIntoBuffer(4, consume);
|
||||
int value = 0;
|
||||
for(int i = 0; i < 4; i++) value |= (buf[i] & 0xFF) << (24 - i * 8);
|
||||
if(value >= Short.MIN_VALUE && value <= Short.MAX_VALUE)
|
||||
throw new FormatException();
|
||||
return value;
|
||||
}
|
||||
|
||||
private long readInt64(boolean consume) throws IOException {
|
||||
readIntoBuffer(8, consume);
|
||||
long value = 0;
|
||||
for(int i = 0; i < 8; i++) value |= (buf[i] & 0xFFL) << (56 - i * 8);
|
||||
if(value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE)
|
||||
throw new FormatException();
|
||||
return value;
|
||||
}
|
||||
|
||||
public void skipInteger() throws IOException {
|
||||
if(!hasInteger()) throw new FormatException();
|
||||
if(next == INT_8) skip(1);
|
||||
else if(next == INT_16) skip(2);
|
||||
else if(next == INT_32) skip(4);
|
||||
else skip(8);
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasFloat() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
return next == FLOAT_64;
|
||||
}
|
||||
|
||||
public double readFloat() throws IOException {
|
||||
if(!hasFloat()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
readIntoBuffer(8, true);
|
||||
long value = 0;
|
||||
for(int i = 0; i < 8; i++) value |= (buf[i] & 0xFFL) << (56 - i * 8);
|
||||
return Double.longBitsToDouble(value);
|
||||
}
|
||||
|
||||
public void skipFloat() throws IOException {
|
||||
if(!hasFloat()) throw new FormatException();
|
||||
skip(8);
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasString() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
return next == STRING_8 || next == STRING_16 || next == STRING_32;
|
||||
}
|
||||
|
||||
public String readString(int maxLength) throws IOException {
|
||||
if(!hasString()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
int length = readStringLength(true);
|
||||
if(length < 0 || length > maxLength) throw new FormatException();
|
||||
if(length == 0) return "";
|
||||
readIntoBuffer(length, true);
|
||||
return new String(buf, 0, length, "UTF-8");
|
||||
}
|
||||
|
||||
private int readStringLength(boolean consume) throws IOException {
|
||||
if(next == STRING_8) return readInt8(consume);
|
||||
if(next == STRING_16) return readInt16(consume);
|
||||
if(next == STRING_32) return readInt32(consume);
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
public void skipString() throws IOException {
|
||||
if(!hasString()) throw new FormatException();
|
||||
int length = readStringLength(false);
|
||||
if(length < 0) throw new FormatException();
|
||||
skip(length);
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasBytes() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
return next == RAW_8 || next == RAW_16 || next == RAW_32;
|
||||
}
|
||||
|
||||
public byte[] readBytes(int maxLength) throws IOException {
|
||||
if(!hasBytes()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
int length = readBytesLength(true);
|
||||
if(length < 0 || length > maxLength) throw new FormatException();
|
||||
if(length == 0) return EMPTY_BUFFER;
|
||||
byte[] b = new byte[length];
|
||||
readIntoBuffer(b, length, true);
|
||||
return b;
|
||||
}
|
||||
|
||||
private int readBytesLength(boolean consume) throws IOException {
|
||||
if(next == RAW_8) return readInt8(consume);
|
||||
if(next == RAW_16) return readInt16(consume);
|
||||
if(next == RAW_32) return readInt32(consume);
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
public void skipBytes() throws IOException {
|
||||
if(!hasBytes()) throw new FormatException();
|
||||
int length = readBytesLength(false);
|
||||
if(length < 0) throw new FormatException();
|
||||
skip(length);
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasList() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
return next == LIST;
|
||||
}
|
||||
|
||||
public void readListStart() throws IOException {
|
||||
if(!hasList()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
}
|
||||
|
||||
public boolean hasListEnd() throws IOException {
|
||||
return hasEnd();
|
||||
}
|
||||
|
||||
private boolean hasEnd() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
return next == END;
|
||||
}
|
||||
|
||||
public void readListEnd() throws IOException {
|
||||
readEnd();
|
||||
}
|
||||
|
||||
private void readEnd() throws IOException {
|
||||
if(!hasEnd()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
}
|
||||
|
||||
public void skipList() throws IOException {
|
||||
if(!hasList()) throw new FormatException();
|
||||
hasLookahead = false;
|
||||
while(!hasListEnd()) skipObject();
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasMap() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
return next == MAP;
|
||||
}
|
||||
|
||||
public void readMapStart() throws IOException {
|
||||
if(!hasMap()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
}
|
||||
|
||||
public boolean hasMapEnd() throws IOException {
|
||||
return hasEnd();
|
||||
}
|
||||
|
||||
public void readMapEnd() throws IOException {
|
||||
readEnd();
|
||||
}
|
||||
|
||||
public void skipMap() throws IOException {
|
||||
if(!hasMap()) throw new FormatException();
|
||||
hasLookahead = false;
|
||||
while(!hasMapEnd()) {
|
||||
skipObject();
|
||||
skipObject();
|
||||
}
|
||||
hasLookahead = false;
|
||||
}
|
||||
}
|
||||
15
briar-core/src/org/briarproject/data/SerialModule.java
Normal file
15
briar-core/src/org/briarproject/data/SerialModule.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package org.briarproject.data;
|
||||
|
||||
import org.briarproject.api.data.ReaderFactory;
|
||||
import org.briarproject.api.data.WriterFactory;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
|
||||
public class SerialModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ReaderFactory.class).to(ReaderFactoryImpl.class);
|
||||
bind(WriterFactory.class).to(WriterFactoryImpl.class);
|
||||
}
|
||||
}
|
||||
21
briar-core/src/org/briarproject/data/Types.java
Normal file
21
briar-core/src/org/briarproject/data/Types.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package org.briarproject.data;
|
||||
|
||||
interface Types {
|
||||
|
||||
byte NULL = 0x00;
|
||||
byte BOOLEAN = 0x11;
|
||||
byte INT_8 = 0x21;
|
||||
byte INT_16 = 0x22;
|
||||
byte INT_32 = 0x24;
|
||||
byte INT_64 = 0x28;
|
||||
byte FLOAT_64 = 0x38;
|
||||
byte STRING_8 = 0x41;
|
||||
byte STRING_16 = 0x42;
|
||||
byte STRING_32 = 0x44;
|
||||
byte RAW_8 = 0x51;
|
||||
byte RAW_16 = 0x52;
|
||||
byte RAW_32 = 0x54;
|
||||
byte LIST = 0x60;
|
||||
byte MAP = 0x70;
|
||||
byte END = (byte) 0x80;
|
||||
}
|
||||
13
briar-core/src/org/briarproject/data/WriterFactoryImpl.java
Normal file
13
briar-core/src/org/briarproject/data/WriterFactoryImpl.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package org.briarproject.data;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.briarproject.api.data.Writer;
|
||||
import org.briarproject.api.data.WriterFactory;
|
||||
|
||||
class WriterFactoryImpl implements WriterFactory {
|
||||
|
||||
public Writer createWriter(OutputStream out) {
|
||||
return new WriterImpl(out);
|
||||
}
|
||||
}
|
||||
198
briar-core/src/org/briarproject/data/WriterImpl.java
Normal file
198
briar-core/src/org/briarproject/data/WriterImpl.java
Normal file
@@ -0,0 +1,198 @@
|
||||
package org.briarproject.data;
|
||||
|
||||
import static org.briarproject.data.Types.BOOLEAN;
|
||||
import static org.briarproject.data.Types.END;
|
||||
import static org.briarproject.data.Types.FLOAT_64;
|
||||
import static org.briarproject.data.Types.INT_16;
|
||||
import static org.briarproject.data.Types.INT_32;
|
||||
import static org.briarproject.data.Types.INT_64;
|
||||
import static org.briarproject.data.Types.INT_8;
|
||||
import static org.briarproject.data.Types.LIST;
|
||||
import static org.briarproject.data.Types.MAP;
|
||||
import static org.briarproject.data.Types.NULL;
|
||||
import static org.briarproject.data.Types.RAW_16;
|
||||
import static org.briarproject.data.Types.RAW_32;
|
||||
import static org.briarproject.data.Types.RAW_8;
|
||||
import static org.briarproject.data.Types.STRING_16;
|
||||
import static org.briarproject.data.Types.STRING_32;
|
||||
import static org.briarproject.data.Types.STRING_8;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.briarproject.api.Bytes;
|
||||
import org.briarproject.api.data.Consumer;
|
||||
import org.briarproject.api.data.Writer;
|
||||
|
||||
// This class is not thread-safe
|
||||
class WriterImpl implements Writer {
|
||||
|
||||
private final OutputStream out;
|
||||
private final Collection<Consumer> consumers = new ArrayList<Consumer>(0);
|
||||
|
||||
WriterImpl(OutputStream out) {
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
out.close();
|
||||
}
|
||||
|
||||
public void addConsumer(Consumer c) {
|
||||
consumers.add(c);
|
||||
}
|
||||
|
||||
public void removeConsumer(Consumer c) {
|
||||
if(!consumers.remove(c)) throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public void writeNull() throws IOException {
|
||||
write(NULL);
|
||||
}
|
||||
|
||||
public void writeBoolean(boolean b) throws IOException {
|
||||
write(BOOLEAN);
|
||||
if(b) write((byte) 1);
|
||||
else write((byte) 0);
|
||||
}
|
||||
|
||||
public void writeInteger(long i) throws IOException {
|
||||
if(i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE) {
|
||||
write(INT_8);
|
||||
write((byte) i);
|
||||
} else if(i >= Short.MIN_VALUE && i <= Short.MAX_VALUE) {
|
||||
write(INT_16);
|
||||
writeInt16((short) i);
|
||||
} else if(i >= Integer.MIN_VALUE && i <= Integer.MAX_VALUE) {
|
||||
write(INT_32);
|
||||
writeInt32((int) i);
|
||||
} else {
|
||||
write(INT_64);
|
||||
writeInt64(i);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeInt16(short i) throws IOException {
|
||||
write((byte) (i >> 8));
|
||||
write((byte) ((i << 8) >> 8));
|
||||
}
|
||||
|
||||
private void writeInt32(int i) throws IOException {
|
||||
write((byte) (i >> 24));
|
||||
write((byte) ((i << 8) >> 24));
|
||||
write((byte) ((i << 16) >> 24));
|
||||
write((byte) ((i << 24) >> 24));
|
||||
}
|
||||
|
||||
private void writeInt64(long i) throws IOException {
|
||||
write((byte) (i >> 56));
|
||||
write((byte) ((i << 8) >> 56));
|
||||
write((byte) ((i << 16) >> 56));
|
||||
write((byte) ((i << 24) >> 56));
|
||||
write((byte) ((i << 32) >> 56));
|
||||
write((byte) ((i << 40) >> 56));
|
||||
write((byte) ((i << 48) >> 56));
|
||||
write((byte) ((i << 56) >> 56));
|
||||
}
|
||||
|
||||
public void writeFloat(double d) throws IOException {
|
||||
write(FLOAT_64);
|
||||
writeInt64(Double.doubleToRawLongBits(d));
|
||||
}
|
||||
|
||||
public void writeString(String s) throws IOException {
|
||||
byte[] b = s.getBytes("UTF-8");
|
||||
if(b.length <= Byte.MAX_VALUE) {
|
||||
write(STRING_8);
|
||||
write((byte) b.length);
|
||||
} else if(b.length <= Short.MAX_VALUE) {
|
||||
write(STRING_16);
|
||||
writeInt16((short) b.length);
|
||||
} else {
|
||||
write(STRING_32);
|
||||
writeInt32(b.length);
|
||||
}
|
||||
write(b);
|
||||
}
|
||||
|
||||
public void writeBytes(byte[] b) throws IOException {
|
||||
if(b.length <= Byte.MAX_VALUE) {
|
||||
write(RAW_8);
|
||||
write((byte) b.length);
|
||||
} else if(b.length <= Short.MAX_VALUE) {
|
||||
write(RAW_16);
|
||||
writeInt16((short) b.length);
|
||||
} else {
|
||||
write(RAW_32);
|
||||
writeInt32(b.length);
|
||||
}
|
||||
write(b);
|
||||
}
|
||||
|
||||
public void writeList(Collection<?> c) throws IOException {
|
||||
write(Types.LIST);
|
||||
for(Object o : c) writeObject(o);
|
||||
write(Types.END);
|
||||
}
|
||||
|
||||
private void writeObject(Object o) throws IOException {
|
||||
if(o instanceof Boolean) writeBoolean((Boolean) o);
|
||||
else if(o instanceof Byte) writeInteger((Byte) o);
|
||||
else if(o instanceof Short) writeInteger((Short) o);
|
||||
else if(o instanceof Integer) writeInteger((Integer) o);
|
||||
else if(o instanceof Long) writeInteger((Long) o);
|
||||
else if(o instanceof Float) writeFloat((Float) o);
|
||||
else if(o instanceof Double) writeFloat((Double) o);
|
||||
else if(o instanceof String) writeString((String) o);
|
||||
else if(o instanceof byte[]) writeBytes((byte[]) o);
|
||||
else if(o instanceof Bytes) writeBytes(((Bytes) o).getBytes());
|
||||
else if(o instanceof List<?>) writeList((List<?>) o);
|
||||
else if(o instanceof Map<?, ?>) writeMap((Map<?, ?>) o);
|
||||
else if(o == null) writeNull();
|
||||
else throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public void writeListStart() throws IOException {
|
||||
write(LIST);
|
||||
}
|
||||
|
||||
public void writeListEnd() throws IOException {
|
||||
write(END);
|
||||
}
|
||||
|
||||
public void writeMap(Map<?, ?> m) throws IOException {
|
||||
write(MAP);
|
||||
for(Entry<?, ?> e : m.entrySet()) {
|
||||
writeObject(e.getKey());
|
||||
writeObject(e.getValue());
|
||||
}
|
||||
write(END);
|
||||
}
|
||||
|
||||
public void writeMapStart() throws IOException {
|
||||
write(MAP);
|
||||
}
|
||||
|
||||
public void writeMapEnd() throws IOException {
|
||||
write(END);
|
||||
}
|
||||
|
||||
private void write(byte b) throws IOException {
|
||||
out.write(b);
|
||||
for(Consumer c : consumers) c.write(b);
|
||||
}
|
||||
|
||||
private void write(byte[] b) throws IOException {
|
||||
out.write(b);
|
||||
for(Consumer c : consumers) c.write(b, 0, b.length);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user