diff --git a/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayDefinition.kt b/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayDefinition.kt index 1ac8d50..818c0fb 100644 --- a/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayDefinition.kt +++ b/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayDefinition.kt @@ -9,8 +9,7 @@ enum class DataType(val size: Int) { DOUBLE(8), STRING(-1), // max length 65535 CLOB(-1), // max length 2^32-1 - BLOB(-1), - ARRAY(-1), + BLOB(-1), // max length 2^32-1 ; } @@ -24,22 +23,12 @@ class Type( }, ) -interface ByteArrayDefinition { - val types: List - val size: Int -} - -open class BaseByteArrayDefinition( +open class ByteArrayDefinition( vararg types: Type, -) : ByteArrayDefinition{ - override val types: List = types.toList() +) { + val types: List = types.toList() - override val size: Int by lazy { + val size: Int by lazy { this.types.sumOf { it.size } } -} - -interface BinaryType { - val name: String - val typeId: Long -} +} \ No newline at end of file diff --git a/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayHandler.kt b/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayHandler.kt index 52d6c37..bbf1d87 100644 --- a/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayHandler.kt +++ b/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayHandler.kt @@ -45,6 +45,25 @@ class MutableByteArrayHandler( return index + bytes.size + 2 } + fun setClob(index: Int, value: String, maxLength: Int): Int { + val bytes = value.encodeToByteArray() + if (bytes.size > maxLength) { + throw IllegalArgumentException("String is too long") + } + this.setInt(index, bytes.size) + bytes.copyInto(buffer, index + 4) + return index + bytes.size + 4 + } + + fun setBlob(index: Int, bytes: ByteArray, maxLength: Int): Int { + if (bytes.size > maxLength) { + throw IllegalArgumentException("String is too long") + } + this.setInt(index, bytes.size) + bytes.copyInto(buffer, index + 4) + return index + bytes.size + 4 + } + } open class ByteArrayHandler( @@ -105,6 +124,12 @@ open class ByteArrayHandler( return str } + fun getBlob(index: Int): ByteArray { + val length = getInt(index) + val str = buffer.copyOfRange(index + 4, index + 4 + length) + return str + } + fun slice(range: IntRange): ByteArrayHandler { return ByteArrayHandler( buffer, diff --git a/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayProperties.kt b/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayProperties.kt index 28594dc..9215dc6 100644 --- a/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayProperties.kt +++ b/src/commonMain/kotlin/nl/astraeus/tba/ByteArrayProperties.kt @@ -3,18 +3,47 @@ package nl.astraeus.tba import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty -class ByteProperty( +abstract class ByteArrayProperty( val name: String -) : ReadWriteProperty { +) : ReadWriteProperty { var index: Int? = null - private fun getIndex(thisRef: TypedByteArray): Int { + protected fun getIndex(thisRef: TypedByteArray): Int { if (index == null) { index = thisRef.indexMap[name] ?: throw IllegalArgumentException("Property $name not found") } return index!! } +} +abstract class ByteArrayPropertyWithLength( + name: String +) : ByteArrayProperty(name) { + var maxLength: Int? = null + + protected fun getMaxLength(thisRef: TypedByteArray): Int { + if (maxLength == null) { + maxLength = thisRef.typeMap[name]!!.size - 2 + } + return maxLength!! + } +} + +class BooleanProperty( + name: String +) : ByteArrayProperty(name) { + override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): Boolean { + return thisRef.data[getIndex(thisRef)] != 0.toByte() + } + + override fun setValue(thisRef: TypedByteArray, property: KProperty<*>, value: Boolean) { + thisRef.data [getIndex(thisRef)] = if (value) { -1 } else { 0 } + } +} + +class ByteProperty( + name: String +) : ByteArrayProperty(name) { override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): Byte { return thisRef.data[getIndex(thisRef)] } @@ -25,17 +54,8 @@ class ByteProperty( } class ShortProperty( - val name: String -) : ReadWriteProperty { - var index: Int? = null - - private fun getIndex(thisRef: TypedByteArray): Int { - if (index == null) { - index = thisRef.indexMap[name] ?: throw IllegalArgumentException("Property $name not found") - } - return index!! - } - + name: String +) : ByteArrayProperty(name) { override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): Short { return thisRef.data.getShort(getIndex(thisRef)) } @@ -46,17 +66,8 @@ class ShortProperty( } class IntProperty( - val name: String -) : ReadWriteProperty { - var index: Int? = null - - private fun getIndex(thisRef: TypedByteArray): Int { - if (index == null) { - index = thisRef.indexMap[name] ?: throw IllegalArgumentException("Property $name not found") - } - return index!! - } - + name: String +) : ByteArrayProperty(name) { override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): Int { return thisRef.data.getInt(getIndex(thisRef)) } @@ -66,18 +77,21 @@ class IntProperty( } } -class LongProperty( - val name: String -) : ReadWriteProperty { - var index: Int? = null - - private fun getIndex(thisRef: TypedByteArray): Int { - if (index == null) { - index = thisRef.indexMap[name] ?: throw IllegalArgumentException("Property $name not found") - } - return index!! +class FloatProperty( + name: String +) : ByteArrayProperty(name) { + override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): Float { + return thisRef.data.getFloat(getIndex(thisRef)) } + override fun setValue(thisRef: TypedByteArray, property: KProperty<*>, value: Float) { + thisRef.data.setFloat(getIndex(thisRef), value) + } +} + +class LongProperty( + name: String +) : ByteArrayProperty(name) { override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): Long { return thisRef.data.getLong(getIndex(thisRef)) } @@ -87,26 +101,21 @@ class LongProperty( } } +class DoubleProperty( + name: String +) : ByteArrayProperty(name) { + override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): Double { + return thisRef.data.getDouble(getIndex(thisRef)) + } + + override fun setValue(thisRef: TypedByteArray, property: KProperty<*>, value: Double) { + thisRef.data.setDouble(getIndex(thisRef), value) + } +} + class StringProperty( - val name: String -) : ReadWriteProperty { - var index: Int? = null - var maxLength: Int? = null - - private fun getIndex(thisRef: TypedByteArray): Int { - if (index == null) { - index = thisRef.indexMap[name] ?: throw IllegalArgumentException("Property $name not found") - } - return index!! - } - - private fun getMaxLength(thisRef: TypedByteArray): Int { - if (maxLength == null) { - maxLength = thisRef.typeMap[name]!!.size - 2 - } - return maxLength!! - } - + name: String +) : ByteArrayPropertyWithLength(name) { override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): String { return thisRef.data.getString(getIndex(thisRef)) } @@ -116,8 +125,37 @@ class StringProperty( } } +class ClobProperty( + name: String +) : ByteArrayPropertyWithLength(name) { + override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): String { + return thisRef.data.getClob(getIndex(thisRef)) + } + + override fun setValue(thisRef: TypedByteArray, property: KProperty<*>, value: String) { + thisRef.data.setClob(getIndex(thisRef), value, getMaxLength(thisRef)) + } +} + +class BlobProperty( + name: String +) : ByteArrayPropertyWithLength(name) { + override fun getValue(thisRef: TypedByteArray, property: KProperty<*>): ByteArray { + return thisRef.data.getBlob(getIndex(thisRef)) + } + + override fun setValue(thisRef: TypedByteArray, property: KProperty<*>, value: ByteArray) { + thisRef.data.setBlob(getIndex(thisRef), value, getMaxLength(thisRef)) + } +} + +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 string(propertyName: String) = StringProperty(propertyName) +fun clob(propertyName: String) = ClobProperty(propertyName) +fun blob(propertyName: String) = BlobProperty(propertyName) diff --git a/src/commonTest/kotlin/nl/astraeus/tba/ExtendedByteArrayDefinition.kt b/src/commonTest/kotlin/nl/astraeus/tba/ExtendedByteArrayDefinition.kt index 53fcdd0..ac9d305 100644 --- a/src/commonTest/kotlin/nl/astraeus/tba/ExtendedByteArrayDefinition.kt +++ b/src/commonTest/kotlin/nl/astraeus/tba/ExtendedByteArrayDefinition.kt @@ -9,7 +9,7 @@ class ExtendedByteArrayDefinition { open class MessageByteArray( vararg types: Type ) : TypedByteArray( - BaseByteArrayDefinition( + ByteArrayDefinition( Type("messageType", DataType.BYTE), Type("messageLength", DataType.SHORT), Type("message", DataType.STRING, 1024), @@ -21,7 +21,7 @@ class ExtendedByteArrayDefinition { var message by string("message") } - class MessageBlaat() : MessageByteArray( + class PersonMessage() : MessageByteArray( Type("name", DataType.STRING, 10), Type("age", DataType.BYTE), Type("length", DataType.SHORT), @@ -54,7 +54,7 @@ class ExtendedByteArrayDefinition { @Test fun testSimpleTypedByteArray() { val exception = assertFailsWith(IllegalArgumentException::class) { - MessageBlaat( + PersonMessage( 12, 123, "This is the message!", @@ -64,7 +64,7 @@ class ExtendedByteArrayDefinition { ) } - val msg = MessageBlaat( + val msg = PersonMessage( 12, 123, "This is the message!", diff --git a/src/commonTest/kotlin/nl/astraeus/tba/TypedByteArrayTest.kt b/src/commonTest/kotlin/nl/astraeus/tba/TypedByteArrayTest.kt index f2e3973..8cd2c2b 100644 --- a/src/commonTest/kotlin/nl/astraeus/tba/TypedByteArrayTest.kt +++ b/src/commonTest/kotlin/nl/astraeus/tba/TypedByteArrayTest.kt @@ -6,7 +6,7 @@ import kotlin.test.assertEquals class TypedByteArrayTest { class Person() : TypedByteArray( - BaseByteArrayDefinition( + ByteArrayDefinition( Type("name", DataType.STRING, 102), Type("age", DataType.BYTE), Type("length", DataType.SHORT),