blob: 8a7badf0d9863c688e9c614c49edb357b0f03d23 [file] [log] [blame]
Jooyung Han12a0b702021-08-05 23:20:31 +09001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//! Provides extension methods Bytes::read<T>(), which calls back ReadFromBytes::read_from_byte()
18
Alice Wangbc4b9a92022-09-16 13:13:18 +000019use anyhow::{ensure, Result};
Jooyung Han12a0b702021-08-05 23:20:31 +090020use bytes::{Buf, Bytes};
21use std::ops::Deref;
22
Jooyung Han5b4c70e2021-08-09 16:36:13 +090023#[derive(Clone, Debug)]
Jooyung Han12a0b702021-08-05 23:20:31 +090024pub struct LengthPrefixed<T> {
25 inner: T,
26}
27
28impl<T> Deref for LengthPrefixed<T> {
29 type Target = T;
30 fn deref(&self) -> &Self::Target {
31 &self.inner
32 }
33}
34
Alice Wang71701272022-09-20 10:03:02 +000035impl<T> LengthPrefixed<T> {
36 /// Consumes the `LengthPrefixed` instance, returning the wrapped value.
37 pub fn into_inner(self) -> T {
38 self.inner
39 }
40}
41
Jooyung Han12a0b702021-08-05 23:20:31 +090042pub trait BytesExt {
43 fn read<T: ReadFromBytes>(&mut self) -> Result<T>;
44}
45
46impl BytesExt for Bytes {
47 fn read<T: ReadFromBytes>(&mut self) -> Result<T> {
48 T::read_from_bytes(self)
49 }
50}
51
52pub trait ReadFromBytes {
53 fn read_from_bytes(buf: &mut Bytes) -> Result<Self>
54 where
55 Self: Sized;
56}
57
58impl ReadFromBytes for u32 {
59 fn read_from_bytes(buf: &mut Bytes) -> Result<Self> {
60 Ok(buf.get_u32_le())
61 }
62}
63
64impl<T: ReadFromBytes> ReadFromBytes for Vec<T> {
65 fn read_from_bytes(buf: &mut Bytes) -> Result<Self> {
66 let mut result = vec![];
67 while buf.has_remaining() {
68 result.push(buf.read()?);
69 }
70 Ok(result)
71 }
72}
73
74impl<T: ReadFromBytes> ReadFromBytes for LengthPrefixed<T> {
75 fn read_from_bytes(buf: &mut Bytes) -> Result<Self> {
76 let mut inner = read_length_prefixed_slice(buf)?;
77 let inner = inner.read()?;
78 Ok(LengthPrefixed { inner })
79 }
80}
81
82impl ReadFromBytes for Bytes {
83 fn read_from_bytes(buf: &mut Bytes) -> Result<Self> {
84 Ok(buf.slice(..))
85 }
86}
87
88fn read_length_prefixed_slice(buf: &mut Bytes) -> Result<Bytes> {
Alice Wangbc4b9a92022-09-16 13:13:18 +000089 ensure!(
90 buf.remaining() >= 4,
91 "Remaining buffer too short to contain length of length-prefixed field. Remaining: {}",
92 buf.remaining()
93 );
Jooyung Han12a0b702021-08-05 23:20:31 +090094 let len = buf.get_u32_le() as usize;
Alice Wangbc4b9a92022-09-16 13:13:18 +000095 ensure!(
96 buf.remaining() >= len,
97 "length-prefixed field longer than remaining buffer. Field length: {}, remaining: {}",
98 len,
99 buf.remaining()
100 );
Jooyung Han12a0b702021-08-05 23:20:31 +0900101 Ok(buf.split_to(len))
102}
Jooyung Hand821a042021-08-10 16:46:43 +0900103
104#[cfg(test)]
105mod tests {
Andrew Walbran117cd5e2021-08-13 11:42:13 +0000106 use super::*;
Jooyung Hand821a042021-08-10 16:46:43 +0900107 use bytes::{BufMut, BytesMut};
Andrew Walbran117cd5e2021-08-13 11:42:13 +0000108
Jooyung Hand821a042021-08-10 16:46:43 +0900109 #[test]
110 fn test_read_length_prefixed_slice() {
111 let data = b"hello world";
112 let mut b = BytesMut::new();
113 b.put_u32_le(data.len() as u32);
114 b.put_slice(data);
115 let mut slice = b.freeze();
Andrew Walbran117cd5e2021-08-13 11:42:13 +0000116 let res = read_length_prefixed_slice(&mut slice);
Jooyung Hand821a042021-08-10 16:46:43 +0900117 assert!(res.is_ok());
118 assert_eq!(data, res.ok().unwrap().as_ref());
119 }
120}