88import six
99from suitcase .exceptions import SuitcaseException , \
1010 SuitcasePackException , SuitcaseParseError
11- from suitcase .fields import FieldPlaceholder , CRCField , SubstructureField
11+ from suitcase .fields import FieldPlaceholder , CRCField , SubstructureField , \
12+ ConditionalField
1213from six import BytesIO
1314
1415
@@ -85,6 +86,11 @@ def unpack_stream(self, stream):
8586 logic present for dealing with checksum fields.
8687
8788 """
89+ def is_substructure (field ):
90+ return isinstance (field , SubstructureField ) or \
91+ isinstance (field , ConditionalField ) and \
92+ isinstance (field .field , SubstructureField )
93+
8894 crc_fields = []
8995 greedy_field = None
9096 # go through the fields from first to last. If we hit a greedy
@@ -93,11 +99,15 @@ def unpack_stream(self, stream):
9399 if isinstance (field , CRCField ):
94100 crc_fields .append ((field , stream .tell ()))
95101 length = field .bytes_required
96- if isinstance (field , SubstructureField ):
102+ if is_substructure (field ):
97103 remaining_data = stream .getvalue ()[stream .tell ():]
98104 returned_stream = field .unpack (remaining_data , trailing = True )
105+ if returned_stream is not None :
106+ consumed = returned_stream .tell ()
107+ else :
108+ consumed = 0
99109 # We need to fast forward by as much as was consumed by the structure
100- stream .seek (stream .tell () + returned_stream . tell () )
110+ stream .seek (stream .tell () + consumed )
101111 continue
102112 elif length is None :
103113 greedy_field = field
@@ -135,7 +145,7 @@ def unpack_stream(self, stream):
135145 raise SuitcaseParseError ("While attempting to parse field "
136146 "%r we tried to read %s bytes but "
137147 "we were only able to read %s." %
138- (name , length , len (data )))
148+ (_name , length , len (data )))
139149 try :
140150 field .unpack (data )
141151 except SuitcaseException :
0 commit comments