Add little-endian support for numeric types
Introduced `Little-Endian` functionality for `Short`, `Int`, `Long`, `Float`, and `Double` across `SlicedByteArray`, `MutableByteArrayHandler`, and `TypedByteArray`. Enhanced property delegates to handle little-endian byte order with the `littleEndian` parameter. Added `LittleEndianTest` to validate functionality. Bumped version to 0.3.0-SNAPSHOT.
This commit is contained in:
@@ -8,7 +8,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "nl.astraeus"
|
||||
version = "0.2.12-SNAPSHOT"
|
||||
version = "0.3.0-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
||||
@@ -14,23 +14,18 @@ open class ByteArrayHandler(
|
||||
|
||||
fun getShort(index: Int) = buffer.getShort(index)
|
||||
|
||||
fun getInt(index: Int) = buffer.getInt(index)
|
||||
fun getShortLE(index: Int) = buffer.getShortLE(index)
|
||||
|
||||
fun getLong(index: Int): Long {
|
||||
return (
|
||||
(buffer[index].toLong() shl 56) or
|
||||
((buffer[index+1].toLong() and 0xff) shl 48) or
|
||||
((buffer[index+2].toLong() and 0xff) shl 40) or
|
||||
((buffer[index+3].toLong() and 0xff) shl 32) or
|
||||
((buffer[index+4].toLong() and 0xff) shl 24) or
|
||||
((buffer[index+5].toLong() and 0xff) shl 16) or
|
||||
((buffer[index+6].toLong() and 0xff) shl 8) or
|
||||
(buffer[index+7].toLong() and 0xff)
|
||||
)
|
||||
}
|
||||
fun getInt(index: Int) = buffer.getInt(index)
|
||||
fun getIntLE(index: Int) = buffer.getIntLE(index)
|
||||
|
||||
fun getLong(index: Int) = buffer.getLong(index)
|
||||
fun getLongLE(index: Int) = buffer.getLongLE(index)
|
||||
|
||||
fun getFloat(index: Int): Float = buffer.getFloat(index)
|
||||
fun getFloatLE(index: Int): Float = buffer.getFloatLE(index)
|
||||
fun getDouble(index: Int): Double = buffer.getDouble(index)
|
||||
fun getDoubleLE(index: Int): Double = buffer.getDoubleLE(index)
|
||||
|
||||
fun getString(index: Int): String {
|
||||
val length = buffer.getShort(index)
|
||||
@@ -76,13 +71,18 @@ class MutableByteArrayHandler(
|
||||
}
|
||||
|
||||
fun setShort(index: Int, value: Short) = buffer.setShort(index, value)
|
||||
fun setShortLE(index: Int, value: Short) = buffer.setShortLE(index, value)
|
||||
|
||||
fun setInt(index: Int, value: Int) = buffer.setInt(index, value)
|
||||
fun setIntLE(index: Int, value: Int) = buffer.setIntLE(index, value)
|
||||
|
||||
fun setLong(index: Int, value: Long) = buffer.setLong(index, value)
|
||||
fun setLongLE(index: Int, value: Long) = buffer.setLongLE(index, value)
|
||||
|
||||
fun setFloat(index: Int, value: Float) = buffer.setFloat(index, value)
|
||||
fun setFloatLE(index: Int, value: Float) = buffer.setFloatLE(index, value)
|
||||
fun setDouble(index: Int, value: Double) = buffer.setDouble(index, value)
|
||||
fun setDoubleLE(index: Int, value: Double) = buffer.setDoubleLE(index, value)
|
||||
|
||||
fun setString(index: Int, value: String, maxLength: Int) {
|
||||
val bytes = value.encodeToByteArray()
|
||||
|
||||
@@ -64,7 +64,19 @@ class ShortProperty(
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: TypedByteArray, property: KProperty<*>, value: Short) {
|
||||
thisRef.data.setShort(getIndex(thisRef), value)
|
||||
return thisRef.data.setShort(getIndex(thisRef), value)
|
||||
}
|
||||
}
|
||||
|
||||
class ShortPropertyLE(
|
||||
name: String
|
||||
) : ByteArrayProperty<Short>(name) {
|
||||
override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): Short {
|
||||
return thisRef.data.getShortLE(getIndex(thisRef))
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: TypedByteArray, property: KProperty<*>, value: Short) {
|
||||
return thisRef.data.setShortLE(getIndex(thisRef), value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +92,18 @@ class IntProperty(
|
||||
}
|
||||
}
|
||||
|
||||
class IntPropertyLE(
|
||||
name: String
|
||||
) : ByteArrayProperty<Int>(name) {
|
||||
override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): Int {
|
||||
return thisRef.data.getIntLE(getIndex(thisRef))
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: TypedByteArray, property: KProperty<*>, value: Int) {
|
||||
thisRef.data.setIntLE(getIndex(thisRef), value)
|
||||
}
|
||||
}
|
||||
|
||||
class FloatProperty(
|
||||
name: String
|
||||
) : ByteArrayProperty<Float>(name) {
|
||||
@@ -92,6 +116,18 @@ class FloatProperty(
|
||||
}
|
||||
}
|
||||
|
||||
class FloatPropertyLE(
|
||||
name: String
|
||||
) : ByteArrayProperty<Float>(name) {
|
||||
override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): Float {
|
||||
return thisRef.data.getFloatLE(getIndex(thisRef))
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: TypedByteArray, property: KProperty<*>, value: Float) {
|
||||
thisRef.data.setFloatLE(getIndex(thisRef), value)
|
||||
}
|
||||
}
|
||||
|
||||
class LongProperty(
|
||||
name: String
|
||||
) : ByteArrayProperty<Long>(name) {
|
||||
@@ -104,6 +140,18 @@ class LongProperty(
|
||||
}
|
||||
}
|
||||
|
||||
class LongPropertyLE(
|
||||
name: String
|
||||
) : ByteArrayProperty<Long>(name) {
|
||||
override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): Long {
|
||||
return thisRef.data.getLongLE(getIndex(thisRef))
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: TypedByteArray, property: KProperty<*>, value: Long) {
|
||||
thisRef.data.setLongLE(getIndex(thisRef), value)
|
||||
}
|
||||
}
|
||||
|
||||
class DoubleProperty(
|
||||
name: String
|
||||
) : ByteArrayProperty<Double>(name) {
|
||||
@@ -116,6 +164,18 @@ class DoubleProperty(
|
||||
}
|
||||
}
|
||||
|
||||
class DoublePropertyLE(
|
||||
name: String
|
||||
) : ByteArrayProperty<Double>(name) {
|
||||
override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): Double {
|
||||
return thisRef.data.getDoubleLE(getIndex(thisRef))
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: TypedByteArray, property: KProperty<*>, value: Double) {
|
||||
thisRef.data.setDoubleLE(getIndex(thisRef), value)
|
||||
}
|
||||
}
|
||||
|
||||
class StringProperty(
|
||||
name: String,
|
||||
) : ByteArrayPropertyWithLength<String>(name) {
|
||||
@@ -175,11 +235,31 @@ class BlobProperty(
|
||||
|
||||
fun boolean(propertyName: String) = BooleanProperty(propertyName)
|
||||
fun byte(propertyName: String) = ByteProperty(propertyName)
|
||||
fun short(propertyName: String) = ShortProperty(propertyName)
|
||||
fun int(propertyName: String) = IntProperty(propertyName)
|
||||
fun long(propertyName: String) = LongProperty(propertyName)
|
||||
fun float(propertyName: String) = FloatProperty(propertyName)
|
||||
fun double(propertyName: String) = DoubleProperty(propertyName)
|
||||
fun short(propertyName: String, littleEndian: Boolean = false) = if (littleEndian) {
|
||||
ShortPropertyLE(propertyName)
|
||||
} else {
|
||||
ShortProperty(propertyName)
|
||||
}
|
||||
fun int(propertyName: String, littleEndian: Boolean = false) = if (littleEndian) {
|
||||
IntPropertyLE(propertyName)
|
||||
} else {
|
||||
IntProperty(propertyName)
|
||||
}
|
||||
fun long(propertyName: String, littleEndian: Boolean = false) = if (littleEndian) {
|
||||
LongPropertyLE(propertyName)
|
||||
} else {
|
||||
LongProperty(propertyName)
|
||||
}
|
||||
fun float(propertyName: String, littleEndian: Boolean = false) = if (littleEndian) {
|
||||
FloatPropertyLE(propertyName)
|
||||
} else {
|
||||
FloatProperty(propertyName)
|
||||
}
|
||||
fun double(propertyName: String, littleEndian: Boolean = false) = if (littleEndian) {
|
||||
DoubleProperty(propertyName)
|
||||
} else {
|
||||
DoublePropertyLE(propertyName)
|
||||
}
|
||||
fun string(propertyName: String) = StringProperty(propertyName)
|
||||
fun cachedString(propertyName: String) = CachedStringProperty(propertyName)
|
||||
fun clob(propertyName: String) = ClobProperty(propertyName)
|
||||
|
||||
@@ -27,12 +27,25 @@ class SlicedByteArray(
|
||||
data[offset + index + 1] = value.toByte()
|
||||
}
|
||||
|
||||
fun setShortLE(index: Int, value: Short) {
|
||||
check(offset + index + 1 <= offset + length) { "Index out of bounds" }
|
||||
|
||||
data[offset + index + 1] = (value.toInt() shr 8).toByte()
|
||||
data[offset + index] = value.toByte()
|
||||
}
|
||||
|
||||
fun getShort(index: Int): Short {
|
||||
check(offset + index + 1 <= offset + length) { "Index out of bounds, ${offset + index + 1} > ${offset + length} ($offset, $index, $length)" }
|
||||
|
||||
return ((data[offset + index].toInt() shl 8) or (data[offset + index + 1].toInt() and 0xff)).toShort()
|
||||
}
|
||||
|
||||
fun getShortLE(index: Int): Short {
|
||||
check(offset + index + 1 <= offset + length) { "Index out of bounds, ${offset + index + 1} > ${offset + length} ($offset, $index, $length)" }
|
||||
|
||||
return ((data[offset + index + 1].toInt() shl 8) or (data[offset + index].toInt() and 0xff)).toShort()
|
||||
}
|
||||
|
||||
fun setInt(index: Int, value: Int) {
|
||||
check(offset + index + 3 <= offset + length) { "Index out of bounds" }
|
||||
|
||||
@@ -42,13 +55,32 @@ class SlicedByteArray(
|
||||
data[offset + index + 3] = (value and 0xff).toByte()
|
||||
}
|
||||
|
||||
fun setIntLE(index: Int, value: Int) {
|
||||
check(offset + index + 3 <= offset + length) { "Index out of bounds" }
|
||||
|
||||
data[offset + index + 3] = ((value shr 24) and 0xff).toByte()
|
||||
data[offset + index + 2] = ((value shr 16) and 0xff).toByte()
|
||||
data[offset + index + 1] = ((value shr 8) and 0xff).toByte()
|
||||
data[offset + index + 0] = (value and 0xff).toByte()
|
||||
}
|
||||
|
||||
fun getInt(index: Int): Int {
|
||||
check(offset + index + 3 <= offset + length) { "Index out of bounds" }
|
||||
return (
|
||||
(data[offset + index].toInt() shl 24) or
|
||||
((data[offset + index+1].toInt() shl 16) and 0xff0000) or
|
||||
((data[offset + index+2].toInt() shl 8) and 0xff00) or
|
||||
(data[offset + index+3].toInt() and 0xff)
|
||||
((data[offset + index + 1].toInt() shl 16) and 0xff0000) or
|
||||
((data[offset + index + 2].toInt() shl 8) and 0xff00) or
|
||||
(data[offset + index + 3].toInt() and 0xff)
|
||||
)
|
||||
}
|
||||
|
||||
fun getIntLE(index: Int): Int {
|
||||
check(offset + index + 3 <= offset + length) { "Index out of bounds" }
|
||||
return (
|
||||
(data[offset + index + 3].toInt() shl 24) or
|
||||
((data[offset + index + 2].toInt() shl 16) and 0xff0000) or
|
||||
((data[offset + index + 1].toInt() shl 8) and 0xff00) or
|
||||
(data[offset + index + 0].toInt() and 0xff)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -64,27 +96,57 @@ class SlicedByteArray(
|
||||
data[offset + index + 7] = (value and 0xff).toByte()
|
||||
}
|
||||
|
||||
fun setLongLE(index: Int, value: Long) {
|
||||
check(offset + index + 7 <= offset + length) { "Index out of bounds" }
|
||||
data[offset + index + 7] = ((value shr 56) and 0xff).toByte()
|
||||
data[offset + index + 6] = ((value shr 48) and 0xff).toByte()
|
||||
data[offset + index + 5] = ((value shr 40) and 0xff).toByte()
|
||||
data[offset + index + 4] = ((value shr 32) and 0xff).toByte()
|
||||
data[offset + index + 3] = ((value shr 24) and 0xff).toByte()
|
||||
data[offset + index + 2] = ((value shr 16) and 0xff).toByte()
|
||||
data[offset + index + 1] = ((value shr 8) and 0xff).toByte()
|
||||
data[offset + index + 0] = (value and 0xff).toByte()
|
||||
}
|
||||
|
||||
fun getLong(index: Int): Long {
|
||||
check(offset + index + 7 <= offset + length) { "Index out of bounds" }
|
||||
return (
|
||||
(data[offset + index].toLong() shl 56) or
|
||||
((data[offset + index+1].toLong() and 0xff) shl 48) or
|
||||
((data[offset + index+2].toLong() and 0xff) shl 40) or
|
||||
((data[offset + index+3].toLong() and 0xff) shl 32) or
|
||||
((data[offset + index+4].toLong() and 0xff) shl 24) or
|
||||
((data[offset + index+5].toLong() and 0xff) shl 16) or
|
||||
((data[offset + index+6].toLong() and 0xff) shl 8) or
|
||||
(data[offset + index+7].toLong() and 0xff)
|
||||
((data[offset + index + 1].toLong() and 0xff) shl 48) or
|
||||
((data[offset + index + 2].toLong() and 0xff) shl 40) or
|
||||
((data[offset + index + 3].toLong() and 0xff) shl 32) or
|
||||
((data[offset + index + 4].toLong() and 0xff) shl 24) or
|
||||
((data[offset + index + 5].toLong() and 0xff) shl 16) or
|
||||
((data[offset + index + 6].toLong() and 0xff) shl 8) or
|
||||
(data[offset + index + 7].toLong() and 0xff)
|
||||
)
|
||||
}
|
||||
|
||||
fun getLongLE(index: Int): Long {
|
||||
check(offset + index + 7 <= offset + length) { "Index out of bounds" }
|
||||
return (
|
||||
(data[offset + index + 7].toLong() shl 56) or
|
||||
((data[offset + index + 6].toLong() and 0xff) shl 48) or
|
||||
((data[offset + index + 5].toLong() and 0xff) shl 40) or
|
||||
((data[offset + index + 4].toLong() and 0xff) shl 32) or
|
||||
((data[offset + index + 3].toLong() and 0xff) shl 24) or
|
||||
((data[offset + index + 2].toLong() and 0xff) shl 16) or
|
||||
((data[offset + index + 1].toLong() and 0xff) shl 8) or
|
||||
(data[offset + index + 0].toLong() and 0xff)
|
||||
)
|
||||
}
|
||||
|
||||
fun setFloat(index: Int, value: Float) = setInt(index, value.toRawBits())
|
||||
fun setFloatLE(index: Int, value: Float) = setIntLE(index, value.toRawBits())
|
||||
fun getFloat(index: Int): Float = Float.fromBits(getInt(index))
|
||||
fun getFloatLE(index: Int): Float = Float.fromBits(getIntLE(index))
|
||||
|
||||
fun setDouble(index: Int, value: Double) = setLong(index, value.toRawBits())
|
||||
fun setDoubleLE(index: Int, value: Double) = setLongLE(index, value.toRawBits())
|
||||
fun getDouble(index: Int): Double = Double.fromBits(getLong(index))
|
||||
fun getDoubleLE(index: Int): Double = Double.fromBits(getLongLE(index))
|
||||
|
||||
fun getBlob(index: Int, length: Int): SlicedByteArray {
|
||||
fun getBlob(index: Int, length: Int): SlicedByteArray {
|
||||
check(index + length <= this.length) { "Index out of bounds ($index, $length, ${this.length}" }
|
||||
|
||||
val str = SlicedByteArray(data, offset + index, length)
|
||||
@@ -96,17 +158,17 @@ class SlicedByteArray(
|
||||
}
|
||||
|
||||
fun iterator(): Iterator<Byte> = object : Iterator<Byte> {
|
||||
var index = offset
|
||||
var index = offset
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
return index < offset + length
|
||||
}
|
||||
|
||||
override fun next(): Byte {
|
||||
return data[offset + index++]
|
||||
}
|
||||
override fun hasNext(): Boolean {
|
||||
return index < offset + length
|
||||
}
|
||||
|
||||
override fun next(): Byte {
|
||||
return data[offset + index++]
|
||||
}
|
||||
}
|
||||
|
||||
fun toByteArray(): ByteArray = data.copyOfRange(offset, offset + length)
|
||||
|
||||
fun setBlob(index: Int, bytes: SlicedByteArray, blobLength: Int) {
|
||||
|
||||
260
src/commonTest/kotlin/nl/astraeus/tba/LittleEndianTest.kt
Normal file
260
src/commonTest/kotlin/nl/astraeus/tba/LittleEndianTest.kt
Normal file
@@ -0,0 +1,260 @@
|
||||
package nl.astraeus.tba
|
||||
|
||||
/**
|
||||
* This test file was created by AI Assistant to test the little endian functionality
|
||||
* in the typed-byte-arrays library. It tests the functionality at three levels:
|
||||
* 1. SlicedByteArray (low-level implementation)
|
||||
* 2. MutableByteArrayHandler (mid-level implementation)
|
||||
* 3. TypedByteArray (high-level implementation with property delegates)
|
||||
*/
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class LittleEndianTest {
|
||||
|
||||
@Test
|
||||
fun testSlicedByteArrayShortLittleEndian() {
|
||||
val array = SlicedByteArray(10)
|
||||
|
||||
// Test positive value
|
||||
val shortValue: Short = 12345
|
||||
array.setShortLE(0, shortValue)
|
||||
assertEquals(shortValue, array.getShortLE(0))
|
||||
|
||||
// Test negative value
|
||||
val negShortValue: Short = -12345
|
||||
array.setShortLE(2, negShortValue)
|
||||
assertEquals(negShortValue, array.getShortLE(2))
|
||||
|
||||
// Verify byte order is actually little endian
|
||||
val bytes = array.data
|
||||
assertEquals(57, bytes[0].toInt() and 0xff) // 12345 & 0xff = 57
|
||||
assertEquals(48, bytes[1].toInt() and 0xff) // (12345 >> 8) & 0xff = 48
|
||||
|
||||
assertEquals(199, bytes[2].toInt() and 0xff) // -12345 & 0xff = 199
|
||||
assertEquals(207, bytes[3].toInt() and 0xff) // (-12345 >> 8) & 0xff = 207
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSlicedByteArrayIntLittleEndian() {
|
||||
val array = SlicedByteArray(10)
|
||||
|
||||
// Test positive value
|
||||
val intValue = 123456789
|
||||
array.setIntLE(0, intValue)
|
||||
assertEquals(intValue, array.getIntLE(0))
|
||||
|
||||
// Test negative value
|
||||
val negIntValue = -123456789
|
||||
array.setIntLE(4, negIntValue)
|
||||
assertEquals(negIntValue, array.getIntLE(4))
|
||||
|
||||
// Verify byte order is actually little endian
|
||||
val bytes = array.data
|
||||
assertEquals(21, bytes[0].toInt() and 0xff)
|
||||
assertEquals(205, bytes[1].toInt() and 0xff)
|
||||
assertEquals(91, bytes[2].toInt() and 0xff)
|
||||
assertEquals(7, bytes[3].toInt() and 0xff)
|
||||
|
||||
assertEquals(235, bytes[4].toInt() and 0xff)
|
||||
assertEquals(50, bytes[5].toInt() and 0xff)
|
||||
assertEquals(164, bytes[6].toInt() and 0xff)
|
||||
assertEquals(248, bytes[7].toInt() and 0xff)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSlicedByteArrayLongLittleEndian() {
|
||||
val array = SlicedByteArray(20)
|
||||
|
||||
// Test positive value
|
||||
val longValue = 1234567890123456789L
|
||||
array.setLongLE(0, longValue)
|
||||
assertEquals(longValue, array.getLongLE(0))
|
||||
|
||||
// Test negative value
|
||||
val negLongValue = -1234567890123456789L
|
||||
array.setLongLE(8, negLongValue)
|
||||
assertEquals(negLongValue, array.getLongLE(8))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSlicedByteArrayFloatLittleEndian() {
|
||||
val array = SlicedByteArray(10)
|
||||
|
||||
// Test positive value
|
||||
val floatValue = 123.456f
|
||||
array.setFloatLE(0, floatValue)
|
||||
assertEquals(floatValue, array.getFloatLE(0))
|
||||
|
||||
// Test negative value
|
||||
val negFloatValue = -123.456f
|
||||
array.setFloatLE(4, negFloatValue)
|
||||
assertEquals(negFloatValue, array.getFloatLE(4))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSlicedByteArrayDoubleLittleEndian() {
|
||||
val array = SlicedByteArray(20)
|
||||
|
||||
// Test positive value
|
||||
val doubleValue = 123.456789
|
||||
array.setDoubleLE(0, doubleValue)
|
||||
assertEquals(doubleValue, array.getDoubleLE(0))
|
||||
|
||||
// Test negative value
|
||||
val negDoubleValue = -123.456789
|
||||
array.setDoubleLE(8, negDoubleValue)
|
||||
assertEquals(negDoubleValue, array.getDoubleLE(8))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testShortLittleEndian() {
|
||||
val handler = MutableByteArrayHandler(ByteArray(10))
|
||||
|
||||
// Test positive value
|
||||
val shortValue: Short = 12345
|
||||
handler.setShortLE(0, shortValue)
|
||||
assertEquals(shortValue, handler.getShortLE(0))
|
||||
|
||||
// Test negative value
|
||||
val negShortValue: Short = -12345
|
||||
handler.setShortLE(2, negShortValue)
|
||||
assertEquals(negShortValue, handler.getShortLE(2))
|
||||
|
||||
// Verify byte order is actually little endian
|
||||
val bytes = handler.buffer.data
|
||||
assertEquals(57, bytes[0].toInt() and 0xff) // 12345 & 0xff = 57
|
||||
assertEquals(48, bytes[1].toInt() and 0xff) // (12345 >> 8) & 0xff = 48
|
||||
|
||||
assertEquals(199, bytes[2].toInt() and 0xff) // -12345 & 0xff = 199
|
||||
assertEquals(207, bytes[3].toInt() and 0xff) // (-12345 >> 8) & 0xff = 207
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIntLittleEndian() {
|
||||
val handler = MutableByteArrayHandler(ByteArray(10))
|
||||
|
||||
// Test positive value
|
||||
val intValue = 123456789
|
||||
handler.setIntLE(0, intValue)
|
||||
assertEquals(intValue, handler.getIntLE(0))
|
||||
|
||||
// Test negative value
|
||||
val negIntValue = -123456789
|
||||
handler.setIntLE(4, negIntValue)
|
||||
assertEquals(negIntValue, handler.getIntLE(4))
|
||||
|
||||
// Verify byte order is actually little endian
|
||||
val bytes = handler.buffer.data
|
||||
assertEquals(21, bytes[0].toInt() and 0xff)
|
||||
assertEquals(205, bytes[1].toInt() and 0xff)
|
||||
assertEquals(91, bytes[2].toInt() and 0xff)
|
||||
assertEquals(7, bytes[3].toInt() and 0xff)
|
||||
|
||||
assertEquals(235, bytes[4].toInt() and 0xff)
|
||||
assertEquals(50, bytes[5].toInt() and 0xff)
|
||||
assertEquals(164, bytes[6].toInt() and 0xff)
|
||||
assertEquals(248, bytes[7].toInt() and 0xff)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLongLittleEndian() {
|
||||
val handler = MutableByteArrayHandler(ByteArray(20))
|
||||
|
||||
// Test positive value
|
||||
val longValue = 1234567890123456789L
|
||||
handler.setLongLE(0, longValue)
|
||||
assertEquals(longValue, handler.getLongLE(0))
|
||||
|
||||
// Test negative value
|
||||
val negLongValue = -1234567890123456789L
|
||||
handler.setLongLE(8, negLongValue)
|
||||
assertEquals(negLongValue, handler.getLongLE(8))
|
||||
|
||||
// Verify byte order is actually little endian
|
||||
val bytes = handler.buffer.data
|
||||
assertEquals(21, bytes[0].toInt() and 0xff)
|
||||
assertEquals(129, bytes[1].toInt() and 0xff)
|
||||
assertEquals(233, bytes[2].toInt() and 0xff)
|
||||
assertEquals(125, bytes[3].toInt() and 0xff)
|
||||
assertEquals(244, bytes[4].toInt() and 0xff)
|
||||
assertEquals(16, bytes[5].toInt() and 0xff)
|
||||
assertEquals(34, bytes[6].toInt() and 0xff)
|
||||
assertEquals(17, bytes[7].toInt() and 0xff)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFloatLittleEndian() {
|
||||
val handler = MutableByteArrayHandler(ByteArray(10))
|
||||
|
||||
// Test positive value
|
||||
val floatValue = 123.456f
|
||||
handler.setFloatLE(0, floatValue)
|
||||
assertEquals(floatValue, handler.getFloatLE(0))
|
||||
|
||||
// Test negative value
|
||||
val negFloatValue = -123.456f
|
||||
handler.setFloatLE(4, negFloatValue)
|
||||
assertEquals(negFloatValue, handler.getFloatLE(4))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDoubleLittleEndian() {
|
||||
val handler = MutableByteArrayHandler(ByteArray(20))
|
||||
|
||||
// Test positive value
|
||||
val doubleValue = 123.456789
|
||||
handler.setDoubleLE(0, doubleValue)
|
||||
assertEquals(doubleValue, handler.getDoubleLE(0))
|
||||
|
||||
// Test negative value
|
||||
val negDoubleValue = -123.456789
|
||||
handler.setDoubleLE(8, negDoubleValue)
|
||||
assertEquals(negDoubleValue, handler.getDoubleLE(8))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTypedByteArrayLittleEndian() {
|
||||
class LittleEndianData : TypedByteArray(
|
||||
Type("shortValue", DataType.SHORT),
|
||||
Type("intValue", DataType.INT),
|
||||
Type("longValue", DataType.LONG),
|
||||
Type("floatValue", DataType.FLOAT),
|
||||
Type("doubleValue", DataType.DOUBLE)
|
||||
) {
|
||||
var shortValue by short("shortValue", littleEndian = true)
|
||||
var intValue by int("intValue", littleEndian = true)
|
||||
var longValue by long("longValue", littleEndian = true)
|
||||
var floatValue by float("floatValue", littleEndian = true)
|
||||
var doubleValue by double("doubleValue", littleEndian = true)
|
||||
}
|
||||
|
||||
val data = LittleEndianData()
|
||||
|
||||
// Test with positive values
|
||||
data.shortValue = 12345
|
||||
data.intValue = 123456789
|
||||
data.longValue = 1234567890123456789L
|
||||
data.floatValue = 123.456f
|
||||
data.doubleValue = 123.456789
|
||||
|
||||
assertEquals(12345, data.shortValue)
|
||||
assertEquals(123456789, data.intValue)
|
||||
assertEquals(1234567890123456789L, data.longValue)
|
||||
assertEquals(123.456f, data.floatValue)
|
||||
assertEquals(123.456789, data.doubleValue)
|
||||
|
||||
// Test with negative values
|
||||
data.shortValue = -12345
|
||||
data.intValue = -123456789
|
||||
data.longValue = -1234567890123456789L
|
||||
data.floatValue = -123.456f
|
||||
data.doubleValue = -123.456789
|
||||
|
||||
assertEquals(-12345, data.shortValue)
|
||||
assertEquals(-123456789, data.intValue)
|
||||
assertEquals(-1234567890123456789L, data.longValue)
|
||||
assertEquals(-123.456f, data.floatValue)
|
||||
assertEquals(-123.456789, data.doubleValue)
|
||||
}
|
||||
}
|
||||
@@ -21,13 +21,13 @@ class TestCachedString {
|
||||
val cachedPerson = PersonCached()
|
||||
val notCachedPerson = PersonNotCached()
|
||||
|
||||
cachedPerson.name = "A Longer Longer Longer Longer Longer Test"
|
||||
notCachedPerson.name = "A Longer Longer Longer Longer Longer Test"
|
||||
cachedPerson.name = "A Longer Longer Longer Longer Longer 長い 長い 長い 更长 更长 更长 Test"
|
||||
notCachedPerson.name = "A Longer Longer Longer Longer Longer 長い 長い 長い 更长 更长 更长 Test"
|
||||
|
||||
var total = 0
|
||||
repeat(10000000) {
|
||||
total += cachedPerson.name.hashCode()
|
||||
total += notCachedPerson.name.hashCode()
|
||||
total += cachedPerson.name.length
|
||||
total += notCachedPerson.name.length
|
||||
}
|
||||
|
||||
println("Total warmup: $total")
|
||||
@@ -35,14 +35,14 @@ class TestCachedString {
|
||||
var start1 = System.nanoTime()
|
||||
var total1 = 0
|
||||
repeat(10000000) {
|
||||
total1 += cachedPerson.name.hashCode()
|
||||
total1 += cachedPerson.name.length
|
||||
}
|
||||
val stop1 = System.nanoTime()
|
||||
|
||||
var start2 = System.nanoTime()
|
||||
var total2 = 0
|
||||
repeat(10000000) {
|
||||
total2 += notCachedPerson.name.hashCode()
|
||||
total2 += notCachedPerson.name.length
|
||||
}
|
||||
val stop2 = System.nanoTime()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user