package io.sloeber.ui.monitor.internal; import java.nio.BufferOverflowException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.swt.widgets.Display; import io.sloeber.core.api.MessageConsumer; import io.sloeber.ui.Activator; import io.sloeber.ui.monitor.views.Messages; import io.sloeber.ui.monitor.views.SerialMonitor; public class SerialListener implements MessageConsumer { private static boolean myPlotterFilterFlag = false; SerialMonitor theMonitor; int theColorIndex; private ByteBuffer myReceivedPlotterData = ByteBuffer.allocate(2000); public SerialListener(SerialMonitor monitor, int colorIndex) { this.theMonitor = monitor; this.theColorIndex = colorIndex; this.myReceivedPlotterData.order(ByteOrder.LITTLE_ENDIAN); } public int removeBytesFromStart(int n) { if (n == 0) { return this.myReceivedPlotterData.position(); } int index = 0; for (int i = 0; i < n; i++) this.myReceivedPlotterData.put(i, (byte) 0); for (int i = n; i < this.myReceivedPlotterData.position(); i++) { this.myReceivedPlotterData.put(index++, this.myReceivedPlotterData.get(i)); this.myReceivedPlotterData.put(i, (byte) 0); } return this.myReceivedPlotterData.position(index).position(); } @Override public void message(byte[] newData) { if (myPlotterFilterFlag) { // filter plotter data try { this.myReceivedPlotterData.put(newData); } catch (BufferOverflowException e) { this.myReceivedPlotterData.clear(); Activator.log(new Status(IStatus.WARNING, Activator.getId(), Messages.serialListenerPlotterSkippingData)); } internalExtractAndRemovePlotterData(); } else { // treat data just like a event if (newData[newData.length - 1] == '\r') { newData[newData.length - 1] = ' '; } event(new String(newData)); } } private void internalExtractAndRemovePlotterData() { String monitorMessage = ""; //$NON-NLS-1$ boolean doneSearching = false; int length = this.myReceivedPlotterData.position(); int searchPointer; for (searchPointer = 0; (searchPointer < length - 1) && !doneSearching; searchPointer++) { if (this.myReceivedPlotterData.getShort(searchPointer) != Activator.PLOTTER_START_DATA) { char addChar = (char) this.myReceivedPlotterData.get(searchPointer); monitorMessage += Character.toString(addChar); } else { // have we received the full header of the plotter data? if (length < (searchPointer + 6)) { if (searchPointer != 0) { length = removeBytesFromStart(searchPointer); } doneSearching = true; // System.out.println("case 1"); //$NON-NLS-1$ } else { int bytestoRead = this.myReceivedPlotterData.getShort(2); if ((bytestoRead < 0) || (bytestoRead > (10 * 2))) { Activator.log( new Status(IStatus.WARNING, Activator.getId(), Messages.serialListenerErrorInputPart1 + bytestoRead / 2 + Messages.serialListenerErrorInputPart2)); searchPointer += 4;// skip the plotter start and length // so // data is shown // System.out.println("case 2"); //$NON-NLS-1$ } else { if ((searchPointer + (bytestoRead + 4)) < length) { searchPointer += (bytestoRead + 4) - 1; // just skip // the // data // System.out.println("case 3"); //$NON-NLS-1$ } else // not all data arrived for the latest data set { if (searchPointer != 0) { length = removeBytesFromStart(searchPointer); } doneSearching = true; // System.out.println("case 4"); //$NON-NLS-1$ } } } } } if (!doneSearching) { if (searchPointer == length - 1) { byte addChar = this.myReceivedPlotterData.get(searchPointer); if (addChar != (byte) (Activator.PLOTTER_START_DATA)) { if (addChar == '\r') { addChar = ' '; } searchPointer++; monitorMessage += Character.toString((char) addChar); } } removeBytesFromStart(searchPointer); } event(monitorMessage); } @Override public void dispose() { // No need to dispose something } @Override public void event(String event) { final String tempString = new String(event); Display.getDefault().asyncExec(new Runnable() { @Override public void run() { try { SerialListener.this.theMonitor.ReportSerialActivity(tempString, SerialListener.this.theColorIndex); } catch (Exception e) {// ignore as we get errors when closing // down } } }); } public static void setPlotterFilter(boolean selection) { myPlotterFilterFlag = selection; } }