mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 13:19:52 +01:00
Use whole buffers for reads and writes.
This commit is contained in:
@@ -7,20 +7,21 @@ class Ack extends Frame {
|
|||||||
static final int LENGTH = 12;
|
static final int LENGTH = 12;
|
||||||
|
|
||||||
Ack() {
|
Ack() {
|
||||||
super(new byte[LENGTH], LENGTH);
|
super(new byte[LENGTH]);
|
||||||
b[0] = (byte) Frame.ACK_FLAG;
|
buf[0] = (byte) Frame.ACK_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ack(byte[] b) {
|
Ack(byte[] buf) {
|
||||||
super(b, LENGTH);
|
super(buf);
|
||||||
b[0] = (byte) Frame.ACK_FLAG;
|
if(buf.length != LENGTH) throw new IllegalArgumentException();
|
||||||
|
buf[0] = (byte) Frame.ACK_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getWindowSize() {
|
int getWindowSize() {
|
||||||
return ByteUtils.readUint24(b, 5);
|
return ByteUtils.readUint24(buf, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowSize(int windowSize) {
|
void setWindowSize(int windowSize) {
|
||||||
ByteUtils.writeUint24(windowSize, b, 5);
|
ByteUtils.writeUint24(windowSize, buf, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,21 +7,21 @@ class Data extends Frame {
|
|||||||
static final int MAX_PAYLOAD_LENGTH = 1024;
|
static final int MAX_PAYLOAD_LENGTH = 1024;
|
||||||
static final int MAX_LENGTH = MIN_LENGTH + MAX_PAYLOAD_LENGTH;
|
static final int MAX_LENGTH = MIN_LENGTH + MAX_PAYLOAD_LENGTH;
|
||||||
|
|
||||||
Data(byte[] b, int length) {
|
Data(byte[] buf) {
|
||||||
super(b, length);
|
super(buf);
|
||||||
if(length < MIN_LENGTH || length > MAX_LENGTH)
|
if(buf.length < MIN_LENGTH || buf.length > MAX_LENGTH)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isLastFrame() {
|
boolean isLastFrame() {
|
||||||
return b[0] == Frame.FIN_FLAG;
|
return buf[0] == Frame.FIN_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLastFrame(boolean lastFrame) {
|
void setLastFrame(boolean lastFrame) {
|
||||||
if(lastFrame) b[0] = (byte) Frame.FIN_FLAG;
|
if(lastFrame) buf[0] = (byte) Frame.FIN_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getPayloadLength() {
|
int getPayloadLength() {
|
||||||
return length - MIN_LENGTH;
|
return buf.length - MIN_LENGTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,40 +6,38 @@ abstract class Frame {
|
|||||||
|
|
||||||
static final byte ACK_FLAG = (byte) 128, FIN_FLAG = 64;
|
static final byte ACK_FLAG = (byte) 128, FIN_FLAG = 64;
|
||||||
|
|
||||||
protected final byte[] b;
|
protected final byte[] buf;
|
||||||
protected final int length;
|
|
||||||
|
|
||||||
Frame(byte[] b, int length) {
|
Frame(byte[] buf) {
|
||||||
this.b = b;
|
this.buf = buf;
|
||||||
this.length = length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] getBuffer() {
|
byte[] getBuffer() {
|
||||||
return b;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getLength() {
|
int getLength() {
|
||||||
return length;
|
return buf.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
long getChecksum() {
|
long getChecksum() {
|
||||||
return ByteUtils.readUint32(b, length - 4);
|
return ByteUtils.readUint32(buf, buf.length - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setChecksum(long checksum) {
|
void setChecksum(long checksum) {
|
||||||
ByteUtils.writeUint32(checksum, b, length - 4);
|
ByteUtils.writeUint32(checksum, buf, buf.length - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
long calculateChecksum() {
|
long calculateChecksum() {
|
||||||
return Crc32.crc(b, 0, length - 4);
|
return Crc32.crc(buf, 0, buf.length - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
long getSequenceNumber() {
|
long getSequenceNumber() {
|
||||||
return ByteUtils.readUint32(b, 1);
|
return ByteUtils.readUint32(buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSequenceNumber(long sequenceNumber) {
|
void setSequenceNumber(long sequenceNumber) {
|
||||||
ByteUtils.writeUint32(sequenceNumber, b, 1);
|
ByteUtils.writeUint32(sequenceNumber, buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -51,7 +49,7 @@ abstract class Frame {
|
|||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if(o instanceof Frame) {
|
if(o instanceof Frame) {
|
||||||
Frame f = (Frame) o;
|
Frame f = (Frame) o;
|
||||||
if(b[0] != f.b[0]) return false;
|
if(buf[0] != f.buf[0]) return false;
|
||||||
return getSequenceNumber() == f.getSequenceNumber();
|
return getSequenceNumber() == f.getSequenceNumber();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -135,12 +135,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
offHook.release();
|
offHook.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleWrite(byte[] b, int length) throws IOException {
|
public void handleWrite(byte[] b) throws IOException {
|
||||||
if(length < b.length) {
|
|
||||||
byte[] copy = new byte[length];
|
|
||||||
System.arraycopy(b, 0, copy, 0, length);
|
|
||||||
b = copy;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
port.writeBytes(b);
|
port.writeBytes(b);
|
||||||
} catch(SerialPortException e) {
|
} catch(SerialPortException e) {
|
||||||
@@ -153,7 +148,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
try {
|
try {
|
||||||
if(ev.isRXCHAR()) {
|
if(ev.isRXCHAR()) {
|
||||||
byte[] b = port.readBytes();
|
byte[] b = port.readBytes();
|
||||||
if(connected.get()) reliabilityLayer.handleRead(b, b.length);
|
if(connected.get()) reliabilityLayer.handleRead(b);
|
||||||
else handleText(b);
|
else handleText(b);
|
||||||
} else if(ev.isDSR() && ev.getEventValue() == 0) {
|
} else if(ev.isDSR() && ev.getEventValue() == 0) {
|
||||||
if(LOG.isLoggable(INFO)) LOG.info("Remote end hung up");
|
if(LOG.isLoggable(INFO)) LOG.info("Remote end hung up");
|
||||||
@@ -188,7 +183,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
if(off < b.length) {
|
if(off < b.length) {
|
||||||
byte[] data = new byte[b.length - off];
|
byte[] data = new byte[b.length - off];
|
||||||
System.arraycopy(b, off, data, 0, data.length);
|
System.arraycopy(b, off, data, 0, data.length);
|
||||||
reliabilityLayer.handleRead(data, data.length);
|
reliabilityLayer.handleRead(data);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if(s.equals("OK")) {
|
} else if(s.equals("OK")) {
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ import java.io.IOException;
|
|||||||
|
|
||||||
interface ReadHandler {
|
interface ReadHandler {
|
||||||
|
|
||||||
void handleRead(byte[] b, int length) throws IOException;
|
void handleRead(byte[] b) throws IOException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,20 +65,15 @@ class Receiver implements ReadHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleRead(byte[] b, int length) throws IOException {
|
public void handleRead(byte[] b) throws IOException {
|
||||||
if(!valid) throw new IOException("Connection closed");
|
if(!valid) throw new IOException("Connection closed");
|
||||||
if(length < Data.MIN_LENGTH || length > Data.MAX_LENGTH) {
|
|
||||||
if(LOG.isLoggable(FINE))
|
|
||||||
LOG.fine("Ignoring frame with invalid length");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch(b[0]) {
|
switch(b[0]) {
|
||||||
case 0:
|
case 0:
|
||||||
case Frame.FIN_FLAG:
|
case Frame.FIN_FLAG:
|
||||||
handleData(b, length);
|
handleData(b);
|
||||||
break;
|
break;
|
||||||
case Frame.ACK_FLAG:
|
case Frame.ACK_FLAG:
|
||||||
sender.handleAck(b, length);
|
sender.handleAck(b);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(LOG.isLoggable(FINE)) LOG.fine("Ignoring unknown frame type");
|
if(LOG.isLoggable(FINE)) LOG.fine("Ignoring unknown frame type");
|
||||||
@@ -86,9 +81,13 @@ class Receiver implements ReadHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void handleData(byte[] b, int length)
|
private synchronized void handleData(byte[] b) throws IOException {
|
||||||
throws IOException {
|
if(b.length < Data.MIN_LENGTH || b.length > Data.MAX_LENGTH) {
|
||||||
Data d = new Data(b, length);
|
if(LOG.isLoggable(FINE))
|
||||||
|
LOG.fine("Ignoring data frame with invalid length");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Data d = new Data(b);
|
||||||
int payloadLength = d.getPayloadLength();
|
int payloadLength = d.getPayloadLength();
|
||||||
if(payloadLength > windowSize) {
|
if(payloadLength > windowSize) {
|
||||||
if(LOG.isLoggable(FINE)) LOG.fine("No space in the window");
|
if(LOG.isLoggable(FINE)) LOG.fine("No space in the window");
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class ReliabilityLayer implements ReadHandler, WriteHandler {
|
|||||||
while(valid) {
|
while(valid) {
|
||||||
byte[] b = writes.take();
|
byte[] b = writes.take();
|
||||||
if(b.length == 0) return; // Poison pill
|
if(b.length == 0) return; // Poison pill
|
||||||
writeHandler.handleWrite(b, b.length);
|
writeHandler.handleWrite(b);
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch(InterruptedException e) {
|
||||||
if(LOG.isLoggable(WARNING))
|
if(LOG.isLoggable(WARNING))
|
||||||
@@ -73,20 +73,14 @@ class ReliabilityLayer implements ReadHandler, WriteHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The modem calls this method to pass data up to the SLIP decoder
|
// The modem calls this method to pass data up to the SLIP decoder
|
||||||
public void handleRead(byte[] b, int length) throws IOException {
|
public void handleRead(byte[] b) throws IOException {
|
||||||
if(!valid) throw new IOException("Connection closed");
|
if(!valid) throw new IOException("Connection closed");
|
||||||
decoder.handleRead(b, length);
|
decoder.handleRead(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The SLIP encoder calls this method to pass data down to the modem
|
// The SLIP encoder calls this method to pass data down to the modem
|
||||||
public void handleWrite(byte[] b, int length) throws IOException {
|
public void handleWrite(byte[] b) throws IOException {
|
||||||
if(!valid) throw new IOException("Connection closed");
|
if(!valid) throw new IOException("Connection closed");
|
||||||
if(length == 0) return;
|
if(b.length > 0) writes.add(b);
|
||||||
if(length < b.length) {
|
|
||||||
byte[] copy = new byte[length];
|
|
||||||
System.arraycopy(b, 0, copy, 0, length);
|
|
||||||
b = copy;
|
|
||||||
}
|
|
||||||
writes.add(b);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,13 +47,13 @@ class Sender {
|
|||||||
if(LOG.isLoggable(FINE))
|
if(LOG.isLoggable(FINE))
|
||||||
LOG.fine("Acknowledging #" + sequenceNumber);
|
LOG.fine("Acknowledging #" + sequenceNumber);
|
||||||
}
|
}
|
||||||
writeHandler.handleWrite(a.getBuffer(), a.getLength());
|
writeHandler.handleWrite(a.getBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleAck(byte[] b, int length) {
|
void handleAck(byte[] b) {
|
||||||
if(length != Ack.LENGTH) {
|
if(b.length != Ack.LENGTH) {
|
||||||
if(LOG.isLoggable(FINE))
|
if(LOG.isLoggable(FINE))
|
||||||
LOG.fine("Ignoring ack frame with wrong length");
|
LOG.fine("Ignoring ack frame with invalid length");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Ack a = new Ack(b);
|
Ack a = new Ack(b);
|
||||||
@@ -115,7 +115,7 @@ class Sender {
|
|||||||
if(fastRetransmit != null) {
|
if(fastRetransmit != null) {
|
||||||
Data d = fastRetransmit.data;
|
Data d = fastRetransmit.data;
|
||||||
try {
|
try {
|
||||||
writeHandler.handleWrite(d.getBuffer(), d.getLength());
|
writeHandler.handleWrite(d.getBuffer());
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
// FIXME: Do something more meaningful
|
// FIXME: Do something more meaningful
|
||||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||||
@@ -169,16 +169,14 @@ class Sender {
|
|||||||
// Send a window probe if necessary
|
// Send a window probe if necessary
|
||||||
if(sendProbe) {
|
if(sendProbe) {
|
||||||
byte[] buf = new byte[Data.MIN_LENGTH];
|
byte[] buf = new byte[Data.MIN_LENGTH];
|
||||||
Data probe = new Data(buf, Data.MIN_LENGTH);
|
Data probe = new Data(buf);
|
||||||
probe.setChecksum(probe.calculateChecksum());
|
probe.setChecksum(probe.calculateChecksum());
|
||||||
writeHandler.handleWrite(buf, Data.MIN_LENGTH);
|
writeHandler.handleWrite(buf);
|
||||||
}
|
}
|
||||||
// Retransmit any lost data frames
|
// Retransmit any lost data frames
|
||||||
if(retransmit != null) {
|
if(retransmit != null) {
|
||||||
for(Outstanding o : retransmit) {
|
for(Outstanding o : retransmit)
|
||||||
Data d = o.data;
|
writeHandler.handleWrite(o.data.getBuffer());
|
||||||
writeHandler.handleWrite(d.getBuffer(), d.getLength());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
// FIXME: Do something more meaningful
|
// FIXME: Do something more meaningful
|
||||||
@@ -202,7 +200,7 @@ class Sender {
|
|||||||
}
|
}
|
||||||
if(LOG.isLoggable(FINE))
|
if(LOG.isLoggable(FINE))
|
||||||
LOG.fine("Transmitting #" + d.getSequenceNumber());
|
LOG.fine("Transmitting #" + d.getSequenceNumber());
|
||||||
writeHandler.handleWrite(d.getBuffer(), d.getLength());
|
writeHandler.handleWrite(d.getBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Outstanding {
|
private static class Outstanding {
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import java.io.OutputStream;
|
|||||||
class SenderOutputStream extends OutputStream {
|
class SenderOutputStream extends OutputStream {
|
||||||
|
|
||||||
private final Sender sender;
|
private final Sender sender;
|
||||||
|
private final byte[] buf = new byte[Data.MAX_LENGTH];
|
||||||
|
|
||||||
private byte[] buf = null;
|
|
||||||
private int offset = 0;
|
private int offset = 0;
|
||||||
private long sequenceNumber = 1L;
|
private long sequenceNumber = 1L;
|
||||||
|
|
||||||
@@ -17,18 +17,16 @@ class SenderOutputStream extends OutputStream {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
if(buf == null) assignBuffer();
|
|
||||||
send(true);
|
send(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() throws IOException {
|
public void flush() throws IOException {
|
||||||
if(buf != null) send(false);
|
if(offset > Data.HEADER_LENGTH) send(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(int b) throws IOException {
|
public void write(int b) throws IOException {
|
||||||
if(buf == null) assignBuffer();
|
|
||||||
buf[offset] = (byte) b;
|
buf[offset] = (byte) b;
|
||||||
offset++;
|
offset++;
|
||||||
if(offset == Data.HEADER_LENGTH + Data.MAX_PAYLOAD_LENGTH) send(false);
|
if(offset == Data.HEADER_LENGTH + Data.MAX_PAYLOAD_LENGTH) send(false);
|
||||||
@@ -41,13 +39,11 @@ class SenderOutputStream extends OutputStream {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(byte[] b, int off, int len) throws IOException {
|
public void write(byte[] b, int off, int len) throws IOException {
|
||||||
if(buf == null) assignBuffer();
|
|
||||||
int available = Data.MAX_LENGTH - offset - Data.FOOTER_LENGTH;
|
int available = Data.MAX_LENGTH - offset - Data.FOOTER_LENGTH;
|
||||||
while(available <= len) {
|
while(available <= len) {
|
||||||
System.arraycopy(b, off, buf, offset, available);
|
System.arraycopy(b, off, buf, offset, available);
|
||||||
offset += available;
|
offset += available;
|
||||||
send(false);
|
send(false);
|
||||||
assignBuffer();
|
|
||||||
off += available;
|
off += available;
|
||||||
len -= available;
|
len -= available;
|
||||||
available = Data.MAX_LENGTH - offset - Data.FOOTER_LENGTH;
|
available = Data.MAX_LENGTH - offset - Data.FOOTER_LENGTH;
|
||||||
@@ -56,13 +52,10 @@ class SenderOutputStream extends OutputStream {
|
|||||||
offset += len;
|
offset += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assignBuffer() {
|
|
||||||
buf = new byte[Data.MAX_LENGTH];
|
|
||||||
offset = Data.HEADER_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void send(boolean lastFrame) throws IOException {
|
private void send(boolean lastFrame) throws IOException {
|
||||||
Data d = new Data(buf, offset + Data.FOOTER_LENGTH);
|
byte[] frame = new byte[offset + Data.FOOTER_LENGTH];
|
||||||
|
System.arraycopy(buf, 0, frame, 0, frame.length);
|
||||||
|
Data d = new Data(frame);
|
||||||
d.setLastFrame(lastFrame);
|
d.setLastFrame(lastFrame);
|
||||||
d.setSequenceNumber(sequenceNumber++);
|
d.setSequenceNumber(sequenceNumber++);
|
||||||
d.setChecksum(d.calculateChecksum());
|
d.setChecksum(d.calculateChecksum());
|
||||||
@@ -72,7 +65,6 @@ class SenderOutputStream extends OutputStream {
|
|||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
throw new IOException("Interrupted while writing");
|
throw new IOException("Interrupted while writing");
|
||||||
}
|
}
|
||||||
buf = null;
|
offset = Data.HEADER_LENGTH;
|
||||||
offset = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,16 +24,17 @@ class SlipDecoder implements ReadHandler {
|
|||||||
this.readHandler = readHandler;
|
this.readHandler = readHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleRead(byte[] b, int length) throws IOException {
|
public void handleRead(byte[] b) throws IOException {
|
||||||
for(int i = 0; i < length; i++) {
|
for(int i = 0; i < b.length; i++) {
|
||||||
switch(b[i]) {
|
switch(b[i]) {
|
||||||
case END:
|
case END:
|
||||||
if(escape) {
|
if(escape) {
|
||||||
reset(true);
|
reset(true);
|
||||||
} else {
|
} else {
|
||||||
if(decodedLength > 0) {
|
if(decodedLength > 0) {
|
||||||
readHandler.handleRead(buf, decodedLength);
|
byte[] decoded = new byte[decodedLength];
|
||||||
buf = new byte[Data.MAX_LENGTH];
|
System.arraycopy(buf, 0, decoded, 0, decodedLength);
|
||||||
|
readHandler.handleRead(decoded);
|
||||||
}
|
}
|
||||||
reset(false);
|
reset(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,26 +14,25 @@ class SlipEncoder implements WriteHandler {
|
|||||||
this.writeHandler = writeHandler;
|
this.writeHandler = writeHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleWrite(byte[] b, int length) throws IOException {
|
public void handleWrite(byte[] b) throws IOException {
|
||||||
if(length > Data.MAX_LENGTH) throw new IllegalArgumentException();
|
if(b.length > Data.MAX_LENGTH) throw new IllegalArgumentException();
|
||||||
int encodedLength = length + 2;
|
int encodedLength = b.length + 2;
|
||||||
for(int i = 0; i < length; i++) {
|
for(int i = 0; i < b.length; i++)
|
||||||
if(b[i] == END || b[i] == ESC) encodedLength++;
|
if(b[i] == END || b[i] == ESC) encodedLength++;
|
||||||
}
|
byte[] encoded = new byte[encodedLength];
|
||||||
byte[] buf = new byte[encodedLength];
|
encoded[0] = END;
|
||||||
buf[0] = END;
|
for(int i = 0, j = 1; i < b.length; i++) {
|
||||||
for(int i = 0, j = 1; i < length; i++) {
|
|
||||||
if(b[i] == END) {
|
if(b[i] == END) {
|
||||||
buf[j++] = ESC;
|
encoded[j++] = ESC;
|
||||||
buf[j++] = TEND;
|
encoded[j++] = TEND;
|
||||||
} else if(b[i] == ESC) {
|
} else if(b[i] == ESC) {
|
||||||
buf[j++] = ESC;
|
encoded[j++] = ESC;
|
||||||
buf[j++] = TESC;
|
encoded[j++] = TESC;
|
||||||
} else {
|
} else {
|
||||||
buf[j++] = b[i];
|
encoded[j++] = b[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf[encodedLength - 1] = END;
|
encoded[encodedLength - 1] = END;
|
||||||
writeHandler.handleWrite(buf, encodedLength);
|
writeHandler.handleWrite(encoded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ import java.io.IOException;
|
|||||||
|
|
||||||
interface WriteHandler {
|
interface WriteHandler {
|
||||||
|
|
||||||
void handleWrite(byte[] b, int length) throws IOException;
|
void handleWrite(byte[] b) throws IOException;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user