1use crate::bytes::*;
4use crate::internal::*;
5use crate::lib::std::io;
6
7pub fn legacy_wrap<'a, G>(
8 gen: G,
9 x: (&'a mut [u8], usize),
10) -> Result<(&'a mut [u8], usize), GenError>
11where
12 G: SerializeFn<io::Cursor<&'a mut [u8]>>,
13{
14 let (buf, offset) = x;
15 let (buf, offset) = {
16 let mut cursor = io::Cursor::new(buf);
17 cursor.set_position(offset as u64);
18 let cursor = gen_simple(gen, cursor)?;
19 let position = cursor.position();
20 (cursor.into_inner(), position)
21 };
22 Ok((buf, offset as usize))
23}
24
25#[inline]
27pub fn set_be_u8(x: (&mut [u8], usize), v: u8) -> Result<(&mut [u8], usize), GenError> {
28 legacy_wrap(be_u8(v), x)
29}
30
31#[inline]
33pub fn set_be_u16(x: (&mut [u8], usize), v: u16) -> Result<(&mut [u8], usize), GenError> {
34 legacy_wrap(be_u16(v), x)
35}
36
37#[inline]
39pub fn set_be_u32(x: (&mut [u8], usize), v: u32) -> Result<(&mut [u8], usize), GenError> {
40 legacy_wrap(be_u32(v), x)
41}
42
43#[inline]
45pub fn set_be_u64(x: (&mut [u8], usize), v: u64) -> Result<(&mut [u8], usize), GenError> {
46 legacy_wrap(be_u64(v), x)
47}
48
49#[inline]
51pub fn set_le_u8(x: (&mut [u8], usize), v: u8) -> Result<(&mut [u8], usize), GenError> {
52 legacy_wrap(le_u8(v), x)
53}
54
55#[inline]
57pub fn set_le_u16(x: (&mut [u8], usize), v: u16) -> Result<(&mut [u8], usize), GenError> {
58 legacy_wrap(le_u16(v), x)
59}
60
61#[inline]
63pub fn set_le_u32(x: (&mut [u8], usize), v: u32) -> Result<(&mut [u8], usize), GenError> {
64 legacy_wrap(le_u32(v), x)
65}
66
67#[inline]
69pub fn set_le_u64(x: (&mut [u8], usize), v: u64) -> Result<(&mut [u8], usize), GenError> {
70 legacy_wrap(le_u64(v), x)
71}
72
73#[macro_export]
78macro_rules! gen_align(
79 (($i:expr, $idx:expr), $val:expr) => (
80 {
81 let aligned = $val - ($idx % $val);
82 match $i.len() <= $idx+aligned {
83 true => Err(GenError::BufferTooSmall($idx+aligned - $i.len())),
84 false => { Ok(($i,($idx+aligned))) },
85 }
86 }
87 );
88 ($i:expr, $val:expr) => ( gen_align!(($i.0, $i.1), $val) );
89);
90
91#[macro_export]
96macro_rules! gen_skip(
97 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::combinator::skip($val as usize), $i) );
98);
99
100#[macro_export]
103macro_rules! gen_be_u8(
104 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_u8($val), $i) );
105);
106
107#[macro_export]
110macro_rules! gen_be_u16(
111 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_u16($val), $i) );
112);
113
114#[macro_export]
117macro_rules! gen_be_u24(
118 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_u24($val), $i) );
119);
120
121#[macro_export]
124macro_rules! gen_be_u32(
125 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_u32($val), $i) );
126);
127
128#[macro_export]
134macro_rules! gen_be_u64(
135 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_u64($val), $i) );
136);
137
138#[macro_export]
141macro_rules! gen_be_i8(
142 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_i8($val), $i) );
143);
144
145#[macro_export]
148macro_rules! gen_be_i16(
149 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_i16($val), $i) );
150);
151
152#[macro_export]
155macro_rules! gen_be_i24(
156 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_i24($val), $i) );
157);
158
159#[macro_export]
162macro_rules! gen_be_i32(
163 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_i32($val), $i) );
164);
165
166#[macro_export]
169macro_rules! gen_be_i64(
170 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_i64($val), $i) );
171);
172
173#[macro_export]
176macro_rules! gen_be_f32(
177 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_f32($val), $i) );
178);
179
180#[macro_export]
183macro_rules! gen_be_f64(
184 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_f64($val), $i) );
185);
186
187#[macro_export]
190macro_rules! gen_le_u8(
191 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_u8($val), $i) );
192);
193
194#[macro_export]
197macro_rules! gen_le_u16(
198 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_u16($val), $i) );
199);
200
201#[macro_export]
204macro_rules! gen_le_u24(
205 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_u24($val), $i) );
206);
207
208#[macro_export]
211macro_rules! gen_le_u32(
212 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_u32($val), $i) );
213);
214
215#[macro_export]
221macro_rules! gen_le_u64(
222 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_u64($val), $i) );
223);
224
225#[macro_export]
228macro_rules! gen_le_i8(
229 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_i8($val), $i) );
230);
231
232#[macro_export]
235macro_rules! gen_le_i16(
236 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_i16($val), $i) );
237);
238
239#[macro_export]
242macro_rules! gen_le_i24(
243 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_i24($val), $i) );
244);
245
246#[macro_export]
249macro_rules! gen_le_i32(
250 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_i32($val), $i) );
251);
252
253#[macro_export]
256macro_rules! gen_le_i64(
257 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_i64($val), $i) );
258);
259
260#[macro_export]
263macro_rules! gen_le_f32(
264 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_f32($val), $i) );
265);
266
267#[macro_export]
270macro_rules! gen_le_f64(
271 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_f64($val), $i) );
272);
273
274#[macro_export]
277macro_rules! gen_copy(
278 (($i:expr, $idx:expr), $val:expr, $l:expr) => (
279 match $i.len() < $idx+$l {
280 true => Err(GenError::BufferTooSmall($idx+$l - $i.len())),
281 false => {
282 $i[$idx..$idx+$l].clone_from_slice(&$val[0..$l]);
283 Ok(($i,($idx+$l)))
284 }
285 }
286 );
287 ($i:expr, $val:expr, $l:expr) => ( gen_copy!(($i.0,$i.1), $val, $l) );
288);
289
290#[macro_export]
293macro_rules! gen_slice(
294 ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::combinator::slice($val), $i) );
295);
296
297#[macro_export]
298macro_rules! gen_length_slice(
299 (($i:expr, $idx:expr), $lf:ident, $val:expr) => (
300 do_gen!(($i,$idx),
301 $lf($val.len()) >>
302 gen_slice!($val)
303 )
304 );
305 (($i:expr, $idx:expr), $lsubmac:ident >> $val:expr) => (
306 do_gen!(($i,$idx),
307 $lsubmac!($val.len()) >>
308 gen_slice!($val)
309 )
310 );
311);
312
313#[macro_export]
326macro_rules! gen_call(
327 (($i:expr, $idx:expr), $fun:expr) => ( $fun( ($i,$idx) ) );
328 (($i:expr, $idx:expr), $fun:expr, $($args:expr),* ) => ( $fun( ($i,$idx), $($args),* ) );
329);
330
331#[macro_export]
368macro_rules! do_gen(
369 (__impl $i:expr, $idx:expr, ( $($rest:expr),* )) => (
370 {
371 $($rest)*;
372 Ok(($i,$idx))
373 }
374 );
375 (__impl $i:expr, $idx:expr, $e:ident( $($args:tt)* )) => (
376 do_gen!(__impl $i, $idx, gen_call!($e,$($args)*))
377 );
378 (__impl $i:expr, $idx:expr, $submac:ident!( $($args:tt)* )) => (
379 $submac!(($i,$idx), $($args)*)
380 );
381
382 (__impl $i:expr, $idx:expr, $e:ident >> $($rest:tt)*) => (
383 do_gen!(__impl $i, $idx, gen_call!($e) >> $($rest)*)
384 );
385 (__impl $i:expr, $idx:expr, $e:ident( $($args:tt)* ) >> $($rest:tt)*) => (
386 do_gen!(__impl $i, $idx, gen_call!($e,$($args)*) >> $($rest)*)
387 );
388 (__impl $i:expr, $idx:expr, $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => (
389 {
390 match $submac!(($i,$idx), $($args)*) {
391 Ok((j,idx2)) => {
392 do_gen!(__impl j, idx2, $($rest)*)
393 },
394 Err(e) => Err(e),
395 }
396 }
397 );
398
399 (__impl $i:expr, $idx:expr, $e:ident : $($rest:tt)*) => (
400 {
401 let $e = $idx;
402 do_gen!(__impl $i, $idx, $($rest)*)
403 }
404 );
405
406 ( ($i:expr, $idx:expr), $($rest:tt)*) => (
407 do_gen!(__impl $i, $idx, $($rest)*)
408 );
409 ( $i:expr, $($rest:tt)*) => (
410 do_gen!(__impl $i.0, $i.1, $($rest)*)
411 );
412);
413
414#[macro_export]
422macro_rules! gen_cond(
423 (($i:expr, $idx:expr), $cond:expr, $submac:ident!( $($args:tt)* )) => (
424 {
425 if $cond {
426 $submac!(($i,$idx), $($args)*)
427 } else {
428 Ok(($i,$idx))
429 }
430 }
431 );
432 (($i:expr, $idx:expr), $cond:expr, $f:expr) => (
433 gen_cond!(($i,$idx), $cond, gen_call!($f))
434 );
435);
436
437#[macro_export]
447macro_rules! gen_if_else(
448 (($i:expr, $idx:expr), $cond:expr, $submac_if:ident!( $($args_if:tt)* ), $submac_else:ident!( $($args_else:tt)* )) => (
449 {
450 if $cond {
451 $submac_if!(($i,$idx), $($args_if)*)
452 } else {
453 $submac_else!(($i,$idx), $($args_else)*)
454 }
455 }
456 );
457 (($i:expr, $idx:expr), $cond:expr, $f:expr, $g:expr) => (
458 gen_cond!(($i,$idx), $cond, gen_call!($f), gen_call!($g))
459 );
460);
461
462#[macro_export]
465macro_rules! gen_many_ref(
466 (($i:expr, $idx:expr), $l:expr, $f:expr) => (
467 $l.into_iter().fold(
468 Ok(($i,$idx)),
469 |r,ref v| {
470 match r {
471 Err(e) => Err(e),
472 Ok(x) => { $f(x, v) },
473 }
474 }
475 )
476 );
477);
478
479#[macro_export]
482macro_rules! gen_many_byref(
483 (($i:expr, $idx:expr), $l:expr, $f:expr) => (
484 $l.into_iter().fold(
485 Ok(($i,$idx)),
486 |r,&v| {
487 match r {
488 Err(e) => Err(e),
489 Ok(x) => { $f(x, v) },
490 }
491 }
492 )
493 );
494);
495
496#[macro_export]
499macro_rules! gen_many(
500 (($i:expr, $idx:expr), $l:expr, $f:expr) => (
501 $l.into_iter().fold(
502 Ok(($i,$idx)),
503 |r,v| {
504 match r {
505 Err(e) => Err(e),
506 Ok(x) => { $f(x, v) },
507 }
508 }
509 )
510 );
511);
512
513#[macro_export]
522macro_rules! gen_at_offset(
523 (($i:expr, $idx:expr), $offset:expr, $f:ident( $($args:tt)* )) => (
524 match $i.len() < $offset {
525 false => {
526 match $f(($i,$offset), $($args)*) {
527 Ok((r,_)) => Ok((r,($idx))),
528 Err(e) => Err(e),
529 }
530 },
531 true => Err(GenError::BufferTooSmall($offset - $i.len())),
532 }
533 );
534 (($i:expr, $idx:expr), $offset:expr, $submac:ident!( $($args:tt)* )) => (
535 match $i.len() < $offset {
536 false => {
537 match $submac!(($i,$offset), $($args)*) {
538 Ok((r,_)) => Ok((r,($idx))),
539 Err(e) => Err(e),
540 }
541 },
542 true => Err(GenError::BufferTooSmall($offset - $i.len())),
543 }
544 );
545);
546
547#[macro_export]
556macro_rules! gen_at_rel_offset(
557 (($i:expr, $idx:expr), $rel_offset:expr, $f:ident( $($args:tt)* )) => (
558 match ($rel_offset as i32).overflowing_add($idx as i32).1 {
559 (s,false) if s > 0 => { gen_at_offset!(($i,$idx),s as usize,$f($($args)*)) },
560 _ => Err(GenError::InvalidOffset),
561 }
562 );
563 (($i:expr, $idx:expr), $rel_offset:expr, $submac:ident!( $($args:tt)* )) => (
564 match ($rel_offset as i32).overflowing_add($idx as i32) {
565 (s,false) if s > 0 => { gen_at_offset!(($i,$idx),s as usize,$submac!($($args)*)) },
566 _ => Err(GenError::InvalidOffset),
567 }
568 );
569);
570
571#[cfg(test)]
572mod tests {
573 use super::*;
574
575 #[test]
576 fn test_do_gen() {
577 let mut mem: [u8; 8] = [0; 8];
578 let s = &mut mem[..];
579 let expected = [1, 2, 3, 4, 5, 6, 7, 8];
580 let r = do_gen!(
581 (s, 0),
582 gen_be_u8!(1) >> gen_be_u8!(2) >> gen_be_u16!(0x0304) >> gen_be_u32!(0x05060708)
583 );
584 match r {
585 Ok((b, idx)) => {
586 assert_eq!(idx, 8);
587 assert_eq!(b, &expected);
588 }
589 Err(e) => panic!("error {:?}", e),
590 }
591 }
592
593 #[test]
594 fn test_do_gen_vector() {
595 let mut data = [0; 8];
596 let expected = [1, 2, 3, 4, 5, 6, 7, 8];
597 let r = do_gen!(
598 (&mut data, 0),
599 gen_be_u8!(1) >> gen_be_u8!(2) >> gen_be_u16!(0x0304) >> gen_be_u32!(0x05060708)
600 );
601 match r {
602 Ok((b, idx)) => {
603 assert_eq!(idx, 8);
604 assert_eq!(b, &expected);
605 }
606 Err(e) => panic!("error {:?}", e),
607 }
608 }
609
610 #[test]
611 fn test_gen_skip() {
612 let mut mem: [u8; 8] = [0; 8];
613 let s = &mut mem[..];
614 let expected = [0, 0, 0, 0, 0, 0, 0, 0];
615 let r = gen_skip!((s, 0), 5);
616 match r {
617 Ok((b, idx)) => {
618 assert_eq!(idx, 5);
619 assert_eq!(b, &expected);
620 }
621 Err(e) => panic!("error {:?}", e),
622 }
623 }
624
625 #[test]
626 fn test_gen_be_u8() {
627 let mut mem: [u8; 8] = [0; 8];
628 let s = &mut mem[..];
629 let expected = [1, 2, 0, 0, 0, 0, 0, 0];
630 let r = do_gen!((s, 0), gen_be_u8!(1) >> gen_be_u8!(2));
631 match r {
632 Ok((b, idx)) => {
633 assert_eq!(idx, 2);
634 assert_eq!(b, &expected);
635 }
636 Err(e) => panic!("error {:?}", e),
637 }
638 }
639
640 #[test]
641 fn test_gen_le_u8() {
642 let mut mem: [u8; 8] = [0; 8];
643 let s = &mut mem[..];
644 let expected = [1, 2, 0, 0, 0, 0, 0, 0];
645 let r = do_gen!((s, 0), gen_le_u8!(1) >> gen_le_u8!(2));
646 match r {
647 Ok((b, idx)) => {
648 assert_eq!(idx, 2);
649 assert_eq!(b, &expected);
650 }
651 Err(e) => panic!("error {:?}", e),
652 }
653 }
654
655 #[test]
656 fn test_gen_be_i32() {
657 let mut mem: [u8; 8] = [0; 8];
658 let expected = [0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0];
659 let r = gen_be_i32!((&mut mem, 0), -1i32);
660 match r {
661 Ok((b, idx)) => {
662 assert_eq!(idx, 4);
663 assert_eq!(b, &expected);
664 }
665 Err(e) => panic!("error {:?}", e),
666 }
667 }
668
669 #[test]
670 fn test_gen_be_u64() {
671 let mut mem: [u8; 8] = [0; 8];
672 let expected = [1, 2, 3, 4, 5, 6, 7, 8];
673 let r = gen_be_u64!((&mut mem, 0), 0x0102030405060708u64);
674 match r {
675 Ok((b, idx)) => {
676 assert_eq!(idx, 8);
677 assert_eq!(b, &expected);
678 }
679 Err(e) => panic!("error {:?}", e),
680 }
681 }
682
683 #[test]
684 fn test_gen_be_u64_very_short_buffer() {
685 let mut mem = [0; 3];
686
687 let r = gen_be_u64!((&mut mem, 0), 0x0102030405060708u64);
688 match r {
689 Ok((b, idx)) => panic!("should have failed, but wrote {} bytes: {:?}", idx, b),
690 Err(GenError::BufferTooSmall(sz)) => assert_eq!(sz, 5),
691 Err(e) => panic!("error {:?}", e),
692 }
693 }
694
695 #[test]
696 fn test_gen_be_u64_slightly_short_buffer() {
697 let mut mem = [0; 7];
698 let r = gen_be_u64!((&mut mem, 0), 0x0102030405060708u64);
699 match r {
700 Ok((b, idx)) => panic!("should have failed, but wrote {} bytes: {:?}", idx, b),
701 Err(GenError::BufferTooSmall(sz)) => assert_eq!(sz, 1),
702 Err(e) => panic!("error {:?}", e),
703 }
704 }
705
706 #[test]
707 fn test_gen_le_u64() {
708 let mut mem: [u8; 8] = [0; 8];
709 let expected = [8, 7, 6, 5, 4, 3, 2, 1];
710 let r = gen_le_u64!((&mut mem, 0), 0x0102030405060708u64);
711 match r {
712 Ok((b, idx)) => {
713 assert_eq!(idx, 8);
714 assert_eq!(b, &expected);
715 }
716 Err(e) => panic!("error {:?}", e),
717 }
718 }
719
720 #[test]
721 fn test_set_be_u8() {
722 let mut mem: [u8; 8] = [0; 8];
723 let s = &mut mem[..];
724 let expected = [1, 2, 0, 0, 0, 0, 0, 0];
725 let r = do_gen!((s, 0), set_be_u8(1) >> set_be_u8(2));
726 match r {
727 Ok((b, idx)) => {
728 assert_eq!(idx, 2);
729 assert_eq!(b, &expected);
730 }
731 Err(e) => panic!("error {:?}", e),
732 }
733 }
734
735 #[test]
736 fn test_gen_align() {
737 let mut mem: [u8; 8] = [0; 8];
738 let s = &mut mem[..];
739 let expected = [1, 0, 0, 0, 1, 0, 0, 0];
740 let r = do_gen!((s, 0), gen_be_u8!(1) >> gen_align!(4) >> gen_be_u8!(1));
741 match r {
742 Ok((b, idx)) => {
743 assert_eq!(idx, 5);
744 assert_eq!(b, &expected);
745 }
746 Err(e) => panic!("error {:?}", e),
747 }
748 }
749
750 #[test]
751 #[cfg(feature = "std")]
752 fn test_gen_many() {
753 let mut mem: [u8; 8] = [0; 8];
754 let s = &mut mem[..];
755 let v: Vec<u16> = vec![1, 2, 3, 4];
756 let expected = [0, 1, 0, 2, 0, 3, 0, 4];
757 let r = gen_many!((s, 0), v, set_be_u16);
758 match r {
759 Ok((b, idx)) => {
760 assert_eq!(idx, 8);
761 assert_eq!(b, &expected);
762 }
763 Err(e) => panic!("error {:?}", e),
764 }
765 }
766
767 #[test]
768 fn test_gen_copy() {
769 let mut mem: [u8; 8] = [0; 8];
770 let s = &mut mem[..];
771 let v = [1, 2, 3, 4];
772 let expected = [1, 2, 3, 4, 0, 0, 0, 0];
773 let r = gen_copy!((s, 0), v, v.len());
774 match r {
775 Ok((b, idx)) => {
776 assert_eq!(idx, 4);
777 assert_eq!(b, &expected);
778 }
779 Err(e) => panic!("error {:?}", e),
780 }
781 }
782
783 #[test]
784 fn test_gen_copy_buffer_too_small() {
785 let mut mem: [u8; 7] = [0; 7];
786 let s = &mut mem[..];
787 let v = [0, 1, 2, 3, 4, 5, 6, 7];
788 let r = gen_copy!((s, 0), v, v.len());
789 match r {
790 Ok(_) => {
791 panic!("buffer shouldn't have had enough space");
792 }
793 Err(GenError::BufferTooSmall(sz)) => {
794 if sz != 1 {
795 panic!("invalid max index returned, expected {} got {}", 1, sz);
796 }
797 }
798 Err(e) => {
799 panic!("error {:?}", e);
800 }
801 }
802 }
803
804 #[test]
805 fn test_gen_slice() {
806 let mut mem: [u8; 0] = [0; 0];
807 let s = &mut mem[..];
808 let v = [];
809 let expected = [];
810 let r = gen_slice!((s, 0), v);
811 match r {
812 Ok((b, idx)) => {
813 assert_eq!(idx, 0);
814 assert_eq!(b, &expected);
815 }
816 Err(e) => panic!("error {:?}", e),
817 }
818 }
819
820 #[test]
821 fn test_gen_slice_buffer_too_small() {
822 let mut mem: [u8; 7] = [0; 7];
823 let s = &mut mem[..];
824 let v = [0, 1, 2, 3, 4, 5, 6, 7];
825 let r = gen_slice!((s, 0), v);
826 match r {
827 Ok(_) => {
828 panic!("buffer shouldn't have had enough space");
829 }
830 Err(GenError::BufferTooSmall(sz)) => {
831 if sz != 1 {
832 panic!("invalid max index returned, expected {} got {}", 1, sz);
833 }
834 }
835 Err(e) => {
836 panic!("error {:?}", e);
837 }
838 }
839 }
840
841 #[test]
842 fn test_gen_length_slice() {
843 let mut mem: [u8; 8] = [0; 8];
844 let s = &mut mem[..];
845 let v = [1, 2, 3, 4];
846 let expected = [0, 4, 1, 2, 3, 4, 0, 0];
847 macro_rules! gen_be_usize_as_u16(
848 ($i:expr, $val:expr) => ( set_be_u16($i, $val as u16) );
849 );
850 let r = do_gen!((s, 0), gen_length_slice!(gen_be_usize_as_u16 >> v));
851 match r {
852 Ok((b, idx)) => {
853 assert_eq!(idx, 6);
854 assert_eq!(b, &expected);
855 }
856 Err(e) => panic!("error {:?}", e),
857 }
858 }
859
860 #[test]
861 fn test_gen_checkpoint() {
862 let mut mem: [u8; 8] = [0; 8];
863 let s = &mut mem[..];
864 let expected = [1, 0, 0, 0, 0, 4, 0, 0];
865 let r = do_gen!(
866 (s, 0),
867 start: gen_be_u8!(1) >> gen_align!(4) >> end: gen_be_u16!((end - start) as u16)
868 );
869 match r {
870 Ok((b, idx)) => {
871 assert_eq!(idx, 6);
872 assert_eq!(b, &expected);
873 }
874 Err(e) => panic!("error {:?}", e),
875 }
876 }
877
878 #[test]
879 fn test_gen_at_offset() {
880 let mut mem: [u8; 8] = [0; 8];
881 let s = &mut mem[..];
882 let expected = [0, 0, 0, 0, 0, 4, 0, 0];
883 let r = do_gen!((s, 0), gen_skip!(2) >> gen_at_offset!(4, gen_be_u16!(4)));
884 match r {
885 Ok((b, idx)) => {
886 assert_eq!(idx, 2);
887 assert_eq!(b, &expected);
888 }
889 Err(e) => panic!("error {:?}", e),
890 }
891 }
892
893 #[test]
894 fn test_gen_at_rel_offset() {
895 let mut mem: [u8; 8] = [0; 8];
896 let s = &mut mem[..];
897 let expected = [0, 0, 0, 0, 0, 0, 0, 4];
898 let r = do_gen!(
899 (s, 0),
900 gen_skip!(2) >> gen_at_rel_offset!(4, gen_be_u16!(4))
901 );
902 match r {
903 Ok((b, idx)) => {
904 assert_eq!(idx, 2);
905 assert_eq!(b, &expected);
906 }
907 Err(e) => panic!("error {:?}", e),
908 }
909 }
910
911 #[test]
912 fn test_gen_at_rel_offset_fail() {
913 let mut mem: [u8; 8] = [0; 8];
914 let s = &mut mem[..];
915 let r = do_gen!(
916 (s, 0),
917 gen_skip!(2) >> gen_at_rel_offset!(-4, gen_be_u16!(4))
918 );
919 if let Err(GenError::InvalidOffset) = r {
920 } else {
921 panic!("unexpected result {:?}", r)
922 };
923 }
924}