browser_window_core/cookie/
c.rs1use super::*;
2
3use std::{
4 borrow::Cow,
5 ffi::c_void,
6 ops::Add,
7 os::raw::c_uint,
8 mem::MaybeUninit,
9 ptr,
10 time::{Duration, SystemTime}
11};
12
13use browser_window_c::*;
14
15
16
17pub struct CookieImpl {
18 pub(in crate) inner: *mut cbw_Cookie
19}
20
21pub struct CookieMutImpl (CookieImpl);
22
23pub struct CookieJarImpl {
24 pub(in crate) inner: *mut cbw_CookieJar
25}
26
27pub struct CookieIteratorImpl {
28 pub(in crate) inner: *mut cbw_CookieIterator
29}
30
31struct CookieStorageCallbackData {
32 callback: CookieStorageCallbackFn,
33 data: *mut ()
34}
35
36struct CookieDeleteCallbackData {
37 callback: CookieDeleteCallbackFn,
38 data: *mut ()
39}
40
41struct CookieIteratorNextCallbackData {
42 callback: CookieIteratorNextCallbackFn,
43 data: *mut ()
44}
45
46
47
48impl CookieExt for CookieImpl {
49
50 fn creation_time(&self) -> SystemTime {
51 let timestamp = unsafe { cbw_Cookie_getCreationTime(self.inner) };
52
53 SystemTime::UNIX_EPOCH.add(Duration::from_millis(timestamp))
54 }
55
56 fn expires(&self) -> Option<SystemTime> {
57 let timestamp = unsafe { cbw_Cookie_getExpires(self.inner) };
58
59 if timestamp != 0 {
60 Some( SystemTime::UNIX_EPOCH.add(Duration::from_millis(timestamp)) )
61 }
62 else {
63 None
64 }
65 }
66
67 fn domain<'a>(&'a self) -> Cow<'a, str> {
68 let mut slice: cbw_StrSlice = unsafe { MaybeUninit::uninit().assume_init() };
69 let owned = unsafe { cbw_Cookie_getDomain(self.inner, &mut slice) };
70
71 if owned > 0 {
72 let string: String = slice.into();
73 unsafe { cbw_string_free(slice) };
74 string.into()
75 }
76 else {
77 let string: &str = slice.into();
78 string.into()
79 }
80 }
81
82 fn free(&mut self) {
83 unsafe { cbw_Cookie_free(self.inner) };
84 }
85
86 fn is_http_only(&self) -> bool {
87 (unsafe { cbw_Cookie_isHttpOnly(self.inner) }) > 0
88 }
89
90 fn is_secure(&self) -> bool {
91 (unsafe { cbw_Cookie_isSecure(self.inner) }) > 0
92 }
93
94 fn name<'a>(&'a self) -> Cow<'a, str> {
95 let mut slice: cbw_StrSlice = unsafe { MaybeUninit::uninit().assume_init() };
96 let owned = unsafe { cbw_Cookie_getName(self.inner, &mut slice) };
97
98 if owned > 0 {
99 let string: String = slice.into();
100 unsafe { cbw_string_free(slice) };
101 string.into()
102 }
103 else {
104 let string: &str = slice.into();
105 string.into()
106 }
107 }
108
109 fn new(name: &str, value: &str) -> Self {
110 let inner = unsafe { cbw_Cookie_new(name.into(), value.into()) };
111
112 Self { inner }
113 }
114
115 fn path<'a>(&'a self) -> Cow<'a, str> {
116 let mut slice: cbw_StrSlice = unsafe { MaybeUninit::uninit().assume_init() };
117 let owned = unsafe { cbw_Cookie_getPath(self.inner, &mut slice) };
118
119 if owned > 0 {
120 let string: String = slice.into();
121 unsafe { cbw_string_free(slice) };
122 string.into()
123 }
124 else {
125 let string: &str = slice.into();
126 string.into()
127 }
128 }
129
130 fn value<'a>(&'a self) -> Cow<'a, str> {
131 let mut slice: cbw_StrSlice = unsafe { MaybeUninit::uninit().assume_init() };
132
133 let owned = unsafe { cbw_Cookie_getValue(self.inner, &mut slice) };
134
135 if owned > 0 {
136 let string: String = slice.into();
137 unsafe { cbw_string_free(slice) };
138 string.into()
139 }
140 else {
141 let string: &str = slice.into();
142 string.into()
143 }
144 }
145
146 fn make_http_only(&mut self) -> &mut Self {
147 unsafe { cbw_Cookie_makeHttpOnly(self.inner) }; self
148 }
149
150 fn make_secure(&mut self) -> &mut Self {
151 unsafe { cbw_Cookie_makeSecure(self.inner) }; self
152 }
153
154 fn set_creation_time(&mut self, time: &SystemTime) -> &mut Self {
155 unsafe { cbw_Cookie_setCreationTime(self.inner, time.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis() as _) }; self
156 }
157
158 fn set_expires(&mut self, time: &SystemTime) -> &mut Self {
159 unsafe { cbw_Cookie_setExpires(self.inner, time.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis() as _) }; self
160 }
161
162 fn set_domain(&mut self, domain: &str) -> &mut Self {
163 unsafe { cbw_Cookie_setDomain(self.inner, domain.into()) }; self
164 }
165
166 fn set_name(&mut self, name: &str) -> &mut Self {
167 unsafe { cbw_Cookie_setName(self.inner, name.into()) }; self
168 }
169
170
171 fn set_path(&mut self, path: &str) -> &mut Self {
172 unsafe { cbw_Cookie_setPath(self.inner, path.into()) }; self
173 }
174
175 fn set_value(&mut self, value: &str) -> &mut Self{
176 unsafe { cbw_Cookie_setValue(self.inner, value.into()) }; self
177 }
178}
179
180impl CookieJarExt for CookieJarImpl {
181
182 fn delete(&mut self, url: &str, name: &str, complete_cb: CookieDeleteCallbackFn, cb_data: *mut ()) {
183 let data = Box::into_raw(Box::new(CookieDeleteCallbackData {
184 callback: complete_cb,
185 data: cb_data
186 }));
187
188 unsafe { cbw_CookieJar_delete(self.inner, url.into(), name.into(), Some(ffi_cookie_delete_callback_handler), data as _ ) };
189 }
190
191 fn free(&mut self) {
192 unsafe { cbw_CookieJar_free(self.inner) };
193 }
194
195 fn global() -> CookieJarImpl {
196 let inner = unsafe { cbw_CookieJar_newGlobal() };
197
198 CookieJarImpl {
199 inner
200 }
201 }
202
203 fn iterator<'a>(&'a self, url: &str, include_http_only: bool) -> CookieIteratorImpl {
204 let mut iterator: CookieIteratorImpl = unsafe { MaybeUninit::uninit().assume_init() };
205 unsafe { cbw_CookieJar_iterator(self.inner, &mut iterator.inner, if include_http_only {1} else {0}, url.into()) };
206
207 return iterator;
208 }
209
210 fn iterator_all<'a>(&'a self) -> CookieIteratorImpl {
211 let mut iterator: CookieIteratorImpl = unsafe { MaybeUninit::uninit().assume_init() };
212 unsafe { cbw_CookieJar_iteratorAll(self.inner, &mut iterator.inner) };
213
214 return iterator;
215 }
216
217 fn store(&mut self, url: &str, cookie: &CookieImpl, complete_cb: Option<CookieStorageCallbackFn>, cb_data: *mut ()) {
218 let data = if !complete_cb.is_none() {
219 Box::into_raw( Box::new( CookieStorageCallbackData {
220 callback: complete_cb.unwrap(),
221 data: cb_data
222 }))
223 }
224 else {
225 ptr::null_mut()
226 };
227
228 unsafe {
229 let mut error = cbw_CookieJar_store(
230 self.inner,
231 url.into(),
232 cookie.inner,
233 complete_cb.map(|_| ffi_cookie_storage_callback_handler as _),
234 data as _
235 );
236
237 if error.code != 0 && !complete_cb.is_none() {
238 (complete_cb.unwrap())(CookieJarImpl {inner: self.inner}, cb_data, Err(CookieStorageError::Unknown));
239 }
240
241 cbw_Err_free(&mut error);
242 }
243 }
244}
245
246impl CookieIteratorExt for CookieIteratorImpl {
247 fn free(&mut self) {
248 unsafe { cbw_CookieIterator_free(self.inner) }
249 }
250
251 fn next(&mut self, on_next: CookieIteratorNextCallbackFn, cb_data: *mut ()) -> bool {
252 let data = Box::into_raw(Box::new(CookieIteratorNextCallbackData {
253 callback: on_next,
254 data: cb_data
255 }));
256
257 let success = unsafe { cbw_CookieIterator_next(self.inner, Some(ffi_cookie_iterator_next_handler), data as _) };
258
259 return success > 0;
260 }
261}
262
263
264
265
266unsafe extern "C" fn ffi_cookie_storage_callback_handler(cookie_jar: *mut cbw_CookieJar, _data: *mut c_void, error: cbw_Err) {
267
268 let data_ptr = _data as *mut CookieStorageCallbackData;
269 let data: Box<CookieStorageCallbackData> = Box::from_raw( data_ptr );
270
271 let handle = CookieJarImpl {inner: cookie_jar};
272 let result = if error.code == 0 {
273 Ok(())
274 }
275 else {
276 Err(CookieStorageError::Unknown)
277 };
278
279 (data.callback)( handle, data.data, result );
280}
281
282unsafe extern "C" fn ffi_cookie_delete_callback_handler(cookie_jar: *mut cbw_CookieJar, _data: *mut c_void, deleted: c_uint) {
283
284 let data_ptr = _data as *mut CookieDeleteCallbackData;
285 let data: Box<CookieDeleteCallbackData> = Box::from_raw( data_ptr );
286
287 let handle = CookieJarImpl {inner: cookie_jar};
288
289 (data.callback)( handle, data.data, deleted as _ );
290}
291
292unsafe extern "C" fn ffi_cookie_iterator_next_handler(cookie_iterator: *mut cbw_CookieIterator, _data: *mut c_void, _cookie: *mut cbw_Cookie) {
293 let data_ptr = _data as *mut CookieIteratorNextCallbackData;
294 let data: Box<CookieIteratorNextCallbackData> = Box::from_raw(data_ptr);
295
296 let handle = CookieIteratorImpl {inner: cookie_iterator};
297 let cookie = if _cookie == ptr::null_mut() {
298 None
299 }
300 else {
301 Some(CookieImpl {inner: _cookie})
302 };
303
304 (data.callback)(handle, data.data, cookie);
305}