1use bytes::buf::UninitSlice;
2use bytes::BufMut;
3use core::slice;
4
5extern crate savefile;
6extern crate savefile_derive;
7use crate::{
8 abi_entry_light, parse_return_value_impl, AbiConnection, AbiConnectionMethod, AbiErrorMsg, AbiExportable,
9 AbiProtocol, FlexBuffer, RawAbiCallResult, TraitObject,
10};
11use savefile::prelude::{
12 get_schema, AbiMethod, AbiMethodArgument, AbiMethodInfo, AbiTraitDefinition, Deserialize, Deserializer,
13 LittleEndian, ReadBytesExt, ReceiverType, SavefileError, Schema, Serialize, Serializer,
14};
15use std::collections::HashMap;
16use std::io::Cursor;
17use std::mem::MaybeUninit;
18unsafe extern "C" fn abi_entry_light_buf_mut(flag: AbiProtocol) {
19 unsafe {
20 abi_entry_light::<dyn BufMut>(flag);
21 }
22}
23
24unsafe impl AbiExportable for dyn BufMut {
25 const ABI_ENTRY: unsafe extern "C" fn(flag: AbiProtocol) = abi_entry_light_buf_mut;
26 fn get_definition(version: u32) -> AbiTraitDefinition {
27 AbiTraitDefinition {
28 name: "BufMut".to_string(),
29 methods: vec![
30 AbiMethod {
31 name: "remaining_mut".to_string(),
32 info: AbiMethodInfo {
33 return_value: { get_schema::<usize>(version) },
34 receiver: ReceiverType::Shared,
35 arguments: vec![],
36 async_trait_heuristic: false,
37 },
38 },
39 AbiMethod {
40 name: "advance_mut".to_string(),
41 info: AbiMethodInfo {
42 return_value: { get_schema::<()>(0) },
43 receiver: ReceiverType::Mut,
44 arguments: vec![AbiMethodArgument {
45 schema: { get_schema::<usize>(version) },
46 }],
47 async_trait_heuristic: false,
48 },
49 },
50 AbiMethod {
51 name: "chunk_mut".to_string(),
52 info: AbiMethodInfo {
53 return_value: Schema::UninitSlice,
54 receiver: ReceiverType::Mut,
55 arguments: vec![],
56 async_trait_heuristic: false,
57 },
58 },
59 ],
60 sync: false,
61 send: false,
62 }
63 }
64 fn get_latest_version() -> u32 {
65 0u32
66 }
67
68 #[allow(clippy::not_unsafe_ptr_arg_deref)]
70 fn call(
71 trait_object: TraitObject,
72 method_number: u16,
73 effective_version: u32,
74 _compatibility_mask: u64,
75 data: &[u8],
76 abi_result: *mut (),
77 __savefile_internal_receiver: unsafe extern "C" fn(outcome: *const RawAbiCallResult, result_receiver: *mut ()),
78 ) -> Result<(), SavefileError> {
79 let mut cursor = Cursor::new(data);
80 let mut deserializer = Deserializer {
81 file_version: cursor.read_u32::<LittleEndian>()?,
82 reader: &mut cursor,
83 ephemeral_state: HashMap::new(),
84 };
85 match method_number {
86 0u16 => {
87 let ret = unsafe { &*trait_object.as_const_ptr::<dyn BufMut>() }.remaining_mut();
88 let mut __savefile_internal_data = FlexBuffer::new();
89 let mut serializer = Serializer {
90 writer: &mut __savefile_internal_data,
91 file_version: 0u32,
92 };
93 serializer.write_u32(effective_version)?;
94 match ret.serialize(&mut serializer) {
95 Ok(()) => {
96 let outcome = RawAbiCallResult::Success {
97 data: __savefile_internal_data.as_ptr() as *const u8,
98 len: __savefile_internal_data.len(),
99 };
100 unsafe { __savefile_internal_receiver(&outcome as *const _, abi_result) }
101 }
102 Err(err) => {
103 let err_str = format!("{:?}", err);
104 let outcome = RawAbiCallResult::AbiError(AbiErrorMsg {
105 error_msg_utf8: err_str.as_ptr(),
106 len: err_str.len(),
107 });
108 unsafe { __savefile_internal_receiver(&outcome as *const _, abi_result) }
109 }
110 }
111 }
112 1u16 => {
113 let arg_cnt;
114 arg_cnt = <usize as Deserialize>::deserialize(&mut deserializer)?;
115 unsafe { (&mut *trait_object.as_mut_ptr::<dyn BufMut>()).advance_mut(arg_cnt) };
116 }
117 2u16 => {
118 let ret = unsafe { &mut *trait_object.as_mut_ptr::<dyn BufMut>() }.chunk_mut();
119 let mut __savefile_internal_data = FlexBuffer::new();
120 let mut serializer = Serializer {
121 writer: &mut __savefile_internal_data,
122 file_version: 0u32,
123 };
124 serializer.write_u32(effective_version)?;
125
126 match unsafe { serializer.write_raw_ptr_size(ret.as_mut_ptr(), ret.len()) } {
127 Ok(()) => {
128 let outcome = RawAbiCallResult::Success {
129 data: __savefile_internal_data.as_ptr() as *const u8,
130 len: __savefile_internal_data.len(),
131 };
132 unsafe { __savefile_internal_receiver(&outcome as *const _, abi_result) }
133 }
134 Err(err) => {
135 let err_str = format!("{:?}", err);
136 let outcome = RawAbiCallResult::AbiError(AbiErrorMsg {
137 error_msg_utf8: err_str.as_ptr(),
138 len: err_str.len(),
139 });
140 unsafe { __savefile_internal_receiver(&outcome as *const _, abi_result) }
141 }
142 }
143 }
144 _ => {
145 return Err(SavefileError::general("Unknown method number"));
146 }
147 }
148 Ok(())
149 }
150}
151unsafe impl BufMut for AbiConnection<dyn BufMut> {
152 #[inline]
153 fn remaining_mut(&self) -> usize {
154 let info: &AbiConnectionMethod = &self.template.methods[0u16 as usize];
155 let Some(callee_method_number) = info.callee_method_number else {
156 panic!("Method \'{0}\' does not exist in implementation.", info.method_name,);
157 };
158 let mut result_buffer = MaybeUninit::<Result<usize, SavefileError>>::uninit();
159 let compatibility_mask = info.compatibility_mask;
160 let mut __savefile_internal_datarawdata = [0u8; 4usize];
161 let mut __savefile_internal_data = Cursor::new(&mut __savefile_internal_datarawdata[..]);
162 let mut serializer = Serializer {
163 writer: &mut __savefile_internal_data,
164 file_version: self.template.effective_version,
165 };
166 serializer.write_u32(self.template.effective_version).unwrap();
167 unsafe {
168 unsafe extern "C" fn abi_result_receiver(outcome: *const RawAbiCallResult, result_receiver: *mut ()) {
169 let outcome = unsafe { &*outcome };
170 let result_receiver =
171 unsafe { &mut *(result_receiver as *mut std::mem::MaybeUninit<Result<usize, SavefileError>>) };
172 result_receiver.write(parse_return_value_impl(
173 outcome,
174 |deserializer| -> Result<usize, SavefileError> {
175 <usize as Deserialize>::deserialize(deserializer)
176 },
177 ));
178 }
179 (self.template.entry)(AbiProtocol::RegularCall {
180 trait_object: self.trait_object,
181 compatibility_mask,
182 method_number: callee_method_number,
183 effective_version: self.template.effective_version,
184 data: __savefile_internal_datarawdata[..].as_ptr(),
185 data_length: 4usize,
186 abi_result: &mut result_buffer as *mut _ as *mut (),
187 receiver: abi_result_receiver,
188 });
189 }
190 let resval = unsafe { result_buffer.assume_init() };
191 resval.expect("Unexpected panic in invocation target")
192 }
193 #[inline]
194 unsafe fn advance_mut(&mut self, arg_cnt: usize) {
195 let info: &AbiConnectionMethod = &self.template.methods[1u16 as usize];
196 let Some(callee_method_number) = info.callee_method_number else {
197 panic!("Method \'{0}\' does not exist in implementation.", info.method_name,);
198 };
199 let mut result_buffer = MaybeUninit::<Result<(), SavefileError>>::new(Ok(()));
200 let compatibility_mask = info.compatibility_mask;
201 let mut __savefile_internal_datarawdata = [0u8; 12usize];
202 let mut __savefile_internal_data = Cursor::new(&mut __savefile_internal_datarawdata[..]);
203 let mut serializer = Serializer {
204 writer: &mut __savefile_internal_data,
205 file_version: self.template.effective_version,
206 };
207 serializer.write_u32(self.template.effective_version).unwrap();
208 arg_cnt.serialize(&mut serializer).expect("Failed while serializing");
209 debug_assert_eq!(std::mem::size_of_val(&arg_cnt), 8);
210 unsafe {
211 unsafe extern "C" fn abi_result_receiver(outcome: *const RawAbiCallResult, result_receiver: *mut ()) {
212 let outcome = unsafe { &*outcome };
213 let result_receiver =
214 unsafe { &mut *(result_receiver as *mut std::mem::MaybeUninit<Result<(), SavefileError>>) };
215 result_receiver.write(parse_return_value_impl(outcome, |_| -> Result<(), SavefileError> {
216 Ok(())
217 }));
218 }
219 (self.template.entry)(AbiProtocol::RegularCall {
220 trait_object: self.trait_object,
221 compatibility_mask,
222 method_number: callee_method_number,
223 effective_version: self.template.effective_version,
224 data: __savefile_internal_datarawdata.as_ptr() as *const u8,
225 data_length: 12,
226 abi_result: &mut result_buffer as *mut _ as *mut (),
227 receiver: abi_result_receiver,
228 });
229 }
230 let resval = unsafe { result_buffer.assume_init() };
231 resval.expect("Unexpected panic in invocation target")
232 }
233 #[inline]
234 fn chunk_mut(&mut self) -> &mut UninitSlice {
235 let info: &AbiConnectionMethod = &self.template.methods[2u16 as usize];
236 let Some(callee_method_number) = info.callee_method_number else {
237 panic!("Method \'{0}\' does not exist in implementation.", info.method_name,);
238 };
239 let mut result_buffer = MaybeUninit::<Result<&mut UninitSlice, SavefileError>>::uninit();
240 let compatibility_mask = info.compatibility_mask;
241 let mut __savefile_internal_datarawdata = [0u8; 4usize];
242 let mut __savefile_internal_data = Cursor::new(&mut __savefile_internal_datarawdata[..]);
243 let mut serializer = Serializer {
244 writer: &mut __savefile_internal_data,
245 file_version: self.template.effective_version,
246 };
247 serializer.write_u32(self.template.effective_version).unwrap();
248 unsafe {
249 unsafe extern "C" fn abi_result_receiver(outcome: *const RawAbiCallResult, result_receiver: *mut ()) {
250 let outcome = unsafe { &*outcome };
251 let result_receiver = unsafe {
252 &mut *(result_receiver as *mut std::mem::MaybeUninit<Result<&mut UninitSlice, SavefileError>>)
253 };
254 result_receiver.write(parse_return_value_impl(
255 outcome,
256 |deserializer| -> Result<&mut UninitSlice, SavefileError> {
257 let iptr: *mut u8 = deserializer.read_raw_ptr_mut()?;
258 let len = deserializer.read_usize()?;
259 let bytes = slice::from_raw_parts_mut(iptr, len);
260 Ok(UninitSlice::new(bytes))
261 },
262 ));
263 }
264 (self.template.entry)(AbiProtocol::RegularCall {
265 trait_object: self.trait_object,
266 compatibility_mask,
267 method_number: callee_method_number,
268 effective_version: self.template.effective_version,
269 data: __savefile_internal_datarawdata[..].as_ptr(),
270 data_length: 4usize,
271 abi_result: &mut result_buffer as *mut _ as *mut (),
272 receiver: abi_result_receiver,
273 });
274 }
275 let resval = unsafe { result_buffer.assume_init() };
276 resval.expect("Unexpected panic in invocation target")
277 }
278}