1use std::io;
3use std::num::NonZeroUsize;
4
5use bytes::BytesMut;
6use nom::Err::{Error, Failure, Incomplete};
7use tokio_codec::{Decoder, Encoder};
8
9use crate::Message;
10use crate::parser::parse_request;
11
12#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
23pub struct SIPCodec {
24 max_size: Option<NonZeroUsize>,
25}
26
27impl Default for SIPCodec {
28 fn default() -> Self {
29 Self { max_size: NonZeroUsize::new(2_000_000) }
30 }
31}
32
33impl Decoder for SIPCodec {
34 type Item = Message;
35 type Error = std::io::Error;
36
37 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
38 match parse_request(&src[..]) {
39 Err(Incomplete(_)) | Err(Error(_)) => Ok(None),
40 Err(Failure(err)) => Err(io::Error::new(
41 io::ErrorKind::InvalidData,
42 format!("{:?}", err),
43 )),
44 Ok((remaining, req)) => {
45 let remaining_size = remaining.as_ptr() as usize - src.as_ptr() as usize;
46 src.split_to(remaining_size);
47 Ok(Some(Message::Request(req)))
48 }
49 }
50 }
51}
52
53impl Encoder for SIPCodec {
54 type Item = Message;
55 type Error = std::io::Error;
56
57 fn encode(&mut self, item: Self::Item, buf: &mut BytesMut) -> Result<(), Self::Error> {
58 match item {
59 Message::Response(res) => {
60 res.write_buf(buf);
61 }
62 Message::Request(_req) => unimplemented!()
63 }
64 Ok(())
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use bytes::BytesMut;
71 use http::header::HeaderValue;
72 use http::HeaderMap;
73 use tokio_codec::Decoder;
74
75 use crate::{Message, Request, SIPCodec};
76
77 #[test]
78 fn test() {
79 let mut bytes = BytesMut::new();
80 let mut codec = SIPCodec::default();
81 let initial = b"GET sip:user@server:port SIP/2.0\r\na:b\r\nContent-length: 7\r\n\r\nabcdef";
82 bytes.extend_from_slice(initial);
83 assert_eq!(None, codec.decode(&mut bytes).unwrap());
84 bytes.extend_from_slice(b"g");
85 let expected = {
86 let mut headers = HeaderMap::new();
87 headers.insert("a", HeaderValue::from_static("b"));
88 headers.insert("content-length", HeaderValue::from_static("7"));
89 Some(Message::Request(Request {
90 method: "GET".into(),
91 uri: "sip:user@server:port".into(),
92 sip_version: Default::default(),
93 headers,
94 body: b"abcdefg".to_vec(),
95 }))
96 };
97 assert_eq!(expected, codec.decode(&mut bytes).unwrap());
98 }
99}