Line data Source code
1 : use lief_ffi as ffi;
2 : use cxx::memory::UniquePtrTarget;
3 : use std::marker::PhantomData;
4 :
5 : use crate::Range;
6 :
7 : #[doc(hidden)]
8 : pub trait FromFFI<T: UniquePtrTarget> {
9 : fn from_ffi(ptr: cxx::UniquePtr<T>) -> Self;
10 : }
11 :
12 : #[doc(hidden)]
13 : pub trait AsFFI<U> {
14 : fn as_ffi(&self) -> &U;
15 :
16 : #[allow(dead_code)]
17 : fn as_mut_ffi(&mut self) -> std::pin::Pin<&mut U>;
18 : }
19 :
20 : #[doc(hidden)]
21 3126780 : pub fn into_optional<T: FromFFI<U>, U: UniquePtrTarget>(raw_ffi: cxx::UniquePtr<U>) -> Option<T> {
22 3126780 : if raw_ffi.is_null() {
23 1369116 : None
24 : } else {
25 1757664 : Some(T::from_ffi(raw_ffi))
26 : }
27 3126780 : }
28 :
29 : #[doc(hidden)]
30 0 : pub fn into_ranges(raw_ffi: cxx::UniquePtr<cxx::CxxVector<ffi::Range>>) -> Vec<Range> {
31 0 : let cxx_vec = raw_ffi.as_ref().unwrap();
32 0 : if cxx_vec.is_empty() {
33 0 : return Vec::new();
34 0 : }
35 0 :
36 0 : let mut rust_range: Vec<Range> = Vec::with_capacity(cxx_vec.len());
37 :
38 0 : for ffi_range in cxx_vec {
39 0 : rust_range.push(Range::from_ffi(ffi_range));
40 0 : }
41 :
42 0 : rust_range
43 0 : }
44 :
45 : pub struct Iterator<'a, Parent: UniquePtrTarget, It: UniquePtrTarget> {
46 : #[doc(hidden)]
47 : pub it: cxx::UniquePtr<It>,
48 : _owner: PhantomData<&'a Parent>,
49 : }
50 :
51 : impl<'a, Parent: UniquePtrTarget, It: UniquePtrTarget> Iterator<'a, Parent, It> {
52 : #[doc(hidden)]
53 430344 : pub fn new(it: cxx::UniquePtr<It>) -> Self {
54 430344 : Self {
55 430344 : it,
56 430344 : _owner: PhantomData,
57 430344 : }
58 430344 : }
59 : }
60 :
61 : #[doc(hidden)]
62 : #[macro_export]
63 : macro_rules! declare_iterator_conv {
64 : ($name:ident, $from:ty, $ffi:ty, $parent:ty, $ffi_iterator:ty, $conv: expr) => {
65 : pub type $name<'a> = $crate::common::Iterator<'a, $parent, $ffi_iterator>;
66 : impl<'a> Iterator for $name<'a> {
67 : type Item = $from;
68 6130572 : fn next(&mut self) -> Option<Self::Item> {
69 6130572 : let next = self.it.as_mut().unwrap().next();
70 6130572 : if next.is_null() {
71 426324 : None
72 : } else {
73 5704248 : Some($conv(next))
74 : }
75 6130572 : }
76 : }
77 : impl<'a> ExactSizeIterator for $name<'a> {
78 4020 : fn len(&self) -> usize {
79 4020 : self.it.as_ref().unwrap().size().try_into().unwrap()
80 4020 : }
81 : }
82 : };
83 : }
84 :
85 : #[doc(hidden)]
86 : #[macro_export]
87 : macro_rules! declare_iterator {
88 : ($name:ident, $from:ty, $ffi:ty, $parent:ty, $ffi_iterator:ty) => {
89 : $crate::declare_iterator_conv!($name, $from, $ffi, $parent, $ffi_iterator, |n| {
90 : Self::Item::from_ffi(n)
91 : });
92 : };
93 : }
94 :
95 : pub struct ForwardIterator<'a, Parent: UniquePtrTarget, It: UniquePtrTarget> {
96 : #[doc(hidden)]
97 : pub it: cxx::UniquePtr<It>,
98 : _owner: PhantomData<&'a Parent>,
99 : }
100 :
101 : impl<'a, Parent: UniquePtrTarget, It: UniquePtrTarget> ForwardIterator<'a, Parent, It> {
102 : #[doc(hidden)]
103 996 : pub fn new(it: cxx::UniquePtr<It>) -> Self {
104 996 : Self {
105 996 : it,
106 996 : _owner: PhantomData,
107 996 : }
108 996 : }
109 : }
110 :
111 : #[doc(hidden)]
112 : #[macro_export]
113 : macro_rules! declare_fwd_iterator_conv {
114 : ($name:ident, $from:ty, $ffi:ty, $parent:ty, $ffi_iterator:ty, $conv: expr) => {
115 : pub type $name<'a> = $crate::common::ForwardIterator<'a, $parent, $ffi_iterator>;
116 : impl<'a> Iterator for $name<'a> {
117 : type Item = $from;
118 948624 : fn next(&mut self) -> Option<Self::Item> {
119 948624 : let next = self.it.as_mut().unwrap().next();
120 948624 : if next.is_null() {
121 996 : None
122 : } else {
123 947628 : Some($conv(next))
124 : }
125 948624 : }
126 :
127 0 : fn size_hint(&self) -> (usize, Option<usize>) {
128 0 : let hint = self.it.as_ref().unwrap().size().try_into().unwrap();
129 0 : (hint, Some(hint))
130 0 : }
131 : }
132 : };
133 : }
134 :
135 : #[doc(hidden)]
136 : #[macro_export]
137 : macro_rules! declare_fwd_iterator {
138 : ($name:ident, $from:ty, $ffi:ty, $parent:ty, $ffi_iterator:ty) => {
139 : $crate::declare_fwd_iterator_conv!($name, $from, $ffi, $parent, $ffi_iterator, |n| {
140 : Self::Item::from_ffi(n)
141 : });
142 : };
143 : }
144 :
145 : #[doc(hidden)]
146 : #[macro_export]
147 : macro_rules! declare_lazy_iterator_conv {
148 : ($name:ident, $from:ty, $ffi:ty, $parent:ty, $ffi_iterator:ty, $conv: expr) => {
149 : pub type $name<'a> = $crate::common::ForwardIterator<'a, $parent, $ffi_iterator>;
150 : impl<'a> Iterator for $name<'a> {
151 : type Item = $from;
152 0 : fn next(&mut self) -> Option<Self::Item> {
153 0 : let next = self.it.as_mut().unwrap().next();
154 0 : if next.is_null() {
155 0 : None
156 : } else {
157 0 : Some($conv(next))
158 : }
159 0 : }
160 : }
161 : };
162 : }
163 :
164 : #[doc(hidden)]
165 : #[macro_export]
166 : macro_rules! declare_lazy_iterator {
167 : ($name:ident, $from:ty, $ffi:ty, $parent:ty, $ffi_iterator:ty) => {
168 : $crate::declare_lazy_iterator_conv!($name, $from, $ffi, $parent, $ffi_iterator, |n| {
169 : Self::Item::from_ffi(n)
170 : });
171 : };
172 : }
173 :
174 :
175 : #[doc(hidden)]
176 : #[macro_export]
177 : macro_rules! to_slice {
178 : ($e:expr) => {
179 : let content_ptr = $e;
180 : unsafe {
181 : if content_ptr.size > 0 {
182 : return std::slice::from_raw_parts_mut(content_ptr.ptr, content_ptr.size as usize);
183 : }
184 : return &[];
185 : }
186 : };
187 : }
188 :
189 :
190 : #[doc(hidden)]
191 : #[macro_export]
192 : macro_rules! __to_result {
193 : ($func: expr, $self: expr, $conv: expr $(, $args:tt)*) => {
194 : let mut err: u32 = 0;
195 :
196 : let value = $func(&$self, $($args,)* std::pin::Pin::new(&mut err));
197 : if err > 0 {
198 : return Err($crate::Error::from(err));
199 : }
200 : return Ok($conv(value));
201 : };
202 : }
203 :
204 : #[doc(hidden)]
205 : #[macro_export]
206 : macro_rules! to_result {
207 : ($func: expr, $self: expr $(, $args:tt)*) => {
208 : $crate::__to_result!($func, $self.ptr, |x| x $(, $args)*)
209 : };
210 : }
211 :
212 : #[doc(hidden)]
213 : #[macro_export]
214 : macro_rules! to_conv_result {
215 : ($func: expr, $self: expr, $conv: expr $(, $args:tt)*) => {
216 : $crate::__to_result!($func, $self, $conv $(, $args)*)
217 : };
218 : }
219 :
220 :
221 : #[doc(hidden)]
222 : #[macro_export]
223 : macro_rules! __to_opt {
224 : ($func: expr, $self: expr, $conv: expr $(, $args:tt)*) => {
225 : let mut _is_set: u32 = 0;
226 :
227 : let value = $func(&$self, $($args,)* std::pin::Pin::new(&mut _is_set));
228 : if _is_set == 0 {
229 : return None;
230 : }
231 : return Some($conv(value.into()));
232 : };
233 : }
234 :
235 : #[doc(hidden)]
236 : #[macro_export]
237 : macro_rules! to_opt {
238 : ($func: expr, $self: expr $(, $args:tt)*) => {
239 : $crate::__to_opt!($func, $self.ptr, |x| x $(, $args)*)
240 : };
241 : }
242 :
243 : #[doc(hidden)]
244 : #[macro_export]
245 : macro_rules! to_conv_opt {
246 : ($func: expr, $self: expr, $conv: expr $(, $args:tt)*) => {
247 : $crate::__to_opt!($func, $self.ptr, $conv $(, $args)*)
248 : };
249 : }
250 :
251 : #[doc(hidden)]
252 : #[macro_export]
253 : macro_rules! to_opt_trait {
254 : ($func: expr, $self: expr $(, $args:tt)*) => {
255 : $crate::__to_opt!($func, $self, |x| x $(, $args)*)
256 : };
257 : }
258 :
259 : #[doc(hidden)]
260 : #[macro_export]
261 : macro_rules! to_opt_trait_conv {
262 : ($func: expr, $self: expr, $conv: expr $(, $args:tt)*) => {
263 : $crate::__to_opt!($func, $self, $conv $(, $args)*)
264 : };
265 : }
|