• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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