1use crate::error::AdsError;
2use crate::proto::proto_traits::{ReadFrom, WriteTo};
3use crate::proto::response::{ReadResponse, ReadWriteResponse, WriteResponse};
4use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
5use std::io::{self, Read, Write};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
9struct AccessData {
10 result: u32,
11 length: u32,
12}
13
14impl WriteTo for AccessData {
15 fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
16 wtr.write_u32::<LittleEndian>(self.result)?;
17 wtr.write_u32::<LittleEndian>(self.length)?;
18 Ok(())
19 }
20}
21
22impl ReadFrom for AccessData {
23 fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
24 let result = read.read_u32::<LittleEndian>()?;
25 let length = read.read_u32::<LittleEndian>()?;
26
27 Ok(AccessData { result, length })
28 }
29}
30
31#[derive(Debug, Clone, PartialEq, Eq)]
34pub struct SumupReadWriteResponse {
35 pub read_write_responses: Vec<ReadWriteResponse>,
36}
37
38impl SumupReadWriteResponse {
39 pub fn new(read_write_responses: Vec<ReadWriteResponse>) -> Self {
40 SumupReadWriteResponse {
41 read_write_responses,
42 }
43 }
44}
45
46impl ReadFrom for SumupReadWriteResponse {
47 fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
48 let mut data_buf: Vec<u8> = Vec::new();
49 let mut read_access: Vec<AccessData> = Vec::new();
50
51 read.read_to_end(&mut data_buf)?;
53 let total_data_len = data_buf.len() as u32;
54 let mut access_data_length: u32 = 0;
55 let mut data_length: u32 = 0;
56 let mut data_buf = data_buf.as_slice();
57
58 for _ in 0..total_data_len / 8 {
60 let access_data = AccessData::read_from(&mut data_buf)?;
61 access_data_length += 8;
62 data_length += access_data.length;
63 read_access.push(access_data);
64 if (total_data_len - data_length - access_data_length) == 0 {
65 break;
66 }
67 }
68
69 let mut read_write_response: Vec<ReadWriteResponse> = Vec::new();
71 for access in read_access {
72 let mut buf = vec![0; access.length as usize];
73 data_buf.read_exact(&mut buf)?;
74 read_write_response.push(ReadWriteResponse::new(AdsError::from(access.result), buf));
75 }
76 Ok(SumupReadWriteResponse::new(read_write_response))
77 }
78}
79
80impl WriteTo for SumupReadWriteResponse {
81 fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
82 let mut access_data: Vec<u8> = Vec::new();
83 let mut data: Vec<u8> = Vec::new();
84 for response in &self.read_write_responses {
85 access_data.write_u32::<LittleEndian>(response.result.as_u32())?;
86 access_data.write_u32::<LittleEndian>(response.length)?;
87 data.write_all(response.data.as_slice())?;
88 }
89 access_data.append(&mut data);
90 wtr.write_all(&access_data)?;
91 Ok(())
92 }
93}
94
95#[derive(Debug, Clone, PartialEq, Eq)]
98pub struct SumupReadResponse {
99 pub read_responses: Vec<ReadResponse>,
100}
101
102impl SumupReadResponse {
103 pub fn new(read_responses: Vec<ReadResponse>) -> Self {
104 SumupReadResponse { read_responses }
105 }
106}
107
108impl ReadFrom for SumupReadResponse {
109 fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
110 let mut data_buf: Vec<u8> = Vec::new();
111 let mut read_access: Vec<AccessData> = Vec::new();
112
113 read.read_to_end(&mut data_buf)?;
115 let total_data_len = data_buf.len() as u32;
116 let mut access_data_length: u32 = 0;
117 let mut data_length: u32 = 0;
118 let mut data_buf = data_buf.as_slice();
119
120 for _ in 0..total_data_len / 8 {
122 let access_data = AccessData::read_from(&mut data_buf)?;
123 access_data_length += 8;
124 data_length += access_data.length;
125 read_access.push(access_data);
126 if (total_data_len - data_length - access_data_length) == 0 {
127 break;
128 }
129 }
130
131 let mut read_response: Vec<ReadResponse> = Vec::new();
133 for access in read_access {
134 let mut buf = vec![0; access.length as usize];
135 data_buf.read_exact(&mut buf)?;
136 read_response.push(ReadResponse::new(AdsError::from(access.result), buf));
137 }
138 Ok(SumupReadResponse::new(read_response))
139 }
140}
141
142impl WriteTo for SumupReadResponse {
143 fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
144 let mut access_data: Vec<u8> = Vec::new();
145 let mut data: Vec<u8> = Vec::new();
146 for response in &self.read_responses {
147 access_data.write_u32::<LittleEndian>(response.result.as_u32())?;
148 access_data.write_u32::<LittleEndian>(response.length)?;
149 data.write_all(response.data.as_slice())?;
150 }
151 access_data.append(&mut data);
152 wtr.write_all(&access_data)?;
153 Ok(())
154 }
155}
156
157#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct SumupWriteResponse {
161 pub write_responses: Vec<WriteResponse>,
162}
163
164impl SumupWriteResponse {
165 pub fn new(write_responses: Vec<WriteResponse>) -> Self {
166 SumupWriteResponse { write_responses }
167 }
168}
169
170impl ReadFrom for SumupWriteResponse {
171 fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
172 let mut data_buf: Vec<u8> = Vec::new();
173 read.read_to_end(&mut data_buf)?;
174 let mut write_resp: Vec<WriteResponse> = Vec::new();
175 let mut buf = data_buf.as_slice();
176 for _ in 0..(data_buf.len() / 4) {
177 write_resp.push(WriteResponse::read_from(&mut buf)?)
178 }
179 Ok(SumupWriteResponse::new(write_resp))
180 }
181}
182
183impl WriteTo for SumupWriteResponse {
184 fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
185 for result in &self.write_responses {
186 result.write_to(&mut wtr)?;
187 }
188 Ok(())
189 }
190}
191
192#[cfg(test)]
193mod tests {
194 use super::*;
195
196 #[test]
197 fn sumup_read_write_write_to_test() {
198 let mut response_group: Vec<ReadWriteResponse> = Vec::new();
199 let data_1 = vec![1, 0];
200 let response_1 = ReadWriteResponse::new(AdsError::ErrNoError, data_1);
201 response_group.push(response_1);
202 let data_2 = vec![2, 0, 0, 0];
203 let response_2 = ReadWriteResponse::new(AdsError::ErrNoError, data_2);
204 response_group.push(response_2);
205 let data_3 = vec![3, 0, 0, 0, 0, 0, 0, 0];
206 let response_3 = ReadWriteResponse::new(AdsError::ErrNoError, data_3);
207 response_group.push(response_3);
208
209 let sum_read_write_response = SumupReadWriteResponse::new(response_group);
210 let mut buf: Vec<u8> = Vec::new();
211 sum_read_write_response.write_to(&mut buf).unwrap();
212
213 #[rustfmt::skip]
214 let compare_data = vec![
215 0,0,0,0, 2,0,0,0, 0,0,0,0, 4,0,0,0, 0,0,0,0, 8,0,0,0, 1,0, 2,0,0,0, 3,0,0,0,0,0,0,0 ];
225
226 assert_eq!(buf, compare_data);
227 }
228
229 #[test]
230 fn sumup_read_write_read_from_test() {
231 #[rustfmt::skip]
232 let data = vec![
233 0,0,0,0, 2,0,0,0, 0,0,0,0, 4,0,0,0, 0,0,0,0, 8,0,0,0, 1,0, 2,0,0,0, 3,0,0,0,0,0,0,0 ];
243
244 let sum_read_response = SumupReadResponse::read_from(&mut data.as_slice()).unwrap();
245
246 let data_1 = vec![1, 0];
247 let response_1 = ReadResponse::new(AdsError::ErrNoError, data_1);
248 let data_2 = vec![2, 0, 0, 0];
249 let response_2 = ReadResponse::new(AdsError::ErrNoError, data_2);
250 let data_3 = vec![3, 0, 0, 0, 0, 0, 0, 0];
251 let response_3 = ReadResponse::new(AdsError::ErrNoError, data_3);
252
253 assert_eq!(sum_read_response.read_responses[0], response_1);
254 assert_eq!(sum_read_response.read_responses[1], response_2);
255 assert_eq!(sum_read_response.read_responses[2], response_3);
256
257 let value_1: u16 = sum_read_response.read_responses[0]
258 .data
259 .as_slice()
260 .read_u16::<LittleEndian>()
261 .unwrap();
262 assert_eq!(value_1, 1);
263 assert_eq!(
264 sum_read_response.read_responses[0].result,
265 AdsError::ErrNoError
266 );
267 assert_eq!(sum_read_response.read_responses[0].length, 2);
268 let value_2: u32 = sum_read_response.read_responses[1]
269 .data
270 .as_slice()
271 .read_u32::<LittleEndian>()
272 .unwrap();
273 assert_eq!(value_2, 2);
274 assert_eq!(
275 sum_read_response.read_responses[1].result,
276 AdsError::ErrNoError
277 );
278 assert_eq!(sum_read_response.read_responses[1].length, 4);
279 let value_3: u64 = sum_read_response.read_responses[2]
280 .data
281 .as_slice()
282 .read_u64::<LittleEndian>()
283 .unwrap();
284 assert_eq!(value_3, 3);
285 assert_eq!(
286 sum_read_response.read_responses[2].result,
287 AdsError::ErrNoError
288 );
289 assert_eq!(sum_read_response.read_responses[2].length, 8);
290 }
291
292 #[test]
293 fn sumup_read_write_to_test() {
294 let mut response_group: Vec<ReadResponse> = Vec::new();
295 let data_1 = vec![1, 0];
296 let response_1 = ReadResponse::new(AdsError::ErrNoError, data_1);
297 response_group.push(response_1);
298 let data_2 = vec![2, 0, 0, 0];
299 let response_2 = ReadResponse::new(AdsError::ErrNoError, data_2);
300 response_group.push(response_2);
301 let data_3 = vec![3, 0, 0, 0, 0, 0, 0, 0];
302 let response_3 = ReadResponse::new(AdsError::ErrNoError, data_3);
303 response_group.push(response_3);
304
305 let sum_read_write_response = SumupReadResponse::new(response_group);
306 let mut buf: Vec<u8> = Vec::new();
307 sum_read_write_response.write_to(&mut buf).unwrap();
308
309 #[rustfmt::skip]
310 let compare_data = vec![
311 0,0,0,0, 2,0,0,0, 0,0,0,0, 4,0,0,0, 0,0,0,0, 8,0,0,0, 1,0, 2,0,0,0, 3,0,0,0,0,0,0,0 ];
321
322 assert_eq!(buf, compare_data);
323 }
324
325 #[test]
326 fn sumup_read_read_from_test() {
327 #[rustfmt::skip]
328 let data = vec![
329 0,0,0,0, 2,0,0,0, 0,0,0,0, 4,0,0,0, 0,0,0,0, 8,0,0,0, 1,0, 2,0,0,0, 3,0,0,0,0,0,0,0 ];
339
340 let sum_read_response = SumupReadResponse::read_from(&mut data.as_slice()).unwrap();
341
342 let data_1 = vec![1, 0];
343 let response_1 = ReadResponse::new(AdsError::ErrNoError, data_1);
344 let data_2 = vec![2, 0, 0, 0];
345 let response_2 = ReadResponse::new(AdsError::ErrNoError, data_2);
346 let data_3 = vec![3, 0, 0, 0, 0, 0, 0, 0];
347 let response_3 = ReadResponse::new(AdsError::ErrNoError, data_3);
348
349 assert_eq!(sum_read_response.read_responses[0], response_1);
350 assert_eq!(sum_read_response.read_responses[1], response_2);
351 assert_eq!(sum_read_response.read_responses[2], response_3);
352
353 let value_1: u16 = sum_read_response.read_responses[0]
354 .data
355 .as_slice()
356 .read_u16::<LittleEndian>()
357 .unwrap();
358 assert_eq!(value_1, 1);
359 assert_eq!(
360 sum_read_response.read_responses[0].result,
361 AdsError::ErrNoError
362 );
363 assert_eq!(sum_read_response.read_responses[0].length, 2);
364 let value_2: u32 = sum_read_response.read_responses[1]
365 .data
366 .as_slice()
367 .read_u32::<LittleEndian>()
368 .unwrap();
369 assert_eq!(value_2, 2);
370 assert_eq!(
371 sum_read_response.read_responses[1].result,
372 AdsError::ErrNoError
373 );
374 assert_eq!(sum_read_response.read_responses[1].length, 4);
375 let value_3: u64 = sum_read_response.read_responses[2]
376 .data
377 .as_slice()
378 .read_u64::<LittleEndian>()
379 .unwrap();
380 assert_eq!(value_3, 3);
381 assert_eq!(
382 sum_read_response.read_responses[2].result,
383 AdsError::ErrNoError
384 );
385 assert_eq!(sum_read_response.read_responses[2].length, 8);
386 }
387
388 #[test]
389 fn sumup_write_write_to_test() {
390 let mut response_group: Vec<WriteResponse> = Vec::new();
391 let response_1 = WriteResponse::new(AdsError::ErrNoError);
392 response_group.push(response_1);
393 let response_2 = WriteResponse::new(AdsError::AdsErrClientPortNotOpen);
394 response_group.push(response_2);
395 let response_3 = WriteResponse::new(AdsError::ErrNoError);
396 response_group.push(response_3);
397
398 let sum_read_write_response = SumupWriteResponse::new(response_group);
399 let mut buf: Vec<u8> = Vec::new();
400 sum_read_write_response.write_to(&mut buf).unwrap();
401
402 #[rustfmt::skip]
403 let compare_data = vec![
404 0,0,0,0, 72,7,0,0, 0,0,0,0, ];
408
409 assert_eq!(buf, compare_data);
410 }
411
412 #[test]
413 fn sumup_write_read_from_test() {
414 #[rustfmt::skip]
415 let data = vec![
416 0,0,0,0, 72,7,0,0, 0,0,0,0, ];
420
421 let sum_write_response = SumupWriteResponse::read_from(&mut data.as_slice()).unwrap();
422
423 let mut response_group: Vec<WriteResponse> = Vec::new();
424 let response_1 = WriteResponse::new(AdsError::ErrNoError);
425 response_group.push(response_1);
426 let response_2 = WriteResponse::new(AdsError::AdsErrClientPortNotOpen);
427 response_group.push(response_2);
428 let response_3 = WriteResponse::new(AdsError::ErrNoError);
429 response_group.push(response_3);
430 let compare = SumupWriteResponse::new(response_group);
431
432 assert_eq!(sum_write_response, compare);
433 }
434}