Skip to content
Snippets Groups Projects
Verified Commit 00aa4fb3 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

Implement more (de-)serializers

parent edf011c4
Branches
No related tags found
1 merge request!2Draft: Jetpack compose rewrite
Showing
with 665 additions and 35 deletions
package de.kuschku.quasseldroid package de.kuschku.quasseldroid
import de.kuschku.bitflags.flags import de.kuschku.bitflags.of
import de.kuschku.libquassel.protocol.connection.ProtocolInfoSerializer import de.kuschku.libquassel.protocol.connection.ProtocolInfoSerializer
import de.kuschku.libquassel.protocol.features.FeatureSet import de.kuschku.libquassel.protocol.features.FeatureSet
import de.kuschku.libquassel.protocol.features.LegacyFeature
import de.kuschku.libquassel.protocol.features.QuasselFeature
import de.kuschku.libquassel.protocol.io.ChainedByteBuffer import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
import de.kuschku.libquassel.protocol.io.print
import de.kuschku.libquassel.protocol.messages.handshake.ClientInit import de.kuschku.libquassel.protocol.messages.handshake.ClientInit
import de.kuschku.libquassel.protocol.serializers.handshake.ClientInitAckSerializer import de.kuschku.libquassel.protocol.serializers.handshake.ClientInitAckSerializer
import de.kuschku.libquassel.protocol.serializers.handshake.ClientInitRejectSerializer import de.kuschku.libquassel.protocol.serializers.handshake.ClientInitRejectSerializer
...@@ -15,7 +16,6 @@ import de.kuschku.libquassel.protocol.serializers.primitive.UIntSerializer ...@@ -15,7 +16,6 @@ import de.kuschku.libquassel.protocol.serializers.primitive.UIntSerializer
import de.kuschku.libquassel.protocol.variant.into import de.kuschku.libquassel.protocol.variant.into
import de.kuschku.quasseldroid.protocol.io.CoroutineChannel import de.kuschku.quasseldroid.protocol.io.CoroutineChannel
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
import java.net.InetSocketAddress import java.net.InetSocketAddress
import java.nio.ByteBuffer import java.nio.ByteBuffer
...@@ -44,7 +44,7 @@ class ExampleUnitTest { ...@@ -44,7 +44,7 @@ class ExampleUnitTest {
}), null) }), null)
runBlocking { runBlocking {
val connectionFeatureSet = FeatureSet.build() val connectionFeatureSet = FeatureSet.all()
val sizeBuffer = ByteBuffer.allocateDirect(4) val sizeBuffer = ByteBuffer.allocateDirect(4)
val sendBuffer = ChainedByteBuffer(direct = true) val sendBuffer = ChainedByteBuffer(direct = true)
val channel = CoroutineChannel() val channel = CoroutineChannel()
...@@ -105,8 +105,8 @@ class ExampleUnitTest { ...@@ -105,8 +105,8 @@ class ExampleUnitTest {
ClientInitSerializer.serialize(ClientInit( ClientInitSerializer.serialize(ClientInit(
clientVersion = "Quasseldroid test", clientVersion = "Quasseldroid test",
buildDate = "Never", buildDate = "Never",
clientFeatures = flags(), clientFeatures = connectionFeatureSet.legacyFeatures(),
featureList = emptyList() featureList = connectionFeatureSet.featureList()
)), )),
connectionFeatureSet connectionFeatureSet
) )
......
...@@ -19,10 +19,26 @@ ...@@ -19,10 +19,26 @@
package de.kuschku.bitflags package de.kuschku.bitflags
interface Flags<T, U : Flag<T>> { import java.util.*
interface Flags<T, U> where U: Flag<T>, U: Enum<U> {
operator fun get(value: T): U? operator fun get(value: T): U?
fun all(): Collection<U> fun all(): Collection<U>
} }
inline fun <reified T> flags(vararg values: T) where T : Flag<*>, T : Enum<T> = setOf(*values) inline fun <reified T> Flags<*, T>.of(
inline fun <reified T> flags(values: Collection<T>) where T : Flag<*>, T : Enum<T> = values.toSet() vararg values: T
) where T: Flag<*>, T: Enum<T> = values.toEnumSet()
inline fun <reified T> Flags<*, T>.of(
values: Collection<T>
) where T: Flag<*>, T: Enum<T> = values.toEnumSet()
inline fun <reified T: Enum<T>> Array<out T>.toEnumSet() =
EnumSet.noneOf(T::class.java).apply {
addAll(this@toEnumSet)
}
inline fun <reified T: Enum<T>> Collection<T>.toEnumSet() =
EnumSet.noneOf(T::class.java).apply {
addAll(this@toEnumSet)
}
...@@ -22,42 +22,42 @@ package de.kuschku.bitflags ...@@ -22,42 +22,42 @@ package de.kuschku.bitflags
import java.util.* import java.util.*
import kotlin.experimental.and import kotlin.experimental.and
inline fun <reified T> Flags<Byte, T>.toFlag(value: Byte?): EnumSet<T> where T: Flag<Byte>, T: Enum<T> { inline fun <reified T> Flags<Byte, T>.of(value: Byte?): EnumSet<T> where T: Flag<Byte>, T: Enum<T> {
if (value == null) return emptyList<T>().toEnumSet() if (value == null) return emptyList<T>().toEnumSet()
return this.all().filter { (value and it.value) != 0.toByte() }.toEnumSet() return this.all().filter { (value and it.value) != 0.toByte() }.toEnumSet()
} }
inline fun <reified T> Flags<UByte, T>.toFlag(value: UByte?): EnumSet<T> where T: Flag<UByte>, T: Enum<T> { inline fun <reified T> Flags<UByte, T>.of(value: UByte?): EnumSet<T> where T: Flag<UByte>, T: Enum<T> {
if (value == null) return emptyList<T>().toEnumSet() if (value == null) return emptyList<T>().toEnumSet()
return this.all().filter { (value and it.value) != 0.toUByte() }.toEnumSet() return this.all().filter { (value and it.value) != 0.toUByte() }.toEnumSet()
} }
inline fun <reified T> Flags<Short, T>.toFlag(value: Short?): EnumSet<T> where T: Flag<Short>, T: Enum<T> { inline fun <reified T> Flags<Short, T>.of(value: Short?): EnumSet<T> where T: Flag<Short>, T: Enum<T> {
if (value == null) return emptyList<T>().toEnumSet() if (value == null) return emptyList<T>().toEnumSet()
return this.all().filter { (value and it.value) != 0.toShort() }.toEnumSet() return this.all().filter { (value and it.value) != 0.toShort() }.toEnumSet()
} }
inline fun <reified T> Flags<UShort, T>.toFlag(value: UShort?): EnumSet<T> where T: Flag<UShort>, T: Enum<T> { inline fun <reified T> Flags<UShort, T>.of(value: UShort?): EnumSet<T> where T: Flag<UShort>, T: Enum<T> {
if (value == null) return emptyList<T>().toEnumSet() if (value == null) return emptyList<T>().toEnumSet()
return this.all().filter { (value and it.value) != 0.toUShort() }.toEnumSet() return this.all().filter { (value and it.value) != 0.toUShort() }.toEnumSet()
} }
inline fun <reified T> Flags<Int, T>.toFlag(value: Int?): EnumSet<T> where T: Flag<Int>, T: Enum<T> { inline fun <reified T> Flags<Int, T>.of(value: Int?): EnumSet<T> where T: Flag<Int>, T: Enum<T> {
if (value == null) return emptyList<T>().toEnumSet() if (value == null) return emptyList<T>().toEnumSet()
return this.all().filter { (value and it.value) != 0 }.toEnumSet() return this.all().filter { (value and it.value) != 0 }.toEnumSet()
} }
inline fun <reified T> Flags<UInt, T>.toFlag(value: UInt?): EnumSet<T> where T: Flag<UInt>, T: Enum<T> { inline fun <reified T> Flags<UInt, T>.of(value: UInt?): EnumSet<T> where T: Flag<UInt>, T: Enum<T> {
if (value == null) return emptyList<T>().toEnumSet() if (value == null) return emptyList<T>().toEnumSet()
return this.all().filter { (value and it.value) != 0u }.toEnumSet() return this.all().filter { (value and it.value) != 0u }.toEnumSet()
} }
inline fun <reified T> Flags<Long, T>.toFlag(value: Long?): EnumSet<T> where T: Flag<Long>, T: Enum<T> { inline fun <reified T> Flags<Long, T>.of(value: Long?): EnumSet<T> where T: Flag<Long>, T: Enum<T> {
if (value == null) return emptyList<T>().toEnumSet() if (value == null) return emptyList<T>().toEnumSet()
return this.all().filter { (value and it.value) != 0L }.toEnumSet() return this.all().filter { (value and it.value) != 0L }.toEnumSet()
} }
inline fun <reified T> Flags<ULong, T>.toFlag(value: ULong?): EnumSet<T> where T: Flag<ULong>, T: Enum<T> { inline fun <reified T> Flags<ULong, T>.of(value: ULong?): EnumSet<T> where T: Flag<ULong>, T: Enum<T> {
if (value == null) return emptyList<T>().toEnumSet() if (value == null) return emptyList<T>().toEnumSet()
return this.all().filter { (value and it.value) != 0uL }.toEnumSet() return this.all().filter { (value and it.value) != 0uL }.toEnumSet()
} }
...@@ -4,6 +4,7 @@ plugins { ...@@ -4,6 +4,7 @@ plugins {
dependencies { dependencies {
implementation(kotlin("stdlib")) implementation(kotlin("stdlib"))
implementation("org.threeten", "threetenbp", "1.4.0")
api(project(":bitflags")) api(project(":bitflags"))
testImplementation("junit", "junit", "4.13.1") testImplementation("junit", "junit", "4.13.1")
......
...@@ -19,19 +19,19 @@ ...@@ -19,19 +19,19 @@
package de.kuschku.libquassel.protocol.features package de.kuschku.libquassel.protocol.features
import de.kuschku.bitflags.flags import de.kuschku.bitflags.of
class FeatureSet internal constructor( class FeatureSet internal constructor(
private val features: Set<QuasselFeature>, private val features: Set<QuasselFeature>,
private val additional: Set<QuasselFeatureName> = emptySet() private val additional: Set<QuasselFeatureName> = emptySet()
) { ) {
fun enabled(feature: QuasselFeature) = features.contains(feature) fun hasFeature(feature: QuasselFeature) = features.contains(feature)
fun featureList(): List<QuasselFeatureName> = fun featureList(): List<QuasselFeatureName> =
features.map(QuasselFeature::feature) + additional features.map(QuasselFeature::feature) + additional
fun legacyFeatures(): LegacyFeatures = fun legacyFeatures(): LegacyFeatures =
flags(features.mapNotNull(LegacyFeature.Companion::get)) LegacyFeature.of(features.mapNotNull(LegacyFeature.Companion::get))
companion object { companion object {
fun parse( fun parse(
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
package de.kuschku.libquassel.protocol.serializers.handshake package de.kuschku.libquassel.protocol.serializers.handshake
import de.kuschku.bitflags.toBits import de.kuschku.bitflags.toBits
import de.kuschku.bitflags.toFlag import de.kuschku.bitflags.of
import de.kuschku.libquassel.protocol.features.QuasselFeatureName import de.kuschku.libquassel.protocol.features.QuasselFeatureName
import de.kuschku.libquassel.protocol.features.LegacyFeature import de.kuschku.libquassel.protocol.features.LegacyFeature
import de.kuschku.libquassel.protocol.messages.handshake.ClientInitAck import de.kuschku.libquassel.protocol.messages.handshake.ClientInitAck
...@@ -37,7 +37,7 @@ object ClientInitAckSerializer : HandshakeSerializer<ClientInitAck> { ...@@ -37,7 +37,7 @@ object ClientInitAckSerializer : HandshakeSerializer<ClientInitAck> {
) )
override fun deserialize(data: QVariantMap) = ClientInitAck( override fun deserialize(data: QVariantMap) = ClientInitAck(
coreFeatures = LegacyFeature.toFlag(data["CoreFeatures"].into<UInt>()), coreFeatures = LegacyFeature.of(data["CoreFeatures"].into<UInt>()),
backendInfo = data["StorageBackends"].into(emptyList()), backendInfo = data["StorageBackends"].into(emptyList()),
authenticatorInfo = data["Authenticators"].into(emptyList()), authenticatorInfo = data["Authenticators"].into(emptyList()),
coreConfigured = data["Configured"].into(), coreConfigured = data["Configured"].into(),
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
package de.kuschku.libquassel.protocol.serializers.handshake package de.kuschku.libquassel.protocol.serializers.handshake
import de.kuschku.bitflags.toBits import de.kuschku.bitflags.toBits
import de.kuschku.bitflags.toFlag import de.kuschku.bitflags.of
import de.kuschku.libquassel.protocol.features.QuasselFeatureName import de.kuschku.libquassel.protocol.features.QuasselFeatureName
import de.kuschku.libquassel.protocol.features.LegacyFeature import de.kuschku.libquassel.protocol.features.LegacyFeature
import de.kuschku.libquassel.protocol.messages.handshake.ClientInit import de.kuschku.libquassel.protocol.messages.handshake.ClientInit
...@@ -45,7 +45,7 @@ object ClientInitSerializer : HandshakeSerializer<ClientInit> { ...@@ -45,7 +45,7 @@ object ClientInitSerializer : HandshakeSerializer<ClientInit> {
return ClientInit( return ClientInit(
clientVersion = data["ClientVersion"].into(), clientVersion = data["ClientVersion"].into(),
buildDate = data["ClientDate"].into(), buildDate = data["ClientDate"].into(),
clientFeatures = LegacyFeature.toFlag(data["Features"].into<UInt>()), clientFeatures = LegacyFeature.of(data["Features"].into<UInt>()),
featureList = data["FeatureList"].into(emptyList<String>()).map(::QuasselFeatureName), featureList = data["FeatureList"].into(emptyList<String>()).map(::QuasselFeatureName),
) )
} }
......
/*
* 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 de.kuschku.libquassel.protocol.types.BufferId
import de.kuschku.libquassel.protocol.variant.QuasselType
import java.nio.ByteBuffer
object BufferIdSerializer : QuasselSerializer<BufferId> {
override val quasselType: QuasselType = QuasselType.BufferId
override val javaType: Class<out BufferId> = BufferId::class.java
override fun serialize(buffer: ChainedByteBuffer, data: BufferId, featureSet: FeatureSet) {
IntSerializer.serialize(buffer, data.id, featureSet)
}
override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): BufferId {
return BufferId(IntSerializer.deserialize(buffer, featureSet))
}
}
/*
* 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.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.types.BufferInfo
import de.kuschku.libquassel.protocol.types.BufferType
import de.kuschku.libquassel.protocol.variant.QuasselType
import java.nio.ByteBuffer
object BufferInfoSerializer : QuasselSerializer<BufferInfo> {
override val quasselType: QuasselType = QuasselType.BufferInfo
override val javaType: Class<out BufferInfo> = BufferInfo::class.java
override fun serialize(buffer: ChainedByteBuffer, data: BufferInfo, featureSet: FeatureSet) {
BufferIdSerializer.serialize(buffer, data.bufferId, featureSet)
NetworkIdSerializer.serialize(buffer, data.networkId, featureSet)
UShortSerializer.serialize(buffer, data.type.toBits(), featureSet)
IntSerializer.serialize(buffer, data.groupId, featureSet)
StringSerializerUtf8.serialize(buffer, data.bufferName, featureSet)
}
override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): BufferInfo {
val bufferId = BufferIdSerializer.deserialize(buffer, featureSet)
val networkId = NetworkIdSerializer.deserialize(buffer, featureSet)
val type = BufferType.of(UShortSerializer.deserialize(buffer, featureSet))
val groupId = IntSerializer.deserialize(buffer, featureSet)
val bufferName = StringSerializerUtf8.deserialize(buffer, featureSet)
return BufferInfo(
bufferId = bufferId,
networkId = networkId,
type = type,
groupId = groupId,
bufferName = bufferName
)
}
}
/*
* 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.variant.QtType
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalTime
import org.threeten.bp.temporal.JulianFields
import java.nio.ByteBuffer
object DateSerializer : QtSerializer<LocalDate> {
override val qtType: QtType = QtType.QDate
override val javaType: Class<out LocalDate> = LocalDate::class.java
override fun serialize(buffer: ChainedByteBuffer, data: LocalDate, featureSet: FeatureSet) {
val julianDay = data.getLong(JulianFields.JULIAN_DAY).toInt()
IntSerializer.serialize(buffer, julianDay, featureSet)
}
override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): LocalDate {
val julianDay = IntSerializer.deserialize(buffer, featureSet).toLong()
return LocalDate.ofEpochDay(0).with(JulianFields.JULIAN_DAY, julianDay)
}
}
/*
* 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.TimeSpec
import de.kuschku.libquassel.protocol.variant.QtType
import org.threeten.bp.*
import org.threeten.bp.temporal.Temporal
import java.nio.ByteBuffer
object DateTimeSerializer : QtSerializer<Temporal> {
override val qtType: QtType = QtType.QDateTime
override val javaType: Class<out Temporal> = Temporal::class.java
override fun serialize(buffer: ChainedByteBuffer, data: Temporal, featureSet: FeatureSet) {
fun serialize(data: LocalDateTime, timeSpec: TimeSpec, offset: ZoneOffset? = null) {
DateSerializer.serialize(buffer, data.toLocalDate(), featureSet)
TimeSerializer.serialize(buffer, data.toLocalTime(), featureSet)
ByteSerializer.serialize(buffer, timeSpec.value, featureSet)
if (offset != null) {
IntSerializer.serialize(buffer, offset.totalSeconds, featureSet)
}
}
when (data) {
is LocalDateTime ->
serialize(data, TimeSpec.LocalUnknown)
is OffsetDateTime ->
serialize(data.toLocalDateTime(), TimeSpec.OffsetFromUTC, data.offset)
is ZonedDateTime ->
serialize(data.toLocalDateTime(), TimeSpec.OffsetFromUTC, data.offset)
is Instant ->
serialize(data.atOffset(ZoneOffset.UTC).toLocalDateTime(), TimeSpec.OffsetFromUTC)
else ->
throw IllegalArgumentException("Unsupported Format: ${data::class.java.canonicalName}")
}
}
override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): Temporal {
val julianDay = DateSerializer.deserialize(buffer, featureSet)
val localTime = TimeSerializer.deserialize(buffer, featureSet)
val localDateTime = LocalDateTime.of(julianDay, localTime)
val timeSpec = TimeSpec.of(ByteSerializer.deserialize(buffer, featureSet))
?: TimeSpec.LocalUnknown
return when (timeSpec) {
TimeSpec.LocalStandard,
TimeSpec.LocalUnknown,
TimeSpec.LocalDST ->
localDateTime
.atZone(ZoneId.systemDefault())
TimeSpec.OffsetFromUTC ->
localDateTime
.atOffset(ZoneOffset.ofTotalSeconds(
IntSerializer.deserialize(buffer, featureSet)))
.toInstant()
TimeSpec.UTC ->
localDateTime
.atOffset(ZoneOffset.UTC)
.toInstant()
}
}
}
/*
* 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 de.kuschku.libquassel.protocol.types.BufferId
import de.kuschku.libquassel.protocol.types.IdentityId
import de.kuschku.libquassel.protocol.variant.QuasselType
import java.nio.ByteBuffer
object IdentityIdSerializer : QuasselSerializer<IdentityId> {
override val quasselType: QuasselType = QuasselType.IdentityId
override val javaType: Class<out IdentityId> = IdentityId::class.java
override fun serialize(buffer: ChainedByteBuffer, data: IdentityId, featureSet: FeatureSet) {
IntSerializer.serialize(buffer, data.id, featureSet)
}
override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): IdentityId {
return IdentityId(IntSerializer.deserialize(buffer, featureSet))
}
}
/*
* 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.bitflags.of
import de.kuschku.bitflags.toBits
import de.kuschku.libquassel.protocol.features.FeatureSet
import de.kuschku.libquassel.protocol.features.QuasselFeature
import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
import de.kuschku.libquassel.protocol.types.Message
import de.kuschku.libquassel.protocol.types.MessageFlag
import de.kuschku.libquassel.protocol.types.MessageType
import de.kuschku.libquassel.protocol.variant.QuasselType
import org.threeten.bp.Instant
import java.nio.ByteBuffer
object MessageSerializer : QuasselSerializer<Message> {
override val quasselType: QuasselType = QuasselType.Message
override val javaType: Class<out Message> = Message::class.java
override fun serialize(buffer: ChainedByteBuffer, data: Message, featureSet: FeatureSet) {
MsgIdSerializer.serialize(buffer, data.messageId, featureSet)
if (featureSet.hasFeature(QuasselFeature.LongTime)) {
LongSerializer.serialize(buffer, data.time.toEpochMilli(), featureSet)
} else {
IntSerializer.serialize(buffer, data.time.epochSecond.toInt(), featureSet)
}
UIntSerializer.serialize(buffer, data.type.toBits(), featureSet)
UByteSerializer.serialize(buffer, data.flag.toBits().toUByte(), featureSet)
BufferInfoSerializer.serialize(buffer, data.bufferInfo, featureSet)
StringSerializerUtf8.serialize(buffer, data.sender, featureSet)
if (featureSet.hasFeature(QuasselFeature.SenderPrefixes)) {
StringSerializerUtf8.serialize(buffer, data.senderPrefixes, featureSet)
}
if (featureSet.hasFeature(QuasselFeature.RichMessages)) {
StringSerializerUtf8.serialize(buffer, data.realName, featureSet)
StringSerializerUtf8.serialize(buffer, data.avatarUrl, featureSet)
}
StringSerializerUtf8.serialize(buffer, data.content, featureSet)
}
override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): Message {
return Message(
messageId = MsgIdSerializer.deserialize(buffer, featureSet),
time = if (featureSet.hasFeature(QuasselFeature.LongTime))
Instant.ofEpochMilli(LongSerializer.deserialize(buffer, featureSet))
else
Instant.ofEpochSecond(IntSerializer.deserialize(buffer, featureSet).toLong()),
type = MessageType.of(UIntSerializer.deserialize(buffer, featureSet)),
flag = MessageFlag.of(
UByteSerializer.deserialize(buffer, featureSet).toUInt() and 0xffu
),
bufferInfo = BufferInfoSerializer.deserialize(buffer, featureSet),
sender = StringSerializerUtf8.deserialize(buffer, featureSet) ?: "",
senderPrefixes = if (featureSet.hasFeature(QuasselFeature.SenderPrefixes))
StringSerializerUtf8.deserialize(buffer, featureSet) ?: "" else "",
realName = if (featureSet.hasFeature(QuasselFeature.RichMessages))
StringSerializerUtf8.deserialize(buffer, featureSet) ?: "" else "",
avatarUrl = if (featureSet.hasFeature(QuasselFeature.RichMessages))
StringSerializerUtf8.deserialize(buffer, featureSet) ?: "" else "",
content = StringSerializerUtf8.deserialize(buffer, 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.kuschku.libquassel.protocol.serializers.primitive
import de.kuschku.libquassel.protocol.features.FeatureSet
import de.kuschku.libquassel.protocol.features.QuasselFeature
import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
import de.kuschku.libquassel.protocol.types.MsgId
import de.kuschku.libquassel.protocol.variant.QuasselType
import java.nio.ByteBuffer
object MsgIdSerializer : QuasselSerializer<MsgId> {
override val quasselType: QuasselType = QuasselType.MsgId
override val javaType: Class<out MsgId> = MsgId::class.java
override fun serialize(buffer: ChainedByteBuffer, data: MsgId, featureSet: FeatureSet) {
if (featureSet.hasFeature(QuasselFeature.LongMessageId)) {
LongSerializer.serialize(buffer, data.id, featureSet)
} else {
IntSerializer.serialize(buffer, data.id.toInt(), featureSet)
}
}
override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): MsgId {
return if (featureSet.hasFeature(QuasselFeature.LongMessageId)) {
MsgId(LongSerializer.deserialize(buffer, featureSet))
} else {
MsgId(IntSerializer.deserialize(buffer, featureSet).toLong())
}
}
}
/*
* 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 de.kuschku.libquassel.protocol.types.BufferId
import de.kuschku.libquassel.protocol.types.IdentityId
import de.kuschku.libquassel.protocol.types.NetworkId
import de.kuschku.libquassel.protocol.variant.QuasselType
import java.nio.ByteBuffer
object NetworkIdSerializer : QuasselSerializer<NetworkId> {
override val quasselType: QuasselType = QuasselType.NetworkId
override val javaType: Class<out NetworkId> = NetworkId::class.java
override fun serialize(buffer: ChainedByteBuffer, data: NetworkId, featureSet: FeatureSet) {
IntSerializer.serialize(buffer, data.id, featureSet)
}
override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): NetworkId {
return NetworkId(IntSerializer.deserialize(buffer, 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.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 de.kuschku.libquassel.protocol.variant.QuasselType
import java.nio.ByteBuffer
object PeerPtrSerializer : QuasselSerializer<ULong> {
override val quasselType: QuasselType = QuasselType.PeerPtr
override val javaType: Class<ULong> = ULong::class.java
override fun serialize(buffer: ChainedByteBuffer, data: ULong, featureSet: FeatureSet) {
buffer.putLong(data.toLong())
}
override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): ULong {
return buffer.getLong().toULong()
}
}
...@@ -26,23 +26,49 @@ import de.kuschku.libquassel.protocol.variant.QuasselType ...@@ -26,23 +26,49 @@ import de.kuschku.libquassel.protocol.variant.QuasselType
import java.util.* import java.util.*
object Serializers { object Serializers {
private val qtSerializers = listOf<QtSerializer<*>>( private val qtSerializers = setOf<QtSerializer<*>>(
VoidSerializer,
BoolSerializer, BoolSerializer,
UByteSerializer,
ByteSerializer,
ShortSerializer,
UShortSerializer,
IntSerializer, IntSerializer,
UIntSerializer, UIntSerializer,
LongSerializer,
ULongSerializer,
ByteBufferSerializer,
StringSerializerUtf16,
QCharSerializer, QCharSerializer,
QVariantMapSerializer,
QVariantListSerializer,
StringSerializerUtf16,
QStringListSerializer, QStringListSerializer,
ByteBufferSerializer,
DateSerializer,
TimeSerializer,
DateTimeSerializer,
LongSerializer,
ShortSerializer,
ByteSerializer,
ULongSerializer,
UShortSerializer,
UByteSerializer,
QVariantSerializer, QVariantSerializer,
QVariantListSerializer,
QVariantMapSerializer, BufferIdSerializer,
BufferInfoSerializer,
//DccConfigIpDetectionModeSerializer,
//DccConfigPortSelectionModeSerializer,
//IrcUserSerializer,
//IrcChannelSerializer,
//IdentitySerializer,
IdentityIdSerializer,
MessageSerializer,
MsgIdSerializer,
NetworkIdSerializer,
//NetworkInfoSerializer,
//NetworkServerSerializer,
//QHostAddressSerializer,
PeerPtrSerializer,
).associateBy(QtSerializer<*>::qtType) ).associateBy(QtSerializer<*>::qtType)
private val quasselSerializers = listOf<QuasselSerializer<*>>( private val quasselSerializers = listOf<QuasselSerializer<*>>(
......
/*
* 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.variant.QtType
import org.threeten.bp.LocalTime
import java.nio.ByteBuffer
object TimeSerializer : QtSerializer<LocalTime> {
override val qtType: QtType = QtType.QTime
override val javaType: Class<out LocalTime> = LocalTime::class.java
override fun serialize(buffer: ChainedByteBuffer, data: LocalTime, featureSet: FeatureSet) {
val millisecondOfDay = (data.toNanoOfDay() / 1000).toInt()
IntSerializer.serialize(buffer, millisecondOfDay, featureSet)
}
override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): LocalTime {
val millisecondOfDay = IntSerializer.deserialize(buffer, featureSet).toLong()
return LocalTime.ofNanoOfDay(millisecondOfDay * 1000)
}
}
/*
* 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 de.kuschku.libquassel.protocol.variant.QtType
import java.nio.ByteBuffer
object VoidSerializer : QtSerializer<Unit> {
override val qtType: QtType = QtType.Void
override val javaType: Class<out Unit> = Unit::class.java
override fun serialize(buffer: ChainedByteBuffer, data: Unit, featureSet: FeatureSet) = Unit
override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet) = Unit
}
/*
* 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
import de.kuschku.bitflags.Flag
import de.kuschku.bitflags.Flags
enum class BufferActivity(
override val value: UInt,
): Flag<UInt> {
NoActivity(0x00u),
OtherActivity(0x01u),
NewMessage(0x02u),
Highlight(0x04u);
companion object : Flags<UInt, BufferActivity> {
private val values = values().associateBy(BufferActivity::value)
override fun get(value: UInt) = values[value]
override fun all() = values.values
}
}
typealias BufferActivities = Set<BufferActivity>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment