mirror of
https://github.com/tsolomko/SWCompression.git
synced 2026-06-23 14:56:41 +00:00
Complete 7zip structures implementations
Though some questions, problems and opportunities for improvements are remaining.
This commit is contained in:
@@ -13,8 +13,8 @@ struct SevenZipCodec {
|
||||
|
||||
let id: [UInt8]
|
||||
|
||||
var numInStreams: Int?
|
||||
var numOutStreams: Int?
|
||||
let numInStreams: Int
|
||||
let numOutStreams: Int
|
||||
|
||||
var propertiesSize: Int?
|
||||
var properties: [UInt8]?
|
||||
@@ -29,10 +29,11 @@ struct SevenZipCodec {
|
||||
|
||||
id = pointerData.bytes(count: idSize)
|
||||
|
||||
if isComplex {
|
||||
numInStreams = try pointerData.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger
|
||||
numOutStreams = try pointerData.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger
|
||||
}
|
||||
// TODO: Introduce typealias for SevenZipError.multiByteIntegerError.
|
||||
numInStreams = isComplex ? try pointerData
|
||||
.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger : 1
|
||||
numOutStreams = isComplex ? try pointerData
|
||||
.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger : 1
|
||||
|
||||
if attributesExist {
|
||||
propertiesSize = try pointerData.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger
|
||||
|
||||
+32
-15
@@ -10,10 +10,10 @@ struct SevenZipCoderInfo {
|
||||
let numFolders: Int
|
||||
|
||||
let external: UInt8
|
||||
var folders: [SevenZipFolder]?
|
||||
var folders = [SevenZipFolder]()
|
||||
var dataStreamIndex: Int?
|
||||
|
||||
let unpackSizes: [Int]
|
||||
var digests = [UInt32?]()
|
||||
|
||||
init(_ pointerData: DataWithPointer) throws {
|
||||
guard pointerData.byte() == 0x0B
|
||||
@@ -22,9 +22,8 @@ struct SevenZipCoderInfo {
|
||||
external = pointerData.byte()
|
||||
switch external {
|
||||
case 0:
|
||||
folders = []
|
||||
for _ in 0..<numFolders {
|
||||
folders?.append(try SevenZipFolder(pointerData))
|
||||
folders.append(try SevenZipFolder(pointerData))
|
||||
}
|
||||
case 1:
|
||||
dataStreamIndex = try pointerData.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger
|
||||
@@ -36,7 +35,7 @@ struct SevenZipCoderInfo {
|
||||
else { throw SevenZipError.wrongPropertyID }
|
||||
var sizes = [Int]()
|
||||
if external == 0 {
|
||||
for folder in folders! {
|
||||
for folder in folders {
|
||||
for _ in 0..<folder.numPackedStreams { // TODO: ???
|
||||
sizes.append(try pointerData.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger)
|
||||
}
|
||||
@@ -44,15 +43,33 @@ struct SevenZipCoderInfo {
|
||||
}
|
||||
unpackSizes = sizes
|
||||
|
||||
// TODO:
|
||||
//
|
||||
// []
|
||||
// BYTE NID::kCRC (0x0A)
|
||||
// UnPackDigests[NumFolders]
|
||||
// []
|
||||
//
|
||||
|
||||
guard pointerData.byte() == 0x00
|
||||
else { throw SevenZipError.wrongPropertyID }
|
||||
switch pointerData.byte() {
|
||||
case 0x0A:
|
||||
// TODO: Extract digests code.
|
||||
let allDefined = pointerData.byte()
|
||||
let definedBits: [UInt8]
|
||||
if allDefined == 0 {
|
||||
let bitReader = BitReader(data: pointerData.data, bitOrder: .reversed) // TODO: Bit order???
|
||||
bitReader.index = pointerData.index
|
||||
definedBits = bitReader.bits(count: numFolders)
|
||||
bitReader.skipUntilNextByte()
|
||||
pointerData.index = bitReader.index
|
||||
} else {
|
||||
definedBits = Array(repeating: 1, count: numFolders)
|
||||
}
|
||||
for bit in definedBits {
|
||||
if bit == 1 {
|
||||
digests.append(pointerData.uint32())
|
||||
} else {
|
||||
digests.append(nil)
|
||||
}
|
||||
}
|
||||
guard pointerData.byte() == 0x00
|
||||
else { throw SevenZipError.wrongPropertyID }
|
||||
case 0x00:
|
||||
break
|
||||
default:
|
||||
throw SevenZipError.wrongPropertyID
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,95 +16,23 @@ struct SevenZipFileInfo {
|
||||
let numFiles: Int
|
||||
var files = [File]()
|
||||
|
||||
var properties = [(Int, [UInt8])]()
|
||||
|
||||
init(_ pointerData: DataWithPointer) throws {
|
||||
numFiles = try pointerData.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger
|
||||
for _ in 0..<numFiles {
|
||||
files.append(File())
|
||||
}
|
||||
let bitReader = BitReader(data: pointerData.data, bitOrder: .reversed) // TODO: bitOrder ???
|
||||
var totalEmptyStreams = 0
|
||||
while true {
|
||||
let propertyType = pointerData.byte()
|
||||
if propertyType == 0 {
|
||||
break
|
||||
}
|
||||
switch propertyType {
|
||||
case 0x0E: // Empty stream
|
||||
for i in 0..<numFiles {
|
||||
let isEmptyStream = bitReader.bit() != 0
|
||||
files[i].isEmptyStream = isEmptyStream
|
||||
totalEmptyStreams += isEmptyStream ? 1 : 0 // TODO: Should we skipUntilNextByte() ???
|
||||
}
|
||||
case 0x0F: // Empty file
|
||||
break
|
||||
default:
|
||||
break // TODO: Should we throw error?
|
||||
}
|
||||
let size = try pointerData.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger
|
||||
properties.append((propertyType.toInt(), pointerData.bytes(count: size)))
|
||||
|
||||
// TODO: Add properties parsing.
|
||||
}
|
||||
}
|
||||
//
|
||||
// for (;;)
|
||||
// {
|
||||
// BYTE PropertyType;
|
||||
// if (aType == 0)
|
||||
// break;
|
||||
//
|
||||
// UINT64 Size;
|
||||
//
|
||||
// switch(PropertyType)
|
||||
// {
|
||||
//
|
||||
// kEmptyFile: (0x0F)
|
||||
// for(EmptyStreams)
|
||||
// BIT IsEmptyFile
|
||||
//
|
||||
// kAnti: (0x10)
|
||||
// for(EmptyStreams)
|
||||
// BIT IsAntiFile
|
||||
//
|
||||
// case kCTime: (0x12)
|
||||
// case kATime: (0x13)
|
||||
// case kMTime: (0x14)
|
||||
// BYTE AllAreDefined
|
||||
// if (AllAreDefined == 0)
|
||||
// {
|
||||
// for(NumFiles)
|
||||
// BIT TimeDefined
|
||||
// }
|
||||
// BYTE External;
|
||||
// if(External != 0)
|
||||
// UINT64 DataIndex
|
||||
// []
|
||||
// for(Definded Items)
|
||||
// UINT64 Time
|
||||
// []
|
||||
//
|
||||
// kNames: (0x11)
|
||||
// BYTE External;
|
||||
// if(External != 0)
|
||||
// UINT64 DataIndex
|
||||
// []
|
||||
// for(Files)
|
||||
// {
|
||||
// wchar_t Names[NameSize];
|
||||
// wchar_t 0;
|
||||
// }
|
||||
// []
|
||||
//
|
||||
// kAttributes: (0x15)
|
||||
// BYTE AllAreDefined
|
||||
// if (AllAreDefined == 0)
|
||||
// {
|
||||
// for(NumFiles)
|
||||
// BIT AttributesAreDefined
|
||||
// }
|
||||
// BYTE External;
|
||||
// if(External != 0)
|
||||
// UINT64 DataIndex
|
||||
// []
|
||||
// for(Definded Attributes)
|
||||
// UINT32 Attributes
|
||||
// []
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@ struct SevenZipFolder {
|
||||
for _ in 0..<numCodecs {
|
||||
let codec = try SevenZipCodec(pointerData)
|
||||
codecs.append(codec)
|
||||
outStreamsTotal += codec.numOutStreams ?? 0
|
||||
inStreamsTotal += codec.numInStreams ?? 0
|
||||
outStreamsTotal += codec.numOutStreams
|
||||
inStreamsTotal += codec.numInStreams
|
||||
}
|
||||
self.codecs = codecs
|
||||
numBindPairs = outStreamsTotal - 1
|
||||
|
||||
+22
-10
@@ -9,8 +9,8 @@ struct SevenZipPackInfo {
|
||||
|
||||
let packPosition: Int
|
||||
let numPackStreams: Int
|
||||
|
||||
var packSizes: [Int]?
|
||||
var packSizes = [Int]()
|
||||
var digests = [UInt32?]()
|
||||
|
||||
init(_ pointerData: DataWithPointer) throws {
|
||||
packPosition = try pointerData.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger
|
||||
@@ -22,17 +22,29 @@ struct SevenZipPackInfo {
|
||||
}
|
||||
switch structureType {
|
||||
case 0x09: // **PackInfo - PackSizes**
|
||||
packSizes = []
|
||||
for _ in 0..<numPackStreams {
|
||||
packSizes?.append(try pointerData.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger)
|
||||
packSizes.append(try pointerData.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger)
|
||||
}
|
||||
case 0x0A: // **PackInfo - PackStreamDigests**
|
||||
// TODO:
|
||||
// []
|
||||
// BYTE NID::kCRC (0x0A)
|
||||
// PackStreamDigests[NumPackStreams]
|
||||
// []
|
||||
break
|
||||
let allDefined = pointerData.byte()
|
||||
let definedBits: [UInt8]
|
||||
let numStreams = numPackStreams
|
||||
if allDefined == 0 {
|
||||
let bitReader = BitReader(data: pointerData.data, bitOrder: .reversed) // TODO: Bit order???
|
||||
bitReader.index = pointerData.index
|
||||
definedBits = bitReader.bits(count: numStreams)
|
||||
bitReader.skipUntilNextByte()
|
||||
pointerData.index = bitReader.index
|
||||
} else {
|
||||
definedBits = Array(repeating: 1, count: numStreams)
|
||||
}
|
||||
for bit in definedBits {
|
||||
if bit == 1 {
|
||||
digests.append(pointerData.uint32())
|
||||
} else {
|
||||
digests.append(nil)
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw SevenZipError.wrongPropertyID
|
||||
}
|
||||
|
||||
@@ -7,8 +7,9 @@ import Foundation
|
||||
|
||||
struct SevenZipSubstreamInfo {
|
||||
|
||||
var numUnpackStreamsInFolders: [Int]?
|
||||
var unpackSizes: [Int]?
|
||||
var numUnpackStreamsInFolders = [Int]()
|
||||
var unpackSizes = [Int]()
|
||||
var digests = [UInt32?]()
|
||||
|
||||
init(_ pointerData: DataWithPointer, _ numFolders: Int) throws {
|
||||
while true {
|
||||
@@ -18,29 +19,35 @@ struct SevenZipSubstreamInfo {
|
||||
}
|
||||
switch structureType {
|
||||
case 0x0D: // **SubstreamsInfo - NumUnpackStreamsInFolders**
|
||||
numUnpackStreamsInFolders = []
|
||||
for _ in 0..<numFolders {
|
||||
numUnpackStreamsInFolders?
|
||||
numUnpackStreamsInFolders
|
||||
.append(try pointerData.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger)
|
||||
}
|
||||
case 0x09: // **SubstreamsInfo - Size**
|
||||
// TODO: How many sizes?
|
||||
//
|
||||
// []
|
||||
// BYTE NID::kSize (0x09)
|
||||
// UINT64 UnPackSizes[]
|
||||
// []
|
||||
//
|
||||
break
|
||||
case 0x0A: // **SubstreamsInfo - CRC**
|
||||
// TODO:
|
||||
//
|
||||
// []
|
||||
// BYTE NID::kCRC (0x0A)
|
||||
// Digests[Number of streams with unknown CRC]
|
||||
// []
|
||||
//
|
||||
break
|
||||
let numStreams = numUnpackStreamsInFolders.reduce(0, { $0 + $1 })
|
||||
for _ in 0..<numStreams {
|
||||
unpackSizes.append(try pointerData.multiByteDecode(SevenZipError.multiByteIntegerError).multiByteInteger)
|
||||
}
|
||||
case 0x0A: // **SubstreamsInfo - CRC** // TODO: Unknown numStreams???
|
||||
let allDefined = pointerData.byte()
|
||||
let definedBits: [UInt8]
|
||||
let numStreams = numUnpackStreamsInFolders.reduce(0, { $0 + $1 })
|
||||
if allDefined == 0 {
|
||||
let bitReader = BitReader(data: pointerData.data, bitOrder: .reversed) // TODO: Bit order???
|
||||
bitReader.index = pointerData.index
|
||||
definedBits = bitReader.bits(count: numStreams)
|
||||
bitReader.skipUntilNextByte()
|
||||
pointerData.index = bitReader.index
|
||||
} else {
|
||||
definedBits = Array(repeating: 1, count: numStreams)
|
||||
}
|
||||
for bit in definedBits {
|
||||
if bit == 1 {
|
||||
digests.append(pointerData.uint32())
|
||||
} else {
|
||||
digests.append(nil)
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw SevenZipError.wrongPropertyID
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user