45 lines
1.6 KiB
Kotlin
45 lines
1.6 KiB
Kotlin
package net.sergeych.kiloparsec
|
|
|
|
import kotlinx.coroutines.CompletableDeferred
|
|
import net.sergeych.tools.AtomicCounter
|
|
import net.sergeych.utools.pack
|
|
|
|
private val idCounter = AtomicCounter(0)
|
|
|
|
/**
|
|
* This class is not normally used directly. This is a local interface that supports
|
|
* secure transport command layer (encrypted calls/results) to work with [KiloRemoteInterface].
|
|
*
|
|
* It is recommended to use [KiloClientConnection] and [KiloServerConnection] instead.
|
|
*/
|
|
internal class KiloL0Interface<T>(
|
|
private val clientInterface: LocalInterface<KiloScope<T>>,
|
|
private val deferredParams: CompletableDeferred<KiloParams<T>>,
|
|
) : LocalInterface<Unit>() {
|
|
|
|
override var logTag: String = "KL0:${idCounter.incrementAndGet()}"
|
|
|
|
init {
|
|
// local interface uses the same session as a client:
|
|
addErrorProvider(clientInterface)
|
|
|
|
on(L0Call) {
|
|
val params = deferredParams.await()
|
|
val call = Command.unpackCall(params.decrypt(it))
|
|
// tricky part: we need to encrypt a result or error: we can't allow default
|
|
// error transport (as it is not encrypted), so we re-use transport blocks here:
|
|
val result: Transport.Block = try {
|
|
Transport.Block.Response(
|
|
0u,
|
|
clientInterface.execute(params.scope, call.name, call.serializedArgs)
|
|
)
|
|
} catch(t: BreakConnectionException) {
|
|
throw t
|
|
}
|
|
catch (t: Throwable) {
|
|
clientInterface.encodeError(0u, t)
|
|
}
|
|
params.encrypt(pack(result))
|
|
}
|
|
}
|
|
} |