Reduce byte[] allocations in SerialInputStream and SerialOutputStream
* use a shared, re-usable buffer for single byte reads and writes * implement read(byte[]) directly instead of delegating to read(byte[], int, int), which makes an unnecessary copy. * implement write(byte[]) directly instead of delegating to write(byte[], int, int), which makes an unnecessary copy. * avoid a corner case unnecessary copy in write(byte[], int, int)
This commit is contained in:
parent
46790676e6
commit
6edf6f9396
|
@ -27,12 +27,12 @@ package com.fazecast.jSerialComm;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
@ -1022,6 +1022,11 @@ public final class SerialPort
|
||||||
// InputStream interface class
|
// InputStream interface class
|
||||||
private final class SerialPortInputStream extends InputStream
|
private final class SerialPortInputStream extends InputStream
|
||||||
{
|
{
|
||||||
|
// a shared, re-usable, single-byte scratch buffer to avoid allocating
|
||||||
|
// a new byte[] when reading a single byte. not thread safe, but neither
|
||||||
|
// SerialPort nor its Input/Output streams are to begin with.
|
||||||
|
private final byte[] singleByteBuffer = new byte[1];
|
||||||
|
|
||||||
public SerialPortInputStream() {}
|
public SerialPortInputStream() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1036,23 +1041,30 @@ public final class SerialPort
|
||||||
@Override
|
@Override
|
||||||
public final int read() throws IOException
|
public final int read() throws IOException
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[1];
|
|
||||||
int bytesRead;
|
int bytesRead;
|
||||||
|
|
||||||
while (isOpened)
|
while (isOpened)
|
||||||
{
|
{
|
||||||
bytesRead = readBytes(portHandle, buffer, 1l);
|
bytesRead = readBytes(portHandle, singleByteBuffer, 1L);
|
||||||
|
|
||||||
if (bytesRead > 0)
|
if (bytesRead > 0)
|
||||||
return ((int)buffer[0] & 0x000000FF);
|
return ((int) singleByteBuffer[0] & 0xFF);
|
||||||
try { Thread.sleep(1); } catch (Exception e) {}
|
|
||||||
|
sleep1();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IOException("This port appears to have been shutdown or disconnected.");
|
throw new IOException("This port appears to have been shutdown or disconnected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final int read(byte[] b) throws IOException
|
public final int read(byte[] b) throws IOException
|
||||||
{
|
{
|
||||||
return read(b, 0, b.length);
|
if (!isOpened)
|
||||||
|
throw new IOException("This port appears to have been shutdown or disconnected.");
|
||||||
|
if (b.length == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return readBytes(portHandle, b, b.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1085,6 +1097,11 @@ public final class SerialPort
|
||||||
// OutputStream interface class
|
// OutputStream interface class
|
||||||
private final class SerialPortOutputStream extends OutputStream
|
private final class SerialPortOutputStream extends OutputStream
|
||||||
{
|
{
|
||||||
|
// a shared, re-usable, single-byte scratch buffer to avoid allocating
|
||||||
|
// a new byte[] when writing a single byte. not thread safe, but neither
|
||||||
|
// SerialPort nor its Input/Output streams are to begin with.
|
||||||
|
private final byte[] singleByteBuffer = new byte[1];
|
||||||
|
|
||||||
public SerialPortOutputStream() {}
|
public SerialPortOutputStream() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1093,28 +1110,40 @@ public final class SerialPort
|
||||||
if (!isOpened)
|
if (!isOpened)
|
||||||
throw new IOException("This port appears to have been shutdown or disconnected.");
|
throw new IOException("This port appears to have been shutdown or disconnected.");
|
||||||
|
|
||||||
byte[] buffer = new byte[1];
|
singleByteBuffer[0] = (byte) (b & 0xFF);
|
||||||
buffer[0] = (byte)(b & 0x000000FF);
|
|
||||||
if (writeBytes(portHandle, buffer, 1l) < 0)
|
if (writeBytes(portHandle, singleByteBuffer, 1L) < 0)
|
||||||
throw new IOException("This port appears to have been shutdown or disconnected.");
|
throw new IOException("This port appears to have been shutdown or disconnected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void write(byte[] b) throws IOException
|
public final void write(byte[] b) throws IOException
|
||||||
{
|
{
|
||||||
write(b, 0, b.length);
|
if (!isOpened)
|
||||||
|
throw new IOException("This port appears to have been shutdown or disconnected.");
|
||||||
|
|
||||||
|
if (writeBytes(portHandle, b, b.length) < 0)
|
||||||
|
throw new IOException("This port appears to have been shutdown or disconnected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void write(byte[] b, int off, int len) throws IOException
|
public final void write(byte[] b, int off, int len) throws IOException
|
||||||
{
|
{
|
||||||
if (!isOpened)
|
if (off == 0 && len == b.length)
|
||||||
throw new IOException("This port appears to have been shutdown or disconnected.");
|
{
|
||||||
|
write(b);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
byte[] buffer = new byte[len];
|
byte[] buffer = new byte[len];
|
||||||
System.arraycopy(b, off, buffer, 0, len);
|
System.arraycopy(b, off, buffer, 0, len);
|
||||||
if (writeBytes(portHandle, buffer, len) < 0)
|
write(buffer);
|
||||||
throw new IOException("This port appears to have been shutdown or disconnected.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void sleep1() {
|
||||||
|
try { Thread.sleep(1); } catch (Exception ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue