1use crate::{ffi, Result};
2use core::{ffi::c_void, ptr};
3
4#[derive(Debug)]
5#[repr(C)]
6pub struct Blob {
7 m_buffer: *mut c_void,
8 m_size: usize,
9}
10
11impl Blob {
12 pub fn initialize(&mut self, size: usize) -> Result<()> {
13 unsafe { ffi::DirectXTexFFI_Blob_Initialize(self.into(), size) }.success(())
14 }
15
16 pub fn release(&mut self) {
17 unsafe { ffi::DirectXTexFFI_Blob_Release(self.into()) }
18 }
19
20 #[must_use]
21 pub fn buffer(&self) -> &[u8] {
22 unsafe { ffi::from_raw_ffi_parts(self.m_buffer.cast(), self.m_size) }
23 }
24
25 #[must_use]
26 pub fn buffer_mut(&mut self) -> &[u8] {
27 unsafe { ffi::from_raw_ffi_parts_mut(self.m_buffer.cast(), self.m_size) }
28 }
29
30 pub fn resize(&mut self, size: usize) -> Result<()> {
32 unsafe { ffi::DirectXTexFFI_Blob_Resize(self.into(), size) }.success(())
33 }
34
35 pub fn trim(&mut self, size: usize) -> Result<()> {
37 unsafe { ffi::DirectXTexFFI_Blob_Trim(self.into(), size) }.success(())
38 }
39}
40
41impl Default for Blob {
42 fn default() -> Self {
43 Self {
44 m_buffer: ptr::null_mut(),
45 m_size: 0,
46 }
47 }
48}
49
50impl Drop for Blob {
51 fn drop(&mut self) {
52 self.release();
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use crate::{ffi, Blob};
59 use core::mem;
60
61 #[test]
62 fn verify_layout() {
63 assert_eq!(mem::size_of::<Blob>(), unsafe {
64 ffi::DirectXTexFFI_Blob_Sizeof()
65 });
66 assert_eq!(mem::align_of::<Blob>(), unsafe {
67 ffi::DirectXTexFFI_Blob_Alignof()
68 });
69 }
70
71 #[test]
72 fn verify_api() {
73 let mut blob = Blob::default();
74
75 blob.initialize(256).unwrap();
76 assert_eq!(blob.buffer().len(), 256);
77 assert_eq!(blob.buffer_mut().len(), 256);
78
79 blob.resize(128).unwrap();
80 assert_eq!(blob.buffer().len(), 128);
81
82 blob.trim(64).unwrap();
83 assert_eq!(blob.buffer().len(), 64);
84
85 assert!(blob.trim(128).is_err());
86 }
87}