hebo_codec/
binary_data.rs

1// Copyright (c) 2021 Xu Shaohua <shaohua@biofan.org>. All rights reserved.
2// Use of this source is governed by Apache-2.0 License that can be found
3// in the LICENSE file.
4
5use byteorder::{BigEndian, WriteBytesExt};
6use std::io::Write;
7
8use crate::{utils, ByteArray, DecodeError, DecodePacket, EncodeError, EncodePacket};
9
10/// Binary Data is represented by a Two Byte Integer length which indicates
11/// the number of data bytes, followed by that number of bytes.
12///
13/// Thus, the length of Binary Data is limited to the range of 0 to 65,535 Bytes.
14/// ```text
15/// +-------------------+
16/// | Binary Length     |
17/// |                   |
18/// +-------------------+
19/// | Bytes             |
20/// |                   |
21/// +-------------------+
22/// ```
23#[derive(Clone, Debug, Default, PartialEq, Eq)]
24pub struct BinaryData(Vec<u8>);
25
26impl BinaryData {
27    /// Create an empty binary data.
28    #[must_use]
29    pub const fn new() -> Self {
30        Self(Vec::new())
31    }
32
33    /// Convert byte slice into binary data.
34    ///
35    /// # Errors
36    ///
37    /// Returns error if byte slice is too large.
38    pub fn from_slice(data: &[u8]) -> Result<Self, EncodeError> {
39        utils::validate_two_bytes_data(data)?;
40        Ok(Self(data.to_vec()))
41    }
42
43    /// Get byte length used in packet.
44    #[must_use]
45    pub fn bytes(&self) -> usize {
46        2 + self.0.len()
47    }
48
49    /// Clear binary data.
50    pub fn clear(&mut self) {
51        self.0.clear();
52    }
53}
54
55impl AsRef<[u8]> for BinaryData {
56    fn as_ref(&self) -> &[u8] {
57        &self.0
58    }
59}
60
61impl AsMut<Vec<u8>> for BinaryData {
62    fn as_mut(&mut self) -> &mut Vec<u8> {
63        &mut self.0
64    }
65}
66
67impl DecodePacket for BinaryData {
68    fn decode(ba: &mut ByteArray) -> Result<Self, DecodeError> {
69        let len = ba.read_u16()?;
70        let data = ba.read_bytes(len as usize)?;
71        Ok(Self(data.to_vec()))
72    }
73}
74
75impl EncodePacket for BinaryData {
76    fn encode(&self, buf: &mut Vec<u8>) -> Result<usize, EncodeError> {
77        #[allow(clippy::cast_possible_truncation)]
78        let len = self.0.len() as u16;
79        buf.write_u16::<BigEndian>(len)?;
80        buf.write_all(&self.0)?;
81        Ok(self.bytes())
82    }
83}