1use std::io::{self, Read, Write};
3
4use crate::{
5 BorrowedMessage, Message, OwnedMessage, XvcCommand, XvcInfo,
6 codec::{ParseErr, SetTck, Shift},
7 error::ReadError,
8};
9
10pub struct Decoder {
29 buf: Vec<u8>,
30 max_buf: usize,
32 max_shift: usize,
34}
35
36impl Decoder {
37 pub fn new(max_shift: usize) -> Self {
43 let max_buf = max_shift.saturating_mul(2).saturating_add(16);
47 Self {
48 buf: Vec::new(),
49 max_buf,
50 max_shift,
51 }
52 }
53
54 fn read_chunk(&mut self, reader: &mut impl Read) -> Result<(), ReadError> {
55 let mut temp = [0u8; 1024];
56 let read = loop {
57 match reader.read(&mut temp) {
58 Ok(n) => break n,
59 Err(e) if e.kind() == io::ErrorKind::Interrupted => {
60 continue; }
62 Err(e) => return Err(e.into()), }
64 };
65 if read == 0 {
66 return Err(io::Error::new(
68 io::ErrorKind::UnexpectedEof,
69 "unexpected EOF while reading",
70 )
71 .into());
72 }
73
74 if self.max_buf < read + self.buf.len() {
75 return Err(ReadError::TooManyBytes {
76 max: self.max_buf,
77 need: read + self.buf.len(),
78 });
79 }
80 self.buf.extend_from_slice(&temp[..read]);
81
82 Ok(())
83 }
84
85 pub fn read_xvc_info(&mut self, reader: &mut impl Read) -> Result<XvcInfo, ReadError> {
92 self.buf.clear();
93 loop {
94 let mut slice: &[u8] = &self.buf;
95 match XvcInfo::parse(&mut slice) {
96 Ok(frame) => {
97 return Ok(frame);
98 }
99 Err(ParseErr::Incomplete) => {
100 self.read_chunk(reader)?;
101 }
102 Err(other) => return Err(other.into()),
103 }
104 }
105 }
106
107 pub fn read_message(&mut self, reader: &mut impl Read) -> Result<OwnedMessage, ReadError> {
124 self.buf.clear();
125 let cmd = loop {
126 let mut slice: &[u8] = &self.buf;
127 match XvcCommand::parse(&mut slice) {
128 Ok(cmd) => {
129 let consumed = self.buf.len() - slice.len();
130 self.buf.drain(..consumed);
131 break cmd;
132 }
133 Err(ParseErr::Incomplete) => {
134 self.read_chunk(reader)?;
135 }
136 Err(other) => return Err(other.into()),
137 }
138 };
139 match cmd {
140 XvcCommand::GetInfo => Ok(Message::GetInfo),
141 XvcCommand::SetTck => loop {
142 let mut slice: &[u8] = &self.buf;
143 match SetTck::parse(&mut slice) {
144 Ok(tck) => {
145 return Ok(Message::SetTck {
146 period_ns: tck.period(),
147 });
148 }
149 Err(ParseErr::Incomplete) => {
150 self.read_chunk(reader)?;
151 }
152 Err(other) => return Err(other.into()),
153 }
154 },
155 XvcCommand::Shift => loop {
156 let mut slice: &[u8] = &self.buf;
157 match Shift::parse(&mut slice, self.max_shift) {
158 Ok(shift) => {
159 let num_bits = shift.num_bits();
160 let (tms, tdi) = shift.into_tms_tdi();
161 return Ok(Message::Shift { num_bits, tms, tdi });
162 }
163 Err(ParseErr::Incomplete) => {
164 self.read_chunk(reader)?;
165 }
166 Err(other) => return Err(other.into()),
167 }
168 },
169 }
170 }
171}
172
173impl XvcInfo {
174 pub fn write_to(&self, writer: &mut impl Write) -> io::Result<()> {
180 writeln!(
181 writer,
182 "xvcServer_v{}:{}",
183 self.version(),
184 self.max_vector_len()
185 )
186 }
187
188 pub fn from_reader(reader: &mut impl Read) -> Result<XvcInfo, ReadError> {
199 Decoder::new(4096).read_xvc_info(reader)
200 }
201}
202
203impl Message<Box<[u8]>> {
204 pub fn from_reader(
218 reader: &mut impl Read,
219 max_shift_bytes: usize,
220 ) -> Result<OwnedMessage, ReadError> {
221 Decoder::new(max_shift_bytes).read_message(reader)
222 }
223
224 pub fn borrow<'a>(&'a self) -> BorrowedMessage<'a> {
226 match self {
227 Message::GetInfo => BorrowedMessage::GetInfo,
228 Message::SetTck { period_ns } => Message::SetTck {
229 period_ns: *period_ns,
230 },
231 Message::Shift { num_bits, tms, tdi } => BorrowedMessage::Shift {
232 num_bits: *num_bits,
233 tms,
234 tdi,
235 },
236 }
237 }
238}
239
240impl<B: AsRef<[u8]>> Message<B> {
241 pub fn write_to(&self, writer: &mut impl Write) -> io::Result<()> {
250 use crate::codec::{CMD_GET_INFO, CMD_SET_TCK, CMD_SHIFT};
251 match self {
252 Message::GetInfo => writer.write_all(CMD_GET_INFO),
253 Message::SetTck {
254 period_ns: period_in_ns,
255 } => {
256 writer.write_all(CMD_SET_TCK)?;
257 writer.write_all(&period_in_ns.to_le_bytes())
258 }
259 Message::Shift { num_bits, tms, tdi } => {
260 writer.write_all(CMD_SHIFT)?;
261 writer.write_all(&num_bits.to_le_bytes())?;
262 writer.write_all(tms.as_ref())?;
263 writer.write_all(tdi.as_ref())
264 }
265 }
266 }
267}
268
269#[cfg(test)]
270mod test {
271 use std::{io, io::Cursor, vec};
272
273 use crate::{BorrowedMessage, OwnedMessage};
274
275 use super::*;
276
277 const DEFAULT_MAX_SHIFT_BYTES: usize = 1024;
278
279 #[test]
280 fn write_server_info() {
281 let mut out = Vec::new();
282 XvcInfo::default().write_to(&mut out).unwrap();
283 assert_eq!(out, b"xvcServer_v1.0:10485760\n".to_vec());
284 }
285
286 #[test]
287 fn read_server_info() {
288 let data = b"xvcServer_v1.0:32\n";
289 let mut cursor = std::io::Cursor::new(data);
290 let info = XvcInfo::from_reader(&mut cursor).unwrap();
291 assert_eq!(info.version(), crate::protocol::Version::V1_0);
292 assert_eq!(info.max_vector_len(), 32)
293 }
294
295 #[test]
296 fn read_getinfo() {
297 let data = b"getinfo:".to_vec();
298 let mut cursor = Cursor::new(data);
299 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
300 Message::GetInfo => {}
301 _ => panic!("expected GetInfo"),
302 }
303 }
304
305 #[test]
306 fn write_getinfo() {
307 let mut out = Vec::new();
308 BorrowedMessage::GetInfo.write_to(&mut out).unwrap();
309 assert_eq!(out, b"getinfo:".to_vec());
310 }
311
312 #[test]
313 fn read_settck() {
314 let period: u32 = 0x1234_5678;
315 let mut data = b"settck:".to_vec();
316 data.extend_from_slice(&period.to_le_bytes());
317 let mut cursor = Cursor::new(data);
318 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
319 Message::SetTck {
320 period_ns: period_in_ns,
321 } => assert_eq!(period_in_ns, period),
322 _ => panic!("expected SetTck"),
323 }
324 }
325
326 #[test]
327 fn write_settck() {
328 let period: u32 = 0x1234_5678;
329 let mut out = Vec::new();
330 BorrowedMessage::SetTck { period_ns: period }
331 .write_to(&mut out)
332 .unwrap();
333 let mut expected = b"settck:".to_vec();
334 expected.extend_from_slice(&period.to_le_bytes());
335 assert_eq!(out, expected);
336 }
337
338 #[test]
339 fn read_shift() {
340 let num_bits: u32 = 13; let num_bytes = num_bits.div_ceil(8) as usize;
342 let tms = vec![0xAAu8; num_bytes];
343 let tdi = vec![0x55u8; num_bytes];
344
345 let mut data = b"shift:".to_vec();
346 data.extend_from_slice(&num_bits.to_le_bytes());
347 data.extend_from_slice(&tms);
348 data.extend_from_slice(&tdi);
349
350 let mut cursor = Cursor::new(data);
351 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
352 Message::Shift {
353 num_bits: nb,
354 tms: tms_vector,
355 tdi: tdi_vector,
356 } => {
357 assert_eq!(nb, num_bits);
358 assert_eq!(&*tms_vector, &tms[..]);
359 assert_eq!(&*tdi_vector, &tdi[..]);
360 }
361 _ => panic!("expected Shift"),
362 }
363 }
364
365 #[test]
366 fn write_shift() {
367 let num_bits: u32 = 13; let num_bytes = num_bits.div_ceil(8) as usize;
369 let tms = vec![0xAAu8; num_bytes];
370 let tdi = vec![0x55u8; num_bytes];
371
372 let cmd = BorrowedMessage::Shift {
373 num_bits,
374 tms: &tms,
375 tdi: &tdi,
376 };
377 let mut out = Vec::new();
378 cmd.write_to(&mut out).unwrap();
379
380 let mut expected = b"shift:".to_vec();
381 expected.extend_from_slice(&num_bits.to_le_bytes());
382 expected.extend_from_slice(&tms);
383 expected.extend_from_slice(&tdi);
384
385 assert_eq!(out, expected);
386 }
387
388 #[test]
389 fn invalid_prefix() {
390 let data = b"xx".to_vec();
391 let mut cursor = Cursor::new(data);
392 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES) {
393 Err(ReadError::InvalidCommand(p)) => assert_eq!(p, "xx"),
394 other => panic!("expected InvalidCommand, got {:?}", other),
395 }
396 }
397
398 #[test]
399 fn too_many_bytes_shift() {
400 let num_bytes_exceed = 1024 + 1;
401 let num_bits = (num_bytes_exceed * 8) as u32;
402 let mut data = b"shift:".to_vec();
403 data.extend_from_slice(&num_bits.to_le_bytes());
404 let mut cursor = Cursor::new(data);
405 match OwnedMessage::from_reader(&mut cursor, 1024) {
406 Err(ReadError::TooManyBytes { max, need: got }) => {
407 assert_eq!(max, 1024);
408 assert_eq!(got, num_bytes_exceed);
409 }
410 other => panic!("expected TooManyBytes, got {:?}", other),
411 }
412 }
413
414 #[test]
415 fn read_xvc_info_with_max_u32_vector_len() {
416 let data = b"xvcServer_v1.0:4294967295\n";
417 let mut cursor = Cursor::new(data);
418 let info = XvcInfo::from_reader(&mut cursor).unwrap();
419 assert_eq!(info.version(), crate::protocol::Version::V1_0);
420 assert_eq!(info.max_vector_len(), u32::MAX);
421 }
422
423 #[test]
424 fn read_xvc_info_with_zero_vector_len() {
425 let data = b"xvcServer_v1.0:0\n";
426 let mut cursor = Cursor::new(data);
427 let info = XvcInfo::from_reader(&mut cursor).unwrap();
428 assert_eq!(info.version(), crate::protocol::Version::V1_0);
429 assert_eq!(info.max_vector_len(), 0);
430 }
431
432 #[test]
433 fn read_xvc_info_with_large_version_numbers() {
434 let data = b"xvcServer_v999.999:1024\n";
435 let mut cursor = Cursor::new(data);
436 let info = XvcInfo::from_reader(&mut cursor).unwrap();
437 assert_eq!(info.version(), crate::protocol::Version::new(999, 999));
438 assert_eq!(info.max_vector_len(), 1024);
439 }
440
441 #[test]
442 fn read_xvc_info_incomplete_then_complete() {
443 let data = b"xvcServer_v1.0:4\n";
444 let mut cursor = Cursor::new(data);
445 match XvcInfo::from_reader(&mut cursor) {
446 Ok(info) => assert_eq!(info.max_vector_len(), 4),
447 Err(e) => panic!("unexpected error: {:?}", e),
448 }
449 }
450
451 #[test]
452 fn write_xvc_info_max_values() {
453 let mut out = Vec::new();
454 let info = XvcInfo::new(crate::protocol::Version::new(255, 255), u32::MAX);
455 info.write_to(&mut out).unwrap();
456 assert_eq!(out, b"xvcServer_v255.255:4294967295\n".to_vec());
457 }
458
459 #[test]
460 fn read_getinfo_with_extra_data() {
461 let data = b"getinfo:getinfo:";
462 let mut cursor = Cursor::new(data);
463 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
464 Message::GetInfo => {}
465 _ => panic!("expected GetInfo"),
466 }
467 }
468
469 #[test]
470 fn read_getinfo_exact() {
471 let data = b"getinfo:";
472 let mut cursor = Cursor::new(data);
473 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
474 Message::GetInfo => {}
475 _ => panic!("expected GetInfo"),
476 }
477 }
478
479 #[test]
480 fn read_settck_zero_period() {
481 let period: u32 = 0;
482 let mut data = b"settck:".to_vec();
483 data.extend_from_slice(&period.to_le_bytes());
484 let mut cursor = Cursor::new(data);
485 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
486 Message::SetTck {
487 period_ns: period_in_ns,
488 } => assert_eq!(period_in_ns, 0),
489 _ => panic!("expected SetTck"),
490 }
491 }
492
493 #[test]
494 fn read_settck_max_period() {
495 let period: u32 = u32::MAX;
496 let mut data = b"settck:".to_vec();
497 data.extend_from_slice(&period.to_le_bytes());
498 let mut cursor = Cursor::new(data);
499 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
500 Message::SetTck {
501 period_ns: period_in_ns,
502 } => assert_eq!(period_in_ns, u32::MAX),
503 _ => panic!("expected SetTck"),
504 }
505 }
506
507 #[test]
508 fn read_settck_incomplete() {
509 let data = b"settck:".to_vec();
511 let mut cursor = Cursor::new(data);
512 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES) {
513 Err(ReadError::IoError(_)) => {}
514 other => panic!("expected IoError (unexpected EOF), got {:?}", other),
515 }
516 }
517
518 #[test]
519 fn read_settck_partial_period() {
520 let mut data = b"settck:".to_vec();
521 data.extend_from_slice(&[0xAA, 0xBB]);
522 let mut cursor = Cursor::new(data);
523 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES) {
524 Err(ReadError::IoError(e)) if e.kind() == io::ErrorKind::UnexpectedEof => {}
525 other => panic!("expected UnexpectedEof, got {:?}", other),
526 }
527 }
528
529 #[test]
530 fn read_shift_zero_bits() {
531 let num_bits: u32 = 0;
532 let mut data = b"shift:".to_vec();
533 data.extend_from_slice(&num_bits.to_le_bytes());
534
535 let mut cursor = Cursor::new(data);
536 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
537 Message::Shift {
538 num_bits: nb,
539 tms: tms_vector,
540 tdi: tdi_vector,
541 } => {
542 assert_eq!(nb, 0);
543 assert_eq!(&*tms_vector, &[] as &[u8]);
544 assert_eq!(&*tdi_vector, &[] as &[u8]);
545 }
546 _ => panic!("expected Shift"),
547 }
548 }
549
550 #[test]
551 fn read_shift_one_bit() {
552 let num_bits: u32 = 1;
553 let tms = vec![0x00u8];
554 let tdi = vec![0x01u8];
555
556 let mut data = b"shift:".to_vec();
557 data.extend_from_slice(&num_bits.to_le_bytes());
558 data.extend_from_slice(&tms);
559 data.extend_from_slice(&tdi);
560
561 let mut cursor = Cursor::new(data);
562 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
563 Message::Shift {
564 num_bits: nb,
565 tms: tms_vector,
566 tdi: tdi_vector,
567 } => {
568 assert_eq!(nb, 1);
569 assert_eq!(&*tms_vector, &tms[..]);
570 assert_eq!(&*tdi_vector, &tdi[..]);
571 }
572 _ => panic!("expected Shift"),
573 }
574 }
575
576 #[test]
577 fn read_shift_max_bits() {
578 let num_bits: u32 = u32::MAX;
579 let mut data = b"shift:".to_vec();
580 data.extend_from_slice(&num_bits.to_le_bytes());
581
582 let mut cursor = Cursor::new(data);
583 match OwnedMessage::from_reader(&mut cursor, 1024) {
584 Err(ReadError::TooManyBytes { .. }) => {}
585 other => panic!("expected TooManyBytes, got {:?}", other),
586 }
587 }
588
589 #[test]
590 fn read_shift_incomplete_num_bits() {
591 let mut data = b"shift:".to_vec();
592 data.extend_from_slice(&[0xAA, 0xBB]);
593
594 let mut cursor = Cursor::new(data);
595 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES) {
596 Err(ReadError::IoError(e)) if e.kind() == io::ErrorKind::UnexpectedEof => {}
597 other => panic!("expected UnexpectedEof, got {:?}", other),
598 }
599 }
600
601 #[test]
602 fn read_shift_incomplete_tms() {
603 let num_bits: u32 = 16;
604 let mut data = b"shift:".to_vec();
605 data.extend_from_slice(&num_bits.to_le_bytes());
606 data.extend_from_slice(&[0xAA]);
607
608 let mut cursor = Cursor::new(data);
609 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES) {
610 Err(ReadError::IoError(e)) if e.kind() == io::ErrorKind::UnexpectedEof => {}
611 other => panic!("expected UnexpectedEof, got {:?}", other),
612 }
613 }
614
615 #[test]
616 fn read_shift_incomplete_tdi() {
617 let num_bits: u32 = 8;
618 let mut data = b"shift:".to_vec();
619 data.extend_from_slice(&num_bits.to_le_bytes());
620 data.extend_from_slice(&[0xAA]); let mut cursor = Cursor::new(data);
623 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES) {
624 Err(ReadError::IoError(e)) if e.kind() == io::ErrorKind::UnexpectedEof => {}
625 other => panic!("expected UnexpectedEof, got {:?}", other),
626 }
627 }
628
629 #[test]
630 fn read_shift_large_vectors() {
631 let num_bits: u32 = 1000;
632 let num_bytes = num_bits.div_ceil(8) as usize;
633 let tms = vec![0xAA; num_bytes];
634 let tdi = vec![0x55; num_bytes];
635
636 let mut data = b"shift:".to_vec();
637 data.extend_from_slice(&num_bits.to_le_bytes());
638 data.extend_from_slice(&tms);
639 data.extend_from_slice(&tdi);
640
641 let mut cursor = Cursor::new(data);
642 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
643 Message::Shift {
644 num_bits: nb,
645 tms: tms_vector,
646 tdi: tdi_vector,
647 } => {
648 assert_eq!(nb, num_bits);
649 assert_eq!(&*tms_vector, &tms[..]);
650 assert_eq!(&*tdi_vector, &tdi[..]);
651 }
652 _ => panic!("expected Shift"),
653 }
654 }
655
656 #[test]
657 fn shift_at_exact_max_vector_size_succeeds() {
658 let max_shift = 4;
660 let num_bytes = 4usize;
661 let num_bits: u32 = (num_bytes * 8) as u32;
662
663 let mut data = b"shift:".to_vec();
664 data.extend_from_slice(&num_bits.to_le_bytes());
665 data.extend_from_slice(&[0xAA; 4]);
666 data.extend_from_slice(&[0x55; 4]);
667
668 let mut cursor = Cursor::new(data);
669 assert!(
670 OwnedMessage::from_reader(&mut cursor, max_shift).is_ok(),
671 "vectors exactly at max_shift should be accepted"
672 );
673 }
674
675 #[test]
676 fn shift_over_max_vector_size_fails() {
677 let max_shift = 4;
679 let num_bytes = 5usize;
680 let num_bits: u32 = (num_bytes * 8) as u32;
681
682 let mut data = b"shift:".to_vec();
683 data.extend_from_slice(&num_bits.to_le_bytes());
684 data.extend_from_slice(&[0xAA; 5]);
685 data.extend_from_slice(&[0x55; 5]);
686
687 let mut cursor = Cursor::new(data);
688 match OwnedMessage::from_reader(&mut cursor, max_shift) {
689 Err(ReadError::TooManyBytes { .. }) => {}
690 other => panic!("expected TooManyBytes, got {:?}", other),
691 }
692 }
693
694 #[test]
695 fn write_shift_zero_bits() {
696 let cmd = BorrowedMessage::Shift {
697 num_bits: 0,
698 tms: &[],
699 tdi: &[],
700 };
701 let mut out = Vec::new();
702 cmd.write_to(&mut out).unwrap();
703
704 let mut expected = b"shift:".to_vec();
705 expected.extend_from_slice(&0u32.to_le_bytes());
706 assert_eq!(out, expected);
707 }
708
709 #[test]
710 fn write_shift_max_bits() {
711 let cmd = BorrowedMessage::Shift {
712 num_bits: u32::MAX,
713 tms: &[0xFFu8; 512],
714 tdi: &[0xAAu8; 512],
715 };
716 let mut out = Vec::new();
717 cmd.write_to(&mut out).unwrap();
718
719 let mut expected = b"shift:".to_vec();
720 expected.extend_from_slice(&u32::MAX.to_le_bytes());
721 expected.extend_from_slice(&[0xFF; 512]);
722 expected.extend_from_slice(&[0xAA; 512]);
723 assert_eq!(out, expected);
724 }
725
726 #[test]
727 fn invalid_command_name() {
728 let data = b"invalid:".to_vec();
729 let mut cursor = Cursor::new(data);
730 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES) {
731 Err(ReadError::InvalidCommand(_)) => {}
732 other => panic!("expected InvalidCommand, got {:?}", other),
733 }
734 }
735
736 #[test]
737 fn empty_input() {
738 let data = b"".to_vec();
739 let mut cursor = Cursor::new(data);
740 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES) {
741 Err(ReadError::IoError(_)) => {}
742 other => panic!("expected IoError, got {:?}", other),
743 }
744 }
745
746 #[test]
747 fn only_delimiter() {
748 let data = b":".to_vec();
749 let mut cursor = Cursor::new(data);
750 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES) {
751 Err(ReadError::InvalidCommand(_)) => {}
752 other => panic!("expected InvalidCommand, got {:?}", other),
753 }
754 }
755
756 #[test]
757 fn binary_garbage_input() {
758 let data = vec![0xFF, 0xFE, 0xFD, 0xFC];
759 let mut cursor = Cursor::new(data);
760 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES) {
761 Err(ReadError::InvalidCommand(_)) => {}
762 other => panic!("expected InvalidCommand, got {:?}", other),
763 }
764 }
765
766 #[test]
767 fn roundtrip_xvc_info() {
768 let original = XvcInfo::new(crate::protocol::Version::new(1, 0), 8192);
769 let mut buffer = Vec::new();
770 original.write_to(&mut buffer).unwrap();
771
772 let mut cursor = Cursor::new(buffer);
773 let parsed = XvcInfo::from_reader(&mut cursor).unwrap();
774
775 assert_eq!(parsed.version(), original.version());
776 assert_eq!(parsed.max_vector_len(), original.max_vector_len());
777 }
778
779 #[test]
780 fn roundtrip_getinfo() {
781 let original = BorrowedMessage::GetInfo;
782 let mut buffer = Vec::new();
783 original.write_to(&mut buffer).unwrap();
784
785 let mut cursor = Cursor::new(buffer);
786 let parsed = OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap();
787
788 assert_eq!(parsed.borrow(), original);
789 }
790
791 #[test]
792 fn roundtrip_settck() {
793 let original = Message::SetTck {
794 period_ns: 0x12345678,
795 };
796 let mut buffer = Vec::new();
797 original.write_to(&mut buffer).unwrap();
798
799 let mut cursor = Cursor::new(buffer);
800 let parsed = OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap();
801
802 assert_eq!(parsed.borrow(), original);
803 }
804
805 #[test]
806 fn roundtrip_shift() {
807 let num_bits = 128;
808 let num_bytes = (num_bits / 8) as usize;
809 let original = OwnedMessage::Shift {
810 num_bits,
811 tms: vec![0xAA; num_bytes].into_boxed_slice(),
812 tdi: vec![0x55; num_bytes].into_boxed_slice(),
813 };
814 let mut buffer = Vec::new();
815 original.write_to(&mut buffer).unwrap();
816
817 let mut cursor = Cursor::new(buffer);
818 let parsed = OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap();
819
820 assert_eq!(parsed, original);
821 }
822
823 #[test]
824 fn shift_num_bits_rounding() {
825 let num_bits: u32 = 13;
826 let num_bytes = num_bits.div_ceil(8) as usize;
827 let tms = vec![0xAA; num_bytes];
828 let tdi = vec![0x55; num_bytes];
829
830 let mut data = b"shift:".to_vec();
831 data.extend_from_slice(&num_bits.to_le_bytes());
832 data.extend_from_slice(&tms);
833 data.extend_from_slice(&tdi);
834
835 let mut cursor = Cursor::new(data);
836 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
837 Message::Shift {
838 num_bits: nb,
839 tms: tms_vector,
840 tdi: tdi_vector,
841 } => {
842 assert_eq!(nb, 13);
843 assert_eq!(tms_vector.len(), 2);
844 assert_eq!(tdi_vector.len(), 2);
845 }
846 _ => panic!("expected Shift"),
847 }
848 }
849
850 #[test]
851 fn shift_1_bit_requires_1_byte() {
852 let num_bits: u32 = 1;
853 let tms = vec![0x00; 1];
854 let tdi = vec![0x01; 1];
855
856 let mut data = b"shift:".to_vec();
857 data.extend_from_slice(&num_bits.to_le_bytes());
858 data.extend_from_slice(&tms);
859 data.extend_from_slice(&tdi);
860
861 let mut cursor = Cursor::new(data);
862 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
863 Message::Shift {
864 num_bits: nb,
865 tms: tms_vector,
866 tdi: tdi_vector,
867 } => {
868 assert_eq!(nb, 1);
869 assert_eq!(tms_vector.len(), 1);
870 assert_eq!(tdi_vector.len(), 1);
871 }
872 _ => panic!("expected Shift"),
873 }
874 }
875
876 #[test]
877 fn shift_8_bits_requires_1_byte() {
878 let num_bits: u32 = 8;
879 let tms = vec![0xFF; 1];
880 let tdi = vec![0xAA; 1];
881
882 let mut data = b"shift:".to_vec();
883 data.extend_from_slice(&num_bits.to_le_bytes());
884 data.extend_from_slice(&tms);
885 data.extend_from_slice(&tdi);
886
887 let mut cursor = Cursor::new(data);
888 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
889 Message::Shift {
890 num_bits: nb,
891 tms: tms_vector,
892 tdi: tdi_vector,
893 } => {
894 assert_eq!(nb, 8);
895 assert_eq!(tms_vector.len(), 1);
896 assert_eq!(tdi_vector.len(), 1);
897 }
898 _ => panic!("expected Shift"),
899 }
900 }
901
902 #[test]
903 fn shift_9_bits_requires_2_bytes() {
904 let num_bits: u32 = 9;
905 let tms = vec![0xFF; 2];
906 let tdi = vec![0xAA; 2];
907
908 let mut data = b"shift:".to_vec();
909 data.extend_from_slice(&num_bits.to_le_bytes());
910 data.extend_from_slice(&tms);
911 data.extend_from_slice(&tdi);
912
913 let mut cursor = Cursor::new(data);
914 match OwnedMessage::from_reader(&mut cursor, DEFAULT_MAX_SHIFT_BYTES).unwrap() {
915 Message::Shift {
916 num_bits: nb,
917 tms: tms_vector,
918 tdi: tdi_vector,
919 } => {
920 assert_eq!(nb, 9);
921 assert_eq!(tms_vector.len(), 2);
922 assert_eq!(tdi_vector.len(), 2);
923 }
924 _ => panic!("expected Shift"),
925 }
926 }
927
928 #[test]
929 fn decoder_reusable_reads_two_messages() {
930 let mut cursor = Cursor::new(b"getinfo:");
931 let mut dec = Decoder::new(1024);
932 assert!(matches!(
933 dec.read_message(&mut cursor).unwrap(),
934 Message::GetInfo
935 ));
936 let mut cursor2 = Cursor::new(b"settck:\x42\x00\x00\x00");
937 assert!(matches!(
938 dec.read_message(&mut cursor2).unwrap(),
939 Message::SetTck { period_ns: 0x42 }
940 ));
941 }
942}