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