mirror of
https://github.com/tsolomko/SWCompression.git
synced 2026-06-23 14:56:41 +00:00
[ZIP] Replace stored local header and cd entry in ZipEntryInfo with separate actually required properties
This commit is contained in:
@@ -57,17 +57,13 @@ public class ZipContainer: Container {
|
||||
}
|
||||
|
||||
private static func getEntryData(from data: Data, using info: ZipEntryInfo) throws -> (data: Data, crcError: Bool) {
|
||||
let hasDataDescriptor = info.localHeader.generalPurposeBitFlags & 0x08 != 0
|
||||
|
||||
// If file has data descriptor, then some values in local header are absent.
|
||||
// So we need to use values from CD entry.
|
||||
var uncompSize = hasDataDescriptor ? info.cdEntry.uncompSize : info.localHeader.uncompSize
|
||||
var compSize = hasDataDescriptor ? info.cdEntry.compSize : info.localHeader.compSize
|
||||
var crc32 = hasDataDescriptor ? info.cdEntry.crc32 : info.localHeader.crc32
|
||||
var uncompSize = info.uncompSize
|
||||
var compSize = info.compSize
|
||||
var crc32 = info.crc
|
||||
|
||||
let fileData: Data
|
||||
let byteReader = ByteReader(data: data)
|
||||
byteReader.offset = info.localHeader.dataOffset
|
||||
byteReader.offset = info.dataOffset
|
||||
switch info.compressionMethod {
|
||||
case .copy:
|
||||
fileData = Data(bytes: byteReader.bytes(count: uncompSize.toInt()))
|
||||
@@ -100,9 +96,9 @@ public class ZipContainer: Container {
|
||||
default:
|
||||
throw ZipError.compressionNotSupported
|
||||
}
|
||||
let realCompSize = byteReader.offset - info.localHeader.dataOffset
|
||||
let realCompSize = byteReader.offset - info.dataOffset
|
||||
|
||||
if hasDataDescriptor {
|
||||
if info.hasDataDescriptor {
|
||||
// Now we need to parse data descriptor itself.
|
||||
// First, it might or might not have signature.
|
||||
let ddSignature = byteReader.uint32()
|
||||
@@ -111,7 +107,7 @@ public class ZipContainer: Container {
|
||||
}
|
||||
// Now, let's update with values from data descriptor.
|
||||
crc32 = byteReader.uint32()
|
||||
if info.localHeader.zip64FieldsArePresent {
|
||||
if info.zip64FieldsArePresent {
|
||||
compSize = byteReader.uint64()
|
||||
uncompSize = byteReader.uint64()
|
||||
} else {
|
||||
@@ -175,7 +171,7 @@ public class ZipContainer: Container {
|
||||
let info = try ZipEntryInfo(byteReader, endOfCD.currentDiskNumber)
|
||||
entries.append(info)
|
||||
// Move to the next Central Directory entry.
|
||||
byteReader.offset = info.cdEntry.nextEntryOffset
|
||||
byteReader.offset = info.nextCdEntryOffset
|
||||
}
|
||||
|
||||
return entries
|
||||
|
||||
@@ -102,20 +102,22 @@ public struct ZipEntryInfo: ContainerEntryInfo {
|
||||
/// CRC32 of entry's data.
|
||||
public let crc: UInt32
|
||||
|
||||
let cdEntry: ZipCentralDirectoryEntry
|
||||
let localHeader: ZipLocalHeader
|
||||
let hasDataDescriptor: Bool
|
||||
let zip64FieldsArePresent: Bool
|
||||
let nextCdEntryOffset: Int
|
||||
let dataOffset: Int
|
||||
let compSize: UInt64
|
||||
let uncompSize: UInt64
|
||||
|
||||
init(_ byteReader: ByteReader, _ currentDiskNumber: UInt32) throws {
|
||||
// Load and save Central Directory entry.
|
||||
// Read Central Directory entry.
|
||||
let cdEntry = try ZipCentralDirectoryEntry(byteReader)
|
||||
self.cdEntry = cdEntry
|
||||
|
||||
// Move to the location of Local Header.
|
||||
byteReader.offset = cdEntry.localHeaderOffset.toInt()
|
||||
// Load and save Local Header.
|
||||
// Read Local Header.
|
||||
let localHeader = try ZipLocalHeader(byteReader)
|
||||
try localHeader.validate(with: cdEntry, currentDiskNumber)
|
||||
self.localHeader = localHeader
|
||||
|
||||
// If file has data descriptor, then some properties are only present in CD entry.
|
||||
self.hasDataDescriptor = localHeader.generalPurposeBitFlags & 0x08 != 0
|
||||
@@ -172,7 +174,7 @@ public struct ZipEntryInfo: ContainerEntryInfo {
|
||||
}
|
||||
|
||||
// Size
|
||||
self.size = cdEntry.uncompSize.toInt()
|
||||
self.size = (hasDataDescriptor ? cdEntry.uncompSize : localHeader.uncompSize).toInt()
|
||||
|
||||
// External file attributes.
|
||||
self.externalFileAttributes = cdEntry.externalFileAttributes
|
||||
@@ -206,6 +208,13 @@ public struct ZipEntryInfo: ContainerEntryInfo {
|
||||
var customExtraFields = cdEntry.customExtraFields
|
||||
customExtraFields.append(contentsOf: localHeader.customExtraFields)
|
||||
self.customExtraFields = customExtraFields
|
||||
|
||||
// Save some properties from CD entry and Local Header.
|
||||
self.zip64FieldsArePresent = localHeader.zip64FieldsArePresent
|
||||
self.nextCdEntryOffset = cdEntry.nextEntryOffset
|
||||
self.dataOffset = localHeader.dataOffset
|
||||
self.compSize = hasDataDescriptor ? cdEntry.compSize : localHeader.compSize
|
||||
self.uncompSize = hasDataDescriptor ? cdEntry.uncompSize : localHeader.uncompSize
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user