pub fn new(mut reader: R) -> io::Result<Cabinet<R>> {
        let signature = reader.read_u32::<LittleEndian>()?;
        if signature != consts::FILE_SIGNATURE {
            invalid_data!("Not a cabinet file (invalid file signature)");
        }
        let _reserved1 = reader.read_u32::<LittleEndian>()?;
        let total_size = reader.read_u32::<LittleEndian>()?;
        if total_size > consts::MAX_TOTAL_CAB_SIZE {
            invalid_data!(
                "Cabinet total size field is too large \
                 ({} bytes; max is {} bytes)",
                total_size,
                consts::MAX_TOTAL_CAB_SIZE
            );
        }
        let _reserved2 = reader.read_u32::<LittleEndian>()?;
        let first_file_offset = reader.read_u32::<LittleEndian>()?;
        let _reserved3 = reader.read_u32::<LittleEndian>()?;
        let minor_version = reader.read_u8()?;
        let major_version = reader.read_u8()?;
        if major_version > consts::VERSION_MAJOR
            || major_version == consts::VERSION_MAJOR
                && minor_version > consts::VERSION_MINOR
        {
            invalid_data!(
                "Version {}.{} cabinet files are not supported",
                major_version,
                minor_version
            );
        }
        let num_folders = reader.read_u16::<LittleEndian>()? as usize;
        let num_files = reader.read_u16::<LittleEndian>()?;
        let flags = reader.read_u16::<LittleEndian>()?;
        let cabinet_set_id = reader.read_u16::<LittleEndian>()?;
        let cabinet_set_index = reader.read_u16::<LittleEndian>()?;
        let mut header_reserve_size = 0u16;
        let mut folder_reserve_size = 0u8;
        let mut data_reserve_size = 0u8;
        if (flags & consts::FLAG_RESERVE_PRESENT) != 0 {
            header_reserve_size = reader.read_u16::<LittleEndian>()?;
            folder_reserve_size = reader.read_u8()?;
            data_reserve_size = reader.read_u8()?;
        }
        let mut header_reserve_data = vec![0u8; header_reserve_size as usize];
        if header_reserve_size > 0 {
            reader.read_exact(&mut header_reserve_data)?;
        }
        let _prev_cabinet = if (flags & consts::FLAG_PREV_CABINET) != 0 {
            let cab_name = read_null_terminated_string(&mut reader, false)?;
            let disk_name = read_null_terminated_string(&mut reader, false)?;
            Some((cab_name, disk_name))
        } else {
            None
        };
        let _next_cabinet = if (flags & consts::FLAG_NEXT_CABINET) != 0 {
            let cab_name = read_null_terminated_string(&mut reader, false)?;
            let disk_name = read_null_terminated_string(&mut reader, false)?;
            Some((cab_name, disk_name))
        } else {
            None
        };
        let mut folders = Vec::<FolderEntry>::with_capacity(num_folders);
        for _ in 0..num_folders {
            let first_data_offset = reader.read_u32::<LittleEndian>()?;
            let num_data_blocks = reader.read_u16::<LittleEndian>()?;
            let compression_bits = reader.read_u16::<LittleEndian>()?;
            let compression_type =
                CompressionType::from_bitfield(compression_bits)?;
            let mut folder_reserve_data =
                vec![0u8; folder_reserve_size as usize];
            if folder_reserve_size > 0 {
                reader.read_exact(&mut folder_reserve_data)?;
            }
            let entry = FolderEntry {
                first_data_block_offset: first_data_offset,
                num_data_blocks,
                compression_type,
                reserve_data: folder_reserve_data,
                files: Vec::new(),
            };
            folders.push(entry);
        }
        reader.seek(SeekFrom::Start(first_file_offset as u64))?;
        for _ in 0..num_files {
            let uncompressed_size = reader.read_u32::<LittleEndian>()?;
            let uncompressed_offset = reader.read_u32::<LittleEndian>()?;
            let folder_index = reader.read_u16::<LittleEndian>()? as usize;
            if folder_index >= folders.len() {
                invalid_data!("File entry folder index out of bounds");
            }
            let date = reader.read_u16::<LittleEndian>()?;
            let time = reader.read_u16::<LittleEndian>()?;
            let datetime = datetime_from_bits(date, time);
            let attributes = reader.read_u16::<LittleEndian>()?;
            let is_utf8 = (attributes & consts::ATTR_NAME_IS_UTF) != 0;
            let name = read_null_terminated_string(&mut reader, is_utf8)?;
            let entry = FileEntry {
                name,
                datetime,
                uncompressed_size,
                uncompressed_offset,
                attributes,
            };
            folders[folder_index].files.push(entry);
        }
        Ok(Cabinet {
            reader,
            cabinet_set_id,
            cabinet_set_index,
            data_reserve_size,
            reserve_data: header_reserve_data,
            folders,
        })
    }
/// Open an existing cabinet file.
Open an existing cabinet file.
Open an existing cabinet file .
pub fn new(mut reader: R) -> io::Result<Cabinet<R>> {
        let signature = reader.read_u32::<LittleEndian>()?;
        if signature != consts::FILE_SIGNATURE {
            invalid_data!("Not a cabinet file (invalid file signature)");
        }
        let _reserved1 = reader.read_u32::<LittleEndian>()?;
        let total_size = reader.read_u32::<LittleEndian>()?;
        if total_size > consts::MAX_TOTAL_CAB_SIZE {
            invalid_data!(
                "Cabinet total size field is too large \
                 ({} bytes; max is {} bytes)",
                total_size,
                consts::MAX_TOTAL_CAB_SIZE
            );
        }
        let _reserved2 = reader.read_u32::<LittleEndian>()?;
        let first_file_offset = reader.read_u32::<LittleEndian>()?;
        let _reserved3 = reader.read_u32::<LittleEndian>()?;
        let minor_version = reader.read_u8()?;
        let major_version = reader.read_u8()?;
        if major_version > consts::VERSION_MAJOR
            || major_version == consts::VERSION_MAJOR
                && minor_version > consts::VERSION_MINOR
        {
            invalid_data!(
                "Version {}.{} cabinet files are not supported",
                major_version,
                minor_version
            );
        }
        let num_folders = reader.read_u16::<LittleEndian>()? as usize;
        let num_files = reader.read_u16::<LittleEndian>()?;
        let flags = reader.read_u16::<LittleEndian>()?;
        let cabinet_set_id = reader.read_u16::<LittleEndian>()?;
        let cabinet_set_index = reader.read_u16::<LittleEndian>()?;
        let mut header_reserve_size = 0u16;
        let mut folder_reserve_size = 0u8;
        let mut data_reserve_size = 0u8;
        if (flags & consts::FLAG_RESERVE_PRESENT) != 0 {
            header_reserve_size = reader.read_u16::<LittleEndian>()?;
            folder_reserve_size = reader.read_u8()?;
            data_reserve_size = reader.read_u8()?;
        }
        let mut header_reserve_data = vec![0u8; header_reserve_size as usize];
        if header_reserve_size > 0 {
            reader.read_exact(&mut header_reserve_data)?;
        }
        let _prev_cabinet = if (flags & consts::FLAG_PREV_CABINET) != 0 {
            let cab_name = read_null_terminated_string(&mut reader, false)?;
            let disk_name = read_null_terminated_string(&mut reader, false)?;
            Some((cab_name, disk_name))
        } else {
            None
        };
        let _next_cabinet = if (flags & consts::FLAG_NEXT_CABINET) != 0 {
            let cab_name = read_null_terminated_string(&mut reader, false)?;
            let disk_name = read_null_terminated_string(&mut reader, false)?;
            Some((cab_name, disk_name))
        } else {
            None
        };
        let mut folders = Vec::<FolderEntry>::with_capacity(num_folders);
        for _ in 0..num_folders {
            let first_data_offset = reader.read_u32::<LittleEndian>()?;
            let num_data_blocks = reader.read_u16::<LittleEndian>()?;
            let compression_bits = reader.read_u16::<LittleEndian>()?;
            let compression_type =
                CompressionType::from_bitfield(compression_bits)?;
            let mut folder_reserve_data =
                vec![0u8; folder_reserve_size as usize];
            if folder_reserve_size > 0 {
                reader.read_exact(&mut folder_reserve_data)?;
            }
            let entry = FolderEntry {
                first_data_block_offset: first_data_offset,
                num_data_blocks,
                compression_type,
                reserve_data: folder_reserve_data,
                files: Vec::new(),
            };
            folders.push(entry);
        }
        reader.seek(SeekFrom::Start(first_file_offset as u64))?;
        for _ in 0..num_files {
            let uncompressed_size = reader.read_u32::<LittleEndian>()?;
            let uncompressed_offset = reader.read_u32::<LittleEndian>()?;
            let folder_index = reader.read_u16::<LittleEndian>()? as usize;
            if folder_index >= folders.len() {
                invalid_data!("File entry folder index out of bounds");
            }
            let date = reader.read_u16::<LittleEndian>()?;
            let time = reader.read_u16::<LittleEndian>()?;
            let datetime = datetime_from_bits(date, time);
            let attributes = reader.read_u16::<LittleEndian>()?;
            let is_utf8 = (attributes & consts::ATTR_NAME_IS_UTF) != 0;
            let name = read_null_terminated_string(&mut reader, is_utf8)?;
            let entry = FileEntry {
                name,
                datetime,
                uncompressed_size,
                uncompressed_offset,
                attributes,
            };
            folders[folder_index].files.push(entry);
        }
        Ok(Cabinet {
            reader,
            cabinet_set_id,
            cabinet_set_index,
            data_reserve_size,
            reserve_data: header_reserve_data,
            folders,
        })
    }
pub fn new ( mut reader : R ) -> io :: Result < Cabinet < R > > { let signature = reader . read_u32 :: < LittleEndian > ( ) ? ; if signature != consts :: FILE_SIGNATURE { invalid_data ! ( " " ) ; } let _reserved1 = reader . read_u32 :: < LittleEndian > ( ) ? ; let total_size = reader . read_u32 :: < LittleEndian > ( ) ? ; if total_size > consts :: MAX_TOTAL_CAB_SIZE { invalid_data ! ( " \
 " total_size consts MAX_TOTAL_CAB_SIZE ) ; } let _reserved2 = reader . read_u32 :: < LittleEndian > ( ) ? ; let first_file_offset = reader . read_u32 :: < LittleEndian > ( ) ? ; let _reserved3 = reader . read_u32 :: < LittleEndian > ( ) ? ; let minor_version = reader . read_u8 ( ) ? ; let major_version = reader . read_u8 ( ) ? ; if major_version > consts :: VERSION_MAJOR || major_version == consts :: VERSION_MAJOR && minor_version > consts :: VERSION_MINOR { invalid_data ! ( " " major_version minor_version ) ; } let num_folders = reader . read_u16 :: < LittleEndian > ( ) ? as usize ; let num_files = reader . read_u16 :: < LittleEndian > ( ) ? ; let flags = reader . read_u16 :: < LittleEndian > ( ) ? ; let cabinet_set_id = reader . read_u16 :: < LittleEndian > ( ) ? ; let cabinet_set_index = reader . read_u16 :: < LittleEndian > ( ) ? ; let mut header_reserve_size = 0u16 ; let mut folder_reserve_size = 0u8 ; let mut data_reserve_size = 0u8 ; if ( flags & consts :: FLAG_RESERVE_PRESENT ) != 0 { header_reserve_size = reader . read_u16 :: < LittleEndian > ( ) ? ; folder_reserve_size = reader . read_u8 ( ) ? ; data_reserve_size = reader . read_u8 ( ) ? ; } let mut header_reserve_data = vec ! [ 0u8 header_reserve_size as usize ] ; if header_reserve_size > 0 { reader . read_exact ( & mut header_reserve_data ) ? ; } let _prev_cabinet = if ( flags & consts :: FLAG_PREV_CABINET ) != 0 { let cab_name = read_null_terminated_string ( & mut reader , false ) ? ; let disk_name = read_null_terminated_string ( & mut reader , false ) ? ; Some ( ( cab_name , disk_name ) ) } else { None } ; let _next_cabinet = if ( flags & consts :: FLAG_NEXT_CABINET ) != 0 { let cab_name = read_null_terminated_string ( & mut reader , false ) ? ; let disk_name = read_null_terminated_string ( & mut reader , false ) ? ; Some ( ( cab_name , disk_name ) ) } else { None } ; let mut folders = Vec :: < FolderEntry > :: with_capacity ( num_folders ) ; for _ in 0 .. num_folders { let first_data_offset = reader . read_u32 :: < LittleEndian > ( ) ? ; let num_data_blocks = reader . read_u16 :: < LittleEndian > ( ) ? ; let compression_bits = reader . read_u16 :: < LittleEndian > ( ) ? ; let compression_type = CompressionType :: from_bitfield ( compression_bits ) ? ; let mut folder_reserve_data = vec ! [ 0u8 folder_reserve_size as usize ] ; if folder_reserve_size > 0 { reader . read_exact ( & mut folder_reserve_data ) ? ; } let entry = FolderEntry { first_data_block_offset : first_data_offset , num_data_blocks , compression_type , reserve_data : folder_reserve_data , files : Vec :: new ( ) , } ; folders . push ( entry ) ; } reader . seek ( SeekFrom :: Start ( first_file_offset as u64 ) ) ? ; for _ in 0 .. num_files { let uncompressed_size = reader . read_u32 :: < LittleEndian > ( ) ? ; let uncompressed_offset = reader . read_u32 :: < LittleEndian > ( ) ? ; let folder_index = reader . read_u16 :: < LittleEndian > ( ) ? as usize ; if folder_index >= folders . len ( ) { invalid_data ! ( " " ) ; } let date = reader . read_u16 :: < LittleEndian > ( ) ? ; let time = reader . read_u16 :: < LittleEndian > ( ) ? ; let datetime = datetime_from_bits ( date , time ) ; let attributes = reader . read_u16 :: < LittleEndian > ( ) ? ; let is_utf8 = ( attributes & consts :: ATTR_NAME_IS_UTF ) != 0 ; let name = read_null_terminated_string ( & mut reader , is_utf8 ) ? ; let entry = FileEntry { name , datetime , uncompressed_size , uncompressed_offset , attributes , } ; folders [ folder_index ] . files . push ( entry ) ; } Ok ( Cabinet { reader , cabinet_set_id , cabinet_set_index , data_reserve_size , reserve_data : header_reserve_data , folders , } ) }
Open an existing cabinet file.
Open an existing cabinet file .
reader
R
reader
R