BiteUtil makes more sense now as index is counted from LSB and length towards MSB

This commit is contained in:
Ziver Koc 2024-09-04 03:24:58 +02:00
parent c45809048a
commit 3cd3a2fc7c
7 changed files with 148 additions and 67 deletions

View file

@ -33,20 +33,20 @@ import zutil.converter.Converter;
*/
public class ByteUtil {
/** Bitmask array used by utility functions **/
private static final int[][] BYTE_MASK = new int[][]{
{0b0000_0001},
{0b0000_0010, 0b0000_0011},
{0b0000_0100, 0b0000_0110, 0b0000_0111},
{0b0000_1000, 0b0000_1100, 0b0000_1110, 0b0000_1111},
{0b0001_0000, 0b0001_1000, 0b0001_1100, 0b0001_1110, 0b0001_1111},
{0b0010_0000, 0b0011_0000, 0b0011_1000, 0b0011_1100, 0b0011_1110, 0b0011_1111},
{0b0100_0000, 0b0110_0000, 0b0111_0000, 0b0111_1000, 0b0111_1100, 0b0111_1110, 0b0111_1111},
{0b1000_0000, 0b1100_0000, 0b1110_0000, 0b1111_0000, 0b1111_1000, 0b1111_1100, 0b1111_1110, 0b1111_1111}
private static final int[/*index*/][/*length*/] BYTE_MASK = new int[][]{
{0b0000_0001, 0b0000_0011, 0b0000_0111, 0b0000_1111, 0b0001_1111, 0b0011_1111, 0b0111_1111, 0b1111_1111},
{0b0000_0010, 0b0000_0110, 0b0000_1110, 0b0001_1110, 0b0011_1110, 0b0111_1110, 0b1111_1110},
{0b0000_0100, 0b0000_1100, 0b0001_1100, 0b0011_1100, 0b0111_1100, 0b1111_1100},
{0b0000_1000, 0b0001_1000, 0b0011_1000, 0b0111_1000, 0b1111_1000},
{0b0001_0000, 0b0011_0000, 0b0111_0000, 0b1111_0000},
{0b0010_0000, 0b0110_0000, 0b1110_0000},
{0b0100_0000, 0b1100_0000},
{0b1000_0000},
};
/**
* Creates a new sub byte from index and with the given length length
* Creates a new sub byte from index and with the given length
*
* @param data is the byte data
* @param index is the bit index, valid values 0-7
@ -58,7 +58,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 index and with a length and shifts the data all the way to the right (LSB)
*
* @param data is the byte data
* @param index is the bit index, valid values 0-7
@ -67,7 +67,7 @@ public class ByteUtil {
*/
public static byte getShiftedBits(byte data, int index, int length) {
int ret = 0xFF & getBits(data, index, length);
ret = ret >>> index+1-length;
ret = ret >>> index;
return (byte) ret;
}
@ -79,7 +79,7 @@ public class ByteUtil {
* @return a new byte containing a sub byte defined by the index and length
*/
public static byte getBits(byte data, int length) {
return getBits(data, length-1, length);
return getBits(data, 0, length);
}
/**
@ -105,7 +105,7 @@ public class ByteUtil {
* @return a new byte containing a sub byte defined by the index and length
*/
public static byte getBitsMSB(byte data, int length) {
return getShiftedBits(data, 7, length);
return getShiftedBits(data, 8-length, length);
}
/**
@ -119,7 +119,7 @@ public class ByteUtil {
byte[] dest = new byte[data.length];
if (data.length > 0)
for (int i=0; i<data.length; ++i)
dest[dest.length-1-i] = data[i];
dest[dest.length - 1 - i] = data[i];
return dest;
}
@ -127,26 +127,27 @@ public class ByteUtil {
* Returns a byte bitmask
*
* @param index start index of the mask, valid values 0-7
* @param length length of mask from index, valid values 1-8 depending on index
* @param length length of mask from the given index, valid values 1-8 depending on index
*/
public static byte getBitMask(int index, int length) {
--length;
if (0 > index || index > 7)
throw new IllegalArgumentException("Invalid index argument, allowed values: 0-7");
if (length < 0 || index-length < 0)
throw new IllegalArgumentException("Invalid length argument: " + length + ", allowed values: 1 to " + (index+1) + " for index " + index);
throw new IllegalArgumentException("Invalid index argument " + index + ", allowed values: 0-7");
if (1 > length || length > 8 - index)
throw new IllegalArgumentException("Invalid length argument: " + length + ", allowed values: 1 to " + (8 - index) + " for index " + index);
--length;
return (byte) BYTE_MASK[index][length];
}
/**
* Shifts a whole byte array to the left by the specified amount.
* Shifts a whole byte array to the right towards the LSB 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) {
public static byte[] shiftRight(byte[] data, int shiftBy) {
if (0 > shiftBy || shiftBy > 8)
throw new IllegalArgumentException("Invalid shiftBy(" + shiftBy + ") argument, allowed values: 0-8");
if (shiftBy == 0)
@ -154,8 +155,9 @@ public class ByteUtil {
byte rest;
for (int i=0; i<data.length; ++i) {
rest = (byte)(getBits(data[i], shiftBy-1, shiftBy) << 8 - shiftBy);
data[i] = (byte)((data[i]&0xFF) >>> shiftBy);
rest = getBits(data[i], 0, shiftBy);
rest = (byte)(rest << 8 - shiftBy);
data[i] = (byte)((data[i] & 0xFF) >>> shiftBy);
if (i != 0)
data[i-1] |= rest;
}
@ -164,13 +166,13 @@ public class ByteUtil {
}
/**
* Shifts a whole byte array to the right by the specified amount.
* Shifts a whole byte array to the left towards the MSB 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[] shiftRight(byte[] data, int shiftBy) {
public static byte[] shiftLeft(byte[] data, int shiftBy) {
if (0 > shiftBy || shiftBy > 8)
throw new IllegalArgumentException("Invalid shiftBy(" + shiftBy + ") argument, allowed values: 0-8");
if (shiftBy == 0)
@ -193,7 +195,7 @@ public class ByteUtil {
* Presents a binary array in HEX and ASCII
*
* @param data The source binary data to format
* @return A multiline String with human readable HEX and ASCII
* @return A multiline String with human-readable HEX and ASCII
*/
public static String toFormattedString(byte[] data) {
return toFormattedString(data, 0, data.length);

View file

@ -115,12 +115,12 @@ public class BinaryStructInputStream extends InputStream{
dataBitIndex = 7;
}
int subBitLength = Math.min(dataBitIndex + 1, field.getBitLength(struct) - fieldReadLength);
valueData[valueDataIndex] = ByteUtil.getBits(data, dataBitIndex, subBitLength);
valueData[valueDataIndex] = ByteUtil.getBits(data, dataBitIndex - (subBitLength - 1), subBitLength);
fieldReadLength += subBitLength;
dataBitIndex -= subBitLength;
}
// Set value
ByteUtil.shiftLeft(valueData, shiftBy); // shift data so that LSB is at the beginning
ByteUtil.shiftRight(valueData, shiftBy); // shift data so that LSB is at the beginning
field.setByteValue(struct, valueData);
}
}

View file

@ -103,15 +103,15 @@ public class BinaryStructOutputStream extends OutputStream {
} else {
int fieldBitLength = field.getBitLength(struct);
byte[] data = field.getByteValue(struct);
data = ByteUtil.shiftRight(data, ((8 - fieldBitLength % 8) % 8));
data = ByteUtil.shiftLeft(data, ((8 - fieldBitLength % 8) % 8));
for (int i=(int)Math.ceil(fieldBitLength/8.0)-1; fieldBitLength>0; fieldBitLength-=8, --i) {
for (int i=(int)Math.ceil(fieldBitLength / 8.0) - 1; fieldBitLength>0; fieldBitLength-=8, --i) {
byte b = data[i];
if (restBitLength == 0 && fieldBitLength >= 8)
out.write(0xFF & b);
else {
b = (byte) ((b & 0xFF) >> restBitLength);
b &= ByteUtil.getBitMask(7 - restBitLength, fieldBitLength);
b &= ByteUtil.getBitMask(8 - restBitLength - fieldBitLength, fieldBitLength);
rest |= b;
restBitLength += fieldBitLength;
if (restBitLength >= 8)