browser_window_core/cookie/
c.rs

1use 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}