1
0
Fork 0
mirror of https://codeberg.org/demostf/parser.git synced 2026-06-03 18:24:05 +02:00

feat: Expose PInvoke-able analyzers

This commit is contained in:
LukeParkerDev 2024-04-17 15:06:33 +10:00
commit dd06215a79
2 changed files with 58 additions and 0 deletions

View file

@ -13,6 +13,7 @@ rust-version = "1.70.0"
[lib]
name = "tf_demo_parser"
path = "src/lib.rs"
crate-type = ["lib", "cdylib"]
[[bin]]
name = "parse_demo"

View file

@ -3,7 +3,10 @@
#![cfg_attr(not(test), deny(clippy::indexing_slicing))]
#![cfg_attr(not(test), deny(clippy::panic))]
use std::ffi::{c_char, CStr, CString};
use std::fs;
pub use bitbuffer::Result as ReadResult;
use serde::{Deserialize, Serialize};
pub use crate::demo::{
message::MessageType,
@ -13,6 +16,7 @@ pub use crate::demo::{
},
Demo, Stream,
};
use crate::demo::header::Header;
#[cfg(feature = "codegen")]
pub mod codegen;
@ -85,3 +89,56 @@ fn test_roundtrip_encode<
read.pos()
);
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JsonDemo {
header: Header,
#[serde(flatten)]
state: MatchState,
}
#[no_mangle]
pub extern "C" fn analyze_demo(path: *const c_char) -> *mut c_char {
let c_str = unsafe { CStr::from_ptr(path) };
let str_slice = match c_str.to_str() {
Ok(s) => s,
Err(_) => return std::ptr::null_mut(),
};
let file = match fs::read(str_slice) {
Ok(f) => f,
Err(_) => return std::ptr::null_mut(),
};
let demo = Demo::new(&file);
let parser = DemoParser::new(demo.get_stream());
let (header, state) = match parser.parse() {
Ok(results) => results,
Err(_) => return std::ptr::null_mut(),
};
let demo_json = JsonDemo { header, state };
let result = match serde_json::to_string(&demo_json) {
Ok(json) => json,
Err(_) => return std::ptr::null_mut(),
};
// Convert the Rust string to a C string to return
let c_string = match CString::new(result) {
Ok(c_str) => c_str,
Err(_) => return std::ptr::null_mut(),
};
c_string.into_raw()
}
#[no_mangle]
pub extern "C" fn free_string(s: *mut c_char) {
unsafe {
// Reclaim the CString to properly deallocate memory
if !s.is_null() {
let _ = CString::from_raw(s);
}
}
}