1#![cfg(not(feature="safe"))]
2
3#[no_mangle]
4use core;
5use core::slice;
6use ::StaticCommand;
7use super::DivansDecompressorFactory;
8use super::interface::Decompressor;
9pub mod interface;
10pub mod alloc_util;
11use self::alloc_util::SubclassableAllocator;
12mod compressor;
13mod decompressor;
14use self::compressor::DivansCompressorState;
15use self::decompressor::DivansDecompressorState;
16use self::interface::{CAllocator, c_void, DivansOptionSelect, DivansReturnCode, DIVANS_FAILURE, DIVANS_SUCCESS, DIVANS_NEEDS_MORE_INPUT, DIVANS_NEEDS_MORE_OUTPUT};
17#[no_mangle]
18pub extern fn divans_new_compressor() -> *mut compressor::DivansCompressorState{
19 unsafe {
20 divans_new_compressor_with_custom_alloc(CAllocator{
21 alloc_func:None,
22 free_func:None,
23 opaque: core::ptr::null_mut(),
24 })
25 }
26}
27
28
29
30#[cfg(feature="no-stdlib")]
31fn divans_new_compressor_without_custom_alloc(_to_box: DivansCompressorState) -> *mut DivansCompressorState{
32 panic!("Must supply allocators if calling divans when compiled with features=no-stdlib");
33}
34#[cfg(not(feature="no-stdlib"))]
35fn divans_new_compressor_without_custom_alloc(to_box: DivansCompressorState) -> *mut DivansCompressorState{
36 alloc_util::Box::<DivansCompressorState>::into_raw(alloc_util::Box::<DivansCompressorState>::new(to_box))
37}
38#[no_mangle]
39pub unsafe extern fn divans_new_compressor_with_custom_alloc(allocators:CAllocator) -> *mut DivansCompressorState{
40 let to_box = DivansCompressorState{
41 custom_allocator:allocators.clone(),
42 compressor:compressor::CompressorState::default(),
43 };
44 if let Some(alloc_fn) = allocators.alloc_func {
45 let ptr = alloc_fn(allocators.opaque, core::mem::size_of::<DivansCompressorState>());
46 let divans_compressor_state_ptr = core::mem::transmute::<*mut c_void, *mut DivansCompressorState>(ptr);
47 core::ptr::write(divans_compressor_state_ptr, to_box);
48 divans_compressor_state_ptr
49 } else {
50 divans_new_compressor_without_custom_alloc(to_box)
51 }
52}
53
54
55
56
57#[no_mangle]
58pub unsafe extern fn divans_set_option(state_ptr: *mut DivansCompressorState,
59 selector: DivansOptionSelect,
60 value: u32) -> DivansReturnCode {
61 match state_ptr.as_mut() {
62 None => DIVANS_FAILURE,
63 Some(state_ref) => {
64 state_ref.compressor.set_option(selector, value)
65 }
66 }
67}
68
69#[no_mangle]
70pub unsafe extern fn divans_encode(state_ptr: *mut DivansCompressorState,
71 input_buf_ptr: *const u8, input_size: usize, input_offset_ptr: *mut usize,
72 output_buf_ptr: *mut u8, output_size: usize, output_offset_ptr: *mut usize) -> DivansReturnCode {
73 let input_buf = slice::from_raw_parts(input_buf_ptr, input_size);
74 let output_buf = slice::from_raw_parts_mut(output_buf_ptr, output_size);
75 match input_offset_ptr.as_mut() {
76 None => return DIVANS_FAILURE,
77 Some(input_offset) => {
78 match output_offset_ptr.as_mut() {
79 None => return DIVANS_FAILURE,
80 Some(output_offset) => {
81 match state_ptr.as_mut() {
82 None => return DIVANS_FAILURE,
83 Some(state_ref) => {
84 return state_ref.compressor.encode(input_buf, input_offset, output_buf, output_offset, &state_ref.custom_allocator);
85 }
86 }
87 }
88 }
89 }
90 }
91}
92
93#[no_mangle]
94pub unsafe extern fn divans_encode_flush(state_ptr: *mut DivansCompressorState,
95 output_buf_ptr: *mut u8, output_size: usize, output_offset_ptr: *mut usize) -> DivansReturnCode {
96 let output_buf = slice::from_raw_parts_mut(output_buf_ptr, output_size);
97 match output_offset_ptr.as_mut() {
98 None => return DIVANS_FAILURE,
99 Some(output_offset) => {
100 match state_ptr.as_mut() {
101 None => return DIVANS_FAILURE,
102 Some(state_ref) => {
103 return state_ref.compressor.flush(output_buf, output_offset, &state_ref.custom_allocator);
104 }
105 }
106 }
107 }
108}
109
110#[no_mangle]
111pub unsafe extern fn divans_compressor_malloc_u8(state_ptr: *mut DivansCompressorState, size: usize) -> *mut u8 {
112 if let Some(alloc_fn) = (*state_ptr).custom_allocator.alloc_func {
113 return core::mem::transmute::<*mut c_void, *mut u8>(alloc_fn((*state_ptr).custom_allocator.opaque, size));
114 } else {
115 return alloc_util::alloc_stdlib(size);
116 }
117}
118
119#[no_mangle]
120pub unsafe extern fn divans_compressor_free_u8(state_ptr: *mut DivansCompressorState, data: *mut u8, size: usize) {
121 if let Some(free_fn) = (*state_ptr).custom_allocator.free_func {
122 free_fn((*state_ptr).custom_allocator.opaque, core::mem::transmute::<*mut u8, *mut c_void>(data));
123 } else {
124 alloc_util::free_stdlib(data, size);
125 }
126}
127
128
129#[no_mangle]
130pub unsafe extern fn divans_compressor_malloc_usize(state_ptr: *mut DivansCompressorState, size: usize) -> *mut usize {
131 if let Some(alloc_fn) = (*state_ptr).custom_allocator.alloc_func {
132 return core::mem::transmute::<*mut c_void, *mut usize>(alloc_fn((*state_ptr).custom_allocator.opaque,
133 size * core::mem::size_of::<usize>()));
134 } else {
135 return alloc_util::alloc_stdlib(size);
136 }
137}
138#[no_mangle]
139pub unsafe extern fn divans_compressor_free_usize(state_ptr: *mut DivansCompressorState, data: *mut usize, size: usize) {
140 if let Some(free_fn) = (*state_ptr).custom_allocator.free_func {
141 free_fn((*state_ptr).custom_allocator.opaque, core::mem::transmute::<*mut usize, *mut c_void>(data));
142 } else {
143 alloc_util::free_stdlib(data, size);
144 }
145}
146
147
148#[cfg(not(feature="no-stdlib"))]
149unsafe fn free_compressor_no_custom_alloc(state_ptr: *mut DivansCompressorState) {
150 let _state = alloc_util::Box::from_raw(state_ptr);
151}
152
153#[cfg(feature="no-stdlib")]
154unsafe fn free_compressor_no_custom_alloc(_state_ptr: *mut DivansCompressorState) {
155 unreachable!();
156}
157
158#[no_mangle]
159pub unsafe extern fn divans_free_compressor(state_ptr: *mut DivansCompressorState) {
160 if let Some(_) = (*state_ptr).custom_allocator.alloc_func {
161 if let Some(free_fn) = (*state_ptr).custom_allocator.free_func {
162 let _to_free = core::ptr::read(state_ptr);
163 let ptr = core::mem::transmute::<*mut DivansCompressorState, *mut c_void>(state_ptr);
164 free_fn((*state_ptr).custom_allocator.opaque, ptr);
165 }
166 } else {
167 free_compressor_no_custom_alloc(state_ptr)
168 }
169}
170
171
172
173
174
175
176
177#[no_mangle]
178pub extern fn divans_new_decompressor() -> *mut DivansDecompressorState{
179 unsafe {
180 divans_new_decompressor_with_custom_alloc(CAllocator{
181 alloc_func:None,
182 free_func:None,
183 opaque: core::ptr::null_mut(),
184 }, 0, 1)
185 }
186}
187
188
189#[no_mangle]
190pub extern fn divans_new_serial_decompressor() -> *mut DivansDecompressorState{
191 unsafe {
192 divans_new_decompressor_with_custom_alloc(CAllocator{
193 alloc_func:None,
194 free_func:None,
195 opaque: core::ptr::null_mut(),
196 }, 0, 0)
197 }
198}
199
200
201#[cfg(feature="no-stdlib")]
202fn divans_new_decompressor_without_custom_alloc(_to_box: DivansDecompressorState) -> *mut DivansDecompressorState{
203 panic!("Must supply allocators if calling divans when compiled with features=no-stdlib");
204}
205
206#[cfg(not(feature="no-stdlib"))]
207fn divans_new_decompressor_without_custom_alloc(to_box: DivansDecompressorState) -> *mut DivansDecompressorState{
208 alloc_util::Box::<DivansDecompressorState>::into_raw(alloc_util::Box::<DivansDecompressorState>::new(to_box))
209}
210
211
212#[no_mangle]
213pub unsafe extern fn divans_new_decompressor_with_custom_alloc(allocators:CAllocator, skip_crc:u8, multithread: u8) -> *mut DivansDecompressorState{
214 let to_box = DivansDecompressorState{
215 custom_allocator:allocators.clone(),
216 decompressor:decompressor::DecompressorFactory::new(
217 SubclassableAllocator::<u8>::new(allocators.clone()),
218 SubclassableAllocator::<super::DefaultCDF16>::new(allocators.clone()),
219 SubclassableAllocator::<StaticCommand>::new(allocators.clone()),
220 skip_crc != 0,
221 multithread != 0,
222 ),
223 };
224 if let Some(alloc_fn) = allocators.alloc_func {
225 let ptr = alloc_fn(allocators.opaque, core::mem::size_of::<DivansDecompressorState>());
226 let divans_decompressor_state_ptr = core::mem::transmute::<*mut c_void, *mut DivansDecompressorState>(ptr);
227 core::ptr::write(divans_decompressor_state_ptr, to_box);
228 divans_decompressor_state_ptr
229 } else {
230 divans_new_decompressor_without_custom_alloc(to_box)
231 }
232}
233
234
235#[no_mangle]
236pub unsafe extern fn divans_decode(state_ptr: *mut DivansDecompressorState,
237 input_buf_ptr: *const u8, input_size: usize, input_offset_ptr: *mut usize,
238 output_buf_ptr: *mut u8, output_size: usize, output_offset_ptr: *mut usize) -> DivansReturnCode {
239 let input_buf = slice::from_raw_parts(input_buf_ptr, input_size);
240 let output_buf = slice::from_raw_parts_mut(output_buf_ptr, output_size);
241 match input_offset_ptr.as_mut() {
242 None => return DIVANS_FAILURE,
243 Some(input_offset) => {
244 match output_offset_ptr.as_mut() {
245 None => return DIVANS_FAILURE,
246 Some(output_offset) => {
247 match state_ptr.as_mut() {
248 None => return DIVANS_FAILURE,
249 Some(state_ref) => {
250 match state_ref.decompressor.decode(input_buf, input_offset, output_buf, output_offset) {
251 ::interface::DivansResult::Success => return DIVANS_SUCCESS,
252 ::interface::DivansResult::Failure(_) => return DIVANS_FAILURE,
253 ::interface::DivansResult::NeedsMoreInput => return DIVANS_NEEDS_MORE_INPUT,
254 ::interface::DivansResult::NeedsMoreOutput => return DIVANS_NEEDS_MORE_OUTPUT,
255 }
256 }
257 }
258 }
259 }
260 }
261 }
262}
263
264#[cfg(not(feature="no-stdlib"))]
265unsafe fn free_decompressor_no_custom_alloc(state_ptr: *mut DivansDecompressorState) {
266 let _state = alloc_util::Box::from_raw(state_ptr);
267}
268
269#[cfg(feature="no-stdlib")]
270unsafe fn free_decompressor_no_custom_alloc(_state_ptr: *mut DivansDecompressorState) {
271 unreachable!();
272}
273
274
275#[no_mangle]
276pub unsafe extern fn divans_decompressor_malloc_u8(state_ptr: *mut DivansDecompressorState, size: usize) -> *mut u8 {
277 if let Some(alloc_fn) = (*state_ptr).custom_allocator.alloc_func {
278 return core::mem::transmute::<*mut c_void, *mut u8>(alloc_fn((*state_ptr).custom_allocator.opaque, size));
279 } else {
280 return alloc_util::alloc_stdlib(size);
281 }
282}
283
284#[no_mangle]
285pub unsafe extern fn divans_decompressor_free_u8(state_ptr: *mut DivansDecompressorState, data: *mut u8, size: usize) {
286 if let Some(free_fn) = (*state_ptr).custom_allocator.free_func {
287 free_fn((*state_ptr).custom_allocator.opaque, core::mem::transmute::<*mut u8, *mut c_void>(data));
288 } else {
289 alloc_util::free_stdlib(data, size);
290 }
291}
292
293#[no_mangle]
294pub unsafe extern fn divans_decompressor_malloc_usize(state_ptr: *mut DivansDecompressorState, size: usize) -> *mut usize {
295 if let Some(alloc_fn) = (*state_ptr).custom_allocator.alloc_func {
296 return core::mem::transmute::<*mut c_void, *mut usize>(alloc_fn((*state_ptr).custom_allocator.opaque,
297 size * core::mem::size_of::<usize>()));
298 } else {
299 return alloc_util::alloc_stdlib(size);
300 }
301}
302#[no_mangle]
303pub unsafe extern fn divans_decompressor_free_usize(state_ptr: *mut DivansDecompressorState, data: *mut usize, size: usize) {
304 if let Some(free_fn) = (*state_ptr).custom_allocator.free_func {
305 free_fn((*state_ptr).custom_allocator.opaque, core::mem::transmute::<*mut usize, *mut c_void>(data));
306 } else {
307 alloc_util::free_stdlib(data, size);
308 }
309}
310
311#[no_mangle]
312pub unsafe extern fn divans_free_decompressor(state_ptr: *mut DivansDecompressorState) {
313 if let Some(_) = (*state_ptr).custom_allocator.alloc_func {
314 if let Some(free_fn) = (*state_ptr).custom_allocator.free_func {
315 let _to_free = core::ptr::read(state_ptr);
317 let ptr = core::mem::transmute::<*mut DivansDecompressorState, *mut c_void>(state_ptr);
318 free_fn((*state_ptr).custom_allocator.opaque, ptr);
319 }
320 } else {
321 free_decompressor_no_custom_alloc(state_ptr);
322 }
323}
324