Commit f48b9ec9 authored by 李朝发's avatar 李朝发

1.0.2

parent ea728e86
......@@ -33,9 +33,6 @@ android {
dependencies {
implementation 'net.java.dev.jna:jna:5.13.0@aar'
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation 'com.google.android.material:material:1.8.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
......@@ -44,7 +41,7 @@ dependencies {
def USERNAME = "lizhaofa"
def PASSWORD = "0oh7bcnZtweAo7EX"
def VERSION = "1.0.0"
def VERSION = "1.0.2"
def RELEASE_REPOSITORY_URL = "https://hub.zmcms.cn/repository/maven-releases"
afterEvaluate {
......
......@@ -3,7 +3,7 @@
@file:Suppress("NAME_SHADOWING")
package cn.qmai.socket
package cn.qmai.socket;
// Common helper code.
//
......@@ -36,9 +36,7 @@ import kotlin.concurrent.withLock
@Structure.FieldOrder("capacity", "len", "data")
open class RustBuffer : Structure() {
@JvmField var capacity: Int = 0
@JvmField var len: Int = 0
@JvmField var data: Pointer? = null
class ByValue : RustBuffer(), Structure.ByValue
......@@ -46,15 +44,15 @@ open class RustBuffer : Structure() {
companion object {
internal fun alloc(size: Int = 0) = rustCall() { status ->
_UniFFILib.INSTANCE.ffi_NativeSocket_eac7_rustbuffer_alloc(size, status).also {
if (it.data == null) {
throw RuntimeException("RustBuffer.alloc() returned null data pointer (size=$size)")
_UniFFILib.INSTANCE.ffi_NativeSocket_2a33_rustbuffer_alloc(size, status).also {
if(it.data == null) {
throw RuntimeException("RustBuffer.alloc() returned null data pointer (size=${size})")
}
}
}
internal fun free(buf: RustBuffer.ByValue) = rustCall() { status ->
_UniFFILib.INSTANCE.ffi_NativeSocket_eac7_rustbuffer_free(buf, status)
_UniFFILib.INSTANCE.ffi_NativeSocket_2a33_rustbuffer_free(buf, status)
}
}
......@@ -93,12 +91,10 @@ class RustBufferByReference : ByReference(16) {
@Structure.FieldOrder("len", "data")
open class ForeignBytes : Structure() {
@JvmField var len: Int = 0
@JvmField var data: Pointer? = null
class ByValue : ForeignBytes(), Structure.ByValue
}
// The FfiConverter interface handles converter types to and from the FFI
//
// All implementing objects should be public to support external types. When a
......@@ -166,18 +162,16 @@ public interface FfiConverter<KotlinType, FfiType> {
}
// FfiConverter that uses `RustBuffer` as the FfiType
public interface FfiConverterRustBuffer<KotlinType> : FfiConverter<KotlinType, RustBuffer.ByValue> {
public interface FfiConverterRustBuffer<KotlinType>: FfiConverter<KotlinType, RustBuffer.ByValue> {
override fun lift(value: RustBuffer.ByValue) = liftFromRustBuffer(value)
override fun lower(value: KotlinType) = lowerIntoRustBuffer(value)
}
// A handful of classes and functions to support the generated data structures.
// This would be a good candidate for isolating in its own ffi-support lib.
// Error runtime.
@Structure.FieldOrder("code", "error_buf")
internal open class RustCallStatus : Structure() {
@JvmField var code: Int = 0
@JvmField var error_buf: RustBuffer.ByValue = RustBuffer.ByValue()
fun isSuccess(): Boolean {
......@@ -197,7 +191,7 @@ class InternalException(message: String) : Exception(message)
// Each top-level error class has a companion object that can lift the error from the call status's rust buffer
interface CallStatusErrorHandler<E> {
fun lift(error_buf: RustBuffer.ByValue): E
fun lift(error_buf: RustBuffer.ByValue): E;
}
// Helpers for calling Rust
......@@ -205,8 +199,8 @@ interface CallStatusErrorHandler<E> {
// synchronize itself
// Call a rust function that returns a Result<>. Pass in the Error class companion that corresponds to the Err
private inline fun <U, E : Exception> rustCallWithError(errorHandler: CallStatusErrorHandler<E>, callback: (RustCallStatus) -> U): U {
var status = RustCallStatus()
private inline fun <U, E: Exception> rustCallWithError(errorHandler: CallStatusErrorHandler<E>, callback: (RustCallStatus) -> U): U {
var status = RustCallStatus();
val return_value = callback(status)
if (status.isSuccess()) {
return return_value
......@@ -227,7 +221,7 @@ private inline fun <U, E : Exception> rustCallWithError(errorHandler: CallStatus
}
// CallStatusErrorHandler implementation for times when we don't expect a CALL_ERROR
object NullCallStatusErrorHandler : CallStatusErrorHandler<InternalException> {
object NullCallStatusErrorHandler: CallStatusErrorHandler<InternalException> {
override fun lift(error_buf: RustBuffer.ByValue): InternalException {
RustBuffer.free(error_buf)
return InternalException("Unexpected CALL_ERROR")
......@@ -236,7 +230,7 @@ object NullCallStatusErrorHandler : CallStatusErrorHandler<InternalException> {
// Call a rust function that returns a plain value
private inline fun <U> rustCall(callback: (RustCallStatus) -> U): U {
return rustCallWithError(NullCallStatusErrorHandler, callback)
return rustCallWithError(NullCallStatusErrorHandler, callback);
}
// Contains loading, initialization code,
......@@ -251,7 +245,7 @@ private fun findLibraryName(componentName: String): String {
}
private inline fun <reified Lib : Library> loadIndirect(
componentName: String,
componentName: String
): Lib {
return Native.load<Lib>(findLibraryName(componentName), Lib::class.java)
}
......@@ -267,136 +261,105 @@ internal interface _UniFFILib : Library {
FfiConverterTypeLeastOnceListener.register(lib)
FfiConverterTypeMostOnceListener.register(lib)
}
}
}
fun ffi_NativeSocket_eac7_NativeSocketBuilder_object_free(
`ptr`: Pointer,
_uniffi_out_err: RustCallStatus,
fun ffi_NativeSocket_2a33_NativeSocketBuilder_object_free(`ptr`: Pointer,
_uniffi_out_err: RustCallStatus
): Unit
fun NativeSocket_eac7_NativeSocketBuilder_new(
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocketBuilder_new(
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_eac7_NativeSocketBuilder_host(
`ptr`: Pointer,
`host`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocketBuilder_host(`ptr`: Pointer,`host`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_eac7_NativeSocketBuilder_token(
`ptr`: Pointer,
`token`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocketBuilder_token(`ptr`: Pointer,`token`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_eac7_NativeSocketBuilder_brand(
`ptr`: Pointer,
`brand`: Int,
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocketBuilder_brand(`ptr`: Pointer,`brand`: Int,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_eac7_NativeSocketBuilder_store(
`ptr`: Pointer,
`store`: Int,
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocketBuilder_store(`ptr`: Pointer,`store`: Int,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_eac7_NativeSocketBuilder_device(
`ptr`: Pointer,
`device`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocketBuilder_device(`ptr`: Pointer,`device`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_eac7_NativeSocketBuilder_type(
`ptr`: Pointer,
`type`: Int,
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocketBuilder_type(`ptr`: Pointer,`type`: Int,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_eac7_NativeSocketBuilder_topic(
`ptr`: Pointer,
`topic`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocketBuilder_topic(`ptr`: Pointer,`topic`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_eac7_NativeSocketBuilder_clean_start(
`ptr`: Pointer,
`cleanStart`: Byte,
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocketBuilder_clean_start(`ptr`: Pointer,`cleanStart`: Byte,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_eac7_NativeSocketBuilder_cache_dir(
`ptr`: Pointer,
`cacheDir`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocketBuilder_cache_dir(`ptr`: Pointer,`cacheDir`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_eac7_NativeSocketBuilder_log_level(
`ptr`: Pointer,
`logLevel`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocketBuilder_log_level(`ptr`: Pointer,`logLevel`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_eac7_NativeSocketBuilder_sentry(
`ptr`: Pointer,
`sentry`: Byte,
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocketBuilder_sentry(`ptr`: Pointer,`sentry`: Byte,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_eac7_NativeSocketBuilder_build(
`ptr`: Pointer,
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocketBuilder_build(`ptr`: Pointer,
_uniffi_out_err: RustCallStatus
): RustBuffer.ByValue
fun ffi_NativeSocket_eac7_NativeSocket_object_free(
`ptr`: Pointer,
_uniffi_out_err: RustCallStatus,
fun ffi_NativeSocket_2a33_NativeSocket_object_free(`ptr`: Pointer,
_uniffi_out_err: RustCallStatus
): Unit
fun NativeSocket_eac7_NativeSocket_start(
`ptr`: Pointer,
`mostOnce`: RustBuffer.ByValue,
`leastOnce`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus,
fun NativeSocket_2a33_NativeSocket_start(`ptr`: Pointer,`mostOnce`: RustBuffer.ByValue,`leastOnce`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Unit
fun ffi_NativeSocket_eac7_MostOnceListener_init_callback(
`callbackStub`: ForeignCallback,
_uniffi_out_err: RustCallStatus,
fun ffi_NativeSocket_2a33_MostOnceListener_init_callback(`callbackStub`: ForeignCallback,
_uniffi_out_err: RustCallStatus
): Unit
fun ffi_NativeSocket_eac7_LeastOnceListener_init_callback(
`callbackStub`: ForeignCallback,
_uniffi_out_err: RustCallStatus,
fun ffi_NativeSocket_2a33_LeastOnceListener_init_callback(`callbackStub`: ForeignCallback,
_uniffi_out_err: RustCallStatus
): Unit
fun ffi_NativeSocket_eac7_rustbuffer_alloc(
`size`: Int,
_uniffi_out_err: RustCallStatus,
fun ffi_NativeSocket_2a33_rustbuffer_alloc(`size`: Int,
_uniffi_out_err: RustCallStatus
): RustBuffer.ByValue
fun ffi_NativeSocket_eac7_rustbuffer_from_bytes(
`bytes`: ForeignBytes.ByValue,
_uniffi_out_err: RustCallStatus,
fun ffi_NativeSocket_2a33_rustbuffer_from_bytes(`bytes`: ForeignBytes.ByValue,
_uniffi_out_err: RustCallStatus
): RustBuffer.ByValue
fun ffi_NativeSocket_eac7_rustbuffer_free(
`buf`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus,
fun ffi_NativeSocket_2a33_rustbuffer_free(`buf`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Unit
fun ffi_NativeSocket_eac7_rustbuffer_reserve(
`buf`: RustBuffer.ByValue,
`additional`: Int,
_uniffi_out_err: RustCallStatus,
fun ffi_NativeSocket_2a33_rustbuffer_reserve(`buf`: RustBuffer.ByValue,`additional`: Int,
_uniffi_out_err: RustCallStatus
): RustBuffer.ByValue
}
// Public interface members begin here.
public object FfiConverterUByte : FfiConverter<UByte, Byte> {
public object FfiConverterUByte: FfiConverter<UByte, Byte> {
override fun lift(value: Byte): UByte {
return value.toUByte()
}
......@@ -416,7 +379,7 @@ public object FfiConverterUByte : FfiConverter<UByte, Byte> {
}
}
public object FfiConverterInt : FfiConverter<Int, Int> {
public object FfiConverterInt: FfiConverter<Int, Int> {
override fun lift(value: Int): Int {
return value
}
......@@ -436,7 +399,7 @@ public object FfiConverterInt : FfiConverter<Int, Int> {
}
}
public object FfiConverterLong : FfiConverter<Long, Long> {
public object FfiConverterLong: FfiConverter<Long, Long> {
override fun lift(value: Long): Long {
return value
}
......@@ -456,7 +419,7 @@ public object FfiConverterLong : FfiConverter<Long, Long> {
}
}
public object FfiConverterBoolean : FfiConverter<Boolean, Byte> {
public object FfiConverterBoolean: FfiConverter<Boolean, Byte> {
override fun lift(value: Byte): Boolean {
return value.toInt() != 0
}
......@@ -476,7 +439,7 @@ public object FfiConverterBoolean : FfiConverter<Boolean, Byte> {
}
}
public object FfiConverterString : FfiConverter<String, RustBuffer.ByValue> {
public object FfiConverterString: FfiConverter<String, RustBuffer.ByValue> {
// Note: we don't inherit from FfiConverterRustBuffer, because we use a
// special encoding when lowering/lifting. We can use `RustBuffer.len` to
// store our length and avoid writing it out to the buffer.
......@@ -522,6 +485,7 @@ public object FfiConverterString : FfiConverter<String, RustBuffer.ByValue> {
}
}
// Interface implemented by anything that can contain an object reference.
//
// Such types expose a `destroy()` method that must be called to cleanly
......@@ -634,13 +598,13 @@ inline fun <T : Disposable?, R> T.use(block: (T) -> R) =
// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219
//
abstract class FFIObject(
protected val pointer: Pointer,
) : Disposable, AutoCloseable {
protected val pointer: Pointer
): Disposable, AutoCloseable {
private val wasDestroyed = AtomicBoolean(false)
private val callCounter = AtomicLong(1)
protected open fun freeRustArcPtr() {
open protected fun freeRustArcPtr() {
// To be overridden in subclasses.
}
......@@ -671,12 +635,12 @@ abstract class FFIObject(
if (c == Long.MAX_VALUE) {
throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow")
}
} while (!this.callCounter.compareAndSet(c, c + 1L))
} while (! this.callCounter.compareAndSet(c, c + 1L))
// Now we can safely do the method call without the pointer being freed concurrently.
try {
return block(this.pointer)
} finally {
// This decrement aways matches the increment we performed above.
// This decrement always matches the increment we performed above.
if (this.callCounter.decrementAndGet() == 0L) {
this.freeRustArcPtr()
}
......@@ -687,10 +651,11 @@ abstract class FFIObject(
public interface NativeSocketInterface {
fun `start`(`mostOnce`: MostOnceListener?, `leastOnce`: LeastOnceListener?)
}
class NativeSocket(
pointer: Pointer,
pointer: Pointer
) : FFIObject(pointer), NativeSocketInterface {
/**
......@@ -701,21 +666,25 @@ class NativeSocket(
*
* Clients **must** call this method once done with the object, or cause a memory leak.
*/
protected override fun freeRustArcPtr() {
override protected fun freeRustArcPtr() {
rustCall() { status ->
_UniFFILib.INSTANCE.ffi_NativeSocket_eac7_NativeSocket_object_free(this.pointer, status)
_UniFFILib.INSTANCE.ffi_NativeSocket_2a33_NativeSocket_object_free(this.pointer, status)
}
}
override fun `start`(`mostOnce`: MostOnceListener?, `leastOnce`: LeastOnceListener?) =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocket_start(it, FfiConverterOptionalTypeMostOnceListener.lower(`mostOnce`), FfiConverterOptionalTypeLeastOnceListener.lower(`leastOnce`), _status)
}
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocket_start(it, FfiConverterOptionalTypeMostOnceListener.lower(`mostOnce`), FfiConverterOptionalTypeLeastOnceListener.lower(`leastOnce`), _status)
}
}
}
public object FfiConverterTypeNativeSocket : FfiConverter<NativeSocket, Pointer> {
public object FfiConverterTypeNativeSocket: FfiConverter<NativeSocket, Pointer> {
override fun lower(value: NativeSocket): Pointer = value.callWithPointer { it }
override fun lift(value: Pointer): NativeSocket {
......@@ -737,6 +706,9 @@ public object FfiConverterTypeNativeSocket : FfiConverter<NativeSocket, Pointer>
}
}
public interface NativeSocketBuilderInterface {
fun `host`(`host`: String): NativeSocketBuilder
......@@ -762,17 +734,17 @@ public interface NativeSocketBuilderInterface {
fun `sentry`(`sentry`: Boolean): NativeSocketBuilder
fun `build`(): NativeSocket?
}
class NativeSocketBuilder(
pointer: Pointer,
pointer: Pointer
) : FFIObject(pointer), NativeSocketBuilderInterface {
constructor() :
this(
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocketBuilder_new(_status)
},
)
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_new( _status)
})
/**
* Disconnect the object from the underlying Rust object.
......@@ -782,111 +754,114 @@ class NativeSocketBuilder(
*
* Clients **must** call this method once done with the object, or cause a memory leak.
*/
protected override fun freeRustArcPtr() {
override protected fun freeRustArcPtr() {
rustCall() { status ->
_UniFFILib.INSTANCE.ffi_NativeSocket_eac7_NativeSocketBuilder_object_free(this.pointer, status)
_UniFFILib.INSTANCE.ffi_NativeSocket_2a33_NativeSocketBuilder_object_free(this.pointer, status)
}
}
override fun `host`(`host`: String): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocketBuilder_host(it, FfiConverterString.lower(`host`), _status)
}
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_host(it, FfiConverterString.lower(`host`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
}
override fun `token`(`token`: String): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocketBuilder_token(it, FfiConverterString.lower(`token`), _status)
}
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_token(it, FfiConverterString.lower(`token`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
}
override fun `brand`(`brand`: Int): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocketBuilder_brand(it, FfiConverterInt.lower(`brand`), _status)
}
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_brand(it, FfiConverterInt.lower(`brand`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
}
override fun `store`(`store`: Int): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocketBuilder_store(it, FfiConverterInt.lower(`store`), _status)
}
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_store(it, FfiConverterInt.lower(`store`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
}
override fun `device`(`device`: String): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocketBuilder_device(it, FfiConverterString.lower(`device`), _status)
}
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_device(it, FfiConverterString.lower(`device`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
}
override fun `type`(`type`: Int): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocketBuilder_type(it, FfiConverterInt.lower(`type`), _status)
}
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_type(it, FfiConverterInt.lower(`type`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
}
override fun `topic`(`topic`: List<String>): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocketBuilder_topic(it, FfiConverterSequenceString.lower(`topic`), _status)
}
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_topic(it, FfiConverterSequenceString.lower(`topic`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
}
override fun `cleanStart`(`cleanStart`: Boolean): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocketBuilder_clean_start(it, FfiConverterBoolean.lower(`cleanStart`), _status)
}
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_clean_start(it, FfiConverterBoolean.lower(`cleanStart`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
}
override fun `cacheDir`(`cacheDir`: String): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocketBuilder_cache_dir(it, FfiConverterString.lower(`cacheDir`), _status)
}
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_cache_dir(it, FfiConverterString.lower(`cacheDir`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
}
override fun `logLevel`(`logLevel`: LogLevel): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocketBuilder_log_level(it, FfiConverterTypeLogLevel.lower(`logLevel`), _status)
}
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_log_level(it, FfiConverterTypeLogLevel.lower(`logLevel`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
}
override fun `sentry`(`sentry`: Boolean): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocketBuilder_sentry(it, FfiConverterBoolean.lower(`sentry`), _status)
}
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_sentry(it, FfiConverterBoolean.lower(`sentry`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
}
override fun `build`(): NativeSocket? =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_eac7_NativeSocketBuilder_build(it, _status)
}
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_build(it, _status)
}
}.let {
FfiConverterOptionalTypeNativeSocket.lift(it)
}
}
public object FfiConverterTypeNativeSocketBuilder : FfiConverter<NativeSocketBuilder, Pointer> {
public object FfiConverterTypeNativeSocketBuilder: FfiConverter<NativeSocketBuilder, Pointer> {
override fun lower(value: NativeSocketBuilder): Pointer = value.callWithPointer { it }
override fun lift(value: Pointer): NativeSocketBuilder {
......@@ -908,35 +883,47 @@ public object FfiConverterTypeNativeSocketBuilder : FfiConverter<NativeSocketBui
}
}
data class Message(
data class Message (
var `id`: Long,
var `data`: List<UByte>?,
)
var `ty`: Int,
var `data`: List<UByte>?
) {
public object FfiConverterTypeMessage : FfiConverterRustBuffer<Message> {
}
public object FfiConverterTypeMessage: FfiConverterRustBuffer<Message> {
override fun read(buf: ByteBuffer): Message {
return Message(
FfiConverterLong.read(buf),
FfiConverterInt.read(buf),
FfiConverterOptionalSequenceUByte.read(buf),
)
}
override fun allocationSize(value: Message) = (
FfiConverterLong.allocationSize(value.`id`) +
FfiConverterInt.allocationSize(value.`ty`) +
FfiConverterOptionalSequenceUByte.allocationSize(value.`data`)
)
override fun write(value: Message, buf: ByteBuffer) {
FfiConverterLong.write(value.`id`, buf)
FfiConverterInt.write(value.`ty`, buf)
FfiConverterOptionalSequenceUByte.write(value.`data`, buf)
}
}
enum class LogLevel {
ERROR, WARN, INFO, DEBUG, TRACE
ERROR,WARN,INFO,DEBUG,TRACE;
}
public object FfiConverterTypeLogLevel : FfiConverterRustBuffer<LogLevel> {
public object FfiConverterTypeLogLevel: FfiConverterRustBuffer<LogLevel> {
override fun read(buf: ByteBuffer) = try {
LogLevel.values()[buf.getInt() - 1]
} catch (e: IndexOutOfBoundsException) {
......@@ -950,10 +937,55 @@ public object FfiConverterTypeLogLevel : FfiConverterRustBuffer<LogLevel> {
}
}
sealed class ConsumerException(message: String): Exception(message) {
// Each variant is a nested class
// Flat enums carries a string error message, so no special implementation is necessary.
class Exception(message: String) : ConsumerException(message)
companion object ErrorHandler : CallStatusErrorHandler<ConsumerException> {
override fun lift(error_buf: RustBuffer.ByValue): ConsumerException = FfiConverterTypeConsumerError.lift(error_buf)
}
}
public object FfiConverterTypeConsumerError : FfiConverterRustBuffer<ConsumerException> {
override fun read(buf: ByteBuffer): ConsumerException {
return when(buf.getInt()) {
1 -> ConsumerException.Exception(FfiConverterString.read(buf))
else -> throw RuntimeException("invalid error enum value, something is very wrong!!")
}
}
override fun allocationSize(value: ConsumerException): Int {
return 4
}
override fun write(value: ConsumerException, buf: ByteBuffer) {
when(value) {
is ConsumerException.Exception -> {
buf.putInt(1)
Unit
}
}.let { /* this makes the `when` an expression, which ensures it is exhaustive */ }
}
}
internal typealias Handle = Long
internal class ConcurrentHandleMap<T>(
private val leftMap: MutableMap<Handle, T> = mutableMapOf(),
private val rightMap: MutableMap<T, Handle> = mutableMapOf(),
private val rightMap: MutableMap<T, Handle> = mutableMapOf()
) {
private val lock = java.util.concurrent.locks.ReentrantLock()
private val currentHandle = AtomicLong(0L)
......@@ -961,8 +993,8 @@ internal class ConcurrentHandleMap<T>(
fun insert(obj: T): Handle =
lock.withLock {
rightMap[obj]
?: currentHandle.getAndAdd(stride)
rightMap[obj] ?:
currentHandle.getAndAdd(stride)
.also { handle ->
leftMap[handle] = obj
rightMap[obj] = handle
......@@ -995,8 +1027,8 @@ interface ForeignCallback : com.sun.jna.Callback {
internal const val IDX_CALLBACK_FREE = 0
public abstract class FfiConverterCallbackInterface<CallbackInterface>(
protected val foreignCallback: ForeignCallback,
) : FfiConverter<CallbackInterface, Handle> {
protected val foreignCallback: ForeignCallback
): FfiConverter<CallbackInterface, Handle> {
private val handleMap = ConcurrentHandleMap<CallbackInterface>()
// Registers the foreign callback with the Rust side.
......@@ -1029,6 +1061,7 @@ public abstract class FfiConverterCallbackInterface<CallbackInterface>(
public interface LeastOnceListener {
fun `consumerMessage`(`message`: Message)
}
// The ForeignCallback that is passed to Rust.
......@@ -1046,11 +1079,18 @@ internal class ForeignCallbackTypeLeastOnceListener : ForeignCallback {
1 -> {
// Call the method, write to outBuf and return a status code
// See docs of ForeignCallback in `uniffi/src/ffi/foreigncallbacks.rs` for info
try {
try {
val buffer = this.`invokeConsumerMessage`(cb, args)
// Success
outBuf.setValue(buffer)
1
} catch (e: ConsumerException) {
// Expected error
val buffer = FfiConverterTypeConsumerError.lowerIntoRustBuffer(e)
outBuf.setValue(buffer)
-2
}
} catch (e: Throwable) {
// Unexpected error
try {
......@@ -1077,11 +1117,12 @@ internal class ForeignCallbackTypeLeastOnceListener : ForeignCallback {
}
}
private fun `invokeConsumerMessage`(kotlinCallbackInterface: LeastOnceListener, args: RustBuffer.ByValue): RustBuffer.ByValue =
try {
val buf = args.asByteBuffer() ?: throw InternalException("No ByteBuffer in RustBuffer; this is a Uniffi bug")
kotlinCallbackInterface.`consumerMessage`(
FfiConverterTypeMessage.read(buf),
FfiConverterTypeMessage.read(buf)
)
.let { RustBuffer.ByValue() }
// TODO catch errors and report them back to Rust.
......@@ -1089,23 +1130,31 @@ internal class ForeignCallbackTypeLeastOnceListener : ForeignCallback {
} finally {
RustBuffer.free(args)
}
}
// The ffiConverter which transforms the Callbacks in to Handles to pass to Rust.
public object FfiConverterTypeLeastOnceListener : FfiConverterCallbackInterface<LeastOnceListener>(
foreignCallback = ForeignCallbackTypeLeastOnceListener(),
public object FfiConverterTypeLeastOnceListener: FfiConverterCallbackInterface<LeastOnceListener>(
foreignCallback = ForeignCallbackTypeLeastOnceListener()
) {
override fun register(lib: _UniFFILib) {
rustCall() { status ->
lib.ffi_NativeSocket_eac7_LeastOnceListener_init_callback(this.foreignCallback, status)
lib.ffi_NativeSocket_2a33_LeastOnceListener_init_callback(this.foreignCallback, status)
}
}
}
// Declaration and FfiConverters for MostOnceListener Callback Interface
public interface MostOnceListener {
fun `consumerMessage`(`message`: Message)
}
// The ForeignCallback that is passed to Rust.
......@@ -1123,11 +1172,18 @@ internal class ForeignCallbackTypeMostOnceListener : ForeignCallback {
1 -> {
// Call the method, write to outBuf and return a status code
// See docs of ForeignCallback in `uniffi/src/ffi/foreigncallbacks.rs` for info
try {
try {
val buffer = this.`invokeConsumerMessage`(cb, args)
// Success
outBuf.setValue(buffer)
1
} catch (e: ConsumerException) {
// Expected error
val buffer = FfiConverterTypeConsumerError.lowerIntoRustBuffer(e)
outBuf.setValue(buffer)
-2
}
} catch (e: Throwable) {
// Unexpected error
try {
......@@ -1154,11 +1210,12 @@ internal class ForeignCallbackTypeMostOnceListener : ForeignCallback {
}
}
private fun `invokeConsumerMessage`(kotlinCallbackInterface: MostOnceListener, args: RustBuffer.ByValue): RustBuffer.ByValue =
try {
val buf = args.asByteBuffer() ?: throw InternalException("No ByteBuffer in RustBuffer; this is a Uniffi bug")
kotlinCallbackInterface.`consumerMessage`(
FfiConverterTypeMessage.read(buf),
FfiConverterTypeMessage.read(buf)
)
.let { RustBuffer.ByValue() }
// TODO catch errors and report them back to Rust.
......@@ -1166,20 +1223,25 @@ internal class ForeignCallbackTypeMostOnceListener : ForeignCallback {
} finally {
RustBuffer.free(args)
}
}
// The ffiConverter which transforms the Callbacks in to Handles to pass to Rust.
public object FfiConverterTypeMostOnceListener : FfiConverterCallbackInterface<MostOnceListener>(
foreignCallback = ForeignCallbackTypeMostOnceListener(),
public object FfiConverterTypeMostOnceListener: FfiConverterCallbackInterface<MostOnceListener>(
foreignCallback = ForeignCallbackTypeMostOnceListener()
) {
override fun register(lib: _UniFFILib) {
rustCall() { status ->
lib.ffi_NativeSocket_eac7_MostOnceListener_init_callback(this.foreignCallback, status)
lib.ffi_NativeSocket_2a33_MostOnceListener_init_callback(this.foreignCallback, status)
}
}
}
public object FfiConverterOptionalTypeNativeSocket : FfiConverterRustBuffer<NativeSocket?> {
public object FfiConverterOptionalTypeNativeSocket: FfiConverterRustBuffer<NativeSocket?> {
override fun read(buf: ByteBuffer): NativeSocket? {
if (buf.get().toInt() == 0) {
return null
......@@ -1205,7 +1267,10 @@ public object FfiConverterOptionalTypeNativeSocket : FfiConverterRustBuffer<Nati
}
}
public object FfiConverterOptionalTypeLeastOnceListener : FfiConverterRustBuffer<LeastOnceListener?> {
public object FfiConverterOptionalTypeLeastOnceListener: FfiConverterRustBuffer<LeastOnceListener?> {
override fun read(buf: ByteBuffer): LeastOnceListener? {
if (buf.get().toInt() == 0) {
return null
......@@ -1231,7 +1296,10 @@ public object FfiConverterOptionalTypeLeastOnceListener : FfiConverterRustBuffer
}
}
public object FfiConverterOptionalTypeMostOnceListener : FfiConverterRustBuffer<MostOnceListener?> {
public object FfiConverterOptionalTypeMostOnceListener: FfiConverterRustBuffer<MostOnceListener?> {
override fun read(buf: ByteBuffer): MostOnceListener? {
if (buf.get().toInt() == 0) {
return null
......@@ -1257,7 +1325,10 @@ public object FfiConverterOptionalTypeMostOnceListener : FfiConverterRustBuffer<
}
}
public object FfiConverterOptionalSequenceUByte : FfiConverterRustBuffer<List<UByte>?> {
public object FfiConverterOptionalSequenceUByte: FfiConverterRustBuffer<List<UByte>?> {
override fun read(buf: ByteBuffer): List<UByte>? {
if (buf.get().toInt() == 0) {
return null
......@@ -1283,7 +1354,10 @@ public object FfiConverterOptionalSequenceUByte : FfiConverterRustBuffer<List<UB
}
}
public object FfiConverterSequenceUByte : FfiConverterRustBuffer<List<UByte>> {
public object FfiConverterSequenceUByte: FfiConverterRustBuffer<List<UByte>> {
override fun read(buf: ByteBuffer): List<UByte> {
val len = buf.getInt()
return List<UByte>(len) {
......@@ -1305,7 +1379,10 @@ public object FfiConverterSequenceUByte : FfiConverterRustBuffer<List<UByte>> {
}
}
public object FfiConverterSequenceString : FfiConverterRustBuffer<List<String>> {
public object FfiConverterSequenceString: FfiConverterRustBuffer<List<String>> {
override fun read(buf: ByteBuffer): List<String> {
val len = buf.getInt()
return List<String>(len) {
......@@ -1326,3 +1403,5 @@ public object FfiConverterSequenceString : FfiConverterRustBuffer<List<String>>
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment