@@ -1526,51 +1526,29 @@ impl DmaTxStreamBufView {
15261526
15271527 /// Pushes a buffer into the stream buffer.
15281528 /// Returns the number of bytes pushed.
1529- pub fn push ( & mut self , buf : & [ u8 ] ) -> usize {
1530- let bytes = self . available_bytes ( ) ;
1531- let bytes_to_fill = buf. len ( ) . min ( bytes) ;
1532- let buf = & buf[ ..bytes_to_fill] ;
1533- if buf. is_empty ( ) {
1534- return 0 ;
1535- }
1536-
1537- fn truncate_by ( n : usize , by : usize ) -> usize {
1538- if n >= by { n - by } else { n }
1539- }
1540-
1541- let n_chunks = self . buf . descriptors . len ( ) ;
1529+ pub fn push_with ( & mut self , f : impl FnOnce ( & mut [ u8 ] ) -> usize ) -> usize {
15421530 let chunk_size = self . buf . descriptors [ 0 ] . size ( ) ;
1543- let dma_size = self . buf . buffer . len ( ) ;
15441531 let dma_start = self . descriptor_idx * chunk_size + self . descriptor_offset ;
1545- let dma_end = truncate_by ( dma_start + buf. len ( ) , dma_size) ;
1546-
1547- if dma_start < dma_end {
1548- self . buf . buffer [ dma_start..dma_end] . copy_from_slice ( buf) ;
1549- } else {
1550- self . buf . buffer [ dma_start..] . copy_from_slice ( & buf[ ..dma_size - dma_start] ) ;
1551- self . buf . buffer [ ..dma_end] . copy_from_slice ( & buf[ dma_size - dma_start..] ) ;
1552- }
1532+ let bytes_pushed = f ( & mut self . buf . buffer [ dma_start..] ) ;
15531533
1554- let descs = ( self . descriptor_idx ..n_chunks) . chain ( 0 ..self . descriptor_idx ) ;
15551534 let mut bytes_filled = 0 ;
1556-
1557- for d in descs {
1535+ for d in ( self . descriptor_idx ..self . buf . descriptors . len ( ) ) . chain ( core:: iter:: once ( 0 ) ) {
15581536 let desc = & mut self . buf . descriptors [ d] ;
15591537 let bytes_in_d = desc. size ( ) - self . descriptor_offset ;
1560- if bytes_in_d + bytes_filled > buf . len ( ) {
1561- // I will have empty space in `desc`
1538+ // There is at least one byte left in `desc`.
1539+ if bytes_in_d + bytes_filled > bytes_pushed {
15621540 self . descriptor_idx = d;
1563- self . descriptor_offset = self . descriptor_offset + buf . len ( ) - bytes_filled;
1541+ self . descriptor_offset = self . descriptor_offset + bytes_pushed - bytes_filled;
15641542 break ;
15651543 }
1566- // fill `desc` with data from `buf`
15671544 bytes_filled += bytes_in_d;
15681545 self . descriptor_offset = 0 ;
15691546
1547+ // Put the current descriptor at the end of the list
15701548 desc. set_owner ( Owner :: Dma ) ;
15711549 desc. set_length ( desc. size ( ) ) ;
15721550 desc. set_suc_eof ( true ) ;
1573- let p = d. checked_sub ( 1 ) . unwrap_or ( n_chunks - 1 ) ;
1551+ let p = d. checked_sub ( 1 ) . unwrap_or ( self . buf . descriptors . len ( ) - 1 ) ;
15741552 if p != d {
15751553 let [ prev, desc] = self . buf . descriptors . get_disjoint_mut ( [ p, d] ) . unwrap ( ) ;
15761554 desc. next = null_mut ( ) ;
@@ -1579,7 +1557,26 @@ impl DmaTxStreamBufView {
15791557 }
15801558 }
15811559
1582- bytes_to_fill
1560+ bytes_pushed
1561+ }
1562+
1563+ /// Pushes a buffer into the stream buffer.
1564+ /// Returns the number of bytes pushed.
1565+ pub fn push ( & mut self , data : & [ u8 ] ) -> usize {
1566+ let mut remaining = data. len ( ) ;
1567+ let mut offset = 0 ;
1568+
1569+ while self . available_bytes ( ) >= remaining && remaining > 0 {
1570+ let written = self . push_with ( |buffer| {
1571+ let len = usize:: min ( buffer. len ( ) , data. len ( ) - offset) ;
1572+ buffer[ ..len] . copy_from_slice ( & data[ offset..] [ ..len] ) ;
1573+ len
1574+ } ) ;
1575+ offset += written;
1576+ remaining -= written;
1577+ }
1578+
1579+ offset
15831580 }
15841581}
15851582
0 commit comments