1use luadec_sys::{
2 DecompileResult, luadec_decompile_buffer, luadec_free_result,
3 luadec_get_result, luadec_get_error
4};
5use std::ffi::CStr;
6use crate::error::{DecompileError, Result};
7
8pub fn decompile_bytecode_raw(bytecode: &[u8]) -> Result<String> {
10 if bytecode.is_empty() {
11 return Err(DecompileError::InvalidBytecode("Empty bytecode".to_string()));
12 }
13
14 let result_ptr = unsafe {
15 luadec_decompile_buffer(
16 bytecode.as_ptr() as *const i8,
17 bytecode.len(),
18 )
19 };
20
21 if result_ptr.is_null() {
22 return Err(DecompileError::InternalError("Failed to get result".to_string()));
23 }
24
25 let _guard = ResultGuard(result_ptr);
27
28 let error_ptr = unsafe { luadec_get_error(result_ptr) };
30 if !error_ptr.is_null() {
31 let error_cstr = unsafe { CStr::from_ptr(error_ptr) };
32 let error_msg = error_cstr.to_string_lossy().to_string();
33 return Err(DecompileError::DecompilationFailed(error_msg));
34 }
35
36 let result_cstr_ptr = unsafe { luadec_get_result(result_ptr) };
38 if result_cstr_ptr.is_null() {
39 return Err(DecompileError::InternalError("No result returned".to_string()));
40 }
41
42 let result_cstr = unsafe { CStr::from_ptr(result_cstr_ptr) };
43 let result_string = result_cstr.to_string_lossy().to_string();
44
45 Ok(result_string)
46}
47
48struct ResultGuard(*mut DecompileResult);
50
51impl Drop for ResultGuard {
52 fn drop(&mut self) {
53 unsafe {
54 luadec_free_result(self.0);
55 }
56 }
57}