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

Performance improvements

parent 5902cde0
No related branches found
No related tags found
No related merge requests found
Showing
with 475 additions and 272 deletions
......@@ -3,6 +3,7 @@ import org.gradle.api.Project
import org.gradle.kotlin.dsl.*
import org.jetbrains.kotlin.gradle.plugin.KaptAnnotationProcessorOptions
import org.jetbrains.kotlin.gradle.plugin.KaptExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.ByteArrayOutputStream
import java.util.*
......@@ -75,8 +76,11 @@ dependencies {
implementation(appCompat("cardview-v7"))
implementation(appCompat("recyclerview-v7"))
implementation("io.reactivex.rxjava2:rxjava:2.1.3")
implementation(appArch("lifecycle", "runtime", version = "1.0.0"))
implementation(appArch("lifecycle", "extensions"))
implementation(appArch("lifecycle", "reactivestreams"))
kapt(appArch("lifecycle", "compiler"))
implementation(appArch("persistence.room", "runtime"))
......@@ -104,6 +108,15 @@ dependencies {
androidTestImplementation("com.android.support.test:rules:0.5")
}
tasks.withType(KotlinCompile::class.java) {
kotlinOptions {
freeCompilerArgs = listOf(
"-Xno-param-assertions",
"-Xno-call-assertions"
)
}
}
fun cmd(vararg command: String) = try {
val stdOut = ByteArrayOutputStream()
exec {
......
package de.kuschku.quasseldroid_ng.service
import android.arch.lifecycle.LifecycleService
import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.Transformations
import android.content.Intent
import android.os.Binder
import de.kuschku.libquassel.protocol.*
import de.kuschku.libquassel.session.Backend
import de.kuschku.libquassel.session.CoreConnection
import de.kuschku.libquassel.session.Session
import de.kuschku.libquassel.session.SocketAddress
import de.kuschku.quasseldroid_ng.BuildConfig
import de.kuschku.quasseldroid_ng.R
import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase
import de.kuschku.libquassel.protocol.*
import de.kuschku.libquassel.session.*
import de.kuschku.quasseldroid_ng.util.AndroidHandlerService
import org.threeten.bp.Instant
import java.security.cert.X509Certificate
......@@ -24,21 +25,14 @@ class QuasselService : LifecycleService() {
override fun connect(address: SocketAddress, user: String, pass: String) {
disconnect()
val handlerService = AndroidHandlerService()
session.coreConnection = CoreConnection(session, address, handlerService)
session.coreConnection?.start()
session.connection.onNext(CoreConnection(session, address, handlerService))
session.connection.value.start()
session.userData = user to pass
connection.postValue(session.coreConnection)
}
override fun disconnect() {
session.cleanUp()
connection.postValue(null)
ABSENT.postValue(ConnectionState.DISCONNECTED)
}
private val connection = MutableLiveData<CoreConnection>()
val ABSENT = MutableLiveData<ConnectionState>()
}
private lateinit var database: QuasselDatabase
......
package de.kuschku.quasseldroid_ng.ui
import android.arch.lifecycle.LiveData
import android.arch.lifecycle.MutableLiveData
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.widget.Button
......@@ -11,16 +13,16 @@ import android.widget.TextView
import butterknife.BindView
import butterknife.ButterKnife
import de.kuschku.libquassel.session.Backend
import de.kuschku.libquassel.session.ConnectionState
import de.kuschku.libquassel.session.Session
import de.kuschku.libquassel.session.SocketAddress
import de.kuschku.libquassel.util.LoggingHandler
import de.kuschku.quasseldroid_ng.R
import de.kuschku.quasseldroid_ng.util.helper.stickyMapNotNull
import org.threeten.bp.Instant
import io.reactivex.disposables.Disposable
import org.threeten.bp.ZoneOffset
import org.threeten.bp.ZonedDateTime
import org.threeten.bp.format.DateTimeFormatter
import java.util.logging.Handler
import java.util.logging.LogManager
import java.util.logging.LogRecord
class MainActivity : ServiceBoundActivity() {
@BindView(R.id.host)
......@@ -47,37 +49,33 @@ class MainActivity : ServiceBoundActivity() {
@BindView(R.id.errorList)
lateinit var errorList: TextView
/*
private val status: LiveData<ConnectionState>
= stickySwitchMapNotNull(backend, Backend::status,
ConnectionState.DISCONNECTED)
*/
private val session: LiveData<Session?>
= stickyMapNotNull(backend, Backend::session, null)
private var subscription: Disposable? = null
private val state = MutableLiveData<ConnectionState>()
private var snackbar: Snackbar? = null
private val dateTimeFormatter: DateTimeFormatter = DateTimeFormatter.ISO_TIME
private val handler = object : Handler() {
override fun publish(p0: LogRecord?) {
if (p0 != null) {
private val handler = object : LoggingHandler() {
override fun log(logLevel: LogLevel, tag: String, message: String?, throwable: Throwable?) {
if (logLevel.ordinal < LogLevel.INFO.ordinal)
return
val time = dateTimeFormatter.format(ZonedDateTime.now(ZoneOffset.UTC))
runOnUiThread {
errorList.append(
dateTimeFormatter.format(Instant.ofEpochMilli(p0.millis).atZone(ZoneOffset.UTC)))
errorList.append(" ")
errorList.append(p0.loggerName)
errorList.append(": ")
errorList.append(p0.message)
errorList.append("\n")
errorList.append("$time $tag: ")
if (message != null) {
errorList.append(message)
}
if (throwable != null) {
errorList.append("\n")
errorList.append(Log.getStackTraceString(throwable))
}
errorList.append("\n")
}
override fun flush() {
}
override fun close() {
}
override fun isLoggable(logLevel: LogLevel, tag: String) = true
}
override fun onCreate(savedInstanceState: Bundle?) {
......@@ -126,11 +124,11 @@ class MainActivity : ServiceBoundActivity() {
override fun onStart() {
super.onStart()
LogManager.getLogManager().getLogger("").addHandler(handler)
LoggingHandler.loggingHandlers.add(handler)
}
override fun onStop() {
LogManager.getLogManager().getLogger("").removeHandler(handler)
LoggingHandler.loggingHandlers.remove(handler)
super.onStop()
}
}
......@@ -18,9 +18,9 @@ class AndroidHandlerService : HandlerService {
backendHandler.post(f)
}
private val parseThread = HandlerThread("parse", Process.THREAD_PRIORITY_BACKGROUND)
private val parseThread = HandlerThread("parse", Process.THREAD_PRIORITY_DISPLAY)
private val writeThread = HandlerThread("write", Process.THREAD_PRIORITY_BACKGROUND)
private val backendThread = HandlerThread("backend", Process.THREAD_PRIORITY_BACKGROUND)
private val backendThread = HandlerThread("backend", Process.THREAD_PRIORITY_DISPLAY)
private val parseHandler: Handler
private val writeHandler: Handler
......
package de.kuschku.quasseldroid_ng.util
import android.util.Log
import java.util.logging.Handler
import java.util.logging.Level
import java.util.logging.LogManager
import java.util.logging.LogRecord
import de.kuschku.libquassel.util.LoggingHandler
/**
* Make JUL work on Android.
*/
class AndroidLoggingHandler : Handler() {
override fun close() {}
override fun flush() {}
override fun publish(record: LogRecord) {
if (!super.isLoggable(record))
return
val name = record.loggerName
val maxLength = 30
val tag = if (name.length > maxLength) name.substring(name.length - maxLength) else name
try {
val level = getAndroidLevel(record.level)
Log.println(level, tag, record.message)
if (record.thrown != null) {
Log.println(level, tag, Log.getStackTraceString(record.thrown))
}
} catch (e: RuntimeException) {
Log.e("AndroidLoggingHandler", "Error logging message.", e)
object AndroidLoggingHandler : LoggingHandler() {
override fun isLoggable(logLevel: LogLevel, tag: String): Boolean {
return Log.isLoggable(tag, priority(logLevel))
}
override fun log(logLevel: LogLevel, tag: String, message: String?, throwable: Throwable?) {
val priority = priority(logLevel)
if (message != null)
Log.println(priority, tag, message)
if (throwable != null)
Log.println(priority, tag, Log.getStackTraceString(throwable))
}
companion object {
fun reset(rootHandler: Handler) {
val rootLogger = LogManager.getLogManager().getLogger("")
val handlers = rootLogger.handlers
for (handler in handlers) {
rootLogger.removeHandler(handler)
}
rootLogger.addHandler(rootHandler)
private fun priority(logLevel: LogLevel): Int = when (logLevel) {
LogLevel.VERBOSE -> Log.VERBOSE
LogLevel.DEBUG -> Log.DEBUG
LogLevel.INFO -> Log.INFO
LogLevel.WARN -> Log.WARN
LogLevel.ERROR -> Log.ERROR
LogLevel.ASSERT -> Log.ASSERT
}
fun init() {
reset(AndroidLoggingHandler())
}
private fun getAndroidLevel(level: Level): Int {
val value = level.intValue()
return when {
value >= 1000 -> Log.ERROR
value >= 900 -> Log.WARN
value >= 800 -> Log.INFO
else -> Log.DEBUG
}
}
LoggingHandler.loggingHandlers.clear()
LoggingHandler.loggingHandlers.add(this)
}
}
......@@ -5,6 +5,10 @@ import android.arch.lifecycle.LiveData
import android.arch.lifecycle.MediatorLiveData
import android.arch.lifecycle.Observer
import android.support.annotation.MainThread
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.BehaviorSubject
@MainThread
fun <X, Y> stickySwitchMapNotNull(
......@@ -45,6 +49,93 @@ fun <X, Y> stickySwitchMapNotNull(
return result
}
@MainThread
inline fun <X, Y> rxStickySwitchMapNotNull(
trigger: LiveData<X?>,
crossinline func: (X) -> BehaviorSubject<Y>?,
defaultValue: Y
): LiveData<Y> {
return stickySwitchMapNotNull(trigger, {
val data = func(it)
if (data != null)
BehaviorSubjectLiveData(data)
else
null
}, defaultValue)
}
class BehaviorSubjectLiveData<T>(val observable: BehaviorSubject<T>) : LiveData<T>() {
var subscription: Disposable? = null
override fun getValue(): T? {
return observable.value
}
override fun setValue(value: T) {
observable.onNext(value)
}
override fun postValue(value: T) {
observable.onNext(value)
}
override fun observe(owner: LifecycleOwner?, observer: Observer<T>?) {
super.observe(owner, observer)
if (subscription == null && hasActiveObservers()) {
subscription = observable.subscribeOn(Schedulers.io()).subscribe(this::postValue)
}
}
override fun observeForever(observer: Observer<T>?) {
super.observeForever(observer)
if (subscription == null && hasActiveObservers()) {
subscription = observable.subscribeOn(Schedulers.io()).subscribe(this::postValue)
}
}
override fun removeObserver(observer: Observer<T>?) {
super.removeObserver(observer)
if (subscription != null && !hasActiveObservers()) {
subscription?.dispose()
}
}
override fun removeObservers(owner: LifecycleOwner?) {
super.removeObservers(owner)
if (subscription != null && !hasActiveObservers()) {
subscription?.dispose()
}
}
}
@MainThread
fun <X, Y> rxSwitchMap(
trigger: LiveData<X?>,
func: (X) -> Observable<Y>?,
defaultValue: Y
): LiveData<Y> {
val result = object : MediatorLiveData<Y>() {
override fun observe(owner: LifecycleOwner?, observer: Observer<Y>?) {
super.observe(owner, observer)
observer?.onChanged(value ?: defaultValue)
}
override fun observeForever(observer: Observer<Y>?) {
super.observeForever(observer)
observer?.onChanged(value ?: defaultValue)
}
}
result.addSource(trigger, object : Observer<X?> {
internal var mSource: Observable<Y>? = null
override fun onChanged(x: X?) {
val newLiveData = if (x != null) func(x) else null
}
})
return result
}
@MainThread
fun <X, Y> stickyMapNotNull(
trigger: LiveData<X?>,
......
......@@ -6,9 +6,11 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp">
android:paddingLeft="24dp"
android:paddingRight="24dp">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
......@@ -19,8 +21,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Host"
android:singleLine="true"
android:maxLines="1" />
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
......@@ -33,9 +35,9 @@
android:layout_height="wrap_content"
android:hint="Port"
android:inputType="number"
android:text="4242"
android:maxLines="1"
android:singleLine="true"
android:maxLines="1" />
android:text="4242" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
......@@ -47,8 +49,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Username"
android:singleLine="true"
android:maxLines="1" />
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
......@@ -61,8 +63,8 @@
android:layout_height="wrap_content"
android:hint="Password"
android:inputType="textPassword"
android:singleLine="true"
android:maxLines="1" />
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<LinearLayout
......
......@@ -3,6 +3,7 @@ import org.gradle.api.Project
import org.gradle.api.artifacts.ExternalModuleDependency
import org.gradle.kotlin.dsl.*
import org.jetbrains.kotlin.gradle.plugin.KaptExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
apply {
plugin("kotlin")
......@@ -23,6 +24,15 @@ dependencies {
testImplementation("junit:junit:4.12")
}
tasks.withType(KotlinCompile::class.java) {
kotlinOptions {
freeCompilerArgs = listOf(
"-Xno-param-assertions",
"-Xno-call-assertions"
)
}
}
/**
* Builds the dependency notation for the named AppCompat [module] at the given [version].
*
......
......@@ -56,4 +56,10 @@ class Message(
override fun of(vararg flags: MessageFlag) = Flags.of(*flags)
}
}
override fun toString(): String {
return "Message(messageId=$messageId, time=$time, type=$type, flag=$flag, bufferInfo=$bufferInfo, sender='$sender', senderPrefixes='$senderPrefixes', content='$content')"
}
}
package de.kuschku.libquassel.protocol
import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer.UTF8
import de.kuschku.libquassel.protocol.primitive.serializer.deserializeString
import de.kuschku.libquassel.protocol.primitive.serializer.serializeString
import org.threeten.bp.Instant
import java.nio.ByteBuffer
enum class RequestType(val value: Int) {
Invalid(0),
Sync(1),
RpcCall(2),
InitRequest(3),
InitData(4),
HeartBeat(5),
HeartBeatReply(6);
companion object {
private val byId = enumValues<RequestType>().associateBy(RequestType::value)
fun of(value: Int) = byId[value] ?: Invalid
}
}
sealed class SignalProxyMessage {
class SyncMessage(val className: String, val objectName: String, val slotName: String,
val params: QVariantList) : SignalProxyMessage() {
override fun toString(): String {
return "SyncMessage::$className:${objectName.hashCode()}/$slotName"
}
}
class RpcCall(val slotName: String, val params: QVariantList) : SignalProxyMessage() {
override fun toString(): String {
return "RpcCall::$slotName"
}
}
class InitRequest(val className: String, val objectName: String) : SignalProxyMessage() {
override fun toString(): String {
return "InitRequest::$className:${objectName.hashCode()}"
}
}
class InitData(val className: String, val objectName: String, val initData: QVariantMap) :
SignalProxyMessage() {
override fun toString(): String {
return "InitData::$className:${objectName.hashCode()}"
}
}
class HeartBeat(val timestamp: Instant) : SignalProxyMessage() {
override fun toString(): String {
return "HeartBeat::$timestamp"
}
}
class HeartBeatReply(val timestamp: Instant) : SignalProxyMessage() {
override fun toString(): String {
return "HeartBeatReply::$timestamp"
}
}
companion object : SignalProxyMessageSerializer<SignalProxyMessage> {
override fun serialize(data: SignalProxyMessage) = when (data) {
is SignalProxyMessage.SyncMessage -> SyncMessageSerializer.serialize(data)
is SignalProxyMessage.RpcCall -> RpcCallSerializer.serialize(data)
is SignalProxyMessage.InitRequest -> InitRequestSerializer.serialize(data)
is SignalProxyMessage.InitData -> InitDataSerializer.serialize(data)
is SignalProxyMessage.HeartBeat -> HeartBeatSerializer.serialize(data)
is SignalProxyMessage.HeartBeatReply -> HeartBeatReplySerializer.serialize(data)
}
override fun deserialize(data: QVariantList): SignalProxyMessage {
val type = data.first().value(-1)
return when (RequestType.of(type)) {
RequestType.Sync -> SyncMessageSerializer.deserialize(data.drop(1))
RequestType.RpcCall -> RpcCallSerializer.deserialize(data.drop(1))
RequestType.InitRequest -> InitRequestSerializer.deserialize(data.drop(1))
RequestType.InitData -> InitDataSerializer.deserialize(data.drop(1))
RequestType.HeartBeat -> HeartBeatSerializer.deserialize(data.drop(1))
RequestType.HeartBeatReply -> HeartBeatReplySerializer.deserialize(data.drop(1))
else -> throw IllegalArgumentException("Invalid MsgType: $type")
}
}
}
}
object SyncMessageSerializer : SignalProxyMessageSerializer<SignalProxyMessage.SyncMessage> {
override fun serialize(data: SignalProxyMessage.SyncMessage): QVariantList = listOf(
QVariant_(RequestType.Sync.value, Type.Int),
QVariant_(data.className.serializeString(UTF8), Type.QByteArray),
QVariant_(data.objectName.serializeString(UTF8), Type.QByteArray),
QVariant_(data.slotName.serializeString(UTF8), Type.QByteArray),
*data.params.toTypedArray()
)
override fun deserialize(data: QVariantList) = SignalProxyMessage.SyncMessage(
data[0].value<ByteBuffer?>().deserializeString(UTF8) ?: "",
data[1].value<ByteBuffer?>().deserializeString(UTF8) ?: "",
data[2].value<ByteBuffer?>().deserializeString(UTF8) ?: "",
data.drop(3)
)
}
object RpcCallSerializer : SignalProxyMessageSerializer<SignalProxyMessage.RpcCall> {
override fun serialize(data: SignalProxyMessage.RpcCall) = listOf(
QVariant_(RequestType.RpcCall.value, Type.Int),
QVariant_(data.slotName.serializeString(UTF8), Type.QByteArray),
*data.params.toTypedArray()
)
override fun deserialize(data: QVariantList) = SignalProxyMessage.RpcCall(
data[0].value<ByteBuffer?>().deserializeString(UTF8) ?: "",
data.drop(1)
)
}
object InitRequestSerializer : SignalProxyMessageSerializer<SignalProxyMessage.InitRequest> {
override fun serialize(data: SignalProxyMessage.InitRequest) = listOf(
QVariant_(RequestType.InitRequest.value, Type.Int),
QVariant_(data.className.serializeString(UTF8), Type.QByteArray),
QVariant_(data.objectName.serializeString(UTF8), Type.QByteArray)
)
override fun deserialize(data: QVariantList) = SignalProxyMessage.InitRequest(
data[0].value<ByteBuffer?>().deserializeString(UTF8) ?: "",
data[1].value<ByteBuffer?>().deserializeString(UTF8) ?: ""
)
}
object InitDataSerializer : SignalProxyMessageSerializer<SignalProxyMessage.InitData> {
override fun serialize(data: SignalProxyMessage.InitData) = listOf(
QVariant_(RequestType.InitData.value, Type.Int),
QVariant_(data.className.serializeString(UTF8), Type.QByteArray),
QVariant_(data.objectName.serializeString(UTF8), Type.QByteArray),
QVariant_(data.initData, Type.QVariantMap)
)
override fun deserialize(data: QVariantList) = SignalProxyMessage.InitData(
data[0].value<ByteBuffer?>().deserializeString(UTF8) ?: "",
data[1].value<ByteBuffer?>().deserializeString(UTF8) ?: "",
data.drop(2).toVariantMap()
)
}
object HeartBeatSerializer : SignalProxyMessageSerializer<SignalProxyMessage.HeartBeat> {
override fun serialize(data: SignalProxyMessage.HeartBeat) = listOf(
QVariant_(RequestType.HeartBeat.value, Type.Int),
QVariant_(data.timestamp, Type.QDateTime)
)
override fun deserialize(data: QVariantList) = SignalProxyMessage.HeartBeat(
data[0].value(Instant.EPOCH)
)
}
object HeartBeatReplySerializer : SignalProxyMessageSerializer<SignalProxyMessage.HeartBeatReply> {
override fun serialize(data: SignalProxyMessage.HeartBeatReply) = listOf(
QVariant_(RequestType.HeartBeatReply.value, Type.Int),
QVariant_(data.timestamp, Type.QDateTime)
)
override fun deserialize(data: QVariantList) = SignalProxyMessage.HeartBeatReply(
data[0].value(Instant.EPOCH)
)
}
interface SignalProxyMessageSerializer<T : SignalProxyMessage> {
fun serialize(data: T): QVariantList
fun deserialize(data: QVariantList): T
}
package de.kuschku.libquassel.protocol.message
import de.kuschku.libquassel.protocol.QVariantMap
import de.kuschku.libquassel.protocol.QVariant_
import de.kuschku.libquassel.protocol.Type
import de.kuschku.libquassel.protocol.value
import de.kuschku.libquassel.util.Flags
object ClientInitAckSerializer : HandshakeMessageSerializer<HandshakeMessage.ClientInitAck> {
override fun serialize(data: HandshakeMessage.ClientInitAck) = mapOf(
"MsgType" to QVariant_("ClientInitAck", Type.QString),
"CoreFeatures" to QVariant_(data.coreFeatures?.toInt(), Type.UInt),
"StorageBackends" to QVariant_(data.backendInfo, Type.QVariantList),
"Authenticator" to QVariant_(data.authenticatorInfo, Type.QVariantList),
"Configured" to QVariant_(data.coreConfigured, Type.Bool)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientInitAck(
coreFeatures = Flags.Companion.of(data["CoreFeatures"].value(0)),
backendInfo = data["StorageBackends"].value(),
authenticatorInfo = data["Authenticators"].value(),
coreConfigured = data["Configured"].value()
)
}
package de.kuschku.libquassel.protocol.message
import de.kuschku.libquassel.protocol.QVariantMap
import de.kuschku.libquassel.protocol.QVariant_
import de.kuschku.libquassel.protocol.Type
import de.kuschku.libquassel.protocol.value
object ClientInitRejectSerializer : HandshakeMessageSerializer<HandshakeMessage.ClientInitReject> {
override fun serialize(data: HandshakeMessage.ClientInitReject) = mapOf(
"MsgType" to QVariant_("ClientInitReject", Type.QString),
"Error" to QVariant_(data.errorString, Type.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientInitReject(
errorString = data["Error"].value()
)
}
package de.kuschku.libquassel.protocol.message
import de.kuschku.libquassel.protocol.QVariantMap
import de.kuschku.libquassel.protocol.QVariant_
import de.kuschku.libquassel.protocol.Type
import de.kuschku.libquassel.protocol.value
import de.kuschku.libquassel.util.Flags
object ClientInitSerializer : HandshakeMessageSerializer<HandshakeMessage.ClientInit> {
override fun serialize(data: HandshakeMessage.ClientInit) = mapOf(
"MsgType" to QVariant_("ClientInit", Type.QString),
"ClientVersion" to QVariant_(data.clientVersion, Type.QString),
"ClientDate" to QVariant_(data.buildDate, Type.QString),
"ClientFeatures" to QVariant_(data.clientFeatures?.toInt(), Type.UInt)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientInit(
clientVersion = data["ClientVersion"].value(),
buildDate = data["ClientDate"].value(),
clientFeatures = Flags.Companion.of(data["ClientFeatures"].value(0))
)
}
package de.kuschku.libquassel.protocol.message
import de.kuschku.libquassel.protocol.QVariantMap
import de.kuschku.libquassel.protocol.QVariant_
import de.kuschku.libquassel.protocol.Type
object ClientLoginAckSerializer : HandshakeMessageSerializer<HandshakeMessage.ClientLoginAck> {
override fun serialize(data: HandshakeMessage.ClientLoginAck) = mapOf(
"MsgType" to QVariant_("ClientLoginAck", Type.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientLoginAck()
}
package de.kuschku.libquassel.protocol.message
import de.kuschku.libquassel.protocol.QVariantMap
import de.kuschku.libquassel.protocol.QVariant_
import de.kuschku.libquassel.protocol.Type
import de.kuschku.libquassel.protocol.value
object ClientLoginRejectSerializer :
HandshakeMessageSerializer<HandshakeMessage.ClientLoginReject> {
override fun serialize(data: HandshakeMessage.ClientLoginReject) = mapOf(
"MsgType" to QVariant_("ClientLoginReject", Type.QString),
"Error" to QVariant_(data.errorString, Type.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientLoginReject(
errorString = data["Error"].value()
)
}
package de.kuschku.libquassel.protocol.message
import de.kuschku.libquassel.protocol.QVariantMap
import de.kuschku.libquassel.protocol.QVariant_
import de.kuschku.libquassel.protocol.Type
import de.kuschku.libquassel.protocol.value
object ClientLoginSerializer : HandshakeMessageSerializer<HandshakeMessage.ClientLogin> {
override fun serialize(data: HandshakeMessage.ClientLogin) = mapOf(
"MsgType" to QVariant_("ClientLogin", Type.QString),
"User" to QVariant_(data.user, Type.QString),
"Password" to QVariant_(data.password, Type.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientLogin(
user = data["User"].value(),
password = data["Password"].value()
)
}
package de.kuschku.libquassel.protocol.message
import de.kuschku.libquassel.protocol.QVariantMap
import de.kuschku.libquassel.protocol.QVariant_
import de.kuschku.libquassel.protocol.Type
object CoreSetupAckSerializer : HandshakeMessageSerializer<HandshakeMessage.CoreSetupAck> {
override fun serialize(data: HandshakeMessage.CoreSetupAck) = mapOf(
"MsgType" to QVariant_("CoreSetupAck", Type.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.CoreSetupAck()
}
package de.kuschku.libquassel.protocol.message
import de.kuschku.libquassel.protocol.QVariantMap
import de.kuschku.libquassel.protocol.QVariant_
import de.kuschku.libquassel.protocol.Type
import de.kuschku.libquassel.protocol.value
object CoreSetupDataSerializer : HandshakeMessageSerializer<HandshakeMessage.CoreSetupData> {
override fun serialize(data: HandshakeMessage.CoreSetupData) = mapOf(
"MsgType" to QVariant_("CoreSetupData", Type.QString),
"SetupData" to QVariant_(mapOf(
"AdminUser" to QVariant_(data.adminUser, Type.QString),
"AdminPasswd" to QVariant_(data.adminPassword, Type.QString),
"Backend" to QVariant_(data.backend, Type.QString),
"ConnectionProperties" to QVariant_(data.setupData, Type.QVariantMap),
"Authenticator" to QVariant_(data.authenticator, Type.QString),
"AuthProperties" to QVariant_(data.authSetupData, Type.QVariantMap)
), Type.QVariantMap)
)
override fun deserialize(data: QVariantMap): HandshakeMessage.CoreSetupData {
val setupData = data["SetupData"].value<QVariantMap?>()
return HandshakeMessage.CoreSetupData(
adminUser = setupData?.get("AdminUser").value(),
adminPassword = setupData?.get("AdminPasswd").value(),
backend = setupData?.get("Backend").value(),
setupData = setupData?.get("ConnectionProperties").value(),
authenticator = setupData?.get("Authenticator").value(),
authSetupData = setupData?.get("AuthProperties").value()
)
}
}
package de.kuschku.libquassel.protocol.message
import de.kuschku.libquassel.protocol.QVariantMap
import de.kuschku.libquassel.protocol.QVariant_
import de.kuschku.libquassel.protocol.Type
import de.kuschku.libquassel.protocol.value
object CoreSetupRejectSerializer : HandshakeMessageSerializer<HandshakeMessage.CoreSetupReject> {
override fun serialize(data: HandshakeMessage.CoreSetupReject) = mapOf(
"MsgType" to QVariant_("CoreSetupReject", Type.QString),
"Error" to QVariant_(data.errorString, Type.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.CoreSetupReject(
errorString = data["Error"].value()
)
}
package de.kuschku.libquassel.protocol
package de.kuschku.libquassel.protocol.message
import de.kuschku.libquassel.util.Flags
import de.kuschku.libquassel.protocol.QVariantList
import de.kuschku.libquassel.protocol.QVariantMap
import de.kuschku.libquassel.protocol.Quassel_Features
import de.kuschku.libquassel.protocol.value
sealed class HandshakeMessage {
......@@ -30,7 +33,7 @@ sealed class HandshakeMessage {
val authSetupData: QVariantMap?) :
HandshakeMessage() {
override fun toString(): String {
return "CoreSetupData(adminUser=$adminUser, adminPassword=$adminPassword, backend=$backend, setupData=$setupData, authenticator=$authenticator, authSetupData=$authSetupData)"
return "CoreSetupData"
}
}
......@@ -68,11 +71,12 @@ sealed class HandshakeMessage {
val networkIds: QVariantList?) :
HandshakeMessage() {
override fun toString(): String {
return "SessionInit(identities=$identities, bufferInfos=$bufferInfos, networkIds=$networkIds)"
return "SessionInit"
}
}
companion object : HandshakeMessageSerializer<HandshakeMessage> {
companion object :
HandshakeMessageSerializer<HandshakeMessage> {
override fun serialize(data: HandshakeMessage) = when (data) {
is ClientInit -> ClientInitSerializer.serialize(data)
is ClientInitReject -> ClientInitRejectSerializer.serialize(data)
......@@ -107,149 +111,3 @@ sealed class HandshakeMessage {
}
}
object ClientInitSerializer : HandshakeMessageSerializer<HandshakeMessage.ClientInit> {
override fun serialize(data: HandshakeMessage.ClientInit) = mapOf(
"MsgType" to QVariant_(data::class.java.simpleName, Type.QString),
"ClientVersion" to QVariant_(data.clientVersion, Type.QString),
"ClientDate" to QVariant_(data.buildDate, Type.QString),
"ClientFeatures" to QVariant_(data.clientFeatures?.toInt(), Type.UInt)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientInit(
clientVersion = data["ClientVersion"].value(),
buildDate = data["ClientDate"].value(),
clientFeatures = Flags.of(data["ClientFeatures"].value(0))
)
}
object ClientInitRejectSerializer : HandshakeMessageSerializer<HandshakeMessage.ClientInitReject> {
override fun serialize(data: HandshakeMessage.ClientInitReject) = mapOf(
"MsgType" to QVariant_(data::class.java.simpleName, Type.QString),
"Error" to QVariant_(data.errorString, Type.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientInitReject(
errorString = data["Error"].value()
)
}
object ClientInitAckSerializer : HandshakeMessageSerializer<HandshakeMessage.ClientInitAck> {
override fun serialize(data: HandshakeMessage.ClientInitAck) = mapOf(
"MsgType" to QVariant_(data::class.java.simpleName, Type.QString),
"CoreFeatures" to QVariant_(data.coreFeatures?.toInt(), Type.UInt),
"StorageBackends" to QVariant_(data.backendInfo, Type.QVariantList),
"Authenticator" to QVariant_(data.authenticatorInfo, Type.QVariantList),
"Configured" to QVariant_(data.coreConfigured, Type.Bool)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientInitAck(
coreFeatures = Flags.of(data["CoreFeatures"].value(0)),
backendInfo = data["StorageBackends"].value(),
authenticatorInfo = data["Authenticators"].value(),
coreConfigured = data["Configured"].value()
)
}
object CoreSetupDataSerializer : HandshakeMessageSerializer<HandshakeMessage.CoreSetupData> {
override fun serialize(data: HandshakeMessage.CoreSetupData) = mapOf(
"MsgType" to QVariant_(data::class.java.simpleName, Type.QString),
"SetupData" to QVariant_(mapOf(
"AdminUser" to QVariant_(data.adminUser, Type.QString),
"AdminPasswd" to QVariant_(data.adminPassword, Type.QString),
"Backend" to QVariant_(data.backend, Type.QString),
"ConnectionProperties" to QVariant_(data.setupData, Type.QVariantMap),
"Authenticator" to QVariant_(data.authenticator, Type.QString),
"AuthProperties" to QVariant_(data.authSetupData, Type.QVariantMap)
), Type.QVariantMap)
)
override fun deserialize(data: QVariantMap): HandshakeMessage.CoreSetupData {
val setupData = data["SetupData"].value<QVariantMap?>()
return HandshakeMessage.CoreSetupData(
adminUser = setupData?.get("AdminUser").value(),
adminPassword = setupData?.get("AdminPasswd").value(),
backend = setupData?.get("Backend").value(),
setupData = setupData?.get("ConnectionProperties").value(),
authenticator = setupData?.get("Authenticator").value(),
authSetupData = setupData?.get("AuthProperties").value()
)
}
}
object CoreSetupRejectSerializer : HandshakeMessageSerializer<HandshakeMessage.CoreSetupReject> {
override fun serialize(data: HandshakeMessage.CoreSetupReject) = mapOf(
"MsgType" to QVariant_(data::class.java.simpleName, Type.QString),
"Error" to QVariant_(data.errorString, Type.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.CoreSetupReject(
errorString = data["Error"].value()
)
}
object CoreSetupAckSerializer : HandshakeMessageSerializer<HandshakeMessage.CoreSetupAck> {
override fun serialize(data: HandshakeMessage.CoreSetupAck) = mapOf(
"MsgType" to QVariant_(data::class.java.simpleName, Type.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.CoreSetupAck()
}
object ClientLoginSerializer : HandshakeMessageSerializer<HandshakeMessage.ClientLogin> {
override fun serialize(data: HandshakeMessage.ClientLogin) = mapOf(
"MsgType" to QVariant_(data::class.java.simpleName, Type.QString),
"User" to QVariant_(data.user, Type.QString),
"Password" to QVariant_(data.password, Type.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientLogin(
user = data["User"].value(),
password = data["Password"].value()
)
}
object ClientLoginRejectSerializer :
HandshakeMessageSerializer<HandshakeMessage.ClientLoginReject> {
override fun serialize(data: HandshakeMessage.ClientLoginReject) = mapOf(
"MsgType" to QVariant_(data::class.java.simpleName, Type.QString),
"Error" to QVariant_(data.errorString, Type.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientLoginReject(
errorString = data["Error"].value()
)
}
object ClientLoginAckSerializer : HandshakeMessageSerializer<HandshakeMessage.ClientLoginAck> {
override fun serialize(data: HandshakeMessage.ClientLoginAck) = mapOf(
"MsgType" to QVariant_(data::class.java.simpleName, Type.QString)
)
override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientLoginAck()
}
object SessionInitSerializer : HandshakeMessageSerializer<HandshakeMessage.SessionInit> {
override fun serialize(data: HandshakeMessage.SessionInit) = mapOf(
"MsgType" to QVariant_(data::class.java.simpleName, Type.QString),
"SessionState" to QVariant_(mapOf(
"BufferInfos" to QVariant_(data.bufferInfos, Type.QVariantList),
"NetworkIds" to QVariant_(data.networkIds, Type.QVariantList),
"Identities" to QVariant_(data.identities, Type.QVariantList)
), Type.QVariantMap)
)
override fun deserialize(data: QVariantMap): HandshakeMessage.SessionInit {
val setupData = data["SessionState"].value<QVariantMap?>()
return HandshakeMessage.SessionInit(
bufferInfos = setupData?.get("BufferInfos").value(),
networkIds = setupData?.get("NetworkIds").value(),
identities = setupData?.get("Identities").value()
)
}
}
interface HandshakeMessageSerializer<T : HandshakeMessage> {
fun serialize(data: T): QVariantMap
fun deserialize(data: QVariantMap): T
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment