From 2ee571c34722083f90c52040d3214e8a602f1f04 Mon Sep 17 00:00:00 2001 From: hama Date: Wed, 13 Jul 2016 23:25:11 +0200 Subject: [PATCH] GPIO settings can handle output (blinking) --- src/main/java/de/republib/net/TcpClient.java | 41 +- src/main/java/de/republib/pinet/Client.java | 9 +- .../java/de/republib/pinet/PinNumber.java | 4 +- .../de/republib/pinet/gui/ControlCenter.java | 69 +++- .../de/republib/pinet/gui/GPIOSettings.java | 362 ++++++++++++++++++ src/main/java/de/republib/util/Announcer.java | 17 + src/main/java/de/republib/util/DynBytes.java | 66 +++- .../java/de/republib/util/DynBytesTest.java | 41 ++ 8 files changed, 589 insertions(+), 20 deletions(-) create mode 100644 src/main/java/de/republib/pinet/gui/GPIOSettings.java create mode 100644 src/main/java/de/republib/util/Announcer.java diff --git a/src/main/java/de/republib/net/TcpClient.java b/src/main/java/de/republib/net/TcpClient.java index 7056797..2e072ce 100644 --- a/src/main/java/de/republib/net/TcpClient.java +++ b/src/main/java/de/republib/net/TcpClient.java @@ -16,13 +16,13 @@ import de.republib.util.DynBytes; * */ public class TcpClient { - Logger logger = LoggerFactory.getLogger(TcpClient.class); - Socket socket = null; - DataOutputStream outStream = null; - DataInputStream inStream = null; - String host = "127.0.0.1"; - int port; - boolean active; + private final Logger logger = LoggerFactory.getLogger(TcpClient.class); + private Socket socket = null; + private DataOutputStream outStream = null; + private DataInputStream inStream = null; + private String host = "127.0.0.1"; + private final int port; + private boolean active; /** * Constructor. @@ -49,6 +49,20 @@ public class TcpClient { } } + /** + * @return the host + */ + public String getHost() { + return this.host; + } + + /** + * @return the port + */ + public int getPort() { + return this.port; + } + /** * Receives a message. * @@ -71,6 +85,19 @@ public class TcpClient { return buffer; } + /** + * Tests whether the address is the same as a given address. + * + * @param host + * hostname of the address to compare + * @param port + * port of the address to compare + * @return + */ + public boolean sameAddress(String host, int port) { + return host.equals(this.host) && port == this.port; + } + /** * * @param buffer diff --git a/src/main/java/de/republib/pinet/Client.java b/src/main/java/de/republib/pinet/Client.java index 0dbfea7..2586eb4 100644 --- a/src/main/java/de/republib/pinet/Client.java +++ b/src/main/java/de/republib/pinet/Client.java @@ -16,9 +16,12 @@ public class Client { client.blink(PinNumber.PIN_RPi2_12, 10, 500, 500); } - public static void gui() { + /** + * Starts the graphical user interface client. + */ + public static void gui(String host, int port) { final ControlCenter center = new ControlCenter(); - center.populate(); + center.populate(host, port); center.run(); } @@ -40,7 +43,7 @@ public class Client { port = Integer.parseInt(arg); } } - Client.gui(); + Client.gui(host, port); // Client.client(host, port); } } diff --git a/src/main/java/de/republib/pinet/PinNumber.java b/src/main/java/de/republib/pinet/PinNumber.java index 09b2260..bbd7ddc 100644 --- a/src/main/java/de/republib/pinet/PinNumber.java +++ b/src/main/java/de/republib/pinet/PinNumber.java @@ -5,7 +5,7 @@ package de.republib.pinet; /** * Pins of the SystemOnChip BM2835 (used in raspberry pi). - * + * * @author hm * */ @@ -27,6 +27,8 @@ public enum PinNumber { PIN_RPi2_23("RPi2_23", 11), // PIN_RPi2_24("RPi2_24", 8), // PIN_RPi2_26("RPi2_26", 7), // + PIN_RPi2_27("RPi2_27", -1), // + PIN_RPi2_28("RPi2_28", -1), // PIN_RPi2_29("RPi2_29", 5), // PIN_RPi2_31("RPi2_31", 6), // PIN_RPi2_32("RPi2_32", 12), // diff --git a/src/main/java/de/republib/pinet/gui/ControlCenter.java b/src/main/java/de/republib/pinet/gui/ControlCenter.java index 61f7692..df3949e 100644 --- a/src/main/java/de/republib/pinet/gui/ControlCenter.java +++ b/src/main/java/de/republib/pinet/gui/ControlCenter.java @@ -12,6 +12,8 @@ import javax.swing.JTabbedPane; import javax.swing.JTextField; import de.republib.gui.MultiChannelSheet; +import de.republib.pinet.GpioClient; +import de.republib.util.Announcer; import de.republib.util.FunctionPairData; import de.republib.util.I18N; import de.republib.util.MathFunction; @@ -19,10 +21,12 @@ import de.republib.util.MathFunction; /** * Created by hm on 03.07.16. */ -public class ControlCenter { +public class ControlCenter implements Announcer { + private GpioClient client = null; private JFrame frame; + private JPanel panelCenter; - private JPanel panelOutput; + private GPIOSettings panelGPIOSettings; private JPanel panelLog; private JLabel labelStatusLine; private MultiChannelSheet panelData; @@ -31,7 +35,28 @@ public class ControlCenter { private JTextField textFieldPort; private JTabbedPane tabbedPane; - public void populate() { + /** + * Constructor. + */ + public ControlCenter() { + + } + + /** + * @return the client + */ + public GpioClient getClient() { + final String host = this.textFieldServer.getText(); + final String port = this.textFieldPort.getText(); + final int port2 = port.length() == 0 ? 15000 : Integer.parseInt(port); + if (this.client == null || !this.client.sameAddress(host, port2)) { + this.client = new GpioClient(host, port2); + } + + return this.client; + } + + public void populate(String host, int port) { this.frame = new JFrame(I18N.tr("Pinet Control Center")); this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); @@ -43,13 +68,19 @@ public class ControlCenter { this.frame.add(this.labelStatusLine = new JLabel(I18N.tr("welcome")), BorderLayout.SOUTH); this.panelHead.add(new JLabel(I18N.tr("Server:"))); - this.panelHead.add(this.textFieldServer = new JTextField("localhost")); + this.panelHead.add(this.textFieldServer = new JTextField(host)); this.panelHead.add(new JLabel(I18N.tr("Port:"))); - this.panelHead.add(this.textFieldPort = new JTextField("15000")); + this.panelHead.add(this.textFieldPort = new JTextField(String.valueOf(port))); this.panelCenter.add(this.tabbedPane = new JTabbedPane()); - this.tabbedPane.addTab(I18N.tr("Output"), this.panelOutput = new JPanel()); + this.tabbedPane.addTab(I18N.tr("GPIO settings"), this.panelGPIOSettings = new GPIOSettings(this)); + this.panelGPIOSettings.populate(); this.tabbedPane.addTab(I18N.tr("Diagram"), this.panelData = new MultiChannelSheet()); + populateCurves(); + this.tabbedPane.addTab(I18N.tr("Log"), this.panelLog = new JPanel()); + } + + private void populateCurves() { FunctionPairData function = new FunctionPairData(MathFunction.X, 0.0, 10.0, 790); function.setFactor(9.0); function.setOffset(1.0); @@ -70,7 +101,7 @@ public class ControlCenter { this.panelData.addChannel(function); function = new FunctionPairData(MathFunction.TAN, 0.0, 1.0, 790); this.panelData.addChannel(function); - this.tabbedPane.addTab(I18N.tr("Log"), this.panelLog = new JPanel()); + } public void run() { @@ -78,4 +109,28 @@ public class ControlCenter { this.frame.pack(); this.frame.setVisible(true); } + + /* + * (non-Javadoc) + * + * @see de.republib.util.Announcer#say(int, java.lang.String) + */ + @Override + public void say(int level, final String message) { + String prefix = null; + switch (level) { + case Announcer.ERROR: + prefix = "+++ "; + break; + case Announcer.WARNING: + prefix = "*** "; + break; + default: + } + if (prefix == null) { + this.labelStatusLine.setText(message); + } else { + this.labelStatusLine.setText(prefix + message); + } + } } diff --git a/src/main/java/de/republib/pinet/gui/GPIOSettings.java b/src/main/java/de/republib/pinet/gui/GPIOSettings.java new file mode 100644 index 0000000..812fd18 --- /dev/null +++ b/src/main/java/de/republib/pinet/gui/GPIOSettings.java @@ -0,0 +1,362 @@ +/** + * + */ +package de.republib.pinet.gui; + +import java.awt.Component; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; + +import de.republib.pinet.GpioClient; +import de.republib.pinet.PinNumber; +import de.republib.util.Announcer; +import de.republib.util.DynBytes; +import de.republib.util.I18N; + +/** + * Manages the register page "GPIO Settings". + * + * @author hm + * + */ +public class GPIOSettings extends JPanel { + /** + * + */ + private static final long serialVersionUID = 1L; + private GPIOTable gpioTable; + private OutputData panelOutputData; + private final ControlCenter center; + + /** + * + * @param center + * @return + */ + public GPIOSettings(ControlCenter center) { + this.center = center; + } + + public void populate() { + + this.gpioTable = new GPIOTable(); + add(this.gpioTable); + final PinData panelPinData = new PinData(this.gpioTable); + this.gpioTable.setPanelPinData(panelPinData); + add(panelPinData); + add(this.panelOutputData = new OutputData(this.center, panelPinData)); + } +} + +class GPIOTable extends JPanel implements ActionListener { + /** + * + */ + private static final long serialVersionUID = 1L; + + private final PinButton[] pinButtons = new PinButton[40]; + + private final JLabel[] columnNames = { new JLabel(I18N.tr("Name")), new JLabel(I18N.tr("Pin")), + new JLabel(I18N.tr("Pin")), new JLabel(I18N.tr("Name")) }; + + private final Object[][] cells; + PinData panelPinData; + + /** + * Constructor. + */ + public GPIOTable() { + super(new GridLayout(21, 4)); + this.panelPinData = this.panelPinData; + this.pinButtons[0] = new PinButton(0, I18N.tr("+3.3V"), null); + this.pinButtons[1] = new PinButton(1, I18N.tr("+5V"), null); + this.pinButtons[2] = new PinButton(2, "SDA1", PinNumber.PIN_RPi2_03); + this.pinButtons[3] = new PinButton(3, I18N.tr("+5V"), null); + this.pinButtons[4] = new PinButton(4, "SCL1", PinNumber.PIN_RPi2_05); + this.pinButtons[5] = new PinButton(5, I18N.tr("GND"), null); + this.pinButtons[6] = new PinButton(6, "GCLK", PinNumber.PIN_RPi2_07); + this.pinButtons[7] = new PinButton(7, "TXD0", PinNumber.PIN_RPi2_08); + this.pinButtons[8] = new PinButton(8, I18N.tr("GND"), null); + this.pinButtons[9] = new PinButton(9, "RXD0", PinNumber.PIN_RPi2_10); + this.pinButtons[10] = new PinButton(10, "GEN0", PinNumber.PIN_RPi2_11); + this.pinButtons[11] = new PinButton(11, "GEN1", PinNumber.PIN_RPi2_12); + this.pinButtons[12] = new PinButton(12, "GEN2", PinNumber.PIN_RPi2_13); + this.pinButtons[13] = new PinButton(13, I18N.tr("GND"), null); + this.pinButtons[14] = new PinButton(14, "GEN3", PinNumber.PIN_RPi2_15); + this.pinButtons[15] = new PinButton(15, "GEN4", PinNumber.PIN_RPi2_16); + this.pinButtons[16] = new PinButton(16, I18N.tr("+3.3V"), null); + this.pinButtons[17] = new PinButton(17, "GEN5", PinNumber.PIN_RPi2_18); + this.pinButtons[18] = new PinButton(18, "SPI_MOSI", PinNumber.PIN_RPi2_19); + this.pinButtons[19] = new PinButton(19, I18N.tr("GND"), null); + this.pinButtons[20] = new PinButton(20, "SPI_MISO", PinNumber.PIN_RPi2_21); + this.pinButtons[21] = new PinButton(21, "GEN6", PinNumber.PIN_RPi2_22); + this.pinButtons[22] = new PinButton(22, "SPI_SCLK", PinNumber.PIN_RPi2_23); + this.pinButtons[23] = new PinButton(23, "SPI_CE0", PinNumber.PIN_RPi2_24); + this.pinButtons[24] = new PinButton(24, I18N.tr("GND"), null); + this.pinButtons[25] = new PinButton(25, "SPI_CE1", PinNumber.PIN_RPi2_26); + this.pinButtons[26] = new PinButton(26, "I2C_ID_SC", PinNumber.PIN_RPi2_27); + this.pinButtons[27] = new PinButton(27, "I2C_ID_SD", PinNumber.PIN_RPi2_28); + this.pinButtons[28] = new PinButton(28, null, PinNumber.PIN_RPi2_29); + this.pinButtons[29] = new PinButton(29, I18N.tr("GND"), null); + this.pinButtons[30] = new PinButton(30, null, PinNumber.PIN_RPi2_31); + this.pinButtons[31] = new PinButton(31, null, PinNumber.PIN_RPi2_32); + this.pinButtons[32] = new PinButton(32, null, PinNumber.PIN_RPi2_33); + this.pinButtons[33] = new PinButton(33, I18N.tr("GND"), null); + this.pinButtons[34] = new PinButton(34, null, PinNumber.PIN_RPi2_35); + this.pinButtons[35] = new PinButton(35, null, PinNumber.PIN_RPi2_36); + this.pinButtons[36] = new PinButton(36, null, PinNumber.PIN_RPi2_37); + this.pinButtons[37] = new PinButton(37, null, PinNumber.PIN_RPi2_38); + this.pinButtons[38] = new PinButton(38, I18N.tr("GND"), null); + this.pinButtons[39] = new PinButton(39, null, PinNumber.PIN_RPi2_40); + for (final PinButton pinButton : this.pinButtons) { + pinButton.addActionListener(this); + } + + this.cells = new Object[20][4]; + for (int row = 0; row < 20; row++) { + PinButton button = this.pinButtons[row * 2]; + this.cells[row][0] = new JLabel(button.getTitle()); + this.cells[row][1] = button; + button = this.pinButtons[row * 2 + 1]; + this.cells[row][2] = button; + this.cells[row][3] = new JLabel(button.getTitle()); + } + populate(); + } + + @Override + public void actionPerformed(ActionEvent e) { + final PinButton button = (PinButton) e.getSource(); + this.panelPinData.fillData(button); + } + + public Component getCell(int row, int column) { + final Component rc = (Component) this.cells[row][column]; + return rc; + } + + /** + * @return the pinButtons + */ + public PinButton getPinButton(int index) { + return this.pinButtons[index]; + } + + public void populate() { + int col; + for (col = 0; col < 4; col++) { + add(this.columnNames[col]); + } + for (int row = 0; row < 20; row++) { + for (col = 0; col < 4; col++) { + add((Component) this.cells[row][col]); + } + } + } + + /** + * @param panelPinData + * the panelPinData to set + */ + public void setPanelPinData(PinData panelPinData) { + this.panelPinData = panelPinData; + } +} + +/** + * Shows and manages the panel controlling the output behaviour of a pin. + * + * @author hm + * + */ +class OutputData extends JPanel implements ActionListener { + /** + * + */ + private static final long serialVersionUID = 1L; + + private final static String[] modes = { I18N.tr("Blink") }; + private JComboBox comboMode; + private JTextField textCount; + private JTextField textHigh; + private JTextField textLow; + private JButton buttonRun; + private final ControlCenter center; + private final PinData pinData; + + /** + * Constructor. + */ + public OutputData(ControlCenter center, PinData pinData) { + super(new GridLayout(0, 2)); + this.center = center; + this.pinData = pinData; + add(new JLabel(I18N.tr("Mode:"))); + add(this.comboMode = new JComboBox<>(OutputData.modes)); + add(new JLabel(I18N.tr("Count:"))); + add(this.textCount = new JTextField("10")); + add(new JLabel(I18N.tr("High:"))); + add(this.textHigh = new JTextField("500")); + add(new JLabel(I18N.tr("Low:"))); + add(this.textLow = new JTextField("500")); + add(new JLabel("")); + add(this.buttonRun = new JButton(I18N.tr("Start"))); + this.buttonRun.addActionListener(this); + } + + @Override + public void actionPerformed(ActionEvent e) { + final GpioClient client = this.center.getClient(); + final PinButton current = this.pinData.getCurrentPin(); + final int count = numberOf(this.textCount, 10); + final int high = numberOf(this.textHigh, 500); + final int low = numberOf(this.textLow, 500); + this.center.say(Announcer.LOG, String.format(I18N.tr("blinking started on pin %d"), current.getPinNumber())); + final DynBytes answer = client.blink(current.getPinNumber(), count, high, low); + if (answer.startsWith("OK")) { + this.center.say(Announcer.LOG, + String.format(I18N.tr("pin %d blinks %d times"), current.getPinNumber(), count)); + } + } + + /** + * Gets a number from a text field. + * + * @param text + * the text field + * @param defaultValue + * the return value for invalid field values + * @return defaultValue: invalid field value
+ * otherwise: the value of the field as integer + */ + private int numberOf(JTextField text, int defaultValue) { + int rc = defaultValue; + try { + rc = Integer.parseInt(text.getText()); + } catch (final NumberFormatException e) { + this.center.say(Announcer.ERROR, + String.format(I18N.tr("not a number: '%s' used instead: %d"), text.getText(), rc)); + text.setText(String.valueOf(rc)); + } + return rc; + } +} + +class PinButton extends JButton { + /** + * + */ + private static final long serialVersionUID = 1L; + private final PinNumber pinNumber; + private final String title; + + int index; + + /** + * Constructor. + * + * @param title + * null: the title is generated from the + * pinNumber
+ * otherwise: the title of the pin + * @param pinNumber + * null: not a IO pin, e.g. ground or +3.3V
+ * otherwise: the pin number + */ + public PinButton(int index, String title, PinNumber pinNumber) { + super(pinNumber == null ? title : String.valueOf(index + 1)); + this.index = index; + this.title = title == null ? pinNumber.getName() : title; + this.pinNumber = pinNumber; + } + + /** + * @return the index + */ + public int getIndex() { + return this.index; + } + + /** + * @return the pinNumber + */ + public PinNumber getPinNumber() { + return this.pinNumber; + } + + /** + * @return the title + */ + public String getTitle() { + return this.title; + } +} + +/** + * Shows and manages the data of the current pin in a panel. + * + * @author hm + * + */ +class PinData extends JPanel { + /** + * + */ + private static final long serialVersionUID = 1L; + private JLabel labelPin; + private JLabel labelInternalNo; + private JLabel labelTitle; + private JComboBox comboMode; + private final String[] modes = { I18N.tr("undefined"), I18N.tr("input"), I18N.tr("output") }; + private PinButton currentPin = null; + + /** + * Constructor. + * + * @param table + * info about the pins + */ + public PinData(GPIOTable table) { + super(new GridLayout(0, 2)); + add(new JLabel(I18N.tr("Pin No:"))); + add(this.labelPin = new JLabel()); + add(new JLabel(I18N.tr("GPIO number:"))); + add(this.labelInternalNo = new JLabel()); + add(new JLabel(I18N.tr("Title:"))); + add(this.labelTitle = new JLabel()); + add(new JLabel(I18N.tr("Mode:"))); + add(this.comboMode = new JComboBox<>(this.modes)); + add(new JLabel()); + fillData(table.getPinButton(11)); + } + + /** + * Fills the data of the panel from the current pin. + * + * @param button + * properties of the pin + */ + public void fillData(PinButton button) { + this.currentPin = button; + final PinNumber number = button.getPinNumber(); + this.labelPin.setText(String.valueOf(button.getIndex() + 1)); + this.labelInternalNo.setText(number == null ? "-" : String.valueOf(number.getNumber())); + this.labelTitle.setText(button.getTitle()); + this.comboMode.setVisible(number != null); + this.comboMode.setSelectedIndex(0); + } + + /** + * @return the currentPin + */ + public PinButton getCurrentPin() { + return this.currentPin; + } +} \ No newline at end of file diff --git a/src/main/java/de/republib/util/Announcer.java b/src/main/java/de/republib/util/Announcer.java new file mode 100644 index 0000000..8993314 --- /dev/null +++ b/src/main/java/de/republib/util/Announcer.java @@ -0,0 +1,17 @@ +/** + * + */ +package de.republib.util; + +/** + * @author hm + * + */ +public interface Announcer { + final int ERROR = 1; + final int WARNING = 2; + final int LOG = 3; + final int DEBUG = 4; + + void say(int level, String message); +} diff --git a/src/main/java/de/republib/util/DynBytes.java b/src/main/java/de/republib/util/DynBytes.java index d01cfaa..eb3edcd 100644 --- a/src/main/java/de/republib/util/DynBytes.java +++ b/src/main/java/de/republib/util/DynBytes.java @@ -195,6 +195,45 @@ public class DynBytes { return this; } + /** + * Compares the instance with a given byte sequence. + * + * @param value + * value to compare + * @param from + * first index of valueto compare.
+ * Set to 0 if < 0 + * @param from2 + * first index of this.bufferto compare.
+ * Set to 0 if < 0 + * @param length + * number of bytes to compare + * @return < 0: value < instance
+ * 0: value == instance
+ * > 0: value > instance
+ */ + public int compare(byte[] value, int from, int from2, int length) { + int rc = 0; + if (from < 0) { + from = 0; + } + if (from2 < 0) { + from2 = 0; + } + final int maxLength = Math.max(value.length - from, this.length - from2); + if (length > maxLength) { + length = maxLength; + } + while (rc == 0 && length > 0 && from < value.length && from2 < this.length) { + rc = this.buffer[from2++] - value[from++]; + length--; + } + if (rc == 0 && length != 0) { + rc = from < value.length ? -1 : from2 < this.length ? 1 : -1; + } + return rc; + } + /** * Ensures that the size of the buffer is larger or equal to a given size. *

@@ -361,10 +400,29 @@ public class DynBytes { return this; } + /** + * Tests whether a buffer starts with a given string. + * + * @param prefix + * string to test + * @return true: the instance starts with the given string + */ + public boolean startsWith(String prefix) { + byte[] value; + boolean rc = false; + try { + value = prefix.getBytes("UTF-8"); + rc = compare(value, 0, 0, value.length) == 0; + } catch (final UnsupportedEncodingException e) { + DynBytes.logger.error("cannot convert from UTF-8", e); + } + return rc; + } + /** * Converts the content into an UTF-8 string. * - * @return null: not convertable
+ * @return null: not convertible
* otherwise: the content as UTF-8 string */ public String toUtf8() { @@ -392,7 +450,11 @@ public class DynBytes { } else { try { final int length = Math.min(this.length, maxLength); - rc = new String(this.buffer, 0, length, "UTF-8"); + if (length <= 0) { + rc = ""; + } else { + rc = new String(this.buffer, 0, length, "UTF-8"); + } } catch (final UnsupportedEncodingException e) { DynBytes.logger.error("DynBytes.toUtf8(): ", e); } diff --git a/src/test/java/de/republib/util/DynBytesTest.java b/src/test/java/de/republib/util/DynBytesTest.java index 4e6e3f8..e0dadd0 100644 --- a/src/test/java/de/republib/util/DynBytesTest.java +++ b/src/test/java/de/republib/util/DynBytesTest.java @@ -89,6 +89,47 @@ public class DynBytesTest { Assert.assertEquals(buffer.getBlocksize(), 17); } + @org.testng.annotations.Test + public void testCompare() throws Exception { + final DynBytes buffer = new DynBytes(16, 16); + buffer.append((byte) 0x41).append((byte) 0x31).append((byte) 0x61); + final byte[] buffer2 = { 0x41, 0x31, 0x61 }; + // buffer == buffer2 + Assert.assertEquals(buffer.compare(buffer2, 0, 0, 1), 0); + Assert.assertEquals(buffer.compare(buffer2, 0, 0, 2), 0); + Assert.assertEquals(buffer.compare(buffer2, 0, 0, 3), 0); + Assert.assertEquals(buffer.compare(buffer2, 0, 0, 4), 0); + // buffer < buffer2 + Assert.assertEquals(buffer.compare(buffer2, 0, 1, 1), -0x10); + Assert.assertEquals(buffer.compare(buffer2, 0, 1, 2), -0x10); + // buffer > buffer2 + Assert.assertEquals(buffer.compare(buffer2, 1, 0, 1), 0x10); + Assert.assertEquals(buffer.compare(buffer2, 1, 0, 2), 0x10); + // different length: + final byte[] buffer3 = { 0x41, 0x31 }; + // buffer > buffer3 + Assert.assertEquals(buffer.compare(buffer3, 0, 0, 4), 1); + Assert.assertEquals(buffer.compare(buffer3, 1, 1, 4), 1); + final byte[] buffer4 = { 0x41, 0x31, 0x61, 0x62 }; + // buffer < buffer4 + Assert.assertEquals(buffer.compare(buffer4, 0, 0, 4), -1); + Assert.assertEquals(buffer.compare(buffer4, 1, 1, 4), -1); + Assert.assertEquals(buffer.compare(buffer4, 2, 2, 4), -1); + + // wrong indexes: + // too large in value: + Assert.assertEquals(buffer.compare(buffer2, 3, 0, 2), -1); + // too large in buffer: + Assert.assertEquals(buffer.compare(buffer2, 0, 4, 2), 1); + // both too large: + Assert.assertEquals(buffer.compare(buffer2, 3, 4, 2), 0); + + // to small in value: + Assert.assertEquals(buffer.compare(buffer2, -1, 0, 2), -1); + // too small in buffer: + Assert.assertEquals(buffer.compare(buffer2, 4, -1, 2), 1); + } + @org.testng.annotations.Test public void testEnsureSize() throws Exception { final DynBytes buffer = new DynBytes(2, 2); -- 2.39.5