opentdf_protocol/binary/
mod.rs1use std::io::{self, Read, Write};
8
9pub mod traits;
10
11pub use traits::{BinaryRead, BinaryWrite};
12
13pub fn read_u8<R: Read>(reader: &mut R) -> io::Result<u8> {
15 let mut buf = [0u8; 1];
16 reader.read_exact(&mut buf)?;
17 Ok(buf[0])
18}
19
20pub fn read_u16_be<R: Read>(reader: &mut R) -> io::Result<u16> {
22 let mut buf = [0u8; 2];
23 reader.read_exact(&mut buf)?;
24 Ok(u16::from_be_bytes(buf))
25}
26
27pub fn read_u24_be<R: Read>(reader: &mut R) -> io::Result<u32> {
30 let mut buf = [0u8; 3];
31 reader.read_exact(&mut buf)?;
32 Ok(u32::from_be_bytes([0, buf[0], buf[1], buf[2]]))
33}
34
35pub fn read_u32_be<R: Read>(reader: &mut R) -> io::Result<u32> {
37 let mut buf = [0u8; 4];
38 reader.read_exact(&mut buf)?;
39 Ok(u32::from_be_bytes(buf))
40}
41
42pub fn read_bytes<R: Read>(reader: &mut R, n: usize) -> io::Result<Vec<u8>> {
44 let mut buf = vec![0u8; n];
45 reader.read_exact(&mut buf)?;
46 Ok(buf)
47}
48
49pub fn write_u8<W: Write>(writer: &mut W, value: u8) -> io::Result<()> {
51 writer.write_all(&[value])
52}
53
54pub fn write_u16_be<W: Write>(writer: &mut W, value: u16) -> io::Result<()> {
56 writer.write_all(&value.to_be_bytes())
57}
58
59pub fn write_u24_be<W: Write>(writer: &mut W, value: u32) -> io::Result<()> {
62 if value > 0x00FF_FFFF {
63 return Err(io::Error::new(
64 io::ErrorKind::InvalidInput,
65 "Value too large for u24",
66 ));
67 }
68 let bytes = value.to_be_bytes();
69 writer.write_all(&bytes[1..4])
70}
71
72pub fn write_u32_be<W: Write>(writer: &mut W, value: u32) -> io::Result<()> {
74 writer.write_all(&value.to_be_bytes())
75}
76
77pub fn write_bytes<W: Write>(writer: &mut W, bytes: &[u8]) -> io::Result<()> {
79 writer.write_all(bytes)
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85 use std::io::Cursor;
86
87 #[test]
88 fn test_u8_roundtrip() {
89 let mut buf = Vec::new();
90 write_u8(&mut buf, 0x42).unwrap();
91 assert_eq!(buf, vec![0x42]);
92
93 let mut cursor = Cursor::new(buf);
94 assert_eq!(read_u8(&mut cursor).unwrap(), 0x42);
95 }
96
97 #[test]
98 fn test_u16_roundtrip() {
99 let mut buf = Vec::new();
100 write_u16_be(&mut buf, 0x1234).unwrap();
101 assert_eq!(buf, vec![0x12, 0x34]);
102
103 let mut cursor = Cursor::new(buf);
104 assert_eq!(read_u16_be(&mut cursor).unwrap(), 0x1234);
105 }
106
107 #[test]
108 fn test_u24_roundtrip() {
109 let mut buf = Vec::new();
110 write_u24_be(&mut buf, 0x12_3456).unwrap();
111 assert_eq!(buf, vec![0x12, 0x34, 0x56]);
112
113 let mut cursor = Cursor::new(buf);
114 assert_eq!(read_u24_be(&mut cursor).unwrap(), 0x12_3456);
115 }
116
117 #[test]
118 fn test_u24_overflow() {
119 let mut buf = Vec::new();
120 let result = write_u24_be(&mut buf, 0x01_000000);
121 assert!(result.is_err());
122 }
123
124 #[test]
125 fn test_u32_roundtrip() {
126 let mut buf = Vec::new();
127 write_u32_be(&mut buf, 0x12345678).unwrap();
128 assert_eq!(buf, vec![0x12, 0x34, 0x56, 0x78]);
129
130 let mut cursor = Cursor::new(buf);
131 assert_eq!(read_u32_be(&mut cursor).unwrap(), 0x12345678);
132 }
133
134 #[test]
135 fn test_bytes_roundtrip() {
136 let data = vec![0x01, 0x02, 0x03, 0x04, 0x05];
137 let mut buf = Vec::new();
138 write_bytes(&mut buf, &data).unwrap();
139 assert_eq!(buf, data);
140
141 let mut cursor = Cursor::new(buf);
142 assert_eq!(read_bytes(&mut cursor, 5).unwrap(), data);
143 }
144}