Impl variable length binary struct. Data will now be shifted to the correct possitions
This commit is contained in:
parent
bae988e8dd
commit
3f21caa35b
7 changed files with 77 additions and 45 deletions
|
|
@ -45,21 +45,7 @@ public class ByteUtil {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new sub byte from index and with a length and shifts the data to the left
|
* Creates a new sub byte from MSB to the given length
|
||||||
*
|
|
||||||
* @param data is the byte data
|
|
||||||
* @param index is the bit index, valid values 0-7
|
|
||||||
* @param length is the length of bits to return, valid values 1-8
|
|
||||||
* @return a new byte containing a sub byte defined by the index and length
|
|
||||||
*/
|
|
||||||
public static byte getShiftedBits(byte data, int index, int length){
|
|
||||||
int ret = 0xFF & getBits(data, index, length);
|
|
||||||
ret = ret >>> index+1-length;
|
|
||||||
return (byte) ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new sub byte from index and with the given length length
|
|
||||||
*
|
*
|
||||||
* @param data is the byte data
|
* @param data is the byte data
|
||||||
* @param length is the length of bits to return, valid values 1-8
|
* @param length is the length of bits to return, valid values 1-8
|
||||||
|
|
@ -83,7 +69,21 @@ public class ByteUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new sub byte array with only the given length of bits from the data array.
|
* Creates a new sub byte from index and with a length and shifts the data to the left
|
||||||
|
*
|
||||||
|
* @param data is the byte data
|
||||||
|
* @param index is the bit index, valid values 0-7
|
||||||
|
* @param length is the length of bits to return, valid values 1-8
|
||||||
|
* @return a new byte containing a sub byte defined by the index and length
|
||||||
|
*/
|
||||||
|
public static byte getShiftedBits(byte data, int index, int length){
|
||||||
|
int ret = 0xFF & getBits(data, index, length);
|
||||||
|
ret = ret >>> index+1-length;
|
||||||
|
return (byte) ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new sub byte array with only the given length of bits from the LSB.
|
||||||
*
|
*
|
||||||
* @param data is the byte data array
|
* @param data is the byte data array
|
||||||
* @param length is the length of bits to return
|
* @param length is the length of bits to return
|
||||||
|
|
@ -127,6 +127,32 @@ public class ByteUtil {
|
||||||
return (byte) BYTE_MASK[index][length];
|
return (byte) BYTE_MASK[index][length];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shifts a whole byte array to the left by the specified amount.
|
||||||
|
*
|
||||||
|
* @param data the array to be shifted
|
||||||
|
* @param shiftBy the amount to shift. Currently only supports maximum value of 8
|
||||||
|
* @return same data reference as the data input
|
||||||
|
*/
|
||||||
|
public static byte[] shiftLeft(byte[] data, int shiftBy) {
|
||||||
|
if(0 > shiftBy || shiftBy > 8)
|
||||||
|
throw new IllegalArgumentException("Invalid shiftBy argument, allowed values: 0-8");
|
||||||
|
if (shiftBy == 0)
|
||||||
|
return data;
|
||||||
|
|
||||||
|
byte rest = 0;
|
||||||
|
for (int i=0; i<data.length; ++i){
|
||||||
|
rest = (byte)(getBits(data[i], shiftBy-1, shiftBy) << 8 - shiftBy);
|
||||||
|
data[i] >>>= shiftBy;
|
||||||
|
if(i != 0)
|
||||||
|
data[i-1] |= rest;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Presents a binary array in HEX and ASCII
|
* Presents a binary array in HEX and ASCII
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -361,24 +361,10 @@ public class Converter {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
switch (b.length){
|
switch (b.length){
|
||||||
default:
|
default:
|
||||||
case 4:
|
case 4: i |= 0xFF000000 & (b[3] << 24);
|
||||||
i |= 0xFF000000 & (b[0] << 24);
|
case 3: i |= 0x00FF0000 & (b[2] << 16);
|
||||||
i |= 0x00FF0000 & (b[1] << 16);
|
case 2: i |= 0x0000FF00 & (b[1] << 8);
|
||||||
i |= 0x0000FF00 & (b[2] << 8);
|
case 1: i |= 0x000000FF & b[0];
|
||||||
i |= 0x000000FF & b[3];
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
i |= 0x00FF0000 & (b[0] << 16);
|
|
||||||
i |= 0x0000FF00 & (b[1] << 8);
|
|
||||||
i |= 0x000000FF & b[2];
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
i |= 0x0000FF00 & (b[0] << 8);
|
|
||||||
i |= 0x000000FF & b[1];
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
i |= 0x000000FF & b[0];
|
|
||||||
break;
|
|
||||||
case 0: break;
|
case 0: break;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ public class BinaryFieldData {
|
||||||
else if (field.getType() == Integer.class || field.getType() == int.class)
|
else if (field.getType() == Integer.class || field.getType() == int.class)
|
||||||
field.set(obj, Converter.toInt(data));
|
field.set(obj, Converter.toInt(data));
|
||||||
else if (field.getType() == String.class)
|
else if (field.getType() == String.class)
|
||||||
field.set(obj, new String(data, StandardCharsets.ISO_8859_1));
|
field.set(obj, new String(ByteUtil.getReverseByteOrder(data), StandardCharsets.ISO_8859_1));
|
||||||
else
|
else
|
||||||
throw new UnsupportedOperationException("Unsupported BinaryStruct field class: "+ field.getClass());
|
throw new UnsupportedOperationException("Unsupported BinaryStruct field class: "+ field.getClass());
|
||||||
} catch (IllegalAccessException e){
|
} catch (IllegalAccessException e){
|
||||||
|
|
|
||||||
|
|
@ -77,20 +77,23 @@ public class BinaryStructInputStream {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
byte[] valueData = new byte[(int) Math.ceil(field.getBitLength(struct) / 8.0)];
|
byte[] valueData = new byte[(int) Math.ceil(field.getBitLength(struct) / 8.0)];
|
||||||
int fieldReadLength = 0;
|
int fieldReadLength = 0; // How much we have read so far
|
||||||
|
int shiftBy = (dataBitIndex+1 + field.getBitLength(struct)) % 8;
|
||||||
|
|
||||||
|
|
||||||
// Parse value
|
// Parse value
|
||||||
for (int valueDataIndex = 0; valueDataIndex < valueData.length; ++valueDataIndex) {
|
for (int valueDataIndex=valueData.length-1; valueDataIndex >= 0 ; --valueDataIndex) {
|
||||||
if (dataBitIndex < 0) { // Read new data?
|
if (dataBitIndex < 0) { // Read new data?
|
||||||
data = (byte) in.read();
|
data = (byte) in.read();
|
||||||
dataBitIndex = 7;
|
dataBitIndex = 7;
|
||||||
}
|
}
|
||||||
int bitLength = Math.min(dataBitIndex + 1, field.getBitLength(struct) - fieldReadLength);
|
int subBitLength = Math.min(dataBitIndex + 1, field.getBitLength(struct) - fieldReadLength);
|
||||||
valueData[valueDataIndex] = ByteUtil.getShiftedBits(data, dataBitIndex, bitLength);
|
valueData[valueDataIndex] = ByteUtil.getBits(data, dataBitIndex, subBitLength);
|
||||||
fieldReadLength += bitLength;
|
fieldReadLength += subBitLength;
|
||||||
dataBitIndex -= bitLength;
|
dataBitIndex -= subBitLength;
|
||||||
}
|
}
|
||||||
// Set value
|
// Set value
|
||||||
|
ByteUtil.shiftLeft(valueData, shiftBy); // shift data so that LSB is at the beginning
|
||||||
field.setByteValue(struct, valueData);
|
field.setByteValue(struct, valueData);
|
||||||
totalReadLength += fieldReadLength;
|
totalReadLength += fieldReadLength;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,4 +99,21 @@ public class ByteUtilTest {
|
||||||
"024 00 00 00 00 00 00 00 00 '........'",
|
"024 00 00 00 00 00 00 00 00 '........'",
|
||||||
ByteUtil.toFormattedString(data3));
|
ByteUtil.toFormattedString(data3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shiftLeft(){
|
||||||
|
assertArrayEquals( new byte[]{},
|
||||||
|
ByteUtil.shiftLeft(new byte[]{}, 4));
|
||||||
|
assertArrayEquals( new byte[]{0b0000_0001},
|
||||||
|
ByteUtil.shiftLeft(new byte[]{0b0000_0001}, 0));
|
||||||
|
assertArrayEquals( new byte[]{0b0000_0001},
|
||||||
|
ByteUtil.shiftLeft(new byte[]{0b0001_0000}, 4));
|
||||||
|
assertArrayEquals( new byte[]{0b0001_0001, 0b0000_0000},
|
||||||
|
ByteUtil.shiftLeft(new byte[]{0b0001_0000, 0b0000_0001}, 4));
|
||||||
|
assertArrayEquals( new byte[]{0b0100_1001, 0b0000_0001},
|
||||||
|
ByteUtil.shiftLeft(new byte[]{0b0111_1111, 0b0101_0010}, 6));
|
||||||
|
assertArrayEquals( new byte[]{0b0000_0001,0b0000_0001,0b0000_0001,0b0000_0001},
|
||||||
|
ByteUtil.shiftLeft(new byte[]{0b0001_0000,0b0001_0000,0b0001_0000,0b0001_0000}, 4));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,11 +84,11 @@ public class ConverterTest {
|
||||||
public void byteArrayToInt(){
|
public void byteArrayToInt(){
|
||||||
assertEquals(0, Converter.toInt(new byte[]{}));
|
assertEquals(0, Converter.toInt(new byte[]{}));
|
||||||
assertEquals(1, Converter.toInt(new byte[]{0b0000_0001}));
|
assertEquals(1, Converter.toInt(new byte[]{0b0000_0001}));
|
||||||
assertEquals(1, Converter.toInt(new byte[]{0x00,0x01}));
|
assertEquals(1, Converter.toInt(new byte[]{0x01,0x00}));
|
||||||
assertEquals(256, Converter.toInt(new byte[]{0x00,0x01,0x00}));
|
assertEquals(256, Converter.toInt(new byte[]{0x00,0x01,0x00}));
|
||||||
assertEquals(-1, Converter.toInt(new byte[]{(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF}));
|
assertEquals(-1, Converter.toInt(new byte[]{(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF}));
|
||||||
assertEquals(Integer.MAX_VALUE, Converter.toInt(new byte[]{(byte)0x7F,(byte)0xFF,(byte)0xFF,(byte)0xFF}));
|
assertEquals(Integer.MAX_VALUE, Converter.toInt(new byte[]{(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0x7F}));
|
||||||
assertEquals(Integer.MAX_VALUE, Converter.toInt(new byte[]{(byte)0x7F,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF}));
|
assertEquals(Integer.MAX_VALUE, Converter.toInt(new byte[]{(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0x7F, (byte)0xFF,(byte)0xFF}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ public class BinaryStructInputStreamTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add full non lined length support
|
// TODO: add full non lined length support
|
||||||
// @Test
|
@Test
|
||||||
public void nonLinedLength2(){
|
public void nonLinedLength2(){
|
||||||
BinaryTestStruct struct = new BinaryTestStruct() {
|
BinaryTestStruct struct = new BinaryTestStruct() {
|
||||||
@BinaryField(index=1, length=12)
|
@BinaryField(index=1, length=12)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue