feat: update toad-jni
This commit is contained in:
parent
7c96dd576b
commit
7eef137bcd
@ -1,2 +1,2 @@
|
||||
[build]
|
||||
target-dir = "../target/native"
|
||||
target-dir = "../target/glue"
|
||||
|
28
glue/Cargo.lock
generated
28
glue/Cargo.lock
generated
@ -504,9 +504,9 @@ checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||
|
||||
[[package]]
|
||||
name = "toad"
|
||||
version = "0.17.2"
|
||||
version = "0.17.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6e3e3216e542ea3b2da0d2200e498b016907b68acb288b47a487cb9fd681b42"
|
||||
checksum = "5d4000090e5f6d1380e1a4bfb9a5428019cb7a4374b3663792ef7965384968fc"
|
||||
dependencies = [
|
||||
"embedded-time",
|
||||
"log",
|
||||
@ -525,7 +525,7 @@ dependencies = [
|
||||
"toad-len",
|
||||
"toad-macros",
|
||||
"toad-map",
|
||||
"toad-msg 0.15.1",
|
||||
"toad-msg",
|
||||
"toad-stem",
|
||||
"toad-writable",
|
||||
]
|
||||
@ -570,17 +570,18 @@ name = "toad-java-glue"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"jni",
|
||||
"nb",
|
||||
"tinyvec",
|
||||
"toad",
|
||||
"toad-jni",
|
||||
"toad-msg 0.18.1",
|
||||
"toad-msg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toad-jni"
|
||||
version = "0.4.1"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff5fbc1fb554ad85160c74d6c6db551f164b79917c89509037477ad308d2b4ac"
|
||||
checksum = "9d47119dc7ecc1c65fa860a7b2c95dd45b177d07331ee8a18cac0cc41c9bd825"
|
||||
dependencies = [
|
||||
"jni",
|
||||
"toad-array 0.5.0",
|
||||
@ -618,21 +619,6 @@ dependencies = [
|
||||
"toad-len",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toad-msg"
|
||||
version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "172e73f5ce192a45314eef776dd7e1e3cbde1c51ea021d79ac3630549925fbe5"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"tinyvec",
|
||||
"toad-array 0.2.3",
|
||||
"toad-cursor",
|
||||
"toad-len",
|
||||
"toad-macros",
|
||||
"toad-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toad-msg"
|
||||
version = "0.18.1"
|
||||
|
@ -9,7 +9,8 @@ crate_type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
jni = "0.21.1"
|
||||
toad = "0.17.2"
|
||||
toad-jni = "0.4.1"
|
||||
nb = "1"
|
||||
toad = "0.17.3"
|
||||
toad-jni = "0.5.1"
|
||||
toad-msg = "0.18.1"
|
||||
tinyvec = {version = "1.5", default_features = false, features = ["rustc_1_55"]}
|
||||
|
@ -1,15 +1,7 @@
|
||||
#![feature(strict_provenance)]
|
||||
|
||||
use jni::objects::{JClass, JObject};
|
||||
use jni::JNIEnv;
|
||||
use toad::std::{dtls, Platform as Std};
|
||||
use toad::step::runtime::std::Runtime;
|
||||
|
||||
pub static mut RUNTIME: *const Std<dtls::N, Runtime<dtls::N>> = std::ptr::null();
|
||||
|
||||
pub unsafe fn with_runtime_provenance<T>(addr: i64) -> *mut T {
|
||||
RUNTIME.with_addr(addr as usize).cast::<T>().cast_mut()
|
||||
}
|
||||
pub type Runtime =
|
||||
toad::std::Platform<toad::std::dtls::N, toad::step::runtime::std::Runtime<toad::std::dtls::N>>;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! package {
|
||||
@ -18,33 +10,31 @@ macro_rules! package {
|
||||
(ext $start:ident.$($thing:ident).+) => {concat!(stringify!($start), $("/", stringify!($thing)),+)};
|
||||
}
|
||||
|
||||
pub mod mem;
|
||||
pub mod message_code;
|
||||
pub mod message_opt_ref;
|
||||
pub mod message_opt_value_ref;
|
||||
pub mod message_ref;
|
||||
pub mod message_type;
|
||||
pub mod retry_strategy;
|
||||
pub mod runtime;
|
||||
pub mod runtime_config;
|
||||
pub mod uint;
|
||||
|
||||
pub extern "system" fn Java_dev_toad_Runtime_init<'local>(mut env: JNIEnv<'local>,
|
||||
_: JClass<'local>,
|
||||
cfg: JObject<'local>) {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::Once;
|
||||
|
||||
use jni::{InitArgsBuilder, JNIEnv, JavaVM};
|
||||
use jni::{InitArgsBuilder, JavaVM};
|
||||
use toad::retry::Strategy;
|
||||
use toad::time::Millis;
|
||||
use toad_jni::java;
|
||||
|
||||
use crate::retry_strategy::RetryStrategy;
|
||||
use crate::runtime_config::RuntimeConfig;
|
||||
|
||||
static INIT: Once = Once::new();
|
||||
pub fn init<'a>() -> JNIEnv<'a> {
|
||||
pub fn init<'a>() -> java::Env<'a> {
|
||||
INIT.call_once(|| {
|
||||
let jvm =
|
||||
JavaVM::new(InitArgsBuilder::new().option("--enable-preview")
|
||||
@ -54,8 +44,9 @@ mod tests {
|
||||
toad_jni::global::init_with(jvm);
|
||||
});
|
||||
|
||||
toad_jni::global::jvm().attach_current_thread_permanently();
|
||||
toad_jni::global::env()
|
||||
toad_jni::global::jvm().attach_current_thread_permanently()
|
||||
.unwrap();
|
||||
toad_jni::global::jvm().get_env().unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
50
glue/src/mem.rs
Normal file
50
glue/src/mem.rs
Normal file
@ -0,0 +1,50 @@
|
||||
/// global [`RuntimeAllocator`] implementation
|
||||
pub type Runtime = RuntimeGlobalStaticAllocator;
|
||||
|
||||
/// Trait managing the memory region(s) associated with the toad runtime
|
||||
/// data structure.
|
||||
///
|
||||
/// Notably, any and all references produced by the runtime will be to data
|
||||
/// within the Runtime's memory region, meaning that we can easily leverage
|
||||
/// strict provenance to prevent addresses from leaking outside of that memory region.
|
||||
pub trait RuntimeAllocator: core::default::Default + core::fmt::Debug + Copy {
|
||||
/// Allocate memory for the runtime and yield a stable pointer to it
|
||||
unsafe fn alloc(r: crate::Runtime) -> *mut crate::Runtime;
|
||||
|
||||
/// Coerce a `long` rep of the stable pointer created by [`Self::alloc`] to
|
||||
/// a pointer (preferably using strict_provenance)
|
||||
unsafe fn deref(addr: i64) -> *mut crate::Runtime;
|
||||
|
||||
/// Coerce a `long` rep of a pointer to some data within the
|
||||
/// Runtime data structure.
|
||||
///
|
||||
/// Requires the Runtime address in order for the new pointer
|
||||
/// to inherit its provenance.
|
||||
unsafe fn deref_inner<T>(runtime_addr: i64, addr: i64) -> *mut T {
|
||||
Self::deref(runtime_addr).with_addr(addr as usize)
|
||||
.cast::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
static mut RUNTIME: *mut crate::Runtime = core::ptr::null_mut();
|
||||
|
||||
#[derive(Default, Debug, Clone, Copy)]
|
||||
pub struct RuntimeGlobalStaticAllocator;
|
||||
impl RuntimeAllocator for RuntimeGlobalStaticAllocator {
|
||||
/// Nops on already-init
|
||||
unsafe fn alloc(r: crate::Runtime) -> *mut crate::Runtime {
|
||||
if RUNTIME.is_null() {
|
||||
let p =
|
||||
std::alloc::alloc(std::alloc::Layout::new::<crate::Runtime>()).cast::<crate::Runtime>();
|
||||
*p = r;
|
||||
RUNTIME = p;
|
||||
RUNTIME
|
||||
} else {
|
||||
RUNTIME
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn deref(_: i64) -> *mut crate::Runtime {
|
||||
RUNTIME
|
||||
}
|
||||
}
|
@ -1,19 +1,16 @@
|
||||
use jni::objects::{JClass, JObject};
|
||||
use jni::sys::jobject;
|
||||
use jni::JNIEnv;
|
||||
use toad_jni::Sig;
|
||||
use toad_jni::java;
|
||||
use toad_msg::Code;
|
||||
|
||||
pub struct MessageCode<'local>(pub JObject<'local>);
|
||||
impl<'local> MessageCode<'local> {
|
||||
const ID: &'static str = package!(dev.toad.msg.MessageCode);
|
||||
const CTOR: Sig = Sig::new().arg(Sig::INT).arg(Sig::INT).returning(Sig::VOID);
|
||||
pub struct MessageCode(java::lang::Object);
|
||||
|
||||
pub fn new(env: &mut JNIEnv<'local>, code: Code) -> Self {
|
||||
let o = env.new_object(Self::ID,
|
||||
Self::CTOR,
|
||||
&[i32::from(code.class).into(), i32::from(code.detail).into()])
|
||||
.unwrap();
|
||||
Self(o)
|
||||
java::object_newtype!(MessageCode);
|
||||
impl java::Class for MessageCode {
|
||||
const PATH: &'static str = package!(dev.toad.msg.MessageCode);
|
||||
}
|
||||
|
||||
impl MessageCode {
|
||||
pub fn new(e: &mut java::Env, code: Code) -> Self {
|
||||
static CTOR: java::Constructor<MessageCode, fn(i32, i32)> = java::Constructor::new();
|
||||
CTOR.invoke(e, code.class.into(), code.detail.into())
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +1,34 @@
|
||||
use jni::objects::{JClass, JObject};
|
||||
use jni::sys::jobject;
|
||||
use jni::JNIEnv;
|
||||
use toad_jni::Sig;
|
||||
use toad_jni::java::{self, Object};
|
||||
use toad_msg::{OptNumber, OptValue};
|
||||
|
||||
use crate::mem::RuntimeAllocator;
|
||||
use crate::message_opt_value_ref::MessageOptValueRef;
|
||||
use crate::with_runtime_provenance;
|
||||
|
||||
pub struct MessageOptRef<'local>(pub JObject<'local>);
|
||||
impl<'local> MessageOptRef<'local> {
|
||||
const ID: &'static str = package!(dev.toad.msg.MessageOptionRef);
|
||||
const CTOR: Sig = Sig::new().arg(Sig::LONG)
|
||||
.arg(Sig::LONG)
|
||||
.returning(Sig::VOID);
|
||||
pub struct MessageOptRef(pub java::lang::Object);
|
||||
|
||||
const NUMBER: &'static str = "number";
|
||||
java::object_newtype!(MessageOptRef);
|
||||
|
||||
pub fn class(env: &mut JNIEnv<'local>) -> JClass<'local> {
|
||||
env.find_class(Self::ID).unwrap()
|
||||
impl java::Class for MessageOptRef {
|
||||
const PATH: &'static str = package!(dev.toad.msg.MessageOptionRef);
|
||||
}
|
||||
|
||||
impl MessageOptRef {
|
||||
pub fn new(env: &mut java::Env, addr: i64, num: i64) -> Self {
|
||||
static CTOR: java::Constructor<MessageOptRef, fn(i64, i64)> = java::Constructor::new();
|
||||
CTOR.invoke(env, addr, num)
|
||||
}
|
||||
|
||||
pub fn new(env: &mut JNIEnv<'local>, addr: i64, num: i64) -> Self {
|
||||
let o = env.new_object(Self::ID, Self::CTOR, &[addr.into(), num.into()])
|
||||
.unwrap();
|
||||
Self(o)
|
||||
}
|
||||
|
||||
pub fn number(&self, env: &mut JNIEnv<'local>) -> OptNumber {
|
||||
OptNumber(env.get_field(&self.0, Self::NUMBER, Sig::LONG)
|
||||
.unwrap()
|
||||
.j()
|
||||
.unwrap() as u32)
|
||||
pub fn number(&self, env: &mut java::Env) -> OptNumber {
|
||||
static NUMBER: java::Field<MessageOptRef, i64> = java::Field::new("number");
|
||||
OptNumber(NUMBER.get(env, self) as u32)
|
||||
}
|
||||
|
||||
pub unsafe fn values_ptr<'a>(addr: i64) -> &'a mut Vec<OptValue<Vec<u8>>> {
|
||||
with_runtime_provenance::<Vec<OptValue<Vec<u8>>>>(addr).as_mut()
|
||||
.unwrap()
|
||||
crate::mem::Runtime::deref_inner::<Vec<OptValue<Vec<u8>>>>(/* TODO */ 0, addr).as_mut()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,24 +37,21 @@ pub extern "system" fn Java_dev_toad_msg_MessageOptionRef_number<'local>(mut env
|
||||
o: JObject<'local>,
|
||||
p: i64)
|
||||
-> i64 {
|
||||
MessageOptRef(o).number(&mut env).0 as i64
|
||||
java::lang::Object::from_local(&mut env, o).upcast_to::<MessageOptRef>(&mut env)
|
||||
.number(&mut env)
|
||||
.0 as i64
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageOptionRef_values<'local>(mut env: JNIEnv<'local>,
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageOptionRef_values<'local>(mut e: JNIEnv<'local>,
|
||||
_: JClass<'local>,
|
||||
p: i64)
|
||||
-> jobject {
|
||||
let o = &unsafe { MessageOptRef::values_ptr(p) };
|
||||
|
||||
let value_ref_class = MessageOptValueRef::class(&mut env);
|
||||
let mut arr = env.new_object_array(o.len() as i32, value_ref_class, JObject::null())
|
||||
.unwrap();
|
||||
let refs = o.iter()
|
||||
.map(|v| MessageOptValueRef::new(&mut e, (&v.0 as *const Vec<u8>).addr() as i64))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for (ix, v) in o.iter().enumerate() {
|
||||
let value_ref = MessageOptValueRef::new(&mut env, v as *const _ as i64);
|
||||
env.set_object_array_element(&mut arr, ix as i32, value_ref.0);
|
||||
}
|
||||
|
||||
arr.as_raw()
|
||||
refs.downcast(&mut e).as_raw()
|
||||
}
|
||||
|
@ -1,34 +1,31 @@
|
||||
use jni::objects::{JClass, JObject};
|
||||
use jni::objects::JClass;
|
||||
use jni::sys::jobject;
|
||||
use jni::JNIEnv;
|
||||
use toad_jni::Sig;
|
||||
use toad_msg::{OptNumber, OptValue};
|
||||
use toad_jni::java;
|
||||
use toad_msg::OptValue;
|
||||
|
||||
use crate::with_runtime_provenance;
|
||||
use crate::mem::RuntimeAllocator;
|
||||
|
||||
pub struct MessageOptValueRef<'local>(pub JObject<'local>);
|
||||
impl<'local> MessageOptValueRef<'local> {
|
||||
const ID: &'static str = package!(dev.toad.msg.MessageOptionValueRef);
|
||||
const CTOR: Sig = Sig::new().arg(Sig::LONG).returning(Sig::VOID);
|
||||
pub struct MessageOptValueRef(java::lang::Object);
|
||||
|
||||
pub fn class(env: &mut JNIEnv<'local>) -> JClass<'local> {
|
||||
env.find_class(Self::ID).unwrap()
|
||||
}
|
||||
java::object_newtype!(MessageOptValueRef);
|
||||
impl java::Class for MessageOptValueRef {
|
||||
const PATH: &'static str = package!(dev.toad.msg.MessageOptionValueRef);
|
||||
}
|
||||
|
||||
pub fn new(env: &mut JNIEnv<'local>, addr: i64) -> Self {
|
||||
let o = env.new_object(Self::ID, Self::CTOR, &[addr.into()])
|
||||
.unwrap();
|
||||
Self(o)
|
||||
impl MessageOptValueRef {
|
||||
pub fn new(env: &mut java::Env, addr: i64) -> Self {
|
||||
static CTOR: java::Constructor<MessageOptValueRef, fn(i64)> = java::Constructor::new();
|
||||
CTOR.invoke(env, addr)
|
||||
}
|
||||
|
||||
pub unsafe fn ptr<'a>(addr: i64) -> &'a mut OptValue<Vec<u8>> {
|
||||
with_runtime_provenance::<OptValue<Vec<u8>>>(addr).as_mut()
|
||||
.unwrap()
|
||||
crate::mem::Runtime::deref_inner::<OptValue<Vec<u8>>>(/* TODO */ 0, addr).as_mut()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageOptionValueRef_bytes<'local>(mut env: JNIEnv<'local>,
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageOptionValueRef_bytes<'local>(mut env: java::Env<'local>,
|
||||
_: JClass<'local>,
|
||||
p: i64)
|
||||
-> jobject {
|
||||
|
@ -1,32 +1,34 @@
|
||||
use jni::objects::{JClass, JObject};
|
||||
use jni::objects::JClass;
|
||||
use jni::sys::jobject;
|
||||
use jni::JNIEnv;
|
||||
use toad_jni::Sig;
|
||||
use toad_jni::java::{self, Object};
|
||||
use toad_msg::alloc::Message;
|
||||
|
||||
use crate::mem::RuntimeAllocator;
|
||||
use crate::message_code::MessageCode;
|
||||
use crate::message_opt_ref::MessageOptRef;
|
||||
use crate::message_type::MessageType;
|
||||
use crate::{with_runtime_provenance, RUNTIME};
|
||||
|
||||
pub struct MessageRef<'local>(pub JObject<'local>);
|
||||
impl<'local> MessageRef<'local> {
|
||||
const ID: &'static str = package!(dev.toad.msg.MessageRef);
|
||||
const CTOR: Sig = Sig::new().arg(Sig::LONG).returning(Sig::VOID);
|
||||
pub struct MessageRef(java::lang::Object);
|
||||
|
||||
pub fn new(env: &mut JNIEnv<'local>, addr: i64) -> Self {
|
||||
let o = env.new_object(Self::ID, Self::CTOR, &[addr.into()])
|
||||
.unwrap();
|
||||
Self(o)
|
||||
java::object_newtype!(MessageRef);
|
||||
impl java::Class for MessageRef {
|
||||
const PATH: &'static str = package!(dev.toad.msg.MessageRef);
|
||||
}
|
||||
|
||||
impl MessageRef {
|
||||
pub fn new(env: &mut java::Env, addr: *const Message) -> Self {
|
||||
static CTOR: java::Constructor<MessageRef, fn(i64)> = java::Constructor::new();
|
||||
CTOR.invoke(env, addr.addr() as i64)
|
||||
}
|
||||
|
||||
pub unsafe fn ptr<'a>(addr: i64) -> &'a mut Message {
|
||||
with_runtime_provenance::<Message>(addr).as_mut().unwrap()
|
||||
crate::mem::Runtime::deref_inner::<Message>(/* TODO */ 0, addr).as_mut()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageRef_id<'local>(mut env: JNIEnv<'local>,
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageRef_id<'local>(mut env: java::Env<'local>,
|
||||
_: JClass<'local>,
|
||||
addr: i64)
|
||||
-> i32 {
|
||||
@ -35,7 +37,7 @@ pub extern "system" fn Java_dev_toad_msg_MessageRef_id<'local>(mut env: JNIEnv<'
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageRef_token<'local>(mut env: JNIEnv<'local>,
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageRef_token<'local>(mut env: java::Env<'local>,
|
||||
_: JClass<'local>,
|
||||
addr: i64)
|
||||
-> jobject {
|
||||
@ -44,7 +46,7 @@ pub extern "system" fn Java_dev_toad_msg_MessageRef_token<'local>(mut env: JNIEn
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageRef_payload<'local>(mut env: JNIEnv<'local>,
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageRef_payload<'local>(mut env: java::Env<'local>,
|
||||
_: JClass<'local>,
|
||||
addr: i64)
|
||||
-> jobject {
|
||||
@ -53,39 +55,34 @@ pub extern "system" fn Java_dev_toad_msg_MessageRef_payload<'local>(mut env: JNI
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageRef_type<'local>(mut env: JNIEnv<'local>,
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageRef_type<'local>(mut e: java::Env<'local>,
|
||||
_: JClass<'local>,
|
||||
addr: i64)
|
||||
-> jobject {
|
||||
let msg = unsafe { MessageRef::ptr(addr) };
|
||||
MessageType::new(&mut env, msg.ty).0.into_raw()
|
||||
MessageType::new(&mut e, msg.ty).downcast(&mut e).as_raw()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageRef_code<'local>(mut env: JNIEnv<'local>,
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageRef_code<'local>(mut e: java::Env<'local>,
|
||||
_: JClass<'local>,
|
||||
addr: i64)
|
||||
-> jobject {
|
||||
let msg = unsafe { MessageRef::ptr(addr) };
|
||||
MessageCode::new(&mut env, msg.code).0.into_raw()
|
||||
MessageCode::new(&mut e, msg.code).downcast(&mut e).as_raw()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageRef_opts<'local>(mut env: JNIEnv<'local>,
|
||||
pub extern "system" fn Java_dev_toad_msg_MessageRef_opts<'local>(mut e: java::Env<'local>,
|
||||
_: JClass<'local>,
|
||||
addr: i64)
|
||||
-> jobject {
|
||||
let msg = unsafe { MessageRef::ptr(addr) };
|
||||
let opts = &msg.opts;
|
||||
|
||||
let opt_ref_class = MessageOptRef::class(&mut env);
|
||||
let mut arr = env.new_object_array((*opts).len() as i32, opt_ref_class, JObject::null())
|
||||
.unwrap();
|
||||
let refs = opts.into_iter()
|
||||
.map(|(n, v)| MessageOptRef::new(&mut e, v as *const _ as i64, n.0.into()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for (ix, (num, v)) in (*opts).iter().enumerate() {
|
||||
let opt_ref = MessageOptRef::new(&mut env, v as *const _ as i64, num.0.into());
|
||||
env.set_object_array_element(&mut arr, ix as i32, opt_ref.0);
|
||||
}
|
||||
|
||||
arr.as_raw()
|
||||
refs.downcast(&mut e).as_raw()
|
||||
}
|
||||
|
@ -1,32 +1,25 @@
|
||||
use jni::objects::{JObject, JString, JValueGen};
|
||||
use jni::sys::jstring;
|
||||
use jni::JNIEnv;
|
||||
use toad_jni::Sig;
|
||||
use toad_jni::java;
|
||||
use toad_msg::Type;
|
||||
|
||||
pub struct MessageType<'local>(pub JObject<'local>);
|
||||
impl<'local> MessageType<'local> {
|
||||
const ID: &'static str = package!(dev.toad.msg.MessageType);
|
||||
const FROM_STRING: Sig = Sig::new().arg(Sig::class("java/lang/String"))
|
||||
.returning(Sig::class(Self::ID));
|
||||
pub struct MessageType(java::lang::Object);
|
||||
|
||||
pub fn new(env: &mut JNIEnv<'local>, ty: Type) -> Self {
|
||||
let str = env.new_string(match ty {
|
||||
| Type::Con => "CON",
|
||||
| Type::Non => "NON",
|
||||
| Type::Ack => "ACK",
|
||||
| Type::Reset => "RESET",
|
||||
})
|
||||
.unwrap();
|
||||
java::object_newtype!(MessageType);
|
||||
impl java::Class for MessageType {
|
||||
const PATH: &'static str = package!(dev.toad.msg.MessageType);
|
||||
}
|
||||
|
||||
let o = env.call_static_method(Self::ID,
|
||||
"fromString",
|
||||
Self::FROM_STRING,
|
||||
&[JValueGen::Object(&str)])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
impl MessageType {
|
||||
pub fn new(env: &mut java::Env, ty: Type) -> Self {
|
||||
static FROM_STRING: java::StaticMethod<MessageType, fn(String) -> MessageType> =
|
||||
java::StaticMethod::new("fromString");
|
||||
|
||||
Self(o)
|
||||
let str = match ty {
|
||||
| Type::Con => "CON",
|
||||
| Type::Non => "NON",
|
||||
| Type::Ack => "ACK",
|
||||
| Type::Reset => "RESET",
|
||||
};
|
||||
|
||||
FROM_STRING.invoke(env, str.to_string())
|
||||
}
|
||||
}
|
||||
|
@ -1,89 +1,103 @@
|
||||
use jni::objects::{GlobalRef, JObject};
|
||||
use jni::JNIEnv;
|
||||
use toad::retry::Strategy;
|
||||
use toad::time::Millis;
|
||||
use toad_jni::cls::java;
|
||||
use toad_jni::convert::Object;
|
||||
use toad_jni::Sig;
|
||||
use toad_jni::java::{self, Object};
|
||||
|
||||
use crate::uint;
|
||||
|
||||
pub struct RetryStrategy(GlobalRef);
|
||||
pub struct RetryStrategyExp(java::lang::Object);
|
||||
|
||||
java::object_newtype!(RetryStrategyExp);
|
||||
impl java::Class for RetryStrategyExp {
|
||||
const PATH: &'static str = package!(dev.toad.RetryStrategyExponential);
|
||||
}
|
||||
|
||||
impl RetryStrategyExp {
|
||||
pub fn new(e: &mut java::Env, init_min: Millis, init_max: Millis) -> Self {
|
||||
let (init_min, init_max) = (java::time::Duration::of_millis(e, init_min.0 as i64),
|
||||
java::time::Duration::of_millis(e, init_max.0 as i64));
|
||||
static CTOR: java::Constructor<RetryStrategyExp,
|
||||
fn(java::time::Duration, java::time::Duration)> =
|
||||
java::Constructor::new();
|
||||
CTOR.invoke(e, init_min, init_max)
|
||||
}
|
||||
|
||||
pub fn as_super(self) -> RetryStrategy {
|
||||
RetryStrategy(self.0)
|
||||
}
|
||||
|
||||
pub fn init_min(&self, e: &mut java::Env) -> Millis {
|
||||
static INIT_MIN: java::Field<RetryStrategyExp, uint::u64> = java::Field::new("initMin");
|
||||
Millis::new(INIT_MIN.get(e, self).to_rust(e))
|
||||
}
|
||||
|
||||
pub fn init_max(&self, e: &mut java::Env) -> Millis {
|
||||
static INIT_MAX: java::Field<RetryStrategyExp, uint::u64> = java::Field::new("initMax");
|
||||
Millis::new(INIT_MAX.get(e, self).to_rust(e))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RetryStrategyDelay(java::lang::Object);
|
||||
|
||||
java::object_newtype!(RetryStrategyDelay);
|
||||
impl java::Class for RetryStrategyDelay {
|
||||
const PATH: &'static str = package!(dev.toad.RetryStrategyDelay);
|
||||
}
|
||||
|
||||
impl RetryStrategyDelay {
|
||||
pub fn new(e: &mut java::Env, min: Millis, max: Millis) -> Self {
|
||||
let (min, max) = (java::time::Duration::of_millis(e, min.0 as i64),
|
||||
java::time::Duration::of_millis(e, max.0 as i64));
|
||||
static CTOR: java::Constructor<RetryStrategyDelay,
|
||||
fn(java::time::Duration, java::time::Duration)> =
|
||||
java::Constructor::new();
|
||||
CTOR.invoke(e, min, max)
|
||||
}
|
||||
|
||||
pub fn as_super(self) -> RetryStrategy {
|
||||
RetryStrategy(self.0)
|
||||
}
|
||||
|
||||
pub fn min(&self, e: &mut java::Env) -> Millis {
|
||||
static MIN: java::Field<RetryStrategyDelay, uint::u64> = java::Field::new("min");
|
||||
Millis::new(MIN.get(e, self).to_rust(e))
|
||||
}
|
||||
|
||||
pub fn max(&self, e: &mut java::Env) -> Millis {
|
||||
static MAX: java::Field<RetryStrategyDelay, uint::u64> = java::Field::new("max");
|
||||
Millis::new(MAX.get(e, self).to_rust(e))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RetryStrategy(java::lang::Object);
|
||||
|
||||
java::object_newtype!(RetryStrategy);
|
||||
impl java::Class for RetryStrategy {
|
||||
const PATH: &'static str = package!(dev.toad.RetryStrategy);
|
||||
}
|
||||
|
||||
impl RetryStrategy {
|
||||
pub const PATH: &'static str = package!(dev.toad.RetryStrategy);
|
||||
|
||||
pub const EXPONENTIAL: &'static str = package!(dev.toad.RetryStrategyExponential);
|
||||
pub const EXPONENTIAL_CTOR: Sig = Sig::new().arg(Sig::class(java::time::Duration::PATH))
|
||||
.arg(Sig::class(java::time::Duration::PATH))
|
||||
.returning(Sig::VOID);
|
||||
|
||||
pub const DELAY: &'static str = package!(dev.toad.RetryStrategyDelay);
|
||||
pub const DELAY_CTOR: Sig = Sig::new().arg(Sig::class(java::time::Duration::PATH))
|
||||
.arg(Sig::class(java::time::Duration::PATH))
|
||||
.returning(Sig::VOID);
|
||||
|
||||
pub fn exp<'a>(&self, e: &mut JNIEnv<'a>) -> Self {
|
||||
let o = e.new_object(Self::PATH, Sig::new().returning(Sig::VOID), &[])
|
||||
.unwrap();
|
||||
let g = e.new_global_ref(o).unwrap();
|
||||
Self(g)
|
||||
}
|
||||
|
||||
pub fn millis_field<'a>(&self, e: &mut JNIEnv<'a>, key: &str) -> Millis {
|
||||
let o = e.get_field(&self.0, key, Sig::class(uint::u64::PATH))
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
let g = e.new_global_ref(o).unwrap();
|
||||
let d = uint::u64::from_java(g);
|
||||
Millis::new(d.to_rust(e))
|
||||
}
|
||||
|
||||
pub fn to_toad<'a>(self, e: &mut JNIEnv<'a>) -> Strategy {
|
||||
if e.is_instance_of(&self.0, Self::EXPONENTIAL).unwrap() {
|
||||
Strategy::Exponential { init_min: self.millis_field(e, "initMin"),
|
||||
init_max: self.millis_field(e, "initMax") }
|
||||
pub fn to_toad(self, e: &mut java::Env) -> Strategy {
|
||||
if self.0.is_instance_of::<RetryStrategyExp>(e) {
|
||||
let me = RetryStrategyExp(self.0);
|
||||
Strategy::Exponential { init_min: me.init_min(e),
|
||||
init_max: me.init_max(e) }
|
||||
} else if self.0.is_instance_of::<RetryStrategyDelay>(e) {
|
||||
let me = RetryStrategyDelay(self.0);
|
||||
Strategy::Delay { min: me.min(e),
|
||||
max: me.max(e) }
|
||||
} else {
|
||||
Strategy::Delay { min: self.millis_field(e, "min"),
|
||||
max: self.millis_field(e, "max") }
|
||||
let cls = e.get_object_class(self.0).unwrap();
|
||||
panic!("unknown inheritor of RetryStrategy: {}",
|
||||
java::lang::Object::from_local(e, cls).to_string(e));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_toad<'a>(e: &mut JNIEnv<'a>, s: Strategy) -> Self {
|
||||
let g = match s {
|
||||
| Strategy::Delay { min, max } => {
|
||||
let (min, max) = (java::time::Duration::of_millis(e, min.0 as i64),
|
||||
java::time::Duration::of_millis(e, max.0 as i64));
|
||||
let (min, max) = (min.to_java(), max.to_java());
|
||||
let o = e.new_object(Self::DELAY,
|
||||
Self::DELAY_CTOR,
|
||||
&[min.as_obj().into(), max.as_obj().into()])
|
||||
.unwrap();
|
||||
e.new_global_ref(o).unwrap()
|
||||
},
|
||||
pub fn from_toad(e: &mut java::Env, s: Strategy) -> Self {
|
||||
match s {
|
||||
| Strategy::Delay { min, max } => RetryStrategyDelay::new(e, min, max).as_super(),
|
||||
| Strategy::Exponential { init_min, init_max } => {
|
||||
let (init_min, init_max) = (java::time::Duration::of_millis(e, init_min.0 as i64),
|
||||
java::time::Duration::of_millis(e, init_max.0 as i64));
|
||||
let (init_min, init_max) = (init_min.to_java(), init_max.to_java());
|
||||
let o = e.new_object(Self::EXPONENTIAL,
|
||||
Self::EXPONENTIAL_CTOR,
|
||||
&[init_min.as_obj().into(), init_max.as_obj().into()])
|
||||
.unwrap();
|
||||
e.new_global_ref(o).unwrap()
|
||||
RetryStrategyExp::new(e, init_min, init_max).as_super()
|
||||
},
|
||||
};
|
||||
|
||||
Self(g)
|
||||
}
|
||||
}
|
||||
|
||||
impl Object for RetryStrategy {
|
||||
fn from_java(jobj: GlobalRef) -> Self {
|
||||
Self(jobj)
|
||||
}
|
||||
|
||||
fn to_java(self) -> GlobalRef {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
69
glue/src/runtime.rs
Normal file
69
glue/src/runtime.rs
Normal file
@ -0,0 +1,69 @@
|
||||
use jni::objects::{JClass, JObject};
|
||||
use jni::sys::jobject;
|
||||
use toad::platform::Platform;
|
||||
use toad_jni::java::{self, Object};
|
||||
|
||||
use crate::mem::RuntimeAllocator;
|
||||
use crate::message_ref::MessageRef;
|
||||
use crate::runtime_config::RuntimeConfig;
|
||||
use crate::Runtime as ToadRuntime;
|
||||
|
||||
pub struct Runtime(java::lang::Object);
|
||||
|
||||
impl Runtime {
|
||||
pub fn init(e: &mut java::Env, cfg: RuntimeConfig) -> i64 {
|
||||
let r =
|
||||
ToadRuntime::try_new(format!("0.0.0.0:{}", cfg.net(e).port(e)), cfg.to_toad(e)).unwrap();
|
||||
unsafe { crate::mem::Runtime::alloc(r).addr() as i64 }
|
||||
}
|
||||
|
||||
pub fn addr(&self, e: &mut java::Env) -> i64 {
|
||||
static ADDR: java::Field<Runtime, i64> = java::Field::new("addr");
|
||||
ADDR.get(e, self)
|
||||
}
|
||||
|
||||
pub fn ref_(&self, e: &mut java::Env) -> &'static ToadRuntime {
|
||||
unsafe { crate::mem::Runtime::deref(self.addr(e)).as_ref().unwrap() }
|
||||
}
|
||||
}
|
||||
|
||||
java::object_newtype!(Runtime);
|
||||
|
||||
impl java::Class for Runtime {
|
||||
const PATH: &'static str = package!(dev.toad.Runtime);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_dev_toad_Runtime_init<'local>(mut e: java::Env<'local>,
|
||||
_: JClass<'local>,
|
||||
cfg: JObject<'local>)
|
||||
-> i64 {
|
||||
let e = &mut e;
|
||||
let cfg = java::lang::Object::from_local(e, cfg).upcast_to::<RuntimeConfig>(e);
|
||||
|
||||
Runtime::init(e, cfg)
|
||||
}
|
||||
|
||||
// JNIEXPORT jobject JNICALL Java_dev_toad_Runtime_pollReq
|
||||
// (JNIEnv *, jobject, jobject);
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_dev_toad_Runtime_pollReq<'local>(mut e: java::Env<'local>,
|
||||
runtime: JObject<'local>,
|
||||
cfg: JObject<'local>)
|
||||
-> jobject {
|
||||
let e = &mut e;
|
||||
let runtime = java::lang::Object::from_local(e, runtime).upcast_to::<Runtime>(e);
|
||||
match runtime.ref_(e).poll_req() {
|
||||
| Ok(req) => {
|
||||
let mr = MessageRef::new(e, req.data().msg());
|
||||
java::util::Optional::<MessageRef>::of(e, mr).downcast(e)
|
||||
.as_raw()
|
||||
},
|
||||
| Err(nb::Error::WouldBlock) => java::util::Optional::<MessageRef>::empty(e).downcast(e)
|
||||
.as_raw(),
|
||||
| Err(nb::Error::Other(err)) => {
|
||||
e.throw(format!("{:?}", err)).unwrap();
|
||||
core::ptr::null_mut()
|
||||
},
|
||||
}
|
||||
}
|
@ -1,39 +1,29 @@
|
||||
use jni::objects::{GlobalRef, JObject};
|
||||
use jni::sys::{jint, jshort};
|
||||
use jni::JNIEnv;
|
||||
use toad::config::{self, BytesPerSecond};
|
||||
use toad::retry::{Attempts, Strategy};
|
||||
use toad::time::Millis;
|
||||
use toad_jni::cls::java;
|
||||
use toad_jni::convert::{Object, Primitive};
|
||||
use toad_jni::Sig;
|
||||
use toad_jni::java;
|
||||
|
||||
use crate::retry_strategy::RetryStrategy;
|
||||
|
||||
pub struct RuntimeConfig<'a>(JObject<'a>);
|
||||
pub struct RuntimeConfig(java::lang::Object);
|
||||
|
||||
impl<'a> RuntimeConfig<'a> {
|
||||
pub const PATH: &'static str = package!(dev.toad.RuntimeOptions);
|
||||
java::object_newtype!(RuntimeConfig);
|
||||
impl java::Class for RuntimeConfig {
|
||||
const PATH: &'static str = package!(dev.toad.RuntimeOptions);
|
||||
}
|
||||
|
||||
pub const CTOR: Sig = Sig::new().returning(Sig::VOID);
|
||||
|
||||
pub fn new(e: &mut JNIEnv<'a>) -> Self {
|
||||
let o = e.new_object(Self::PATH, Self::CTOR, &[]).unwrap();
|
||||
Self(o)
|
||||
impl RuntimeConfig {
|
||||
pub fn new(e: &mut java::Env) -> Self {
|
||||
static CTOR: java::Constructor<RuntimeConfig, fn()> = java::Constructor::new();
|
||||
CTOR.invoke(e)
|
||||
}
|
||||
|
||||
pub fn net(&self, e: &mut JNIEnv<'a>) -> Net<'a> {
|
||||
let o = e.call_method(&self.0,
|
||||
"net",
|
||||
Sig::new().returning(Sig::class(Net::PATH)),
|
||||
&[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
Net(o)
|
||||
pub fn net(&self, e: &mut java::Env) -> Net {
|
||||
static NET: java::Method<RuntimeConfig, fn() -> Net> = java::Method::new("net");
|
||||
NET.invoke(e, self)
|
||||
}
|
||||
|
||||
pub fn to_toad(&self, e: &mut JNIEnv<'a>) -> config::Config {
|
||||
pub fn to_toad(&self, e: &mut java::Env) -> config::Config {
|
||||
let def = config::Config::default();
|
||||
|
||||
let net = self.net(e);
|
||||
@ -78,182 +68,121 @@ impl<'a> RuntimeConfig<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Net<'a>(JObject<'a>);
|
||||
impl<'a> Net<'a> {
|
||||
pub const PATH: &'static str = concat!(package!(dev.toad.RuntimeOptions), "$Net");
|
||||
pub struct Net(java::lang::Object);
|
||||
java::object_newtype!(Net);
|
||||
impl java::Class for Net {
|
||||
const PATH: &'static str = concat!(package!(dev.toad.RuntimeOptions), "$Net");
|
||||
}
|
||||
|
||||
pub fn port(&self, e: &mut JNIEnv<'a>) -> jshort {
|
||||
e.call_method(&self.0, "port", Sig::new().returning(Sig::SHORT), &[])
|
||||
.unwrap()
|
||||
.s()
|
||||
.unwrap()
|
||||
impl Net {
|
||||
pub fn port(&self, e: &mut java::Env) -> i16 {
|
||||
static PORT: java::Method<Net, fn() -> i16> = java::Method::new("port");
|
||||
PORT.invoke(e, self)
|
||||
}
|
||||
|
||||
pub fn concurrency(&self, e: &mut JNIEnv<'a>) -> jshort {
|
||||
e.call_method(&self.0,
|
||||
"concurrency",
|
||||
Sig::new().returning(Sig::SHORT),
|
||||
&[])
|
||||
.unwrap()
|
||||
.s()
|
||||
.unwrap()
|
||||
pub fn concurrency(&self, e: &mut java::Env) -> i16 {
|
||||
static CONCURRENCY: java::Method<Net, fn() -> i16> = java::Method::new("concurrency");
|
||||
CONCURRENCY.invoke(e, self)
|
||||
}
|
||||
|
||||
pub fn msg(&self, e: &mut JNIEnv<'a>) -> Msg<'a> {
|
||||
let o = e.call_method(&self.0,
|
||||
"msg",
|
||||
Sig::new().returning(Sig::class(Msg::PATH)),
|
||||
&[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
Msg(o)
|
||||
pub fn msg(&self, e: &mut java::Env) -> Msg {
|
||||
static MSG: java::Method<Net, fn() -> Msg> = java::Method::new("msg");
|
||||
MSG.invoke(e, self)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Msg<'a>(JObject<'a>);
|
||||
impl<'a> Msg<'a> {
|
||||
pub const PATH: &'static str = concat!(package!(dev.toad.RuntimeOptions), "$Msg");
|
||||
pub struct Msg(java::lang::Object);
|
||||
|
||||
pub const TOKEN_SEED: Sig = Sig::new().returning(Sig::class(java::util::Optional::<jint>::PATH));
|
||||
pub const PROBING_RATE: Sig =
|
||||
Sig::new().returning(Sig::class(java::util::Optional::<jint>::PATH));
|
||||
pub const MULTICAST_RESP_LEISURE: Sig =
|
||||
Sig::new().returning(Sig::class(java::util::Optional::<GlobalRef>::PATH));
|
||||
pub const CON: Sig = Sig::new().returning(Sig::class(Con::PATH));
|
||||
pub const NON: Sig = Sig::new().returning(Sig::class(Non::PATH));
|
||||
java::object_newtype!(Msg);
|
||||
|
||||
pub fn token_seed(&self, e: &mut JNIEnv<'a>) -> Option<jint> {
|
||||
let o = e.call_method(&self.0, "tokenSeed", Self::TOKEN_SEED, &[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
let g = e.new_global_ref(o).unwrap();
|
||||
java::util::Optional::<jint>::from_java(g).to_option(e)
|
||||
impl java::Class for Msg {
|
||||
const PATH: &'static str = concat!(package!(dev.toad.RuntimeOptions), "$Msg");
|
||||
}
|
||||
|
||||
impl Msg {
|
||||
pub fn token_seed(&self, e: &mut java::Env) -> Option<i32> {
|
||||
static TOKEN_SEED: java::Method<Msg, fn() -> java::util::Optional<i32>> =
|
||||
java::Method::new("tokenSeed");
|
||||
TOKEN_SEED.invoke(e, self).to_option(e)
|
||||
}
|
||||
|
||||
pub fn probing_rate(&self, e: &mut JNIEnv<'a>) -> Option<jint> {
|
||||
let o = e.call_method(&self.0,
|
||||
"probingRateBytesPerSecond",
|
||||
Self::PROBING_RATE,
|
||||
&[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
let g = e.new_global_ref(o).unwrap();
|
||||
java::util::Optional::<jint>::from_java(g).to_option(e)
|
||||
pub fn probing_rate(&self, e: &mut java::Env) -> Option<i32> {
|
||||
static PROBING_RATE: java::Method<Msg, fn() -> java::util::Optional<i32>> =
|
||||
java::Method::new("probingRateBytesPerSecond");
|
||||
PROBING_RATE.invoke(e, self).to_option(e)
|
||||
}
|
||||
|
||||
pub fn multicast_response_leisure(&self, e: &mut JNIEnv<'a>) -> Option<Millis> {
|
||||
let o = e.call_method(&self.0,
|
||||
"multicastResponseLeisure",
|
||||
Self::MULTICAST_RESP_LEISURE,
|
||||
&[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
let g = e.new_global_ref(o).unwrap();
|
||||
java::util::Optional::<GlobalRef>::from_java(g).to_option(e)
|
||||
.map(java::time::Duration::from_java)
|
||||
.map(|d| Millis::new(d.to_millis(e) as u64))
|
||||
pub fn multicast_response_leisure(&self, e: &mut java::Env) -> Option<Millis> {
|
||||
static MULTICAST_RESP_LEISURE: java::Method<Msg,
|
||||
fn()
|
||||
-> java::util::Optional<java::time::Duration>> =
|
||||
java::Method::new("multicastResponseLeisure");
|
||||
MULTICAST_RESP_LEISURE.invoke(e, self)
|
||||
.to_option(e)
|
||||
.map(|d| Millis::new(d.to_millis(e) as u64))
|
||||
}
|
||||
|
||||
pub fn con(&self, e: &mut JNIEnv<'a>) -> Con<'a> {
|
||||
let o = e.call_method(&self.0, "con", Self::CON, &[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
Con(o)
|
||||
pub fn con(&self, e: &mut java::Env) -> Con {
|
||||
static CON: java::Method<Msg, fn() -> Con> = java::Method::new("con");
|
||||
CON.invoke(e, self)
|
||||
}
|
||||
|
||||
pub fn non(&self, e: &mut JNIEnv<'a>) -> Non<'a> {
|
||||
let o = e.call_method(&self.0, "non", Self::NON, &[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
Non(o)
|
||||
pub fn non(&self, e: &mut java::Env) -> Non {
|
||||
static NON: java::Method<Msg, fn() -> Non> = java::Method::new("non");
|
||||
NON.invoke(e, self)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Con<'a>(JObject<'a>);
|
||||
impl<'a> Con<'a> {
|
||||
pub const PATH: &'static str = concat!(package!(dev.toad.RuntimeOptions), "$Msg$Con");
|
||||
pub struct Con(java::lang::Object);
|
||||
|
||||
pub const ACKED_RETRY_STRATEGY: Sig =
|
||||
Sig::new().returning(Sig::class(java::util::Optional::<GlobalRef>::PATH));
|
||||
pub const UNACKED_RETRY_STRATEGY: Sig =
|
||||
Sig::new().returning(Sig::class(java::util::Optional::<GlobalRef>::PATH));
|
||||
pub const MAX_ATTEMPTS: Sig =
|
||||
Sig::new().returning(Sig::class(java::util::Optional::<jint>::PATH));
|
||||
java::object_newtype!(Con);
|
||||
impl java::Class for Con {
|
||||
const PATH: &'static str = concat!(package!(dev.toad.RuntimeOptions), "$Msg$Con");
|
||||
}
|
||||
|
||||
pub fn acked_retry_strategy(&self, e: &mut JNIEnv<'a>) -> Option<Strategy> {
|
||||
let o = e.call_method(&self.0,
|
||||
"ackedRetryStrategy",
|
||||
Self::ACKED_RETRY_STRATEGY,
|
||||
&[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
let g = e.new_global_ref(o).unwrap();
|
||||
java::util::Optional::<GlobalRef>::from_java(g).to_option(e)
|
||||
.map(RetryStrategy::from_java)
|
||||
.map(|j| j.to_toad(e))
|
||||
impl Con {
|
||||
pub fn acked_retry_strategy(&self, e: &mut java::Env) -> Option<Strategy> {
|
||||
static ACKED_RETRY_STRATEGY: java::Method<Con, fn() -> java::util::Optional<RetryStrategy>> =
|
||||
java::Method::new("ackedRetryStrategy");
|
||||
ACKED_RETRY_STRATEGY.invoke(e, self)
|
||||
.to_option(e)
|
||||
.map(|s| s.to_toad(e))
|
||||
}
|
||||
|
||||
pub fn unacked_retry_strategy(&self, e: &mut JNIEnv<'a>) -> Option<Strategy> {
|
||||
let o = e.call_method(&self.0,
|
||||
"unackedRetryStrategy",
|
||||
Self::UNACKED_RETRY_STRATEGY,
|
||||
&[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
let g = e.new_global_ref(o).unwrap();
|
||||
java::util::Optional::<GlobalRef>::from_java(g).to_option(e)
|
||||
.map(RetryStrategy::from_java)
|
||||
.map(|j| j.to_toad(e))
|
||||
pub fn unacked_retry_strategy(&self, e: &mut java::Env) -> Option<Strategy> {
|
||||
static UNACKED_RETRY_STRATEGY: java::Method<Con, fn() -> java::util::Optional<RetryStrategy>> =
|
||||
java::Method::new("unackedRetryStrategy");
|
||||
UNACKED_RETRY_STRATEGY.invoke(e, self)
|
||||
.to_option(e)
|
||||
.map(|s| s.to_toad(e))
|
||||
}
|
||||
|
||||
pub fn max_attempts(&self, e: &mut JNIEnv<'a>) -> Option<jint> {
|
||||
let o = e.call_method(&self.0, "maxAttempts", Self::MAX_ATTEMPTS, &[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
let g = e.new_global_ref(o).unwrap();
|
||||
java::util::Optional::<GlobalRef>::from_java(g).to_option(e)
|
||||
.map(java::lang::Integer::from_java)
|
||||
.map(Primitive::dewrap)
|
||||
pub fn max_attempts(&self, e: &mut java::Env) -> Option<i32> {
|
||||
static MAX_ATTEMPTS: java::Method<Con, fn() -> java::util::Optional<i32>> =
|
||||
java::Method::new("maxAttempts");
|
||||
MAX_ATTEMPTS.invoke(e, self).to_option(e)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Non<'a>(JObject<'a>);
|
||||
impl<'a> Non<'a> {
|
||||
pub const PATH: &'static str = concat!(package!(dev.toad.RuntimeOptions), "$Msg$Non");
|
||||
pub struct Non(java::lang::Object);
|
||||
|
||||
pub const RETRY_STRATEGY: Sig =
|
||||
Sig::new().returning(Sig::class(java::util::Optional::<GlobalRef>::PATH));
|
||||
pub const MAX_ATTEMPTS: Sig =
|
||||
Sig::new().returning(Sig::class(java::util::Optional::<jint>::PATH));
|
||||
java::object_newtype!(Non);
|
||||
impl java::Class for Non {
|
||||
const PATH: &'static str = concat!(package!(dev.toad.RuntimeOptions), "$Msg$Non");
|
||||
}
|
||||
|
||||
pub fn retry_strategy(&self, e: &mut JNIEnv<'a>) -> Option<Strategy> {
|
||||
let o = e.call_method(&self.0, "retryStrategy", Self::RETRY_STRATEGY, &[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
let g = e.new_global_ref(o).unwrap();
|
||||
java::util::Optional::<GlobalRef>::from_java(g).to_option(e)
|
||||
.map(RetryStrategy::from_java)
|
||||
.map(|j| j.to_toad(e))
|
||||
impl Non {
|
||||
pub fn retry_strategy(&self, e: &mut java::Env) -> Option<Strategy> {
|
||||
static RETRY_STRATEGY: java::Method<Non, fn() -> java::util::Optional<RetryStrategy>> =
|
||||
java::Method::new("retryStrategy");
|
||||
RETRY_STRATEGY.invoke(e, self)
|
||||
.to_option(e)
|
||||
.map(|s| s.to_toad(e))
|
||||
}
|
||||
|
||||
pub fn max_attempts(&self, e: &mut JNIEnv<'a>) -> Option<jint> {
|
||||
let o = e.call_method(&self.0, "maxAttempts", Self::MAX_ATTEMPTS, &[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
let g = e.new_global_ref(o).unwrap();
|
||||
java::util::Optional::<GlobalRef>::from_java(g).to_option(e)
|
||||
.map(java::lang::Integer::from_java)
|
||||
.map(Primitive::dewrap)
|
||||
pub fn max_attempts(&self, e: &mut java::Env) -> Option<i32> {
|
||||
static MAX_ATTEMPTS: java::Method<Non, fn() -> java::util::Optional<i32>> =
|
||||
java::Method::new("maxAttempts");
|
||||
MAX_ATTEMPTS.invoke(e, self).to_option(e)
|
||||
}
|
||||
}
|
||||
|
163
glue/src/uint.rs
163
glue/src/uint.rs
@ -1,139 +1,86 @@
|
||||
use core::primitive as rust;
|
||||
|
||||
use jni::objects::{GlobalRef, JByteArray, JObject};
|
||||
use jni::JNIEnv;
|
||||
use toad_jni::cls::java;
|
||||
use toad_jni::convert::Object;
|
||||
use toad_jni::Sig;
|
||||
use toad_jni::java;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct u64(GlobalRef);
|
||||
pub struct u64(java::lang::Object);
|
||||
|
||||
java::object_newtype!(u64);
|
||||
impl java::Class for u64 {
|
||||
const PATH: &'static str = package!(dev.toad.ffi.u64);
|
||||
}
|
||||
|
||||
impl u64 {
|
||||
pub const PATH: &'static str = package!(dev.toad.ffi.u64);
|
||||
pub const CTOR: Sig = Sig::new().arg(Sig::class(java::math::BigInteger::PATH))
|
||||
.returning(Sig::VOID);
|
||||
pub const BIGINT_VALUE: Sig = Sig::new().returning(Sig::class(java::math::BigInteger::PATH));
|
||||
|
||||
pub fn to_rust<'a>(&self, e: &mut JNIEnv<'a>) -> rust::u64 {
|
||||
let bi = e.call_method(self.0.as_obj(), "bigintValue", Self::BIGINT_VALUE, &[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap();
|
||||
let bi = e.new_global_ref(bi).unwrap();
|
||||
let bi = java::math::BigInteger::from_java(bi);
|
||||
bi.to_i128(e) as rust::u64
|
||||
pub fn to_rust(&self, e: &mut java::Env) -> rust::u64 {
|
||||
static BIGINT_VALUE: java::Method<u64, fn() -> java::math::BigInteger> =
|
||||
java::Method::new("bigintValue");
|
||||
let bigint = BIGINT_VALUE.invoke(e, self);
|
||||
bigint.to_i128(e) as rust::u64
|
||||
}
|
||||
|
||||
pub fn from_rust<'a>(e: &mut JNIEnv<'a>, u: rust::u64) -> Self {
|
||||
pub fn from_rust(e: &mut java::Env, u: rust::u64) -> Self {
|
||||
static CTOR: java::Constructor<u64, fn(java::math::BigInteger)> = java::Constructor::new();
|
||||
let bi = java::math::BigInteger::from_be_bytes(e, &i128::from(u).to_be_bytes());
|
||||
let bi = e.new_object(Self::PATH, Self::CTOR, &[bi.to_java().as_obj().into()])
|
||||
.unwrap();
|
||||
Self(e.new_global_ref(bi).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Object for u64 {
|
||||
fn from_java(jobj: GlobalRef) -> Self {
|
||||
Self(jobj)
|
||||
}
|
||||
|
||||
fn to_java(self) -> GlobalRef {
|
||||
self.0
|
||||
CTOR.invoke(e, bi)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct u32(GlobalRef);
|
||||
pub struct u32(java::lang::Object);
|
||||
|
||||
java::object_newtype!(u32);
|
||||
impl java::Class for u32 {
|
||||
const PATH: &'static str = package!(dev.toad.ffi.u32);
|
||||
}
|
||||
|
||||
impl u32 {
|
||||
pub const PATH: &'static str = package!(dev.toad.ffi.u32);
|
||||
pub const CTOR: Sig = Sig::new().arg(Sig::LONG).returning(Sig::VOID);
|
||||
pub const LONG_VALUE: Sig = Sig::new().returning(Sig::LONG);
|
||||
|
||||
pub fn to_rust<'a>(&self, e: &mut JNIEnv<'a>) -> rust::u32 {
|
||||
let long = e.call_method(self.0.as_obj(), "longValue", Self::LONG_VALUE, &[])
|
||||
.unwrap()
|
||||
.j()
|
||||
.unwrap();
|
||||
long as rust::u32
|
||||
pub fn to_rust(&self, e: &mut java::Env) -> rust::u32 {
|
||||
static LONG_VALUE: java::Method<u32, fn() -> i64> = java::Method::new("longValue");
|
||||
LONG_VALUE.invoke(e, self) as rust::u32
|
||||
}
|
||||
|
||||
pub fn from_rust<'a>(e: &mut JNIEnv<'a>, u: rust::u32) -> Self {
|
||||
let bi = e.new_object(Self::PATH, Self::CTOR, &[rust::i64::from(u).into()])
|
||||
.unwrap();
|
||||
Self(e.new_global_ref(bi).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Object for u32 {
|
||||
fn from_java(jobj: GlobalRef) -> Self {
|
||||
Self(jobj)
|
||||
}
|
||||
|
||||
fn to_java(self) -> GlobalRef {
|
||||
self.0
|
||||
pub fn from_rust(e: &mut java::Env, u: rust::u32) -> Self {
|
||||
static CTOR: java::Constructor<u32, fn(i64)> = java::Constructor::new();
|
||||
CTOR.invoke(e, u.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct u16(GlobalRef);
|
||||
pub struct u16(java::lang::Object);
|
||||
|
||||
java::object_newtype!(u16);
|
||||
impl java::Class for u16 {
|
||||
const PATH: &'static str = package!(dev.toad.ffi.u16);
|
||||
}
|
||||
|
||||
impl u16 {
|
||||
pub const PATH: &'static str = package!(dev.toad.ffi.u16);
|
||||
pub const CTOR: Sig = Sig::new().arg(Sig::INT).returning(Sig::VOID);
|
||||
pub const INT_VALUE: Sig = Sig::new().returning(Sig::INT);
|
||||
|
||||
pub fn to_rust<'a>(&self, e: &mut JNIEnv<'a>) -> rust::u16 {
|
||||
let int = e.call_method(self.0.as_obj(), "intValue", Self::INT_VALUE, &[])
|
||||
.unwrap()
|
||||
.i()
|
||||
.unwrap();
|
||||
int as rust::u16
|
||||
pub fn to_rust(&self, e: &mut java::Env) -> rust::u16 {
|
||||
static INT_VALUE: java::Method<u16, fn() -> i32> = java::Method::new("intValue");
|
||||
INT_VALUE.invoke(e, self) as rust::u16
|
||||
}
|
||||
|
||||
pub fn from_rust<'a>(e: &mut JNIEnv<'a>, u: rust::u16) -> Self {
|
||||
let bi = e.new_object(Self::PATH, Self::CTOR, &[rust::i32::from(u).into()])
|
||||
.unwrap();
|
||||
Self(e.new_global_ref(bi).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Object for u16 {
|
||||
fn from_java(jobj: GlobalRef) -> Self {
|
||||
Self(jobj)
|
||||
}
|
||||
|
||||
fn to_java(self) -> GlobalRef {
|
||||
self.0
|
||||
pub fn from_rust(e: &mut java::Env, u: rust::u16) -> Self {
|
||||
static CTOR: java::Constructor<u16, fn(i32)> = java::Constructor::new();
|
||||
CTOR.invoke(e, u.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct u8(GlobalRef);
|
||||
pub struct u8(java::lang::Object);
|
||||
|
||||
java::object_newtype!(u8);
|
||||
impl java::Class for u8 {
|
||||
const PATH: &'static str = package!(dev.toad.ffi.u8);
|
||||
}
|
||||
|
||||
impl u8 {
|
||||
pub const PATH: &'static str = package!(dev.toad.ffi.u8);
|
||||
pub const CTOR: Sig = Sig::new().arg(Sig::SHORT).returning(Sig::VOID);
|
||||
pub const SHORT_VALUE: Sig = Sig::new().returning(Sig::SHORT);
|
||||
|
||||
pub fn to_rust<'a>(&self, e: &mut JNIEnv<'a>) -> rust::u8 {
|
||||
let int = e.call_method(self.0.as_obj(), "shortValue", Self::SHORT_VALUE, &[])
|
||||
.unwrap()
|
||||
.s()
|
||||
.unwrap();
|
||||
int as rust::u8
|
||||
pub fn to_rust(&self, e: &mut java::Env) -> rust::u8 {
|
||||
static SHORT_VALUE: java::Method<u8, fn() -> i16> = java::Method::new("shortValue");
|
||||
SHORT_VALUE.invoke(e, self) as rust::u8
|
||||
}
|
||||
|
||||
pub fn from_rust<'a>(e: &mut JNIEnv<'a>, u: rust::u8) -> Self {
|
||||
let bi = e.new_object(Self::PATH, Self::CTOR, &[rust::i16::from(u).into()])
|
||||
.unwrap();
|
||||
Self(e.new_global_ref(bi).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Object for u8 {
|
||||
fn from_java(jobj: GlobalRef) -> Self {
|
||||
Self(jobj)
|
||||
}
|
||||
|
||||
fn to_java(self) -> GlobalRef {
|
||||
self.0
|
||||
pub fn from_rust(e: &mut java::Env, u: rust::u8) -> Self {
|
||||
static CTOR: java::Constructor<u8, fn(i16)> = java::Constructor::new();
|
||||
CTOR.invoke(e, u.into())
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,16 @@
|
||||
package dev.toad;
|
||||
|
||||
import dev.toad.msg.MessageRef;
|
||||
import java.util.Optional;
|
||||
|
||||
public class Runtime {
|
||||
|
||||
public static native void init(RuntimeOptions o);
|
||||
private final long addr;
|
||||
|
||||
private Runtime() {}
|
||||
private static native long init(RuntimeOptions o);
|
||||
private native Optional<MessageRef> pollReq(RuntimeOptions o);
|
||||
|
||||
public Runtime(RuntimeOptions o) {
|
||||
this.addr = Runtime.init(o);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user