pub fn recv(&mut self, start_pos: StreamPos, data: &[u8]) -> Option<StreamPos> {
        assert!(data.len() <= u32::MAX as usize / 2);

        // This is the stream position at the beginning of the read buffer
        let recv_start_pos = self.recv_pos - Wrapping(self.ready);

        // `recv_end_pos` is the stream position at the end of the maximum capacity of the receive
        // buffer.
        let recv_end_pos = self.recv_pos + Wrapping(self.capacity as u32 - self.ready);

        // `end_pos` is the stream position at the end of the input data
        let end_pos = start_pos + Wrapping(data.len() as u32);

        // If stream positions were strictly ordered this would not be necessary, but this check
        // combined with the assertions that `data.len() <= u32::MAX / 2` and `self.capacity <=
        // u32::MAX / 2` should prevent wrapping issues.
        if stream_gt(&start_pos, &recv_end_pos) {
            return None;
        }

        // `copy_start_pos` is the stream position at either the given `start_pos`, or the current
        // receive position, whichever is greater.  We do not copy data that has already been
        // received, so this is where we will begin copying.
        let copy_start_pos = if stream_gt(&self.recv_pos, &start_pos) {
            self.recv_pos
        } else {
            start_pos
        };

        // We calculate the `end_pos` as being either the previous `end_pos` or the stream position
        // at the maximum capacity of the receive buffer.  We should not read more data than the
        // requested buffer capacity can hold.
        let end_pos = if stream_lt(&end_pos, &recv_end_pos) {
            end_pos
        } else {
            recv_end_pos
        };

        // If we are not copying any new data (the range from `copy_start_pos` to `end_pos` is
        // empty), then we are done.
        if stream_ge(&copy_start_pos, &end_pos) {
            // We should only return and end position if there is actually acknowledged data (it
            // doesn't matter if the data has already been read and we skip copying it).
            if stream_lt(&start_pos, &end_pos) {
                return Some(end_pos);
            } else {
                return None;
            }
        }

        // The index in the destination buffer where we start copying from
        let data_start = (copy_start_pos - start_pos).0 as usize;
        // The index in the receive buffer where we start copying to
        let buf_start = (copy_start_pos - recv_start_pos).0 as usize;
        // The index in the receive buffer where we stop copying
        let buf_end = (end_pos - recv_start_pos).0 as usize;

        assert!(buf_end <= self.capacity as usize);
        self.buffer.resize(self.buffer.len().max(buf_end), 0);
        for i in buf_start..buf_end {
            self.buffer[i] = data[i - buf_start + data_start];
        }

        // Very, very carefully, combine this newly received region with the existing unready
        // regions and maintain all the invariants of the unready list.

        if stream_ge(&self.recv_pos, &start_pos) {
            // If this received region touches the end of the ready block, we need to combine this
            // region with the ready block, and any unready regions that it overlaps with also need
            // to be combined into the ready block.

            let pos = match self
                .unready
                .binary_search_by(|(_, end)| stream_cmp(end, &end_pos))
            {
                Ok(i) => i,
                Err(i) => i,
            };

            let end = if pos == self.unready.len() {
                self.unready.clear();
                end_pos
            } else if end_pos >= self.unready[pos].0 {
                let end = self.unready[pos].1;
                self.unready.drain(0..=pos);
                end
            } else {
                end_pos
            };

            self.ready += (end - self.recv_pos).0;
            self.recv_pos = end;
        } else {
            // If this received region does not touch the end of the ready block, we just need to
            // combine this with the other unready regions to maintain the invariants.  It must be
            // combined with any overlapping unready regions or any unready regions that are exactly
            // next to each other.

            let insert_pos = match self
                .unready
                .binary_search_by(|(_, end)| stream_cmp(end, &start_pos))
            {
                Ok(i) => i,
                Err(i) => i,
            };

            if insert_pos == self.unready.len() {
                self.unready.push((start_pos, end_pos));
            } else if stream_lt(&end_pos, &self.unready[insert_pos].0) {
                self.unready.insert(insert_pos, (start_pos, end_pos));
            } else {
                let start = self.unready[insert_pos].0;
                for i in insert_pos..self.unready.len() {
                    if stream_lt(&end_pos, &self.unready[i].0) {
                        self.unready.drain(insert_pos + 1..i);
                        self.unready[insert_pos].0 = start.min(start_pos);
                        self.unready[insert_pos].1 = end_pos;
                        break;
                    } else if stream_lt(&end_pos, &self.unready[i].1) || i == self.unready.len() - 1
                    {
                        self.unready.drain(insert_pos..i);
                        self.unready[insert_pos].0 = start.min(start_pos);
                        self.unready[insert_pos].1 = self.unready[insert_pos].1.max(end_pos);
                        break;
                    }
                }
            }
        }

        Some(end_pos)
    }
/// Receive a new block of data and return the upper bound of the stream range that was
/// successfully stored.
///
/// If redundant data is received, all redundant data will be returned as successfully stored,
/// even data that has already been read out.  It will *not* be checked for consistency with
/// existing data, it will simply be ignored and assumed to be identical.
///
/// The returned upper bound will never be beyond the current window end, any data that falls
/// beyond the receive window cannot be stored.
///
/// The range formed by the start position and the returned upper bound will never be empty, it
/// will either be a non-empty range of successfully received data or this method will return
/// None.  The range formed by the start position and the returned upper bound will also never
/// be larger than the provided data, it will either be equal to or smaller.
///
/// Received data may not be made immediately available for read if it is not contiguous with
/// the existing ready data.
Receive a new block of data and return the upper bound of the stream range that was
successfully stored.

If redundant data is received, all redundant data will be returned as successfully stored,
even data that has already been read out.  It will *not* be checked for consistency with
existing data, it will simply be ignored and assumed to be identical.

The returned upper bound will never be beyond the current window end, any data that falls
beyond the receive window cannot be stored.

The range formed by the start position and the returned upper bound will never be empty, it
will either be a non-empty range of successfully received data or this method will return
None.  The range formed by the start position and the returned upper bound will also never
be larger than the provided data, it will either be equal to or smaller.

Received data may not be made immediately available for read if it is not contiguous with
the existing ready data.
Receive a new block of data and return the upper bound of the stream range that was successfully stored . If redundant data is received all redundant data will be returned as successfully stored even data that has already been read out . It will * not * be checked for consistency with existing data it will simply be ignored and assumed to be identical . The returned upper bound will never be beyond the current window end any data that falls beyond the receive window cannot be stored . The range formed by the start position and the returned upper bound will never be empty it will either be a non - empty range of successfully received data or this method will return None . The range formed by the start position and the returned upper bound will also never be larger than the provided data it will either be equal to or smaller . Received data may not be made immediately available for read if it is not contiguous with the existing ready data .
pub fn recv(&mut self, start_pos: StreamPos, data: &[u8]) -> Option<StreamPos> {
        assert!(data.len() <= u32::MAX as usize / 2);
        // This is the stream position at the beginning of the read buffer
        let recv_start_pos = self.recv_pos - Wrapping(self.ready);
        // `recv_end_pos` is the stream position at the end of the maximum capacity of the receive
        // buffer.
        let recv_end_pos = self.recv_pos + Wrapping(self.capacity as u32 - self.ready);
        // `end_pos` is the stream position at the end of the input data
        let end_pos = start_pos + Wrapping(data.len() as u32);
        // If stream positions were strictly ordered this would not be necessary, but this check
        // combined with the assertions that `data.len() <= u32::MAX / 2` and `self.capacity <=
        // u32::MAX / 2` should prevent wrapping issues.
        if stream_gt(&start_pos, &recv_end_pos) {
            return None;
        }
        // `copy_start_pos` is the stream position at either the given `start_pos`, or the current
        // receive position, whichever is greater.  We do not copy data that has already been
        // received, so this is where we will begin copying.
        let copy_start_pos = if stream_gt(&self.recv_pos, &start_pos) {
            self.recv_pos
        } else {
            start_pos
        };
        // We calculate the `end_pos` as being either the previous `end_pos` or the stream position
        // at the maximum capacity of the receive buffer.  We should not read more data than the
        // requested buffer capacity can hold.
        let end_pos = if stream_lt(&end_pos, &recv_end_pos) {
            end_pos
        } else {
            recv_end_pos
        };
        // If we are not copying any new data (the range from `copy_start_pos` to `end_pos` is
        // empty), then we are done.
        if stream_ge(&copy_start_pos, &end_pos) {
            // We should only return and end position if there is actually acknowledged data (it
            // doesn't matter if the data has already been read and we skip copying it).
            if stream_lt(&start_pos, &end_pos) {
                return Some(end_pos);
            } else {
                return None;
            }
        }
        // The index in the destination buffer where we start copying from
        let data_start = (copy_start_pos - start_pos).0 as usize;
        // The index in the receive buffer where we start copying to
        let buf_start = (copy_start_pos - recv_start_pos).0 as usize;
        // The index in the receive buffer where we stop copying
        let buf_end = (end_pos - recv_start_pos).0 as usize;
        assert!(buf_end <= self.capacity as usize);
        self.buffer.resize(self.buffer.len().max(buf_end), 0);
        for i in buf_start..buf_end {
            self.buffer[i] = data[i - buf_start + data_start];
        }
        // Very, very carefully, combine this newly received region with the existing unready
        // regions and maintain all the invariants of the unready list.
        if stream_ge(&self.recv_pos, &start_pos) {
            // If this received region touches the end of the ready block, we need to combine this
            // region with the ready block, and any unready regions that it overlaps with also need
            // to be combined into the ready block.
            let pos = match self
                .unready
                .binary_search_by(|(_, end)| stream_cmp(end, &end_pos))
            {
                Ok(i) => i,
                Err(i) => i,
            };
            let end = if pos == self.unready.len() {
                self.unready.clear();
                end_pos
            } else if end_pos >= self.unready[pos].0 {
                let end = self.unready[pos].1;
                self.unready.drain(0..=pos);
                end
            } else {
                end_pos
            };
            self.ready += (end - self.recv_pos).0;
            self.recv_pos = end;
        } else {
            // If this received region does not touch the end of the ready block, we just need to
            // combine this with the other unready regions to maintain the invariants.  It must be
            // combined with any overlapping unready regions or any unready regions that are exactly
            // next to each other.
            let insert_pos = match self
                .unready
                .binary_search_by(|(_, end)| stream_cmp(end, &start_pos))
            {
                Ok(i) => i,
                Err(i) => i,
            };
            if insert_pos == self.unready.len() {
                self.unready.push((start_pos, end_pos));
            } else if stream_lt(&end_pos, &self.unready[insert_pos].0) {
                self.unready.insert(insert_pos, (start_pos, end_pos));
            } else {
                let start = self.unready[insert_pos].0;
                for i in insert_pos..self.unready.len() {
                    if stream_lt(&end_pos, &self.unready[i].0) {
                        self.unready.drain(insert_pos + 1..i);
                        self.unready[insert_pos].0 = start.min(start_pos);
                        self.unready[insert_pos].1 = end_pos;
                        break;
                    } else if stream_lt(&end_pos, &self.unready[i].1) || i == self.unready.len() - 1
                    {
                        self.unready.drain(insert_pos..i);
                        self.unready[insert_pos].0 = start.min(start_pos);
                        self.unready[insert_pos].1 = self.unready[insert_pos].1.max(end_pos);
                        break;
                    }
                }
            }
        }
        Some(end_pos)
    }
pub fn recv ( & mut self , start_pos : StreamPos , data : & [ u8 ] ) -> Option < StreamPos > { assert ! ( data len ( ) u32 MAX as usize 2 ) ; // This is the stream position at the beginning of the read buffer let recv_start_pos = self . recv_pos - Wrapping ( self . ready ) ; // `recv_end_pos` is the stream position at the end of the maximum capacity of the receive // buffer. let recv_end_pos = self . recv_pos + Wrapping ( self . capacity as u32 - self . ready ) ; // `end_pos` is the stream position at the end of the input data let end_pos = start_pos + Wrapping ( data . len ( ) as u32 ) ; // If stream positions were strictly ordered this would not be necessary, but this check // combined with the assertions that `data.len() <= u32::MAX / 2` and `self.capacity <= // u32::MAX / 2` should prevent wrapping issues. if stream_gt ( & start_pos , & recv_end_pos ) { return None ; } // `copy_start_pos` is the stream position at either the given `start_pos`, or the current // receive position, whichever is greater.  We do not copy data that has already been // received, so this is where we will begin copying. let copy_start_pos = if stream_gt ( & self . recv_pos , & start_pos ) { self . recv_pos } else { start_pos } ; // We calculate the `end_pos` as being either the previous `end_pos` or the stream position // at the maximum capacity of the receive buffer.  We should not read more data than the // requested buffer capacity can hold. let end_pos = if stream_lt ( & end_pos , & recv_end_pos ) { end_pos } else { recv_end_pos } ; // If we are not copying any new data (the range from `copy_start_pos` to `end_pos` is // empty), then we are done. if stream_ge ( & copy_start_pos , & end_pos ) { // We should only return and end position if there is actually acknowledged data (it // doesn't matter if the data has already been read and we skip copying it). if stream_lt ( & start_pos , & end_pos ) { return Some ( end_pos ) ; } else { return None ; } } // The index in the destination buffer where we start copying from let data_start = ( copy_start_pos - start_pos ) . 0 as usize ; // The index in the receive buffer where we start copying to let buf_start = ( copy_start_pos - recv_start_pos ) . 0 as usize ; // The index in the receive buffer where we stop copying let buf_end = ( end_pos - recv_start_pos ) . 0 as usize ; assert ! ( buf_end self capacity as usize ) ; self . buffer . resize ( self . buffer . len ( ) . max ( buf_end ) , 0 ) ; for i in buf_start .. buf_end { self . buffer [ i ] = data [ i - buf_start + data_start ] ; } // Very, very carefully, combine this newly received region with the existing unready // regions and maintain all the invariants of the unready list. if stream_ge ( & self . recv_pos , & start_pos ) { // If this received region touches the end of the ready block, we need to combine this // region with the ready block, and any unready regions that it overlaps with also need // to be combined into the ready block. let pos = match self . unready . binary_search_by ( | ( _ , end ) | stream_cmp ( end , & end_pos ) ) { Ok ( i ) => i , Err ( i ) => i , } ; let end = if pos == self . unready . len ( ) { self . unready . clear ( ) ; end_pos } else if end_pos >= self . unready [ pos ] . 0 { let end = self . unready [ pos ] . 1 ; self . unready . drain ( 0 ..= pos ) ; end } else { end_pos } ; self . ready += ( end - self . recv_pos ) . 0 ; self . recv_pos = end ; } else { // If this received region does not touch the end of the ready block, we just need to // combine this with the other unready regions to maintain the invariants.  It must be // combined with any overlapping unready regions or any unready regions that are exactly // next to each other. let insert_pos = match self . unready . binary_search_by ( | ( _ , end ) | stream_cmp ( end , & start_pos ) ) { Ok ( i ) => i , Err ( i ) => i , } ; if insert_pos == self . unready . len ( ) { self . unready . push ( ( start_pos , end_pos ) ) ; } else if stream_lt ( & end_pos , & self . unready [ insert_pos ] . 0 ) { self . unready . insert ( insert_pos , ( start_pos , end_pos ) ) ; } else { let start = self . unready [ insert_pos ] . 0 ; for i in insert_pos .. self . unready . len ( ) { if stream_lt ( & end_pos , & self . unready [ i ] . 0 ) { self . unready . drain ( insert_pos + 1 .. i ) ; self . unready [ insert_pos ] . 0 = start . min ( start_pos ) ; self . unready [ insert_pos ] . 1 = end_pos ; break ; } else if stream_lt ( & end_pos , & self . unready [ i ] . 1 ) || i == self . unready . len ( ) - 1 { self . unready . drain ( insert_pos .. i ) ; self . unready [ insert_pos ] . 0 = start . min ( start_pos ) ; self . unready [ insert_pos ] . 1 = self . unready [ insert_pos ] . 1 . max ( end_pos ) ; break ; } } } } Some ( end_pos ) }
Receive a new block of data and return the upper bound of the stream range that was
successfully stored.
Receive a new block of data and return the upper bound of the stream range that was successfully stored .
&mut self
start_pos
StreamPos
data
&[u8]
&mut self
start_pos
StreamPos
data
&[u8]