/* Function which parsers headers into uninitialized buffer.
 *
 * Guarantees that it doesn't write garbage, so casting
 * &mut &mut [Header] -> &mut &mut [MaybeUninit<Header>]
 * is safe here.
 *
 * Also it promises `headers` get shrunk to number of initialized headers,
 * so casting the other way around after calling this function is safe
 */
Function which parsers headers into uninitialized buffer.
Guarantees that it doesn't write garbage, so casting
&mut &mut [Header] -> &mut &mut [MaybeUninit]
is safe here.

Also it promises `headers` get shrunk to number of initialized headers,
so casting the other way around after calling this function is safe
Function which parsers headers into uninitialized buffer . Guarantees that it doesn ' t write garbage so casting &mut &mut [ Header ] - > &mut &mut [ MaybeUninit ] is safe here . Also it promises ` headers ` get shrunk to number of initialized headers so casting the other way around after calling this function is safe
fn parse_headers_iter_uninit<'a, 'b>(
    headers: &mut &mut [MaybeUninit<Header<'a>>],
    bytes: &'b mut Bytes<'a>,
    config: &ParserConfig,
) -> Result<usize> {
    /* Flow of this function is pretty complex, especially with macros,
     * so this struct makes sure we shrink `headers` to only parsed ones.
     * Comparing to previous code, this only may introduce some additional
     * instructions in case of early return */
    struct ShrinkOnDrop<'r1, 'r2, 'a> {
        headers: &'r1 mut &'r2 mut [MaybeUninit<Header<'a>>],
        num_headers: usize,
    }
    impl<'r1, 'r2, 'a> Drop for ShrinkOnDrop<'r1, 'r2, 'a> {
        fn drop(&mut self) {
            let headers = mem::replace(self.headers, &mut []);
            /* SAFETY: num_headers is the number of initialized headers */
            let headers = unsafe { headers.get_unchecked_mut(..self.num_headers) };
            *self.headers = headers;
        }
    }
    let mut autoshrink = ShrinkOnDrop {
        headers,
        num_headers: 0,
    };
    let mut count: usize = 0;
    let mut result = Err(Error::TooManyHeaders);
    let mut iter = autoshrink.headers.iter_mut();
    'headers: loop {
        // a newline here means the head is over!
        let b = next!(bytes);
        if b == b'\r' {
            expect!(bytes.next() == b'\n' => Err(Error::NewLine));
            result = Ok(Status::Complete(count + bytes.pos()));
            break;
        } else if b == b'\n' {
            result = Ok(Status::Complete(count + bytes.pos()));
            break;
        } else if !is_header_name_token(b) {
            return Err(Error::HeaderName);
        }
        let uninit_header = match iter.next() {
            Some(header) => header,
            None => break 'headers
        };
        // parse header name until colon
        let header_name: &str = 'name: loop {
            let b = next!(bytes);
            if b == b':' {
                count += bytes.pos();
                let _name = unsafe {
                    str::from_utf8_unchecked(bytes.slice_skip(1))
                };
                break 'name _name;
            } else if !is_header_name_token(b) {
                if !config.allow_spaces_after_header_name_in_responses {
                    return Err(Error::HeaderName);
                }
                count += bytes.pos();
                let _name = unsafe { str::from_utf8_unchecked(bytes.slice_skip(1)) };
                // eat white space between name and colon
                'whitespace_before_colon: loop {
                    let b = next!(bytes);
                    if b == b' ' || b == b'\t' {
                        count += bytes.pos();
                        bytes.slice();
                        continue 'whitespace_before_colon;
                    } else if b == b':' {
                        count += bytes.pos();
                        bytes.slice();
                        break 'name _name;
                    } else {
                        return Err(Error::HeaderName);
                    }
                }
            }
        };
        let mut b;
        'value: loop {
            // eat white space between colon and value
            'whitespace_after_colon: loop {
                b = next!(bytes);
                if b == b' ' || b == b'\t' {
                    count += bytes.pos();
                    bytes.slice();
                    continue 'whitespace_after_colon;
                } else {
                    if !is_header_value_token(b) {
                        break 'value;
                    }
                    break 'whitespace_after_colon;
                }
            }
            // parse value till EOL
            simd::match_header_value_vectored(bytes);
            macro_rules! check {
                ($bytes:ident, $i:ident) => ({
                    b = $bytes.$i();
                    if !is_header_value_token(b) {
                        break 'value;
                    }
                });
                ($bytes:ident) => ({
                    check!($bytes, _0);
                    check!($bytes, _1);
                    check!($bytes, _2);
                    check!($bytes, _3);
                    check!($bytes, _4);
                    check!($bytes, _5);
                    check!($bytes, _6);
                    check!($bytes, _7);
                })
            }
            while let Some(mut bytes8) = bytes.next_8() {
                check!(bytes8);
            }
            loop {
                b = next!(bytes);
                if !is_header_value_token(b) {
                    break 'value;
                }
            }
        }
        //found_ctl
        let value_slice : &[u8] = if b == b'\r' {
            expect!(bytes.next() == b'\n' => Err(Error::HeaderValue));
            count += bytes.pos();
            // having just check that `\r\n` exists, it's safe to skip those 2 bytes
            unsafe {
                bytes.slice_skip(2)
            }
        } else if b == b'\n' {
            count += bytes.pos();
            // having just check that `\r\n` exists, it's safe to skip 1 byte
            unsafe {
                bytes.slice_skip(1)
            }
        } else {
            return Err(Error::HeaderValue);
        };
        let header_value: &[u8];
        // trim trailing whitespace in the header
        if let Some(last_visible) = value_slice.iter().rposition(|b| *b != b' ' && *b != b'\t' ) {
            // There is at least one non-whitespace character.
            header_value = &value_slice[0..last_visible+1];
        } else {
            // There is no non-whitespace character. This can only happen when value_slice is
            // empty.
            header_value = value_slice;
        }
        *uninit_header = MaybeUninit::new(Header {
            name: header_name,
            value: header_value,
        });
        autoshrink.num_headers += 1;
    }
    result
}
fn parse_headers_iter_uninit < ' a , ' b > ( headers : & mut & mut [ MaybeUninit < Header < ' a > > ] , bytes : & ' b mut Bytes < ' a > , config : & ParserConfig , ) -> Result < usize > { /* Flow of this function is pretty complex, especially with macros,
     * so this struct makes sure we shrink `headers` to only parsed ones.
     * Comparing to previous code, this only may introduce some additional
     * instructions in case of early return */ struct ShrinkOnDrop < ' r1 , ' r2 , ' a > { headers : & ' r1 mut & ' r2 mut [ MaybeUninit < Header < ' a > > ] , num_headers : usize , } impl < ' r1 , ' r2 , ' a > Drop for ShrinkOnDrop < ' r1 , ' r2 , ' a > { fn drop ( & mut self ) { let headers = mem :: replace ( self . headers , & mut [ ] ) ; /* SAFETY: num_headers is the number of initialized headers */ let headers = unsafe { headers . get_unchecked_mut ( .. self . num_headers ) } ; * self . headers = headers ; } } let mut autoshrink = ShrinkOnDrop { headers , num_headers : 0 , } ; let mut count : usize = 0 ; let mut result = Err ( Error :: TooManyHeaders ) ; let mut iter = autoshrink . headers . iter_mut ( ) ; ' headers : loop { // a newline here means the head is over! let b = next ! ( bytes ) ; if b == b'\r' { expect ! ( bytes next ( ) b'\n' Err ( Error NewLine ) ) ; result = Ok ( Status :: Complete ( count + bytes . pos ( ) ) ) ; break ; } else if b == b'\n' { result = Ok ( Status :: Complete ( count + bytes . pos ( ) ) ) ; break ; } else if ! is_header_name_token ( b ) { return Err ( Error :: HeaderName ) ; } let uninit_header = match iter . next ( ) { Some ( header ) => header , None => break ' headers } ; // parse header name until colon let header_name : & str = ' name : loop { let b = next ! ( bytes ) ; if b == b':' { count += bytes . pos ( ) ; let _name = unsafe { str :: from_utf8_unchecked ( bytes . slice_skip ( 1 ) ) } ; break ' name _name ; } else if ! is_header_name_token ( b ) { if ! config . allow_spaces_after_header_name_in_responses { return Err ( Error :: HeaderName ) ; } count += bytes . pos ( ) ; let _name = unsafe { str :: from_utf8_unchecked ( bytes . slice_skip ( 1 ) ) } ; // eat white space between name and colon ' whitespace_before_colon : loop { let b = next ! ( bytes ) ; if b == b' ' || b == b'\t' { count += bytes . pos ( ) ; bytes . slice ( ) ; continue ' whitespace_before_colon ; } else if b == b':' { count += bytes . pos ( ) ; bytes . slice ( ) ; break ' name _name ; } else { return Err ( Error :: HeaderName ) ; } } } } ; let mut b ; ' value : loop { // eat white space between colon and value ' whitespace_after_colon : loop { b = next ! ( bytes ) ; if b == b' ' || b == b'\t' { count += bytes . pos ( ) ; bytes . slice ( ) ; continue ' whitespace_after_colon ; } else { if ! is_header_value_token ( b ) { break ' value ; } break ' whitespace_after_colon ; } } // parse value till EOL simd :: match_header_value_vectored ( bytes ) ; macro_rules! check { ( $bytes : ident $i : ident ) => ( { b $bytes $i ( ) if is_header_value_token ( b ) { break ' value } } ) ; ( $bytes : ident ) => ( { check ( $bytes _0 ) check ( $bytes _1 ) check ( $bytes _2 ) check ( $bytes _3 ) check ( $bytes _4 ) check ( $bytes _5 ) check ( $bytes _6 ) check ( $bytes _7 ) } ) } while let Some ( mut bytes8 ) = bytes . next_8 ( ) { check ! ( bytes8 ) ; } loop { b = next ! ( bytes ) ; if ! is_header_value_token ( b ) { break ' value ; } } } //found_ctl let value_slice : & [ u8 ] = if b == b'\r' { expect ! ( bytes next ( ) b'\n' Err ( Error HeaderValue ) ) ; count += bytes . pos ( ) ; // having just check that `\r\n` exists, it's safe to skip those 2 bytes unsafe { bytes . slice_skip ( 2 ) } } else if b == b'\n' { count += bytes . pos ( ) ; // having just check that `\r\n` exists, it's safe to skip 1 byte unsafe { bytes . slice_skip ( 1 ) } } else { return Err ( Error :: HeaderValue ) ; } ; let header_value : & [ u8 ] ; // trim trailing whitespace in the header if let Some ( last_visible ) = value_slice . iter ( ) . rposition ( | b | * b != b' ' && * b != b'\t' ) { // There is at least one non-whitespace character. header_value = & value_slice [ 0 .. last_visible + 1 ] ; } else { // There is no non-whitespace character. This can only happen when value_slice is // empty. header_value = value_slice ; } * uninit_header = MaybeUninit :: new ( Header { name : header_name , value : header_value , } ) ; autoshrink . num_headers += 1 ; } result }
Function which parsers headers into uninitialized buffer.
Function which parsers headers into uninitialized buffer .
headers
&mut &mut [MaybeUninit<Header<'a>>]
bytes
&'b mut Bytes<'a>
config
&ParserConfig