1use std::io::{Read, Write};
4
5use crate::error::Result;
6use crate::header::{SomeIpHeader, HEADER_SIZE};
7use crate::message::SomeIpMessage;
8
9pub fn read_message<R: Read>(reader: &mut R) -> Result<SomeIpMessage> {
14 let mut header_buf = [0u8; HEADER_SIZE];
16 reader.read_exact(&mut header_buf)?;
17
18 let header = SomeIpHeader::from_bytes(&header_buf)?;
19 let payload_len = header.payload_length() as usize;
20
21 let mut payload = vec![0u8; payload_len];
23 if payload_len > 0 {
24 reader.read_exact(&mut payload)?;
25 }
26
27 Ok(SomeIpMessage::new(header, payload))
28}
29
30pub fn write_message<W: Write>(writer: &mut W, message: &SomeIpMessage) -> Result<()> {
32 writer.write_all(&message.header.to_bytes())?;
33 writer.write_all(&message.payload)?;
34 Ok(())
35}
36
37#[derive(Debug)]
42pub struct MessageReader {
43 buffer: Vec<u8>,
44 position: usize,
45}
46
47impl MessageReader {
48 pub fn new() -> Self {
50 Self {
51 buffer: Vec::with_capacity(4096),
52 position: 0,
53 }
54 }
55
56 pub fn with_capacity(capacity: usize) -> Self {
58 Self {
59 buffer: Vec::with_capacity(capacity),
60 position: 0,
61 }
62 }
63
64 pub fn feed(&mut self, data: &[u8]) {
66 self.buffer.extend_from_slice(data);
67 }
68
69 pub fn try_parse(&mut self) -> Result<Option<SomeIpMessage>> {
74 let available = self.buffer.len() - self.position;
75
76 if available < HEADER_SIZE {
78 return Ok(None);
79 }
80
81 let header_data = &self.buffer[self.position..self.position + HEADER_SIZE];
83 let header = SomeIpHeader::from_bytes(header_data)?;
84 let total_len = HEADER_SIZE + header.payload_length() as usize;
85
86 if available < total_len {
88 return Ok(None);
89 }
90
91 let message_data = &self.buffer[self.position..self.position + total_len];
93 let message = SomeIpMessage::from_bytes(message_data)?;
94
95 self.position += total_len;
96
97 if self.position > self.buffer.len() / 2 {
99 self.compact();
100 }
101
102 Ok(Some(message))
103 }
104
105 pub fn parse_all(&mut self) -> Result<Vec<SomeIpMessage>> {
107 let mut messages = Vec::new();
108 while let Some(msg) = self.try_parse()? {
109 messages.push(msg);
110 }
111 Ok(messages)
112 }
113
114 fn compact(&mut self) {
116 if self.position > 0 {
117 self.buffer.drain(..self.position);
118 self.position = 0;
119 }
120 }
121
122 pub fn clear(&mut self) {
124 self.buffer.clear();
125 self.position = 0;
126 }
127
128 pub fn len(&self) -> usize {
130 self.buffer.len() - self.position
131 }
132
133 pub fn is_empty(&self) -> bool {
135 self.len() == 0
136 }
137}
138
139impl Default for MessageReader {
140 fn default() -> Self {
141 Self::new()
142 }
143}
144
145#[derive(Debug)]
147pub struct MessageWriter {
148 buffer: Vec<u8>,
149}
150
151impl MessageWriter {
152 pub fn new() -> Self {
154 Self {
155 buffer: Vec::with_capacity(4096),
156 }
157 }
158
159 pub fn encode(&mut self, message: &SomeIpMessage) {
161 self.buffer.extend_from_slice(&message.header.to_bytes());
162 self.buffer.extend_from_slice(&message.payload);
163 }
164
165 pub fn data(&self) -> &[u8] {
167 &self.buffer
168 }
169
170 pub fn take(&mut self) -> Vec<u8> {
172 std::mem::take(&mut self.buffer)
173 }
174
175 pub fn clear(&mut self) {
177 self.buffer.clear();
178 }
179}
180
181impl Default for MessageWriter {
182 fn default() -> Self {
183 Self::new()
184 }
185}
186
187#[cfg(test)]
188mod tests {
189 use super::*;
190 use crate::header::{MethodId, ServiceId};
191
192 #[test]
193 fn test_read_write_message() {
194 let original = SomeIpMessage::request(ServiceId(0x1234), MethodId(0x0001))
195 .payload(b"test payload".as_slice())
196 .build();
197
198 let mut buffer = Vec::new();
199 write_message(&mut buffer, &original).unwrap();
200
201 let mut cursor = std::io::Cursor::new(buffer);
202 let parsed = read_message(&mut cursor).unwrap();
203
204 assert_eq!(original, parsed);
205 }
206
207 #[test]
208 fn test_message_reader_complete() {
209 let msg = SomeIpMessage::request(ServiceId(0x1234), MethodId(0x0001))
210 .payload(b"hello".as_slice())
211 .build();
212
213 let data = msg.to_bytes();
214
215 let mut reader = MessageReader::new();
216 reader.feed(&data);
217
218 let parsed = reader.try_parse().unwrap();
219 assert!(parsed.is_some());
220 assert_eq!(parsed.unwrap(), msg);
221 }
222
223 #[test]
224 fn test_message_reader_partial() {
225 let msg = SomeIpMessage::request(ServiceId(0x1234), MethodId(0x0001))
226 .payload(b"hello".as_slice())
227 .build();
228
229 let data = msg.to_bytes();
230
231 let mut reader = MessageReader::new();
232
233 reader.feed(&data[..10]);
235 assert!(reader.try_parse().unwrap().is_none());
236
237 reader.feed(&data[10..]);
239 let parsed = reader.try_parse().unwrap();
240 assert!(parsed.is_some());
241 assert_eq!(parsed.unwrap(), msg);
242 }
243
244 #[test]
245 fn test_message_reader_multiple() {
246 let msg1 = SomeIpMessage::request(ServiceId(0x1234), MethodId(0x0001))
247 .payload(b"first".as_slice())
248 .build();
249 let msg2 = SomeIpMessage::request(ServiceId(0x5678), MethodId(0x0002))
250 .payload(b"second".as_slice())
251 .build();
252
253 let mut data = msg1.to_bytes();
254 data.extend_from_slice(&msg2.to_bytes());
255
256 let mut reader = MessageReader::new();
257 reader.feed(&data);
258
259 let messages = reader.parse_all().unwrap();
260 assert_eq!(messages.len(), 2);
261 assert_eq!(messages[0], msg1);
262 assert_eq!(messages[1], msg2);
263 }
264
265 #[test]
266 fn test_message_writer() {
267 let msg = SomeIpMessage::request(ServiceId(0x1234), MethodId(0x0001))
268 .payload(b"test".as_slice())
269 .build();
270
271 let mut writer = MessageWriter::new();
272 writer.encode(&msg);
273
274 let data = writer.take();
275 assert_eq!(data, msg.to_bytes());
276 }
277}