mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GT-3512 cleanup DataConverter interface and BE/LE impls
This commit is contained in:
parent
283e148b26
commit
b6bea0fb39
33 changed files with 539 additions and 666 deletions
|
@ -16,6 +16,7 @@
|
|||
package ghidra.util;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Helper class to convert a byte array to Java primitives and primitives to a
|
||||
|
@ -27,42 +28,26 @@ import java.math.BigInteger;
|
|||
public class BigEndianDataConverter implements DataConverter {
|
||||
public static final BigEndianDataConverter INSTANCE = new BigEndianDataConverter();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructor for BigEndianDataConverter.
|
||||
* Don't use this constructor to create new instances of this class. Use the static {@link #INSTANCE} instead.
|
||||
*/
|
||||
public BigEndianDataConverter() {
|
||||
// empty
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getShort(byte[])
|
||||
*/
|
||||
public final short getShort(byte[] b) {
|
||||
return getShort(b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getShort(byte[], int)
|
||||
*/
|
||||
@Override
|
||||
public short getShort(byte[] b, int offset) {
|
||||
Objects.checkFromIndexSize(offset, Short.BYTES, b.length);
|
||||
|
||||
return (short) (((b[offset] & 0xff) << 8) | (b[offset + 1] & 0xff));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getInt(byte[])
|
||||
*/
|
||||
public final int getInt(byte[] b) {
|
||||
return getInt(b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getInt(byte[], int)
|
||||
*/
|
||||
@Override
|
||||
public int getInt(byte[] b, int offset) {
|
||||
Objects.checkFromIndexSize(offset, Integer.BYTES, b.length);
|
||||
|
||||
int v = b[offset];
|
||||
for (int i = 1; i < 4; i++) {
|
||||
v = (v << 8) | (b[offset + i] & 0xff);
|
||||
|
@ -70,17 +55,10 @@ public class BigEndianDataConverter implements DataConverter {
|
|||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getLong(byte[])
|
||||
*/
|
||||
public final long getLong(byte[] b) {
|
||||
return getLong(b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getLong(byte[], int)
|
||||
*/
|
||||
@Override
|
||||
public long getLong(byte[] b, int offset) {
|
||||
Objects.checkFromIndexSize(offset, Long.BYTES, b.length);
|
||||
|
||||
long v = b[offset];
|
||||
for (int i = 1; i < 8; i++) {
|
||||
v = (v << 8) | (b[offset + i] & 0xff);
|
||||
|
@ -88,20 +66,11 @@ public class BigEndianDataConverter implements DataConverter {
|
|||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#getValue(byte[], int)
|
||||
*/
|
||||
public long getValue(byte[] b, int size) {
|
||||
return getValue(b, 0, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#getValue(byte[], int, int)
|
||||
*/
|
||||
@Override
|
||||
public long getValue(byte[] b, int offset, int size) {
|
||||
if (size > 8) {
|
||||
throw new IndexOutOfBoundsException("size exceeds sizeof long: " + size);
|
||||
}
|
||||
Objects.checkFromIndexSize(offset, size, b.length);
|
||||
Objects.checkIndex(size, Long.BYTES + 1);
|
||||
|
||||
long val = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
val = (val << 8) | (b[offset + i] & 0xff);
|
||||
|
@ -109,16 +78,10 @@ public class BigEndianDataConverter implements DataConverter {
|
|||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final BigInteger getBigInteger(byte[] b, int size, boolean signed) {
|
||||
return getBigInteger(b, 0, size, signed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final BigInteger getBigInteger(byte[] b, int offset, int size, boolean signed) {
|
||||
if ((size + offset) > b.length) {
|
||||
throw new IndexOutOfBoundsException("insufficient bytes");
|
||||
}
|
||||
Objects.checkFromIndexSize(offset, size, b.length);
|
||||
|
||||
if (offset != 0 || size != b.length) {
|
||||
int index = 0;
|
||||
if (!signed && b[offset] < 0) {
|
||||
|
@ -132,39 +95,25 @@ public class BigEndianDataConverter implements DataConverter {
|
|||
}
|
||||
else if (!signed && b[0] < 0) {
|
||||
// keep unsigned - prepend 0 byte
|
||||
byte[] bytes = new byte[size+1];
|
||||
byte[] bytes = new byte[size + 1];
|
||||
System.arraycopy(b, 0, bytes, 1, size);
|
||||
b = bytes;
|
||||
}
|
||||
return new BigInteger(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getBytes(short, byte[])
|
||||
*/
|
||||
public final void getBytes(short value, byte[] b) {
|
||||
getBytes(value, b, 0);
|
||||
}
|
||||
@Override
|
||||
public void putShort(byte[] b, int offset, short value) {
|
||||
Objects.checkFromIndexSize(offset, Short.BYTES, b.length);
|
||||
|
||||
/**
|
||||
* @see DataConverter#getBytes(short, byte[], int)
|
||||
*/
|
||||
public void getBytes(short value, byte[] b, int offset) {
|
||||
b[offset] = (byte) (value >> 8);
|
||||
b[offset + 1] = (byte) (value & 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getBytes(int, byte[])
|
||||
*/
|
||||
public final void getBytes(int value, byte[] b) {
|
||||
getBytes(value, b, 0);
|
||||
}
|
||||
@Override
|
||||
public void putInt(byte[] b, int offset, int value) {
|
||||
Objects.checkFromIndexSize(offset, Integer.BYTES, b.length);
|
||||
|
||||
/**
|
||||
* @see DataConverter#getBytes(int, byte[], int)
|
||||
*/
|
||||
public void getBytes(int value, byte[] b, int offset) {
|
||||
b[offset + 3] = (byte) (value);
|
||||
for (int i = 2; i >= 0; i--) {
|
||||
value >>= 8;
|
||||
|
@ -172,113 +121,20 @@ public class BigEndianDataConverter implements DataConverter {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getBytes(long, byte[])
|
||||
*/
|
||||
public final void getBytes(long value, byte[] b) {
|
||||
getBytes(value, 8, b, 0);
|
||||
}
|
||||
@Override
|
||||
public void putValue(long value, int size, byte[] b, int offset) {
|
||||
Objects.checkFromIndexSize(offset, size, b.length);
|
||||
Objects.checkIndex(size, Long.BYTES + 1);
|
||||
|
||||
/**
|
||||
* @see DataConverter#getBytes(long, byte[], int)
|
||||
*/
|
||||
public void getBytes(long value, byte[] b, int offset) {
|
||||
getBytes(value, 8, b, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#getBytes(long, int, byte[], int)
|
||||
*/
|
||||
public void getBytes(long value, int size, byte[] b, int offset) {
|
||||
for (int i = size - 1; i >= 0; i--) {
|
||||
b[offset + i] = (byte) value;
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#putInt(byte[], int, int)
|
||||
*/
|
||||
public final void putInt(byte[] b, int offset, int value) {
|
||||
getBytes(value, b, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#putInt(byte[], int)
|
||||
*/
|
||||
public final void putInt(byte[] b, int value) {
|
||||
getBytes(value, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#putLong(byte[], int, long)
|
||||
*/
|
||||
public final void putLong(byte[] b, int offset, long value) {
|
||||
getBytes(value, b, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#putLong(byte[], long)
|
||||
*/
|
||||
public final void putLong(byte[] b, long value) {
|
||||
getBytes(value, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#putShort(byte[], int, short)
|
||||
*/
|
||||
public final void putShort(byte[] b, int offset, short value) {
|
||||
getBytes(value, b, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#putShort(byte[], short)
|
||||
*/
|
||||
public final void putShort(byte[] b, short value) {
|
||||
getBytes(value, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#getBytes(int)
|
||||
*/
|
||||
public byte[] getBytes(int value) {
|
||||
byte[] bytes = new byte[4];
|
||||
getBytes(value, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#getBytes(long)
|
||||
*/
|
||||
public byte[] getBytes(long value) {
|
||||
byte[] bytes = new byte[8];
|
||||
getBytes(value, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#getBytes(short)
|
||||
*/
|
||||
public byte[] getBytes(short value) {
|
||||
byte[] bytes = new byte[2];
|
||||
getBytes(value, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes(BigInteger value, int size) {
|
||||
byte[] bytes = new byte[size];
|
||||
putBigInteger(bytes, 0, size, value);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBytes(BigInteger value, int size, byte[] b, int offset) {
|
||||
putBigInteger(b, offset, size, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBigInteger(byte[] b, int offset, int size, BigInteger value) {
|
||||
Objects.checkFromIndexSize(offset, size, b.length);
|
||||
|
||||
int fillIndex = offset; // start fill from MSB
|
||||
int srcIndex;
|
||||
|
@ -300,9 +156,4 @@ public class BigEndianDataConverter implements DataConverter {
|
|||
System.arraycopy(valBytes, srcIndex, b, fillIndex, fillCnt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBigInteger(byte[] b, int size, BigInteger value) {
|
||||
putBigInteger(b, 0, size, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ import java.math.BigInteger;
|
|||
|
||||
/**
|
||||
*
|
||||
* Defines methods to convert byte arrays to a specific primitive Java types,
|
||||
* and to populate byte arrays from primitive Java types.
|
||||
*
|
||||
* Defines methods to convert Java numeric types to and from their
|
||||
* raw form in a byte array.
|
||||
* <p>
|
||||
*
|
||||
*/
|
||||
public interface DataConverter extends Serializable {
|
||||
|
@ -32,264 +32,466 @@ public interface DataConverter extends Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the short value from the given byte array.
|
||||
* @param b array containing bytes
|
||||
* @throws IndexOutOfBoundsException if byte array size is
|
||||
* less than 2.
|
||||
* Returns the endianess of this DataConverter instance.
|
||||
*
|
||||
* @return boolean flag, true means big-endian
|
||||
*/
|
||||
public short getShort(byte[] b);
|
||||
default boolean isBigEndian() {
|
||||
return this instanceof BigEndianDataConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the short value from the given byte array.
|
||||
* @param b array containing bytes
|
||||
* @return signed short value from the beginning of the specified array
|
||||
* @throws IndexOutOfBoundsException if byte array size is less than 2.
|
||||
*/
|
||||
default short getShort(byte[] b) {
|
||||
return getShort(b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the short value from the given byte array.
|
||||
*
|
||||
* @param b array containing bytes
|
||||
* @param offset offset into byte array for getting the short
|
||||
* @throws IndexOutOfBoundsException if byte array size is
|
||||
* less than offset+2.
|
||||
* @return signed short value
|
||||
* @throws IndexOutOfBoundsException if byte array size is less than offset+2
|
||||
*/
|
||||
public short getShort(byte[] b, int offset);
|
||||
short getShort(byte[] b, int offset);
|
||||
|
||||
/**
|
||||
* Get the int value from the given byte array.
|
||||
*
|
||||
* @param b array containing bytes
|
||||
* @throws IndexOutOfBoundsException if byte array size is
|
||||
* less than 4.
|
||||
* @return signed int value from the beginning of the specified array
|
||||
* @throws IndexOutOfBoundsException if byte array size is less than 4
|
||||
*/
|
||||
public int getInt(byte[] b);
|
||||
default int getInt(byte[] b) {
|
||||
return getInt(b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the int value from the given byte array.
|
||||
*
|
||||
* @param b array containing bytes
|
||||
* @param offset offset into byte array for getting the int
|
||||
* @throws IndexOutOfBoundsException if byte array size is
|
||||
* less than offset+4.
|
||||
* @return signed int value
|
||||
* @throws IndexOutOfBoundsException if byte array size is less than offset+4
|
||||
*/
|
||||
public int getInt(byte[] b, int offset);
|
||||
int getInt(byte[] b, int offset);
|
||||
|
||||
/**
|
||||
* Get the long value from the given byte array.
|
||||
*
|
||||
* @param b array containing bytes
|
||||
* @throws IndexOutOfBoundsException if byte array size is
|
||||
* less than 8.
|
||||
* @return signed long value from the beginning of the specified array
|
||||
* @throws IndexOutOfBoundsException if byte array size is less than 8
|
||||
*/
|
||||
public long getLong(byte[] b);
|
||||
default long getLong(byte[] b) {
|
||||
return getLong(b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the long value from the given byte array.
|
||||
*
|
||||
* @param b array containing bytes
|
||||
* @param offset offset into byte array for getting the long
|
||||
* @throws IndexOutOfBoundsException if byte array size is
|
||||
* less than offset+8.
|
||||
* @return signed long value
|
||||
* @throws IndexOutOfBoundsException if byte array size is less than offset+8
|
||||
*/
|
||||
public long getLong(byte[] b, int offset);
|
||||
long getLong(byte[] b, int offset);
|
||||
|
||||
/**
|
||||
* Get the <b>unsigned</b> value from the given byte array using the specified
|
||||
* integer size, returned as a long.
|
||||
* <p>
|
||||
* Values with a size less than sizeof(long) will <b>not</b> have their sign bit
|
||||
* extended and therefore will appear as an 'unsigned' value.
|
||||
* <p>
|
||||
* Casting the 'unsigned' long value to the correctly sized smaller
|
||||
* java primitive will cause the value to appear as a signed value.
|
||||
* <p>
|
||||
* Values of size 8 (ie. longs) will be signed.
|
||||
*
|
||||
* @param b array containing bytes
|
||||
* @param size number of bytes (1 - 8) to use from array at offset 0
|
||||
* @return unsigned value from the beginning of the specified array
|
||||
* @throws IndexOutOfBoundsException if byte array size is less than specified size
|
||||
*/
|
||||
default long getValue(byte[] b, int size) {
|
||||
return getValue(b, 0, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <b>unsigned</b> value from the given byte array using the specified
|
||||
* integer size, returned as a long.
|
||||
* <p>
|
||||
* Values with a size less than sizeof(long) will <b>not</b> have their sign bit
|
||||
* extended and therefore will appear as an 'unsigned' value.
|
||||
* <p>
|
||||
* Casting the 'unsigned' long value to the correctly sized smaller
|
||||
* java primitive will cause the value to appear as a signed value.
|
||||
* <p>
|
||||
* Values of size 8 (ie. longs) will be signed.
|
||||
*
|
||||
* @param b array containing bytes
|
||||
* @param size number of bytes (1 - 8) to use from array
|
||||
* @param offset offset into byte array for getting the long
|
||||
* @return unsigned value
|
||||
* @throws IndexOutOfBoundsException if byte array size is
|
||||
* less than offset+size or size is greater than 8 (sizeof long)
|
||||
*/
|
||||
long getValue(byte[] b, int offset, int size);
|
||||
|
||||
/**
|
||||
* Get the <b>signed</b> value from the given byte array using the specified
|
||||
* integer size, returned as a long.
|
||||
* <p>
|
||||
* Values with a size less than sizeof(long) will have their sign bit
|
||||
* extended.
|
||||
*
|
||||
* @param b array containing bytes
|
||||
* @param size number of bytes (1 - 8) to use from array at offset 0
|
||||
* @return signed value from the beginning of the specified array
|
||||
* @throws IndexOutOfBoundsException if byte array size is less than specified size
|
||||
*/
|
||||
default long getSignedValue(byte[] b, int size) {
|
||||
return getSignedValue(b, 0, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <b>signed</b> value from the given byte array using the specified
|
||||
* integer size, returned as a long.
|
||||
* <p>
|
||||
* Values with a size less than sizeof(long) will have their sign bit
|
||||
* extended.
|
||||
*
|
||||
* @param b array containing bytes
|
||||
* @param size number of bytes (1 - 8) to use from array
|
||||
* @param offset offset into byte array for getting the long
|
||||
* @return signed value
|
||||
* @throws IndexOutOfBoundsException if byte array size is
|
||||
* less than offset+size or size is greater than 8 (sizeof long)
|
||||
*/
|
||||
default long getSignedValue(byte[] b, int offset, int size) {
|
||||
long val = getValue(b, offset, size);
|
||||
|
||||
int shiftBits = (8 /*sizeof(long)*/ - size) * 8;
|
||||
|
||||
// this little bit of magic will sign-extend the value
|
||||
val = val << shiftBits;
|
||||
val = val >> shiftBits;
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value from the given byte array using the specified size.
|
||||
*
|
||||
* @param b array containing bytes
|
||||
* @param size number of bytes to use from array at offset 0
|
||||
* @param signed boolean flag indicating the value is signed
|
||||
* @return {@link BigInteger} with value
|
||||
* @throws IndexOutOfBoundsException if byte array size is
|
||||
* less than size.
|
||||
* less than size
|
||||
*/
|
||||
public long getValue(byte[] b, int size);
|
||||
default BigInteger getBigInteger(byte[] b, int size, boolean signed) {
|
||||
return getBigInteger(b, 0, size, signed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value from the given byte array using the specified size.
|
||||
*
|
||||
* @param b array containing bytes
|
||||
* @param size number of bytes to use from array
|
||||
* @param offset offset into byte array for getting the long
|
||||
* @param signed boolean flag indicating the value is signed
|
||||
* @return {@link BigInteger} with value
|
||||
* @throws IndexOutOfBoundsException if byte array size is
|
||||
* less than offset+size or size is greater than 8 (sizeof long).
|
||||
* less than offset+size
|
||||
*/
|
||||
public long getValue(byte[] b, int offset, int size);
|
||||
BigInteger getBigInteger(byte[] b, int offset, int size, boolean signed);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get the value from the given byte array using the specified size.
|
||||
* @param b array containing bytes
|
||||
* @param size number of bytes to use from array at offset 0
|
||||
* @throws IndexOutOfBoundsException if byte array size is
|
||||
* less than size.
|
||||
* Converts the short value to an array of bytes.
|
||||
*
|
||||
* @param value short value to be converted
|
||||
* @return array of bytes
|
||||
*/
|
||||
public BigInteger getBigInteger(byte[] b, int size, boolean signed);
|
||||
default byte[] getBytes(short value) {
|
||||
byte[] bytes = new byte[2];
|
||||
getBytes(value, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value from the given byte array using the specified size.
|
||||
* @param b array containing bytes
|
||||
* @param size number of bytes to use from array
|
||||
* @param offset offset into byte array for getting the long
|
||||
* @throws IndexOutOfBoundsException if byte array size is
|
||||
* less than offset+size.
|
||||
* Converts the int value to an array of bytes.
|
||||
*
|
||||
* @param value int value to be converted
|
||||
* @return array of bytes
|
||||
*/
|
||||
public BigInteger getBigInteger(byte[] b, int offset, int size, boolean signed);
|
||||
default byte[] getBytes(int value) {
|
||||
byte[] bytes = new byte[4];
|
||||
getBytes(value, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the long value to an array of bytes.
|
||||
*
|
||||
* @param value long value to be converted
|
||||
* @return array of bytes
|
||||
*/
|
||||
default byte[] getBytes(long value) {
|
||||
byte[] bytes = new byte[8];
|
||||
getBytes(value, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the value to an array of bytes.
|
||||
*
|
||||
* @param value value to be converted
|
||||
* @param size value size in bytes
|
||||
* @return array of bytes
|
||||
*/
|
||||
default byte[] getBytes(BigInteger value, int size) {
|
||||
byte[] bytes = new byte[size];
|
||||
putBigInteger(bytes, 0, size, value);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Writes a short value into a byte array.
|
||||
*
|
||||
* @param b array to contain the bytes
|
||||
* @param value the short value
|
||||
*/
|
||||
default void putShort(byte[] b, short value) {
|
||||
putShort(b, 0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a short value into the byte array at the given offset
|
||||
*
|
||||
* @param b array to contain the bytes
|
||||
* @param offset the offset into the byte array to store the value
|
||||
* @param value the short value
|
||||
*/
|
||||
default void putShort(byte[] b, int offset, short value) {
|
||||
getBytes(value, b, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a int value into a byte array.
|
||||
* <p>
|
||||
* See {@link #getBytes(int, byte[])}
|
||||
*
|
||||
* @param b array to contain the bytes
|
||||
* @param value the int value
|
||||
*/
|
||||
default void putInt(byte[] b, int value) {
|
||||
putInt(b, 0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a int value into the byte array at the given offset.
|
||||
* <p>
|
||||
* See {@link #getBytes(int, byte[], int)}
|
||||
*
|
||||
* @param b array to contain the bytes
|
||||
* @param offset the offset into the byte array to store the value
|
||||
* @param value the int value
|
||||
*/
|
||||
void putInt(byte[] b, int offset, int value);
|
||||
|
||||
/**
|
||||
* Writes a long value into a byte array.
|
||||
* <p>
|
||||
* See {@link #getBytes(long, byte[])}
|
||||
*
|
||||
* @param b array to contain the bytes
|
||||
* @param value the long value
|
||||
*/
|
||||
default void putLong(byte[] b, long value) {
|
||||
putLong(b, 0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a long value into the byte array at the given offset
|
||||
* <p>
|
||||
* See {@link #getBytes(long, byte[], int)}
|
||||
*
|
||||
* @param b array to contain the bytes
|
||||
* @param offset the offset into the byte array to store the value
|
||||
* @param value the long value
|
||||
*/
|
||||
default void putLong(byte[] b, int offset, long value) {
|
||||
putValue(value, Long.BYTES, b, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given value to bytes using the number of least significant bytes
|
||||
* specified by size.
|
||||
* <p>
|
||||
*
|
||||
* @param value value to convert to bytes
|
||||
* @param size number of least significant bytes of value to be written to the byte array
|
||||
* @param b byte array to store bytes
|
||||
* @param offset offset into byte array to put the bytes
|
||||
* @throws IndexOutOfBoundsException if (offset+size)>b.length
|
||||
*/
|
||||
void putValue(long value, int size, byte[] b, int offset);
|
||||
|
||||
/**
|
||||
* Writes a value of specified size into the byte array at the given offset.
|
||||
* <p>
|
||||
* See {@link #getBytes(BigInteger, int, byte[], int)}
|
||||
*
|
||||
* @param b array to contain the bytes at offset 0
|
||||
* @param size number of bytes to be written
|
||||
* @param value BigInteger value to convert
|
||||
*/
|
||||
default void putBigInteger(byte[] b, int size, BigInteger value) {
|
||||
putBigInteger(b, 0, size, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a value of specified size into the byte array at the given offset
|
||||
* <p>
|
||||
* See {@link #getBytes(BigInteger, int, byte[], int)}
|
||||
*
|
||||
* @param b array to contain the bytes
|
||||
* @param offset the offset into the byte array to store the value
|
||||
* @param size number of bytes to be written
|
||||
* @param value BigInteger value to convert
|
||||
*/
|
||||
public void putBigInteger(byte[] b, int offset, int size, BigInteger value);
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Converts the given value to bytes.
|
||||
* See {@link #putShort(byte[], short)}
|
||||
* @param value value to convert to bytes
|
||||
* @param b byte array to store bytes
|
||||
* @throws IndexOutOfBoundsException if b.length is not at least
|
||||
* 2.
|
||||
*/
|
||||
public void getBytes(short value, byte[] b);
|
||||
default void getBytes(short value, byte[] b) {
|
||||
getBytes(value, b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given value to bytes.
|
||||
* <p>
|
||||
* See {@link #putShort(byte[], int, short)}
|
||||
*
|
||||
* @param value value to convert to bytes
|
||||
* @param b byte array to store bytes
|
||||
* @param offset offset into byte array to put the bytes
|
||||
* @throws IndexOutOfBoundsException if (offset+2)>b.length
|
||||
*/
|
||||
public void getBytes(short value, byte[] b, int offset);
|
||||
default void getBytes(short value, byte[] b, int offset) {
|
||||
putShort(b, offset, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given value to bytes.
|
||||
* <p>
|
||||
* See {@link #putInt(byte[], int)}
|
||||
*
|
||||
* @param value value to convert to bytes
|
||||
* @param b byte array to store bytes
|
||||
* @throws IndexOutOfBoundsException if b.length is not at least
|
||||
* 4.
|
||||
*/
|
||||
public void getBytes(int value, byte[] b);
|
||||
default void getBytes(int value, byte[] b) {
|
||||
getBytes(value, b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given value to bytes.
|
||||
* <p>
|
||||
* See {@link #putInt(byte[], int)}
|
||||
*
|
||||
* @param value value to convert to bytes
|
||||
* @param b byte array to store bytes
|
||||
* @param offset offset into byte array to put the bytes
|
||||
* @throws IndexOutOfBoundsException if (offset+4)>b.length
|
||||
*/
|
||||
public void getBytes(int value, byte[] b, int offset);
|
||||
default void getBytes(int value, byte[] b, int offset) {
|
||||
putInt(b, offset, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given value to bytes.
|
||||
* <p>
|
||||
* See {@link #putLong(byte[], long)}
|
||||
*
|
||||
* @param value value to convert to bytes
|
||||
* @param b byte array to store bytes
|
||||
* @throws IndexOutOfBoundsException if b.length is not at least
|
||||
* 8.
|
||||
*/
|
||||
public void getBytes(long value, byte[] b);
|
||||
default void getBytes(long value, byte[] b) {
|
||||
getBytes(value, b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given value to bytes.
|
||||
* <p>
|
||||
* See {@link #putLong(byte[], long)}
|
||||
*
|
||||
* @param value value to convert to bytes
|
||||
* @param b byte array to store bytes
|
||||
* @param offset offset into byte array to put the bytes
|
||||
* @throws IndexOutOfBoundsException if (offset+8)>b.length
|
||||
*/
|
||||
public void getBytes(long value, byte[] b, int offset);
|
||||
default void getBytes(long value, byte[] b, int offset) {
|
||||
putLong(b, offset, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given value to bytes using the number of least significant bytes
|
||||
* specified by size.
|
||||
* <p>
|
||||
* See {@link #putValue(long, int, byte[], int)}
|
||||
*
|
||||
* @param value value to convert to bytes
|
||||
* @param size number of least significant bytes of value to be written to the byte array
|
||||
* @param b byte array to store bytes
|
||||
* @param offset offset into byte array to put the bytes
|
||||
* @throws IndexOutOfBoundsException if (offset+size)>b.length
|
||||
*/
|
||||
default void getBytes(long value, int size, byte[] b, int offset) {
|
||||
putValue(value, size, b, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given value to bytes using the number of least significant bytes
|
||||
* specified by size.
|
||||
* <p>
|
||||
* See {@link #putBigInteger(byte[], int, BigInteger)}
|
||||
*
|
||||
* @param value value to convert to bytes
|
||||
* @param size number of least significant bytes of value to be written to the byte array
|
||||
* @param b byte array to store bytes
|
||||
* @param offset offset into byte array to put the bytes
|
||||
* @throws IndexOutOfBoundsException if (offset+size)>b.length.
|
||||
*/
|
||||
public void getBytes(long value, int size, byte[] b, int offset);
|
||||
|
||||
/**
|
||||
* Converts the given value to bytes using the number of least significant bytes
|
||||
* specified by size.
|
||||
* @param value value to convert to bytes
|
||||
* @param size number of least significant bytes of value to be written to the byte array
|
||||
* @param b byte array to store bytes
|
||||
* @param offset offset into byte array to put the bytes
|
||||
* @throws IndexOutOfBoundsException if (offset+size)>b.length.
|
||||
*/
|
||||
public void getBytes(BigInteger value, int size, byte[] b, int offset);
|
||||
|
||||
/**
|
||||
* Converts the short value to an array of bytes.
|
||||
* @param value short value to be converted
|
||||
* @return array of bytes
|
||||
*/
|
||||
public byte[] getBytes(short value);
|
||||
|
||||
/**
|
||||
* Converts the int value to an array of bytes.
|
||||
* @param value int value to be converted
|
||||
* @return array of bytes
|
||||
*/
|
||||
public byte[] getBytes(int value);
|
||||
|
||||
/**
|
||||
* Converts the long value to an array of bytes.
|
||||
* @param value long value to be converted
|
||||
* @return array of bytes
|
||||
*/
|
||||
public byte[] getBytes(long value);
|
||||
|
||||
/**
|
||||
* Converts the value to an array of bytes.
|
||||
* @param value value to be converted
|
||||
* @param size value size in bytes
|
||||
* @return array of bytes
|
||||
*/
|
||||
public byte[] getBytes(BigInteger value, int size);
|
||||
|
||||
/**
|
||||
* Writes a short value into a byte array.
|
||||
* @param b array to contain the bytes;
|
||||
* @param value the short value
|
||||
*/
|
||||
public void putShort(byte[] b, short value);
|
||||
|
||||
/**
|
||||
* Writes a short value into the byte array at the given offset
|
||||
* @param b array to contain the bytes;
|
||||
* @param offset the offset into the byte array to store the value.
|
||||
* @param value the short value
|
||||
*/
|
||||
public void putShort(byte[] b, int offset, short value);
|
||||
|
||||
/**
|
||||
* Writes a int value into a byte array.
|
||||
* @param b array to contain the bytes;
|
||||
* @param value the int value
|
||||
*/
|
||||
public void putInt(byte[] b, int value);
|
||||
|
||||
/**
|
||||
* Writes a int value into the byte array at the given offset
|
||||
* @param b array to contain the bytes;
|
||||
* @param offset the offset into the byte array to store the value.
|
||||
* @param value the int value
|
||||
*/
|
||||
public void putInt(byte[] b, int offset, int value);
|
||||
|
||||
/**
|
||||
* Writes a long value into a byte array.
|
||||
* @param b array to contain the bytes;
|
||||
* @param value the long value
|
||||
*/
|
||||
public void putLong(byte[] b, long value);
|
||||
|
||||
/**
|
||||
* Writes a long value into the byte array at the given offset
|
||||
* @param b array to contain the bytes;
|
||||
* @param offset the offset into the byte array to store the value.
|
||||
* @param value the long value
|
||||
*/
|
||||
public void putLong(byte[] b, int offset, long value);
|
||||
|
||||
/**
|
||||
* Writes a value of specified size into the byte array at the given offset
|
||||
* @param b array to contain the bytes at offset 0;
|
||||
* @param size number of bytes to be written
|
||||
* @param value
|
||||
*/
|
||||
public void putBigInteger(byte[] b, int size, BigInteger value);
|
||||
|
||||
/**
|
||||
* Writes a value of specified size into the byte array at the given offset
|
||||
* @param b array to contain the bytes;
|
||||
* @param offset the offset into the byte array to store the value.
|
||||
* @param size number of bytes to be written
|
||||
* @param value
|
||||
*/
|
||||
public void putBigInteger(byte[] b, int offset, int size, BigInteger value);
|
||||
default void getBytes(BigInteger value, int size, byte[] b, int offset) {
|
||||
putBigInteger(b, offset, size, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap the least-significant bytes (based upon size)
|
||||
* @param val value whoose bytes are to be swapped
|
||||
* @param val value whose bytes are to be swapped
|
||||
* @param size number of least significant bytes to be swapped
|
||||
* @return value with bytes swapped (any high-order bytes beyond size will be 0)
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -17,6 +16,7 @@
|
|||
package ghidra.util;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -25,43 +25,29 @@ import java.math.BigInteger;
|
|||
*/
|
||||
|
||||
public class LittleEndianDataConverter implements DataConverter {
|
||||
public static LittleEndianDataConverter INSTANCE = new LittleEndianDataConverter();
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final LittleEndianDataConverter INSTANCE = new LittleEndianDataConverter();
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructor for BigEndianDataConverter.
|
||||
* Don't use this constructor to create new instances of this class. Use the static {@link #INSTANCE} instead
|
||||
* or {@link DataConverter#getInstance(Endian)}
|
||||
*/
|
||||
public LittleEndianDataConverter() {
|
||||
// empty
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getShort(byte[])
|
||||
*/
|
||||
public final short getShort(byte[] b) {
|
||||
return getShort(b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getShort(byte[], int)
|
||||
*/
|
||||
@Override
|
||||
public short getShort(byte[] b, int offset) {
|
||||
Objects.checkFromIndexSize(offset, Short.BYTES, b.length);
|
||||
|
||||
return (short) (((b[offset + 1] & 0xff) << 8) | (b[offset] & 0xff));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getInt(byte[])
|
||||
*/
|
||||
public final int getInt(byte[] b) {
|
||||
return getInt(b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getInt(byte[], int)
|
||||
*/
|
||||
@Override
|
||||
public int getInt(byte[] b, int offset) {
|
||||
Objects.checkFromIndexSize(offset, Integer.BYTES, b.length);
|
||||
|
||||
int v = b[offset + 3];
|
||||
for (int i = 2; i >= 0; i--) {
|
||||
v = (v << 8) | (b[offset + i] & 0xff);
|
||||
|
@ -69,17 +55,10 @@ public class LittleEndianDataConverter implements DataConverter {
|
|||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getLong(byte[])
|
||||
*/
|
||||
public final long getLong(byte[] b) {
|
||||
return getLong(b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getLong(byte[], int)
|
||||
*/
|
||||
@Override
|
||||
public long getLong(byte[] b, int offset) {
|
||||
Objects.checkFromIndexSize(offset, Long.BYTES, b.length);
|
||||
|
||||
long v = b[offset + 7];
|
||||
for (int i = 6; i >= 0; i--) {
|
||||
v = (v << 8) | (b[offset + i] & 0xff);
|
||||
|
@ -87,20 +66,11 @@ public class LittleEndianDataConverter implements DataConverter {
|
|||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#getValue(byte[], int)
|
||||
*/
|
||||
public long getValue(byte[] b, int size) {
|
||||
return getValue(b, 0, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#getValue(byte[], int, int)
|
||||
*/
|
||||
@Override
|
||||
public long getValue(byte[] b, int offset, int size) {
|
||||
if (size > 8) {
|
||||
throw new IndexOutOfBoundsException("size exceeds sizeof long: " + size);
|
||||
}
|
||||
Objects.checkFromIndexSize(offset, size, b.length);
|
||||
Objects.checkIndex(size, Long.BYTES + 1);
|
||||
|
||||
long val = 0;
|
||||
for (int i = size - 1; i >= 0; i--) {
|
||||
val = (val << 8) | (b[offset + i] & 0xff);
|
||||
|
@ -109,15 +79,9 @@ public class LittleEndianDataConverter implements DataConverter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public final BigInteger getBigInteger(byte[] b, int size, boolean signed) {
|
||||
return getBigInteger(b, 0, size, signed);
|
||||
}
|
||||
public BigInteger getBigInteger(byte[] b, int offset, int size, boolean signed) {
|
||||
Objects.checkFromIndexSize(offset, size, b.length);
|
||||
|
||||
@Override
|
||||
public final BigInteger getBigInteger(byte[] b, int offset, int size, boolean signed) {
|
||||
if ((size + offset) > b.length) {
|
||||
throw new IndexOutOfBoundsException("insufficient bytes");
|
||||
}
|
||||
int msbIndex = 0;
|
||||
if (!signed) {
|
||||
// prepend 0 byte
|
||||
|
@ -132,32 +96,18 @@ public class LittleEndianDataConverter implements DataConverter {
|
|||
return new BigInteger(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getBytes(short, byte[])
|
||||
*/
|
||||
public final void getBytes(short value, byte[] b) {
|
||||
getBytes(value, b, 0);
|
||||
}
|
||||
@Override
|
||||
public void putShort(byte[] b, int offset, short value) {
|
||||
Objects.checkFromIndexSize(offset, Short.BYTES, b.length);
|
||||
|
||||
/**
|
||||
* @see DataConverter#getBytes(short, byte[], int)
|
||||
*/
|
||||
public void getBytes(short value, byte[] b, int offset) {
|
||||
b[offset + 1] = (byte) (value >> 8);
|
||||
b[offset] = (byte) (value & 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getBytes(int, byte[])
|
||||
*/
|
||||
public final void getBytes(int value, byte[] b) {
|
||||
getBytes(value, b, 0);
|
||||
}
|
||||
@Override
|
||||
public void putInt(byte[] b, int offset, int value) {
|
||||
Objects.checkFromIndexSize(offset, Integer.BYTES, b.length);
|
||||
|
||||
/**
|
||||
* @see DataConverter#getBytes(int, byte[], int)
|
||||
*/
|
||||
public void getBytes(int value, byte[] b, int offset) {
|
||||
b[offset] = (byte) (value);
|
||||
for (int i = 1; i < 4; i++) {
|
||||
value >>= 8;
|
||||
|
@ -165,113 +115,20 @@ public class LittleEndianDataConverter implements DataConverter {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DataConverter#getBytes(long, byte[])
|
||||
*/
|
||||
public final void getBytes(long value, byte[] b) {
|
||||
getBytes(value, 8, b, 0);
|
||||
}
|
||||
@Override
|
||||
public void putValue(long value, int size, byte[] b, int offset) {
|
||||
Objects.checkFromIndexSize(offset, size, b.length);
|
||||
Objects.checkIndex(size, Long.BYTES + 1);
|
||||
|
||||
/**
|
||||
* @see DataConverter#getBytes(long, byte[], int)
|
||||
*/
|
||||
public void getBytes(long value, byte[] b, int offset) {
|
||||
getBytes(value, 8, b, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#getBytes(long, int, byte[], int)
|
||||
*/
|
||||
public void getBytes(long value, int size, byte[] b, int offset) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
b[offset + i] = (byte) value;
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#putInt(byte[], int, int)
|
||||
*/
|
||||
public final void putInt(byte[] b, int offset, int value) {
|
||||
getBytes(value, b, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#putInt(byte[], int)
|
||||
*/
|
||||
public final void putInt(byte[] b, int value) {
|
||||
getBytes(value, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#putLong(byte[], int, long)
|
||||
*/
|
||||
public final void putLong(byte[] b, int offset, long value) {
|
||||
getBytes(value, b, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#putLong(byte[], long)
|
||||
*/
|
||||
public final void putLong(byte[] b, long value) {
|
||||
getBytes(value, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#putShort(byte[], int, short)
|
||||
*/
|
||||
public final void putShort(byte[] b, int offset, short value) {
|
||||
getBytes(value, b, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#putShort(byte[], short)
|
||||
*/
|
||||
public final void putShort(byte[] b, short value) {
|
||||
getBytes(value, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#getBytes(int)
|
||||
*/
|
||||
public byte[] getBytes(int value) {
|
||||
byte[] bytes = new byte[4];
|
||||
getBytes(value, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#getBytes(long)
|
||||
*/
|
||||
public byte[] getBytes(long value) {
|
||||
byte[] bytes = new byte[8];
|
||||
getBytes(value, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.DataConverter#getBytes(short)
|
||||
*/
|
||||
public byte[] getBytes(short value) {
|
||||
byte[] bytes = new byte[2];
|
||||
getBytes(value, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes(BigInteger value, int size) {
|
||||
byte[] bytes = new byte[size];
|
||||
putBigInteger(bytes, 0, size, value);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBytes(BigInteger value, int size, byte[] b, int offset) {
|
||||
putBigInteger(b, offset, size, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBigInteger(byte[] b, int offset, int size, BigInteger value) {
|
||||
Objects.checkFromIndexSize(offset, size, b.length);
|
||||
|
||||
int fillIndex = offset + size - 1; // start fill from MSB
|
||||
int srcIndex;
|
||||
|
@ -292,9 +149,4 @@ public class LittleEndianDataConverter implements DataConverter {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBigInteger(byte[] b, int size, BigInteger value) {
|
||||
putBigInteger(b, 0, size, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import util.CollectionUtils;
|
|||
public final class NumericUtilities {
|
||||
public static final BigInteger MAX_UNSIGNED_LONG = new BigInteger("ffffffffffffffff", 16);
|
||||
public static final BigInteger MAX_SIGNED_LONG = new BigInteger("7fffffffffffffff", 16);
|
||||
public static final long MAX_UNSIGNED_INT32_AS_LONG = 0xffffffffL;
|
||||
|
||||
private final static String HEX_PREFIX_X = "0X";
|
||||
private final static String HEX_PREFIX_x = "0x";
|
||||
|
@ -228,14 +229,26 @@ public final class NumericUtilities {
|
|||
return buf.toString();
|
||||
}
|
||||
|
||||
public final static BigInteger unsignedLongToBigInteger(long value) {
|
||||
/**
|
||||
* Converts a <strong>unsigned</strong> long value, which is currently stored in a
|
||||
* java <strong>signed</strong> long, into a {@link BigInteger}.
|
||||
* <p>
|
||||
* In other words, the full 64 bits of the primitive java <strong>signed</strong>
|
||||
* long is being used to store an <strong>unsigned</strong> value. This
|
||||
* method converts this into a positive BigInteger value.
|
||||
*
|
||||
* @param value java <strong>unsigned</strong> long value stuffed into a
|
||||
* java <strong>signed</strong> long
|
||||
* @return new {@link BigInteger} with the positive value of the unsigned long value
|
||||
*/
|
||||
public static BigInteger unsignedLongToBigInteger(long value) {
|
||||
if (value >= 0) {
|
||||
return BigInteger.valueOf(value);
|
||||
}
|
||||
return MAX_UNSIGNED_LONG.add(BigInteger.valueOf(value + 1));
|
||||
}
|
||||
|
||||
public final static long bigIntegerToUnsignedLong(BigInteger value) {
|
||||
public static long bigIntegerToUnsignedLong(BigInteger value) {
|
||||
if (value.compareTo(MAX_SIGNED_LONG) <= 0) {
|
||||
return value.longValue();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue