Line data Source code
1 : use cxx::memory::UniquePtrTarget;
2 : use lief_ffi as ffi;
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 3561480 : pub fn into_optional<T: FromFFI<U>, U: UniquePtrTarget>(raw_ffi: cxx::UniquePtr<U>) -> Option<T> {
22 3561480 : if raw_ffi.is_null() {
23 1579240 : None
24 : } else {
25 1982240 : Some(T::from_ffi(raw_ffi))
26 : }
27 3561480 : }
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 463637 : pub fn new(it: cxx::UniquePtr<It>) -> Self {
54 463637 : Self {
55 463637 : it,
56 463637 : _owner: PhantomData,
57 463637 : }
58 463637 : }
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 6712147 : fn next(&mut self) -> Option<Self::Item> {
69 6712147 : let next = self.it.as_mut().unwrap().next();
70 6712147 : if next.is_null() {
71 463073 : None
72 : } else {
73 6249074 : Some($conv(next))
74 : }
75 6712147 : }
76 : }
77 : impl<'a> ExactSizeIterator for $name<'a> {
78 4355 : fn len(&self) -> usize {
79 4355 : self.it.as_ref().unwrap().size().try_into().unwrap()
80 4355 : }
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 1222 : pub fn new(it: cxx::UniquePtr<It>) -> Self {
104 1222 : Self {
105 1222 : it,
106 1222 : _owner: PhantomData,
107 1222 : }
108 1222 : }
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 1037686 : fn next(&mut self) -> Option<Self::Item> {
119 1037686 : let next = self.it.as_mut().unwrap().next();
120 1037686 : if next.is_null() {
121 1222 : None
122 : } else {
123 1036464 : Some($conv(next))
124 : }
125 1037686 : }
126 :
127 52 : fn size_hint(&self) -> (usize, Option<usize>) {
128 52 : let hint = self.it.as_ref().unwrap().size().try_into().unwrap();
129 52 : (hint, Some(hint))
130 52 : }
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 : #[doc(hidden)]
175 : #[macro_export]
176 : macro_rules! to_slice {
177 : ($e:expr) => {
178 : let content_ptr = $e;
179 : unsafe {
180 : if content_ptr.size > 0 {
181 : return std::slice::from_raw_parts_mut(content_ptr.ptr, content_ptr.size as usize);
182 : }
183 : return &[];
184 : }
185 : };
186 : }
187 :
188 : #[doc(hidden)]
189 : #[macro_export]
190 : macro_rules! __to_result {
191 : ($func: expr, $self: expr, $conv: expr $(, $args:tt)*) => {
192 : let mut err: u32 = 0;
193 :
194 : let value = $func($self, $($args,)* std::pin::Pin::new(&mut err));
195 : if err > 0 {
196 : return Err($crate::Error::from(err));
197 : }
198 : return Ok($conv(value));
199 : };
200 : }
201 :
202 : #[doc(hidden)]
203 : #[macro_export]
204 : macro_rules! to_result {
205 : ($func: expr, $self: expr $(, $args:tt)*) => {
206 : $crate::__to_result!($func, &$self.ptr, |x| x $(, $args)*)
207 : };
208 : }
209 :
210 : #[doc(hidden)]
211 : #[macro_export]
212 : macro_rules! to_conv_result {
213 : ($func: expr, $self: expr, $conv: expr $(, $args:tt)*) => {
214 : $crate::__to_result!($func, $self, $conv $(, $args)*)
215 : };
216 : }
217 :
218 : #[doc(hidden)]
219 : #[macro_export]
220 : macro_rules! __to_opt {
221 : ($func: expr, $self: expr, $conv: expr $(, $args:tt)*) => {
222 : let mut _is_set: u32 = 0;
223 :
224 : let value = $func(&$self, $($args,)* std::pin::Pin::new(&mut _is_set));
225 : if _is_set == 0 {
226 : return None;
227 : }
228 : return Some($conv(value.into()));
229 : };
230 : }
231 :
232 : #[doc(hidden)]
233 : #[macro_export]
234 : macro_rules! to_opt {
235 : ($func: expr, $self: expr $(, $args:tt)*) => {
236 : $crate::__to_opt!($func, $self.ptr, |x| x $(, $args)*)
237 : };
238 : }
239 :
240 : #[doc(hidden)]
241 : #[macro_export]
242 : macro_rules! to_conv_opt {
243 : ($func: expr, $self: expr, $conv: expr $(, $args:tt)*) => {
244 : $crate::__to_opt!($func, $self.ptr, $conv $(, $args)*)
245 : };
246 : }
247 :
248 : #[doc(hidden)]
249 : #[macro_export]
250 : macro_rules! to_opt_trait {
251 : ($func: expr, $self: expr $(, $args:tt)*) => {
252 : $crate::__to_opt!($func, $self, |x| x $(, $args)*)
253 : };
254 : }
255 :
256 : #[doc(hidden)]
257 : #[macro_export]
258 : macro_rules! to_opt_trait_conv {
259 : ($func: expr, $self: expr, $conv: expr $(, $args:tt)*) => {
260 : $crate::__to_opt!($func, $self, $conv $(, $args)*)
261 : };
262 : }
|