brotli/ffi/
broccoli.rs

1pub use brotli_decompressor::ffi::interface::c_void;
2use brotli_decompressor::ffi::{slice_from_raw_parts_or_nil, slice_from_raw_parts_or_nil_mut};
3use concat::BroCatli;
4pub use concat::BroCatliResult;
5use core;
6pub type BroccoliResult = BroCatliResult;
7// a tool to concatenate brotli files together
8
9#[repr(C)]
10pub struct BroccoliState {
11    more_data: *mut c_void,
12    current_data: [u8; 120],
13}
14
15impl Clone for BroccoliState {
16    fn clone(&self) -> BroccoliState {
17        let mut cd = [0u8; 120];
18        cd.clone_from_slice(&self.current_data[..]);
19        BroccoliState {
20            more_data: self.more_data,
21            current_data: cd,
22        }
23    }
24}
25
26impl Copy for BroccoliState {}
27
28impl Default for BroccoliState {
29    fn default() -> BroccoliState {
30        BroCatli::new().into()
31    }
32}
33impl From<BroCatli> for BroccoliState {
34    fn from(data: BroCatli) -> BroccoliState {
35        let mut buffer = [0u8; 120];
36        data.serialize_to_buffer(&mut buffer[..]).unwrap();
37        BroccoliState {
38            more_data: core::ptr::null_mut(),
39            current_data: buffer,
40        }
41    }
42}
43impl From<BroccoliState> for BroCatli {
44    fn from(val: BroccoliState) -> Self {
45        BroCatli::deserialize_from_buffer(&val.current_data[..]).unwrap()
46    }
47}
48
49#[no_mangle]
50pub extern "C" fn BroccoliCreateInstance() -> BroccoliState {
51    BroCatli::new().into()
52}
53#[no_mangle]
54pub extern "C" fn BroccoliCreateInstanceWithWindowSize(window_size: u8) -> BroccoliState {
55    BroCatli::new_with_window_size(window_size).into()
56}
57#[no_mangle]
58pub extern "C" fn BroccoliDestroyInstance(_state: BroccoliState) {}
59
60#[no_mangle]
61pub unsafe extern "C" fn BroccoliNewBrotliFile(state: *mut BroccoliState) {
62    let mut bro_catli: BroCatli = (*state).into();
63    bro_catli.new_brotli_file();
64    *state = BroccoliState::from(bro_catli);
65}
66
67#[no_mangle]
68pub unsafe extern "C" fn BroccoliConcatStream(
69    state: *mut BroccoliState,
70    available_in: *mut usize,
71    input_buf_ptr: *mut *const u8,
72    available_out: *mut usize,
73    output_buf_ptr: *mut *mut u8,
74) -> BroccoliResult {
75    let input_buf = slice_from_raw_parts_or_nil(*input_buf_ptr, *available_in);
76    let output_buf = slice_from_raw_parts_or_nil_mut(*output_buf_ptr, *available_out);
77    let mut input_offset = 0usize;
78    let mut output_offset = 0usize;
79    let mut bro_catli: BroCatli = (*state).into();
80    let ret = bro_catli.stream(input_buf, &mut input_offset, output_buf, &mut output_offset);
81    *input_buf_ptr = (*input_buf_ptr).add(input_offset);
82    *output_buf_ptr = (*output_buf_ptr).add(output_offset);
83    *available_in -= input_offset;
84    *available_out -= output_offset;
85    *state = BroccoliState::from(bro_catli);
86    ret
87}
88
89#[no_mangle]
90pub unsafe extern "C" fn BroccoliConcatStreaming(
91    state: *mut BroccoliState,
92    available_in: *mut usize,
93    mut input_buf: *const u8,
94    available_out: *mut usize,
95    mut output_buf: *mut u8,
96) -> BroccoliResult {
97    BroccoliConcatStream(
98        state,
99        available_in,
100        &mut input_buf,
101        available_out,
102        &mut output_buf,
103    )
104}
105
106#[no_mangle]
107pub unsafe extern "C" fn BroccoliConcatFinish(
108    state: *mut BroccoliState,
109    available_out: *mut usize,
110    output_buf_ptr: *mut *mut u8,
111) -> BroCatliResult {
112    let output_buf = slice_from_raw_parts_or_nil_mut(*output_buf_ptr, *available_out);
113    let mut output_offset = 0usize;
114    let mut bro_catli: BroCatli = (*state).into();
115    let ret = bro_catli.finish(output_buf, &mut output_offset);
116    *output_buf_ptr = (*output_buf_ptr).add(output_offset);
117    *available_out -= output_offset;
118    *state = BroccoliState::from(bro_catli);
119    ret
120}
121
122// exactly the same as BrotliConcatFinish but without the indirect
123#[no_mangle]
124pub unsafe extern "C" fn BroccoliConcatFinished(
125    state: *mut BroccoliState,
126    available_out: *mut usize,
127    mut output_buf: *mut u8,
128) -> BroCatliResult {
129    BroccoliConcatFinish(state, available_out, &mut output_buf)
130}