1 use std::{borrow::Cow, os::raw::c_char}; 2 3 use log::warn; 4 5 use crate::{errors::*, objects::JString, strings::JNIStr, JNIEnv}; 6 7 /// Reference to a string in the JVM. Holds a pointer to the array 8 /// returned by GetStringUTFChars. Calls ReleaseStringUTFChars on Drop. 9 /// Can be converted to a `&JNIStr` with the same cost as the `&CStr.from_ptr` 10 /// conversion. 11 pub struct JavaStr<'a: 'b, 'b> { 12 internal: *const c_char, 13 obj: JString<'a>, 14 env: &'b JNIEnv<'a>, 15 } 16 17 impl<'a: 'b, 'b> JavaStr<'a, 'b> { 18 /// Build a `JavaStr` from an object and a reference to the environment. You 19 /// probably want to use `JNIEnv::get_string` instead. from_env(env: &'b JNIEnv<'a>, obj: JString<'a>) -> Result<Self>20 pub fn from_env(env: &'b JNIEnv<'a>, obj: JString<'a>) -> Result<Self> { 21 let ptr = env.get_string_utf_chars(obj)?; 22 let java_str = JavaStr { 23 internal: ptr, 24 env, 25 obj, 26 }; 27 Ok(java_str) 28 } 29 30 /// Extract the raw C string pointer from the JavaStr. This will be 31 /// encoded using the JVM internal `CESU-8`-style. get_raw(&self) -> *const c_char32 pub fn get_raw(&self) -> *const c_char { 33 self.internal 34 } 35 } 36 37 impl<'a: 'b, 'b> ::std::ops::Deref for JavaStr<'a, 'b> { 38 type Target = JNIStr; deref(&self) -> &Self::Target39 fn deref(&self) -> &Self::Target { 40 self.into() 41 } 42 } 43 44 impl<'a: 'b, 'b: 'c, 'c> From<&'c JavaStr<'a, 'b>> for &'c JNIStr { from(other: &'c JavaStr) -> &'c JNIStr45 fn from(other: &'c JavaStr) -> &'c JNIStr { 46 unsafe { JNIStr::from_ptr(other.internal) } 47 } 48 } 49 50 impl<'a: 'b, 'b: 'c, 'c> From<&'c JavaStr<'a, 'b>> for Cow<'c, str> { from(other: &'c JavaStr) -> Cow<'c, str>51 fn from(other: &'c JavaStr) -> Cow<'c, str> { 52 let jni_str: &JNIStr = other; 53 jni_str.into() 54 } 55 } 56 57 impl<'a: 'b, 'b> From<JavaStr<'a, 'b>> for String { from(other: JavaStr) -> String58 fn from(other: JavaStr) -> String { 59 let cow: Cow<str> = (&other).into(); 60 cow.into_owned() 61 } 62 } 63 64 impl<'a: 'b, 'b> Drop for JavaStr<'a, 'b> { drop(&mut self)65 fn drop(&mut self) { 66 match unsafe { self.env.release_string_utf_chars(self.obj, self.internal) } { 67 Ok(()) => {} 68 Err(e) => warn!("error dropping java str: {}", e), 69 } 70 } 71 } 72