@@ -361,54 +361,73 @@ impl<'a> ZeroCopyParser<'a> {
361361
362362 #[ inline( always) ]
363363 pub fn parse_next ( & mut self ) -> Option < ZeroCopyMessage < ' a > > {
364- let data_len = self . data . len ( ) ;
365- let pos = self . position ;
364+ loop {
365+ let data_len = self . data . len ( ) ;
366+ let pos = self . position ;
366367
367- if pos + 3 > data_len {
368- return None ;
369- }
368+ if pos + 3 > data_len {
369+ return None ;
370+ }
370371
371- let length = unsafe {
372- let ptr = self . data . as_ptr ( ) . add ( pos) ;
373- u16:: from_be_bytes ( std:: ptr:: read_unaligned ( ptr as * const [ u8 ; 2 ] ) )
374- } as usize ;
372+ let length = unsafe {
373+ let ptr = self . data . as_ptr ( ) . add ( pos) ;
374+ u16:: from_be_bytes ( std:: ptr:: read_unaligned ( ptr as * const [ u8 ; 2 ] ) )
375+ } as usize ;
375376
376- let total_size = length + 2 ;
377- let msg_end = pos + total_size;
377+ let total_size = length + 2 ;
378+ let msg_end = pos + total_size;
378379
379- if msg_end > data_len {
380- return None ;
381- }
380+ if msg_end <= pos {
381+ self . position = pos + 1 ;
382+ continue ;
383+ }
382384
383- #[ cfg( all( feature = "simd" , target_arch = "x86_64" ) ) ]
384- {
385- if msg_end + 64 <= data_len {
386- unsafe {
387- use std:: arch:: x86_64:: * ;
388- _mm_prefetch ( self . data . as_ptr ( ) . add ( msg_end) as * const i8 , _MM_HINT_T0) ;
385+ if msg_end > data_len {
386+ return None ;
387+ }
388+
389+ #[ cfg( all( feature = "simd" , target_arch = "x86_64" ) ) ]
390+ {
391+ if msg_end + 64 <= data_len {
392+ unsafe {
393+ use std:: arch:: x86_64:: * ;
394+ _mm_prefetch ( self . data . as_ptr ( ) . add ( msg_end) as * const i8 , _MM_HINT_T0) ;
395+ }
389396 }
390397 }
391- }
392398
393- let msg_type = self . data [ pos + 2 ] ;
394- let header_start = pos + 3 ;
395- let header_end = header_start + 10 ;
399+ let msg_type = self . data [ pos + 2 ] ;
396400
397- if header_end > data_len {
398- return None ;
399- }
401+ if !crate :: simd:: is_valid_message_type ( msg_type) {
402+ self . position = msg_end;
403+ continue ;
404+ }
400405
401- let payload_start = header_end;
406+ let header_start = pos + 3 ;
407+ let header_end = header_start + 10 ;
408+
409+ if header_end > msg_end {
410+ self . position = msg_end;
411+ continue ;
412+ }
413+
414+ if header_end > data_len {
415+ return None ;
416+ }
417+
418+ let payload_start = header_end;
419+
420+ if let Ok ( ( hdr_ref, _) ) =
421+ Ref :: < & [ u8 ] , MessageHeaderRaw > :: from_prefix ( & self . data [ header_start..header_end] )
422+ {
423+ let payload = & self . data [ payload_start..msg_end] ;
424+ self . position = msg_end;
425+ return Some ( ZeroCopyMessage :: new ( msg_type, hdr_ref, payload) ) ;
426+ }
402427
403- if let Ok ( ( hdr_ref, _) ) =
404- Ref :: < & [ u8 ] , MessageHeaderRaw > :: from_prefix ( & self . data [ header_start..header_end] )
405- {
406- let payload = & self . data [ payload_start..msg_end] ;
407428 self . position = msg_end;
408- return Some ( ZeroCopyMessage :: new ( msg_type , hdr_ref , payload ) ) ;
429+ continue ;
409430 }
410-
411- None
412431 }
413432
414433 #[ inline]
@@ -741,14 +760,14 @@ mod tests {
741760 let mut data = Vec :: new ( ) ;
742761 for _ in 0 ..2 {
743762 data. extend ( & [ 0u8 , 11u8 ] ) ;
744- data. push ( 1u8 ) ;
763+ data. push ( b'S' ) ;
745764 data. extend ( & [ 0u8 ; 10 ] ) ;
746765 }
747766
748767 let mut parser = ZeroCopyParser :: new ( & data) ;
749768 let arcs = parser. parse_all_arc ( ) ;
750769 assert_eq ! ( arcs. len( ) , 2 ) ;
751- assert_eq ! ( arcs[ 0 ] . msg_type, 1u8 ) ;
770+ assert_eq ! ( arcs[ 0 ] . msg_type, b'S' ) ;
752771 assert ! ( Arc :: strong_count( & arcs[ 0 ] . payload) >= 1 ) ;
753772 }
754773}
0 commit comments