mqtt5_protocol/encoding/
binary.rs1use crate::error::{MqttError, Result};
2use bytes::{Buf, BufMut, Bytes};
3
4pub fn encode_binary<B: BufMut>(buf: &mut B, data: &[u8]) -> Result<()> {
14 if data.len() > crate::constants::limits::MAX_STRING_LENGTH as usize {
15 return Err(MqttError::MalformedPacket(format!(
16 "Binary data length {} exceeds maximum {}",
17 data.len(),
18 crate::constants::limits::MAX_STRING_LENGTH
19 )));
20 }
21
22 #[allow(clippy::cast_possible_truncation)]
25 buf.put_u16(data.len() as u16);
26 buf.put_slice(data);
28
29 Ok(())
30}
31
32pub fn decode_binary<B: Buf>(buf: &mut B) -> Result<Bytes> {
38 if buf.remaining() < 2 {
39 return Err(MqttError::MalformedPacket(
40 "Insufficient bytes for binary data length".to_string(),
41 ));
42 }
43
44 let len = buf.get_u16() as usize;
45
46 if buf.remaining() < len {
47 return Err(MqttError::MalformedPacket(format!(
48 "Insufficient bytes for binary data: expected {}, got {}",
49 len,
50 buf.remaining()
51 )));
52 }
53
54 Ok(buf.copy_to_bytes(len))
55}
56
57pub fn encode_optional_binary<B: BufMut>(buf: &mut B, data: Option<&[u8]>) -> Result<()> {
65 if let Some(data) = data {
66 encode_binary(buf, data)?;
67 }
68 Ok(())
69}
70
71#[must_use]
73pub fn binary_len(data: &[u8]) -> usize {
74 2 + data.len()
75}
76
77#[must_use]
79pub fn optional_binary_len(data: Option<&[u8]>) -> usize {
80 data.map_or(0, binary_len)
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86 use bytes::BytesMut;
87
88 #[test]
89 fn test_encode_decode_binary() {
90 let mut buf = BytesMut::new();
91
92 let test_data = [
94 vec![],
95 vec![0x00],
96 vec![0x01, 0x02, 0x03],
97 vec![0xFF; 100],
98 (0..=255).collect::<Vec<u8>>(),
99 ];
100
101 for data in &test_data {
102 buf.clear();
103 encode_binary(&mut buf, data).unwrap();
104
105 let decoded = decode_binary(&mut buf).unwrap();
106 assert_eq!(&decoded[..], data.as_slice());
107 }
108 }
109
110 #[test]
111 fn test_encode_binary_too_long() {
112 let mut buf = BytesMut::new();
113 let data = vec![0u8; crate::constants::limits::MAX_BINARY_LENGTH as usize];
114 let result = encode_binary(&mut buf, &data);
115 assert!(result.is_err());
116 }
117
118 #[test]
119 fn test_decode_insufficient_length_bytes() {
120 let mut buf = BytesMut::new();
121 buf.put_u8(0); let result = decode_binary(&mut buf);
124 assert!(result.is_err());
125 }
126
127 #[test]
128 fn test_decode_insufficient_data_bytes() {
129 let mut buf = BytesMut::new();
130 buf.put_u16(10); buf.put_slice(&[1, 2, 3, 4, 5]); let result = decode_binary(&mut buf);
134 assert!(result.is_err());
135 }
136
137 #[test]
138 fn test_encode_optional_binary() {
139 let mut buf = BytesMut::new();
140
141 encode_optional_binary(&mut buf, None).unwrap();
143 assert_eq!(buf.len(), 0);
144
145 buf.clear();
147 encode_optional_binary(&mut buf, Some(&[1, 2, 3])).unwrap();
148 assert_eq!(buf.len(), 5); }
150
151 #[test]
152 fn test_binary_len() {
153 assert_eq!(binary_len(&[]), 2);
154 assert_eq!(binary_len(&[1, 2, 3]), 5);
155 assert_eq!(binary_len(&[0u8; 100]), 102);
156 }
157
158 #[test]
159 fn test_optional_binary_len() {
160 assert_eq!(optional_binary_len(None), 0);
161 assert_eq!(optional_binary_len(Some(&[])), 2);
162 assert_eq!(optional_binary_len(Some(&[1, 2, 3])), 5);
163 }
164
165 #[test]
166 fn test_empty_binary() {
167 let mut buf = BytesMut::new();
168 encode_binary(&mut buf, &[]).unwrap();
169
170 assert_eq!(buf.len(), 2);
171 assert_eq!(buf[0], 0);
172 assert_eq!(buf[1], 0);
173
174 let decoded = decode_binary(&mut buf).unwrap();
175 assert_eq!(decoded.len(), 0);
176 }
177}