DSL signed 24bit interger?
mimil opened this issue · 4 comments
Hello,
from what I read in your documentation, I do not see the way to map a primary type on an abritrary bit/byte lenght. Like how could I do for:
- 24 bits signed integer (so stored on 3 bytes)
- 23 bits signed integer (so stored on 2 bytes + 7 bits)
Every primary types should support the notation [:1..x] not only bit type, no?
Thank you for you help,
Regards,
Cedric,
JBBP allows to define custom types and process them, for instance I implemented type for reading 3 byte int values (it may contain errors in implementation because I wrote it just as example)
private static final class Int24CustomTypeProcessor implements JBBPCustomFieldTypeProcessor {
private static final String[] TYPES = new String[]{"int24"};
@Override
public String[] getCustomFieldTypes() {
return TYPES;
}
@Override
public boolean isAllowed(final JBBPFieldTypeParameterContainer fieldType, final String fieldName, final int extraData, final boolean isArray) {
return true;
}
private int readInt24(final JBBPBitInputStream in) throws IOException {
final int part1 = in.readUnsignedShort(JBBPByteOrder.BIG_ENDIAN);
final int part2 = in.readByte();
return (part1 << 8) | (part2 & 0xFF);
}
@Override
public JBBPAbstractField readCustomFieldType(final JBBPBitInputStream in,
final JBBPBitOrder bitOrder,
final int parserFlags,
final JBBPFieldTypeParameterContainer customTypeFieldInfo,
final JBBPNamedFieldInfo fieldName,
final int extraData,
final boolean readWholeStream,
final int arrayLength) throws IOException {
final String name = customTypeFieldInfo.getTypeName();
if (name.equals("int24")) {
if (arrayLength < 0) {
return new JBBPFieldInt(fieldName, readInt24(in));
} else if (readWholeStream) {
int[] buffer = new int[1024];
int pos = 0;
while (in.hasAvailableData()) {
final int next = readInt24(in);
if (buffer.length == pos) {
final int[] newbuffer = new int[buffer.length << 1];
System.arraycopy(buffer, 0, newbuffer, 0, buffer.length);
buffer = newbuffer;
}
buffer[pos++] = (int) next;
}
if (buffer.length == pos) {
return new JBBPFieldArrayInt(fieldName, buffer);
}
final int[] result = new int[pos];
System.arraycopy(buffer, 0, result, 0, pos);
return new JBBPFieldArrayInt(fieldName, result);
} else {
final int[] array = new int[arrayLength];
for (int i = 0; i < arrayLength; i++) {
array[i] = readInt24(in);
}
return new JBBPFieldArrayInt(fieldName, array);
}
} else {
throw new Error("Unexpected type");
}
}
}
public static void main(String... args) throws Exception {
final JBBPParser parser = JBBPParser.prepare("int24 v1; byte v2;",new Int24CustomTypeProcessor());
final JBBPFieldStruct struct = parser.parse(new byte[]{0x01,0x02,0x03,0x04});
System.out.println("v1 = 0x"+Integer.toHexString(struct.findFieldForNameAndType("v1", JBBPFieldInt.class).getAsInt()));
System.out.println("v2 = 0x"+Integer.toHexString(struct.findFieldForNameAndType("v2", JBBPFieldByte.class).getAsInt()));
}
as result it will print
v1 = 0x10203
v2 = 0x4
Hi,
thank you for this fast reply, I will use your sample code.
But do you think it makes sense to support the [:..x] notation? If I look to another java binary framework (preon), it supports such kind of feature:
@Purpose("The offset of the byte where the bitmap data can be found.")
@BoundNumber(size = "32")
private long bitmapDataOffset;
Regards,
Cedric
may be preon is more powerful framework and covers bigger number of cases, I developed JBBP for my own purposes and for such cases implemented points to extend behavior
I have added test case for three byte integer
Thanks for the other users for sharing the testcase source code in github.
it was more a question than a request to you to think about this feature. I am no expert de binary data structures, but I think (if someone/or me) wants to provide a pull request on this topic, it could be nice to have your point of view.
It is alreay a good feature to support adding new types the way you did it!
Cedric,