diff --git a/clients/java-client-lib/client-command-builders/src/test/java/net/zscript/model/modules/testing/test/JavaCommandBuilderBuildTest.java b/clients/java-client-lib/client-command-builders/src/test/java/net/zscript/model/modules/testing/test/JavaCommandBuilderBuildTest.java
index 8cf4b37ea..478fb042b 100644
--- a/clients/java-client-lib/client-command-builders/src/test/java/net/zscript/model/modules/testing/test/JavaCommandBuilderBuildTest.java
+++ b/clients/java-client-lib/client-command-builders/src/test/java/net/zscript/model/modules/testing/test/JavaCommandBuilderBuildTest.java
@@ -1,6 +1,5 @@
package net.zscript.model.modules.testing.test;
-import java.nio.charset.StandardCharsets;
import java.util.EnumSet;
import java.util.Optional;
import java.util.OptionalInt;
@@ -20,9 +19,9 @@
import net.zscript.client.modules.test.testing.TestingModule;
import net.zscript.client.modules.test.testing.TestingModule.TestCommand0Command.Builder.BitsetReqTestE;
-import net.zscript.javaclient.commandbuilder.commandnodes.ZscriptCommandBuilder;
import net.zscript.javaclient.commandbuilder.ZscriptFieldOutOfRangeException;
import net.zscript.javaclient.commandbuilder.ZscriptMissingFieldException;
+import net.zscript.javaclient.commandbuilder.commandnodes.ZscriptCommandBuilder;
public class JavaCommandBuilderBuildTest {
@Test
diff --git a/clients/java-client-lib/client-command-builders/src/test/java/net/zscript/model/modules/testing/test/JavaCommandBuilderResponseTest.java b/clients/java-client-lib/client-command-builders/src/test/java/net/zscript/model/modules/testing/test/JavaCommandBuilderResponseTest.java
index bf4946231..d1a252601 100644
--- a/clients/java-client-lib/client-command-builders/src/test/java/net/zscript/model/modules/testing/test/JavaCommandBuilderResponseTest.java
+++ b/clients/java-client-lib/client-command-builders/src/test/java/net/zscript/model/modules/testing/test/JavaCommandBuilderResponseTest.java
@@ -18,13 +18,13 @@
import net.zscript.javaclient.commandbuilder.commandnodes.ResponseCaptor;
import net.zscript.javaclient.commandbuilder.commandnodes.ZscriptCommandBuilder;
import net.zscript.javaclient.commandbuilder.commandnodes.ZscriptCommandNode;
+import net.zscript.javaclient.tokens.ExtendingTokenBuffer;
import net.zscript.tokenizer.TokenBuffer.TokenReader;
-import net.zscript.tokenizer.TokenExtendingBuffer;
import net.zscript.tokenizer.Tokenizer;
import net.zscript.tokenizer.ZscriptTokenExpression;
public class JavaCommandBuilderResponseTest {
- final TokenExtendingBuffer buffer = new TokenExtendingBuffer();
+ final ExtendingTokenBuffer buffer = new ExtendingTokenBuffer();
final Tokenizer tokenizer = new Tokenizer(buffer.getTokenWriter(), 2);
final TokenReader tokenReader = buffer.getTokenReader();
diff --git a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/tokens/ExtendingTokenBuffer.java b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/tokens/ExtendingTokenBuffer.java
new file mode 100644
index 000000000..056129c9b
--- /dev/null
+++ b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/tokens/ExtendingTokenBuffer.java
@@ -0,0 +1,39 @@
+package net.zscript.javaclient.tokens;
+
+import net.zscript.tokenizer.AbstractArrayTokenBuffer;
+
+/**
+ * A TokenBuffer that automatically expands on being filled, for handling Zscript responses in a Client.
+ */
+public class ExtendingTokenBuffer extends AbstractArrayTokenBuffer {
+ public ExtendingTokenBuffer() {
+ super(20);
+ }
+
+ /**
+ * There's always room, as we auto-expand.
+ *
+ * @param writeCursor
+ * @param size
+ * @return always true
+ */
+ @Override
+ protected boolean checkAvailableCapacityFrom(int writeCursor, int size) {
+ return true;
+ }
+
+ /**
+ * Expands the underlying array, and returns the offset we were trying for now that it will fit.
+ *
+ * {@inheritDoc}
+ *
+ * @param overflowedOffset the offset we were trying to access
+ * @return the overflowedOffset that was passed in, as there's now enough space
+ */
+ @Override
+ protected int offsetOnOverflow(int overflowedOffset) {
+ // expand to double current size
+ extendData(getDataSize());
+ return overflowedOffset;
+ }
+}
diff --git a/clients/java-client-lib/client-core/src/test/java/net/zscript/javaclient/commandPrinting/CommandExecutionPathRegenerationTest.java b/clients/java-client-lib/client-core/src/test/java/net/zscript/javaclient/commandPrinting/CommandExecutionPathRegenerationTest.java
index 0b7af8ed3..a46592d3c 100644
--- a/clients/java-client-lib/client-core/src/test/java/net/zscript/javaclient/commandPrinting/CommandExecutionPathRegenerationTest.java
+++ b/clients/java-client-lib/client-core/src/test/java/net/zscript/javaclient/commandPrinting/CommandExecutionPathRegenerationTest.java
@@ -11,7 +11,7 @@
import org.junit.jupiter.params.provider.MethodSource;
import net.zscript.javaclient.commandPaths.CommandExecutionPath;
-import net.zscript.tokenizer.TokenExtendingBuffer;
+import net.zscript.javaclient.tokens.ExtendingTokenBuffer;
import net.zscript.tokenizer.Tokenizer;
public class CommandExecutionPathRegenerationTest {
@@ -19,7 +19,7 @@ public class CommandExecutionPathRegenerationTest {
@ParameterizedTest
@MethodSource
public void shouldProduceActionsForLogicalCommandSeries(final String input, final String output) {
- TokenExtendingBuffer bufferCmd = new TokenExtendingBuffer();
+ ExtendingTokenBuffer bufferCmd = new ExtendingTokenBuffer();
Tokenizer tokenizerCmd = new Tokenizer(bufferCmd.getTokenWriter(), 2);
for (byte b : input.getBytes(StandardCharsets.UTF_8)) {
tokenizerCmd.accept(b);
diff --git a/clients/java-client-lib/client-core/src/test/java/net/zscript/javaclient/commandPrinting/CompleteCommandGrapherTest.java b/clients/java-client-lib/client-core/src/test/java/net/zscript/javaclient/commandPrinting/CompleteCommandGrapherTest.java
index 8f49fd9f3..49ce85db7 100644
--- a/clients/java-client-lib/client-core/src/test/java/net/zscript/javaclient/commandPrinting/CompleteCommandGrapherTest.java
+++ b/clients/java-client-lib/client-core/src/test/java/net/zscript/javaclient/commandPrinting/CompleteCommandGrapherTest.java
@@ -13,7 +13,7 @@
import net.zscript.ascii.AnsiCharacterStylePrinter;
import net.zscript.javaclient.commandPaths.CommandExecutionPath;
-import net.zscript.tokenizer.TokenExtendingBuffer;
+import net.zscript.javaclient.tokens.ExtendingTokenBuffer;
import net.zscript.tokenizer.Tokenizer;
public class CompleteCommandGrapherTest {
@@ -23,7 +23,7 @@ public class CompleteCommandGrapherTest {
@ParameterizedTest
@MethodSource
public void shouldProduceGoodGraphs(final String input, final String output) {
- TokenExtendingBuffer bufferCmd = new TokenExtendingBuffer();
+ ExtendingTokenBuffer bufferCmd = new ExtendingTokenBuffer();
Tokenizer tokenizerCmd = new Tokenizer(bufferCmd.getTokenWriter(), 2);
for (byte b : input.getBytes(StandardCharsets.UTF_8)) {
tokenizerCmd.accept(b);
diff --git a/clients/java-client-lib/client-main/src/main/java/net/zscript/javaclient/connectors/RawConnection.java b/clients/java-client-lib/client-main/src/main/java/net/zscript/javaclient/connectors/RawConnection.java
index 11c56f186..18a3f17cc 100644
--- a/clients/java-client-lib/client-main/src/main/java/net/zscript/javaclient/connectors/RawConnection.java
+++ b/clients/java-client-lib/client-main/src/main/java/net/zscript/javaclient/connectors/RawConnection.java
@@ -14,7 +14,7 @@
import net.zscript.javaclient.addressing.CompleteAddressedResponse;
import net.zscript.javaclient.nodes.Connection;
import net.zscript.javaclient.threading.ZscriptWorkerThread;
-import net.zscript.tokenizer.TokenExtendingBuffer;
+import net.zscript.javaclient.tokens.ExtendingTokenBuffer;
import net.zscript.tokenizer.Tokenizer;
public abstract class RawConnection implements Connection, AutoCloseable {
@@ -44,7 +44,7 @@ public final void onReceive(Consumer resp) {
onReceiveBytes(data -> thread.moveOntoThread(() -> {
AddressedResponse parsed = null;
try {
- TokenExtendingBuffer buffer = new TokenExtendingBuffer();
+ ExtendingTokenBuffer buffer = new ExtendingTokenBuffer();
Tokenizer t = new Tokenizer(buffer.getTokenWriter(), 2);
for (byte b : data) {
t.accept(b);
diff --git a/clients/java-client-lib/client-main/src/main/java/net/zscript/javaclient/devices/Device.java b/clients/java-client-lib/client-main/src/main/java/net/zscript/javaclient/devices/Device.java
index 63a78968c..401cdff9f 100644
--- a/clients/java-client-lib/client-main/src/main/java/net/zscript/javaclient/devices/Device.java
+++ b/clients/java-client-lib/client-main/src/main/java/net/zscript/javaclient/devices/Device.java
@@ -25,8 +25,8 @@
import net.zscript.javaclient.commandbuilder.notifications.NotificationId;
import net.zscript.javaclient.nodes.ZscriptNode;
import net.zscript.javaclient.sequence.CommandSequence;
+import net.zscript.javaclient.tokens.ExtendingTokenBuffer;
import net.zscript.model.ZscriptModel;
-import net.zscript.tokenizer.TokenExtendingBuffer;
import net.zscript.tokenizer.Tokenizer;
public class Device {
@@ -133,7 +133,7 @@ public ResponseSequenceCallback sendAndWaitExpectSuccess(final CommandSequenceNo
}
public void send(final byte[] cmdSeq, final Consumer callback) {
- TokenExtendingBuffer buffer = new TokenExtendingBuffer();
+ ExtendingTokenBuffer buffer = new ExtendingTokenBuffer();
Tokenizer tok = new Tokenizer(buffer.getTokenWriter(), 2);
for (byte b : cmdSeq) {
tok.accept(b);
diff --git a/clients/java-client-lib/client-main/src/test/java/net/zscript/javaclient/connection/SerialMain.java b/clients/java-client-lib/client-main/src/test/java/net/zscript/javaclient/connection/SerialMain.java
index 731b74081..973aaa252 100644
--- a/clients/java-client-lib/client-main/src/test/java/net/zscript/javaclient/connection/SerialMain.java
+++ b/clients/java-client-lib/client-main/src/test/java/net/zscript/javaclient/connection/SerialMain.java
@@ -13,8 +13,8 @@
import net.zscript.javaclient.connectors.ZscriptConnectors;
import net.zscript.javaclient.connectors.serial.SerialConnector;
import net.zscript.javaclient.sequence.CommandSequence;
+import net.zscript.javaclient.tokens.ExtendingTokenBuffer;
import net.zscript.model.modules.base.CoreModule;
-import net.zscript.tokenizer.TokenExtendingBuffer;
import net.zscript.tokenizer.Tokenizer;
class SerialMain {
@@ -91,7 +91,7 @@ public static void main(String[] args) throws IOException, InterruptedException
});
for (int i = 0; i < 10; i++) {
byte[] ba = CoreModule.echoBuilder().setAny('A', 35).build().asString().getBytes(StandardCharsets.UTF_8);
- TokenExtendingBuffer buffer = new TokenExtendingBuffer();
+ ExtendingTokenBuffer buffer = new ExtendingTokenBuffer();
Tokenizer t = new Tokenizer(buffer.getTokenWriter(), 2);
for (byte b : ba) {
t.accept(b);
diff --git a/clients/java-client-lib/client-main/src/test/java/net/zscript/javaclient/connection/TcpMain.java b/clients/java-client-lib/client-main/src/test/java/net/zscript/javaclient/connection/TcpMain.java
index 095efd398..8c34aa809 100644
--- a/clients/java-client-lib/client-main/src/test/java/net/zscript/javaclient/connection/TcpMain.java
+++ b/clients/java-client-lib/client-main/src/test/java/net/zscript/javaclient/connection/TcpMain.java
@@ -9,8 +9,8 @@
import net.zscript.javaclient.connectors.ZscriptConnectors;
import net.zscript.javaclient.connectors.ZscriptConnectors.ZscriptConnector;
import net.zscript.javaclient.sequence.CommandSequence;
+import net.zscript.javaclient.tokens.ExtendingTokenBuffer;
import net.zscript.model.modules.base.CoreModule;
-import net.zscript.tokenizer.TokenExtendingBuffer;
import net.zscript.tokenizer.Tokenizer;
class TcpMain {
@@ -23,7 +23,7 @@ public static void main(String[] args) throws Exception {
conn.onReceive((response) -> {
System.out.println("Response: " + response.toString());
});
- TokenExtendingBuffer buffer = new TokenExtendingBuffer();
+ ExtendingTokenBuffer buffer = new ExtendingTokenBuffer();
Tokenizer t = new Tokenizer(buffer.getTokenWriter(), 2);
for (byte b : CoreModule.echoBuilder().setAny('A', 1234).build().asString().getBytes(StandardCharsets.UTF_8)) {
t.accept(b);
diff --git a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/scriptSpaces/ScriptSpaceSetupCommand.java b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/scriptSpaces/ScriptSpaceSetupCommand.java
index 1433ab22d..fe44bbec9 100644
--- a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/scriptSpaces/ScriptSpaceSetupCommand.java
+++ b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/scriptSpaces/ScriptSpaceSetupCommand.java
@@ -18,22 +18,26 @@ public static void execute(List spaces, CommandContext ctx) {
ctx.status(ZscriptStatus.VALUE_OUT_OF_RANGE);
return;
}
- ZscriptCommandOutStream out = ctx.getOutStream();
- ScriptSpace target = spaces.get(spaceIndex.getAsInt());
- out.writeField('P', target.getCurrentLength());
- if (target.isRunning()) {
+
+ ZscriptCommandOutStream out = ctx.getOutStream();
+ ScriptSpace targetSpace = spaces.get(spaceIndex.getAsInt());
+ out.writeField('P', targetSpace.getCurrentLength());
+
+ if (targetSpace.isRunning()) {
out.writeField('R', 0);
}
- if (target.canBeWrittenTo()) {
+
+ if (targetSpace.isWritable()) {
out.writeField('W', 0);
}
+
out.writeField('L', 0xFFFF);
OptionalInt runOpt = ctx.getField('R');
if (runOpt.isPresent()) {
if (runOpt.getAsInt() != 0) {
- target.run();
+ targetSpace.run();
} else {
- target.stop();
+ targetSpace.stop();
}
}
}
diff --git a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/scriptSpaces/ScriptSpaceWriteCommand.java b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/scriptSpaces/ScriptSpaceWriteCommand.java
index 373e3eaa8..ee781a2ad 100644
--- a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/scriptSpaces/ScriptSpaceWriteCommand.java
+++ b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/scriptSpaces/ScriptSpaceWriteCommand.java
@@ -7,8 +7,8 @@
import net.zscript.javareceiver.core.ZscriptCommandOutStream;
import net.zscript.javareceiver.execution.CommandContext;
import net.zscript.javareceiver.scriptSpaces.ScriptSpace;
+import net.zscript.javareceiver.scriptSpaces.ScriptSpaceTokenBuffer.ScriptSpaceWriterTokenBuffer;
import net.zscript.model.components.ZscriptStatus;
-import net.zscript.tokenizer.ScriptSpaceBuffer.ScriptSpaceWriterBuffer;
import net.zscript.tokenizer.Tokenizer;
public class ScriptSpaceWriteCommand {
@@ -21,18 +21,21 @@ public static void execute(List spaces, CommandContext ctx) {
ctx.status(ZscriptStatus.VALUE_OUT_OF_RANGE);
return;
}
+
ZscriptCommandOutStream out = ctx.getOutStream();
ScriptSpace target = spaces.get(spaceIndex.getAsInt());
if (target.isRunning()) {
ctx.status(ZscriptStatus.COMMAND_FAIL);
return;
}
- ScriptSpaceWriterBuffer writer;
+
+ ScriptSpaceWriterTokenBuffer writer;
if (ctx.hasField((byte) 'R')) {
writer = target.overwrite();
} else {
writer = target.append();
}
+
Tokenizer tok = new Tokenizer(writer.getTokenWriter(), 2);
for (Iterator iterator = ctx.getBigField(); iterator.hasNext(); ) {
tok.accept(iterator.next());
diff --git a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/scriptSpaces/ScriptSpace.java b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/scriptSpaces/ScriptSpace.java
index 4324c33bf..ea5e85a9e 100644
--- a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/scriptSpaces/ScriptSpace.java
+++ b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/scriptSpaces/ScriptSpace.java
@@ -6,22 +6,24 @@
import net.zscript.javareceiver.core.Zscript;
import net.zscript.javareceiver.execution.ActionSource;
import net.zscript.javareceiver.execution.ZscriptAction;
+import net.zscript.javareceiver.scriptSpaces.ScriptSpaceTokenBuffer.ScriptSpaceWriterTokenBuffer;
import net.zscript.javareceiver.semanticParser.ExecutionActionFactory;
import net.zscript.javareceiver.semanticParser.SemanticParser;
-import net.zscript.tokenizer.ScriptSpaceBuffer;
-import net.zscript.tokenizer.ScriptSpaceBuffer.ScriptSpaceWriterBuffer;
import net.zscript.tokenizer.Tokenizer;
+/**
+ *
+ */
public class ScriptSpace implements ActionSource {
- private final ScriptSpaceOutStream outStream;
- private final ScriptSpaceBuffer buffer;
- private final SemanticParser parser;
- private final boolean canBeWrittenTo;
+ private final ScriptSpaceOutStream outStream;
+ private final ScriptSpaceTokenBuffer buffer;
+ private final SemanticParser parser;
+ private final boolean isWritable;
public static ScriptSpace from(Zscript z, String str) {
- ScriptSpaceBuffer buffer = new ScriptSpaceBuffer();
- ScriptSpaceWriterBuffer writer = buffer.fromStart();
- Tokenizer tok = new Tokenizer(writer.getTokenWriter(), 2);
+ ScriptSpaceTokenBuffer buffer = new ScriptSpaceTokenBuffer();
+ ScriptSpaceWriterTokenBuffer writer = buffer.fromStart();
+ Tokenizer tok = new Tokenizer(writer.getTokenWriter(), 2);
for (byte b : str.getBytes(StandardCharsets.UTF_8)) {
tok.accept(b);
}
@@ -30,17 +32,17 @@ public static ScriptSpace from(Zscript z, String str) {
}
public static ScriptSpace blank(Zscript z) {
- ScriptSpaceBuffer buffer = new ScriptSpaceBuffer();
- ScriptSpace space = new ScriptSpace(z, buffer, true);
+ ScriptSpaceTokenBuffer buffer = new ScriptSpaceTokenBuffer();
+ ScriptSpace space = new ScriptSpace(z, buffer, true);
space.stop();
return space;
}
- public ScriptSpace(Zscript z, ScriptSpaceBuffer buffer, boolean canBeWrittenTo) {
+ private ScriptSpace(Zscript z, ScriptSpaceTokenBuffer buffer, boolean isWritable) {
this.buffer = buffer;
this.parser = new SemanticParser(buffer.getTokenReader(), new ExecutionActionFactory());
this.outStream = new ScriptSpaceOutStream(z, parser, new byte[32]);
- this.canBeWrittenTo = canBeWrittenTo;
+ this.isWritable = isWritable;
}
@Override
@@ -53,20 +55,20 @@ public OutStream getOutStream(Zscript zscript) {
return outStream;
}
- public boolean canBeWrittenTo() {
- return canBeWrittenTo;
+ public boolean isWritable() {
+ return isWritable;
}
- public ScriptSpaceWriterBuffer append() {
- if (canBeWrittenTo) {
+ public ScriptSpaceWriterTokenBuffer append() {
+ if (isWritable) {
return buffer.append();
} else {
throw new UnsupportedOperationException();
}
}
- public ScriptSpaceWriterBuffer overwrite() {
- if (canBeWrittenTo) {
+ public ScriptSpaceWriterTokenBuffer overwrite() {
+ if (isWritable) {
return buffer.fromStart();
} else {
throw new UnsupportedOperationException();
@@ -88,5 +90,4 @@ public void run() {
public void stop() {
parser.stop();
}
-
}
diff --git a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/scriptSpaces/ScriptSpaceTokenBuffer.java b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/scriptSpaces/ScriptSpaceTokenBuffer.java
new file mode 100644
index 000000000..394916846
--- /dev/null
+++ b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/scriptSpaces/ScriptSpaceTokenBuffer.java
@@ -0,0 +1,74 @@
+package net.zscript.javareceiver.scriptSpaces;
+
+import net.zscript.tokenizer.AbstractArrayTokenBuffer;
+
+public class ScriptSpaceTokenBuffer extends AbstractArrayTokenBuffer {
+
+ public ScriptSpaceTokenBuffer() {
+ super(new byte[0], 0);
+ }
+
+ private int getAvailableWrite(int writeCursor) {
+ return (writeCursor >= getReadStart() ? getDataSize() : 0) + getReadStart() - writeCursor - 1;
+ }
+
+ @Override
+ protected boolean checkAvailableCapacityFrom(int writeCursor, int size) {
+ return getAvailableWrite(writeCursor) >= size;
+ }
+
+ @Override
+ protected int offsetOnOverflow(int overflowedOffset) {
+ return overflowedOffset - getDataSize();
+ }
+
+ public ScriptSpaceWriterTokenBuffer append() {
+ return new ScriptSpaceWriterTokenBuffer(this, getInternalData(), true);
+ }
+
+ public ScriptSpaceWriterTokenBuffer fromStart() {
+ return new ScriptSpaceWriterTokenBuffer(this, new byte[20], false);
+ }
+
+ public int getCurrentLength() {
+ return getDataSize();
+ }
+
+ @Override
+ public TokenWriter getTokenWriter() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Special token buffer for collecting tokens to be written to a real ScriptSpaceTokenBuffer.
+ */
+ public static class ScriptSpaceWriterTokenBuffer extends AbstractArrayTokenBuffer {
+ private final ScriptSpaceTokenBuffer parent;
+
+ private ScriptSpaceWriterTokenBuffer(ScriptSpaceTokenBuffer parent, byte[] data, boolean append) {
+ super(data, append ? data.length : 0);
+ this.parent = parent;
+ // ensure a reasonable amount of space
+ if (getDataSize() < 32) {
+ extendData(32 - getDataSize());
+ }
+ }
+
+ @Override
+ protected boolean checkAvailableCapacityFrom(int writeCursor, int size) {
+ return true;
+ }
+
+ @Override
+ protected int offsetOnOverflow(int overflowedOffset) {
+ extendData(getDataSize() + overflowedOffset);
+ return overflowedOffset;
+ }
+
+ public void commitChanges() {
+ parent.importInternalDataFrom(this);
+ // parent.data = Arrays.copyOf(data, writeStart);
+ // parent.writeStart = writeStart + 2; // Question: Why is it +2 ??
+ }
+ }
+}
diff --git a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/core/StringWriterOutStream.java b/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/core/StringWriterOutStream.java
index 999b1565a..a9a42b011 100644
--- a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/core/StringWriterOutStream.java
+++ b/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/core/StringWriterOutStream.java
@@ -11,14 +11,18 @@
*/
public class StringWriterOutStream extends OutputStreamOutStream {
private final StringWriter stringWriter;
- private boolean open = false;
+ private boolean open = false;
public StringWriterOutStream() throws IOException {
this(new StringWriter());
}
private StringWriterOutStream(StringWriter stringWriter) throws IOException {
- super(new WriterOutputStream.Builder().setCharset(StandardCharsets.ISO_8859_1).setWriter(stringWriter).setWriteImmediately(true).get());
+ super(new WriterOutputStream.Builder()
+ .setCharset(StandardCharsets.ISO_8859_1)
+ .setWriter(stringWriter)
+ .setWriteImmediately(true)
+ .get());
this.stringWriter = stringWriter;
}
diff --git a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/fullRun/FullRunningTest.java b/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/fullRun/FullRunningTest.java
index ad5c38d45..ddc518aca 100644
--- a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/fullRun/FullRunningTest.java
+++ b/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/fullRun/FullRunningTest.java
@@ -1,9 +1,9 @@
package net.zscript.javareceiver.fullRun;
-import static org.assertj.core.api.Assertions.assertThat;
-
import java.io.IOException;
+import static org.assertj.core.api.Assertions.assertThat;
+
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -11,6 +11,7 @@
import net.zscript.javareceiver.core.Zscript;
import net.zscript.javareceiver.modules.core.ZscriptCoreModule;
+@SuppressWarnings("StatementWithEmptyBody")
public class FullRunningTest {
private final Zscript zscript = new Zscript();
@@ -26,9 +27,38 @@ void setup() throws IOException {
public void shouldRunBasicCommand() {
StringChannel channel = StringChannel.from("Z1AB\n", outStream);
zscript.addChannel(channel);
+
while (zscript.progress()) {
}
+
assertThat(outStream.getStringAndReset()).isEqualTo("!ABS\n");
}
+ @Test
+ public void shouldRunSeveralBasicCommands() {
+ StringChannel channel = StringChannel.from("Z1AB\nZ1CD\n", outStream);
+ zscript.addChannel(channel);
+
+ while (zscript.progress()) {
+ }
+
+ assertThat(outStream.getStringAndReset()).isEqualTo("!ABS\n!CDS\n");
+ }
+
+ @Test
+ public void shouldHandleMultipleChannels() throws IOException {
+ StringWriterOutStream outStream1 = new StringWriterOutStream();
+ StringChannel channel1 = StringChannel.from("Z1AB\nZ1CD\n", outStream1);
+ zscript.addChannel(channel1);
+
+ StringWriterOutStream outStream2 = new StringWriterOutStream();
+ StringChannel channel2 = StringChannel.from("Z1EF\n", outStream2);
+ zscript.addChannel(channel2);
+
+ while (zscript.progress()) {
+ }
+
+ assertThat(outStream1.getStringAndReset()).isEqualTo("!ABS\n!CDS\n");
+ assertThat(outStream2.getStringAndReset()).isEqualTo("!EFS\n");
+ }
}
diff --git a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/scriptSpace/ScriptSpaceTest.java b/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/scriptSpace/ScriptSpaceTest.java
index 55e471858..22b207355 100644
--- a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/scriptSpace/ScriptSpaceTest.java
+++ b/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/scriptSpace/ScriptSpaceTest.java
@@ -1,9 +1,9 @@
package net.zscript.javareceiver.scriptSpace;
-import static org.assertj.core.api.Assertions.assertThat;
-
import java.io.IOException;
+import static org.assertj.core.api.Assertions.assertThat;
+
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -14,6 +14,7 @@
import net.zscript.javareceiver.modules.scriptSpaces.ScriptSpaceModule;
import net.zscript.javareceiver.scriptSpaces.ScriptSpace;
+@SuppressWarnings("StatementWithEmptyBody")
public class ScriptSpaceTest {
private final ScriptSpaceModule module = new ScriptSpaceModule();
@@ -31,10 +32,10 @@ void setup() throws IOException {
@Test
public void shouldRunScriptSpaceWithFailuresAndErrors() {
- ScriptSpace space = ScriptSpace.from(zscript, "Z1&Z0\nZ1ABC&Z1S1\nZ1S1|Z0\nZ1S10\n");
+ ScriptSpace space = ScriptSpace.from(zscript, "Z1 & Z0\n Z1ABC & Z1S1\n Z1S1 | Z0\n Z1S10\n");
zscript.addActionSource(space);
module.addScriptSpace(space);
- while (zscript.progress()) {
+ for (int i = 0; zscript.progress() && i < 1000000; i++) {
}
assertThat(outStream.getStringAndReset()).isEqualTo("!ABCS&S1\n!S10\n");
}
@@ -42,12 +43,12 @@ public void shouldRunScriptSpaceWithFailuresAndErrors() {
@Test
public void scriptSpaceShouldJamZscript() {
StringChannel channel = StringChannel.from("Z1AB\n", outStream);
- ScriptSpace space = ScriptSpace.from(zscript, "Z1&Z0\n");
+ ScriptSpace space = ScriptSpace.from(zscript, "Z1 & Z0\n");
zscript.addActionSource(space);
zscript.addChannel(channel);
module.addScriptSpace(space);
- int i = 0;
- while (zscript.progress() && i++ < 1000000) {
+
+ for (int i = 0; zscript.progress() && i < 1000000; i++) {
}
assertThat(outStream.getStringAndReset()).isEqualTo("");
}
@@ -55,12 +56,11 @@ public void scriptSpaceShouldJamZscript() {
@Test
public void scriptSpaceDelayShouldUnjamZscript() {
StringChannel channel = StringChannel.from("Z1AB\n", outStream);
- ScriptSpace space = ScriptSpace.from(zscript, "Z2&Z0\n%Z28M10\n");
+ ScriptSpace space = ScriptSpace.from(zscript, "Z2 & Z0\n %Z28M10\n");
zscript.addActionSource(space);
zscript.addChannel(channel);
module.addScriptSpace(space);
- int i = 0;
- while (zscript.progress() && i++ < 1000000) {
+ for (int i = 0; zscript.progress() && i < 1000000; i++) {
}
assertThat(outStream.getStringAndReset()).isEqualTo("!ABS\n");
}
@@ -72,90 +72,83 @@ public void scriptSpaceDelayWithLockingShouldJamZscript() {
zscript.addActionSource(space);
zscript.addChannel(channel);
module.addScriptSpace(space);
- int i = 0;
- while (zscript.progress() && i++ < 1000000) {
+ for (int i = 0; zscript.progress() && i < 1000000; i++) {
}
assertThat(outStream.getStringAndReset()).isEqualTo("");
}
@Test
public void shouldReadScriptSpaceCapabilities() {
- StringChannel channel = StringChannel.from("Z2&Z20\n", outStream);
- ScriptSpace space = ScriptSpace.from(zscript, "Z2&Z0\n");
+ StringChannel channel = StringChannel.from("Z2 & Z20\n", outStream);
+ ScriptSpace space = ScriptSpace.from(zscript, "Z2 & Z0\n");
space.stop();
zscript.addActionSource(space);
zscript.addChannel(channel);
module.addScriptSpace(space);
- int i = 0;
- while (zscript.progress() && i++ < 1000000) {
+ for (int i = 0; zscript.progress() && i < 1000000; i++) {
}
assertThat(outStream.getStringAndReset()).isEqualTo("!AS&C107P1S\n");
}
@Test
public void shouldReadScriptSpaceSetup() {
- StringChannel channel = StringChannel.from("Z2&Z21P0\n", outStream);
- ScriptSpace space = ScriptSpace.from(zscript, "Z2&Z0\n");
+ StringChannel channel = StringChannel.from("Z2 & Z21P0\n", outStream);
+ ScriptSpace space = ScriptSpace.from(zscript, "Z2 & Z0\n");
space.stop();
zscript.addActionSource(space);
zscript.addChannel(channel);
module.addScriptSpace(space);
- int i = 0;
- while (zscript.progress() && i++ < 1000000) {
+ for (int i = 0; zscript.progress() && i < 1000000; i++) {
}
assertThat(outStream.getStringAndReset()).isEqualTo("!AS&P7LffffS\n");
}
@Test
public void shouldRunScriptSpaceFromSetup() {
- StringChannel channel = StringChannel.from("Z2&Z21P0R1\nZ\n", outStream);
- ScriptSpace space = ScriptSpace.from(zscript, "Z2&Z0\n");
+ StringChannel channel = StringChannel.from("Z2 & Z21P0R1\n Z\n", outStream);
+ ScriptSpace space = ScriptSpace.from(zscript, "Z2 & Z0\n");
space.stop();
zscript.addActionSource(space);
zscript.addChannel(channel);
module.addScriptSpace(space);
- int i = 0;
- while (zscript.progress() && i++ < 1000000) {
+ for (int i = 0; zscript.progress() && i < 1000000; i++) {
}
assertThat(outStream.getStringAndReset()).isEqualTo("!AS&P7LffffS\n");
}
@Test
public void shouldRunAndStopScriptSpaceFromSetup() {
- StringChannel channel = StringChannel.from("Z2&Z21P0R1&Z21P&Z21PR&Z21P\nZ1\n", outStream);
- ScriptSpace space = ScriptSpace.from(zscript, "Z2&Z1S1\n");
+ StringChannel channel = StringChannel.from("Z2 & Z21P0R1 & Z21P & Z21PR & Z21P\n Z1\n", outStream);
+ ScriptSpace space = ScriptSpace.from(zscript, "Z2 & Z1S1\n");
space.stop();
zscript.addActionSource(space);
zscript.addChannel(channel);
module.addScriptSpace(space);
- int i = 0;
- while (zscript.progress() && i++ < 1000000) {
+ for (int i = 0; zscript.progress() && i < 1000000; i++) {
}
assertThat(outStream.getStringAndReset()).isEqualTo("!AS&PbLffffS&PbRLffffS&PbRLffffS&PbLffffS\n!S\n");
}
@Test
public void shouldCreateBlankSpace() {
- StringChannel channel = StringChannel.from("Z2&Z21P\n", outStream);
+ StringChannel channel = StringChannel.from("Z2 & Z21P\n", outStream);
ScriptSpace space = ScriptSpace.blank(zscript);
zscript.addActionSource(space);
zscript.addChannel(channel);
module.addScriptSpace(space);
- int i = 0;
- while (zscript.progress() && i++ < 1000000) {
+ for (int i = 0; zscript.progress() && i < 1000000; i++) {
}
assertThat(outStream.getStringAndReset()).isEqualTo("!AS&PWLffffS\n");
}
@Test
public void shouldWriteToBlankSpace() {
- StringChannel channel = StringChannel.from("Z2&Z21P&Z22P\"Z1S10=0a\"&Z21PR1\n", outStream);
+ StringChannel channel = StringChannel.from("Z2 & Z21P & Z22P\"Z1S10=0a\" & Z21PR1\n", outStream);
ScriptSpace space = ScriptSpace.blank(zscript);
zscript.addActionSource(space);
zscript.addChannel(channel);
module.addScriptSpace(space);
- int i = 0;
- while (zscript.progress() && i++ < 1000000) {
+ for (int i = 0; zscript.progress() && i < 1000000; i++) {
}
assertThat(outStream.getStringAndReset()).isEqualTo("!AS&PWLffffS&LffffS&P7WLffffS\n!S10\n");
}
diff --git a/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenArrayBuffer.java b/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/AbstractArrayTokenBuffer.java
similarity index 87%
rename from receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenArrayBuffer.java
rename to receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/AbstractArrayTokenBuffer.java
index b23764dce..61cd2d72d 100644
--- a/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenArrayBuffer.java
+++ b/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/AbstractArrayTokenBuffer.java
@@ -4,25 +4,25 @@
import java.util.NoSuchElementException;
import java.util.Optional;
+import static java.lang.String.format;
import static net.zscript.tokenizer.TokenBuffer.isMarker;
import static net.zscript.tokenizer.TokenBuffer.isSequenceEndMarker;
/**
- * Array based implementation of a Token Buffer - the tokens making up incoming command or response sequences are encoded and accessed here. Rules are:
+ * Array based implementation of a TokenBuffer - the tokens making up incoming command or response sequences are encoded and accessed here. Rules are:
*
* - There is a writable area, owned by a TokenWriter, in the space writeStart <= i < readStart.
* - There is a readable area, owned by a TokenIterator, in the space readStart <= i < writeStart.
* - A token is written as >=2 bytes at writeStart:
key | datalen | [data]
- so tokens can be iterated by adding (datalen+2) to an existing token start.
* - A marker is written as 1 byte at writeStart, indicating a dataless key - markers are identified as a key with top 3 bits set (eg from 0xe0-0xff).
* - Tokens may exceed datalen of 255 using additional new token with special key TOKEN_EXTENSION
- *
*
*/
-public abstract class TokenArrayBuffer implements TokenBuffer {
+public abstract class AbstractArrayTokenBuffer implements TokenBuffer {
private static final byte MAX_TOKEN_DATA_LENGTH = (byte) 255;
/** the ring-buffer's data array */
- protected byte[] data;
+ private byte[] data;
private final TokenWriter tokenWriter;
@@ -31,26 +31,40 @@ public abstract class TokenArrayBuffer implements TokenBuffer {
private final TokenBufferFlags flags;
/** index of first byte owned by reader, writable space ends just before it */
- protected int readStart = 0;
+ private int readStart;
/** index of first byte owned by TokenWriter, readable space ends just before it */
- protected int writeStart = 0;
+ private int writeStart;
// construct via static factories
- protected TokenArrayBuffer(final int sz) {
- this(new byte[sz]);
+ protected AbstractArrayTokenBuffer(final int sz) {
+ this(new byte[sz], 0);
}
// construct via static factories
- protected TokenArrayBuffer(final byte[] preloaded) {
- data = preloaded;
- tokenWriter = new TokenArrayBufferWriter();
- tokenReader = new TokenArrayBufferReader();
- flags = new TokenBufferFlags();
+ protected AbstractArrayTokenBuffer(final byte[] preloaded, int writeStart) {
+ this.data = preloaded;
+ this.tokenWriter = new ArrayTokenBufferWriter();
+ this.tokenReader = new ArrayTokenBufferReader();
+ this.flags = new TokenBufferFlags();
+ this.writeStart = writeStart;
+ this.readStart = 0;
}
- // Visible for testing only!
- byte[] getInternalData() {
- return data.clone();
+ protected final byte[] getInternalData() {
+ return data;
+ }
+
+ protected final int getDataSize() {
+ return data.length;
+ }
+
+ protected final void importInternalDataFrom(final AbstractArrayTokenBuffer other) {
+ this.data = Arrays.copyOf(other.data, other.writeStart);
+ this.writeStart = other.writeStart;
+ }
+
+ protected final void extendData(int extra) {
+ data = Arrays.copyOf(data, data.length + extra);
}
@Override
@@ -65,7 +79,11 @@ public TokenReader getTokenReader() {
protected abstract boolean checkAvailableCapacityFrom(final int writeCursor, final int size);
- private class TokenArrayBufferWriter implements TokenWriter {
+ protected final int getReadStart() {
+ return readStart;
+ }
+
+ private class ArrayTokenBufferWriter implements TokenWriter {
/** index of data-length field of most recent token segment (esp required for long multi-segment tokens) */
private int writeLastLen = 0;
/** the current write index into data array */
@@ -235,13 +253,28 @@ private void moveCursor() {
}
/**
- * Utility method that performs wrap-around for a lookup into the buffer
+ * Utility method that finds the correct offset from the supplied index, handling the off-the-end condition in a subclass-specific way (eg wrap, or expand the buffer, etc).
*
* @param index location in the underlying ring-buffer
* @param offset an offset to add, >= 0
* @return a new index, at the requested offset
*/
- abstract int offset(final int index, final int offset);
+ final int offset(final int index, final int offset) {
+ if (index < 0 || offset < 0 || offset >= data.length) {
+ throw new IllegalArgumentException(format("Unexpected values [index=%d, offset=%d]", index, offset));
+ }
+ final int newOffset = index + offset;
+ return (newOffset < data.length) ? newOffset : offsetOnOverflow(newOffset);
+ }
+
+ /**
+ * Hook method that allows an action to be taken when an offset lookup goes off the end of the data buffer.
+ *
+ * @param overflowedOffset the offset we were trying to access, required to be data.length <= overflowedOffset < 2*data.length (ie off the end, but not by multiple
+ * rounds)
+ * @return a new offset that should be used instead (eg loop around if this is a ring buffer, or just the overflowed offset if we've expanded the buffer)
+ */
+ protected abstract int offsetOnOverflow(final int overflowedOffset);
/**
* Utility for determining whether the specified index is in the current readable area, defined as readStart <= index < writeStart (but accounting for this being a
@@ -257,7 +290,7 @@ boolean isInReadableArea(final int index) {
|| writeStart < readStart && (index < writeStart || index >= readStart);
}
- private class TokenArrayBufferReader implements TokenReader {
+ private class ArrayTokenBufferReader implements TokenReader {
private class ArrayBufferTokenIterator implements TokenBufferIterator {
private int index;
diff --git a/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/ScriptSpaceBuffer.java b/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/ScriptSpaceBuffer.java
deleted file mode 100644
index cfa10afc6..000000000
--- a/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/ScriptSpaceBuffer.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package net.zscript.tokenizer;
-
-import java.util.Arrays;
-
-import static java.text.MessageFormat.format;
-
-public class ScriptSpaceBuffer extends TokenArrayBuffer {
-
- public ScriptSpaceBuffer() {
- super(new byte[0]);
- writeStart = 0;
- }
-
- private int getAvailableWrite(int writeCursor) {
- return (writeCursor >= readStart ? data.length : 0) + readStart - writeCursor - 1;
- }
-
- @Override
- protected boolean checkAvailableCapacityFrom(int writeCursor, int size) {
- return getAvailableWrite(writeCursor) >= size;
- }
-
- @Override
- int offset(final int index, final int offset) {
- if (index < 0 || offset < 0 || offset >= data.length) {
- throw new IllegalArgumentException(format("Unexpected values [pos={}, offset={}]", index, offset));
- }
- return (index + offset) % data.length;
- }
-
- @Override
- public TokenWriter getTokenWriter() {
- throw new UnsupportedOperationException();
- }
-
- public static class ScriptSpaceWriterBuffer extends TokenArrayBuffer {
- private final ScriptSpaceBuffer parent;
-
- private ScriptSpaceWriterBuffer(ScriptSpaceBuffer parent, byte[] data) {
- super(data);
- this.parent = parent;
- offset(data.length, 1);
- }
-
- @Override
- protected boolean checkAvailableCapacityFrom(int writeCursor, int size) {
- return true;
- }
-
- @Override
- int offset(int index, int offset) {
- if (index < 0 || offset < 0) {
- throw new IllegalArgumentException(format("Unexpected values [pos={}, offset={}]", index, offset));
- }
- if (index + offset >= data.length) {
- int newSize = index + offset + data.length;
- data = Arrays.copyOf(data, newSize);
- }
- return index + offset;
- }
-
- public void commitChanges() {
- parent.data = Arrays.copyOf(data, writeStart);
- parent.writeStart = writeStart + 2;
- }
- }
-
- public ScriptSpaceWriterBuffer append() {
- ScriptSpaceWriterBuffer writer = new ScriptSpaceWriterBuffer(this, data);
- writer.writeStart = data.length;
- return writer;
- }
-
- public ScriptSpaceWriterBuffer fromStart() {
- ScriptSpaceWriterBuffer writer = new ScriptSpaceWriterBuffer(this, new byte[20]);
- return writer;
- }
-
- public int getCurrentLength() {
- return data.length;
- }
-
-}
diff --git a/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenBuffer.java b/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenBuffer.java
index b9d918075..7d9dd0bf1 100644
--- a/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenBuffer.java
+++ b/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenBuffer.java
@@ -2,6 +2,9 @@
import java.util.NoSuchElementException;
+/**
+ * Defines the interface for the standard buffer for tokenizing Zscript.
+ */
public interface TokenBuffer {
/**
* Special token key to indicate that this segment is a continuation of the previous token due to its data size hitting maximum.
diff --git a/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenExtendingBuffer.java b/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenExtendingBuffer.java
deleted file mode 100644
index 7df2ef766..000000000
--- a/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenExtendingBuffer.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.zscript.tokenizer;
-
-import java.util.Arrays;
-
-import static java.text.MessageFormat.format;
-
-public class TokenExtendingBuffer extends TokenArrayBuffer {
- public TokenExtendingBuffer() {
- super(20);
- }
-
- @Override
- protected boolean checkAvailableCapacityFrom(int writeCursor, int size) {
- return true;
- }
-
- @Override
- int offset(int index, int offset) {
- if (index < 0 || offset < 0) {
- throw new IllegalArgumentException(format("Unexpected values [pos={}, offset={}]", index, offset));
- }
- if (index + offset >= data.length) {
- int newSize = index + offset + data.length;
- data = Arrays.copyOf(data, newSize);
- }
- return index + offset;
- }
-}
diff --git a/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenRingBuffer.java b/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenRingBuffer.java
index 6a5a5c99a..946898197 100644
--- a/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenRingBuffer.java
+++ b/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/TokenRingBuffer.java
@@ -1,16 +1,15 @@
package net.zscript.tokenizer;
-import static java.text.MessageFormat.format;
+import static java.lang.String.format;
/**
- * Ring-buffer implementation of a Token Buffer - a specific implementation of the ArrayBuffer. Additional rules are:
+ * Ring-buffer implementation of a TokenBuffer - a specific implementation of the AbstractArrayTokenBuffer. Additional rules are:
*
* - Maximum size is 64k bytes - Zscript isn't expected to work on huge datasets.
* - All indices are incremented modulo the length of the underlying byte array.
- *
*
*/
-public class TokenRingBuffer extends TokenArrayBuffer {
+public class TokenRingBuffer extends AbstractArrayTokenBuffer {
/**
* Zscript shouldn't need huge buffers, so 64K is our extreme limit. It should be addressable by uint16 indexes. Note that *exact* 64K size implies that data.length cannot be
* held in a uint16, so careful code required if porting!
@@ -24,12 +23,12 @@ public static TokenRingBuffer createBufferWithCapacity(final int sz) {
private TokenRingBuffer(int sz) {
super(sz);
if (sz > MAX_RING_BUFFER_SIZE) {
- throw new IllegalArgumentException(format("size too big [sz={}, max={}]", sz, MAX_RING_BUFFER_SIZE));
+ throw new IllegalArgumentException(format("size too big [sz=%d, max=%d]", sz, MAX_RING_BUFFER_SIZE));
}
}
private int getAvailableWrite(int writeCursor) {
- return (writeCursor >= readStart ? data.length : 0) + readStart - writeCursor - 1;
+ return (writeCursor >= getReadStart() ? getDataSize() : 0) + getReadStart() - writeCursor - 1;
}
@Override
@@ -38,10 +37,7 @@ protected boolean checkAvailableCapacityFrom(int writeCursor, int size) {
}
@Override
- int offset(final int index, final int offset) {
- if (index < 0 || offset < 0 || offset >= data.length) {
- throw new IllegalArgumentException(format("Unexpected values [pos={}, offset={}]", index, offset));
- }
- return (index + offset) % data.length;
+ protected int offsetOnOverflow(int overflowedOffset) {
+ return overflowedOffset - getDataSize();
}
}
diff --git a/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/Tokenizer.java b/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/Tokenizer.java
index 6f9341ace..a06c50d1e 100644
--- a/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/Tokenizer.java
+++ b/receivers/jvm/java-tokenizer/src/main/java/net/zscript/tokenizer/Tokenizer.java
@@ -119,7 +119,7 @@ public boolean checkCapacity() {
/**
* Requests to process a byte of Zscript input into the tokenizer buffer, if there's capacity. If the offer returns true, then the byte has been consumed; otherwise the byte
- * was rejected, and it should be kept so that it can be presented again. It is possible the
+ * was rejected, and it should be kept so that it can be presented again.
*
* @param b the new byte of zscript input
* @return true if the byte was processed, false otherwise