Function init [src]

Prototype

pub fn init(input: *File.Reader) !Iterator

Parameters

input: *File.Reader

Source

pub fn init(input: *File.Reader) !Iterator { const end_record = try EndRecord.findFile(input); if (!isMaxInt(end_record.record_count_disk) and end_record.record_count_disk > end_record.record_count_total) return error.ZipDiskRecordCountTooLarge; if (end_record.disk_number != 0 or end_record.central_directory_disk_number != 0) return error.ZipMultiDiskUnsupported; { const counts_valid = !isMaxInt(end_record.record_count_disk) and !isMaxInt(end_record.record_count_total); if (counts_valid and end_record.record_count_disk != end_record.record_count_total) return error.ZipMultiDiskUnsupported; } var result: Iterator = .{ .input = input, .cd_record_count = end_record.record_count_total, .cd_zip_offset = end_record.central_directory_offset, .cd_size = end_record.central_directory_size, }; if (!end_record.need_zip64()) return result; const locator_end_offset: u64 = @as(u64, end_record.comment_len) + @sizeOf(EndRecord) + @sizeOf(EndLocator64); const stream_len = try input.getSize(); if (locator_end_offset > stream_len) return error.ZipTruncated; try input.seekTo(stream_len - locator_end_offset); const locator = input.interface.takeStruct(EndLocator64, .little) catch |err| switch (err) { error.ReadFailed => return input.err.?, error.EndOfStream => return error.EndOfStream, }; if (!std.mem.eql(u8, &locator.signature, &end_locator64_sig)) return error.ZipBadLocatorSig; if (locator.zip64_disk_count != 0) return error.ZipUnsupportedZip64DiskCount; if (locator.total_disk_count != 1) return error.ZipMultiDiskUnsupported; try input.seekTo(locator.record_file_offset); const record64 = input.interface.takeStruct(EndRecord64, .little) catch |err| switch (err) { error.ReadFailed => return input.err.?, error.EndOfStream => return error.EndOfStream, }; if (!std.mem.eql(u8, &record64.signature, &end_record64_sig)) return error.ZipBadEndRecord64Sig; if (record64.end_record_size < @sizeOf(EndRecord64) - 12) return error.ZipEndRecord64SizeTooSmall; if (record64.end_record_size > @sizeOf(EndRecord64) - 12) return error.ZipEndRecord64UnhandledExtraData; if (record64.version_needed_to_extract > 45) return error.ZipUnsupportedVersion; { const is_multidisk = record64.disk_number != 0 or record64.central_directory_disk_number != 0 or record64.record_count_disk != record64.record_count_total; if (is_multidisk) return error.ZipMultiDiskUnsupported; } if (isMaxInt(end_record.record_count_total)) { result.cd_record_count = record64.record_count_total; } else if (end_record.record_count_total != record64.record_count_total) return error.Zip64RecordCountTotalMismatch; if (isMaxInt(end_record.central_directory_offset)) { result.cd_zip_offset = record64.central_directory_offset; } else if (end_record.central_directory_offset != record64.central_directory_offset) return error.Zip64CentralDirectoryOffsetMismatch; if (isMaxInt(end_record.central_directory_size)) { result.cd_size = record64.central_directory_size; } else if (end_record.central_directory_size != record64.central_directory_size) return error.Zip64CentralDirectorySizeMismatch; return result; }