Commit 264a6e1f authored by 李朝发's avatar 李朝发

update

parent 028094f0
......@@ -26,8 +26,6 @@ import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicLong
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
// This is a helper for safely working with byte buffers returned from the Rust code.
// A rust-owned buffer is represented by its capacity, its current length, and a
......@@ -44,7 +42,7 @@ open class RustBuffer : Structure() {
companion object {
internal fun alloc(size: Int = 0) = rustCall() { status ->
_UniFFILib.INSTANCE.ffi_NativeSocket_2a33_rustbuffer_alloc(size, status).also {
_UniFFILib.INSTANCE.ffi_NativeSocket_2c48_rustbuffer_alloc(size, status).also {
if(it.data == null) {
throw RuntimeException("RustBuffer.alloc() returned null data pointer (size=${size})")
}
......@@ -52,7 +50,7 @@ open class RustBuffer : Structure() {
}
internal fun free(buf: RustBuffer.ByValue) = rustCall() { status ->
_UniFFILib.INSTANCE.ffi_NativeSocket_2a33_rustbuffer_free(buf, status)
_UniFFILib.INSTANCE.ffi_NativeSocket_2c48_rustbuffer_free(buf, status)
}
}
......@@ -257,99 +255,95 @@ internal interface _UniFFILib : Library {
companion object {
internal val INSTANCE: _UniFFILib by lazy {
loadIndirect<_UniFFILib>(componentName = "NativeSocket")
.also { lib: _UniFFILib ->
FfiConverterTypeLeastOnceListener.register(lib)
FfiConverterTypeMostOnceListener.register(lib)
}
}
}
fun ffi_NativeSocket_2a33_NativeSocketBuilder_object_free(`ptr`: Pointer,
fun ffi_NativeSocket_2c48_NativeSocketBuilder_object_free(`ptr`: Pointer,
_uniffi_out_err: RustCallStatus
): Unit
fun NativeSocket_2a33_NativeSocketBuilder_new(
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_2a33_NativeSocketBuilder_host(`ptr`: Pointer,`host`: RustBuffer.ByValue,
fun NativeSocket_2c48_NativeSocketBuilder_new(
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_2a33_NativeSocketBuilder_token(`ptr`: Pointer,`token`: RustBuffer.ByValue,
fun NativeSocket_2c48_NativeSocketBuilder_host(`ptr`: Pointer,`host`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_2a33_NativeSocketBuilder_brand(`ptr`: Pointer,`brand`: Int,
fun NativeSocket_2c48_NativeSocketBuilder_token(`ptr`: Pointer,`token`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_2a33_NativeSocketBuilder_store(`ptr`: Pointer,`store`: Int,
fun NativeSocket_2c48_NativeSocketBuilder_brand(`ptr`: Pointer,`brand`: Int,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_2a33_NativeSocketBuilder_device(`ptr`: Pointer,`device`: RustBuffer.ByValue,
fun NativeSocket_2c48_NativeSocketBuilder_store(`ptr`: Pointer,`store`: Int,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_2a33_NativeSocketBuilder_type(`ptr`: Pointer,`type`: Int,
fun NativeSocket_2c48_NativeSocketBuilder_device(`ptr`: Pointer,`device`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_2a33_NativeSocketBuilder_topic(`ptr`: Pointer,`topic`: RustBuffer.ByValue,
fun NativeSocket_2c48_NativeSocketBuilder_ty(`ptr`: Pointer,`type`: Int,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_2a33_NativeSocketBuilder_clean_start(`ptr`: Pointer,`cleanStart`: Byte,
fun NativeSocket_2c48_NativeSocketBuilder_clean_start(`ptr`: Pointer,`cleanStart`: Byte,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_2a33_NativeSocketBuilder_cache_dir(`ptr`: Pointer,`cacheDir`: RustBuffer.ByValue,
fun NativeSocket_2c48_NativeSocketBuilder_cache_dir(`ptr`: Pointer,`cacheDir`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_2a33_NativeSocketBuilder_log_level(`ptr`: Pointer,`logLevel`: RustBuffer.ByValue,
fun NativeSocket_2c48_NativeSocketBuilder_log_level(`ptr`: Pointer,`logLevel`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_2a33_NativeSocketBuilder_sentry(`ptr`: Pointer,`sentry`: Byte,
fun NativeSocket_2c48_NativeSocketBuilder_version(`ptr`: Pointer,`version`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Pointer
fun NativeSocket_2a33_NativeSocketBuilder_build(`ptr`: Pointer,
fun NativeSocket_2c48_NativeSocketBuilder_build(`ptr`: Pointer,
_uniffi_out_err: RustCallStatus
): RustBuffer.ByValue
fun ffi_NativeSocket_2a33_NativeSocket_object_free(`ptr`: Pointer,
fun ffi_NativeSocket_2c48_NativeSocket_object_free(`ptr`: Pointer,
_uniffi_out_err: RustCallStatus
): Unit
fun NativeSocket_2a33_NativeSocket_start(`ptr`: Pointer,`mostOnce`: RustBuffer.ByValue,`leastOnce`: RustBuffer.ByValue,
fun NativeSocket_2c48_NativeSocket_poll(`ptr`: Pointer,
_uniffi_out_err: RustCallStatus
): Unit
): RustBuffer.ByValue
fun ffi_NativeSocket_2a33_MostOnceListener_init_callback(`callbackStub`: ForeignCallback,
fun NativeSocket_2c48_NativeSocket_try_poll(`ptr`: Pointer,
_uniffi_out_err: RustCallStatus
): Unit
): RustBuffer.ByValue
fun ffi_NativeSocket_2a33_LeastOnceListener_init_callback(`callbackStub`: ForeignCallback,
fun NativeSocket_2c48_NativeSocket_poll_timeout(`ptr`: Pointer,`timeout`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Unit
): RustBuffer.ByValue
fun ffi_NativeSocket_2a33_rustbuffer_alloc(`size`: Int,
fun NativeSocket_2c48_NativeSocket_invoke(`ptr`: Pointer,`input`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): RustBuffer.ByValue
fun ffi_NativeSocket_2a33_rustbuffer_from_bytes(`bytes`: ForeignBytes.ByValue,
fun ffi_NativeSocket_2c48_rustbuffer_alloc(`size`: Int,
_uniffi_out_err: RustCallStatus
): RustBuffer.ByValue
fun ffi_NativeSocket_2a33_rustbuffer_free(`buf`: RustBuffer.ByValue,
fun ffi_NativeSocket_2c48_rustbuffer_from_bytes(`bytes`: ForeignBytes.ByValue,
_uniffi_out_err: RustCallStatus
): RustBuffer.ByValue
fun ffi_NativeSocket_2c48_rustbuffer_free(`buf`: RustBuffer.ByValue,
_uniffi_out_err: RustCallStatus
): Unit
fun ffi_NativeSocket_2a33_rustbuffer_reserve(`buf`: RustBuffer.ByValue,`additional`: Int,
fun ffi_NativeSocket_2c48_rustbuffer_reserve(`buf`: RustBuffer.ByValue,`additional`: Int,
_uniffi_out_err: RustCallStatus
): RustBuffer.ByValue
......@@ -486,6 +480,44 @@ public object FfiConverterString: FfiConverter<String, RustBuffer.ByValue> {
}
public object FfiConverterDuration: FfiConverterRustBuffer<java.time.Duration> {
override fun read(buf: ByteBuffer): java.time.Duration {
// Type mismatch (should be u64) but we check for overflow/underflow below
val seconds = buf.getLong()
// Type mismatch (should be u32) but we check for overflow/underflow below
val nanoseconds = buf.getInt().toLong()
if (seconds < 0) {
throw java.time.DateTimeException("Duration exceeds minimum or maximum value supported by uniffi")
}
if (nanoseconds < 0) {
throw java.time.DateTimeException("Duration nanoseconds exceed minimum or maximum supported by uniffi")
}
return java.time.Duration.ofSeconds(seconds, nanoseconds)
}
// 8 bytes for seconds, 4 bytes for nanoseconds
override fun allocationSize(value: java.time.Duration) = 12
override fun write(value: java.time.Duration, buf: ByteBuffer) {
if (value.seconds < 0) {
// Rust does not support negative Durations
throw IllegalArgumentException("Invalid duration, must be non-negative")
}
if (value.nano < 0) {
// Java docs provide guarantee that nano will always be positive, so this should be impossible
// See: https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html
throw IllegalArgumentException("Invalid duration, nano value must be non-negative")
}
// Type mismatch (should be u64) but since Rust doesn't support negative durations we should be OK
buf.putLong(value.seconds)
// Type mismatch (should be u32) but since values will always be between 0 and 999,999,999 it should be OK
buf.putInt(value.nano)
}
}
// Interface implemented by anything that can contain an object reference.
//
// Such types expose a `destroy()` method that must be called to cleanly
......@@ -650,7 +682,13 @@ abstract class FFIObject(
public interface NativeSocketInterface {
fun `start`(`mostOnce`: MostOnceListener?, `leastOnce`: LeastOnceListener?)
fun `poll`(): Message?
fun `tryPoll`(): Message?
fun `pollTimeout`(`timeout`: java.time.Duration): Message?
fun `invoke`(`input`: InvokeInput): InvokeOutput
}
......@@ -668,17 +706,42 @@ class NativeSocket(
*/
override protected fun freeRustArcPtr() {
rustCall() { status ->
_UniFFILib.INSTANCE.ffi_NativeSocket_2a33_NativeSocket_object_free(this.pointer, status)
_UniFFILib.INSTANCE.ffi_NativeSocket_2c48_NativeSocket_object_free(this.pointer, status)
}
}
override fun `start`(`mostOnce`: MostOnceListener?, `leastOnce`: LeastOnceListener?) =
override fun `poll`(): Message? =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocket_start(it, FfiConverterOptionalTypeMostOnceListener.lower(`mostOnce`), FfiConverterOptionalTypeLeastOnceListener.lower(`leastOnce`), _status)
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocket_poll(it, _status)
}
}.let {
FfiConverterOptionalTypeMessage.lift(it)
}
override fun `tryPoll`(): Message? =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocket_try_poll(it, _status)
}
}.let {
FfiConverterOptionalTypeMessage.lift(it)
}
override fun `pollTimeout`(`timeout`: java.time.Duration): Message? =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocket_poll_timeout(it, FfiConverterDuration.lower(`timeout`), _status)
}
}.let {
FfiConverterOptionalTypeMessage.lift(it)
}
override fun `invoke`(`input`: InvokeInput): InvokeOutput =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocket_invoke(it, FfiConverterTypeInvokeInput.lower(`input`), _status)
}
}.let {
FfiConverterTypeInvokeOutput.lift(it)
}
......@@ -721,9 +784,7 @@ public interface NativeSocketBuilderInterface {
fun `device`(`device`: String): NativeSocketBuilder
fun `type`(`type`: Int): NativeSocketBuilder
fun `topic`(`topic`: List<String>): NativeSocketBuilder
fun `ty`(`type`: Int): NativeSocketBuilder
fun `cleanStart`(`cleanStart`: Boolean): NativeSocketBuilder
......@@ -731,7 +792,7 @@ public interface NativeSocketBuilderInterface {
fun `logLevel`(`logLevel`: LogLevel): NativeSocketBuilder
fun `sentry`(`sentry`: Boolean): NativeSocketBuilder
fun `version`(`version`: String): NativeSocketBuilder
fun `build`(): NativeSocket?
......@@ -743,7 +804,7 @@ class NativeSocketBuilder(
constructor() :
this(
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_new( _status)
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocketBuilder_new( _status)
})
/**
......@@ -756,14 +817,14 @@ class NativeSocketBuilder(
*/
override protected fun freeRustArcPtr() {
rustCall() { status ->
_UniFFILib.INSTANCE.ffi_NativeSocket_2a33_NativeSocketBuilder_object_free(this.pointer, status)
_UniFFILib.INSTANCE.ffi_NativeSocket_2c48_NativeSocketBuilder_object_free(this.pointer, status)
}
}
override fun `host`(`host`: String): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_host(it, FfiConverterString.lower(`host`), _status)
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocketBuilder_host(it, FfiConverterString.lower(`host`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
......@@ -771,7 +832,7 @@ class NativeSocketBuilder(
override fun `token`(`token`: String): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_token(it, FfiConverterString.lower(`token`), _status)
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocketBuilder_token(it, FfiConverterString.lower(`token`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
......@@ -779,7 +840,7 @@ class NativeSocketBuilder(
override fun `brand`(`brand`: Int): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_brand(it, FfiConverterInt.lower(`brand`), _status)
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocketBuilder_brand(it, FfiConverterInt.lower(`brand`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
......@@ -787,7 +848,7 @@ class NativeSocketBuilder(
override fun `store`(`store`: Int): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_store(it, FfiConverterInt.lower(`store`), _status)
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocketBuilder_store(it, FfiConverterInt.lower(`store`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
......@@ -795,23 +856,15 @@ class NativeSocketBuilder(
override fun `device`(`device`: String): NativeSocketBuilder =
callWithPointer {
rustCall() { _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_2a33_NativeSocketBuilder_type(it, FfiConverterInt.lower(`type`), _status)
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocketBuilder_device(it, FfiConverterString.lower(`device`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
}
override fun `topic`(`topic`: List<String>): NativeSocketBuilder =
override fun `ty`(`type`: Int): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_topic(it, FfiConverterSequenceString.lower(`topic`), _status)
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocketBuilder_ty(it, FfiConverterInt.lower(`type`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
......@@ -819,7 +872,7 @@ class NativeSocketBuilder(
override fun `cleanStart`(`cleanStart`: Boolean): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_clean_start(it, FfiConverterBoolean.lower(`cleanStart`), _status)
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocketBuilder_clean_start(it, FfiConverterBoolean.lower(`cleanStart`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
......@@ -827,7 +880,7 @@ class NativeSocketBuilder(
override fun `cacheDir`(`cacheDir`: String): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_cache_dir(it, FfiConverterString.lower(`cacheDir`), _status)
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocketBuilder_cache_dir(it, FfiConverterString.lower(`cacheDir`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
......@@ -835,15 +888,15 @@ class NativeSocketBuilder(
override fun `logLevel`(`logLevel`: LogLevel): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_log_level(it, FfiConverterTypeLogLevel.lower(`logLevel`), _status)
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocketBuilder_log_level(it, FfiConverterTypeLogLevel.lower(`logLevel`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
}
override fun `sentry`(`sentry`: Boolean): NativeSocketBuilder =
override fun `version`(`version`: String): NativeSocketBuilder =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_sentry(it, FfiConverterBoolean.lower(`sentry`), _status)
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocketBuilder_version(it, FfiConverterString.lower(`version`), _status)
}
}.let {
FfiConverterTypeNativeSocketBuilder.lift(it)
......@@ -851,7 +904,7 @@ class NativeSocketBuilder(
override fun `build`(): NativeSocket? =
callWithPointer {
rustCall() { _status ->
_UniFFILib.INSTANCE.NativeSocket_2a33_NativeSocketBuilder_build(it, _status)
_UniFFILib.INSTANCE.NativeSocket_2c48_NativeSocketBuilder_build(it, _status)
}
}.let {
FfiConverterOptionalTypeNativeSocket.lift(it)
......@@ -889,6 +942,7 @@ public object FfiConverterTypeNativeSocketBuilder: FfiConverter<NativeSocketBuil
data class Message (
var `id`: Long,
var `ty`: Int,
var `qos`: Qos,
var `data`: List<UByte>?
) {
......@@ -899,6 +953,7 @@ public object FfiConverterTypeMessage: FfiConverterRustBuffer<Message> {
return Message(
FfiConverterLong.read(buf),
FfiConverterInt.read(buf),
FfiConverterTypeQos.read(buf),
FfiConverterOptionalSequenceUByte.read(buf),
)
}
......@@ -906,12 +961,14 @@ public object FfiConverterTypeMessage: FfiConverterRustBuffer<Message> {
override fun allocationSize(value: Message) = (
FfiConverterLong.allocationSize(value.`id`) +
FfiConverterInt.allocationSize(value.`ty`) +
FfiConverterTypeQos.allocationSize(value.`qos`) +
FfiConverterOptionalSequenceUByte.allocationSize(value.`data`)
)
override fun write(value: Message, buf: ByteBuffer) {
FfiConverterLong.write(value.`id`, buf)
FfiConverterInt.write(value.`ty`, buf)
FfiConverterTypeQos.write(value.`qos`, buf)
FfiConverterOptionalSequenceUByte.write(value.`data`, buf)
}
}
......@@ -919,324 +976,213 @@ public object FfiConverterTypeMessage: FfiConverterRustBuffer<Message> {
enum class LogLevel {
ERROR,WARN,INFO,DEBUG,TRACE;
}
public object FfiConverterTypeLogLevel: FfiConverterRustBuffer<LogLevel> {
override fun read(buf: ByteBuffer) = try {
LogLevel.values()[buf.getInt() - 1]
} catch (e: IndexOutOfBoundsException) {
throw RuntimeException("invalid enum value, something is very wrong!!", e)
}
override fun allocationSize(value: LogLevel) = 4
override fun write(value: LogLevel, buf: ByteBuffer) {
buf.putInt(value.ordinal + 1)
}
}
sealed class InvokeInput {
object Stop : InvokeInput()
data class Ack(
val `messageId`: Long
) : InvokeInput()
data class Cache(
val `messageId`: Long
) : InvokeInput()
object Online : InvokeInput()
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 {
public object FfiConverterTypeInvokeInput : FfiConverterRustBuffer<InvokeInput>{
override fun read(buf: ByteBuffer): InvokeInput {
return when(buf.getInt()) {
1 -> ConsumerException.Exception(FfiConverterString.read(buf))
else -> throw RuntimeException("invalid error enum value, something is very wrong!!")
1 -> InvokeInput.Stop
2 -> InvokeInput.Ack(
FfiConverterLong.read(buf),
)
3 -> InvokeInput.Cache(
FfiConverterLong.read(buf),
)
4 -> InvokeInput.Online
else -> throw RuntimeException("invalid enum value, something is very wrong!!")
}
}
override fun allocationSize(value: ConsumerException): Int {
return 4
override fun allocationSize(value: InvokeInput) = when(value) {
is InvokeInput.Stop -> {
// Add the size for the Int that specifies the variant plus the size needed for all fields
(
4
)
}
override fun write(value: ConsumerException, buf: ByteBuffer) {
when(value) {
is ConsumerException.Exception -> {
buf.putInt(1)
Unit
is InvokeInput.Ack -> {
// Add the size for the Int that specifies the variant plus the size needed for all fields
(
4
+ FfiConverterLong.allocationSize(value.`messageId`)
)
}
}.let { /* this makes the `when` an expression, which ensures it is exhaustive */ }
is InvokeInput.Cache -> {
// Add the size for the Int that specifies the variant plus the size needed for all fields
(
4
+ FfiConverterLong.allocationSize(value.`messageId`)
)
}
}
internal typealias Handle = Long
internal class ConcurrentHandleMap<T>(
private val leftMap: MutableMap<Handle, T> = mutableMapOf(),
private val rightMap: MutableMap<T, Handle> = mutableMapOf()
) {
private val lock = java.util.concurrent.locks.ReentrantLock()
private val currentHandle = AtomicLong(0L)
private val stride = 1L
fun insert(obj: T): Handle =
lock.withLock {
rightMap[obj] ?:
currentHandle.getAndAdd(stride)
.also { handle ->
leftMap[handle] = obj
rightMap[obj] = handle
is InvokeInput.Online -> {
// Add the size for the Int that specifies the variant plus the size needed for all fields
(
4
)
}
}
fun get(handle: Handle) = lock.withLock {
leftMap[handle]
override fun write(value: InvokeInput, buf: ByteBuffer) {
when(value) {
is InvokeInput.Stop -> {
buf.putInt(1)
Unit
}
fun delete(handle: Handle) {
this.remove(handle)
is InvokeInput.Ack -> {
buf.putInt(2)
FfiConverterLong.write(value.`messageId`, buf)
Unit
}
fun remove(handle: Handle): T? =
lock.withLock {
leftMap.remove(handle)?.let { obj ->
rightMap.remove(obj)
obj
is InvokeInput.Cache -> {
buf.putInt(3)
FfiConverterLong.write(value.`messageId`, buf)
Unit
}
is InvokeInput.Online -> {
buf.putInt(4)
Unit
}
}.let { /* this makes the `when` an expression, which ensures it is exhaustive */ }
}
}
interface ForeignCallback : com.sun.jna.Callback {
public fun invoke(handle: Handle, method: Int, args: RustBuffer.ByValue, outBuf: RustBufferByReference): Int
}
// Magic number for the Rust proxy to call using the same mechanism as every other method,
// to free the callback once it's dropped by Rust.
internal const val IDX_CALLBACK_FREE = 0
public abstract class FfiConverterCallbackInterface<CallbackInterface>(
protected val foreignCallback: ForeignCallback
): FfiConverter<CallbackInterface, Handle> {
private val handleMap = ConcurrentHandleMap<CallbackInterface>()
// Registers the foreign callback with the Rust side.
// This method is generated for each callback interface.
internal abstract fun register(lib: _UniFFILib)
fun drop(handle: Handle): RustBuffer.ByValue {
return handleMap.remove(handle).let { RustBuffer.ByValue() }
}
override fun lift(value: Handle): CallbackInterface {
return handleMap.get(value) ?: throw InternalException("No callback in handlemap; this is a Uniffi bug")
}
sealed class InvokeOutput {
object None : InvokeOutput()
override fun read(buf: ByteBuffer) = lift(buf.getLong())
data class Cache(
val `message`: Message?
) : InvokeOutput()
data class Online(
val `status`: Boolean
) : InvokeOutput()
override fun lower(value: CallbackInterface) =
handleMap.insert(value).also {
assert(handleMap.get(it) === value) { "Handle map is not returning the object we just placed there. This is a bug in the HandleMap." }
}
override fun allocationSize(value: CallbackInterface) = 8
override fun write(value: CallbackInterface, buf: ByteBuffer) {
buf.putLong(lower(value))
}
}
// Declaration and FfiConverters for LeastOnceListener Callback Interface
public interface LeastOnceListener {
fun `consumerMessage`(`message`: Message)
}
public object FfiConverterTypeInvokeOutput : FfiConverterRustBuffer<InvokeOutput>{
override fun read(buf: ByteBuffer): InvokeOutput {
return when(buf.getInt()) {
1 -> InvokeOutput.None
2 -> InvokeOutput.Cache(
FfiConverterOptionalTypeMessage.read(buf),
)
3 -> InvokeOutput.Online(
FfiConverterBoolean.read(buf),
)
else -> throw RuntimeException("invalid enum value, something is very wrong!!")
}
}
// The ForeignCallback that is passed to Rust.
internal class ForeignCallbackTypeLeastOnceListener : ForeignCallback {
@Suppress("TooGenericExceptionCaught")
override fun invoke(handle: Handle, method: Int, args: RustBuffer.ByValue, outBuf: RustBufferByReference): Int {
val cb = FfiConverterTypeLeastOnceListener.lift(handle)
return when (method) {
IDX_CALLBACK_FREE -> {
FfiConverterTypeLeastOnceListener.drop(handle)
// No return value.
// See docs of ForeignCallback in `uniffi/src/ffi/foreigncallbacks.rs`
0
}
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
override fun allocationSize(value: InvokeOutput) = when(value) {
is InvokeOutput.None -> {
// Add the size for the Int that specifies the variant plus the size needed for all fields
(
4
)
}
} catch (e: Throwable) {
// Unexpected error
try {
// Try to serialize the error into a string
outBuf.setValue(FfiConverterString.lower(e.toString()))
} catch (e: Throwable) {
// If that fails, then it's time to give up and just return
is InvokeOutput.Cache -> {
// Add the size for the Int that specifies the variant plus the size needed for all fields
(
4
+ FfiConverterOptionalTypeMessage.allocationSize(value.`message`)
)
}
-1
is InvokeOutput.Online -> {
// Add the size for the Int that specifies the variant plus the size needed for all fields
(
4
+ FfiConverterBoolean.allocationSize(value.`status`)
)
}
}
else -> {
// An unexpected error happened.
// See docs of ForeignCallback in `uniffi/src/ffi/foreigncallbacks.rs`
try {
// Try to serialize the error into a string
outBuf.setValue(FfiConverterString.lower("Invalid Callback index"))
} catch (e: Throwable) {
// If that fails, then it's time to give up and just return
override fun write(value: InvokeOutput, buf: ByteBuffer) {
when(value) {
is InvokeOutput.None -> {
buf.putInt(1)
Unit
}
-1
is InvokeOutput.Cache -> {
buf.putInt(2)
FfiConverterOptionalTypeMessage.write(value.`message`, buf)
Unit
}
is InvokeOutput.Online -> {
buf.putInt(3)
FfiConverterBoolean.write(value.`status`, buf)
Unit
}
}.let { /* this makes the `when` an expression, which ensures it is exhaustive */ }
}
}
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)
)
.let { RustBuffer.ByValue() }
// TODO catch errors and report them back to Rust.
// https://github.com/mozilla/uniffi-rs/issues/351
} finally {
RustBuffer.free(args)
}
enum class LogLevel {
ERROR,WARN,INFO,DEBUG,TRACE;
}
// The ffiConverter which transforms the Callbacks in to Handles to pass to Rust.
public object FfiConverterTypeLeastOnceListener: FfiConverterCallbackInterface<LeastOnceListener>(
foreignCallback = ForeignCallbackTypeLeastOnceListener()
) {
override fun register(lib: _UniFFILib) {
rustCall() { status ->
lib.ffi_NativeSocket_2a33_LeastOnceListener_init_callback(this.foreignCallback, status)
}
public object FfiConverterTypeLogLevel: FfiConverterRustBuffer<LogLevel> {
override fun read(buf: ByteBuffer) = try {
LogLevel.values()[buf.getInt() - 1]
} catch (e: IndexOutOfBoundsException) {
throw RuntimeException("invalid enum value, something is very wrong!!", e)
}
}
override fun allocationSize(value: LogLevel) = 4
override fun write(value: LogLevel, buf: ByteBuffer) {
buf.putInt(value.ordinal + 1)
}
}
// Declaration and FfiConverters for MostOnceListener Callback Interface
public interface MostOnceListener {
fun `consumerMessage`(`message`: Message)
enum class Qos {
AT_MOST_ONCE,AT_LEAST_ONCE;
}
// The ForeignCallback that is passed to Rust.
internal class ForeignCallbackTypeMostOnceListener : ForeignCallback {
@Suppress("TooGenericExceptionCaught")
override fun invoke(handle: Handle, method: Int, args: RustBuffer.ByValue, outBuf: RustBufferByReference): Int {
val cb = FfiConverterTypeMostOnceListener.lift(handle)
return when (method) {
IDX_CALLBACK_FREE -> {
FfiConverterTypeMostOnceListener.drop(handle)
// No return value.
// See docs of ForeignCallback in `uniffi/src/ffi/foreigncallbacks.rs`
0
}
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 {
// Try to serialize the error into a string
outBuf.setValue(FfiConverterString.lower(e.toString()))
} catch (e: Throwable) {
// If that fails, then it's time to give up and just return
}
-1
}
}
else -> {
// An unexpected error happened.
// See docs of ForeignCallback in `uniffi/src/ffi/foreigncallbacks.rs`
try {
// Try to serialize the error into a string
outBuf.setValue(FfiConverterString.lower("Invalid Callback index"))
} catch (e: Throwable) {
// If that fails, then it's time to give up and just return
}
-1
}
}
public object FfiConverterTypeQos: FfiConverterRustBuffer<Qos> {
override fun read(buf: ByteBuffer) = try {
Qos.values()[buf.getInt() - 1]
} catch (e: IndexOutOfBoundsException) {
throw RuntimeException("invalid enum value, something is very wrong!!", e)
}
override fun allocationSize(value: Qos) = 4
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)
)
.let { RustBuffer.ByValue() }
// TODO catch errors and report them back to Rust.
// https://github.com/mozilla/uniffi-rs/issues/351
} finally {
RustBuffer.free(args)
override fun write(value: Qos, buf: ByteBuffer) {
buf.putInt(value.ordinal + 1)
}
}
// The ffiConverter which transforms the Callbacks in to Handles to pass to Rust.
public object FfiConverterTypeMostOnceListener: FfiConverterCallbackInterface<MostOnceListener>(
foreignCallback = ForeignCallbackTypeMostOnceListener()
) {
override fun register(lib: _UniFFILib) {
rustCall() { status ->
lib.ffi_NativeSocket_2a33_MostOnceListener_init_callback(this.foreignCallback, status)
}
}
}
......@@ -1270,57 +1216,28 @@ public object FfiConverterOptionalTypeNativeSocket: FfiConverterRustBuffer<Nativ
public object FfiConverterOptionalTypeLeastOnceListener: FfiConverterRustBuffer<LeastOnceListener?> {
override fun read(buf: ByteBuffer): LeastOnceListener? {
public object FfiConverterOptionalTypeMessage: FfiConverterRustBuffer<Message?> {
override fun read(buf: ByteBuffer): Message? {
if (buf.get().toInt() == 0) {
return null
}
return FfiConverterTypeLeastOnceListener.read(buf)
return FfiConverterTypeMessage.read(buf)
}
override fun allocationSize(value: LeastOnceListener?): Int {
override fun allocationSize(value: Message?): Int {
if (value == null) {
return 1
} else {
return 1 + FfiConverterTypeLeastOnceListener.allocationSize(value)
return 1 + FfiConverterTypeMessage.allocationSize(value)
}
}
override fun write(value: LeastOnceListener?, buf: ByteBuffer) {
override fun write(value: Message?, buf: ByteBuffer) {
if (value == null) {
buf.put(0)
} else {
buf.put(1)
FfiConverterTypeLeastOnceListener.write(value, buf)
}
}
}
public object FfiConverterOptionalTypeMostOnceListener: FfiConverterRustBuffer<MostOnceListener?> {
override fun read(buf: ByteBuffer): MostOnceListener? {
if (buf.get().toInt() == 0) {
return null
}
return FfiConverterTypeMostOnceListener.read(buf)
}
override fun allocationSize(value: MostOnceListener?): Int {
if (value == null) {
return 1
} else {
return 1 + FfiConverterTypeMostOnceListener.allocationSize(value)
}
}
override fun write(value: MostOnceListener?, buf: ByteBuffer) {
if (value == null) {
buf.put(0)
} else {
buf.put(1)
FfiConverterTypeMostOnceListener.write(value, buf)
FfiConverterTypeMessage.write(value, buf)
}
}
}
......@@ -1380,28 +1297,3 @@ public object FfiConverterSequenceUByte: FfiConverterRustBuffer<List<UByte>> {
}
public object FfiConverterSequenceString: FfiConverterRustBuffer<List<String>> {
override fun read(buf: ByteBuffer): List<String> {
val len = buf.getInt()
return List<String>(len) {
FfiConverterString.read(buf)
}
}
override fun allocationSize(value: List<String>): Int {
val sizeForLength = 4
val sizeForItems = value.map { FfiConverterString.allocationSize(it) }.sum()
return sizeForLength + sizeForItems
}
override fun write(value: List<String>, buf: ByteBuffer) {
buf.putInt(value.size)
value.forEach {
FfiConverterString.write(it, buf)
}
}
}
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