diff --git a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/addressing/AddressedCommand.java b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/addressing/AddressedCommand.java index 4d09ceee3..a84a9e113 100644 --- a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/addressing/AddressedCommand.java +++ b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/addressing/AddressedCommand.java @@ -8,6 +8,9 @@ import net.zscript.util.ByteString.ByteAppendable; import net.zscript.util.ByteString.ByteStringBuilder; +/** + * Represents a fixed command-sequence, augmented by the addresses of nodes it passes through to get to the target.. + */ public class AddressedCommand implements ByteAppendable { private final Queue addressSections; private final CommandSequence content; diff --git a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/addressing/ZscriptAddress.java b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/addressing/ZscriptAddress.java index e8620f5b1..e67be7369 100644 --- a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/addressing/ZscriptAddress.java +++ b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/addressing/ZscriptAddress.java @@ -12,7 +12,7 @@ /** * Representation of a single address, as per @1.5.192, where each element is a uint16. - * + *

* Aggregation to create a full multi-hop address is managed by {@link AddressedCommand} and {@link CompleteAddressedResponse} */ public class ZscriptAddress implements ByteAppendable { diff --git a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/commandPaths/Command.java b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/commandPaths/Command.java index 488d757ba..4f1d6d771 100644 --- a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/commandPaths/Command.java +++ b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/commandPaths/Command.java @@ -5,6 +5,9 @@ import net.zscript.util.ByteString; import net.zscript.util.ByteString.ByteAppendable; +/** + * Represents a single command within a command-sequence, with its fields; it keeps track of the commands that follow it onSuccess + */ public class Command implements ByteAppendable { private final ZscriptFieldSet fieldSet; diff --git a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/commandPaths/CommandExecutionPath.java b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/commandPaths/CommandExecutionPath.java index 7cdc5b5d7..9aab7f173 100644 --- a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/commandPaths/CommandExecutionPath.java +++ b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/commandPaths/CommandExecutionPath.java @@ -25,39 +25,48 @@ public class CommandExecutionPath implements Iterable, ByteAppendable { - static class CommandBuilder { - ReadToken start = null; + public static CommandExecutionPath parse(ReadToken start) { + return parse(ZscriptModel.standardModel(), start); + } - CommandBuilder onSuccess = null; - int successBracketCount = 0; - CommandBuilder onFail = null; - int failBracketCount = 0; + public static CommandExecutionPath parse(ZscriptModel model, ReadToken start) { + List builders = createLinkedPaths(start); - public void setOnSuccess(CommandBuilder onSuccess) { - this.onSuccess = onSuccess; + Map commands = new HashMap<>(); + for (ListIterator iter = builders.listIterator(builders.size()); iter.hasPrevious(); ) { + CommandBuilder b = iter.previous(); + if (b.start != null) { + commands.put(b, b.generateCommand(commands)); + } } + return new CommandExecutionPath(model, commands.get(builders.get(0))); + } - public void setOnFail(CommandBuilder onFail) { - this.onFail = onFail; - } + public static CommandExecutionPath from(ZscriptModel model, Command success) { + return new CommandExecutionPath(model, success); + } - public ReadToken getStart() { - return start; - } + public static CommandExecutionPath blank() { + return blank(ZscriptModel.standardModel()); + } - public void setStart(ReadToken token) { - this.start = token; - } + public static CommandExecutionPath blank(ZscriptModel model) { + return new CommandExecutionPath(model, null); + } - public Command generateCommand(Map commands) { - return new Command(commands.get(onSuccess), commands.get(onFail), ZscriptFieldSet.fromTokens(start)); - } + private final ZscriptModel model; + private final Command firstCommand; + + private CommandExecutionPath(ZscriptModel model, Command firstCommand) { + this.model = model; + this.firstCommand = firstCommand; } private static List createLinkedPaths(ReadToken start) { + List builders = new ArrayList<>(); + List needSuccessPath = new ArrayList<>(); List needFailPath = new ArrayList<>(); - List builders = new ArrayList<>(); CommandBuilder last = new CommandBuilder(); builders.add(last); @@ -124,43 +133,6 @@ private static List createLinkedPaths(ReadToken start) { return builders; } - public static CommandExecutionPath parse(ReadToken start) { - return parse(ZscriptModel.standardModel(), start); - } - - public static CommandExecutionPath parse(ZscriptModel model, ReadToken start) { - List builders = createLinkedPaths(start); - - Map commands = new HashMap<>(); - for (ListIterator iter = builders.listIterator(builders.size()); iter.hasPrevious(); ) { - CommandBuilder b = iter.previous(); - if (b.start != null) { - commands.put(b, b.generateCommand(commands)); - } - } - return new CommandExecutionPath(model, commands.get(builders.get(0))); - } - - public static CommandExecutionPath from(ZscriptModel model, Command success) { - return new CommandExecutionPath(model, success); - } - - public static CommandExecutionPath blank() { - return blank(ZscriptModel.standardModel()); - } - - public static CommandExecutionPath blank(ZscriptModel model) { - return new CommandExecutionPath(model, null); - } - - private final ZscriptModel model; - private final Command firstCommand; - - private CommandExecutionPath(ZscriptModel model, Command firstCommand) { - this.model = model; - this.firstCommand = firstCommand; - } - @Override public void appendTo(ByteStringBuilder builder) { Deque openedTrees = new ArrayDeque<>(); @@ -246,38 +218,40 @@ public List compareResponses(ResponseExecutionPath resps parenStarts.add(tmp1); tmp1 = tmp1.getOnFail(); } + boolean lastEndedOpen = false; boolean lastEndedClose = false; boolean lastSucceeded = true; int lastParenCount = 0; List cmds = new ArrayList<>(); - Command current = firstCommand; + Command currentCmd = firstCommand; Response currentResp = resps.getFirstResponse(); Command lastFail = null; + while (currentResp != null) { - if (current == null) { + if (currentCmd == null) { throw new IllegalArgumentException("Command sequence ended before response - cannot match"); } - cmds.add(new MatchedCommandResponse(current, currentResp)); + cmds.add(new MatchedCommandResponse(currentCmd, currentResp)); if (lastSucceeded) { if (lastEndedClose) { - if (parenStarts.peek().getOnFail() == current.getOnFail()) { + if (parenStarts.peek().getOnFail() == currentCmd.getOnFail()) { throw new IllegalArgumentException("Response has ')' without valid opening '('"); } Command tmp2 = parenStarts.pop().getOnFail(); - while (tmp2 != null && tmp2 != current) { + while (tmp2 != null && tmp2 != currentCmd) { tmp2 = tmp2.getOnSuccess(); } - if (tmp2 != current) { + if (tmp2 != currentCmd) { throw new IllegalArgumentException("Response has ')' without command sequence merging"); } lastEndedClose = false; } else if (lastEndedOpen) { - parenStarts.push(current); + parenStarts.push(currentCmd); lastEndedOpen = false; - } else if (lastFail != null && current.getOnFail() != lastFail) { + } else if (lastFail != null && currentCmd.getOnFail() != lastFail) { throw new IllegalArgumentException("Fail conditions don't match up around '&'"); } } else { @@ -286,22 +260,22 @@ public List compareResponses(ResponseExecutionPath resps throw new IllegalArgumentException("Command sequence ran out of parens before response sequence"); } Command tmp3 = parenStarts.peek().getOnFail(); - while (tmp3 != null && tmp3.getOnFail() != current) { + while (tmp3 != null && tmp3.getOnFail() != currentCmd) { tmp3 = tmp3.getOnSuccess(); } if (tmp3 == null) { throw new IllegalArgumentException("Response has ')' without command sequence merging"); } tmp3 = parenStarts.peek().getOnFail(); - while (tmp3 != null && tmp3 != current) { + while (tmp3 != null && tmp3 != currentCmd) { tmp3 = tmp3.getOnFail(); } - if (tmp3 != current) { + if (tmp3 != currentCmd) { throw new IllegalArgumentException("Response has ')' without command sequence merging"); } parenStarts.pop(); } - if (parenStarts.isEmpty() || parenStarts.peek().getOnFail() != current) { + if (parenStarts.isEmpty() || parenStarts.peek().getOnFail() != currentCmd) { throw new IllegalArgumentException("Response has failure divergence without parenthesis"); } } @@ -311,14 +285,14 @@ public List compareResponses(ResponseExecutionPath resps } else if (currentResp.hasOpenParen()) { lastEndedOpen = true; } - lastFail = current.getOnFail(); + lastFail = currentCmd.getOnFail(); lastSucceeded = true; - current = current.getOnSuccess(); + currentCmd = currentCmd.getOnSuccess(); } else { lastFail = null; lastParenCount = currentResp.getParenCount(); lastSucceeded = false; - current = current.getOnFail(); + currentCmd = currentCmd.getOnFail(); } currentResp = currentResp.getNext(); } @@ -377,4 +351,33 @@ public Command getFirstCommand() { public ZscriptModel getModel() { return model; } + + private static class CommandBuilder { + ReadToken start = null; + + CommandBuilder onSuccess = null; + int successBracketCount = 0; + CommandBuilder onFail = null; + int failBracketCount = 0; + + public void setOnSuccess(CommandBuilder onSuccess) { + this.onSuccess = onSuccess; + } + + public void setOnFail(CommandBuilder onFail) { + this.onFail = onFail; + } + + public ReadToken getStart() { + return start; + } + + public void setStart(ReadToken token) { + this.start = token; + } + + public Command generateCommand(Map commands) { + return new Command(commands.get(onSuccess), commands.get(onFail), ZscriptFieldSet.fromTokens(start)); + } + } } diff --git a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/commandPaths/NumberField.java b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/commandPaths/NumberField.java index 75149f209..f0336e9cf 100644 --- a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/commandPaths/NumberField.java +++ b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/commandPaths/NumberField.java @@ -6,8 +6,8 @@ import net.zscript.util.ByteString.ByteStringBuilder; public class NumberField implements ZscriptField, ByteString.ByteAppendable { - private byte key; - private int value; + private final byte key; + private final int value; public static NumberField fieldOf(byte key, int value) { return new NumberField(key, value); @@ -42,4 +42,9 @@ public BlockIterator iterator() { public void appendTo(ByteStringBuilder builder) { builder.appendByte(key).appendNumeric16(value); } + + @Override + public String toString() { + return "NumberField[" + ByteString.from(this) + "]"; + } } diff --git a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/nodes/AddressingSystem.java b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/nodes/AddressingSystem.java index 053e0b38c..b4404d3ee 100644 --- a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/nodes/AddressingSystem.java +++ b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/nodes/AddressingSystem.java @@ -9,7 +9,42 @@ import net.zscript.javaclient.addressing.ZscriptAddress; import net.zscript.javaclient.threading.ZscriptWorkerThread; +/** + * Maintains the mapping of addresses to connections for a node in the device tree. The device node must be known at create-time, and the addresses are attached (or detached) + * thereafter. + */ class AddressingSystem { + private final Map connections = new HashMap<>(); + + private final ZscriptBasicNode node; + + AddressingSystem(ZscriptBasicNode node) { + this.node = node; + } + + private void sendAddressed(AddressedCommand cmd) { + node.getParentConnection().send(cmd); + } + + public boolean response(AddressedResponse addrResp) { + AddressingConnection connection = connections.get(addrResp.getAddressSection()); + if (connection == null) { + return false; + } + connection.response(addrResp.getChild()); + return true; + } + + public Connection attach(ZscriptAddress address) { + AddressingConnection connection = new AddressingConnection(address); + connections.put(address, connection); + return connection; + } + + public Connection detach(ZscriptAddress address) { + return connections.remove(address); + } + class AddressingConnection implements Connection { private final ZscriptAddress address; private Consumer respConsumer = null; @@ -45,35 +80,4 @@ public ZscriptWorkerThread getAssociatedThread() { return node.getParentConnection().getAssociatedThread(); } } - - private final Map connections = new HashMap<>(); - - private final ZscriptBasicNode node; - - AddressingSystem(ZscriptBasicNode node) { - this.node = node; - } - - private void sendAddressed(AddressedCommand cmd) { - node.getParentConnection().send(cmd); - } - - public boolean response(AddressedResponse addrResp) { - AddressingConnection connection = connections.get(addrResp.getAddressSection()); - if (connection == null) { - return false; - } - connection.response(addrResp.getChild()); - return true; - } - - public Connection attach(ZscriptAddress address) { - AddressingConnection connection = new AddressingConnection(address); - connections.put(address, connection); - return connection; - } - - public Connection detach(ZscriptAddress address) { - return connections.remove(address); - } } diff --git a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/nodes/ConnectionBuffer.java b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/nodes/ConnectionBuffer.java index 69d54481c..fcb4349bd 100644 --- a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/nodes/ConnectionBuffer.java +++ b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/nodes/ConnectionBuffer.java @@ -1,8 +1,5 @@ package net.zscript.javaclient.nodes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; @@ -18,52 +15,6 @@ import net.zscript.javaclient.sequence.ResponseSequence; public class ConnectionBuffer { - - class BufferElement { - private final AddressedCommand cmd; - private final boolean sameLayer; - private final boolean hadEchoBefore; - private final int length; - private final long nanoTimeTimeout; - - BufferElement(CommandSequence seq, long nanoTimeTimeout) { - this.cmd = new AddressedCommand(seq); - this.sameLayer = true; - this.hadEchoBefore = true; - this.length = seq.getBufferLength(); - this.nanoTimeTimeout = nanoTimeTimeout; - } - - BufferElement(CommandExecutionPath cmd, long nanoTimeTimeout) { - CommandSequence seq = CommandSequence.from(cmd, echo.getEcho(), supports32Locks, lockConditions); - this.cmd = new AddressedCommand(seq); - this.sameLayer = true; - this.hadEchoBefore = false; - this.length = seq.getBufferLength(); - this.nanoTimeTimeout = nanoTimeTimeout; - } - - BufferElement(AddressedCommand cmd, long nanoTimeTimeout) { - this.cmd = cmd; - this.sameLayer = !cmd.hasAddressLayer(); - this.hadEchoBefore = true; - this.length = cmd.getBufferLength(); - this.nanoTimeTimeout = nanoTimeTimeout; - } - - public boolean isSameLayer() { - return sameLayer; - } - - public AddressedCommand getCommand() { - return cmd; - } - - public long getNanoTimeTimeout() { - return nanoTimeTimeout; - } - } - private final Connection connection; private final Queue buffer = new ArrayDeque<>(); @@ -225,4 +176,49 @@ public int getCurrentBufferContent() { public void setBufferSize(int bufferSize) { this.bufferSize = bufferSize; } + + class BufferElement { + private final AddressedCommand cmd; + private final boolean sameLayer; + private final boolean hadEchoBefore; + private final int length; + private final long nanoTimeTimeout; + + BufferElement(CommandSequence seq, long nanoTimeTimeout) { + this.cmd = new AddressedCommand(seq); + this.sameLayer = true; + this.hadEchoBefore = true; + this.length = seq.getBufferLength(); + this.nanoTimeTimeout = nanoTimeTimeout; + } + + BufferElement(CommandExecutionPath cmd, long nanoTimeTimeout) { + CommandSequence seq = CommandSequence.from(cmd, echo.getEcho(), supports32Locks, lockConditions); + this.cmd = new AddressedCommand(seq); + this.sameLayer = true; + this.hadEchoBefore = false; + this.length = seq.getBufferLength(); + this.nanoTimeTimeout = nanoTimeTimeout; + } + + BufferElement(AddressedCommand cmd, long nanoTimeTimeout) { + this.cmd = cmd; + this.sameLayer = !cmd.hasAddressLayer(); + this.hadEchoBefore = true; + this.length = cmd.getBufferLength(); + this.nanoTimeTimeout = nanoTimeTimeout; + } + + public boolean isSameLayer() { + return sameLayer; + } + + public AddressedCommand getCommand() { + return cmd; + } + + public long getNanoTimeTimeout() { + return nanoTimeTimeout; + } + } } diff --git a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/nodes/ZscriptNode.java b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/nodes/ZscriptNode.java index 75199243a..9390274c7 100644 --- a/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/nodes/ZscriptNode.java +++ b/clients/java-client-lib/client-core/src/main/java/net/zscript/javaclient/nodes/ZscriptNode.java @@ -13,6 +13,9 @@ import net.zscript.javaclient.sequence.ResponseSequence; import net.zscript.javaclient.threading.ZscriptWorkerThread; +/** + * Defines the core interface for a device as a node in the zscript device-tree. + */ public interface ZscriptNode { static ZscriptNode newNode(Connection parentConnection) { return newNode(parentConnection, 128, 100, TimeUnit.MILLISECONDS); @@ -22,6 +25,7 @@ static ZscriptNode newNode(Connection parentConnection, int bufferSize, long min ZscriptWorkerThread thread = parentConnection.getAssociatedThread(); ZscriptBasicNode node = new ZscriptBasicNode(thread.getCallbackPool(), parentConnection, bufferSize, minSegmentChangeTime, unit); thread.addTimeoutCheck(node::checkTimeouts); + return (ZscriptNode) Proxy.newProxyInstance(ZscriptNode.class.getClassLoader(), new Class[] { ZscriptNode.class }, (obj, method, params) -> thread.moveOntoThread(() -> method.invoke(node, params))); } diff --git a/clients/java-client-lib/client-main/src/test/java/net/zscript/javaclient/connection/LocalZscriptConnection.java b/clients/java-client-lib/client-main/src/test/java/net/zscript/javaclient/connection/LocalZscriptConnection.java index 560e1af73..16fb9bfc0 100644 --- a/clients/java-client-lib/client-main/src/test/java/net/zscript/javaclient/connection/LocalZscriptConnection.java +++ b/clients/java-client-lib/client-main/src/test/java/net/zscript/javaclient/connection/LocalZscriptConnection.java @@ -46,6 +46,7 @@ public void run() { } catch (Exception e) { e.printStackTrace(); } + // resubmit itself exec.submit(this); } } @@ -90,7 +91,7 @@ public void moveAlong() { @Override public void channelInfo(CommandContext view) { - view.getOutStream().writeQuotedString("Basic text channel"); + view.getOutStream().writeBigFieldQuoted("Basic text channel"); } @Override diff --git a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/core/AbstractOutStream.java b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/core/AbstractOutStream.java index e373afe76..247e006c5 100644 --- a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/core/AbstractOutStream.java +++ b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/core/AbstractOutStream.java @@ -119,12 +119,12 @@ public void writeField(ZscriptField field) { } @Override - public void writeQuotedString(String string) { - writeQuotedString(string.getBytes(StandardCharsets.UTF_8)); + public void writeBigFieldQuoted(String string) { + writeBigFieldQuoted(string.getBytes(StandardCharsets.UTF_8)); } @Override - public void writeQuotedString(byte[] data) { + public void writeBigFieldQuoted(byte[] data) { writeCharAsByte(Zchars.Z_BIGFIELD_QUOTED); for (byte b : data) { writeStringByte(b); @@ -133,7 +133,7 @@ public void writeQuotedString(byte[] data) { } @Override - public void writeBig(byte[] data) { + public void writeBigFieldHex(byte[] data) { writeCharAsByte(Zchars.Z_BIGFIELD_HEX); writeBytes(data, data.length, true); } diff --git a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/core/CommandOutStream.java b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/core/CommandOutStream.java index 354583316..2b6b02861 100644 --- a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/core/CommandOutStream.java +++ b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/core/CommandOutStream.java @@ -33,7 +33,7 @@ default void writeField(char field, int value) { * * @param text the text to write */ - void writeQuotedString(String text); + void writeBigFieldQuoted(String text); /** * Writes the supplied bytes as a quoted Big Field. It is assumed to already be encoded as required, and will *not* be UTF-8 encoded. However, forbidden chars (eg '\n', '"', @@ -41,12 +41,12 @@ default void writeField(char field, int value) { * * @param utf8text the text to write */ - void writeQuotedString(byte[] utf8text); + void writeBigFieldQuoted(byte[] utf8text); /** * Writes the bytes provided as a hex big field, eg +68656c6c6f * * @param data the data to write */ - void writeBig(byte[] data); + void writeBigFieldHex(byte[] data); } diff --git a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/core/ZscriptChannel.java b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/core/ZscriptChannel.java index dfdd88f50..a1db8793d 100644 --- a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/core/ZscriptChannel.java +++ b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/core/ZscriptChannel.java @@ -13,15 +13,15 @@ *

*/ public abstract class ZscriptChannel implements ActionSource { - protected final SemanticParser p; + protected final SemanticParser parser; protected final SequenceOutStream out; - protected ZscriptChannel(final SemanticParser p, final SequenceOutStream out) { - this.p = p; + protected ZscriptChannel(final SemanticParser parser, final SequenceOutStream out) { + this.parser = parser; this.out = out; } @@ -30,7 +30,7 @@ protected ZscriptChannel(final TokenBuffer buffer, final SequenceOutStream out) } public SemanticParser getParser() { - return p; + return parser; } @Override @@ -40,7 +40,7 @@ public SequenceOutStream getOutStream(Zscript zscript) { @Override public SemanticAction getAction() { - return p.getAction(); + return parser.getAction(); } /** @@ -50,7 +50,7 @@ public void moveAlong() { } public void setChannelIndex(byte i) { - p.setChannelIndex(i); + parser.setChannelIndex(i); } public abstract void channelInfo(final CommandContext ctx); diff --git a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/core/ZscriptCapabilitiesCommand.java b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/core/ZscriptCapabilitiesCommand.java index 8575b4693..3d201e16c 100644 --- a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/core/ZscriptCapabilitiesCommand.java +++ b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/core/ZscriptCapabilitiesCommand.java @@ -62,7 +62,7 @@ public void execute(CommandContext ctx) { if (str != null) { out.writeField('V', ver); if (!str.isEmpty()) { - out.writeQuotedString(str); + out.writeBigFieldQuoted(str); } } else { ctx.status(ZscriptStatus.VALUE_OUT_OF_RANGE); diff --git a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/core/ZscriptGuidCommand.java b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/core/ZscriptGuidCommand.java index 312c0cc95..1ee76571c 100644 --- a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/core/ZscriptGuidCommand.java +++ b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/core/ZscriptGuidCommand.java @@ -17,7 +17,7 @@ public void fetch(CommandContext ctx) { ByteBuffer bb = ByteBuffer.wrap(new byte[16]); bb.putLong(uuid.getMostSignificantBits()); bb.putLong(uuid.getLeastSignificantBits()); - ctx.getOutStream().writeBig(bb.array()); + ctx.getOutStream().writeBigFieldHex(bb.array()); } } diff --git a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/outerCore/ZscriptOuterCoreModule.java b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/outerCore/ZscriptOuterCoreModule.java index ba0b05bb2..3abb726f4 100644 --- a/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/outerCore/ZscriptOuterCoreModule.java +++ b/receivers/jvm/java-receiver/src/main/java/net/zscript/javareceiver/modules/outerCore/ZscriptOuterCoreModule.java @@ -47,7 +47,7 @@ public void execute(CommandContext ctx, int command) { @Override public void notification(NotificationContext ctx, boolean moveAlong) { - ctx.getOutStream().asCommandOutStream().writeQuotedString("System has reset"); + ctx.getOutStream().asCommandOutStream().writeBigFieldQuoted("System has reset"); } } diff --git a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/core/AbstractOutStreamTest.java b/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/core/AbstractOutStreamTest.java index bbcb0ed23..3820ccb5a 100644 --- a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/core/AbstractOutStreamTest.java +++ b/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/core/AbstractOutStreamTest.java @@ -1,10 +1,10 @@ package net.zscript.javareceiver.core; -import static org.assertj.core.api.Assertions.assertThat; - import java.io.IOException; import java.nio.charset.StandardCharsets; +import static org.assertj.core.api.Assertions.assertThat; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -75,7 +75,7 @@ void shouldWriteBigField() { expected.append(toHexChar(j)); } } - stOut.writeBig(data); + stOut.writeBigFieldHex(data); assertThat(stOut.getString()).isEqualTo(expected.toString()); } @@ -99,14 +99,14 @@ void shouldWriteStringFieldWithBytes() { data[i] = (byte) i; } expected.append('"'); - stOut.writeQuotedString(data); + stOut.writeBigFieldQuoted(data); assertThat(stOut.getString()).isEqualTo(expected.toString()); } @Test void shouldWriteStringFieldWithHiByte() { // 0xb5 is the 'µ' symbol, but we expect literally 0xb5, not utf-8's 0xc2b5 - stOut.writeQuotedString(new byte[] { (byte) 0xb5 }); + stOut.writeBigFieldQuoted(new byte[] { (byte) 0xb5 }); // note: ISO_8859_1 handily takes bottom byte of each char. We're not really using it. assertThat(stOut.getString().getBytes(StandardCharsets.ISO_8859_1)).hasSize(3).containsExactly('"', 0xb5, '"'); } @@ -114,14 +114,14 @@ void shouldWriteStringFieldWithHiByte() { @Test void shouldWriteStringFieldWithStringContainingHiByte() { // 0xb5 is the 'µ' symbol, and writing strings should convert to UTF-8's 0xc2b5 - stOut.writeQuotedString("µ"); + stOut.writeBigFieldQuoted("µ"); // note: ISO_8859_1 handily takes bottom byte of each char. We're not really using it. assertThat(stOut.getString().getBytes(StandardCharsets.ISO_8859_1)).hasSize(4).containsExactly('"', 0xc2, 0xb5, '"'); } @Test void shouldWriteStringFieldWithString() { - stOut.writeQuotedString("Hello World"); + stOut.writeBigFieldQuoted("Hello World"); assertThat(stOut.getString()).isEqualTo("\"Hello World\""); } diff --git a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/demoRun/Main.java b/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/demoRun/Main.java index 2a5c1b1af..8f0aba834 100644 --- a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/demoRun/Main.java +++ b/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/demoRun/Main.java @@ -2,6 +2,7 @@ import java.io.IOException; +import net.zscript.javareceiver.core.OutputStreamOutStream; import net.zscript.javareceiver.core.SequenceOutStream; import net.zscript.javareceiver.core.Zscript; import net.zscript.javareceiver.core.ZscriptChannel; @@ -28,7 +29,7 @@ public static void main(String[] args) throws IOException { zscript.addActionSource(space); TokenRingBuffer rbuff = TokenRingBuffer.createBufferWithCapacity(100); - SequenceOutStream out = new ZscriptPrintingOutStream(); + SequenceOutStream out = new OutputStreamOutStream<>(System.out); zscript.addChannel(new ZscriptChannel(rbuff, out) { final Tokenizer in = new Tokenizer(rbuff.getTokenWriter(), 2); private int i = 0; @@ -42,7 +43,7 @@ public void moveAlong() { @Override public void channelInfo(CommandContext ctx) { - ctx.getOutStream().writeQuotedString("Basic text channel"); + ctx.getOutStream().writeBigFieldQuoted("Basic text channel"); } @Override diff --git a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/demoRun/ZscriptPrintingOutStream.java b/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/demoRun/ZscriptPrintingOutStream.java deleted file mode 100644 index db6d64729..000000000 --- a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/demoRun/ZscriptPrintingOutStream.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.zscript.javareceiver.demoRun; - -import java.io.PrintStream; - -import net.zscript.javareceiver.core.OutputStreamOutStream; - -public class ZscriptPrintingOutStream extends OutputStreamOutStream { - public ZscriptPrintingOutStream() { - super(System.out); - } -} diff --git a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/notifications/NotificationTest.java b/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/notifications/NotificationTest.java index d3eac664c..14da267b1 100644 --- a/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/notifications/NotificationTest.java +++ b/receivers/jvm/java-receiver/src/test/java/net/zscript/javareceiver/notifications/NotificationTest.java @@ -1,9 +1,9 @@ package net.zscript.javareceiver.notifications; -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; @@ -52,7 +52,7 @@ public void notification(NotificationContext ctx, boolean moveAlong) { someValue--; } notifier = ctx.getAsyncActionNotifier(); - ctx.getOutStream().asCommandOutStream().writeQuotedString(toWrite); + ctx.getOutStream().asCommandOutStream().writeBigFieldQuoted(toWrite); } } diff --git a/receivers/jvm/java-tokenizer/src/test/java/net/zscript/tokenizer/TokenRingBufferReaderTest.java b/receivers/jvm/java-tokenizer/src/test/java/net/zscript/tokenizer/TokenRingBufferReaderTest.java index 4b7713b4a..ec115e052 100644 --- a/receivers/jvm/java-tokenizer/src/test/java/net/zscript/tokenizer/TokenRingBufferReaderTest.java +++ b/receivers/jvm/java-tokenizer/src/test/java/net/zscript/tokenizer/TokenRingBufferReaderTest.java @@ -28,7 +28,7 @@ class TokenRingBufferReaderTest { private final TokenReader reader = buffer.getTokenReader(); private final List tokens = new ArrayList<>(); - private class TokenExpectation { + private static class TokenExpectation { boolean isMarker; boolean isExtended; byte key; @@ -40,7 +40,6 @@ public TokenExpectation(boolean isMarker, boolean isExtended, byte key, byte[] d this.key = key; this.data = data; } - } private TokenExpectation marker(byte key) { @@ -96,7 +95,7 @@ private void writeExtendedToken(Random r, int byteCount) { } private void testTokenSimilarity(ReadToken found, TokenExpectation expected) { - assertThat(found.isMarker() == expected.isMarker); + assertThat(found.isMarker()).isSameAs(expected.isMarker); assertThat(found.getKey()).isEqualTo(expected.key); if (!found.isMarker()) { if (expected.data.length <= 4) { @@ -111,7 +110,7 @@ private void testTokenSimilarity(ReadToken found, TokenExpectation expected) { } } ByteArrayOutputStream st = new ByteArrayOutputStream(); - Streams.stream(found.dataIterator()).forEach(t -> st.write(t)); + Streams.stream(found.dataIterator()).forEach(st::write); assertThat(st.toByteArray()).containsExactly(expected.data); } if (expected.isExtended) { @@ -260,30 +259,30 @@ void shouldIterateTokenDataInContiguousChunks() { writeExtendedToken(r, 800); BlockIterator data = reader.tokenIterator().next().get().dataIterator(); int i = 0; - for (BlockIterator iterator = data; iterator.hasNext(); ) { - byte[] nextCont = iterator.nextContiguous(); + while (data.hasNext()) { + byte[] nextCont = data.nextContiguous(); assertThat(nextCont).containsExactly(Arrays.copyOfRange(tokens.get(0).data, i, Math.min(i + 255, 800))); i += 255; } } @Test - void shouldIterateTokenDataInLimtedContiguousChunks() { + void shouldIterateTokenDataInLimitedContiguousChunks() { Random r = new Random(SEED); writeExtendedToken(r, 800); BlockIterator data = reader.tokenIterator().next().get().dataIterator(); int i = 0; - for (BlockIterator iterator = data; iterator.hasNext(); ) { - assertThat(iterator.nextContiguous(200)).containsExactly(Arrays.copyOfRange(tokens.get(0).data, i, Math.min(i + 200, 800))); - if (iterator.hasNext()) { - assertThat(iterator.nextContiguous(200)).containsExactly(Arrays.copyOfRange(tokens.get(0).data, i + 200, Math.min(i + 255, 800))); + while (data.hasNext()) { + assertThat(data.nextContiguous(200)).containsExactly(Arrays.copyOfRange(tokens.get(0).data, i, Math.min(i + 200, 800))); + if (data.hasNext()) { + assertThat(data.nextContiguous(200)).containsExactly(Arrays.copyOfRange(tokens.get(0).data, i + 200, Math.min(i + 255, 800))); i += 255; } } } @Test - void shouldIterateTokenDataInLimtedContiguousChunksAroundEnd() { + void shouldIterateTokenDataInLimitedContiguousChunksAroundEnd() { int initialLength = 700; Random r = new Random(SEED); writeExtendedToken(r, initialLength); @@ -293,22 +292,22 @@ void shouldIterateTokenDataInLimtedContiguousChunksAroundEnd() { writeExtendedToken(r, 800); BlockIterator data = reader.tokenIterator().next().get().dataIterator(); int i = 0; - for (BlockIterator iterator = data; iterator.hasNext(); ) { + while (data.hasNext()) { int offset = 200; if (i + initialLength + (initialLength + 254) / 255 * 2 + i / 255 * 2 < BUFSIZE && i + 200 + initialLength + (initialLength + 254) / 255 * 2 + i / 255 * 2 + 2 > BUFSIZE) { offset = BUFSIZE - (initialLength + i + (initialLength + 254) / 255 * 2 + i / 255 * 2 + 2); } - assertThat(iterator.nextContiguous(200)).containsExactly(Arrays.copyOfRange(tokens.get(1).data, i, Math.min(i + offset, 800))); - if (iterator.hasNext()) { + assertThat(data.nextContiguous(200)).containsExactly(Arrays.copyOfRange(tokens.get(1).data, i, Math.min(i + offset, 800))); + if (data.hasNext()) { if (i + offset > 800) { throw new AssertionError("Iterator didn't terminate when it should have"); } if (offset + 200 < 255) { - assertThat(iterator.nextContiguous(200)).containsExactly(Arrays.copyOfRange(tokens.get(1).data, i + offset, Math.min(i + offset + 200, 800))); + assertThat(data.nextContiguous(200)).containsExactly(Arrays.copyOfRange(tokens.get(1).data, i + offset, Math.min(i + offset + 200, 800))); offset += 200; } - assertThat(iterator.nextContiguous(200)).containsExactly(Arrays.copyOfRange(tokens.get(1).data, i + offset, Math.min(i + 255, 800))); + assertThat(data.nextContiguous(200)).containsExactly(Arrays.copyOfRange(tokens.get(1).data, i + offset, Math.min(i + 255, 800))); i += 255; } } diff --git a/receivers/jvm/java-tokenizer/src/test/java/net/zscript/tokenizer/TokenizerTest.java b/receivers/jvm/java-tokenizer/src/test/java/net/zscript/tokenizer/TokenizerTest.java index e05439ecd..9a9185cc1 100644 --- a/receivers/jvm/java-tokenizer/src/test/java/net/zscript/tokenizer/TokenizerTest.java +++ b/receivers/jvm/java-tokenizer/src/test/java/net/zscript/tokenizer/TokenizerTest.java @@ -24,8 +24,6 @@ @ExtendWith(MockitoExtension.class) class TokenizerTest { - @Mock - private TokenBuffer buffer; @Mock private TokenBuffer.TokenWriter writer; diff --git a/simulator/zscript-simulator-jvm/src/main/java/net/zscript/javasimulator/zcode/i2c/I2cReadCommand.java b/simulator/zscript-simulator-jvm/src/main/java/net/zscript/javasimulator/zcode/i2c/I2cReadCommand.java index afc453082..e3f0e7bfb 100644 --- a/simulator/zscript-simulator-jvm/src/main/java/net/zscript/javasimulator/zcode/i2c/I2cReadCommand.java +++ b/simulator/zscript-simulator-jvm/src/main/java/net/zscript/javasimulator/zcode/i2c/I2cReadCommand.java @@ -63,7 +63,7 @@ public static void execute(CommandContext ctx, I2cModule module) { } else { out.writeField('I', 0); I2cReceiveResponse recResp = (I2cReceiveResponse) resp; - out.writeBig(recResp.getData()); + out.writeBigFieldHex(recResp.getData()); } } }