Skip to content

Commit

Permalink
[#163] Added NumberField
Browse files Browse the repository at this point in the history
  • Loading branch information
susanw1 committed Sep 11, 2024
1 parent f56d678 commit 659600a
Show file tree
Hide file tree
Showing 15 changed files with 216 additions and 92 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package net.zscript.javaclient.commandPaths;

import net.zscript.model.components.Zchars;
import net.zscript.tokenizer.BlockIterator;
import net.zscript.tokenizer.ZscriptField;
import net.zscript.util.ByteString;
import net.zscript.util.ByteString.ByteAppendable;
import net.zscript.util.ByteString.ByteStringBuilder;

public class BigField implements ByteAppendable {
/**
* Represents a single big-field element (there may be multiple elements within n expression).
*/
public class BigField implements ZscriptField, ByteAppendable {
private final ByteString data;
private final boolean isString;

Expand Down Expand Up @@ -37,7 +42,7 @@ public ByteString getDataAsByteString() {
}

/**
* Determines whether this big-field identifies as a text string, or binary data. Doesn't matter much, except we might keep it in its preferred form.
* Determines whether this big-field identifies as a text string, or binary data. Doesn't matter much, except we might keep it in its preferred form.
*
* @return true if textual, false if binary
*/
Expand All @@ -54,6 +59,11 @@ public int getDataLength() {
return data.size();
}

/**
* Writes the big-field in its preferred form to the ByteStringBuilder.
*
* @param builder the builder to append to
*/
@Override
public void appendTo(ByteStringBuilder builder) {
if (isString) {
Expand All @@ -74,7 +84,34 @@ public void appendTo(ByteStringBuilder builder) {
}
}

/**
* Determines how much space this BigField requires when Tokenized in a standard TokenBuffer.
*
* @return the length of this field when written as a token
*/
public int getBufferLength() {
// FIXME: Note: doesn't take into account extension blocks length (they add 2 bytes each) - should it? (yes...)
return 2 + getDataLength();
}

@Override
public byte getKey() {
return isString ? Zchars.Z_BIGFIELD_QUOTED : Zchars.Z_BIGFIELD_HEX;
}

@Override
public int getValue() {
return 0;
}

@Override
public boolean isBigField() {
return true;
}

@Override
public BlockIterator iterator() {
// FIXME - this needs implementing, should ByteStrings be BlockIterable?
return BlockIterator.EMPTY;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package net.zscript.javaclient.commandPaths;

import net.zscript.tokenizer.BlockIterator;
import net.zscript.tokenizer.ZscriptField;
import net.zscript.util.ByteString;
import net.zscript.util.ByteString.ByteStringBuilder;

public class NumberField implements ZscriptField, ByteString.ByteAppendable {
private byte key;
private int value;

public NumberField(byte key, int value) {
this.key = key;
this.value = value;
}

@Override
public byte getKey() {
return key;
}

@Override
public int getValue() {
return value;
}

@Override
public boolean isBigField() {
return false;
}

@Override
public BlockIterator iterator() {
return BlockIterator.EMPTY;
}

@Override
public void appendTo(ByteStringBuilder builder) {
append(key, value, builder);
}

public static void append(byte key, int value, ByteStringBuilder builder) {
builder.appendByte(key).appendNumeric16(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import static java.util.Collections.emptyList;

import net.zscript.model.components.Zchars;
import net.zscript.tokenizer.BlockIterator;
import net.zscript.tokenizer.TokenBuffer;
import net.zscript.tokenizer.TokenBufferIterator;
import net.zscript.tokenizer.ZscriptExpression;
Expand Down Expand Up @@ -39,11 +38,7 @@ public static ZscriptFieldSet fromTokens(TokenBuffer.TokenReader.ReadToken start
for (Optional<TokenBuffer.TokenReader.ReadToken> opt = iterator.next(); opt.filter(t -> !t.isMarker()).isPresent(); opt = iterator.next()) {
TokenBuffer.TokenReader.ReadToken token = opt.get();
if (Zchars.isBigField(token.getKey())) {
ByteStringBuilder builder = ByteString.builder();
for (BlockIterator iter = token.blockIterator(); iter.hasNext(); ) {
builder.appendRaw(iter.nextContiguous());
}
bigFields.add(new BigField(builder.build(), token.getKey() == Zchars.Z_BIGFIELD_QUOTED));
bigFields.add(new BigField(ByteString.from(token.blockIterator()), token.getKey() == Zchars.Z_BIGFIELD_QUOTED));
} else {
if (fields[token.getKey() - 'A'] != -1 || token.getDataSize() > 2 || !Zchars.isNumericKey(token.getKey())) {
hasClash = true;
Expand Down Expand Up @@ -120,11 +115,11 @@ public ByteString getBigFieldAsByteString() {
@Override
public void appendTo(ByteStringBuilder builder) {
if (fields['Z' - 'A'] != -1) {
builder.appendByte(Zchars.Z_CMD).appendNumeric16(fields['Z' - 'A']);
NumberField.append(Zchars.Z_CMD, fields['Z' - 'A'], builder);
}
for (int i = 0; i < fields.length; i++) {
if (i != 'Z' - 'A' && fields[i] != -1) {
builder.appendByte((byte) (i + 'A')).appendNumeric16(fields[i]);
if (i + 'A' != 'Z' && fields[i] != -1) {
NumberField.append((byte) (i + 'A'), fields[i], builder);
}
}
for (BigField big : bigFields) {
Expand All @@ -146,7 +141,7 @@ public int getBufferLength() {
}
}
for (BigField big : bigFields) {
length += big.getDataLength() + 2;
length += big.getBufferLength();
}
return length;
}
Expand All @@ -156,31 +151,10 @@ public OptionalInt getField(byte key) {
return fields[key - 'A'] == -1 ? OptionalInt.empty() : OptionalInt.of(fields[key - 'A']);
}

// FIXME - this needs externalizing
@Override
public Optional<? extends ZscriptField> getField2(byte key) {
public Optional<? extends ZscriptField> getZscriptField(byte key) {
int v = fields[key - 'A'];
return Optional.ofNullable(v != -1 ? new ZscriptField() {
@Override
public byte getKey() {
return key;
}

@Override
public int getValue() {
return v;
}

@Override
public boolean isBigField() {
return false;
}

@Override
public BlockIterator iterator() {
return null;
}
} : null);
return Optional.ofNullable(v != -1 ? new NumberField(key, v) : null);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public OptionalInt getField(final byte key) {
}

@Override
public Optional<? extends ZscriptField> getField2(byte key) {
return expression.getField2(key);
public Optional<? extends ZscriptField> getZscriptField(byte key) {
return expression.getZscriptField(key);
}

@Override
Expand All @@ -59,6 +59,12 @@ public boolean hasBigField() {
return expression.hasBigField();
}

/**
* Produces a BlockIterator that iterates over multiple big-field items appearing in a single expression, including any extension tokens, thus providing access to all the
* big-field bytes.
*
* @return fully big-field-aware data iterator
*/
public BlockIterator getBigField() {
return expression.getBigField();
}
Expand All @@ -82,12 +88,19 @@ public boolean status(final byte status) {
return false;
}

public OptIterator<ZscriptTokenField> fieldIterator() {
/**
* Returns an iterator that supplies ZscriptField objects representing the fields (big-fields and numeric) in the current ZscriptExpression.
* <p/>
* Note: relies on {@link ZscriptTokenExpression#iteratorToMarker()} to supply tokens, which should skip extension tokens correctly.
*
* @return OptIterator for all the fields in this expression
*/
public OptIterator<ZscriptField> fieldIterator() {
return new OptIterator<>() {
final OptIterator<ReadToken> iter = expression.iteratorToMarker();

@Override
public Optional<ZscriptTokenField> next() {
public Optional<ZscriptField> next() {
return iter.next().map(ZscriptTokenField::new);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
import net.zscript.javareceiver.core.CommandOutStream;
import net.zscript.javareceiver.execution.CommandContext;
import net.zscript.model.components.Zchars;
import net.zscript.tokenizer.ZscriptTokenField;
import net.zscript.tokenizer.ZscriptField;
import net.zscript.util.OptIterator;

public class ZscriptEchoCommand {

public static void execute(CommandContext ctx) {
CommandOutStream out = ctx.getOutStream();
OptIterator<ZscriptTokenField> iterator = ctx.fieldIterator();
for (Optional<ZscriptTokenField> opt = iterator.next(); opt.isPresent(); opt = iterator.next()) {
ZscriptTokenField field = opt.get();
CommandOutStream out = ctx.getOutStream();
OptIterator<ZscriptField> iterator = ctx.fieldIterator();
for (Optional<ZscriptField> opt = iterator.next(); opt.isPresent(); opt = iterator.next()) {
ZscriptField field = opt.get();
if (field.getKey() == Zchars.Z_STATUS) {
int status = field.getValue();
ctx.status((byte) status);
Expand All @@ -25,5 +25,4 @@ public static void execute(CommandContext ctx) {
}
}
}

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package net.zscript.javareceiver.modules.core;

import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.UUID;

import net.zscript.javareceiver.execution.CommandContext;
import net.zscript.model.components.ZscriptStatus;

public class ZscriptGuidCommand {
private UUID uuid = null;
private static final int GUID_LENGTH = 16;
private UUID uuid = null;

public void fetch(CommandContext ctx) {
if (uuid == null) {
Expand All @@ -18,23 +18,15 @@ public void fetch(CommandContext ctx) {
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
ctx.getOutStream().writeBig(bb.array());

}
}

public void set(CommandContext ctx) {
if (ctx.getBigFieldSize() != 16) {
if (ctx.getBigFieldSize() != GUID_LENGTH) {
ctx.status(ZscriptStatus.VALUE_OUT_OF_RANGE);
} else {
byte[] data = new byte[16];
int i = 0;
for (Iterator<Byte> iterator = ctx.getBigField(); iterator.hasNext(); ) {
byte b = iterator.next();
data[i++] = b;
}
ByteBuffer bb = ByteBuffer.wrap(data);
ByteBuffer bb = ByteBuffer.wrap(ctx.getBigFieldData());
uuid = new UUID(bb.getLong(), bb.getLong());
}
}

}
Loading

0 comments on commit 659600a

Please sign in to comment.