@@ -668,6 +668,14 @@ class ConditionalDispatch(Structure):
668668 condition = lambda m : m .f2 == 255 )
669669
670670
671+ class ConditionalSubstructures (Structure ):
672+ f1 = UBInt8 ()
673+ f2 = ConditionalField (SubstructureField (BasicMessage ),
674+ condition = lambda m : m .f1 < 10 )
675+ f3 = ConditionalField (SubstructureField (BasicMessage ),
676+ condition = lambda m : m .f1 < 20 )
677+
678+
671679class TestConditionalField (unittest .TestCase ):
672680 def test_conditional_pack (self ):
673681 m1 = Conditional ()
@@ -732,6 +740,62 @@ def test_conditional_dispatch(self):
732740 self .assertEqual (m2 .f3 .b1 , 0x11 )
733741 self .assertEqual (m2 .f3 .b2 , 0x22 )
734742
743+ def test_conditional_substructure_pack (self ):
744+ m = ConditionalSubstructures ()
745+ m .f1 = 9
746+
747+ f2 = BasicMessage ()
748+ f2 .b1 = 0x55
749+ f2 .b2 = 0x66
750+ m .f2 = f2
751+
752+ f3 = BasicMessage ()
753+ f3 .b1 = 0x77
754+ f3 .b2 = 0x88
755+ m .f3 = f3
756+
757+ self .assertEqual (m .pack (), b"\x09 \x55 \x66 \x77 \x88 " )
758+
759+ # Remove f2
760+ m .f1 = 10
761+ m .f2 = None
762+ self .assertEqual (m .pack (), b"\x0a \x77 \x88 " )
763+
764+ # Remove f3
765+ m .f1 = 20
766+ m .f3 = None
767+ self .assertEqual (m .pack (), b"\x14 " )
768+
769+ def test_conditional_substructure_unpack (self ):
770+ # Neither substructure is present
771+ m1 = ConditionalSubstructures .from_data (b"\x20 " )
772+ self .assertEqual (m1 .f1 , 0x20 )
773+ self .assertEqual (m1 .f2 , None )
774+ self .assertEqual (m1 .f3 , None )
775+
776+ # Include f3 but not f2
777+ m2 = ConditionalSubstructures ()
778+ m2 .unpack (b"\x10 " +
779+ b"\x11 \x22 " )
780+ self .assertEqual (m2 .f1 , 0x10 )
781+ self .assertEqual (m2 .f2 , None )
782+ self .assertIsInstance (m2 .f3 , BasicMessage )
783+ self .assertEqual (m2 .f3 .b1 , 0x11 )
784+ self .assertEqual (m2 .f3 .b2 , 0x22 )
785+
786+ # Include both substructures
787+ m3 = ConditionalSubstructures ()
788+ m3 .unpack (b"\x00 " +
789+ b"\x11 \x22 " +
790+ b"\x33 \x44 " )
791+ self .assertEqual (m3 .f1 , 0x00 )
792+ self .assertIsInstance (m3 .f2 , BasicMessage )
793+ self .assertEqual (m3 .f2 .b1 , 0x11 )
794+ self .assertEqual (m3 .f2 .b2 , 0x22 )
795+ self .assertIsInstance (m3 .f3 , BasicMessage )
796+ self .assertEqual (m3 .f3 .b1 , 0x33 )
797+ self .assertEqual (m3 .f3 .b2 , 0x44 )
798+
735799
736800class TestStructure (unittest .TestCase ):
737801 def test_unpack_fewer_bytes_than_required (self ):
0 commit comments