aboutsummaryrefslogtreecommitdiff
path: root/src/wrapper/strings/java_str.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/wrapper/strings/java_str.rs')
-rw-r--r--src/wrapper/strings/java_str.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/wrapper/strings/java_str.rs b/src/wrapper/strings/java_str.rs
new file mode 100644
index 0000000..2829ce6
--- /dev/null
+++ b/src/wrapper/strings/java_str.rs
@@ -0,0 +1,71 @@
+use std::{borrow::Cow, os::raw::c_char};
+
+use log::warn;
+
+use crate::{errors::*, objects::JString, strings::JNIStr, JNIEnv};
+
+/// Reference to a string in the JVM. Holds a pointer to the array
+/// returned by GetStringUTFChars. Calls ReleaseStringUTFChars on Drop.
+/// Can be converted to a `&JNIStr` with the same cost as the `&CStr.from_ptr`
+/// conversion.
+pub struct JavaStr<'a: 'b, 'b> {
+ internal: *const c_char,
+ obj: JString<'a>,
+ env: &'b JNIEnv<'a>,
+}
+
+impl<'a: 'b, 'b> JavaStr<'a, 'b> {
+ /// Build a `JavaStr` from an object and a reference to the environment. You
+ /// probably want to use `JNIEnv::get_string` instead.
+ pub fn from_env(env: &'b JNIEnv<'a>, obj: JString<'a>) -> Result<Self> {
+ let ptr = env.get_string_utf_chars(obj)?;
+ let java_str = JavaStr {
+ internal: ptr,
+ env,
+ obj,
+ };
+ Ok(java_str)
+ }
+
+ /// Extract the raw C string pointer from the JavaStr. This will be
+ /// encoded using the JVM internal `CESU-8`-style.
+ pub fn get_raw(&self) -> *const c_char {
+ self.internal
+ }
+}
+
+impl<'a: 'b, 'b> ::std::ops::Deref for JavaStr<'a, 'b> {
+ type Target = JNIStr;
+ fn deref(&self) -> &Self::Target {
+ self.into()
+ }
+}
+
+impl<'a: 'b, 'b: 'c, 'c> From<&'c JavaStr<'a, 'b>> for &'c JNIStr {
+ fn from(other: &'c JavaStr) -> &'c JNIStr {
+ unsafe { JNIStr::from_ptr(other.internal) }
+ }
+}
+
+impl<'a: 'b, 'b: 'c, 'c> From<&'c JavaStr<'a, 'b>> for Cow<'c, str> {
+ fn from(other: &'c JavaStr) -> Cow<'c, str> {
+ let jni_str: &JNIStr = &*other;
+ jni_str.into()
+ }
+}
+
+impl<'a: 'b, 'b> From<JavaStr<'a, 'b>> for String {
+ fn from(other: JavaStr) -> String {
+ let cow: Cow<str> = (&other).into();
+ cow.into_owned()
+ }
+}
+
+impl<'a: 'b, 'b> Drop for JavaStr<'a, 'b> {
+ fn drop(&mut self) {
+ match self.env.release_string_utf_chars(self.obj, self.internal) {
+ Ok(()) => {}
+ Err(e) => warn!("error dropping java str: {}", e),
+ }
+ }
+}