merged with protocols buffer and testing write buffer with okio

pull/197/head
Felipe Herranz 2019-01-05 17:14:20 +01:00
commit 72d736bb46
5 zmienionych plików z 490 dodań i 9 usunięć

Wyświetl plik

@ -37,6 +37,13 @@ android {
dependencies {
implementation 'com.annimon:stream:1.2.1'
implementation 'com.squareup.okio:okio:2.1.0'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'junit:junit:4.12'
testImplementation 'junit:junit:4.12'
}
createJar.dependsOn(deleteJar, build)

Wyświetl plik

@ -0,0 +1,107 @@
package com.felhr.tests.usbserial;
import com.felhr.usbserial.SerialBuffer;
import junit.framework.TestCase;
import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays;
import java.util.Random;
public class SerialBufferTest extends TestCase {
private static final int BIG_BUFFER_1 = 64 * 1024;
private static final int BIG_BUFFER_2 = 1024 * 1024;
private static final String text1 = "HOLA";
private static final byte[] bigBuffer = new byte[BIG_BUFFER_1];
private static final byte[] bigBuffer2 = new byte[BIG_BUFFER_2];
private SerialBuffer serialBuffer;
@Test
public void testSimpleWriteBuffer(){
serialBuffer = new SerialBuffer(true);
serialBuffer.putWriteBuffer(text1.getBytes());
byte[] dataReceived = serialBuffer.getWriteBuffer();
assertEquals(text1, new String(dataReceived));
}
@Test
public void testBigSimpleWriteBuffer(){
Arrays.fill(bigBuffer, (byte) 0x0A);
serialBuffer = new SerialBuffer(true);
serialBuffer.putWriteBuffer(bigBuffer);
byte[] dataReceived = serialBuffer.getWriteBuffer();
Assert.assertArrayEquals(bigBuffer, dataReceived);
}
@Test
public void testSuperBigSimpleWriteBuffer(){
new Random().nextBytes(bigBuffer2);
serialBuffer = new SerialBuffer(true);
serialBuffer.putWriteBuffer(bigBuffer2);
byte[] dataReceived = serialBuffer.getWriteBuffer();
Assert.assertArrayEquals(bigBuffer2, dataReceived);
}
@Test
public void testSimpleWriteBufferAsync1(){
new Random().nextBytes(bigBuffer2);
serialBuffer = new SerialBuffer(true);
WriterThread writerThread = new WriterThread(serialBuffer, bigBuffer2, false);
writerThread.start();
byte[] dataReceived = serialBuffer.getWriteBuffer();
Assert.assertArrayEquals(bigBuffer2, dataReceived);
}
@Test
public void testSimpleWriteBufferAsync2(){
new Random().nextBytes(bigBuffer2);
serialBuffer = new SerialBuffer(true);
WriterThread writerThread = new WriterThread(serialBuffer, bigBuffer2, true);
writerThread.start();
byte[] dataReceived = serialBuffer.getWriteBuffer();
Assert.assertArrayEquals(bigBuffer2, dataReceived);
}
private class WriterThread extends Thread{
private final static long DELAY_TIME = 5000;
private SerialBuffer serialBuffer;
private byte[] data;
private boolean delay;
public WriterThread(SerialBuffer serialBuffer, byte[] data, boolean delay){
this.serialBuffer = serialBuffer;
this.data = data;
this.delay = delay;
}
@Override
public void run() {
if(delay)
delayWrite();
serialBuffer.putWriteBuffer(data);
}
private void delayWrite(){
synchronized (this) {
try {
wait(DELAY_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

Wyświetl plik

@ -0,0 +1,214 @@
package com.felhr.tests.utils;
import com.felhr.utils.ProtocolBuffer;
import junit.framework.TestCase;
import org.junit.Assert;
import org.junit.Test;
public class ProtocolBufferTest extends TestCase {
private final String onePacket = "$GPAAM,A,A,0.10,N,WPTNME*32\r\n";
private final String twoPackets = "$GPAAM,A,A,0.10,N,WPTNME*32\r\n$GPGGA,092750.000,5321.6802,N,00630.3372,W,1,8,1.03,61.7,M,55.2,M,,*76\r\n";
private final String splitPacket = "$GPAAM,A,A,0.10,N,WPTN";
private final String oneHalfPacket = "$GPAAM,A,A,0.10,N,WPTNME*32\r\n$GPGGA,092750.000";
private final String[] verySplit ={"$GPAAM,",
"A",
",",
"A,",
"0",
".",
"10,N",
",WPTNME*32\r\n"};
private final byte[] rawPacket = new byte[]{0x21, 0x3b, 0x20, 0x40};
private final byte[] twoRawPackets = new byte[]{0x21, 0x3b, 0x20, 0x40, 0x4a, 0x20, 0x40};
private final byte[] splitRawPacket = new byte[]{0x21, 0x3b, 0x20, 0x40, 0x4a};
private final byte[][] verySplitRawPacket = {
new byte[]{0x21},
new byte[]{0x3b},
new byte[]{0x20},
new byte[]{0x40}};
private ProtocolBuffer protocolBuffer;
private final String modeText = ProtocolBuffer.TEXT;
private final String modeBinary = ProtocolBuffer.BINARY;
@Test
public void testOnePacket(){
protocolBuffer = new ProtocolBuffer(modeText);
protocolBuffer.setDelimiter("\r\n");
protocolBuffer.appendData(onePacket.getBytes());
boolean hasMoreData = protocolBuffer.hasMoreCommands();
assertTrue(hasMoreData);
String nextCommand = protocolBuffer.nextTextCommand();
assertEquals(onePacket, nextCommand);
}
@Test
public void testTwoPackets(){
protocolBuffer = new ProtocolBuffer(modeText);
protocolBuffer.setDelimiter("\r\n");
protocolBuffer.appendData(twoPackets.getBytes());
StringBuilder builder = new StringBuilder();
while(protocolBuffer.hasMoreCommands()){
builder.append(protocolBuffer.nextTextCommand());
}
assertEquals(twoPackets, builder.toString());
}
@Test
public void testSplitPackets(){
protocolBuffer = new ProtocolBuffer(modeText);
protocolBuffer.setDelimiter("\r\n");
protocolBuffer.appendData(splitPacket.getBytes());
boolean hasMoreData = protocolBuffer.hasMoreCommands();
assertFalse(hasMoreData);
}
@Test
public void testOneHalfPacket(){
protocolBuffer = new ProtocolBuffer(modeText);
protocolBuffer.setDelimiter("\r\n");
protocolBuffer.appendData(oneHalfPacket.getBytes());
boolean hasMoreData = protocolBuffer.hasMoreCommands();
assertTrue(hasMoreData);
String nextCommand = protocolBuffer.nextTextCommand();
assertEquals("$GPAAM,A,A,0.10,N,WPTNME*32\r\n", nextCommand);
hasMoreData = protocolBuffer.hasMoreCommands();
assertFalse(hasMoreData);
nextCommand = protocolBuffer.nextTextCommand();
assertNull(nextCommand);
}
@Test
public void testVerySplit(){
protocolBuffer = new ProtocolBuffer(modeText);
protocolBuffer.setDelimiter("\r\n");
protocolBuffer.appendData(verySplit[0].getBytes());
boolean hasMoreData = protocolBuffer.hasMoreCommands();
assertFalse(hasMoreData);
protocolBuffer.appendData(verySplit[1].getBytes());
hasMoreData = protocolBuffer.hasMoreCommands();
assertFalse(hasMoreData);
protocolBuffer.appendData(verySplit[2].getBytes());
hasMoreData = protocolBuffer.hasMoreCommands();
assertFalse(hasMoreData);
protocolBuffer.appendData(verySplit[3].getBytes());
hasMoreData = protocolBuffer.hasMoreCommands();
assertFalse(hasMoreData);
protocolBuffer.appendData(verySplit[4].getBytes());
hasMoreData = protocolBuffer.hasMoreCommands();
assertFalse(hasMoreData);
protocolBuffer.appendData(verySplit[5].getBytes());
hasMoreData = protocolBuffer.hasMoreCommands();
assertFalse(hasMoreData);
protocolBuffer.appendData(verySplit[6].getBytes());
hasMoreData = protocolBuffer.hasMoreCommands();
assertFalse(hasMoreData);
protocolBuffer.appendData(verySplit[7].getBytes());
hasMoreData = protocolBuffer.hasMoreCommands();
assertTrue(hasMoreData);
String command = protocolBuffer.nextTextCommand();
assertEquals("$GPAAM,A,A,0.10,N,WPTNME*32\r\n", command);
}
@Test
public void testRawPacket(){
protocolBuffer = new ProtocolBuffer(modeBinary);
protocolBuffer.setDelimiter(new byte[]{0x20, 0x40});
protocolBuffer.appendData(rawPacket);
boolean hasMoreData = protocolBuffer.hasMoreCommands();
assertTrue(hasMoreData);
byte[] command = protocolBuffer.nextBinaryCommand();
Assert.assertArrayEquals(command, rawPacket);
command = protocolBuffer.nextBinaryCommand();
assertNull(command);
}
@Test
public void testTwoRawPackets(){
protocolBuffer = new ProtocolBuffer(modeBinary);
protocolBuffer.setDelimiter(new byte[]{0x20, 0x40});
protocolBuffer.appendData(twoRawPackets);
boolean hasMoreData = protocolBuffer.hasMoreCommands();
assertTrue(hasMoreData);
byte[] command1 = protocolBuffer.nextBinaryCommand();
Assert.assertArrayEquals(command1, new byte[]{0x21, 0x3b, 0x20, 0x40});
hasMoreData = protocolBuffer.hasMoreCommands();
assertTrue(hasMoreData);
byte[] command2 = protocolBuffer.nextBinaryCommand();
Assert.assertArrayEquals(command2, new byte[]{0x4a, 0x20, 0x40});
command2 = protocolBuffer.nextBinaryCommand();
assertNull(command2);
}
@Test
public void testSplitRawPacket(){
protocolBuffer = new ProtocolBuffer(modeBinary);
protocolBuffer.setDelimiter(new byte[]{0x20, 0x40});
protocolBuffer.appendData(splitRawPacket);
boolean hasMoreData = protocolBuffer.hasMoreCommands();
assertTrue(hasMoreData);
byte[] command1 = protocolBuffer.nextBinaryCommand();
Assert.assertArrayEquals(command1, new byte[]{0x21, 0x3b, 0x20, 0x40});
hasMoreData = protocolBuffer.hasMoreCommands();
assertFalse(hasMoreData);
}
@Test
public void testVerySplitRawPacket(){
protocolBuffer = new ProtocolBuffer(modeBinary);
protocolBuffer.setDelimiter(new byte[]{0x20, 0x40});
protocolBuffer.appendData(verySplitRawPacket[0]);
boolean hasMoreData = protocolBuffer.hasMoreCommands();
assertFalse(hasMoreData);
protocolBuffer.appendData(verySplitRawPacket[1]);
hasMoreData = protocolBuffer.hasMoreCommands();
assertFalse(hasMoreData);
protocolBuffer.appendData(verySplitRawPacket[2]);
hasMoreData = protocolBuffer.hasMoreCommands();
assertFalse(hasMoreData);
protocolBuffer.appendData(verySplitRawPacket[3]);
hasMoreData = protocolBuffer.hasMoreCommands();
assertTrue(hasMoreData);
byte[] command = protocolBuffer.nextBinaryCommand();
Assert.assertArrayEquals(command, new byte[]{0x21, 0x3b, 0x20, 0x40});
}
}

Wyświetl plik

@ -13,7 +13,7 @@ public class SerialBuffer
private byte[] readBufferCompatible; // Read buffer for android < 4.2
private boolean debugging = false;
SerialBuffer(boolean version)
public SerialBuffer(boolean version)
{
writeBuffer = new SynchronizedBuffer();
if(version)
@ -34,7 +34,7 @@ public class SerialBuffer
debugging = value;
}
ByteBuffer getReadBuffer()
public ByteBuffer getReadBuffer()
{
synchronized(this)
{
@ -43,7 +43,7 @@ public class SerialBuffer
}
byte[] getDataReceived()
public byte[] getDataReceived()
{
synchronized(this)
{
@ -56,7 +56,7 @@ public class SerialBuffer
}
}
void clearReadBuffer()
public void clearReadBuffer()
{
synchronized(this)
{
@ -64,23 +64,23 @@ public class SerialBuffer
}
}
byte[] getWriteBuffer()
public byte[] getWriteBuffer()
{
return writeBuffer.get();
}
void putWriteBuffer(byte[]data)
public void putWriteBuffer(byte[]data)
{
writeBuffer.put(data);
}
byte[] getBufferCompatible()
public byte[] getBufferCompatible()
{
return readBufferCompatible;
}
byte[] getDataReceivedCompatible(int numberBytes)
public byte[] getDataReceivedCompatible(int numberBytes)
{
return Arrays.copyOfRange(readBufferCompatible, 0, numberBytes);
}
@ -107,7 +107,7 @@ public class SerialBuffer
synchronized byte[] get()
{
if(buffer.size() > 0)
if(buffer.size() == 0)
{
try
{

Wyświetl plik

@ -0,0 +1,153 @@
package com.felhr.utils;
import com.annimon.stream.IntStream;
import com.annimon.stream.function.IntPredicate;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ProtocolBuffer {
public static final String BINARY = "binary";
public static final String TEXT = "text";
private String mode;
private static final int DEFAULT_BUFFER_SIZE = 16 * 1024;
private byte[] rawBuffer;
private int bufferPointer = 0;
private byte[] separator;
private String delimiter;
private StringBuilder stringBuffer;
private List<String> commands = new ArrayList<>();
private List<byte[]> rawCommands = new ArrayList<>();
public ProtocolBuffer(String mode){
this.mode = mode;
if(mode.equals(BINARY)){
rawBuffer = new byte[DEFAULT_BUFFER_SIZE];
}else{
stringBuffer = new StringBuilder(DEFAULT_BUFFER_SIZE);
}
}
public ProtocolBuffer(String mode, int bufferSize){
this.mode = mode;
if(mode.equals(BINARY)){
rawBuffer = new byte[bufferSize];
}else{
stringBuffer = new StringBuilder(bufferSize);
}
}
public void setDelimiter(String delimiter){
this.delimiter = delimiter;
}
public void setDelimiter(byte[] delimiter){
this.separator = delimiter;
}
public void appendData(byte[] data){
if(mode.equals(TEXT)){
try {
String dataStr = new String(data, "UTF-8");
stringBuffer.append(dataStr);
String buffer = stringBuffer.toString();
int prevIndex = 0;
int index = buffer.indexOf(delimiter);
while (index >= 0) {
String tempStr = buffer.substring(prevIndex, index + delimiter.length());
commands.add(tempStr);
prevIndex = index + delimiter.length();
index = stringBuffer.toString().indexOf(delimiter, prevIndex);
}
if(prevIndex < buffer.length()
&& prevIndex > 0){
String tempStr = buffer.substring(prevIndex, buffer.length());
stringBuffer.setLength(0);
stringBuffer.append(tempStr);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}else if(mode.equals(BINARY)){
appendRawData(data);
}
}
public boolean hasMoreCommands(){
if(mode.equals(TEXT)) {
return commands.size() > 0;
}else {
return rawCommands.size() > 0;
}
}
public String nextTextCommand(){
if(commands.size() > 0){
return commands.remove(0);
}else{
return null;
}
}
public byte[] nextBinaryCommand(){
if(rawCommands.size() > 0){
return rawCommands.remove(0);
}else{
return null;
}
}
private void appendRawData(byte[] rawData){
System.arraycopy(rawData, 0, rawBuffer, bufferPointer, rawData.length);
bufferPointer += rawData.length;
SeparatorPredicate predicate = new SeparatorPredicate();
int[] indexes =
IntStream.range(0, bufferPointer)
.filter(predicate)
.toArray();
int prevIndex = 0;
for(Integer i : indexes){
byte[] command = Arrays.copyOfRange(rawBuffer, prevIndex, i + separator.length);
rawCommands.add(command);
prevIndex = i + separator.length;
}
if(prevIndex < rawBuffer.length
&& prevIndex > 0){
byte[] tempBuffer = Arrays.copyOfRange(rawBuffer, prevIndex, rawBuffer.length);
bufferPointer = 0;
System.arraycopy(tempBuffer, 0, rawBuffer, bufferPointer, rawData.length);
bufferPointer += rawData.length;
}
}
private class SeparatorPredicate implements IntPredicate{
@Override
public boolean test(int value) {
if(rawBuffer[value] == separator[0]){
for(int i=1;i<=separator.length-1;i++){
if(rawBuffer[value + i] != separator[i]){
return false;
}
}
return true;
}
return false;
}
}
}