1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
pub mod error;
pub mod fd;
pub mod net;
pub mod time;
use nss_sys::nspr as ffi;
use std::marker::PhantomData;
use std::sync::{Once, ONCE_INIT};
use GenStatus;
pub use self::fd::File;
pub fn init() {
static PR_INIT_ONCE: Once = ONCE_INIT;
PR_INIT_ONCE.call_once(|| {
unsafe {
ffi::PR_Init(ffi::PR_SYSTEM_THREAD, ffi::PR_PRIORITY_NORMAL, 0);
}
});
}
impl From<ffi::PRStatus> for GenStatus<()> {
fn from(status: ffi::PRStatus) -> Self {
match status {
ffi::PR_SUCCESS => GenStatus::Success(()),
ffi::PR_FAILURE => GenStatus::ErrorFromC,
}
}
}
impl From<i32> for GenStatus<usize> {
fn from(rv: i32) -> Self {
if rv >= 0 {
GenStatus::Success(rv as usize)
} else {
GenStatus::ErrorFromC
}
}
}
pub fn bool_from_nspr(b: ffi::PRBool) -> bool {
match b {
ffi::PR_FALSE => false,
ffi::PR_TRUE => true,
_ => unreachable!(),
}
}
pub fn bool_to_nspr(b: bool) -> ffi::PRBool {
if b {
ffi::PR_TRUE
} else {
ffi::PR_FALSE
}
}
pub type ListNode = *mut ffi::PRCList;
pub trait Listable {
unsafe fn from_list_node(node: ListNode) -> Self;
}
#[derive(Clone, Debug)]
pub struct ListIterator<'l, L: Listable + 'l> {
next: ListNode,
end: ListNode,
phantom: PhantomData<&'l [L]>,
}
impl<'l, L: Listable + 'l> ListIterator<'l, L> {
pub unsafe fn new(list: ListNode) -> Self {
ListIterator {
next: (*list).next,
end: list,
phantom: PhantomData,
}
}
}
impl<'l, L: Listable + 'l> Iterator for ListIterator<'l, L> {
type Item = L;
fn next(&mut self) -> Option<L> {
if self.next == self.end {
None
} else {
unsafe {
let next = self.next;
self.next = (*next).next;
Some(Listable::from_list_node(next))
}
}
}
}
impl<'l, L: Listable + 'l> DoubleEndedIterator for ListIterator<'l, L> {
fn next_back(&mut self) -> Option<L> {
if self.next == self.end {
None
} else {
unsafe {
let prev = (*self.end).prev;
self.end = prev;
Some(Listable::from_list_node(prev))
}
}
}
}