diff --git a/build.gradle.kts b/build.gradle.kts index cc4bef8..88ccff7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { } group = "nl.astraeus" -version = "0.2.12-SNAPSHOT" +version = "0.3.0-SNAPSHOT" repositories { mavenCentral() diff --git a/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayHandler.kt b/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayHandler.kt index d4bf5b0..1ce72d3 100644 --- a/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayHandler.kt +++ b/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayHandler.kt @@ -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() diff --git a/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayProperties.kt b/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayProperties.kt index 516c0a5..ec6e9ec 100644 --- a/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayProperties.kt +++ b/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayProperties.kt @@ -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(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(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(name) { @@ -92,6 +116,18 @@ class FloatProperty( } } +class FloatPropertyLE( + name: String +) : ByteArrayProperty(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(name) { @@ -104,6 +140,18 @@ class LongProperty( } } +class LongPropertyLE( + name: String +) : ByteArrayProperty(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(name) { @@ -116,6 +164,18 @@ class DoubleProperty( } } +class DoublePropertyLE( + name: String +) : ByteArrayProperty(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(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) diff --git a/src/commonMain/kotlin/nl/astraeus/tba/SlicedByteArray.kt b/src/commonMain/kotlin/nl/astraeus/tba/SlicedByteArray.kt index 13cfdcc..5e0f028 100644 --- a/src/commonMain/kotlin/nl/astraeus/tba/SlicedByteArray.kt +++ b/src/commonMain/kotlin/nl/astraeus/tba/SlicedByteArray.kt @@ -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 = object : Iterator { - 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) { diff --git a/src/commonTest/kotlin/nl/astraeus/tba/LittleEndianTest.kt b/src/commonTest/kotlin/nl/astraeus/tba/LittleEndianTest.kt new file mode 100644 index 0000000..3fc56b1 --- /dev/null +++ b/src/commonTest/kotlin/nl/astraeus/tba/LittleEndianTest.kt @@ -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) + } +} diff --git a/src/jvmTest/kotlin/nl/astraeus/tba/TestCachedString.kt b/src/jvmTest/kotlin/nl/astraeus/tba/TestCachedString.kt index 85246d5..ab9fc07 100644 --- a/src/jvmTest/kotlin/nl/astraeus/tba/TestCachedString.kt +++ b/src/jvmTest/kotlin/nl/astraeus/tba/TestCachedString.kt @@ -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()