1#![warn(unsafe_op_in_unsafe_fn)]
2#![allow(non_camel_case_types)]
3#![allow(clippy::missing_safety_doc)]
4#![allow(unused_unsafe)]
5
6use ffizz_passby::Unboxed;
7
8struct ByteBuffer(Vec<u8>);
10
11#[derive(Clone, Copy)]
20#[repr(C)]
21pub struct byte_buffer_t([u64; 4]); type UnboxedByteBuffer = Unboxed<ByteBuffer, byte_buffer_t>;
24
25#[no_mangle]
27pub unsafe extern "C" fn byte_buffer_new() -> byte_buffer_t {
28 unsafe { UnboxedByteBuffer::return_val(ByteBuffer(Vec::new())) }
29}
30
31#[no_mangle]
33pub unsafe extern "C" fn byte_buffer_init(bb: *mut byte_buffer_t) {
34 unsafe { UnboxedByteBuffer::to_out_param_nonnull(ByteBuffer(Vec::new()), bb) }
35}
36
37#[no_mangle]
39pub unsafe extern "C" fn byte_buffer_free(bb: *mut byte_buffer_t) {
40 let bb = unsafe { UnboxedByteBuffer::take_ptr_nonnull(bb) };
41 drop(bb); }
43
44#[no_mangle]
46pub unsafe extern "C" fn byte_buffer_checksum(bb: *const byte_buffer_t) -> u8 {
47 unsafe {
48 UnboxedByteBuffer::with_ref_nonnull(bb, |bb| {
49 bb.0.iter().copied().reduce(|a, b| a ^ b).unwrap_or(0)
51 })
52 }
53}
54
55#[no_mangle]
57pub unsafe extern "C" fn byte_buffer_push(bb: *mut byte_buffer_t, b: u8) {
58 unsafe { UnboxedByteBuffer::with_ref_mut_nonnull(bb, |bb| bb.0.push(b)) }
59}
60
61#[no_mangle]
65pub unsafe extern "C" fn byte_buffer_combine(
66 bb1: *mut byte_buffer_t,
67 bb2: *mut byte_buffer_t,
68) -> byte_buffer_t {
69 let mut bb1 = unsafe { UnboxedByteBuffer::take_ptr_nonnull(bb1) };
70 let bb2 = unsafe { UnboxedByteBuffer::take_ptr_nonnull(bb2) };
71
72 bb1.0.extend(&bb2.0[..]);
74 unsafe { UnboxedByteBuffer::return_val(bb1) }
75}
76
77fn main() {
78 let mut bb1 = unsafe { byte_buffer_new() };
79 assert_eq!(
80 unsafe { byte_buffer_checksum(&bb1 as *const byte_buffer_t) },
81 0
82 );
83
84 unsafe {
85 byte_buffer_push(&mut bb1 as *mut byte_buffer_t, 0xf0);
86 byte_buffer_push(&mut bb1 as *mut byte_buffer_t, 0x0f);
87 }
88
89 assert_eq!(
90 unsafe { byte_buffer_checksum(&bb1 as *const byte_buffer_t) },
91 0xff
92 );
93
94 let mut bb2: byte_buffer_t = unsafe { std::mem::zeroed() }; unsafe {
96 byte_buffer_init(&mut bb2 as *mut byte_buffer_t);
97 }
98 unsafe {
99 byte_buffer_push(&mut bb2 as *mut byte_buffer_t, 0xa5);
100 byte_buffer_push(&mut bb2 as *mut byte_buffer_t, 0x5b);
101 }
102 assert_eq!(
103 unsafe { byte_buffer_checksum(&bb2 as *const byte_buffer_t) },
104 0xfe
105 );
106
107 let mut bb3 = unsafe {
108 byte_buffer_combine(
109 &mut bb1 as *mut byte_buffer_t,
110 &mut bb2 as *mut byte_buffer_t,
111 )
112 };
113
114 assert_eq!(
117 unsafe { byte_buffer_checksum(&bb3 as *const byte_buffer_t) },
118 0xff ^ 0xfe
119 );
120
121 unsafe { byte_buffer_free(&mut bb3 as *mut byte_buffer_t) };
122}