1pub const STX_CHAR: u8 = 0x02;
4pub const ETX_CHAR: u8 = 0x03;
5pub const DLE_CHAR: u8 = 0x10;
6pub const CR_CHAR: u8 = 0x0d;
7
8#[derive(Copy, Clone)]
11pub struct DleEncoder {
12 pub escape_stx_etx: bool,
14 pub escape_cr: bool,
16 pub add_stx_etx: bool,
19}
20
21#[derive(Debug, PartialEq)]
22pub enum DleError {
23 StreamTooShort,
24 DecodingError,
25}
26
27impl Default for DleEncoder {
28 fn default() -> DleEncoder {
29 DleEncoder {
30 escape_stx_etx: true,
31 escape_cr: false,
32 add_stx_etx: true,
33 }
34 }
35}
36
37impl DleEncoder {
38 pub fn encode(&self, source_stream: &[u8], dest_stream: &mut [u8]) -> Result<usize, DleError> {
66 if self.escape_stx_etx {
67 self.encode_escaped(source_stream, dest_stream)
68 } else {
69 self.encode_non_escaped(source_stream, dest_stream)
70 }
71 }
72
73 pub fn encode_escaped(
82 &self,
83 source_stream: &[u8],
84 dest_stream: &mut [u8],
85 ) -> Result<usize, DleError> {
86 let mut encoded_idx = 0;
87 let mut source_idx = 0;
88 let max_dest_len = dest_stream.len();
89 if self.add_stx_etx {
90 if max_dest_len < 1 {
91 return Err(DleError::StreamTooShort);
92 }
93 dest_stream[encoded_idx] = STX_CHAR;
94 encoded_idx += 1;
95 }
96 while encoded_idx < max_dest_len && source_idx < source_stream.len() {
97 let next_byte = source_stream[source_idx];
98 if next_byte == STX_CHAR
99 || next_byte == ETX_CHAR
100 || (self.escape_cr && next_byte == CR_CHAR)
101 {
102 if encoded_idx + 1 >= max_dest_len {
103 return Err(DleError::StreamTooShort);
104 } else {
105 dest_stream[encoded_idx] = DLE_CHAR;
106 encoded_idx += 1;
107 dest_stream[encoded_idx] = next_byte + 0x40;
114 }
115 } else if next_byte == DLE_CHAR {
116 if encoded_idx + 1 >= max_dest_len {
117 return Err(DleError::StreamTooShort);
118 } else {
119 dest_stream[encoded_idx] = DLE_CHAR;
120 encoded_idx += 1;
121 dest_stream[encoded_idx] = DLE_CHAR;
122 }
123 } else {
124 dest_stream[encoded_idx] = next_byte;
125 }
126 encoded_idx += 1;
127 source_idx += 1;
128 }
129
130 if source_idx == source_stream.len() {
131 if self.add_stx_etx {
132 if encoded_idx + 1 >= max_dest_len {
133 return Err(DleError::StreamTooShort);
134 }
135 dest_stream[encoded_idx] = ETX_CHAR;
136 encoded_idx += 1
137 }
138 Ok(encoded_idx)
139 } else {
140 Err(DleError::StreamTooShort)
141 }
142 }
143
144 pub fn encode_non_escaped(
172 &self,
173 source_stream: &[u8],
174 dest_stream: &mut [u8],
175 ) -> Result<usize, DleError> {
176 let mut encoded_idx = 0;
177 let mut source_idx = 0;
178 let source_stream_len = source_stream.len();
179 let max_dest_len = dest_stream.len();
180 if self.add_stx_etx {
181 if max_dest_len < 2 {
182 return Err(DleError::StreamTooShort);
183 }
184 dest_stream[encoded_idx] = DLE_CHAR;
185 encoded_idx += 1;
186 dest_stream[encoded_idx] = STX_CHAR;
187 encoded_idx += 1;
188 }
189
190 while encoded_idx < max_dest_len && source_idx < source_stream_len {
191 let next_byte = source_stream[source_idx];
192 if next_byte == DLE_CHAR {
193 if encoded_idx + 1 >= max_dest_len {
194 return Err(DleError::StreamTooShort);
195 } else {
196 dest_stream[encoded_idx] = DLE_CHAR;
197 encoded_idx += 1;
198 dest_stream[encoded_idx] = DLE_CHAR;
199 }
200 } else {
201 dest_stream[encoded_idx] = next_byte;
202 }
203 encoded_idx += 1;
204 source_idx += 1;
205 }
206
207 if source_idx == source_stream_len {
208 if self.add_stx_etx {
209 if encoded_idx + 2 >= max_dest_len {
210 return Err(DleError::StreamTooShort);
211 }
212 dest_stream[encoded_idx] = DLE_CHAR;
213 encoded_idx += 1;
214 dest_stream[encoded_idx] = ETX_CHAR;
215 encoded_idx += 1;
216 }
217 Ok(encoded_idx)
218 } else {
219 Err(DleError::StreamTooShort)
220 }
221 }
222
223 pub fn decode(
255 &self,
256 source_stream: &[u8],
257 dest_stream: &mut [u8],
258 read_len: &mut usize,
259 ) -> Result<usize, DleError> {
260 if self.escape_stx_etx {
261 self.decode_escaped(source_stream, dest_stream, read_len)
262 } else {
263 self.decode_non_escaped(source_stream, dest_stream, read_len)
264 }
265 }
266
267 pub fn decode_escaped(
279 &self,
280 source_stream: &[u8],
281 dest_stream: &mut [u8],
282 read_len: &mut usize,
283 ) -> Result<usize, DleError> {
284 let mut encoded_idx = 0;
285 let mut decoded_idx = 0;
286 let source_stream_len = source_stream.len();
287 let dest_stream_len = dest_stream.len();
288 *read_len = 0;
289 if dest_stream_len < 1 {
290 return Err(DleError::StreamTooShort);
291 }
292 if source_stream[encoded_idx] != STX_CHAR {
293 return Err(DleError::DecodingError);
294 }
295 encoded_idx += 1;
296 while encoded_idx < source_stream_len - 1
297 && decoded_idx < dest_stream_len
298 && source_stream[encoded_idx] != ETX_CHAR
299 && source_stream[encoded_idx] != STX_CHAR
300 {
301 if source_stream[encoded_idx] == DLE_CHAR {
302 if encoded_idx + 1 >= source_stream_len {
303 *read_len = source_stream_len;
304 return Err(DleError::DecodingError);
305 }
306 let next_byte = source_stream[encoded_idx + 1];
307 if next_byte == DLE_CHAR {
308 dest_stream[decoded_idx] = next_byte;
309 } else if next_byte == STX_CHAR + 0x40
310 || next_byte == ETX_CHAR + 0x40
311 || (self.escape_cr && next_byte == CR_CHAR + 0x40)
312 {
313 dest_stream[decoded_idx] = next_byte - 0x40;
314 } else {
315 *read_len = encoded_idx + 2;
316 return Err(DleError::DecodingError);
317 }
318 encoded_idx += 1
319 } else {
320 dest_stream[decoded_idx] = source_stream[encoded_idx];
321 }
322 encoded_idx += 1;
323 decoded_idx += 1
324 }
325
326 if source_stream[encoded_idx] != ETX_CHAR {
327 if decoded_idx == dest_stream_len {
328 *read_len = 0;
329 Err(DleError::StreamTooShort)
330 } else {
331 *read_len = encoded_idx + 1;
332 Err(DleError::DecodingError)
333 }
334 } else {
335 *read_len = encoded_idx + 1;
336 Ok(decoded_idx)
337 }
338 }
339
340 pub fn decode_non_escaped(
372 &self,
373 source_stream: &[u8],
374 dest_stream: &mut [u8],
375 read_len: &mut usize,
376 ) -> Result<usize, DleError> {
377 let mut encoded_idx = 0;
378 let mut decoded_idx = 0;
379 let source_stream_len = source_stream.len();
380 let dest_stream_len = dest_stream.len();
381 *read_len = 0;
382
383 if dest_stream_len < 2 {
384 return Err(DleError::StreamTooShort);
385 }
386 if source_stream[encoded_idx] != DLE_CHAR {
387 return Err(DleError::DecodingError);
388 }
389 encoded_idx += 1;
390 if source_stream[encoded_idx] != STX_CHAR {
391 *read_len = 1;
392 return Err(DleError::DecodingError);
393 }
394 encoded_idx += 1;
395 while encoded_idx < source_stream_len && decoded_idx < dest_stream_len {
396 if source_stream[encoded_idx] == DLE_CHAR {
397 if encoded_idx + 1 >= source_stream_len {
398 *read_len = encoded_idx;
399 return Err(DleError::DecodingError);
400 }
401 let next_byte = source_stream[encoded_idx + 1];
402 if next_byte == STX_CHAR {
403 *read_len = encoded_idx;
406 return Err(DleError::DecodingError);
407 } else if next_byte == DLE_CHAR {
408 dest_stream[decoded_idx] = next_byte;
409 encoded_idx += 1;
410 } else if next_byte == ETX_CHAR {
411 *read_len = encoded_idx + 2;
413 return Ok(decoded_idx);
414 } else {
415 *read_len = encoded_idx;
416 return Err(DleError::DecodingError);
417 }
418 } else {
419 dest_stream[decoded_idx] = source_stream[encoded_idx];
420 }
421 encoded_idx += 1;
422 decoded_idx += 1;
423 }
424
425 if decoded_idx == dest_stream_len {
426 *read_len = 0;
429 Err(DleError::StreamTooShort)
430 } else {
431 *read_len = encoded_idx;
432 Err(DleError::DecodingError)
433 }
434 }
435
436 }
439
440#[cfg(test)]
441mod tests {
442 use super::*;
443
444 const TEST_ARRAY_0: [u8; 5] = [0, 0, 0, 0, 0];
445 const TEST_ARRAY_1: [u8; 3] = [0, DLE_CHAR, 5];
446 const TEST_ARRAY_2: [u8; 3] = [0, STX_CHAR, 5];
447 const TEST_ARRAY_3: [u8; 3] = [0, CR_CHAR, ETX_CHAR];
448 const TEST_ARRAY_4: [u8; 3] = [DLE_CHAR, ETX_CHAR, STX_CHAR];
449
450 const TEST_ARRAY_0_ENCODED_ESCPAED: &[u8] = &[STX_CHAR, 0, 0, 0, 0, 0, ETX_CHAR];
451 const TEST_ARRAY_0_ENCODED_NON_ESCPAED: &[u8] =
452 &[DLE_CHAR, STX_CHAR, 0, 0, 0, 0, 0, DLE_CHAR, ETX_CHAR];
453
454 const TEST_ARRAY_1_ENCODED_ESCPAED: [u8; 6] = [STX_CHAR, 0, DLE_CHAR, DLE_CHAR, 5, ETX_CHAR];
455 const TEST_ARRAY_1_ENCODED_NON_ESCPAED: [u8; 8] = [
456 DLE_CHAR, STX_CHAR, 0, DLE_CHAR, DLE_CHAR, 5, DLE_CHAR, ETX_CHAR,
457 ];
458
459 const TEST_ARRAY_2_ENCODED_ESCPAED: &[u8] =
460 &[STX_CHAR, 0, DLE_CHAR, STX_CHAR + 0x40, 5, ETX_CHAR];
461 const TEST_ARRAY_2_ENCODED_NON_ESCPAED: &[u8] =
462 &[DLE_CHAR, STX_CHAR, 0, STX_CHAR, 5, DLE_CHAR, ETX_CHAR];
463
464 const TEST_ARRAY_3_ENCODED_ESCPAED: &[u8] =
465 &[STX_CHAR, 0, CR_CHAR, DLE_CHAR, ETX_CHAR + 0x40, ETX_CHAR];
466 const TEST_ARRAY_3_ENCODED_NON_ESCPAED: &[u8] =
467 &[DLE_CHAR, STX_CHAR, 0, CR_CHAR, ETX_CHAR, DLE_CHAR, ETX_CHAR];
468
469 const TEST_ARRAY_4_ENCODED_ESCPAED: &[u8] = &[
470 STX_CHAR,
471 DLE_CHAR,
472 DLE_CHAR,
473 DLE_CHAR,
474 ETX_CHAR + 0x40,
475 DLE_CHAR,
476 STX_CHAR + 0x40,
477 ETX_CHAR,
478 ];
479 const TEST_ARRAY_4_ENCODED_NON_ESCPAED: [u8; 8] = [
480 DLE_CHAR, STX_CHAR, DLE_CHAR, DLE_CHAR, ETX_CHAR, STX_CHAR, DLE_CHAR, ETX_CHAR,
481 ];
482
483 #[test]
484 fn test_encoder() {
485 let mut dle_encoder = DleEncoder::default();
486 let mut buffer: [u8; 32] = [0; 32];
487 let test_encode_closure = |dle_encoder: &DleEncoder,
488 buf_to_encode: &[u8],
489 expected_buf: &[u8],
490 buffer: &mut [u8]| {
491 let encode_res = dle_encoder.encode(buf_to_encode, buffer);
492 assert!(encode_res.is_ok());
493 for (idx, byte) in expected_buf.iter().enumerate() {
494 assert_eq!(buffer[idx], *byte);
495 }
496 assert_eq!(encode_res.unwrap(), expected_buf.len());
497 };
498
499 let test_faulty_encoding = |dle_encoder: &DleEncoder,
500 buf_to_encode: &[u8],
501 expected_buf: &[u8],
502 buffer: &mut [u8]| {
503 for faulty_dest_size in 0..expected_buf.len() {
504 let encode_res =
505 dle_encoder.encode(buf_to_encode, &mut buffer[0..faulty_dest_size]);
506 assert!(encode_res.is_err());
507 assert_eq!(encode_res.unwrap_err(), DleError::StreamTooShort);
508 }
509 };
510
511 test_encode_closure(
512 &dle_encoder,
513 &TEST_ARRAY_0,
514 TEST_ARRAY_0_ENCODED_ESCPAED,
515 &mut buffer,
516 );
517 test_encode_closure(
518 &dle_encoder,
519 &TEST_ARRAY_1,
520 &TEST_ARRAY_1_ENCODED_ESCPAED,
521 &mut buffer,
522 );
523 test_encode_closure(
524 &dle_encoder,
525 &TEST_ARRAY_2,
526 TEST_ARRAY_2_ENCODED_ESCPAED,
527 &mut buffer,
528 );
529 test_encode_closure(
530 &dle_encoder,
531 &TEST_ARRAY_3,
532 TEST_ARRAY_3_ENCODED_ESCPAED,
533 &mut buffer,
534 );
535 test_encode_closure(
536 &dle_encoder,
537 &TEST_ARRAY_4,
538 TEST_ARRAY_4_ENCODED_ESCPAED,
539 &mut buffer,
540 );
541
542 test_faulty_encoding(
543 &dle_encoder,
544 &TEST_ARRAY_0,
545 TEST_ARRAY_0_ENCODED_ESCPAED,
546 &mut buffer,
547 );
548 test_faulty_encoding(
549 &dle_encoder,
550 &TEST_ARRAY_1,
551 &TEST_ARRAY_1_ENCODED_ESCPAED,
552 &mut buffer,
553 );
554 test_faulty_encoding(
555 &dle_encoder,
556 &TEST_ARRAY_2,
557 TEST_ARRAY_2_ENCODED_ESCPAED,
558 &mut buffer,
559 );
560 test_faulty_encoding(
561 &dle_encoder,
562 &TEST_ARRAY_3,
563 TEST_ARRAY_3_ENCODED_ESCPAED,
564 &mut buffer,
565 );
566 test_faulty_encoding(
567 &dle_encoder,
568 &TEST_ARRAY_4,
569 TEST_ARRAY_4_ENCODED_ESCPAED,
570 &mut buffer,
571 );
572
573 dle_encoder.escape_stx_etx = false;
574 test_encode_closure(
575 &dle_encoder,
576 &TEST_ARRAY_0,
577 TEST_ARRAY_0_ENCODED_NON_ESCPAED,
578 &mut buffer,
579 );
580 test_encode_closure(
581 &dle_encoder,
582 &TEST_ARRAY_1,
583 &TEST_ARRAY_1_ENCODED_NON_ESCPAED,
584 &mut buffer,
585 );
586 test_encode_closure(
587 &dle_encoder,
588 &TEST_ARRAY_2,
589 TEST_ARRAY_2_ENCODED_NON_ESCPAED,
590 &mut buffer,
591 );
592 test_encode_closure(
593 &dle_encoder,
594 &TEST_ARRAY_3,
595 TEST_ARRAY_3_ENCODED_NON_ESCPAED,
596 &mut buffer,
597 );
598 test_encode_closure(
599 &dle_encoder,
600 &TEST_ARRAY_4,
601 &TEST_ARRAY_4_ENCODED_NON_ESCPAED,
602 &mut buffer,
603 );
604
605 test_faulty_encoding(
606 &dle_encoder,
607 &TEST_ARRAY_0,
608 TEST_ARRAY_0_ENCODED_ESCPAED,
609 &mut buffer,
610 );
611 test_faulty_encoding(
612 &dle_encoder,
613 &TEST_ARRAY_1,
614 &TEST_ARRAY_1_ENCODED_ESCPAED,
615 &mut buffer,
616 );
617 test_faulty_encoding(
618 &dle_encoder,
619 &TEST_ARRAY_2,
620 TEST_ARRAY_2_ENCODED_ESCPAED,
621 &mut buffer,
622 );
623 test_faulty_encoding(
624 &dle_encoder,
625 &TEST_ARRAY_3,
626 TEST_ARRAY_3_ENCODED_ESCPAED,
627 &mut buffer,
628 );
629 test_faulty_encoding(
630 &dle_encoder,
631 &TEST_ARRAY_4,
632 TEST_ARRAY_4_ENCODED_ESCPAED,
633 &mut buffer,
634 );
635 }
636
637 #[test]
638 fn test_decoder() {
639 let mut dle_encoder = DleEncoder::default();
640 let mut buffer: [u8; 32] = [0; 32];
641 let test_decode_closure = |dle_encoder: &DleEncoder,
642 encoded_test_vec: &[u8],
643 expected_buf: &[u8],
644 buffer: &mut [u8]| {
645 let mut read_len = 0;
646 let decode_res = dle_encoder.decode(encoded_test_vec, buffer, &mut read_len);
647 assert!(decode_res.is_ok());
648 for (idx, byte) in expected_buf.iter().enumerate() {
649 assert_eq!(buffer[idx], *byte);
650 }
651 assert_eq!(read_len, encoded_test_vec.len());
652 assert_eq!(decode_res.unwrap(), expected_buf.len());
653 };
654
655 let test_faulty_decoding =
656 |dle_encoder: &DleEncoder, faulty_encoded_buf: &[u8], buffer: &mut [u8]| {
657 let mut read_len = 0;
658 let decode_res = dle_encoder.decode(&faulty_encoded_buf, buffer, &mut read_len);
659 assert!(decode_res.is_err());
660 assert_eq!(decode_res.unwrap_err(), DleError::DecodingError);
661 };
662
663 test_decode_closure(
664 &dle_encoder,
665 TEST_ARRAY_0_ENCODED_ESCPAED,
666 &TEST_ARRAY_0,
667 &mut buffer,
668 );
669 test_decode_closure(
670 &dle_encoder,
671 &TEST_ARRAY_1_ENCODED_ESCPAED,
672 &TEST_ARRAY_1,
673 &mut buffer,
674 );
675 test_decode_closure(
676 &dle_encoder,
677 TEST_ARRAY_2_ENCODED_ESCPAED,
678 &TEST_ARRAY_2,
679 &mut buffer,
680 );
681 test_decode_closure(
682 &dle_encoder,
683 TEST_ARRAY_3_ENCODED_ESCPAED,
684 &TEST_ARRAY_3,
685 &mut buffer,
686 );
687 test_decode_closure(
688 &dle_encoder,
689 TEST_ARRAY_4_ENCODED_ESCPAED,
690 &TEST_ARRAY_4,
691 &mut buffer,
692 );
693
694 dle_encoder.escape_stx_etx = false;
695 test_decode_closure(
696 &dle_encoder,
697 TEST_ARRAY_0_ENCODED_NON_ESCPAED,
698 &TEST_ARRAY_0,
699 &mut buffer,
700 );
701 test_decode_closure(
702 &dle_encoder,
703 &TEST_ARRAY_1_ENCODED_NON_ESCPAED,
704 &TEST_ARRAY_1,
705 &mut buffer,
706 );
707 test_decode_closure(
708 &dle_encoder,
709 TEST_ARRAY_2_ENCODED_NON_ESCPAED,
710 &TEST_ARRAY_2,
711 &mut buffer,
712 );
713 test_decode_closure(
714 &dle_encoder,
715 TEST_ARRAY_3_ENCODED_NON_ESCPAED,
716 &TEST_ARRAY_3,
717 &mut buffer,
718 );
719 test_decode_closure(
720 &dle_encoder,
721 &TEST_ARRAY_4_ENCODED_NON_ESCPAED,
722 &TEST_ARRAY_4,
723 &mut buffer,
724 );
725
726 let mut test_array_1_encoded_faulty = TEST_ARRAY_1_ENCODED_NON_ESCPAED.clone();
727 let mut prev_val = test_array_1_encoded_faulty[0];
728 test_array_1_encoded_faulty[0] = 0;
729 test_faulty_decoding(&dle_encoder, &test_array_1_encoded_faulty, &mut buffer);
730
731 test_array_1_encoded_faulty[0] = prev_val;
732 prev_val = test_array_1_encoded_faulty[1];
733 test_array_1_encoded_faulty[1] = 0;
734 test_faulty_decoding(&dle_encoder, &test_array_1_encoded_faulty, &mut buffer);
735
736 test_array_1_encoded_faulty[1] = prev_val;
737 prev_val = test_array_1_encoded_faulty[6];
738 test_array_1_encoded_faulty[6] = 0;
739 test_faulty_decoding(&dle_encoder, &test_array_1_encoded_faulty, &mut buffer);
740
741 test_array_1_encoded_faulty[6] = prev_val;
742 test_array_1_encoded_faulty[7] = 0;
743 test_faulty_decoding(&dle_encoder, &test_array_1_encoded_faulty, &mut buffer);
744
745 let mut test_array_4_encoded_faulty = TEST_ARRAY_4_ENCODED_NON_ESCPAED.clone();
746 test_array_4_encoded_faulty[3] = 0;
747 test_faulty_decoding(&dle_encoder, &test_array_4_encoded_faulty, &mut buffer);
748
749 dle_encoder.escape_stx_etx = true;
750 let mut test_array_1_encoded_faulty = TEST_ARRAY_1_ENCODED_ESCPAED.clone();
751 prev_val = test_array_1_encoded_faulty[3];
752 test_array_1_encoded_faulty[3] = 0;
753 test_faulty_decoding(&dle_encoder, &test_array_1_encoded_faulty, &mut buffer);
754
755 test_array_1_encoded_faulty[3] = prev_val;
756 prev_val = test_array_1_encoded_faulty[0];
757 test_array_1_encoded_faulty[0] = 0;
758 test_faulty_decoding(&dle_encoder, &test_array_1_encoded_faulty, &mut buffer);
759
760 test_array_1_encoded_faulty[0] = prev_val;
761 prev_val = test_array_1_encoded_faulty[5];
762 test_array_1_encoded_faulty[5] = 0;
763 test_faulty_decoding(&dle_encoder, &test_array_1_encoded_faulty, &mut buffer);
764
765 test_array_1_encoded_faulty[5] = prev_val;
766 test_array_1_encoded_faulty[2] = 0;
767 test_faulty_decoding(&dle_encoder, &test_array_1_encoded_faulty, &mut buffer);
768
769 let mut decoding_buffer: [u8; 16] = [0; 16];
770 let encoded_array: [u8; 4] = [0x02, 0x10, 0x02 + 0x40, 0x03];
771 let mut read_len = 0;
772 let decode_result = dle_encoder.decode(&encoded_array, &mut decoding_buffer, &mut read_len);
773 assert!(decode_result.is_ok());
774 let decoded_len = decode_result.unwrap();
775 assert_eq!(decoded_len, 1);
776 }
777}