java_spaghetti/
string_chars.rs1use std::{char, iter, slice};
2
3use jni_sys::*;
4
5use crate::Env;
6
7pub struct StringChars<'env> {
10 env: Env<'env>,
11 string: jstring,
12 chars: *const jchar,
13 length: jsize, }
15
16impl<'env> StringChars<'env> {
17 pub unsafe fn from_env_jstring(env: Env<'env>, string: jstring) -> Self {
19 debug_assert!(!string.is_null());
20
21 let chars = env.get_string_chars(string);
22 let length = env.get_string_length(string);
23
24 Self {
25 env,
26 string,
27 chars,
28 length,
29 }
30 }
31
32 pub fn chars(&self) -> &[jchar] {
34 unsafe { slice::from_raw_parts(self.chars, self.length as usize) }
35 }
36
37 pub fn decode(&self) -> char::DecodeUtf16<iter::Cloned<slice::Iter<u16>>> {
39 char::decode_utf16(self.chars().iter().cloned())
40 }
41
42 pub fn to_string(&self) -> Result<String, char::DecodeUtf16Error> {
44 self.decode().collect()
45 }
46
47 pub fn to_string_lossy(&self) -> String {
49 self.decode()
50 .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
51 .collect()
52 }
53}
54
55impl<'env> Drop for StringChars<'env> {
56 fn drop(&mut self) {
57 unsafe { self.env.release_string_chars(self.string, self.chars) };
58 }
59}