mirror of
https://github.com/tsolomko/SWCompression.git
synced 2026-06-23 14:56:41 +00:00
Remove intFromAlignedBytes function
Also changes were made to adopt this removal. This was done to improve behavior in some corner cases as well as enforce intentional usage of particular integer types.
This commit is contained in:
@@ -148,11 +148,6 @@ class BitReader: DataWithPointer {
|
||||
return super.bytes(count: count)
|
||||
}
|
||||
|
||||
override func intFromAlignedBytes(count: Int) -> Int {
|
||||
self.skipUntilNextByte()
|
||||
return super.intFromAlignedBytes(count: count)
|
||||
}
|
||||
|
||||
override func uint64(count: UInt64 = 8) -> UInt64 {
|
||||
self.skipUntilNextByte()
|
||||
return super.uint64(count: count)
|
||||
|
||||
@@ -45,12 +45,12 @@ struct CheckSums {
|
||||
return ~crc
|
||||
}
|
||||
|
||||
static func adler32(_ array: [UInt8]) -> Int {
|
||||
let base = 65521
|
||||
var s1 = 1
|
||||
var s2 = 0
|
||||
static func adler32(_ array: [UInt8]) -> UInt32 {
|
||||
let base: UInt32 = 65521
|
||||
var s1: UInt32 = 1
|
||||
var s2: UInt32 = 0
|
||||
for i in 0..<array.count {
|
||||
s1 = (s1 + array[i].toInt()) % base
|
||||
s1 = (s1 + UInt32(array[i])) % base
|
||||
s2 = (s2 + s1) % base
|
||||
}
|
||||
return (s2 << 16) + s1
|
||||
|
||||
@@ -42,15 +42,6 @@ class DataWithPointer {
|
||||
return result
|
||||
}
|
||||
|
||||
func intFromAlignedBytes(count: Int) -> Int {
|
||||
var result = 0
|
||||
for i in 0..<count {
|
||||
result |= self.data[self.index].toInt() << (8 * i)
|
||||
self.index += 1
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func uint64(count: UInt64 = 8) -> UInt64 {
|
||||
precondition(count <= 8, "UInt64 cannot store more than 8 bytes of data!")
|
||||
var result: UInt64 = 0
|
||||
|
||||
@@ -80,8 +80,8 @@ public class GzipArchive: Archive {
|
||||
let crc32 = bitReader.uint32()
|
||||
guard CheckSums.crc32(memberData) == crc32 else { throw GzipError.wrongCRC(memberData) }
|
||||
|
||||
let isize = bitReader.intFromAlignedBytes(count: 4)
|
||||
guard UInt64(memberData.count) % UInt64(1) << 32 == UInt64(isize) else { throw GzipError.wrongISize }
|
||||
let isize = bitReader.uint64(count: 4)
|
||||
guard UInt64(memberData.count) % (UInt64(1) << 32) == isize else { throw GzipError.wrongISize }
|
||||
|
||||
return Member(header: header, data: memberData)
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public struct GzipHeader {
|
||||
|
||||
init(_ pointerData: DataWithPointer) throws {
|
||||
// First two bytes should be correct 'magic' bytes
|
||||
let magic = pointerData.intFromAlignedBytes(count: 2)
|
||||
let magic = pointerData.uint16()
|
||||
guard magic == 0x8b1f else { throw GzipError.wrongMagic }
|
||||
var headerBytes: [UInt8] = [0x1f, 0x8b]
|
||||
|
||||
@@ -94,9 +94,11 @@ public struct GzipHeader {
|
||||
guard (flags & 0x20 == 0) && (flags & 0x40 == 0) && (flags & 0x80 == 0) else { throw GzipError.wrongFlags }
|
||||
headerBytes.append(flags)
|
||||
|
||||
let mtime = pointerData.intFromAlignedBytes(count: 4)
|
||||
var mtime = 0
|
||||
for i in 0..<4 {
|
||||
headerBytes.append(((mtime & (0xFF << (i * 8))) >> (i * 8)).toUInt8())
|
||||
let byte = pointerData.byte()
|
||||
mtime |= byte.toInt() << (8 * i)
|
||||
headerBytes.append(byte)
|
||||
}
|
||||
self.modificationTime = mtime == 0 ? nil : Date(timeIntervalSince1970: TimeInterval(mtime))
|
||||
|
||||
@@ -110,9 +112,11 @@ public struct GzipHeader {
|
||||
|
||||
// Some archives may contain extra fields
|
||||
if flags & Flags.fextra != 0 {
|
||||
let xlen = pointerData.intFromAlignedBytes(count: 2)
|
||||
var xlen = 0
|
||||
for i in 0..<2 {
|
||||
headerBytes.append(((xlen & (0xFF << (i * 8))) >> (i * 8)).toUInt8())
|
||||
let byte = pointerData.byte()
|
||||
xlen |= byte.toInt() << (8 * i)
|
||||
headerBytes.append(byte)
|
||||
}
|
||||
for _ in 0..<xlen {
|
||||
headerBytes.append(pointerData.byte())
|
||||
|
||||
@@ -204,11 +204,11 @@ class LZMADecoder {
|
||||
func decodeLZMA(_ externalUncompressedSize: Int? = nil) throws {
|
||||
// Firstly, we need to parse LZMA properties.
|
||||
try self.resetProperties()
|
||||
let dictSize = pointerData.intFromAlignedBytes(count: 4)
|
||||
let dictSize = pointerData.uint32().toInt()
|
||||
dictionarySize = dictSize < (1 << 12) ? 1 << 12 : dictSize
|
||||
|
||||
/// Size of uncompressed data. -1 means it is unknown/undefined.
|
||||
var uncompressedSize = pointerData.intFromAlignedBytes(count: 8)
|
||||
var uncompressedSize = pointerData.uint64().toInt()
|
||||
uncompressedSize = Double(uncompressedSize) == pow(Double(2), Double(64)) - 1 ? -1 : uncompressedSize
|
||||
|
||||
if let extUncompSize = externalUncompressedSize {
|
||||
|
||||
@@ -358,7 +358,7 @@ public class XZArchive: Archive {
|
||||
else { throw XZError.fieldReservedValue }
|
||||
|
||||
// Check footer's magic number
|
||||
guard pointerData.intFromAlignedBytes(count: 2) == 0x5A59
|
||||
guard pointerData.bytes(count: 2) == [0x59, 0x5A]
|
||||
else { throw XZError.wrongMagic }
|
||||
}
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@ import Foundation
|
||||
|
||||
struct ZipCentralDirectoryEntry {
|
||||
|
||||
let versionMadeBy: Int
|
||||
let versionNeeded: Int
|
||||
let generalPurposeBitFlags: Int
|
||||
let compressionMethod: Int
|
||||
let lastModFileTime: Int
|
||||
let lastModFileDate: Int
|
||||
let versionMadeBy: UInt16
|
||||
let versionNeeded: UInt16
|
||||
let generalPurposeBitFlags: UInt16
|
||||
let compressionMethod: UInt16
|
||||
let lastModFileTime: UInt16
|
||||
let lastModFileDate: UInt16
|
||||
let crc32: UInt32
|
||||
private(set) var compSize: UInt64
|
||||
private(set) var uncompSize: UInt64
|
||||
@@ -22,40 +22,40 @@ struct ZipCentralDirectoryEntry {
|
||||
|
||||
private(set) var diskNumberStart: UInt32
|
||||
|
||||
let internalFileAttributes: Int
|
||||
let internalFileAttributes: UInt16
|
||||
let externalFileAttributes: UInt32
|
||||
|
||||
private(set) var offset: UInt64
|
||||
|
||||
private(set) var modificationTimestamp: Int?
|
||||
private(set) var modificationTimestamp: UInt32?
|
||||
|
||||
init(_ pointerData: DataWithPointer, _ currentDiskNumber: UInt32) throws {
|
||||
// Check signature.
|
||||
guard pointerData.uint32() == 0x02014b50
|
||||
else { throw ZipError.wrongSignature }
|
||||
|
||||
self.versionMadeBy = pointerData.intFromAlignedBytes(count: 2)
|
||||
self.versionNeeded = pointerData.intFromAlignedBytes(count: 2)
|
||||
self.versionMadeBy = pointerData.uint16()
|
||||
self.versionNeeded = pointerData.uint16()
|
||||
|
||||
self.generalPurposeBitFlags = pointerData.intFromAlignedBytes(count: 2)
|
||||
self.generalPurposeBitFlags = pointerData.uint16()
|
||||
|
||||
self.compressionMethod = pointerData.intFromAlignedBytes(count: 2)
|
||||
self.compressionMethod = pointerData.uint16()
|
||||
|
||||
self.lastModFileTime = pointerData.intFromAlignedBytes(count: 2)
|
||||
self.lastModFileDate = pointerData.intFromAlignedBytes(count: 2)
|
||||
self.lastModFileTime = pointerData.uint16()
|
||||
self.lastModFileDate = pointerData.uint16()
|
||||
|
||||
self.crc32 = pointerData.uint32()
|
||||
|
||||
self.compSize = pointerData.uint64(count: 4)
|
||||
self.uncompSize = pointerData.uint64(count: 4)
|
||||
|
||||
let fileNameLength = pointerData.intFromAlignedBytes(count: 2)
|
||||
let extraFieldLength = pointerData.intFromAlignedBytes(count: 2)
|
||||
let fileCommentLength = pointerData.intFromAlignedBytes(count: 2)
|
||||
let fileNameLength = pointerData.uint16().toInt()
|
||||
let extraFieldLength = pointerData.uint16().toInt()
|
||||
let fileCommentLength = pointerData.uint16().toInt()
|
||||
|
||||
self.diskNumberStart = pointerData.uint32(count: 2)
|
||||
|
||||
self.internalFileAttributes = pointerData.intFromAlignedBytes(count: 2)
|
||||
self.internalFileAttributes = pointerData.uint16()
|
||||
self.externalFileAttributes = pointerData.uint32()
|
||||
|
||||
self.offset = pointerData.uint64(count: 4)
|
||||
@@ -68,10 +68,8 @@ struct ZipCentralDirectoryEntry {
|
||||
let extraFieldStart = pointerData.index
|
||||
while pointerData.index - extraFieldStart < extraFieldLength {
|
||||
// There are a lot of possible extra fields.
|
||||
// But we are (currently) only interested in Zip64 related fields (with headerID = 0x0001),
|
||||
// because they directly impact further extraction process.
|
||||
let headerID = pointerData.intFromAlignedBytes(count: 2)
|
||||
let size = pointerData.intFromAlignedBytes(count: 2)
|
||||
let headerID = pointerData.uint16()
|
||||
let size = pointerData.uint16().toInt()
|
||||
switch headerID {
|
||||
case 0x0001: // Zip64
|
||||
if self.uncompSize == 0xFFFFFFFF {
|
||||
@@ -90,7 +88,7 @@ struct ZipCentralDirectoryEntry {
|
||||
let flags = pointerData.byte()
|
||||
guard flags & 0xF8 == 0 else { break }
|
||||
if flags & 0x01 != 0 {
|
||||
self.modificationTimestamp = pointerData.intFromAlignedBytes(count: 4)
|
||||
self.modificationTimestamp = pointerData.uint32()
|
||||
}
|
||||
default:
|
||||
pointerData.index += size
|
||||
|
||||
@@ -39,7 +39,7 @@ struct ZipEndOfCentralDirectory {
|
||||
|
||||
// There is also a .ZIP file comment, but we don't need it.
|
||||
// Here's how it can be processed:
|
||||
// let zipCommentLength = pointerData.intFromAlignedBytes(count: 2)
|
||||
// let zipCommentLength = pointerData.uint16().toInt()
|
||||
// let zipComment = String(data: Data(bytes: pointerData.bytes(count: zipCommentLength)),
|
||||
// encoding: .utf8)
|
||||
|
||||
|
||||
@@ -159,13 +159,13 @@ public class ZipEntry: ContainerEntry {
|
||||
var attributesDict = [FileAttributeKey: Any]()
|
||||
|
||||
// Modification time
|
||||
let dosDate = cdEntry.lastModFileDate
|
||||
let dosDate = cdEntry.lastModFileDate.toInt()
|
||||
|
||||
let day = dosDate & 0x1F
|
||||
let month = (dosDate & 0x1E0) >> 5
|
||||
let year = 1980 + ((dosDate & 0xFE00) >> 9)
|
||||
|
||||
let dosTime = cdEntry.lastModFileTime
|
||||
let dosTime = cdEntry.lastModFileTime.toInt()
|
||||
|
||||
let seconds = 2 * (dosTime & 0x1F)
|
||||
let minutes = (dosTime & 0x7E0) >> 5
|
||||
|
||||
@@ -7,11 +7,11 @@ import Foundation
|
||||
|
||||
struct ZipLocalHeader {
|
||||
|
||||
let versionNeeded: Int
|
||||
let generalPurposeBitFlags: Int
|
||||
let compressionMethod: Int
|
||||
let lastModFileTime: Int
|
||||
let lastModFileDate: Int
|
||||
let versionNeeded: UInt16
|
||||
let generalPurposeBitFlags: UInt16
|
||||
let compressionMethod: UInt16
|
||||
let lastModFileTime: UInt16
|
||||
let lastModFileDate: UInt16
|
||||
|
||||
let crc32: UInt32
|
||||
private(set) var compSize: UInt64
|
||||
@@ -21,31 +21,31 @@ struct ZipLocalHeader {
|
||||
|
||||
let fileName: String
|
||||
|
||||
private(set) var modificationTimestamp: Int?
|
||||
private(set) var accessTimestamp: Int?
|
||||
private(set) var creationTimestamp: Int?
|
||||
private(set) var modificationTimestamp: UInt32?
|
||||
private(set) var accessTimestamp: UInt32?
|
||||
private(set) var creationTimestamp: UInt32?
|
||||
|
||||
init(_ pointerData: DataWithPointer) throws {
|
||||
// Check signature.
|
||||
guard pointerData.uint32() == 0x04034b50
|
||||
else { throw ZipError.wrongSignature }
|
||||
|
||||
self.versionNeeded = pointerData.intFromAlignedBytes(count: 2)
|
||||
self.versionNeeded = pointerData.uint16()
|
||||
|
||||
self.generalPurposeBitFlags = pointerData.intFromAlignedBytes(count: 2)
|
||||
self.generalPurposeBitFlags = pointerData.uint16()
|
||||
|
||||
self.compressionMethod = pointerData.intFromAlignedBytes(count: 2)
|
||||
self.compressionMethod = pointerData.uint16()
|
||||
|
||||
self.lastModFileTime = pointerData.intFromAlignedBytes(count: 2)
|
||||
self.lastModFileDate = pointerData.intFromAlignedBytes(count: 2)
|
||||
self.lastModFileTime = pointerData.uint16()
|
||||
self.lastModFileDate = pointerData.uint16()
|
||||
|
||||
self.crc32 = pointerData.uint32()
|
||||
|
||||
self.compSize = pointerData.uint64(count: 4)
|
||||
self.uncompSize = pointerData.uint64(count: 4)
|
||||
|
||||
let fileNameLength = pointerData.intFromAlignedBytes(count: 2)
|
||||
let extraFieldLength = pointerData.intFromAlignedBytes(count: 2)
|
||||
let fileNameLength = pointerData.uint16().toInt()
|
||||
let extraFieldLength = pointerData.uint16().toInt()
|
||||
|
||||
guard let fileName = String(data: Data(bytes: pointerData.bytes(count: fileNameLength)),
|
||||
encoding: .utf8)
|
||||
@@ -55,12 +55,10 @@ struct ZipLocalHeader {
|
||||
let extraFieldStart = pointerData.index
|
||||
while pointerData.index - extraFieldStart < extraFieldLength {
|
||||
// There are a lot of possible extra fields.
|
||||
// But we are (currently) only interested in Zip64 related fields (with headerID = 0x0001),
|
||||
// because they directly impact further extraction process.
|
||||
let headerID = pointerData.intFromAlignedBytes(count: 2)
|
||||
let size = pointerData.intFromAlignedBytes(count: 2)
|
||||
let headerID = pointerData.uint16()
|
||||
let size = pointerData.uint16().toInt()
|
||||
switch headerID {
|
||||
case 0x0001:
|
||||
case 0x0001: // Zip64
|
||||
// In local header both uncompressed size and compressed size fields are required.
|
||||
self.uncompSize = pointerData.uint64()
|
||||
self.compSize = pointerData.uint64()
|
||||
@@ -70,13 +68,13 @@ struct ZipLocalHeader {
|
||||
let flags = pointerData.byte()
|
||||
guard flags & 0xF8 == 0 else { break }
|
||||
if flags & 0x01 != 0 {
|
||||
self.modificationTimestamp = pointerData.intFromAlignedBytes(count: 4)
|
||||
self.modificationTimestamp = pointerData.uint32()
|
||||
}
|
||||
if flags & 0x02 != 0 {
|
||||
self.accessTimestamp = pointerData.intFromAlignedBytes(count: 4)
|
||||
self.accessTimestamp = pointerData.uint32()
|
||||
}
|
||||
if flags & 0x04 != 0 {
|
||||
self.creationTimestamp = pointerData.intFromAlignedBytes(count: 4)
|
||||
self.creationTimestamp = pointerData.uint32()
|
||||
}
|
||||
default:
|
||||
pointerData.index += size
|
||||
|
||||
@@ -33,7 +33,7 @@ public class ZlibArchive: Archive {
|
||||
|
||||
let out = try Deflate.decompress(bitReader)
|
||||
|
||||
let adler32 = bitReader.intFromAlignedBytes(count: 4).reverseBytes()
|
||||
let adler32 = bitReader.uint32().reverseBytes()
|
||||
guard CheckSums.adler32(out) == adler32 else { throw ZlibError.wrongAdler32(Data(bytes: out)) }
|
||||
|
||||
return Data(bytes: out)
|
||||
|
||||
Reference in New Issue
Block a user