Skip to content
Snippets Groups Projects
Verified Commit 7f3268d2 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski Committed by Janne Mareike Koschinski
Browse files

Split libquassel out from quasseldroid

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 1004 additions and 0 deletions
/*
* 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.justjanne.libquassel.messages.handshake
import de.justjanne.libquassel.protocol.variant.QVariantMap
import de.justjanne.libquassel.protocol.variant.QtType
import de.justjanne.libquassel.protocol.variant.qVariant
object ClientLoginAckSerializer : HandshakeSerializer<HandshakeMessage.ClientLoginAck> {
override val type: String = "ClientLoginAck"
override val javaType: Class<out HandshakeMessage.ClientLoginAck> =
HandshakeMessage.ClientLoginAck::class.java
override fun serialize(data: HandshakeMessage.ClientLoginAck) = mapOf(
"MsgType" to qVariant(type, QtType.QString),
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientLoginAck
}
/*
* 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.justjanne.libquassel.messages.handshake
import de.justjanne.libquassel.protocol.variant.QVariantMap
import de.justjanne.libquassel.protocol.variant.QtType
import de.justjanne.libquassel.protocol.variant.into
import de.justjanne.libquassel.protocol.variant.qVariant
object ClientLoginRejectSerializer : HandshakeSerializer<HandshakeMessage.ClientLoginReject> {
override val type: String = "ClientLoginReject"
override val javaType: Class<out HandshakeMessage.ClientLoginReject> =
HandshakeMessage.ClientLoginReject::class.java
override fun serialize(data: HandshakeMessage.ClientLoginReject) = mapOf(
"MsgType" to qVariant(type, QtType.QString),
"Error" to qVariant(data.errorString, QtType.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientLoginReject(
errorString = data["Error"].into()
)
}
/*
* 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.justjanne.libquassel.messages.handshake
import de.justjanne.libquassel.protocol.variant.QVariantMap
import de.justjanne.libquassel.protocol.variant.QtType
import de.justjanne.libquassel.protocol.variant.into
import de.justjanne.libquassel.protocol.variant.qVariant
object ClientLoginSerializer : HandshakeSerializer<HandshakeMessage.ClientLogin> {
override val type: String = "ClientLogin"
override val javaType: Class<out HandshakeMessage.ClientLogin> =
HandshakeMessage.ClientLogin::class.java
override fun serialize(data: HandshakeMessage.ClientLogin) = mapOf(
"MsgType" to qVariant(type, QtType.QString),
"User" to qVariant(data.user, QtType.QString),
"Password" to qVariant(data.password, QtType.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientLogin(
user = data["User"].into(),
password = data["Password"].into(),
)
}
/*
* 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.justjanne.libquassel.messages.handshake
import de.justjanne.libquassel.protocol.variant.QVariantMap
import de.justjanne.libquassel.protocol.variant.QtType
import de.justjanne.libquassel.protocol.variant.qVariant
object CoreSetupAckSerializer : HandshakeSerializer<HandshakeMessage.CoreSetupAck> {
override val type: String = "CoreSetupAck"
override val javaType: Class<out HandshakeMessage.CoreSetupAck> =
HandshakeMessage.CoreSetupAck::class.java
override fun serialize(data: HandshakeMessage.CoreSetupAck) = mapOf(
"MsgType" to qVariant(type, QtType.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.CoreSetupAck
}
/*
* 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.justjanne.libquassel.messages.handshake
import de.justjanne.libquassel.protocol.variant.QVariantMap
import de.justjanne.libquassel.protocol.variant.QtType
import de.justjanne.libquassel.protocol.variant.into
import de.justjanne.libquassel.protocol.variant.qVariant
object CoreSetupDataSerializer : HandshakeSerializer<HandshakeMessage.CoreSetupData> {
override val type: String = "CoreSetupData"
override val javaType: Class<out HandshakeMessage.CoreSetupData> =
HandshakeMessage.CoreSetupData::class.java
override fun serialize(data: HandshakeMessage.CoreSetupData) = mapOf(
"MsgType" to qVariant(type, QtType.QString),
"SetupData" to qVariant(
mapOf(
"AdminUser" to qVariant(data.adminUser, QtType.QString),
"AdminPasswd" to qVariant(data.adminPassword, QtType.QString),
"Backend" to qVariant(data.backend, QtType.QString),
"ConnectionProperties" to qVariant(data.setupData, QtType.QVariantMap),
"Authenticator" to qVariant(data.authenticator, QtType.QString),
"AuthProperties" to qVariant(data.authSetupData, QtType.QVariantMap),
),
QtType.QVariantMap
)
)
override fun deserialize(data: QVariantMap) =
data["SetupData"].into<QVariantMap>().let {
HandshakeMessage.CoreSetupData(
adminUser = it?.get("AdminUser").into(),
adminPassword = it?.get("AdminPasswd").into(),
backend = it?.get("Backend").into(),
setupData = it?.get("ConnectionProperties").into(),
authenticator = it?.get("Authenticator").into(),
authSetupData = it?.get("AuthProperties").into()
)
}
}
/*
* 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.justjanne.libquassel.messages.handshake
import de.justjanne.libquassel.protocol.variant.QVariantMap
import de.justjanne.libquassel.protocol.variant.QtType
import de.justjanne.libquassel.protocol.variant.into
import de.justjanne.libquassel.protocol.variant.qVariant
object CoreSetupRejectSerializer : HandshakeSerializer<HandshakeMessage.CoreSetupReject> {
override val type: String = "CoreSetupReject"
override val javaType: Class<out HandshakeMessage.CoreSetupReject> =
HandshakeMessage.CoreSetupReject::class.java
override fun serialize(data: HandshakeMessage.CoreSetupReject) = mapOf(
"MsgType" to qVariant(type, QtType.QString),
"Error" to qVariant(data.errorString, QtType.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.CoreSetupReject(
errorString = data["Error"].into()
)
}
/*
* 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.justjanne.libquassel.messages.handshake
import de.justjanne.libquassel.protocol.features.LegacyFeatures
import de.justjanne.libquassel.protocol.features.QuasselFeatureName
import de.justjanne.libquassel.protocol.variant.QVariantList
import de.justjanne.libquassel.protocol.variant.QVariantMap
sealed class HandshakeMessage {
data class ClientInit(
val clientVersion: String?,
val buildDate: String?,
val clientFeatures: LegacyFeatures,
val featureList: List<QuasselFeatureName>
) : HandshakeMessage()
data class ClientInitAck(
val coreFeatures: LegacyFeatures,
val coreConfigured: Boolean?,
val backendInfo: QVariantList,
val authenticatorInfo: QVariantList,
val featureList: List<QuasselFeatureName>
) : HandshakeMessage()
data class ClientInitReject(
val errorString: String?
) : HandshakeMessage()
data class ClientLogin(
val user: String?,
val password: String?
) : HandshakeMessage()
object ClientLoginAck : HandshakeMessage() {
override fun toString(): String {
return "ClientLoginAck"
}
}
data class ClientLoginReject(
val errorString: String?
) : HandshakeMessage()
object CoreSetupAck : HandshakeMessage() {
override fun toString(): String {
return "CoreSetupAck"
}
}
data class CoreSetupData(
val adminUser: String?,
val adminPassword: String?,
val backend: String?,
val setupData: QVariantMap?,
val authenticator: String?,
val authSetupData: QVariantMap?
) : HandshakeMessage()
data class CoreSetupReject(
val errorString: String?
) : HandshakeMessage()
data class SessionInit(
val identities: QVariantList?,
val bufferInfos: QVariantList?,
val networkIds: QVariantList?
) : HandshakeMessage()
}
/*
* 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.justjanne.libquassel.messages.handshake
import de.justjanne.libquassel.protocol.variant.QVariantMap
interface HandshakeSerializer<T> {
val type: String
val javaType: Class<out T>
fun serialize(data: T): QVariantMap
fun deserialize(data: QVariantMap): T
}
/*
* 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.justjanne.libquassel.messages.handshake
import de.justjanne.libquassel.protocol.serializers.NoSerializerForTypeException
object HandshakeSerializers {
private val serializers = listOf<HandshakeSerializer<*>>(
ClientInitSerializer,
ClientInitAckSerializer,
ClientInitRejectSerializer,
CoreSetupDataSerializer,
CoreSetupAckSerializer,
CoreSetupRejectSerializer,
ClientLoginSerializer,
ClientLoginAckSerializer,
ClientLoginRejectSerializer,
SessionInitSerializer,
).associateBy(HandshakeSerializer<*>::type)
operator fun get(type: String) = serializers[type]
@Suppress("UNCHECKED_CAST")
inline fun <reified T> find(type: String): HandshakeSerializer<T> {
val serializer = get(type)
?: throw NoSerializerForTypeException.Handshake(type, T::class.java)
if (serializer.javaType == T::class.java) {
return serializer as HandshakeSerializer<T>
} else {
throw NoSerializerForTypeException.Handshake(type, T::class.java)
}
}
}
/*
* 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.justjanne.libquassel.messages.handshake
import de.justjanne.libquassel.protocol.variant.QVariantMap
import de.justjanne.libquassel.protocol.variant.QtType
import de.justjanne.libquassel.protocol.variant.into
import de.justjanne.libquassel.protocol.variant.qVariant
object SessionInitSerializer : HandshakeSerializer<HandshakeMessage.SessionInit> {
override val type: String = "SessionInit"
override val javaType: Class<out HandshakeMessage.SessionInit> =
HandshakeMessage.SessionInit::class.java
override fun serialize(data: HandshakeMessage.SessionInit) = mapOf(
"MsgType" to qVariant(type, QtType.QString),
"SessionState" to qVariant(
mapOf(
"BufferInfos" to qVariant(data.bufferInfos, QtType.QVariantList),
"NetworkIds" to qVariant(data.networkIds, QtType.QVariantList),
"Identities" to qVariant(data.identities, QtType.QVariantList),
),
QtType.QVariantMap
)
)
override fun deserialize(data: QVariantMap) = data["SessionState"].into<QVariantMap>().let {
HandshakeMessage.SessionInit(
bufferInfos = it?.get("BufferInfos").into(),
networkIds = it?.get("NetworkIds").into(),
identities = it?.get("Identities").into(),
)
}
}
/*
* 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.justjanne.libquassel.messages.handshake
import de.justjanne.bitflags.none
import de.justjanne.libquassel.messages.testutil.byteBufferOf
import de.justjanne.libquassel.messages.testutil.handshakeSerializerTest
import de.justjanne.libquassel.protocol.features.FeatureSet
import de.justjanne.libquassel.protocol.features.LegacyFeature
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
class ClientInitSerializerTest {
@Test
fun testIsRegistered() {
assertEquals(
ClientInitSerializer,
HandshakeSerializers.find<HandshakeMessage.ClientInit>("ClientInit"),
)
}
@Test
fun testSimple() = handshakeSerializerTest(
ClientInitSerializer,
HandshakeMessage.ClientInit(
clientVersion = "Quasseldroid test",
buildDate = "Never",
clientFeatures = LegacyFeature.none(),
featureList = emptyList()
),
byteBufferOf(
0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x0Cu,
0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au,
0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x43u, 0x00u,
0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u,
0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u,
0x00u, 0x0Du, 0x43u, 0x6Cu, 0x69u, 0x65u, 0x6Eu, 0x74u,
0x56u, 0x65u, 0x72u, 0x73u, 0x69u, 0x6Fu, 0x6Eu, 0x00u,
0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x22u,
0x00u, 0x51u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u,
0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x64u,
0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x69u, 0x00u, 0x64u,
0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x73u,
0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u,
0x00u, 0x00u, 0x0Au, 0x43u, 0x6Cu, 0x69u, 0x65u, 0x6Eu,
0x74u, 0x44u, 0x61u, 0x74u, 0x65u, 0x00u, 0x00u, 0x00u,
0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x4Eu,
0x00u, 0x65u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x72u,
0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u,
0x08u, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u,
0x73u, 0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u,
0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u,
0x00u, 0x00u, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u,
0x72u, 0x65u, 0x4Cu, 0x69u, 0x73u, 0x74u, 0x00u, 0x00u,
0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u
)
)
@Test
fun testRealistic() = handshakeSerializerTest(
ClientInitSerializer,
HandshakeMessage.ClientInit(
clientVersion = "Quasseldroid <a href=\"https://git.kuschku.de/justJanne/QuasselDroid-ng/commit/" +
"b622ad63056b6054b06e09f8e1f1ef2b0c3aaf9a\">v1.3.3</a>",
buildDate = "2020-04-27T22:21:17Z",
clientFeatures = FeatureSet.all().legacyFeatures(),
featureList = FeatureSet.all().featureList()
)
)
}
/*
* 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.justjanne.libquassel.messages.testutil
import java.nio.ByteBuffer
@Suppress("NOTHING_TO_INLINE")
inline fun byteBufferOf(
vararg elements: Byte
): ByteBuffer = ByteBuffer.wrap(byteArrayOf(*elements))
@Suppress("NOTHING_TO_INLINE")
inline fun byteBufferOf(
vararg elements: UByte
): ByteBuffer = ByteBuffer.wrap(ubyteArrayOf(*elements).toByteArray())
@Suppress("NOTHING_TO_INLINE")
inline fun byteBufferOf(): ByteBuffer =
ByteBuffer.allocateDirect(0)
/*
* 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.justjanne.libquassel.messages.testutil
import de.justjanne.libquassel.messages.handshake.HandshakeSerializer
import de.justjanne.libquassel.protocol.features.FeatureSet
import de.justjanne.libquassel.protocol.serializers.Serializer
import de.justjanne.libquassel.protocol.serializers.qt.HandshakeMapSerializer
import org.hamcrest.Matcher
import org.hamcrest.MatcherAssert.assertThat
import org.junit.jupiter.api.Assertions.assertEquals
import java.nio.ByteBuffer
fun <T> deserialize(
serializer: Serializer<T>,
buffer: ByteBuffer,
featureSet: FeatureSet = FeatureSet.all()
): T {
val result = serializer.deserialize(buffer, featureSet)
assertEquals(0, buffer.remaining())
return result
}
fun <T> testDeserialize(
serializer: HandshakeSerializer<T>,
matcher: Matcher<in T>,
buffer: ByteBuffer,
featureSet: FeatureSet = FeatureSet.all()
) {
val map = deserialize(HandshakeMapSerializer, buffer, featureSet)
val after = serializer.deserialize(map)
assertThat(after, matcher)
}
fun <T> testDeserialize(
serializer: HandshakeSerializer<T>,
data: T,
buffer: ByteBuffer,
featureSet: FeatureSet = FeatureSet.all()
) {
val map = deserialize(HandshakeMapSerializer, buffer, featureSet)
val after = serializer.deserialize(map)
assertEquals(data, after)
}
/*
* 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.justjanne.libquassel.messages.testutil
import de.justjanne.libquassel.messages.handshake.HandshakeSerializer
import de.justjanne.libquassel.protocol.features.FeatureSet
import org.hamcrest.Matcher
import java.nio.ByteBuffer
fun <T> handshakeSerializerTest(
serializer: HandshakeSerializer<T>,
value: T,
encoded: ByteBuffer? = null,
matcher: ((T) -> Matcher<T>)? = null,
featureSets: List<FeatureSet> = listOf(FeatureSet.none(), FeatureSet.all()),
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)
}
}
for (featureSet in featureSets) {
testHandshakeSerializerDirect(serializer, value)
testHandshakeSerializerEncoded(serializer, value, featureSet)
}
}
/*
* 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.justjanne.libquassel.protocol.testutil.matchers
import org.hamcrest.BaseMatcher
import org.hamcrest.Description
class BomMatcherChar(private val expected: Char) : BaseMatcher<Char>() {
private val malformed = charArrayOf(
'\uFFFE', '\uFEFF', '\uFFFD', ''
)
override fun describeTo(description: Description?) {
description?.appendText(expected.toString())
}
override fun matches(item: Any?): Boolean {
if (item is Char) {
return (item == expected) || (item in malformed && expected in malformed)
}
return false
}
}
/*
* 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.justjanne.libquassel.protocol.testutil.matchers
import org.hamcrest.BaseMatcher
import org.hamcrest.Description
class BomMatcherString(private val expected: String?) : BaseMatcher<String?>() {
private val malformed = charArrayOf(
'￾', ''
)
override fun describeTo(description: Description?) {
description?.appendText(expected)
}
override fun matches(item: Any?) =
(item as? String)?.endsWith(expected?.trimStart(*malformed) ?: "") == true
}
/*
* 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.justjanne.libquassel.protocol.testutil.matchers
import de.justjanne.libquassel.protocol.io.contentToString
import de.justjanne.libquassel.protocol.io.isEmpty
import org.hamcrest.BaseMatcher
import org.hamcrest.Description
import java.nio.ByteBuffer
class ByteBufferMatcher(buffer: ByteBuffer?) : BaseMatcher<ByteBuffer>() {
private val expected = buffer?.let { original ->
val copy = ByteBuffer.allocateDirect(original.limit())
original.rewind()
copy.put(original)
copy.rewind()
original.rewind()
copy
}
override fun describeTo(description: Description?) {
description?.appendText(expected?.contentToString())
}
override fun describeMismatch(item: Any?, description: Description?) {
description?.appendText("was ")
description?.appendText((item as? ByteBuffer)?.rewind()?.contentToString())
}
override fun matches(item: Any?): Boolean {
val actual = item as? ByteBuffer
if (actual.isEmpty() && expected.isEmpty()) {
return true
}
return actual?.rewind()?.contentToString() == expected?.rewind()?.contentToString()
}
}
/*
* 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.justjanne.libquassel.protocol.testutil.matchers
import org.hamcrest.BaseMatcher
import org.hamcrest.Description
class MapMatcher<K, V>(
private val expected: Map<K, V>
) : BaseMatcher<Map<K, V>>() {
override fun describeTo(description: Description?) {
description?.appendText(expected.toString())
}
override fun describeMismatch(item: Any?, description: Description?) {
if (item is Map<*, *>) {
for (key in expected.keys) {
if (!item.containsKey(key)) {
description?.appendText(" did not have key $key")
}
if (expected[key] != item[key]) {
description?.appendText(" key $key was: ${item[key]} instead of ${expected[key]}")
}
}
} else {
description?.appendText("was: $item")
}
}
override fun matches(item: Any?): Boolean {
if (item is Map<*, *>) {
for (key in expected.keys) {
if (!item.containsKey(key)) {
return false
}
if (expected[key] != item[key]) {
return false
}
}
return true
} else {
return false
}
}
}
/*
* 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.justjanne.libquassel.protocol.testutil.matchers
import org.hamcrest.BaseMatcher
import org.hamcrest.Description
import org.threeten.bp.Instant
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime
import org.threeten.bp.LocalTime
import org.threeten.bp.OffsetDateTime
import org.threeten.bp.ZonedDateTime
import org.threeten.bp.temporal.Temporal
class TemporalMatcher<T : Temporal>(
private val expected: T
) : BaseMatcher<T>() {
override fun describeTo(description: Description?) {
description?.appendText(expected.toString())
}
override fun matches(item: Any?): Boolean {
return when {
expected is ZonedDateTime && item is ZonedDateTime ->
expected == item
expected is ZonedDateTime && item is OffsetDateTime ->
expected.toOffsetDateTime() == item
expected is OffsetDateTime && item is OffsetDateTime ->
expected == item
expected is LocalDateTime && item is LocalDateTime ->
expected == item
expected is LocalTime && item is LocalTime ->
expected == item
expected is LocalDate && item is LocalDate ->
expected == item
expected is Instant && item is Instant ->
expected == item
else ->
false
}
}
}
/*
* 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.justjanne.libquassel.messages.testutil
import de.justjanne.libquassel.messages.handshake.HandshakeSerializer
import de.justjanne.libquassel.protocol.features.FeatureSet
import de.justjanne.libquassel.protocol.io.ChainedByteBuffer
import de.justjanne.libquassel.protocol.serializers.Serializer
import de.justjanne.libquassel.protocol.serializers.qt.HandshakeMapSerializer
import de.justjanne.libquassel.protocol.testutil.matchers.ByteBufferMatcher
import org.hamcrest.MatcherAssert.assertThat
import java.nio.ByteBuffer
fun <T> serialize(
serializer: Serializer<T>,
data: T,
featureSet: FeatureSet = FeatureSet.all()
): ByteBuffer {
val buffer = ChainedByteBuffer()
serializer.serialize(buffer, data, featureSet)
return buffer.toBuffer()
}
fun <T> testSerialize(
serializer: HandshakeSerializer<T>,
data: T,
buffer: ByteBuffer,
featureSet: FeatureSet = FeatureSet.all()
) {
val map = serializer.serialize(data)
val after = serialize(HandshakeMapSerializer, map, featureSet)
assertThat(after, ByteBufferMatcher(buffer))
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment