use init_arguments::InitArguments;
use java_string::*;
use jni_sys;
use std::marker::PhantomData;
use std::os::raw::c_char;
use std::ptr;
use version::{self, JniVersion};
#[derive(Debug, PartialEq, Eq)]
pub struct AttachArguments<'a> {
version: JniVersion,
thread_name: Option<&'a str>,
}
impl<'a> AttachArguments<'a> {
pub fn new(init_arguments: &InitArguments) -> Self {
AttachArguments {
thread_name: None,
version: init_arguments.version(),
}
}
pub fn named(init_arguments: &InitArguments, thread_name: &'a str) -> Self {
AttachArguments {
thread_name: Some(thread_name),
version: init_arguments.version(),
}
}
pub fn version(&self) -> JniVersion {
self.version
}
}
#[cfg(test)]
mod tests {
use super::*;
use init_arguments;
#[test]
fn new() {
let init_arguments = init_arguments::test(JniVersion::V4);
assert_eq!(
AttachArguments::new(&init_arguments),
AttachArguments {
thread_name: None,
version: JniVersion::V4
}
);
}
#[test]
fn named() {
let init_arguments = init_arguments::test(JniVersion::V4);
assert_eq!(
AttachArguments::named(&init_arguments, "test-name"),
AttachArguments {
thread_name: Some("test-name"),
version: JniVersion::V4,
}
);
}
#[test]
fn version() {
let arguments = AttachArguments {
version: JniVersion::V4,
thread_name: None,
};
assert_eq!(arguments.version(), JniVersion::V4);
}
}
pub struct RawAttachArguments<'a> {
pub raw_arguments: jni_sys::JavaVMAttachArgs,
#[allow(dead_code)]
buffer_len: usize,
_buffer: PhantomData<&'a Vec<u8>>,
}
pub fn to_raw<'a>(arguments: &AttachArguments, buffer: &'a mut Vec<u8>) -> RawAttachArguments<'a> {
let version = version::to_raw(arguments.version);
let group = ptr::null_mut();
let raw_arguments = jni_sys::JavaVMAttachArgs {
name: match arguments.thread_name {
None => ptr::null_mut(),
Some(ref thread_name) => {
*buffer = to_java_string(thread_name);
buffer.as_ptr() as *mut c_char
}
},
version,
group,
};
RawAttachArguments {
raw_arguments,
buffer_len: buffer.len(),
_buffer: PhantomData::<&'a Vec<u8>>,
}
}
#[cfg(test)]
mod to_raw_tests {
use super::*;
use init_arguments;
use std::slice;
#[test]
fn to_raw() {
let init_arguments = init_arguments::test(JniVersion::V8);
let arguments = AttachArguments::new(&init_arguments);
let mut buffer: Vec<u8> = vec![];
let raw_arguments = super::to_raw(&arguments, &mut buffer);
assert_eq!(raw_arguments.raw_arguments.group, ptr::null_mut());
assert_eq!(raw_arguments.raw_arguments.name, ptr::null_mut());
assert_eq!(
raw_arguments.raw_arguments.version,
version::to_raw(JniVersion::V8)
);
}
#[test]
fn to_raw_named() {
let init_arguments = init_arguments::test(JniVersion::V8);
let test_name = "test-name";
let arguments = AttachArguments::named(&init_arguments, test_name);
let mut buffer: Vec<u8> = vec![];
let raw_arguments = super::to_raw(&arguments, &mut buffer);
assert_eq!(raw_arguments.raw_arguments.group, ptr::null_mut());
assert_eq!(
raw_arguments.raw_arguments.version,
version::to_raw(JniVersion::V8)
);
assert_eq!(
from_java_string(unsafe {
slice::from_raw_parts(
raw_arguments.raw_arguments.name as *const u8,
raw_arguments.buffer_len,
)
}).unwrap(),
test_name
);
}
}