1use std::time::Duration;
2
3use libc::c_int;
4use sys::*;
5use error::{self, Error};
6
7pub struct Handle {
9 ptr: *mut hid_device,
10}
11
12impl Handle {
13 #[doc(hidden)]
14 pub unsafe fn new(ptr: *mut hid_device) -> Self {
15 Handle {
16 ptr: ptr,
17 }
18 }
19
20 #[doc(hidden)]
21 pub unsafe fn as_ptr(&self) -> *const hid_device {
22 self.ptr as *const _
23 }
24
25 #[doc(hidden)]
26 pub unsafe fn as_mut_ptr(&mut self) -> *mut hid_device {
27 self.ptr
28 }
29}
30
31impl Handle {
32 pub fn blocking(&mut self, value: bool) -> error::Result<&mut Self> {
34 unsafe {
35 match hid_set_nonblocking(self.as_mut_ptr(), if value { 1 } else { 0 }) {
36 0 =>
37 Ok(self),
38
39 _ =>
40 Err(Error::General)
41 }
42 }
43 }
44
45 pub fn data(&mut self) -> Data {
47 unsafe {
48 Data::new(self)
49 }
50 }
51
52 pub fn feature(&mut self) -> Feature {
54 unsafe {
55 Feature::new(self)
56 }
57 }
58}
59
60pub struct Data<'a> {
62 handle: &'a mut Handle,
63}
64
65impl<'a> Data<'a> {
66 #[doc(hidden)]
67 pub unsafe fn new(handle: &mut Handle) -> Data {
68 Data { handle: handle }
69 }
70
71 pub fn write<T: AsRef<[u8]>>(&mut self, data: T) -> error::Result<usize> {
75 let data = data.as_ref();
76
77 unsafe {
78 match hid_write(self.handle.as_mut_ptr(), data.as_ptr(), data.len()) {
79 -1 =>
80 Err(Error::Write),
81
82 length =>
83 Ok(length as usize)
84 }
85 }
86 }
87
88 pub fn write_to<T: AsRef<[u8]>>(&mut self, id: u8, data: T) -> error::Result<usize> {
90 let data = data.as_ref();
91 let mut buffer = vec![0u8; data.len() + 1];
92
93 buffer[0] = id;
94 (&mut buffer[1 ..]).copy_from_slice(data);
95
96 self.write(&buffer)
97 }
98
99 pub fn read<T: AsMut<[u8]>>(&mut self, mut data: T, timeout: Duration) -> error::Result<Option<usize>> {
105 let data = data.as_mut();
106 let result = if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
107 unsafe {
108 hid_read(self.handle.as_mut_ptr(), data.as_mut_ptr(), data.len())
109 }
110 }
111 else {
112 unsafe {
113 hid_read_timeout(self.handle.as_mut_ptr(), data.as_mut_ptr(), data.len(),
115 timeout.as_secs() as c_int * 1_000 + timeout.subsec_nanos() as c_int / 1_000_000)
116 }
117 };
118
119 match result {
120 -1 =>
121 Err(Error::Read),
122
123 0 =>
124 Ok(None),
125
126 v =>
127 Ok(Some(v as usize))
128 }
129 }
130
131 pub fn read_from<T: AsMut<[u8]>>(&mut self, mut data: T, timeout: Duration) -> error::Result<Option<(u8, usize)>> {
135 let data = data.as_mut();
136 let mut buffer = Vec::with_capacity(data.len() + 1);
137
138 if let Some(length) = self.read(&mut buffer, timeout)? {
139 data[0..length - 1].copy_from_slice(&buffer[1..length]);
140
141 Ok(Some((buffer[0], length - 1)))
142 }
143 else {
144 Ok(None)
145 }
146 }
147}
148
149pub struct Feature<'a> {
151 handle: &'a mut Handle,
152}
153
154impl<'a> Feature<'a> {
155 #[doc(hidden)]
156 pub unsafe fn new(handle: &mut Handle) -> Feature {
157 Feature { handle: handle }
158 }
159
160 pub fn send<T: AsRef<[u8]>>(&mut self, data: T) -> error::Result<usize> {
164 let data = data.as_ref();
165
166 unsafe {
167 match hid_send_feature_report(self.handle.as_mut_ptr(), data.as_ptr(), data.len()) {
168 -1 =>
169 Err(Error::Write),
170
171 length =>
172 Ok(length as usize)
173 }
174 }
175 }
176
177 pub fn send_to<T: AsRef<[u8]>>(&mut self, id: u8, data: T) -> error::Result<usize> {
179 let data = data.as_ref();
180 let mut buffer = Vec::with_capacity(data.len() + 1);
181
182 buffer.push(id);
183 buffer.extend(data);
184
185 self.send(&buffer).map(|v| v - 1)
186 }
187
188 pub fn get<T: AsMut<[u8]>>(&mut self, mut data: T) -> error::Result<usize> {
192 let data = data.as_mut();
193
194 unsafe {
195 match hid_get_feature_report(self.handle.as_mut_ptr(), data.as_mut_ptr(), data.len()) {
196 -1 =>
197 Err(Error::Read),
198
199 length =>
200 Ok(length as usize)
201 }
202 }
203 }
204
205 pub fn get_from<T: AsMut<[u8]>>(&mut self, id: u8, mut data: T) -> error::Result<usize> {
207 let data = data.as_mut();
208 let mut buffer = vec![0u8; data.len() + 1];
209 buffer[0] = id;
210
211 let length = self.get(&mut buffer)?;
212 data[0..length - 1].copy_from_slice(&buffer[1..length]);
213
214 Ok(length - 1)
215 }
216}
217
218impl Drop for Handle {
219 fn drop(&mut self) {
220 unsafe {
221 hid_close(self.as_mut_ptr());
222 }
223 }
224}