1use crate::event;
2
3pub fn host_service_result_buffer_ptr() -> *mut u8 {
4 event::__fui_text_buffer() as *mut u8
5}
6
7pub fn host_service_result_buffer_size() -> u32 {
8 event::__fui_text_buffer_size()
9}
10
11fn assert_result_byte_length(result_len: u32, import_name: &str) {
12 let capacity = host_service_result_buffer_size();
13 if result_len > capacity {
14 panic!(
15 "Host service {} returned {} bytes but the shared result buffer only holds {}.",
16 import_name, result_len, capacity
17 );
18 }
19}
20
21pub fn decode_host_service_string_result(
22 result_ptr: *mut u8,
23 result_len: u32,
24 import_name: &str,
25) -> String {
26 assert_result_byte_length(result_len, import_name);
27 if result_len == 0 {
28 return String::new();
29 }
30 let bytes = unsafe { std::slice::from_raw_parts(result_ptr as *const u8, result_len as usize) };
31 String::from_utf8_lossy(bytes).into_owned()
32}
33
34pub fn decode_host_service_bytes_result(
35 result_ptr: *mut u8,
36 result_len: u32,
37 import_name: &str,
38) -> Vec<u8> {
39 assert_result_byte_length(result_len, import_name);
40 if result_len == 0 {
41 return Vec::new();
42 }
43 unsafe { std::slice::from_raw_parts(result_ptr as *const u8, result_len as usize) }.to_vec()
44}
45
46pub fn decode_host_service_i32_array_result(
47 result_ptr: *mut u8,
48 result_len: u32,
49 import_name: &str,
50) -> Vec<i32> {
51 assert_result_byte_length(result_len, import_name);
52 assert_eq!(
53 result_len & 3,
54 0,
55 "Host service {} returned misaligned i32 array byte length.",
56 import_name
57 );
58 if result_len == 0 {
59 return Vec::new();
60 }
61 unsafe {
62 std::slice::from_raw_parts(result_ptr as *const i32, (result_len >> 2) as usize).to_vec()
63 }
64}
65
66pub fn decode_host_service_u32_array_result(
67 result_ptr: *mut u8,
68 result_len: u32,
69 import_name: &str,
70) -> Vec<u32> {
71 assert_result_byte_length(result_len, import_name);
72 assert_eq!(
73 result_len & 3,
74 0,
75 "Host service {} returned misaligned u32 array byte length.",
76 import_name
77 );
78 if result_len == 0 {
79 return Vec::new();
80 }
81 unsafe {
82 std::slice::from_raw_parts(result_ptr as *const u32, (result_len >> 2) as usize).to_vec()
83 }
84}
85
86pub fn decode_host_service_i64_array_result(
87 result_ptr: *mut u8,
88 result_len: u32,
89 import_name: &str,
90) -> Vec<i64> {
91 assert_result_byte_length(result_len, import_name);
92 assert_eq!(
93 result_len & 7,
94 0,
95 "Host service {} returned misaligned i64 array byte length.",
96 import_name
97 );
98 if result_len == 0 {
99 return Vec::new();
100 }
101 unsafe {
102 std::slice::from_raw_parts(result_ptr as *const i64, (result_len >> 3) as usize).to_vec()
103 }
104}
105
106pub fn decode_host_service_u64_array_result(
107 result_ptr: *mut u8,
108 result_len: u32,
109 import_name: &str,
110) -> Vec<u64> {
111 assert_result_byte_length(result_len, import_name);
112 assert_eq!(
113 result_len & 7,
114 0,
115 "Host service {} returned misaligned u64 array byte length.",
116 import_name
117 );
118 if result_len == 0 {
119 return Vec::new();
120 }
121 unsafe {
122 std::slice::from_raw_parts(result_ptr as *const u64, (result_len >> 3) as usize).to_vec()
123 }
124}
125
126pub fn decode_host_service_f64_array_result(
127 result_ptr: *mut u8,
128 result_len: u32,
129 import_name: &str,
130) -> Vec<f64> {
131 assert_result_byte_length(result_len, import_name);
132 assert_eq!(
133 result_len & 7,
134 0,
135 "Host service {} returned misaligned f64 array byte length.",
136 import_name
137 );
138 if result_len == 0 {
139 return Vec::new();
140 }
141 unsafe {
142 std::slice::from_raw_parts(result_ptr as *const f64, (result_len >> 3) as usize).to_vec()
143 }
144}
145
146#[cfg(test)]
147mod tests {
148 use super::*;
149
150 #[test]
151 fn decodes_string_result_from_shared_text_buffer() {
152 let ptr = host_service_result_buffer_ptr();
153 let bytes = b"demo-host";
154 unsafe {
155 std::ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, bytes.len());
156 }
157 assert_eq!(
158 decode_host_service_string_result(ptr, bytes.len() as u32, "demo_service"),
159 "demo-host"
160 );
161 }
162}