diff --git a/app/src/test/java/de/kuschku/quasseldroid/ExampleUnitTest.kt b/app/src/test/java/de/kuschku/quasseldroid/ExampleUnitTest.kt index 990e5521979bb227f8f611b31699d6a4768ca349..920911ec3be3d160311679c341dbae119de781ca 100644 --- a/app/src/test/java/de/kuschku/quasseldroid/ExampleUnitTest.kt +++ b/app/src/test/java/de/kuschku/quasseldroid/ExampleUnitTest.kt @@ -1,6 +1,7 @@ package de.kuschku.quasseldroid -import de.kuschku.libquassel.protocol.connection.ProtocolInfoSerializer +import de.kuschku.bitflags.of +import de.kuschku.libquassel.protocol.connection.* import de.kuschku.libquassel.protocol.features.FeatureSet import de.kuschku.libquassel.protocol.io.ChainedByteBuffer import de.kuschku.libquassel.protocol.io.contentToString @@ -84,9 +85,22 @@ class ExampleUnitTest { println("Writing protocol") write(sizePrefix = false) { - UIntSerializer.serialize(it, 0x42b3_3f00u or 0x03u, connectionFeatureSet) - IntSerializer.serialize(it, 2, connectionFeatureSet) - UIntSerializer.serialize(it, 0x8000_0000u, connectionFeatureSet) + ConnectionHeaderSerializer.serialize( + it, + ConnectionHeader( + features = ProtocolFeature.of( + ProtocolFeature.Compression, + ProtocolFeature.TLS + ), + versions = listOf( + ProtocolMeta( + 0x0000u, + ProtocolVersion.Datastream, + ), + ) + ), + connectionFeatureSet + ) } println("Reading protocol") diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ConnectionHeader.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ConnectionHeader.kt new file mode 100644 index 0000000000000000000000000000000000000000..6e0d939d4dd3320930640d7eb65acf205b33ebcc --- /dev/null +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ConnectionHeader.kt @@ -0,0 +1,25 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2021 Janne Mareike Koschinski + * Copyright (c) 2021 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.connection + +data class ConnectionHeader( + val features: ProtocolFeatures, + val versions: List<ProtocolMeta> +) diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ConnectionHeaderSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ConnectionHeaderSerializer.kt new file mode 100644 index 0000000000000000000000000000000000000000..aea9cf66e2112d61a01910999c2c788c0ff65cbb --- /dev/null +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ConnectionHeaderSerializer.kt @@ -0,0 +1,87 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2021 Janne Mareike Koschinski + * Copyright (c) 2021 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.connection + +import de.kuschku.bitflags.of +import de.kuschku.bitflags.toBits +import de.kuschku.libquassel.protocol.features.FeatureSet +import de.kuschku.libquassel.protocol.io.ChainedByteBuffer +import de.kuschku.libquassel.protocol.serializers.primitive.Serializer +import de.kuschku.libquassel.protocol.serializers.primitive.UByteSerializer +import de.kuschku.libquassel.protocol.serializers.primitive.UIntSerializer +import java.nio.ByteBuffer + +object ConnectionHeaderSerializer : Serializer<ConnectionHeader> { + private const val magic: UInt = 0x42b3_3f00u + private const val featureMask: UInt = 0x0000_00ffu + private const val lastMagic: UByte = 0x80u + + private fun addMagic(data: UByte): UInt = + magic or data.toUInt() + + private fun removeMagic(data: UInt): UByte = + (data and featureMask).toUByte() + + private fun <T> writeList( + buffer: ChainedByteBuffer, + list: List<T>, + featureSet: FeatureSet, + f: (T) -> Unit + ) { + for (index in list.indices) { + val isLast = index + 1 == list.size + val magic = if (isLast) lastMagic else 0x00u + UByteSerializer.serialize(buffer, magic, featureSet) + f(list[index]) + } + } + + private fun <T> readList( + buffer: ByteBuffer, + featureSet: FeatureSet, + f: () -> T + ) : List<T> { + val list = mutableListOf<T>() + while (true) { + val isLast = UByteSerializer.deserialize(buffer, featureSet) != 0x00u.toUByte() + list.add(f()) + if (isLast) { + break + } + } + return list + } + + override fun serialize(buffer: ChainedByteBuffer, data: ConnectionHeader, featureSet: FeatureSet) { + UIntSerializer.serialize(buffer, addMagic(data.features.toBits()), featureSet) + writeList(buffer, data.versions, featureSet) { + ProtocolMetaSerializer.serialize(buffer, it, featureSet) + } + } + + override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet) = ConnectionHeader( + features = ProtocolFeature.of( + removeMagic(UIntSerializer.deserialize(buffer, featureSet)) + ), + versions = readList(buffer, featureSet) { + ProtocolMetaSerializer.deserialize(buffer, featureSet) + } + ) +} diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolFeature.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolFeature.kt new file mode 100644 index 0000000000000000000000000000000000000000..5ecc2de186cb03d43160ce1101a2881283c1e46b --- /dev/null +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolFeature.kt @@ -0,0 +1,39 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2021 Janne Mareike Koschinski + * Copyright (c) 2021 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.connection + +import de.kuschku.bitflags.Flag +import de.kuschku.bitflags.Flags +import de.kuschku.bitflags.toEnumSet + +enum class ProtocolFeature( + override val value: UByte, +) : Flag<UByte> { + None(0x00u), + TLS(0x01u), + Compression(0x02u); + + companion object : Flags<UByte, ProtocolFeature> { + private val values = values().associateBy(ProtocolFeature::value) + override val all: ProtocolFeatures = values.values.toEnumSet() + } +} + +typealias ProtocolFeatures = Set<ProtocolFeature> diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolInfo.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolInfo.kt index f71e8185e7249205bebe212f6b7e501277d16258..1ec8299c8aba98274fa379c491bbaa0a33a838b3 100644 --- a/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolInfo.kt +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolInfo.kt @@ -20,7 +20,6 @@ package de.kuschku.libquassel.protocol.connection data class ProtocolInfo( - val flags: UByte, - val data: UShort, - val version: UByte, + val flags: ProtocolFeatures, + val meta: ProtocolMeta, ) diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolInfoSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolInfoSerializer.kt index db699001ac4c963bbf2b958749070583e101d601..2a48500c063268fdfab0217bff75e48d4a229434 100644 --- a/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolInfoSerializer.kt +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolInfoSerializer.kt @@ -19,24 +19,22 @@ package de.kuschku.libquassel.protocol.connection +import de.kuschku.bitflags.of +import de.kuschku.bitflags.toBits import de.kuschku.libquassel.protocol.features.FeatureSet import de.kuschku.libquassel.protocol.io.ChainedByteBuffer +import de.kuschku.libquassel.protocol.serializers.primitive.Serializer import de.kuschku.libquassel.protocol.serializers.primitive.UByteSerializer -import de.kuschku.libquassel.protocol.serializers.primitive.UShortSerializer import java.nio.ByteBuffer -object ProtocolInfoSerializer { - fun serialize(buffer: ChainedByteBuffer, data: ProtocolInfo, featureSet: FeatureSet) { - UByteSerializer.serialize(buffer, data.flags, featureSet) - UShortSerializer.serialize(buffer, data.data, featureSet) - UByteSerializer.serialize(buffer, data.version, featureSet) +object ProtocolInfoSerializer : Serializer<ProtocolInfo> { + override fun serialize(buffer: ChainedByteBuffer, data: ProtocolInfo, featureSet: FeatureSet) { + UByteSerializer.serialize(buffer, data.flags.toBits(), featureSet) + ProtocolMetaSerializer.serialize(buffer, data.meta, featureSet) } - fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): ProtocolInfo { - return ProtocolInfo( - UByteSerializer.deserialize(buffer, featureSet), - UShortSerializer.deserialize(buffer, featureSet), - UByteSerializer.deserialize(buffer, featureSet) - ) - } + override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet) = ProtocolInfo( + ProtocolFeature.of(UByteSerializer.deserialize(buffer, featureSet)), + ProtocolMetaSerializer.deserialize(buffer, featureSet) + ) } diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolMeta.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolMeta.kt new file mode 100644 index 0000000000000000000000000000000000000000..f8c3323d766b943908a68270f12d8becda369987 --- /dev/null +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolMeta.kt @@ -0,0 +1,25 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2021 Janne Mareike Koschinski + * Copyright (c) 2021 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.connection + +data class ProtocolMeta( + val data: UShort, + val version: ProtocolVersion +) diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolMetaSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolMetaSerializer.kt new file mode 100644 index 0000000000000000000000000000000000000000..54628ff1c1a21f0055941b4e846a39061468a49d --- /dev/null +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolMetaSerializer.kt @@ -0,0 +1,39 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2021 Janne Mareike Koschinski + * Copyright (c) 2021 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.connection + +import de.kuschku.libquassel.protocol.features.FeatureSet +import de.kuschku.libquassel.protocol.io.ChainedByteBuffer +import de.kuschku.libquassel.protocol.serializers.primitive.Serializer +import de.kuschku.libquassel.protocol.serializers.primitive.UByteSerializer +import de.kuschku.libquassel.protocol.serializers.primitive.UShortSerializer +import java.nio.ByteBuffer + +object ProtocolMetaSerializer : Serializer<ProtocolMeta> { + override fun serialize(buffer: ChainedByteBuffer, data: ProtocolMeta, featureSet: FeatureSet) { + UShortSerializer.serialize(buffer, data.data, featureSet) + UByteSerializer.serialize(buffer, data.version.value, featureSet) + } + + override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet) = ProtocolMeta( + UShortSerializer.deserialize(buffer, featureSet), + ProtocolVersion.of(UByteSerializer.deserialize(buffer, featureSet)) + ) +} diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolVersion.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolVersion.kt new file mode 100644 index 0000000000000000000000000000000000000000..b4fc9e379af2a4ed2620fb627aaf417b23a89251 --- /dev/null +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/connection/ProtocolVersion.kt @@ -0,0 +1,33 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2021 Janne Mareike Koschinski + * Copyright (c) 2021 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.connection + +enum class ProtocolVersion( + val value: UByte, +) { + Legacy(0x01u), + Datastream(0x02u); + + companion object { + private val values = values().associateBy(ProtocolVersion::value) + fun of(value: UByte): ProtocolVersion = values[value] + ?: throw IllegalArgumentException("Protocol not supported: $value") + } +} diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/NoSerializerForTypeException.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/NoSerializerForTypeException.kt index 9ce61cef5e5da46faa7a00b01f41c8f6411293c2..b8519291cd378a013b5e2d8cd906f53a22f78f2a 100644 --- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/NoSerializerForTypeException.kt +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/NoSerializerForTypeException.kt @@ -31,6 +31,12 @@ sealed class NoSerializerForTypeException : Exception() { type: QtType, javaType: Class<*>? = null ) : this(type.id, javaType) + + override fun toString(): String { + return "NoSerializerForTypeException.Qt(type=$type, javaType=$javaType)" + } + + } data class Quassel( @@ -48,10 +54,18 @@ sealed class NoSerializerForTypeException : Exception() { type: QuasselType, javaType: Class<*>? = null ) : this(type.qtType, type.typeName, javaType) + + override fun toString(): String { + return "NoSerializerForTypeException.Quassel(type=$type, typename=$typename, javaType=$javaType)" + } } data class Handshake( private val type: String, private val javaType: Class<*>? = null - ) : NoSerializerForTypeException() + ) : NoSerializerForTypeException() { + override fun toString(): String { + return "NoSerializerForTypeException.Handshake(type='$type', javaType=$javaType)" + } + } } diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/QuasselSerializers.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/QuasselSerializers.kt index 59c3d014ddd2f5fd17d63ede0474c0ebf50f1f19..ed9ed2883d19fe2a801c12d4b5df8b9b0b1b97fd 100644 --- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/QuasselSerializers.kt +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/QuasselSerializers.kt @@ -27,8 +27,8 @@ object QuasselSerializers { private val serializers = listOf<QuasselSerializer<*>>( BufferIdSerializer, BufferInfoSerializer, - //DccConfigIpDetectionModeSerializer, - //DccConfigPortSelectionModeSerializer, + DccIpDetectionModeSerializer, + DccPortSelectionModeSerializer, //IrcUserSerializer, //IrcChannelSerializer, //IdentitySerializer, @@ -38,7 +38,7 @@ object QuasselSerializers { NetworkIdSerializer, //NetworkInfoSerializer, //NetworkServerSerializer, - //QHostAddressSerializer, + QHostAddressSerializer, PeerPtrSerializer, ).associateBy(QuasselSerializer<*>::quasselType) diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/DccIpDetectionModeSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/DccIpDetectionModeSerializer.kt new file mode 100644 index 0000000000000000000000000000000000000000..3f79c42b5f725927d5415fd30e4ec70ce828fb4d --- /dev/null +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/DccIpDetectionModeSerializer.kt @@ -0,0 +1,50 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.serializers.primitive + +import de.kuschku.libquassel.protocol.features.FeatureSet +import de.kuschku.libquassel.protocol.io.ChainedByteBuffer +import de.kuschku.libquassel.protocol.types.DccIpDetectionMode +import de.kuschku.libquassel.protocol.types.DccPortSelectionMode +import de.kuschku.libquassel.protocol.variant.QuasselType +import java.nio.ByteBuffer + +object DccIpDetectionModeSerializer : QuasselSerializer<DccIpDetectionMode?> { + override val quasselType: QuasselType = QuasselType.DccConfigIpDetectionMode + + @Suppress("UNCHECKED_CAST") + override val javaType: Class<out DccIpDetectionMode?> = + DccIpDetectionMode::class.java + + override fun serialize( + buffer: ChainedByteBuffer, + data: DccIpDetectionMode?, + featureSet: FeatureSet + ) { + UByteSerializer.serialize(buffer, data?.value ?: 0x00u, featureSet) + } + + override fun deserialize( + buffer: ByteBuffer, + featureSet: FeatureSet + ): DccIpDetectionMode? { + return DccIpDetectionMode.of(UByteSerializer.deserialize(buffer, featureSet)) + } +} diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/DccPortSelectionModeSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/DccPortSelectionModeSerializer.kt new file mode 100644 index 0000000000000000000000000000000000000000..6d1d10796a7d477bd3ca899757636ea75f7e09ae --- /dev/null +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/DccPortSelectionModeSerializer.kt @@ -0,0 +1,49 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.serializers.primitive + +import de.kuschku.libquassel.protocol.features.FeatureSet +import de.kuschku.libquassel.protocol.io.ChainedByteBuffer +import de.kuschku.libquassel.protocol.types.DccPortSelectionMode +import de.kuschku.libquassel.protocol.variant.QuasselType +import java.nio.ByteBuffer + +object DccPortSelectionModeSerializer : QuasselSerializer<DccPortSelectionMode?> { + override val quasselType: QuasselType = QuasselType.DccConfigPortSelectionMode + + @Suppress("UNCHECKED_CAST") + override val javaType: Class<out DccPortSelectionMode?> = + DccPortSelectionMode::class.java + + override fun serialize( + buffer: ChainedByteBuffer, + data: DccPortSelectionMode?, + featureSet: FeatureSet + ) { + UByteSerializer.serialize(buffer, data?.value ?: 0x00u, featureSet) + } + + override fun deserialize( + buffer: ByteBuffer, + featureSet: FeatureSet + ): DccPortSelectionMode? { + return DccPortSelectionMode.of(UByteSerializer.deserialize(buffer, featureSet)) + } +} diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QHostAddressSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QHostAddressSerializer.kt new file mode 100644 index 0000000000000000000000000000000000000000..be41946440ae25172b30abf9c9779190fda9093c --- /dev/null +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QHostAddressSerializer.kt @@ -0,0 +1,86 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.serializers.primitive + +import de.kuschku.libquassel.protocol.features.FeatureSet +import de.kuschku.libquassel.protocol.io.ChainedByteBuffer +import de.kuschku.libquassel.protocol.types.NetworkLayerProtocol +import de.kuschku.libquassel.protocol.variant.QuasselType +import java.net.Inet4Address +import java.net.Inet6Address +import java.net.InetAddress +import java.nio.ByteBuffer + +object QHostAddressSerializer : QuasselSerializer<InetAddress> { + override val quasselType: QuasselType = QuasselType.QHostAddress + override val javaType: Class<out InetAddress> = InetAddress::class.java + + override fun serialize( + buffer: ChainedByteBuffer, + data: InetAddress, + featureSet: FeatureSet + ) { + when (data) { + is Inet4Address -> { + UByteSerializer.serialize( + buffer, + NetworkLayerProtocol.IPv4Protocol.value, + featureSet + ) + buffer.put(data.address) + } + is Inet6Address -> { + UByteSerializer.serialize( + buffer, + NetworkLayerProtocol.IPv6Protocol.value, + featureSet + ) + buffer.put(data.address) + } + else -> { + UByteSerializer.serialize( + buffer, + NetworkLayerProtocol.UnknownNetworkLayerProtocol.value, + featureSet + ) + throw IllegalArgumentException("Invalid network protocol ${data.javaClass.canonicalName}") + } + } + } + + override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): InetAddress { + val type = UByteSerializer.deserialize(buffer, featureSet) + return when (NetworkLayerProtocol.of(type)) { + NetworkLayerProtocol.IPv4Protocol -> { + val buf = ByteArray(4) + buffer.get(buf) + Inet4Address.getByAddress(buf) + } + NetworkLayerProtocol.IPv6Protocol -> { + val buf = ByteArray(16) + buffer.get(buf) + Inet6Address.getByAddress(buf) + } + else -> { + throw IllegalArgumentException("Invalid network protocol $type") + } + } + } +} diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QtSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QtSerializer.kt index dfc7eeccb472e15df824cfeea12d7a14ce2d26bc..3e26d5b562c837512bf328111f697266618ec501 100644 --- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QtSerializer.kt +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QtSerializer.kt @@ -19,14 +19,9 @@ package de.kuschku.libquassel.protocol.serializers.primitive -import de.kuschku.libquassel.protocol.features.FeatureSet -import de.kuschku.libquassel.protocol.io.ChainedByteBuffer import de.kuschku.libquassel.protocol.variant.QtType -import java.nio.ByteBuffer -interface QtSerializer<T> { +interface QtSerializer<T> : Serializer<T> { val qtType: QtType val javaType: Class<out T> - fun serialize(buffer: ChainedByteBuffer, data: T, featureSet: FeatureSet) - fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): T } diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/Serializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/Serializer.kt new file mode 100644 index 0000000000000000000000000000000000000000..40dd0fc98ca17f33da390adfc911b7a8b0c648e4 --- /dev/null +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/Serializer.kt @@ -0,0 +1,29 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2021 Janne Mareike Koschinski + * Copyright (c) 2021 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.serializers.primitive + +import de.kuschku.libquassel.protocol.features.FeatureSet +import de.kuschku.libquassel.protocol.io.ChainedByteBuffer +import java.nio.ByteBuffer + +interface Serializer<T> { + fun serialize(buffer: ChainedByteBuffer, data: T, featureSet: FeatureSet) + fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): T +} diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/types/DccIpDetectionMode.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/types/DccIpDetectionMode.kt new file mode 100644 index 0000000000000000000000000000000000000000..dc6dc77b4202b0c11bdfd17f49b41dfe2ba1d74a --- /dev/null +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/types/DccIpDetectionMode.kt @@ -0,0 +1,37 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2021 Janne Mareike Koschinski + * Copyright (c) 2021 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.types + +/** + * Mode for detecting the outgoing IP + */ +enum class DccIpDetectionMode( + val value: UByte, +) { + /** Automatic detection (network socket or USERHOST) */ + Automatic(0x00u), + /** Manually specified IP */ + Manual(0x01u); + + companion object { + private val values = values().associateBy(DccIpDetectionMode::value) + fun of(value: UByte): DccIpDetectionMode? = values[value] + } +} diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/types/DccPortSelectionMode.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/types/DccPortSelectionMode.kt new file mode 100644 index 0000000000000000000000000000000000000000..705bed66e627ca84713bc46d15cb9e6f977250ae --- /dev/null +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/types/DccPortSelectionMode.kt @@ -0,0 +1,37 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2021 Janne Mareike Koschinski + * Copyright (c) 2021 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.types + +/** + * Mode for selecting the port range for DCC + */ +enum class DccPortSelectionMode( + val value: UByte, +) { + /** Automatic port selection */ + Automatic(0x00u), + /** Manually specified port range */ + Manual(0x01u); + + companion object { + private val values = values().associateBy(DccPortSelectionMode::value) + fun of(value: UByte): DccPortSelectionMode? = values[value] + } +} diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/types/NetworkLayerProtocol.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/types/NetworkLayerProtocol.kt new file mode 100644 index 0000000000000000000000000000000000000000..ccae5f617143ddd33b011691b65e7c2ff9fd4930 --- /dev/null +++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/types/NetworkLayerProtocol.kt @@ -0,0 +1,34 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.types + +enum class NetworkLayerProtocol( + val value: UByte, +) { + IPv4Protocol(0x00u), + IPv6Protocol(0x01u), + AnyIPProtocol(0x02u), + UnknownNetworkLayerProtocol(0xFFu); + + companion object { + private val values = values().associateBy(NetworkLayerProtocol::value) + fun of(value: UByte): NetworkLayerProtocol? = values[value] + } +} diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/connection/ConnectionHeaderSerializerTest.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/connection/ConnectionHeaderSerializerTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..0aaf86216359c525f915aac66e3bb6d725202ae8 --- /dev/null +++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/connection/ConnectionHeaderSerializerTest.kt @@ -0,0 +1,97 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2021 Janne Mareike Koschinski + * Copyright (c) 2021 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.protocol.connection + +import de.kuschku.bitflags.of +import de.kuschku.libquassel.protocol.testutil.byteBufferOf +import de.kuschku.libquassel.protocol.testutil.serializerTest +import org.junit.jupiter.api.Test + +class ConnectionHeaderSerializerTest { + @Test + fun testQuasseldroid() = serializerTest( + ConnectionHeaderSerializer, + ConnectionHeader( + features = ProtocolFeature.of( + ProtocolFeature.TLS, + ProtocolFeature.Compression, + ), + versions = listOf( + ProtocolMeta( + data = 0x0000u, + version = ProtocolVersion.Datastream, + ) + ) + ), + byteBufferOf( + 0x42u, 0xb3u, 0x3fu, 0x03u, + 0x80u, 0x00u, 0x00u, 0x02u + ) + ) + + @Test + fun testQuasselClient() = serializerTest( + ConnectionHeaderSerializer, + ConnectionHeader( + features = ProtocolFeature.of( + ProtocolFeature.TLS, + ProtocolFeature.Compression, + ), + versions = listOf( + ProtocolMeta( + data = 0x0000u, + version = ProtocolVersion.Legacy, + ), + ProtocolMeta( + data = 0x0000u, + version = ProtocolVersion.Datastream, + ) + ) + ), + byteBufferOf( + 0x42u, 0xb3u, 0x3fu, 0x03u, + 0x00u, 0x00u, 0x00u, 0x01u, + 0x80u, 0x00u, 0x00u, 0x02u + ) + ) + + @Test + fun testDebugClient() = serializerTest( + ConnectionHeaderSerializer, + ConnectionHeader( + features = ProtocolFeature.of( ), + versions = listOf( + ProtocolMeta( + data = 0x0000u, + version = ProtocolVersion.Legacy, + ), + ProtocolMeta( + data = 0x0000u, + version = ProtocolVersion.Datastream, + ) + ) + ), + byteBufferOf( + 0x42u, 0xb3u, 0x3fu, 0x00u, + 0x00u, 0x00u, 0x00u, 0x01u, + 0x80u, 0x00u, 0x00u, 0x02u + ) + ) +} diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/DccIpDetectionModeSerializerTest.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/DccIpDetectionModeSerializerTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..901267d4f1e26fcc8dddb65ac5ed9ded56353967 --- /dev/null +++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/DccIpDetectionModeSerializerTest.kt @@ -0,0 +1,54 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package de.kuschku.libquassel.protocol.serializers.primitive + +import de.kuschku.libquassel.protocol.serializers.QuasselSerializers +import de.kuschku.libquassel.protocol.testutil.byteBufferOf +import de.kuschku.libquassel.protocol.testutil.quasselSerializerTest +import de.kuschku.libquassel.protocol.types.DccIpDetectionMode +import de.kuschku.libquassel.protocol.types.DccPortSelectionMode +import de.kuschku.libquassel.protocol.variant.QuasselType +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +class DccIpDetectionModeSerializerTest { + @Test + fun testIsRegistered() { + assertEquals( + DccIpDetectionModeSerializer, + QuasselSerializers.find<DccIpDetectionMode>( + QuasselType.DccConfigIpDetectionMode + ), + ) + } + + @Test + fun testAutomatic() = quasselSerializerTest( + DccIpDetectionModeSerializer, + DccIpDetectionMode.Automatic, + byteBufferOf(0x00u) + ) + + @Test + fun testManual() = quasselSerializerTest( + DccIpDetectionModeSerializer, + DccIpDetectionMode.Manual, + byteBufferOf(0x01u) + ) +} diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/DccPortSelectionModeSerializerTest.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/DccPortSelectionModeSerializerTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..aeeca6e97e3445155d278a6639ae5d03c993ed6c --- /dev/null +++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/DccPortSelectionModeSerializerTest.kt @@ -0,0 +1,54 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package de.kuschku.libquassel.protocol.serializers.primitive + +import de.kuschku.libquassel.protocol.serializers.QuasselSerializers +import de.kuschku.libquassel.protocol.testutil.byteBufferOf +import de.kuschku.libquassel.protocol.testutil.quasselSerializerTest +import de.kuschku.libquassel.protocol.types.DccIpDetectionMode +import de.kuschku.libquassel.protocol.types.DccPortSelectionMode +import de.kuschku.libquassel.protocol.variant.QuasselType +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +class DccPortSelectionModeSerializerTest { + @Test + fun testIsRegistered() { + assertEquals( + DccPortSelectionModeSerializer, + QuasselSerializers.find<DccPortSelectionMode>( + QuasselType.DccConfigPortSelectionMode + ), + ) + } + + @Test + fun testAutomatic() = quasselSerializerTest( + DccPortSelectionModeSerializer, + DccPortSelectionMode.Automatic, + byteBufferOf(0x00u) + ) + + @Test + fun testManual() = quasselSerializerTest( + DccPortSelectionModeSerializer, + DccPortSelectionMode.Manual, + byteBufferOf(0x01u) + ) +} diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/QHostAddressSerializerTest.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/QHostAddressSerializerTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..08de96efb92b3dbba58ab0b2de97f76ef6dbccc5 --- /dev/null +++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/QHostAddressSerializerTest.kt @@ -0,0 +1,65 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package de.kuschku.libquassel.protocol.serializers.primitive + +import de.kuschku.libquassel.protocol.serializers.QuasselSerializers +import de.kuschku.libquassel.protocol.testutil.byteBufferOf +import de.kuschku.libquassel.protocol.testutil.quasselSerializerTest +import de.kuschku.libquassel.protocol.variant.QuasselType +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import java.net.Inet4Address +import java.net.Inet6Address +import java.net.InetAddress + +class QHostAddressSerializerTest { + @Test + fun testIsRegistered() { + assertEquals( + QHostAddressSerializer, + QuasselSerializers.find<InetAddress>( + QuasselType.QHostAddress + ), + ) + } + + @Test + fun testIpv4() = quasselSerializerTest( + QHostAddressSerializer, + Inet4Address.getByAddress(byteArrayOf( + 127, 0, 0, 1 + )), + byteBufferOf( + 0x00, + 127, 0, 0, 1 + ) + ) + + @Test + fun testIpv6() = quasselSerializerTest( + QHostAddressSerializer, + Inet6Address.getByAddress(ubyteArrayOf( + 0x26u, 0x07u, 0xf1u, 0x88u, 0x00u, 0x00u, 0x00u, 0x00u, 0xdeu, 0xadu, 0xbeu, 0xefu, 0xcau, 0xfeu, 0xfeu, 0xd1u, + ).toByteArray()), + byteBufferOf( + 0x01u, + 0x26u, 0x07u, 0xf1u, 0x88u, 0x00u, 0x00u, 0x00u, 0x00u, 0xdeu, 0xadu, 0xbeu, 0xefu, 0xcau, 0xfeu, 0xfeu, 0xd1u, + ) + ) +} diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/deserialize.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/deserialize.kt index 38acc37ea2907735e3b25fd831da02352efbd2c4..aec66f4049da7457ebd7a47b0aef4a2eb21b8026 100644 --- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/deserialize.kt +++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/deserialize.kt @@ -22,13 +22,14 @@ import de.kuschku.libquassel.protocol.features.FeatureSet import de.kuschku.libquassel.protocol.serializers.handshake.HandshakeSerializer import de.kuschku.libquassel.protocol.serializers.primitive.HandshakeMapSerializer import de.kuschku.libquassel.protocol.serializers.primitive.QtSerializer +import de.kuschku.libquassel.protocol.serializers.primitive.Serializer import org.hamcrest.Matcher import org.hamcrest.MatcherAssert.assertThat import org.junit.jupiter.api.Assertions.assertEquals import java.nio.ByteBuffer fun <T> deserialize( - serializer: QtSerializer<T>, + serializer: Serializer<T>, buffer: ByteBuffer, featureSet: FeatureSet = FeatureSet.all() ): T { @@ -38,7 +39,7 @@ fun <T> deserialize( } fun <T> testDeserialize( - serializer: QtSerializer<T>, + serializer: Serializer<T>, matcher: Matcher<in T>, buffer: ByteBuffer, featureSet: FeatureSet = FeatureSet.all() @@ -48,7 +49,7 @@ fun <T> testDeserialize( } fun <T> testDeserialize( - serializer: QtSerializer<T>, + serializer: Serializer<T>, data: T, buffer: ByteBuffer, featureSet: FeatureSet = FeatureSet.all() diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/serialize.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/serialize.kt index fca9603c923d779cd593ba1dd8842eaff800498a..d389756f23cea6bc0589c9dea36fc3b08cef9a63 100644 --- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/serialize.kt +++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/serialize.kt @@ -23,6 +23,7 @@ import de.kuschku.libquassel.protocol.io.ChainedByteBuffer import de.kuschku.libquassel.protocol.serializers.handshake.HandshakeSerializer import de.kuschku.libquassel.protocol.serializers.primitive.HandshakeMapSerializer import de.kuschku.libquassel.protocol.serializers.primitive.QtSerializer +import de.kuschku.libquassel.protocol.serializers.primitive.Serializer import de.kuschku.libquassel.protocol.testutil.matchers.ByteBufferMatcher import org.hamcrest.Matcher import org.hamcrest.MatcherAssert.assertThat @@ -30,7 +31,7 @@ import org.junit.jupiter.api.Assertions.assertEquals import java.nio.ByteBuffer fun <T> serialize( - serializer: QtSerializer<T>, + serializer: Serializer<T>, data: T, featureSet: FeatureSet = FeatureSet.all() ): ByteBuffer { @@ -40,7 +41,7 @@ fun <T> serialize( } fun <T> testSerialize( - serializer: QtSerializer<T>, + serializer: Serializer<T>, data: T, buffer: ByteBuffer, featureSet: FeatureSet = FeatureSet.all() diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/serializerTest.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/serializerTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..e6d4299d885754bfab68fffb27efb5fb20e70562 --- /dev/null +++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/serializerTest.kt @@ -0,0 +1,46 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2021 Janne Mareike Koschinski + * Copyright (c) 2021 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package de.kuschku.libquassel.protocol.testutil + +import de.kuschku.libquassel.protocol.features.FeatureSet +import de.kuschku.libquassel.protocol.serializers.primitive.Serializer +import org.hamcrest.Matcher +import java.nio.ByteBuffer + +fun <T : Any?> serializerTest( + serializer: Serializer<T>, + value: T, + encoded: ByteBuffer? = null, + matcher: ((T) -> Matcher<T>)? = null, + deserializeFeatureSet: FeatureSet? = FeatureSet.all(), + serializeFeatureSet: FeatureSet? = FeatureSet.all(), +) { + if (encoded != null) { + if (deserializeFeatureSet != null) { + if (matcher != null) { + testDeserialize(serializer, matcher(value), encoded.rewind(), deserializeFeatureSet) + } else { + testDeserialize(serializer, value, encoded.rewind(), deserializeFeatureSet) + } + } + if (serializeFeatureSet != null) { + testSerialize(serializer, value, encoded.rewind(), serializeFeatureSet) + } + } +}