netlink_rust/core/
variant.rs

1use std::mem;
2use std::str;
3use std::io::{Read, Write, Error, ErrorKind};
4use std::ffi::{CString, CStr};
5use core::hardware_address::HardwareAddress;
6use ::errors::Result;
7
8use byteorder::{ByteOrder, NativeEndian, ReadBytesExt, WriteBytesExt};
9
10pub trait NativeRead: Sized {
11    fn read<R: Read>(reader: &mut R) -> Result<Self>;
12}
13
14pub trait NativeWrite: Sized {
15    fn write<W: Write>(&self, writer: &mut W) -> Result<()>;
16}
17
18pub trait NativeParse: Sized {
19    fn parse(buffer: &[u8]) -> Result<Self>;
20}
21
22pub trait MultiValue: Sized {
23    fn read<R: Read>(reader: &mut R, size: usize) -> Result<Self>;
24    fn write<W: Write>(&self, writer: &mut W) -> Result<()>;
25    fn size(&self) -> usize;
26}
27
28impl NativeRead for u8 {
29    fn read<R: Read>(reader: &mut R) -> Result<Self> {
30        Ok(reader.read_u8()?)
31    }
32}
33impl NativeWrite for u8 {
34    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
35        writer.write_u8(*self)?;
36        Ok(())
37    }
38}
39impl NativeParse for u8 {
40    fn parse(buffer: &[u8]) -> Result<Self> {
41        if buffer.len() < mem::size_of::<u8>() {
42            return Err(Error::new(ErrorKind::InvalidData, "").into());
43        }
44        Ok(buffer[0])
45    }
46}
47
48impl NativeRead for u16 {
49    fn read<R: Read>(reader: &mut R) -> Result<Self> {
50        Ok(reader.read_u16::<NativeEndian>()?)
51    }
52}
53impl NativeWrite for u16 {
54    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
55        writer.write_u16::<NativeEndian>(*self)?;
56        Ok(())
57    }
58}
59impl NativeParse for u16 {
60    fn parse(buffer: &[u8]) -> Result<Self> {
61        if buffer.len() < mem::size_of::<Self>() {
62            return Err(Error::new(ErrorKind::InvalidData, "").into());
63        }
64        Ok(NativeEndian::read_u16(buffer))
65    }
66}
67
68impl NativeRead for u32 {
69    fn read<R: Read>(reader: &mut R) -> Result<Self> {
70        Ok(reader.read_u32::<NativeEndian>()?)
71    }
72}
73impl NativeWrite for u32 {
74    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
75        writer.write_u32::<NativeEndian>(*self)?;
76        Ok(())
77    }
78}
79impl NativeParse for u32 {
80    fn parse(buffer: &[u8]) -> Result<Self> {
81        if buffer.len() < mem::size_of::<Self>() {
82            return Err(Error::new(ErrorKind::InvalidData, "").into());
83        }
84        Ok(NativeEndian::read_u32(buffer))
85    }
86}
87
88impl NativeRead for u64 {
89    fn read<R: Read>(reader: &mut R) -> Result<Self> {
90        Ok(reader.read_u64::<NativeEndian>()?)
91    }
92}
93impl NativeWrite for u64 {
94    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
95        writer.write_u64::<NativeEndian>(*self)?;
96        Ok(())
97    }
98}
99impl NativeParse for u64 {
100    fn parse(buffer: &[u8]) -> Result<Self> {
101        if buffer.len() < mem::size_of::<Self>() {
102            return Err(Error::new(ErrorKind::InvalidData, "").into());
103        }
104        Ok(NativeEndian::read_u64(buffer))
105    }
106}
107
108impl NativeRead for i8 {
109    fn read<R: Read>(reader: &mut R) -> Result<Self> {
110        Ok(reader.read_i8()?)
111    }
112}
113impl NativeWrite for i8 {
114    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
115        writer.write_i8(*self)?;
116        Ok(())
117    }
118}
119impl NativeParse for i8 {
120    fn parse(buffer: &[u8]) -> Result<Self> {
121        if buffer.len() < mem::size_of::<Self>() {
122            return Err(Error::new(ErrorKind::InvalidData, "").into());
123        }
124        Ok(buffer[0] as i8)
125    }
126}
127
128impl NativeRead for i16 {
129    fn read<R: Read>(reader: &mut R) -> Result<Self> {
130        Ok(reader.read_i16::<NativeEndian>()?)
131    }
132}
133impl NativeWrite for i16 {
134    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
135        writer.write_i16::<NativeEndian>(*self)?;
136        Ok(())
137    }
138}
139impl NativeParse for i16 {
140    fn parse(buffer: &[u8]) -> Result<Self> {
141        if buffer.len() < mem::size_of::<Self>() {
142            return Err(Error::new(ErrorKind::InvalidData, "").into());
143        }
144        Ok(NativeEndian::read_i16(buffer))
145    }
146}
147
148impl NativeRead for i32 {
149    fn read<R: Read>(reader: &mut R) -> Result<Self> {
150        Ok(reader.read_i32::<NativeEndian>()?)
151    }
152}
153impl NativeWrite for i32 {
154    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
155        writer.write_i32::<NativeEndian>(*self)?;
156        Ok(())
157    }
158}
159impl NativeParse for i32 {
160    fn parse(buffer: &[u8]) -> Result<Self> {
161        if buffer.len() < mem::size_of::<Self>() {
162            return Err(Error::new(ErrorKind::InvalidData, "").into());
163        }
164        Ok(NativeEndian::read_i32(buffer))
165    }
166}
167
168impl NativeRead for i64 {
169    fn read<R: Read>(reader: &mut R) -> Result<Self> {
170        Ok(reader.read_i64::<NativeEndian>()?)
171    }
172}
173impl NativeWrite for i64 {
174    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
175        writer.write_i64::<NativeEndian>(*self)?;
176        Ok(())
177    }
178}
179impl NativeParse for i64 {
180    fn parse(buffer: &[u8]) -> Result<Self> {
181        if buffer.len() < mem::size_of::<Self>() {
182            return Err(Error::new(ErrorKind::InvalidData, "").into());
183        }
184        Ok(NativeEndian::read_i64(buffer))
185    }
186}
187
188impl NativeRead for f32 {
189    fn read<R: Read>(reader: &mut R) -> Result<Self> {
190        Ok(reader.read_f32::<NativeEndian>()?)
191    }
192}
193impl NativeWrite for f32 {
194    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
195        writer.write_f32::<NativeEndian>(*self)?;
196        Ok(())
197    }
198}
199impl NativeParse for f32 {
200    fn parse(buffer: &[u8]) -> Result<Self> {
201        if buffer.len() < mem::size_of::<Self>() {
202            return Err(Error::new(ErrorKind::InvalidData, "").into());
203        }
204        Ok(NativeEndian::read_f32(buffer))
205    }
206}
207
208impl NativeRead for f64 {
209    fn read<R: Read>(reader: &mut R) -> Result<Self> {
210        Ok(reader.read_f64::<NativeEndian>()?)
211    }
212}
213impl NativeWrite for f64 {
214    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
215        writer.write_f64::<NativeEndian>(*self)?;
216        Ok(())
217    }
218}
219impl NativeParse for f64 {
220    fn parse(buffer: &[u8]) -> Result<Self> {
221        if buffer.len() < mem::size_of::<Self>() {
222            return Err(Error::new(ErrorKind::InvalidData, "").into());
223        }
224        Ok(NativeEndian::read_f64(buffer))
225    }
226}
227
228impl NativeRead for HardwareAddress {
229    fn read<R: Read>(reader: &mut R) -> Result<Self> {
230        let mut data = vec![0u8; 6];
231        reader.read_exact(&mut data)?;
232        Ok(HardwareAddress::from(data.as_slice()))
233    }
234}
235impl NativeWrite for HardwareAddress {
236    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
237        writer.write(&self.bytes())?;
238        Ok(())
239    }
240}
241impl NativeParse for HardwareAddress {
242    fn parse(buffer: &[u8]) -> Result<Self> {
243        if buffer.len() < mem::size_of::<Self>() {
244            return Err(Error::new(ErrorKind::InvalidData, "").into());
245        }
246        Ok(HardwareAddress::from(&buffer[0..6]))
247    }
248}
249
250impl MultiValue for String {
251    fn read<R: Read>(reader: &mut R, size: usize) -> Result<Self> {
252        let mut data = vec![0u8; size];
253        reader.read_exact(&mut data)?;
254        match CStr::from_bytes_with_nul(&data) {
255            Ok(bytes) => {
256                let s = bytes.to_str()?;
257                Ok(String::from(s))
258            },
259            Err(_) => {
260                let s = str::from_utf8(&data)?;
261                Ok(String::from(s))
262            }
263        }
264    }
265    
266    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
267        let c_string = CString::new((*self).clone())?;
268        let bytes = c_string.into_bytes_with_nul();
269        writer.write(&bytes)?;
270        Ok(())
271    }
272
273    fn size(&self) -> usize {
274        self.len() + 1
275    }
276}
277
278
279#[cfg(test)]
280mod tests {
281    use std::io;
282    use super::*;
283    use std::fmt;
284    use std::cmp;
285
286    fn read_write_test<T: NativeRead + NativeWrite + NativeParse + fmt::Debug + cmp::PartialEq>(bytes: &[u8], value: T) {
287        let value_size = mem::size_of::<T>();
288        assert_eq!(bytes.len(), mem::size_of::<T>());
289        let mut reader = io::Cursor::new(bytes);
290        assert_eq!(T::read(&mut reader).unwrap(), value);
291        let mut writer = io::Cursor::new(vec![0u8; value_size]);
292        value.write(&mut writer).unwrap();
293        assert_eq!(writer.into_inner(), Vec::from(bytes));
294        assert_eq!(T::parse(bytes).unwrap(), value);
295    }
296
297    #[test]
298    fn read_write_u8() {
299        read_write_test(&[0x5a], 0x5au8);
300    }
301
302    #[test]
303    fn read_write_i8() {
304        read_write_test(&[0xa5], -91i8);
305    }
306
307    #[test]
308    fn read_write_u16() {
309        read_write_test(&[0x22, 0xaa], 0xaa22u16.to_le());
310    }
311
312    #[test]
313    fn read_write_u32() {
314        read_write_test(&[0x44, 0x33, 0x22, 0x11], 0x11223344u32.to_le());
315    }
316
317    #[test]
318    fn read_write_u64() {
319        read_write_test(&[0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11],
320            0x1122334455667788u64.to_le());
321    }
322
323    #[test]
324    fn read_write_i16() {
325        read_write_test(&[0x55, 0xaa], (-21931i16).to_le());
326    }
327
328    #[test]
329    fn read_write_i32() {
330        read_write_test(&[0x11, 0x22, 0x33, 0xa4], (-1540152815i32).to_le());
331    }
332
333    #[test]
334    fn read_write_i64() {
335        read_write_test(&[0x11, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x88],
336            (-8637284766759618799i64).to_le());
337    }
338
339    #[test]
340    fn read_write_hardware_address() {
341        let bytes = vec![0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff];
342        let hwa = HardwareAddress::from(bytes.as_slice());
343        read_write_test(bytes.as_slice(), hwa);
344    }
345
346    #[test]
347    fn read_string() {
348        let bytes = vec![0xf0, 0x9f, 0x9b, 0xa0];
349        let mut reader = io::Cursor::new(bytes);
350        assert_eq!(String::read(&mut reader, 4).unwrap(), String::from("🛠"));
351
352        let bytes = vec![0xf0, 0x9f, 0x9b, 0xa0, 0x00];
353        let mut reader = io::Cursor::new(bytes);
354        assert_eq!(String::read(&mut reader, 5).unwrap(), String::from("🛠"));
355
356        let bytes = vec![0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x00];
357        let mut reader = io::Cursor::new(bytes);
358        assert_eq!(String::read(&mut reader, 6).unwrap(),
359            String::from("Hello"));
360        
361        let bytes = vec![0x48, 0x65, 0x6c, 0x6c, 0x6f];
362        let mut reader = io::Cursor::new(bytes);
363        assert_eq!(String::read(&mut reader, 5).unwrap(),
364            String::from("Hello"));
365
366        // Could this be an issue?
367        let bytes = vec![0x48, 0x65, 0x6c, 0x6c, 0x6f,
368            0x00, 0x00, 0x00, 0x00, 0x00];
369        let mut reader = io::Cursor::new(bytes);
370        assert_eq!(String::read(&mut reader, 10).unwrap(),
371            String::from("Hello\0\0\0\0\0"));
372    }
373
374    #[test]
375    fn write_string() {
376        let string = String::from("🛠");
377        let mut writer = io::Cursor::new(vec![0u8; 4]);
378        string.write(&mut writer).unwrap();
379        assert_eq!(writer.into_inner(), vec![0xf0, 0x9f, 0x9b, 0xa0, 0x00]);
380
381        let string = String::from("Hello");
382        let mut writer = io::Cursor::new(vec![0u8; 5]);
383        string.write(&mut writer).unwrap();
384        assert_eq!(writer.into_inner(), vec![0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x00]);
385    }
386}
387
388#[cfg(all(test, target_endian = "little"))]
389mod tests_le {
390    // Little endian specific tests
391    use std::io;
392    use super::*;
393
394    #[test]
395    fn read_f32() {
396        let bytes = vec![82, 15, 73, 192];
397        let mut reader = io::Cursor::new(bytes);
398        assert_eq!(f32::read(&mut reader).unwrap(), -3.14156);
399    }
400
401    #[test]
402    fn read_f64() {
403        let bytes = vec![105, 87, 20, 139, 10, 191, 5, 192];
404        let mut reader = io::Cursor::new(bytes);
405        assert_eq!(f64::read(&mut reader).unwrap(), -2.718281828459045);
406    }
407
408    #[test]
409    fn write_f32() {
410        let mut writer = io::Cursor::new(vec![0u8; 4]);
411        (-3.14156f32).write(&mut writer).unwrap();
412        assert_eq!(writer.into_inner(), vec![82, 15, 73, 192]);
413    }
414
415    #[test]
416    fn write_f64() {
417        let mut writer = io::Cursor::new(vec![0u8; 8]);
418        (-2.718281828459045f64).write(&mut writer).unwrap();
419        assert_eq!(writer.into_inner(), vec![105, 87, 20, 139, 10, 191, 5, 192]);
420    }
421}