@@ -373,6 +373,15 @@ public void pack_into(CodeContext/*!*/ context, [NotNull]ByteArray/*!*/ buffer,
373373 return unpack_from ( context , buffer . ToByteArray ( ) , offset ) ;
374374 }
375375
376+ [ Documentation ( "iteratively unpack the current format from the specified array." ) ]
377+ public PythonUnpackIterator iter_unpack ( CodeContext /*!*/ context , [ BytesConversion ] [ NotNull ] IList < byte > /*!*/ buffer , int offset = 0 ) {
378+ return new PythonUnpackIterator ( this , context , buffer , offset ) ;
379+ }
380+
381+ [ Documentation ( "iteratively unpack the current format from the specified array." ) ]
382+ public PythonUnpackIterator iter_unpack ( CodeContext /*!*/ context , [ NotNull ] ArrayModule . array /*!*/ buffer , int offset = 0 ) {
383+ return new PythonUnpackIterator ( this , context , buffer , offset ) ;
384+ }
376385
377386 [ Documentation ( "gets the number of bytes that the serialized string will occupy or are required to deserialize the data" ) ]
378387 public int size {
@@ -582,6 +591,88 @@ internal static Struct Create(string/*!*/ format) {
582591 #endregion
583592 }
584593
594+ [ PythonType ( "unpack_iterator" ) , Documentation ( "Represents an iterator returned by _struct.iter_unpack()" ) ]
595+ public class PythonUnpackIterator : System . Collections . IEnumerator , System . Collections . IEnumerable {
596+ private object _iter_current ;
597+ private int _next_offset ;
598+
599+ private readonly CodeContext _context ;
600+ private readonly IList < byte > _buffer ;
601+ private readonly int _start_offset ;
602+ private readonly Struct _owner ;
603+
604+ private PythonUnpackIterator ( ) { }
605+
606+ internal PythonUnpackIterator ( Struct /*!*/ owner , CodeContext /*!*/ context , IList < byte > /*!*/ buffer , int offset ) {
607+ _context = context ;
608+ _buffer = buffer ;
609+ _start_offset = offset ;
610+ _owner = owner ;
611+
612+ Reset ( ) ;
613+ ValidateBufferLength ( ) ;
614+ }
615+
616+ internal PythonUnpackIterator ( Struct /*!*/ owner , CodeContext /*!*/ context , ArrayModule . array /*!*/ buffer , int offset ) {
617+ _context = context ;
618+ _buffer = buffer . ToByteArray ( ) ;
619+ _start_offset = offset ;
620+ _owner = owner ;
621+
622+ Reset ( ) ;
623+ ValidateBufferLength ( ) ;
624+ }
625+
626+ private void ValidateBufferLength ( ) {
627+ if ( _buffer . Count - _start_offset < _owner . size ) {
628+ throw Error ( _context , $ "iterative unpacking requires a buffer of a multiple of { _owner . size } bytes") ;
629+ }
630+ }
631+
632+ #region IEnumerable
633+ [ PythonHidden ]
634+ public System . Collections . IEnumerator GetEnumerator ( ) {
635+ return this ;
636+ }
637+ #endregion
638+
639+ #region IEnumerator
640+ [ PythonHidden ]
641+ public object Current => _iter_current ;
642+
643+ [ PythonHidden ]
644+ public bool MoveNext ( ) {
645+ if ( _buffer . Count - _next_offset < _owner . size ) {
646+ return false ;
647+ }
648+
649+ _iter_current = _owner . unpack_from ( _context , _buffer , _next_offset ) ;
650+ _next_offset += _owner . size ;
651+ return true ;
652+ }
653+
654+ [ PythonHidden ]
655+ public void Reset ( ) {
656+ _iter_current = null ;
657+ _next_offset = _start_offset ;
658+ }
659+ #endregion
660+
661+ public object __iter__ ( ) {
662+ return this ;
663+ }
664+
665+ public object __next__ ( ) {
666+ if ( ! MoveNext ( ) ) {
667+ throw PythonOps . StopIteration ( ) ;
668+ }
669+ return Current ;
670+ }
671+
672+ public int __length_hint__ ( ) {
673+ return ( _buffer . Count - _next_offset ) / _owner . size ;
674+ }
675+ }
585676 #endregion
586677
587678 #region Compiled Format
@@ -738,6 +829,15 @@ public static void pack_into(CodeContext/*!*/ context, object fmt, [NotNull]Byte
738829 return GetStructFromCache ( context , fmt ) . unpack_from ( context , buffer , offset ) ;
739830 }
740831
832+ [ Documentation ( "Iteratively unpack the buffer, containing packed C structure data, according to\n fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt)." ) ]
833+ public static PythonUnpackIterator /*!*/ iter_unpack ( CodeContext /*!*/ context , object fmt , [ BytesConversion ] [ NotNull ] IList < byte > /*!*/ buffer , int offset = 0 ) {
834+ return GetStructFromCache ( context , fmt ) . iter_unpack ( context , buffer , offset ) ;
835+ }
836+
837+ [ Documentation ( "Iteratively unpack the buffer, containing packed C structure data, according to\n fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt)." ) ]
838+ public static PythonUnpackIterator /*!*/ iter_unpack ( CodeContext /*!*/ context , object fmt , [ NotNull ] ArrayModule . array /*!*/ buffer , int offset = 0 ) {
839+ return GetStructFromCache ( context , fmt ) . iter_unpack ( context , buffer , offset ) ;
840+ }
741841 #endregion
742842
743843 #region Write Helpers
0 commit comments