1mod codec;
8pub mod error;
9
10use bytes::{Buf, BufMut, Bytes, BytesMut};
11
12pub use self::{
13 codec::{
14 RequestFrameSpec, ResponseEnvelope, decode_response_envelope, encode_request_frame,
15 encode_request_frame_body, encode_request_frame_body_with_buffer,
16 encode_request_frame_with_buffer, request_frame_capacity_hint,
17 },
18 error::{FrameError, FrameErrorKind},
19};
20use crate::primitives::check_remaining;
21
22pub type Result<T> = core::result::Result<T, FrameError>;
24
25pub const MAX_FRAME_LENGTH: i32 = 100 * 1024 * 1024;
29
30pub fn read_frame_length(buf: &mut Bytes) -> Result<i32> {
35 check_remaining(buf, 4)?;
36 let len = buf.get_i32();
37 if len < 0 {
38 return Err(FrameErrorKind::NegativeLength { length: len }.into());
39 }
40 if len > MAX_FRAME_LENGTH {
41 return Err(FrameErrorKind::TooLarge {
42 length: len,
43 max: MAX_FRAME_LENGTH,
44 }
45 .into());
46 }
47 Ok(len)
48}
49
50pub fn decode_response_frame(buf: &mut Bytes) -> Result<Bytes> {
55 let frame_len = read_frame_length(buf)?;
56 let len = usize::try_from(frame_len)
57 .map_err(|_| FrameErrorKind::NegativeLength { length: frame_len })?;
58 let available = buf.remaining();
59 if available < len {
60 return Err(FrameErrorKind::Truncated {
61 needed: len,
62 available,
63 }
64 .into());
65 }
66 Ok(buf.split_to(len))
67}
68
69pub fn encode_request(header: &[u8], body: &[u8]) -> Result<BytesMut> {
78 let payload_len = header
79 .len()
80 .checked_add(body.len())
81 .ok_or(FrameErrorKind::TooLarge {
82 length: i32::MAX,
83 max: MAX_FRAME_LENGTH,
84 })?;
85 let max_frame_length = usize::try_from(MAX_FRAME_LENGTH).unwrap_or(usize::MAX);
86 if payload_len > max_frame_length {
87 return Err(FrameErrorKind::TooLarge {
88 length: i32::try_from(payload_len).unwrap_or(i32::MAX),
89 max: MAX_FRAME_LENGTH,
90 }
91 .into());
92 }
93 let capacity = 4usize
94 .checked_add(payload_len)
95 .ok_or(FrameErrorKind::TooLarge {
96 length: i32::MAX,
97 max: MAX_FRAME_LENGTH,
98 })?;
99 let payload_len_i32 = i32::try_from(payload_len).map_err(|_| FrameErrorKind::TooLarge {
100 length: i32::MAX,
101 max: MAX_FRAME_LENGTH,
102 })?;
103 let mut out = BytesMut::with_capacity(capacity);
104 out.put_i32(payload_len_i32);
105 out.extend_from_slice(header);
106 out.extend_from_slice(body);
107 Ok(out)
108}