unrar_async/open_archive/
data.rs1use std::ffi::CString;
2use std::fmt;
3use std::path::Path;
4use std::ptr;
5
6pub(crate) struct Handle(Box<unrar_sys::Handle>);
7impl Handle {
8 pub fn from_ffi(handle: *mut unrar_sys::Handle) -> Self {
9 unsafe { Self(Box::from_raw(handle)) }
10 }
11
12 pub fn as_ffi(&self) -> *const unrar_sys::Handle {
13 &*self.0
14 }
15}
16impl fmt::Debug for Handle {
17 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
18 fmt::Pointer::fmt(&self.0, f)
19 }
20}
21
22#[derive(Debug)]
23pub(crate) struct OpenArchiveData {
24 pub archive_name: CString,
25 pub open_mode: u32,
26 pub open_result: u32,
27 pub comment_buffer: Option<CString>,
28 pub comment_buffer_size: u32,
29 pub comment_state: u32
30}
31
32impl OpenArchiveData {
33 pub fn new(archive_name: CString, open_mode: u32) -> Self {
34 Self{
35 archive_name,
36 open_mode,
37 open_result: 0,
38 comment_buffer: None,
39 comment_buffer_size: 0,
40 comment_state: 0
41 }
42 }
43
44 pub fn as_ffi(&self) -> unrar_sys::OpenArchiveData {
45 unrar_sys::OpenArchiveData{
46 archive_name: self.archive_name.as_ptr(),
47 open_mode: self.open_mode,
48 open_result: self.open_result,
49 comment_buffer: self.comment_buffer.as_ref().map(|s| s.as_ptr() as *mut _).unwrap_or(ptr::null_mut()),
50 comment_buffer_size: self.comment_buffer_size,
51 comment_size: self.comment_buffer.as_ref().map(|s| s.to_bytes().len() as u32).unwrap_or(0),
52 comment_state: self.comment_state
53 }
54 }
55}
56
57pub(crate) struct HeaderData(unrar_sys::HeaderData);
66
67impl HeaderData {
68 fn inner(&self) -> &unrar_sys::HeaderData {
69 &self.0
70 }
71}
72
73impl Default for HeaderData {
74 fn default() -> Self {
75 Self(unrar_sys::HeaderData{
76 archive_name: [0; 260],
77 filename: [0; 260],
78 flags: 0,
79 pack_size: 0,
80 unp_size: 0,
81 host_os: 0,
82 file_crc: 0,
83 file_time: 0,
84 unp_ver: 0,
85 method: 0,
86 file_attr: 0,
87 comment_buffer: ptr::null_mut(),
88 comment_buffer_size: 0,
89 comment_size: 0,
90 comment_state: 0
91 })
92 }
93}
94
95#[allow(clippy::non_send_fields_in_send_ty)]
98unsafe impl Send for HeaderData {}
99
100#[derive(Debug)]
102pub struct Entry {
103 pub filename: String,
104 pub flags: Flags,
105 pub unpacked_size: u32,
106 pub file_crc: u32,
107 pub file_time: u32,
108 pub method: u32,
109 pub file_attr: u32,
110 pub next_volume: Option<String>
111}
112
113impl Entry {
114 #[inline]
116 pub fn is_split(&self) -> bool {
117 self.flags.contains(Flags::SPLIT_BEFORE) || self.flags.contains(Flags::SPLIT_AFTER)
118 }
119
120 #[inline]
121 pub fn is_directory(&self) -> bool {
122 self.flags.contains(Flags::DIRECTORY)
123 }
124
125 #[inline]
126 pub fn is_encrypted(&self) -> bool {
127 self.flags.contains(Flags::ENCRYPTED)
128 }
129
130 #[inline]
131 pub fn is_file(&self) -> bool {
132 !self.is_directory()
133 }
134}
135
136impl AsRef<Path> for Entry {
137 #[inline]
138 fn as_ref(&self) -> &Path {
139 self.filename.as_ref()
140 }
141}
142
143impl fmt::Display for Entry {
144 #[inline]
145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146 f.write_str(&self.filename)?;
147 if(self.is_directory()) {
148 f.write_str("/")?;
149 }
150 if(self.is_split()) {
151 f.write_str(" (partial)")?;
152 }
153 Ok(())
154 }
155}
156
157impl TryFrom<HeaderData> for Entry {
158 type Error = std::string::FromUtf8Error;
159 fn try_from(header: HeaderData) -> Result<Self, Self::Error> {
160 let inner = header.inner();
161 let filename_len = unsafe { libc::strlen(&inner.filename as *const _) };
162 let filename = inner.filename[..filename_len]
163 .iter()
164 .map(|&c| c as u8)
165 .collect::<Vec<_>>();
166 Ok(Self{
167 filename: String::from_utf8(filename)?,
168 flags: Flags::from_bits(inner.flags).unwrap(),
169 unpacked_size: inner.unp_size,
170 file_crc: inner.file_crc,
171 file_time: inner.file_time,
172 method: inner.method,
173 file_attr: inner.file_attr,
174 next_volume: None
175 })
176 }
177}
178
179bitflags::bitflags! {
180 #[derive(Debug)]
181 pub struct Flags: u32 {
182 const SPLIT_BEFORE = 0x01;
183 const SPLIT_AFTER = 0x02;
184 const ENCRYPTED = 0x04;
185 const SOLID = 0x10;
187 const DIRECTORY = 0x20;
188 }
189}
190