How to do it...

  1. If you haven't done it already in the last chapter, open the Cargo.toml file that was generated earlier for you.

  2. Under [dependencies], add the following line:
byteorder = "1.1.0"
  1. If you want, you can go to byteorder's crates.io page (https://crates.io/crates/byteorder) to check for the newest version and use that one instead.
  2. In the bin folder, create a file called binary_files.rs.

  3. Add the following code and run it with cargo run --bin binary_files:

1    extern crate byteorder;
2 use byteorder::{ByteOrder, ReadBytesExt, WriteBytesExt, BE,
LE};
3 use std::fs::File;
4 use std::io::{self, BufReader, BufWriter, Read};
5 use std::io::prelude::*;
6
7
8 fn main() {
9 let path = "./bar.bin";
10 write_dummy_protocol(path).expect("Failed write file");
11 let payload = read_protocol(path).expect("Failed to read
file");
12 print!("The protocol contained the following payload: ");
13 for num in payload {
14 print!("0x{:X} ", num);
15 }
16 println!();
17 }
  1. Create a binary file:
19    // Write a simple custom protocol
20 fn write_dummy_protocol(path: &str) -> io::Result<()> {
21 let file = File::create(path)?;
22 let mut buf_writer = BufWriter::new(file);
23
24 // Let's say our binary file starts with a magic string
25 // to show readers that this is our protocoll
26 let magic = b"MyProtocol";
27 buf_writer.write_all(magic)?;
28
29 // Now comes another magic value to indicate
30 // our endianness
31 let endianness = b"LE";
32 buf_writer.write_all(endianness)?;
33
34 // Let's fill it with two numbers in u32
35 buf_writer.write_u32::<LE>(0xDEAD)?;
36 buf_writer.write_u32::<LE>(0xBEEF)?;
37
38 Ok(())
39 }
  1. Read and parse the file:
42   fn read_protocol(path: &str) -> io::Result<Vec<u32>> {
43 let file = File::open(path)?;
44 let mut buf_reader = BufReader::new(file);
45
46 // Our protocol has to begin with a certain string
47 // Namely "MyProtocol", which is 10 bytes long
48 let mut start = [0u8; 10];
49 buf_reader.read_exact(&mut start)?;
50 if &start != b"MyProtocol" {
51 return Err(io::Error::new(
52 io::ErrorKind::Other,
53 "Protocol didn't start with the expected magic string",
54 ));
55 }
56
57 // Now comes the endianness indicator
58 let mut endian = [0u8; 2];
59 buf_reader.read_exact(&mut endian)?;
60 match &endian {
61 b"LE" => read_protocoll_payload::<LE, _>(&mut buf_reader),
62 b"BE" => read_protocoll_payload::<BE, _>(&mut buf_reader),
63 _ => Err(io::Error::new(
64 io::ErrorKind::Other,
65 "Failed to parse endianness",
66 )),
67 }
68 }
69
70 // Read as much of the payload as possible
71 fn read_protocoll_payload<E, R>(reader: &mut R) ->
io::Result<Vec<u32>>
72 where
73 E: ByteOrder,
74 R: ReadBytesExt,
75 {
76 let mut payload = Vec::new();
77 const SIZE_OF_U32: usize = 4;
78 loop {
79 let mut raw_payload = [0; SIZE_OF_U32];
80 // Read the next 4 bytes
81 match reader.read(&mut raw_payload)? {
82 // Zero means we reached the end
83 0 => return Ok(payload),
84 // SIZE_OF_U32 means we read a complete number
85 SIZE_OF_U32 => {
86 let as_u32 = raw_payload.as_ref().read_u32::<E>()?;
87 payload.push(as_u32)
88 }
89 // Anything else means the last element was not
90 // a valid u32
91 _ => {
92 return Err(io::Error::new(
93 io::ErrorKind::UnexpectedEof,
94 "Payload ended unexpectedly",
95 ))
96 }
97 }
98 }
99 }
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.107.210