summaryrefslogtreecommitdiffstats
path: root/rust/vendor/brotli-decompressor/src/ffi
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:39:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:39:49 +0000
commita0aa2307322cd47bbf416810ac0292925e03be87 (patch)
tree37076262a026c4b48c8a0e84f44ff9187556ca35 /rust/vendor/brotli-decompressor/src/ffi
parentInitial commit. (diff)
downloadsuricata-a0aa2307322cd47bbf416810ac0292925e03be87.tar.xz
suricata-a0aa2307322cd47bbf416810ac0292925e03be87.zip
Adding upstream version 1:7.0.3.upstream/1%7.0.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'rust/vendor/brotli-decompressor/src/ffi')
-rw-r--r--rust/vendor/brotli-decompressor/src/ffi/alloc_util.rs228
-rw-r--r--rust/vendor/brotli-decompressor/src/ffi/interface.rs49
-rw-r--r--rust/vendor/brotli-decompressor/src/ffi/mod.rs379
3 files changed, 656 insertions, 0 deletions
diff --git a/rust/vendor/brotli-decompressor/src/ffi/alloc_util.rs b/rust/vendor/brotli-decompressor/src/ffi/alloc_util.rs
new file mode 100644
index 0000000..ee6759a
--- /dev/null
+++ b/rust/vendor/brotli-decompressor/src/ffi/alloc_util.rs
@@ -0,0 +1,228 @@
+use core;
+#[cfg(feature="std")]
+use std;
+use ::alloc;
+use super::interface::{c_void, CAllocator};
+#[cfg(feature="std")]
+use std::vec::Vec;
+#[cfg(feature="std")]
+pub use std::boxed::Box;
+
+#[cfg(feature="std")]
+pub struct MemoryBlock<Ty:Sized+Default>(Box<[Ty]>);
+#[cfg(feature="std")]
+impl<Ty:Sized+Default> Default for MemoryBlock<Ty> {
+ fn default() -> Self {
+ MemoryBlock(Vec::<Ty>::new().into_boxed_slice())
+ }
+}
+#[cfg(feature="std")]
+impl<Ty:Sized+Default> alloc::SliceWrapper<Ty> for MemoryBlock<Ty> {
+ fn slice(&self) -> &[Ty] {
+ &self.0[..]
+ }
+}
+#[cfg(feature="std")]
+impl<Ty:Sized+Default> alloc::SliceWrapperMut<Ty> for MemoryBlock<Ty> {
+ fn slice_mut(&mut self) -> &mut [Ty] {
+ &mut self.0[..]
+ }
+}
+#[cfg(feature="std")]
+impl<Ty:Sized+Default> core::ops::Index<usize> for MemoryBlock<Ty> {
+ type Output = Ty;
+ fn index(&self, index:usize) -> &Ty {
+ &self.0[index]
+ }
+}
+#[cfg(feature="std")]
+impl<Ty:Sized+Default> core::ops::IndexMut<usize> for MemoryBlock<Ty> {
+
+ fn index_mut(&mut self, index:usize) -> &mut Ty {
+ &mut self.0[index]
+ }
+}
+#[cfg(feature="std")]
+impl<Ty:Sized+Default> Drop for MemoryBlock<Ty> {
+ fn drop (&mut self) {
+ if self.0.len() != 0 {
+ print!("leaking memory block of length {} element size: {}\n", self.0.len(), core::mem::size_of::<Ty>());
+
+ let to_forget = core::mem::replace(self, MemoryBlock::default());
+ core::mem::forget(to_forget);// leak it -- it's the only safe way with custom allocators
+ }
+ }
+}
+pub struct SubclassableAllocator {
+ alloc: CAllocator
+ // have alternative ty here
+}
+
+impl SubclassableAllocator {
+ pub unsafe fn new(sub_alloc:CAllocator) -> Self {
+ SubclassableAllocator{
+ alloc:sub_alloc,
+ }
+ }
+}
+#[cfg(feature="std")]
+impl<Ty:Sized+Default+Clone> alloc::Allocator<Ty> for SubclassableAllocator {
+ type AllocatedMemory = MemoryBlock<Ty>;
+ fn alloc_cell(&mut self, size:usize) ->MemoryBlock<Ty>{
+ if size == 0 {
+ return MemoryBlock::<Ty>::default();
+ }
+ if let Some(alloc_fn) = self.alloc.alloc_func {
+ let ptr = alloc_fn(self.alloc.opaque, size * core::mem::size_of::<Ty>());
+ let typed_ptr = unsafe {core::mem::transmute::<*mut c_void, *mut Ty>(ptr)};
+ let slice_ref = unsafe {super::slice_from_raw_parts_or_nil_mut(typed_ptr, size)};
+ for item in slice_ref.iter_mut() {
+ unsafe{core::ptr::write(item, Ty::default())};
+ }
+ return MemoryBlock(unsafe{Box::from_raw(slice_ref)})
+ }
+ MemoryBlock(vec![Ty::default();size].into_boxed_slice())
+ }
+ fn free_cell(&mut self, mut bv:MemoryBlock<Ty>) {
+ if (*bv.0).len() != 0 {
+ if let Some(_) = self.alloc.alloc_func {
+ let slice_ptr = (*bv.0).as_mut_ptr();
+ let _box_ptr = Box::into_raw(core::mem::replace(&mut bv.0, Vec::<Ty>::new().into_boxed_slice()));
+ if let Some(free_fn) = self.alloc.free_func {
+ unsafe {free_fn(self.alloc.opaque, core::mem::transmute::<*mut Ty, *mut c_void>(slice_ptr))};
+ }
+ } else {
+ let _to_free = core::mem::replace(&mut bv.0, Vec::<Ty>::new().into_boxed_slice());
+ }
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+#[cfg(not(feature="std"))]
+static mut G_SLICE:&'static mut[u8] = &mut[];
+#[cfg(not(feature="std"))]
+pub struct MemoryBlock<Ty:Sized+Default>(*mut[Ty]);
+#[cfg(not(feature="std"))]
+impl<Ty:Sized+Default> Default for MemoryBlock<Ty> {
+ fn default() -> Self {
+ MemoryBlock(unsafe{core::mem::transmute::<*mut [u8], *mut[Ty]>(G_SLICE.as_mut())})
+ }
+}
+#[cfg(not(feature="std"))]
+impl<Ty:Sized+Default> alloc::SliceWrapper<Ty> for MemoryBlock<Ty> {
+ fn slice(&self) -> &[Ty] {
+ if unsafe{(*self.0).len()} == 0 {
+ &[]
+ } else {
+ unsafe{super::slice_from_raw_parts_or_nil(&(*self.0)[0], (*self.0).len())}
+ }
+ }
+}
+#[cfg(not(feature="std"))]
+impl<Ty:Sized+Default> alloc::SliceWrapperMut<Ty> for MemoryBlock<Ty> {
+ fn slice_mut(&mut self) -> &mut [Ty] {
+ if unsafe{(*self.0).len()} == 0 {
+ &mut []
+ } else {
+ unsafe{super::slice_from_raw_parts_or_nil_mut(&mut (*self.0)[0], (*self.0).len())}
+ }
+ }
+}
+
+#[cfg(not(feature="std"))]
+#[cfg(feature="no-stdlib-ffi-binding")]
+#[panic_handler]
+extern fn panic_impl(_: &::core::panic::PanicInfo) -> ! {
+ loop {}
+}
+#[cfg(not(feature="std"))]
+#[cfg(feature="no-stdlib-ffi-binding")]
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {
+}
+
+#[cfg(not(feature="std"))]
+impl<Ty:Sized+Default> core::ops::Index<usize> for MemoryBlock<Ty> {
+ type Output = Ty;
+ fn index(&self, index:usize) -> &Ty {
+ unsafe{&(*self.0)[index]}
+ }
+}
+#[cfg(not(feature="std"))]
+impl<Ty:Sized+Default> core::ops::IndexMut<usize> for MemoryBlock<Ty> {
+
+ fn index_mut(&mut self, index:usize) -> &mut Ty {
+ unsafe{&mut (*self.0)[index]}
+ }
+}
+
+#[cfg(not(feature="std"))]
+impl<Ty:Sized+Default+Clone> alloc::Allocator<Ty> for SubclassableAllocator {
+ type AllocatedMemory = MemoryBlock<Ty>;
+ fn alloc_cell(&mut self, size:usize) ->MemoryBlock<Ty>{
+ if size == 0 {
+ return MemoryBlock::<Ty>::default();
+ }
+ if let Some(alloc_fn) = self.alloc.alloc_func {
+ let ptr = alloc_fn(self.alloc.opaque, size * core::mem::size_of::<Ty>());
+ let typed_ptr = unsafe {core::mem::transmute::<*mut c_void, *mut Ty>(ptr)};
+ let slice_ref = unsafe {super::slice_from_raw_parts_or_nil_mut(typed_ptr, size)};
+ for item in slice_ref.iter_mut() {
+ unsafe{core::ptr::write(item, Ty::default())};
+ }
+ return MemoryBlock(slice_ref.as_mut())
+ } else {
+ panic!("Must provide allocators in no-stdlib code");
+ }
+ }
+ fn free_cell(&mut self, mut bv:MemoryBlock<Ty>) {
+ use alloc::SliceWrapper;
+ use alloc::SliceWrapperMut;
+ if bv.slice().len() != 0 {
+ if let Some(_) = self.alloc.alloc_func {
+ if let Some(free_fn) = self.alloc.free_func {
+ unsafe {free_fn(self.alloc.opaque, core::mem::transmute::<*mut Ty, *mut c_void>(&mut bv.slice_mut()[0]))};
+ }
+ let _ = core::mem::replace(&mut bv,
+ MemoryBlock::<Ty>::default());
+ } else {
+ panic!("Must provide allocators in no-stdlib code");
+ }
+ }
+ }
+}
+
+
+#[cfg(not(feature="std"))]
+pub fn free_stdlib<T>(_data: *mut T, _size: usize) {
+ panic!("Must supply allocators if calling divans when compiled with features=no-stdlib");
+}
+#[cfg(not(feature="std"))]
+pub fn alloc_stdlib<T:Sized+Default+Copy+Clone>(_size: usize) -> *mut T {
+ panic!("Must supply allocators if calling divans when compiled with features=no-stdlib");
+}
+
+#[cfg(feature="std")]
+pub unsafe fn free_stdlib<T>(ptr: *mut T, size: usize) {
+ let slice_ref = super::slice_from_raw_parts_or_nil_mut(ptr, size);
+ let _ = Box::from_raw(slice_ref); // free on drop
+}
+#[cfg(feature="std")]
+pub fn alloc_stdlib<T:Sized+Default+Copy+Clone>(size: usize) -> *mut T {
+ std::panic::catch_unwind(|| {
+ let mut newly_allocated = vec![T::default();size].into_boxed_slice();
+ let slice_ptr = newly_allocated.as_mut_ptr();
+ let _box_ptr = Box::into_raw(newly_allocated);
+ slice_ptr
+ }).unwrap_or(core::ptr::null_mut())
+}
diff --git a/rust/vendor/brotli-decompressor/src/ffi/interface.rs b/rust/vendor/brotli-decompressor/src/ffi/interface.rs
new file mode 100644
index 0000000..eefccac
--- /dev/null
+++ b/rust/vendor/brotli-decompressor/src/ffi/interface.rs
@@ -0,0 +1,49 @@
+use ::BrotliResult;
+#[allow(non_camel_case_types)]
+#[repr(u8)]
+pub enum c_void{
+ _Nothing = 0,
+}
+
+#[repr(C)]
+#[allow(dead_code)]
+pub enum BrotliDecoderParameter {
+ BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION = 0,
+ BROTLI_DECODER_PARAM_LARGE_WINDOW = 1,
+}
+
+
+#[repr(C)]
+pub enum BrotliDecoderResult {
+ BROTLI_DECODER_RESULT_ERROR = 0,
+ BROTLI_DECODER_RESULT_SUCCESS = 1,
+ BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT = 2,
+ BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT = 3,
+}
+
+
+impl From<BrotliResult> for BrotliDecoderResult {
+ fn from(r: BrotliResult) -> Self {
+ match r {
+ BrotliResult::ResultSuccess => BrotliDecoderResult::BROTLI_DECODER_RESULT_SUCCESS,
+ BrotliResult::ResultFailure => BrotliDecoderResult::BROTLI_DECODER_RESULT_ERROR,
+ BrotliResult::NeedsMoreInput => BrotliDecoderResult::BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT ,
+ BrotliResult::NeedsMoreOutput => BrotliDecoderResult::BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT ,
+ }
+ }
+}
+pub type brotli_alloc_func = Option<extern "C" fn(data: *mut c_void, size: usize) -> *mut c_void>;
+
+pub type brotli_free_func = Option<extern "C" fn(data: *mut c_void, ptr: *mut c_void) -> ()>;
+
+
+#[repr(C)]
+#[derive(Clone)]
+pub struct CAllocator {
+ pub alloc_func: brotli_alloc_func,
+ pub free_func: brotli_free_func,
+ pub opaque: *mut c_void,
+}
+
+unsafe impl Send for CAllocator {
+}
diff --git a/rust/vendor/brotli-decompressor/src/ffi/mod.rs b/rust/vendor/brotli-decompressor/src/ffi/mod.rs
new file mode 100644
index 0000000..e8f4ae3
--- /dev/null
+++ b/rust/vendor/brotli-decompressor/src/ffi/mod.rs
@@ -0,0 +1,379 @@
+#![cfg(not(feature="safe"))]
+
+#[cfg(feature="std")]
+use std::{thread,panic, io, boxed, any, string};
+#[cfg(feature="std")]
+use std::io::Write;
+use core;
+use core::slice;
+use core::ops;
+pub mod interface;
+pub mod alloc_util;
+use self::alloc_util::SubclassableAllocator;
+use alloc::{Allocator, SliceWrapper, SliceWrapperMut, StackAllocator, AllocatedStackMemory, bzero};
+use self::interface::{CAllocator, c_void, BrotliDecoderParameter, BrotliDecoderResult, brotli_alloc_func, brotli_free_func};
+use ::BrotliResult;
+use ::BrotliDecoderReturnInfo;
+use ::brotli_decode;
+pub use ::HuffmanCode;
+pub use super::state::{BrotliDecoderErrorCode, BrotliState};
+
+pub unsafe fn slice_from_raw_parts_or_nil<'a, T>(data: *const T, len: usize) -> &'a [T] {
+ if len == 0 {
+ return &[];
+ }
+ slice::from_raw_parts(data, len)
+}
+
+pub unsafe fn slice_from_raw_parts_or_nil_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
+ if len == 0 {
+ return &mut [];
+ }
+ slice::from_raw_parts_mut(data, len)
+}
+
+#[cfg(feature="std")]
+type BrotliAdditionalErrorData = boxed::Box<dyn any::Any + Send + 'static>;
+#[cfg(not(feature="std"))]
+type BrotliAdditionalErrorData = ();
+
+#[repr(C)]
+pub struct BrotliDecoderState {
+ pub custom_allocator: CAllocator,
+ pub decompressor: ::BrotliState<SubclassableAllocator,
+ SubclassableAllocator,
+ SubclassableAllocator>,
+}
+
+#[cfg(not(feature="std"))]
+fn brotli_new_decompressor_without_custom_alloc(_to_box: BrotliDecoderState) -> *mut BrotliDecoderState{
+ panic!("Must supply allocators if calling divans when compiled without features=std");
+}
+
+#[cfg(feature="std")]
+fn brotli_new_decompressor_without_custom_alloc(to_box: BrotliDecoderState) -> *mut BrotliDecoderState{
+ alloc_util::Box::<BrotliDecoderState>::into_raw(
+ alloc_util::Box::<BrotliDecoderState>::new(to_box))
+}
+
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderCreateInstance(
+ alloc_func: brotli_alloc_func,
+ free_func: brotli_free_func,
+ opaque: *mut c_void,
+) -> *mut BrotliDecoderState {
+ match catch_panic_state(|| {
+ let allocators = CAllocator {
+ alloc_func:alloc_func,
+ free_func:free_func,
+ opaque:opaque,
+ };
+ let custom_dictionary = <SubclassableAllocator as Allocator<u8>>::AllocatedMemory::default();
+ let to_box = BrotliDecoderState {
+ custom_allocator: allocators.clone(),
+ decompressor: ::BrotliState::new_with_custom_dictionary(
+ SubclassableAllocator::new(allocators.clone()),
+ SubclassableAllocator::new(allocators.clone()),
+ SubclassableAllocator::new(allocators.clone()),
+ custom_dictionary,
+ ),
+ };
+ if let Some(alloc) = alloc_func {
+ if free_func.is_none() {
+ panic!("either both alloc and free must exist or neither");
+ }
+ let ptr = alloc(allocators.opaque, core::mem::size_of::<BrotliDecoderState>());
+ let brotli_decoder_state_ptr = core::mem::transmute::<*mut c_void, *mut BrotliDecoderState>(ptr);
+ core::ptr::write(brotli_decoder_state_ptr, to_box);
+ brotli_decoder_state_ptr
+ } else {
+ brotli_new_decompressor_without_custom_alloc(to_box)
+ }
+ }) {
+ Ok(ret) => ret,
+ Err(mut e) => {
+ error_print(core::ptr::null_mut(), &mut e);
+ core::ptr::null_mut()
+ },
+ }
+}
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderSetParameter(_state_ptr: *mut BrotliDecoderState,
+ _selector: BrotliDecoderParameter,
+ _value: u32) {
+ // not implemented
+}
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderDecompressPrealloc(
+ encoded_size: usize,
+ encoded_buffer: *const u8,
+ decoded_size: usize,
+ decoded_buffer: *mut u8,
+ scratch_u8_size: usize,
+ scratch_u8_buffer: *mut u8,
+ scratch_u32_size: usize,
+ scratch_u32_buffer: *mut u32,
+ scratch_hc_size: usize,
+ scratch_hc_buffer: *mut HuffmanCode,
+) -> BrotliDecoderReturnInfo {
+ let input = slice_from_raw_parts_or_nil(encoded_buffer, encoded_size);
+ let output = slice_from_raw_parts_or_nil_mut(decoded_buffer, decoded_size);
+ let scratch_u8 = slice_from_raw_parts_or_nil_mut(scratch_u8_buffer, scratch_u8_size);
+ let scratch_u32 = slice_from_raw_parts_or_nil_mut(scratch_u32_buffer, scratch_u32_size);
+ let scratch_hc = slice_from_raw_parts_or_nil_mut(scratch_hc_buffer, scratch_hc_size);
+ ::brotli_decode_prealloc(input, output, scratch_u8, scratch_u32, scratch_hc)
+}
+
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderDecompressWithReturnInfo(
+ encoded_size: usize,
+ encoded_buffer: *const u8,
+ decoded_size: usize,
+ decoded_buffer: *mut u8,
+) -> BrotliDecoderReturnInfo {
+ let input = slice_from_raw_parts_or_nil(encoded_buffer, encoded_size);
+ let output_scratch = slice_from_raw_parts_or_nil_mut(decoded_buffer, decoded_size);
+ ::brotli_decode(input, output_scratch)
+}
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderDecompress(
+ encoded_size: usize,
+ encoded_buffer: *const u8,
+ decoded_size: *mut usize,
+ decoded_buffer: *mut u8,
+) -> BrotliDecoderResult {
+ let res = BrotliDecoderDecompressWithReturnInfo(encoded_size, encoded_buffer, *decoded_size, decoded_buffer);
+ *decoded_size = res.decoded_size;
+ match res.result {
+ BrotliResult::ResultSuccess => BrotliDecoderResult::BROTLI_DECODER_RESULT_SUCCESS,
+ _ => BrotliDecoderResult::BROTLI_DECODER_RESULT_ERROR
+ }
+}
+
+#[cfg(all(feature="std", not(feature="pass-through-ffi-panics")))]
+fn catch_panic<F:FnOnce()->BrotliDecoderResult+panic::UnwindSafe>(f: F) -> thread::Result<BrotliDecoderResult> {
+ panic::catch_unwind(f)
+}
+
+#[cfg(all(feature="std", not(feature="pass-through-ffi-panics")))]
+fn catch_panic_state<F:FnOnce()->*mut BrotliDecoderState+panic::UnwindSafe>(f: F) -> thread::Result<*mut BrotliDecoderState> {
+ panic::catch_unwind(f)
+}
+
+#[cfg(all(feature="std", not(feature="pass-through-ffi-panics")))]
+unsafe fn error_print(state_ptr: *mut BrotliDecoderState, err: &mut BrotliAdditionalErrorData) {
+ if let Some(st) = err.downcast_ref::<&str>() {
+ if !state_ptr.is_null() {
+ let mut str_cpy = [0u8;256];
+ let src:&[u8] = st.as_ref();
+ let xlen = core::cmp::min(src.len(), str_cpy.len() - 1);
+ str_cpy.split_at_mut(xlen).0.clone_from_slice(
+ src.split_at(xlen).0);
+ str_cpy[xlen] = 0; // null terminate
+ (*state_ptr).decompressor.mtf_or_error_string = Err(str_cpy);
+ }
+ let _ign = writeln!(&mut io::stderr(), "panic: {}", st);
+ } else {
+ if let Some(st) = err.downcast_ref::<string::String>() {
+
+ if !state_ptr.is_null() {
+ let mut str_cpy = [0u8;256];
+ let src: &[u8] = st.as_ref();
+ let xlen = core::cmp::min(src.len(), str_cpy.len() - 1);
+ str_cpy.split_at_mut(xlen).0.clone_from_slice(
+ src.split_at(xlen).0);
+ str_cpy[xlen] = 0; // null terminate
+ (*state_ptr).decompressor.mtf_or_error_string = Err(str_cpy);
+ }
+ let _ign = writeln!(&mut io::stderr(), "Internal Error {:?}", st);
+ } else {
+ let _ign = writeln!(&mut io::stderr(), "Internal Error {:?}", err);
+ }
+ }
+}
+
+// can't catch panics in a reliable way without std:: configure with panic=abort. These shouldn't happen
+#[cfg(any(not(feature="std"), feature="pass-through-ffi-panics"))]
+fn catch_panic<F:FnOnce()->BrotliDecoderResult>(f: F) -> Result<BrotliDecoderResult, BrotliAdditionalErrorData> {
+ Ok(f())
+}
+
+#[cfg(any(not(feature="std"), feature="pass-through-ffi-panics"))]
+fn catch_panic_state<F:FnOnce()->*mut BrotliDecoderState>(f: F) -> Result<*mut BrotliDecoderState, BrotliAdditionalErrorData> {
+ Ok(f())
+}
+
+#[cfg(any(not(feature="std"), feature="pass-through-ffi-panics"))]
+fn error_print(_state_ptr: *mut BrotliDecoderState, _err: &mut BrotliAdditionalErrorData) {
+}
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderDecompressStream(
+ state_ptr: *mut BrotliDecoderState,
+ available_in: *mut usize,
+ input_buf_ptr: *mut*const u8,
+ available_out: *mut usize,
+ output_buf_ptr: *mut*mut u8,
+ mut total_out: *mut usize) -> BrotliDecoderResult {
+ match catch_panic(move || {
+ let mut input_offset = 0usize;
+ let mut output_offset = 0usize;
+ let mut fallback_total_out = 0usize;
+ if total_out.is_null() {
+ total_out = &mut fallback_total_out;
+ }
+ let result: BrotliDecoderResult;
+ {
+ let input_buf = slice_from_raw_parts_or_nil(*input_buf_ptr, *available_in);
+ let output_buf = slice_from_raw_parts_or_nil_mut(*output_buf_ptr, *available_out);
+ result = super::decode::BrotliDecompressStream(
+ &mut *available_in,
+ &mut input_offset,
+ input_buf,
+ &mut *available_out,
+ &mut output_offset,
+ output_buf,
+ &mut *total_out,
+ &mut (*state_ptr).decompressor,
+ ).into();
+ }
+ *input_buf_ptr = (*input_buf_ptr).offset(input_offset as isize);
+ *output_buf_ptr = (*output_buf_ptr).offset(output_offset as isize);
+ result
+ }) {
+ Ok(ret) => ret,
+ Err(mut readable_err) => { // if we panic (completely unexpected) then we should report it back to C and print
+ error_print(state_ptr, &mut readable_err);
+ (*state_ptr).decompressor.error_code = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE;
+ BrotliDecoderResult::BROTLI_DECODER_RESULT_ERROR
+ }
+ }
+}
+
+/// Equivalent to BrotliDecoderDecompressStream but with no optional arg and no double indirect ptrs
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderDecompressStreaming(
+ state_ptr: *mut BrotliDecoderState,
+ available_in: *mut usize,
+ mut input_buf_ptr: *const u8,
+ available_out: *mut usize,
+ mut output_buf_ptr: *mut u8) -> BrotliDecoderResult {
+ BrotliDecoderDecompressStream(state_ptr,
+ available_in,
+ &mut input_buf_ptr,
+ available_out,
+ &mut output_buf_ptr,
+ core::ptr::null_mut())
+}
+
+#[cfg(feature="std")]
+unsafe fn free_decompressor_no_custom_alloc(state_ptr: *mut BrotliDecoderState) {
+ let _state = alloc_util::Box::from_raw(state_ptr);
+}
+
+#[cfg(not(feature="std"))]
+unsafe fn free_decompressor_no_custom_alloc(_state_ptr: *mut BrotliDecoderState) {
+ unreachable!();
+}
+
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderMallocU8(state_ptr: *mut BrotliDecoderState, size: usize) -> *mut u8 {
+ if let Some(alloc_fn) = (*state_ptr).custom_allocator.alloc_func {
+ return core::mem::transmute::<*mut c_void, *mut u8>(alloc_fn((*state_ptr).custom_allocator.opaque, size));
+ } else {
+ return alloc_util::alloc_stdlib(size);
+ }
+}
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderFreeU8(state_ptr: *mut BrotliDecoderState, data: *mut u8, size: usize) {
+ if let Some(free_fn) = (*state_ptr).custom_allocator.free_func {
+ free_fn((*state_ptr).custom_allocator.opaque, core::mem::transmute::<*mut u8, *mut c_void>(data));
+ } else {
+ alloc_util::free_stdlib(data, size);
+ }
+}
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderMallocUsize(state_ptr: *mut BrotliDecoderState, size: usize) -> *mut usize {
+ if let Some(alloc_fn) = (*state_ptr).custom_allocator.alloc_func {
+ return core::mem::transmute::<*mut c_void, *mut usize>(alloc_fn((*state_ptr).custom_allocator.opaque,
+ size * core::mem::size_of::<usize>()));
+ } else {
+ return alloc_util::alloc_stdlib(size);
+ }
+}
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderFreeUsize(state_ptr: *mut BrotliDecoderState, data: *mut usize, size: usize) {
+ if let Some(free_fn) = (*state_ptr).custom_allocator.free_func {
+ free_fn((*state_ptr).custom_allocator.opaque, core::mem::transmute::<*mut usize, *mut c_void>(data));
+ } else {
+ alloc_util::free_stdlib(data, size);
+ }
+}
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderDestroyInstance(state_ptr: *mut BrotliDecoderState) {
+ if let Some(_) = (*state_ptr).custom_allocator.alloc_func {
+ if let Some(free_fn) = (*state_ptr).custom_allocator.free_func {
+ let _to_free = core::ptr::read(state_ptr);
+ let ptr = core::mem::transmute::<*mut BrotliDecoderState, *mut c_void>(state_ptr);
+ free_fn((*state_ptr).custom_allocator.opaque, ptr);
+ }
+ } else {
+ free_decompressor_no_custom_alloc(state_ptr);
+ }
+}
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderHasMoreOutput(state_ptr: *const BrotliDecoderState) -> i32 {
+ if super::decode::BrotliDecoderHasMoreOutput(&(*state_ptr).decompressor) {1} else {0}
+}
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderTakeOutput(state_ptr: *mut BrotliDecoderState, size: *mut usize) -> *const u8 {
+ super::decode::BrotliDecoderTakeOutput(&mut (*state_ptr).decompressor, &mut *size).as_ptr()
+}
+
+
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderIsUsed(state_ptr: *const BrotliDecoderState) -> i32 {
+ if super::decode::BrotliDecoderIsUsed(&(*state_ptr).decompressor) {1} else {0}
+}
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderIsFinished(state_ptr: *const BrotliDecoderState) -> i32 {
+ if super::decode::BrotliDecoderIsFinished(&(*state_ptr).decompressor) {1} else {0}
+}
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderGetErrorCode(state_ptr: *const BrotliDecoderState) -> BrotliDecoderErrorCode {
+ super::decode::BrotliDecoderGetErrorCode(&(*state_ptr).decompressor)
+}
+
+#[no_mangle]
+pub unsafe extern fn BrotliDecoderGetErrorString(state_ptr: *const BrotliDecoderState) -> *const u8 {
+ if !state_ptr.is_null() {
+ if let &Err(ref msg) = &(*state_ptr).decompressor.mtf_or_error_string {
+ // important: this must be a ref
+ // so stack memory is not returned
+ return msg.as_ptr();
+ }
+ }
+ BrotliDecoderErrorString(super::decode::BrotliDecoderGetErrorCode(&(*state_ptr).decompressor))
+}
+#[no_mangle]
+pub extern fn BrotliDecoderErrorString(c: BrotliDecoderErrorCode) -> *const u8 {
+ ::state::BrotliDecoderErrorStr(c).as_ptr()
+}
+
+
+#[no_mangle]
+pub extern fn BrotliDecoderVersion() -> u32 {
+ 0x1000f00
+}