pub(crate) fn decompress(
        &self,
        mut dest: Vec<u8>,
        src: &[u8],
        marker: CompressType,
        extra_size: usize,
        max_size: usize,
    ) -> Result<Vec<u8>> {
        match marker {
            CompressType::NoCompress => {
                if dest.len() + src.len() + extra_size > max_size {
                    Err(Error::FailDecompress(format!(
                        "Decompressed length {} would be larger than maximum of {}",
                        dest.len() + src.len() + extra_size,
                        max_size
                    )))
                } else {
                    dest.reserve(src.len() + extra_size);
                    dest.extend_from_slice(src);
                    Ok(dest)
                }
            }
            CompressType::Compress => {
                // Prep for decomressed data
                let header_len = dest.len();
                let expected_len = zstd_safe::get_frame_content_size(src);
                if expected_len > (max_size - header_len) as u64 {
                    return Err(Error::FailDecompress(format!(
                        "Decompressed length {} would be larger than maximum of {}",
                        dest.len() + src.len(),
                        max_size
                    )));
                }
                let expected_len = expected_len as usize;
                dest.reserve(expected_len + extra_size);

                // Safety: Immediately before this, we reserve enough space for the header and the
                // expected length, so setting the length is OK. The decompress function overwrites
                // data and returns the new valid length, so no data is uninitialized after this
                // block completes. In the event of a failure, the vec is freed, so it is never
                // returned in an invalid state.
                unsafe {
                    dest.set_len(header_len + expected_len);
                    let len = zstd_safe::decompress(&mut dest[header_len..], src).map_err(|e| {
                        Error::FailDecompress(format!("Failed Decompression, zstd error = {}", e))
                    })?;
                    dest.truncate(header_len + len);
                }
                Ok(dest)
            }
            CompressType::DictCompress => {
                // Fetch dictionary
                let ddict = if let Compress::Dict(Dictionary(DictionaryPrivate::Zstd {
                    ddict,
                    ..
                })) = self
                {
                    ddict
                } else {
                    return Err(Error::BadHeader(
                            "Header uses dictionary compression, but this has no matching supported dictionary".into()));
                };

                // Prep for decompressed data
                let header_len = dest.len();
                let expected_len = zstd_safe::get_frame_content_size(src);
                if expected_len > (max_size - header_len) as u64 {
                    return Err(Error::FailDecompress(format!(
                        "Decompressed length {} would be larger than maximum of {}",
                        dest.len() + src.len(),
                        max_size
                    )));
                }
                let expected_len = expected_len as usize;
                dest.reserve(expected_len + extra_size);

                // Safety: Immediately before this, we reserve enough space for the header and the
                // expected length, so setting the length is OK. The decompress function overwrites
                // data and returns the new valid length, so no data is uninitialized after this
                // block completes. In the event of a failure, the vec is freed, so it is never
                // returned in an invalid state.
                unsafe {
                    dest.set_len(header_len + expected_len);
                    let mut dctx = zstd_safe::create_dctx();
                    let len = dctx
                        .decompress_using_ddict(&mut dest[header_len..], src, ddict)
                        .map_err(|e| {
                            Error::FailDecompress(format!(
                                "Failed Decompression, zstd error = {}",
                                e
                            ))
                        })?;
                    dest.truncate(header_len + len);
                }
                Ok(dest)
            }
        }
    }
/// Attempt to decompress the data. Fails if the result in `dest` would be greater than
/// `max_size`, or if decompression fails.
Attempt to decompress the data. Fails if the result in `dest` would be greater than
`max_size`, or if decompression fails.
Attempt to decompress the data . Fails if the result in ` dest ` would be greater than ` max_size ` or if decompression fails .
pub(crate) fn decompress(
        &self,
        mut dest: Vec<u8>,
        src: &[u8],
        marker: CompressType,
        extra_size: usize,
        max_size: usize,
    ) -> Result<Vec<u8>> {
        match marker {
            CompressType::NoCompress => {
                if dest.len() + src.len() + extra_size > max_size {
                    Err(Error::FailDecompress(format!(
                        "Decompressed length {} would be larger than maximum of {}",
                        dest.len() + src.len() + extra_size,
                        max_size
                    )))
                } else {
                    dest.reserve(src.len() + extra_size);
                    dest.extend_from_slice(src);
                    Ok(dest)
                }
            }
            CompressType::Compress => {
                // Prep for decomressed data
                let header_len = dest.len();
                let expected_len = zstd_safe::get_frame_content_size(src);
                if expected_len > (max_size - header_len) as u64 {
                    return Err(Error::FailDecompress(format!(
                        "Decompressed length {} would be larger than maximum of {}",
                        dest.len() + src.len(),
                        max_size
                    )));
                }
                let expected_len = expected_len as usize;
                dest.reserve(expected_len + extra_size);
                // Safety: Immediately before this, we reserve enough space for the header and the
                // expected length, so setting the length is OK. The decompress function overwrites
                // data and returns the new valid length, so no data is uninitialized after this
                // block completes. In the event of a failure, the vec is freed, so it is never
                // returned in an invalid state.
                unsafe {
                    dest.set_len(header_len + expected_len);
                    let len = zstd_safe::decompress(&mut dest[header_len..], src).map_err(|e| {
                        Error::FailDecompress(format!("Failed Decompression, zstd error = {}", e))
                    })?;
                    dest.truncate(header_len + len);
                }
                Ok(dest)
            }
            CompressType::DictCompress => {
                // Fetch dictionary
                let ddict = if let Compress::Dict(Dictionary(DictionaryPrivate::Zstd {
                    ddict,
                    ..
                })) = self
                {
                    ddict
                } else {
                    return Err(Error::BadHeader(
                            "Header uses dictionary compression, but this has no matching supported dictionary".into()));
                };
                // Prep for decompressed data
                let header_len = dest.len();
                let expected_len = zstd_safe::get_frame_content_size(src);
                if expected_len > (max_size - header_len) as u64 {
                    return Err(Error::FailDecompress(format!(
                        "Decompressed length {} would be larger than maximum of {}",
                        dest.len() + src.len(),
                        max_size
                    )));
                }
                let expected_len = expected_len as usize;
                dest.reserve(expected_len + extra_size);
                // Safety: Immediately before this, we reserve enough space for the header and the
                // expected length, so setting the length is OK. The decompress function overwrites
                // data and returns the new valid length, so no data is uninitialized after this
                // block completes. In the event of a failure, the vec is freed, so it is never
                // returned in an invalid state.
                unsafe {
                    dest.set_len(header_len + expected_len);
                    let mut dctx = zstd_safe::create_dctx();
                    let len = dctx
                        .decompress_using_ddict(&mut dest[header_len..], src, ddict)
                        .map_err(|e| {
                            Error::FailDecompress(format!(
                                "Failed Decompression, zstd error = {}",
                                e
                            ))
                        })?;
                    dest.truncate(header_len + len);
                }
                Ok(dest)
            }
        }
    }
pub ( crate ) fn decompress ( & self , mut dest : Vec < u8 > , src : & [ u8 ] , marker : CompressType , extra_size : usize , max_size : usize , ) -> Result < Vec < u8 > > { match marker { CompressType :: NoCompress => { if dest . len ( ) + src . len ( ) + extra_size > max_size { Err ( Error :: FailDecompress ( format ! ( " " dest len ( ) src len ( ) extra_size max_size ) ) ) } else { dest . reserve ( src . len ( ) + extra_size ) ; dest . extend_from_slice ( src ) ; Ok ( dest ) } } CompressType :: Compress => { // Prep for decomressed data let header_len = dest . len ( ) ; let expected_len = zstd_safe :: get_frame_content_size ( src ) ; if expected_len > ( max_size - header_len ) as u64 { return Err ( Error :: FailDecompress ( format ! ( " " dest len ( ) src len ( ) max_size ) ) ) ; } let expected_len = expected_len as usize ; dest . reserve ( expected_len + extra_size ) ; // Safety: Immediately before this, we reserve enough space for the header and the // expected length, so setting the length is OK. The decompress function overwrites // data and returns the new valid length, so no data is uninitialized after this // block completes. In the event of a failure, the vec is freed, so it is never // returned in an invalid state. unsafe { dest . set_len ( header_len + expected_len ) ; let len = zstd_safe :: decompress ( & mut dest [ header_len .. ] , src ) . map_err ( | e | { Error :: FailDecompress ( format ! ( " " e ) ) } ) ? ; dest . truncate ( header_len + len ) ; } Ok ( dest ) } CompressType :: DictCompress => { // Fetch dictionary let ddict = if let Compress :: Dict ( Dictionary ( DictionaryPrivate :: Zstd { ddict , .. } ) ) = self { ddict } else { return Err ( Error :: BadHeader ( " " . into ( ) ) ) ; } ; // Prep for decompressed data let header_len = dest . len ( ) ; let expected_len = zstd_safe :: get_frame_content_size ( src ) ; if expected_len > ( max_size - header_len ) as u64 { return Err ( Error :: FailDecompress ( format ! ( " " dest len ( ) src len ( ) max_size ) ) ) ; } let expected_len = expected_len as usize ; dest . reserve ( expected_len + extra_size ) ; // Safety: Immediately before this, we reserve enough space for the header and the // expected length, so setting the length is OK. The decompress function overwrites // data and returns the new valid length, so no data is uninitialized after this // block completes. In the event of a failure, the vec is freed, so it is never // returned in an invalid state. unsafe { dest . set_len ( header_len + expected_len ) ; let mut dctx = zstd_safe :: create_dctx ( ) ; let len = dctx . decompress_using_ddict ( & mut dest [ header_len .. ] , src , ddict ) . map_err ( | e | { Error :: FailDecompress ( format ! ( " " e ) ) } ) ? ; dest . truncate ( header_len + len ) ; } Ok ( dest ) } } }
Attempt to decompress the data.
Attempt to decompress the data .
&self
dest
Vec<u8>
src
&[u8]
marker
CompressType
extra_size
usize
max_size
usize
&self
dest
Vec<u8>
src
&[u8]
marker
CompressType
extra_size
usize
max_size
usize