diff --git a/.gitattributes b/.gitattributes
index 9f52a67f..8f418ef2 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2,3 +2,4 @@
*.deflate filter=lfs diff=lfs merge=lfs -text
*.answer filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
+*.zip filter=lfs diff=lfs merge=lfs -text
diff --git a/.jazzy.yaml b/.jazzy.yaml
index 8dcf9f02..7521aca4 100644
--- a/.jazzy.yaml
+++ b/.jazzy.yaml
@@ -4,9 +4,9 @@ exclude: Tests/
swift_version: 3.0.2
author: Timofey Solomko
module: SWCompression
-module_version: 2.0.0
-copyright: '© 2016 Timofey Solomko'
+module_version: 2.1.0
+copyright: '© 2017 Timofey Solomko'
readme: README.md
github_url: https://github.com/tsolomko/SWCompression
-github_file_prefix: https://github.com/tsolomko/SWCompression/tree/v2.0.0
+github_file_prefix: https://github.com/tsolomko/SWCompression/tree/v2.1.0
theme: fullwidth
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa04b739..25a70c8a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,10 @@
# Changelog
+v2.1.0
+----------------
+- ZIP containers support.
+- HuffmanTree is no longer part of SWCompression/Common.
+- Updated documentation.
+
v2.0.1
----------------
- Fixed incorrect reading adler32 checksum from zlib archives.
diff --git a/README.md b/README.md
index 8ee405f8..e843ca1f 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,8 @@ And here comes SWCompression: no Objective-C, pure Swift.
Features
----------------
+- Containers:
+ - ZIP (complying to ISO/IEC 21320 standard)
- (De)compression algorithms:
- LZMA/LZMA2
- Deflate
@@ -173,3 +175,6 @@ References
- [LZMA SDK and specification](http://www.7-zip.org/sdk.html)
- [XZ specification](http://tukaani.org/xz/xz-file-format-1.0.4.txt)
- [Wikipedia article about LZMA](https://en.wikipedia.org/wiki/Lempel–Ziv–Markov_chain_algorithm)
+- [.ZIP Application Note](http://www.pkware.com/appnote)
+- [ISO/IEC 21320-1](http://www.iso.org/iso/catalogue_detail.htm?csnumber=60101)
+- [List of defined ZIP extra fields](https://opensource.apple.com/source/zip/zip-6/unzip/unzip/proginfo/extra.fld)
diff --git a/SWCompression.podspec b/SWCompression.podspec
index e9139913..8a605549 100644
--- a/SWCompression.podspec
+++ b/SWCompression.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "SWCompression"
- s.version = "2.0.1"
+ s.version = "2.1.0"
s.summary = "Framework with implementations in Swift of different (de)compression algorithms"
s.description = <<-DESC
@@ -29,12 +29,12 @@ Pod::Spec.new do |s|
# It should not be included directly in Podfile.
s.subspec 'Common' do |sp|
sp.public_header_files = 'Sources/Service/SWCompression.h'
- sp.source_files = "Sources/{CheckSums.swift,DataWithPointer.swift,Extensions.swift,HuffmanTree.swift,Protocols.swift,Service/*.swift,Service/*.h}"
+ sp.source_files = "Sources/{CheckSums.swift,DataWithPointer.swift,Extensions.swift,Protocols.swift,Service/*.swift,Service/*.h}"
end
s.subspec 'Deflate' do |sp|
sp.dependency 'SWCompression/Common'
- sp.source_files = 'Sources/Deflate.swift'
+ sp.source_files = 'Sources/{Deflate.swift,HuffmanTree.swift}'
end
s.subspec 'GZip' do |sp|
@@ -51,7 +51,7 @@ Pod::Spec.new do |s|
s.subspec 'BZip2' do |sp|
sp.dependency 'SWCompression/Common'
- sp.source_files = 'Sources/BZip2.swift'
+ sp.source_files = 'Sources/{BZip2.swift,HuffmanTree.swift}'
end
s.subspec 'LZMA' do |sp|
@@ -65,4 +65,10 @@ Pod::Spec.new do |s|
sp.source_files = 'Sources/XZArchive.swift'
end
+ s.subspec 'ZIP' do |sp|
+ sp.dependency 'SWCompression/Common'
+ sp.dependency 'SWCompression/Deflate'
+ sp.source_files = 'Sources/ZipContainer.swift'
+ end
+
end
diff --git a/SWCompression.xcodeproj/project.pbxproj b/SWCompression.xcodeproj/project.pbxproj
index 387d0ff7..f7d96cd9 100644
--- a/SWCompression.xcodeproj/project.pbxproj
+++ b/SWCompression.xcodeproj/project.pbxproj
@@ -33,6 +33,11 @@
065569761DC65C2B00A47E66 /* GzipArchive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 063364E21DC52979007E313F /* GzipArchive.swift */; };
065569771DC65C2B00A47E66 /* ZlibArchive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 064492581DC606D400F10981 /* ZlibArchive.swift */; };
065569781DC65C2B00A47E66 /* Deflate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 061FCE251DBCC4BE0052F7BE /* Deflate.swift */; };
+ 067518361E2A86F700D16354 /* ZipContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 067518351E2A86F700D16354 /* ZipContainer.swift */; };
+ 067518371E2A86F700D16354 /* ZipContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 067518351E2A86F700D16354 /* ZipContainer.swift */; };
+ 067518381E2A86F700D16354 /* ZipContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 067518351E2A86F700D16354 /* ZipContainer.swift */; };
+ 067518391E2A86F700D16354 /* ZipContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 067518351E2A86F700D16354 /* ZipContainer.swift */; };
+ 0675183D1E2A883600D16354 /* ZipTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0675183C1E2A883600D16354 /* ZipTests.swift */; };
0680E1B11DDA2D7C005C05EB /* ZlibTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0680E1B01DDA2D7C005C05EB /* ZlibTests.swift */; };
0680E1B31DDA3D0A005C05EB /* GzipTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0680E1B21DDA3D0A005C05EB /* GzipTests.swift */; };
0680E1B51DDA4076005C05EB /* Bzip2Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0680E1B41DDA4075005C05EB /* Bzip2Tests.swift */; };
@@ -80,6 +85,9 @@
06BB8F311E0C2C720079FB9E /* LZMA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06BB8F2F1E0C2C720079FB9E /* LZMA2.swift */; };
06BB8F321E0C2C720079FB9E /* LZMA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06BB8F2F1E0C2C720079FB9E /* LZMA2.swift */; };
06BB8F331E0C2C720079FB9E /* LZMA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06BB8F2F1E0C2C720079FB9E /* LZMA2.swift */; };
+ 06BD0D231E3D0C630054AA5C /* SWCompressionSourceCode.zip in Resources */ = {isa = PBXBuildFile; fileRef = 06BD0D201E3D0C630054AA5C /* SWCompressionSourceCode.zip */; };
+ 06BD0D241E3D0C630054AA5C /* TestDataDescriptor.zip in Resources */ = {isa = PBXBuildFile; fileRef = 06BD0D211E3D0C630054AA5C /* TestDataDescriptor.zip */; };
+ 06BD0D251E3D0C630054AA5C /* TestZip64.zip in Resources */ = {isa = PBXBuildFile; fileRef = 06BD0D221E3D0C630054AA5C /* TestZip64.zip */; };
06BE1AD21DB410F100EE0F59 /* SWCompression.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 06BE1AC81DB410F100EE0F59 /* SWCompression.framework */; };
06CC18601DE35269003532F5 /* test1.answer in Resources */ = {isa = PBXBuildFile; fileRef = 06CC183F1DE35269003532F5 /* test1.answer */; };
06CC18611DE35269003532F5 /* test2.answer in Resources */ = {isa = PBXBuildFile; fileRef = 06CC18401DE35269003532F5 /* test2.answer */; };
@@ -155,6 +163,8 @@
0655693F1DC659FF00A47E66 /* SWCompression.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SWCompression.framework; sourceTree = BUILT_PRODUCTS_DIR; };
0655694C1DC65A8000A47E66 /* SWCompression.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SWCompression.framework; sourceTree = BUILT_PRODUCTS_DIR; };
065569591DC65A9400A47E66 /* SWCompression.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SWCompression.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 067518351E2A86F700D16354 /* ZipContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZipContainer.swift; sourceTree = ""; };
+ 0675183C1E2A883600D16354 /* ZipTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZipTests.swift; sourceTree = ""; };
0680E1B01DDA2D7C005C05EB /* ZlibTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZlibTests.swift; sourceTree = ""; };
0680E1B21DDA3D0A005C05EB /* GzipTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GzipTests.swift; sourceTree = ""; };
0680E1B41DDA4075005C05EB /* Bzip2Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bzip2Tests.swift; sourceTree = ""; };
@@ -178,6 +188,9 @@
06B374C81E0EECCC00064853 /* random_file.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; path = random_file.gz; sourceTree = ""; };
06B374CA1E0EECD500064853 /* random_file.zlib */ = {isa = PBXFileReference; lastKnownFileType = file; path = random_file.zlib; sourceTree = ""; };
06BB8F2F1E0C2C720079FB9E /* LZMA2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LZMA2.swift; sourceTree = ""; };
+ 06BD0D201E3D0C630054AA5C /* SWCompressionSourceCode.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = SWCompressionSourceCode.zip; sourceTree = ""; };
+ 06BD0D211E3D0C630054AA5C /* TestDataDescriptor.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = TestDataDescriptor.zip; sourceTree = ""; };
+ 06BD0D221E3D0C630054AA5C /* TestZip64.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = TestZip64.zip; sourceTree = ""; };
06BE1AC81DB410F100EE0F59 /* SWCompression.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SWCompression.framework; sourceTree = BUILT_PRODUCTS_DIR; };
06BE1AD11DB410F100EE0F59 /* SWCompressionTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SWCompressionTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
06BE1AD81DB410F100EE0F59 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
@@ -296,7 +309,6 @@
06E234811E06A6C200F18798 /* CheckSums.swift */,
063DF1051DE1F07800F38082 /* DataWithPointer.swift */,
063DF1061DE1F07800F38082 /* Extensions.swift */,
- 063DF1081DE1F07800F38082 /* HuffmanTree.swift */,
063DF1091DE1F07800F38082 /* Protocols.swift */,
);
path = Common;
@@ -314,6 +326,16 @@
path = Service;
sourceTree = "";
};
+ 06BD0D1F1E3D0C630054AA5C /* ZIP */ = {
+ isa = PBXGroup;
+ children = (
+ 06BD0D201E3D0C630054AA5C /* SWCompressionSourceCode.zip */,
+ 06BD0D211E3D0C630054AA5C /* TestDataDescriptor.zip */,
+ 06BD0D221E3D0C630054AA5C /* TestZip64.zip */,
+ );
+ path = ZIP;
+ sourceTree = "";
+ };
06BE1ABE1DB410F100EE0F59 = {
isa = PBXGroup;
children = (
@@ -340,11 +362,13 @@
children = (
06A3931F1DE06FFE00182E12 /* Common */,
069D0FFE1E0D6CF200D8AA87 /* LZMA */,
+ 063DF1081DE1F07800F38082 /* HuffmanTree.swift */,
06E2346B1E068E9600F18798 /* XZArchive.swift */,
063364E21DC52979007E313F /* GzipArchive.swift */,
064492581DC606D400F10981 /* ZlibArchive.swift */,
061FCE251DBCC4BE0052F7BE /* Deflate.swift */,
06FED40B1DD7717E0013DFB2 /* BZip2.swift */,
+ 067518351E2A86F700D16354 /* ZipContainer.swift */,
06A3933D1DE070B500182E12 /* Service */,
);
path = Sources;
@@ -361,6 +385,7 @@
0680E1B21DDA3D0A005C05EB /* GzipTests.swift */,
0680E1B01DDA2D7C005C05EB /* ZlibTests.swift */,
061FCE2C1DBCC6A30052F7BE /* Constants.swift */,
+ 0675183C1E2A883600D16354 /* ZipTests.swift */,
06BE1AD81DB410F100EE0F59 /* Info.plist */,
);
path = Tests;
@@ -375,6 +400,7 @@
06CC184E1DE35269003532F5 /* Deflate */,
06CC18561DE35269003532F5 /* GZip */,
069AC2161E02DE490041AC13 /* LZMA */,
+ 06BD0D1F1E3D0C630054AA5C /* ZIP */,
06CC185F1DE35269003532F5 /* test.zlib */,
06B374CA1E0EECD500064853 /* random_file.zlib */,
);
@@ -674,6 +700,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 06BD0D241E3D0C630054AA5C /* TestDataDescriptor.zip in Resources */,
06CC18711DE35269003532F5 /* test4.deflate in Resources */,
06E234781E069A7F00F18798 /* test1.xz in Resources */,
06CC18621DE35269003532F5 /* test3.answer in Resources */,
@@ -686,12 +713,14 @@
06CC18781DE35269003532F5 /* test4.gz in Resources */,
06CC187B1DE35269003532F5 /* test7.gz in Resources */,
06CC18611DE35269003532F5 /* test2.answer in Resources */,
+ 06BD0D251E3D0C630054AA5C /* TestZip64.zip in Resources */,
06CC18701DE35269003532F5 /* test3.deflate in Resources */,
06CC186F1DE35269003532F5 /* test2.deflate in Resources */,
06E2347B1E069A7F00F18798 /* test4.xz in Resources */,
06CC186C1DE35269003532F5 /* test6.bz2 in Resources */,
06CC186B1DE35269003532F5 /* test5.bz2 in Resources */,
06CC18651DE35269003532F5 /* test6.answer in Resources */,
+ 06BD0D231E3D0C630054AA5C /* SWCompressionSourceCode.zip in Resources */,
06CC18631DE35269003532F5 /* test4.answer in Resources */,
06B374CB1E0EECD500064853 /* random_file.zlib in Resources */,
06FCA0581E033DDA00B6932F /* test8.answer in Resources */,
@@ -735,6 +764,7 @@
069D0FF11E0D6CB600D8AA87 /* LZMARangeDecoder.swift in Sources */,
069D0FEC1E0D6C9F00D8AA87 /* LZMAOutWindow.swift in Sources */,
063DF1171DE1F07800F38082 /* Protocols.swift in Sources */,
+ 067518371E2A86F700D16354 /* ZipContainer.swift in Sources */,
069D0FFB1E0D6CE900D8AA87 /* LZMALenDecoder.swift in Sources */,
06E234831E06A6C200F18798 /* CheckSums.swift in Sources */,
069AC20E1E02DB1D0041AC13 /* LZMA.swift in Sources */,
@@ -759,6 +789,7 @@
069D0FF21E0D6CB600D8AA87 /* LZMARangeDecoder.swift in Sources */,
069D0FED1E0D6C9F00D8AA87 /* LZMAOutWindow.swift in Sources */,
063DF11D1DE1F2E200F38082 /* Protocols.swift in Sources */,
+ 067518381E2A86F700D16354 /* ZipContainer.swift in Sources */,
069D0FFC1E0D6CE900D8AA87 /* LZMALenDecoder.swift in Sources */,
06E234841E06A6C200F18798 /* CheckSums.swift in Sources */,
069AC20F1E02DB1D0041AC13 /* LZMA.swift in Sources */,
@@ -783,6 +814,7 @@
069D0FF31E0D6CB600D8AA87 /* LZMARangeDecoder.swift in Sources */,
069D0FEE1E0D6C9F00D8AA87 /* LZMAOutWindow.swift in Sources */,
063DF1181DE1F07800F38082 /* Protocols.swift in Sources */,
+ 067518391E2A86F700D16354 /* ZipContainer.swift in Sources */,
069D0FFD1E0D6CE900D8AA87 /* LZMALenDecoder.swift in Sources */,
06E234851E06A6C200F18798 /* CheckSums.swift in Sources */,
069AC2101E02DB1D0041AC13 /* LZMA.swift in Sources */,
@@ -807,6 +839,7 @@
069D0FF01E0D6CB600D8AA87 /* LZMARangeDecoder.swift in Sources */,
069D0FEB1E0D6C9F00D8AA87 /* LZMAOutWindow.swift in Sources */,
063DF1161DE1F07800F38082 /* Protocols.swift in Sources */,
+ 067518361E2A86F700D16354 /* ZipContainer.swift in Sources */,
069D0FFA1E0D6CE900D8AA87 /* LZMALenDecoder.swift in Sources */,
06E234821E06A6C200F18798 /* CheckSums.swift in Sources */,
069AC20D1E02DB1D0041AC13 /* LZMA.swift in Sources */,
@@ -831,6 +864,7 @@
0680E1B11DDA2D7C005C05EB /* ZlibTests.swift in Sources */,
0680E1B31DDA3D0A005C05EB /* GzipTests.swift in Sources */,
06E234801E069ABD00F18798 /* XzTests.swift in Sources */,
+ 0675183D1E2A883600D16354 /* ZipTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Sources/BZip2.swift b/Sources/BZip2.swift
index a22bc9ad..88520cd4 100644
--- a/Sources/BZip2.swift
+++ b/Sources/BZip2.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 12.11.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
@@ -43,7 +43,7 @@ public enum BZip2Error: Error {
case SymbolNotFound
}
-/// Provides function to decompress data, which were compressed using BZip2
+/// Provides function to decompress data, which were compressed using BZip2.
public final class BZip2: DecompressionAlgorithm {
/**
diff --git a/Sources/CheckSums.swift b/Sources/CheckSums.swift
index 86f1b644..eb5d72cf 100644
--- a/Sources/CheckSums.swift
+++ b/Sources/CheckSums.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 18.12.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
diff --git a/Sources/DataWithPointer.swift b/Sources/DataWithPointer.swift
index da4de96d..e633bcd5 100644
--- a/Sources/DataWithPointer.swift
+++ b/Sources/DataWithPointer.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 01.11.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
diff --git a/Sources/Deflate.swift b/Sources/Deflate.swift
index 7ddc9f36..c7212a21 100644
--- a/Sources/Deflate.swift
+++ b/Sources/Deflate.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 23.10.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
@@ -28,7 +28,7 @@ public enum DeflateError: Error {
case SymbolNotFound
}
-/// Provides function to decompress data, which were compressed with DEFLATE
+/// Provides function to decompress data, which were compressed with DEFLATE.
public final class Deflate: DecompressionAlgorithm {
/**
diff --git a/Sources/Extensions.swift b/Sources/Extensions.swift
index fed2aea1..d72b547f 100644
--- a/Sources/Extensions.swift
+++ b/Sources/Extensions.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 19.09.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
diff --git a/Sources/GzipArchive.swift b/Sources/GzipArchive.swift
index d56e1e1f..797a3a4b 100644
--- a/Sources/GzipArchive.swift
+++ b/Sources/GzipArchive.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 29.10.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
@@ -39,7 +39,7 @@ public enum GzipError: Error {
case WrongISize
}
-/// A strucutre which provides information about gzip archive.
+/// A structure which provides information about gzip archive.
public struct GzipHeader {
struct Flags {
@@ -176,7 +176,7 @@ public struct GzipHeader {
}
-/// A class with unarchive function for gzip archives.
+/// Provides unarchive function for GZip archives.
public final class GzipArchive: Archive {
/**
diff --git a/Sources/HuffmanTree.swift b/Sources/HuffmanTree.swift
index 61905ef7..913c51a1 100644
--- a/Sources/HuffmanTree.swift
+++ b/Sources/HuffmanTree.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 24.10.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
diff --git a/Sources/LZMA.swift b/Sources/LZMA.swift
index d15f3354..ea087599 100644
--- a/Sources/LZMA.swift
+++ b/Sources/LZMA.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 15.12.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
diff --git a/Sources/LZMA2.swift b/Sources/LZMA2.swift
index 27a49c30..3cc0cf8e 100644
--- a/Sources/LZMA2.swift
+++ b/Sources/LZMA2.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 22.12.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
diff --git a/Sources/LZMABitTreeDecoder.swift b/Sources/LZMABitTreeDecoder.swift
index fdf8f2ec..cd1490f6 100644
--- a/Sources/LZMABitTreeDecoder.swift
+++ b/Sources/LZMABitTreeDecoder.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 23.12.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
diff --git a/Sources/LZMADecoder.swift b/Sources/LZMADecoder.swift
index ee79cb79..4a48787f 100644
--- a/Sources/LZMADecoder.swift
+++ b/Sources/LZMADecoder.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 23.12.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
@@ -32,7 +32,6 @@ final class LZMADecoder {
private var lp: UInt8
private var pb: UInt8
private var dictionarySize: Int
-// private var uncompressedSize: Int
private var outWindow: LZMAOutWindow
private var rangeDecoder: LZMARangeDecoder
@@ -67,7 +66,7 @@ final class LZMADecoder {
private var rep2: Int = 0
private var rep3: Int = 0
- /// Is used to select exact variable from 'IsRep', 'IsRepG0', 'IsRepG1æ and 'IsRepG2' arrays.
+ /// Is used to select exact variable from 'IsRep', 'IsRepG0', 'IsRepG1' and 'IsRepG2' arrays.
private var state: Int = 0
init(_ pointerData: inout DataWithPointer, _ lc: UInt8, _ pb: UInt8, _ lp: UInt8,
diff --git a/Sources/LZMALenDecoder.swift b/Sources/LZMALenDecoder.swift
index 67c880ef..3c758779 100644
--- a/Sources/LZMALenDecoder.swift
+++ b/Sources/LZMALenDecoder.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 23.12.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
diff --git a/Sources/LZMAOutWindow.swift b/Sources/LZMAOutWindow.swift
index d473ad3f..6c0f13ec 100644
--- a/Sources/LZMAOutWindow.swift
+++ b/Sources/LZMAOutWindow.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 23.12.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
diff --git a/Sources/LZMARangeDecoder.swift b/Sources/LZMARangeDecoder.swift
index 5d7aae76..82a5f481 100644
--- a/Sources/LZMARangeDecoder.swift
+++ b/Sources/LZMARangeDecoder.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 23.12.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
diff --git a/Sources/Protocols.swift b/Sources/Protocols.swift
index 8758a5c7..a3fc9ad0 100644
--- a/Sources/Protocols.swift
+++ b/Sources/Protocols.swift
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 29.10.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
diff --git a/Sources/Service/Info-iOS.plist b/Sources/Service/Info-iOS.plist
index 0e27f5f6..f69838d4 100644
--- a/Sources/Service/Info-iOS.plist
+++ b/Sources/Service/Info-iOS.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.0.1
+ 2.1.0
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSPrincipalClass
diff --git a/Sources/Service/Info-tvOS.plist b/Sources/Service/Info-tvOS.plist
index 0e27f5f6..f69838d4 100644
--- a/Sources/Service/Info-tvOS.plist
+++ b/Sources/Service/Info-tvOS.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.0.1
+ 2.1.0
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSPrincipalClass
diff --git a/Sources/Service/Info-watchOS.plist b/Sources/Service/Info-watchOS.plist
index 0e27f5f6..f69838d4 100644
--- a/Sources/Service/Info-watchOS.plist
+++ b/Sources/Service/Info-watchOS.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.0.1
+ 2.1.0
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSPrincipalClass
diff --git a/Sources/Service/Info.plist b/Sources/Service/Info.plist
index 2fc261af..64df5ef2 100644
--- a/Sources/Service/Info.plist
+++ b/Sources/Service/Info.plist
@@ -15,11 +15,11 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.0.1
+ 2.1.0
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSHumanReadableCopyright
- Copyright © 2016 Timofey Solomko. All rights reserved.
+ Copyright © 2017 Timofey Solomko. All rights reserved.
NSPrincipalClass
diff --git a/Sources/Service/SWCompression.h b/Sources/Service/SWCompression.h
index f245fd33..2c4ecbf9 100644
--- a/Sources/Service/SWCompression.h
+++ b/Sources/Service/SWCompression.h
@@ -3,7 +3,7 @@
// SWCompression
//
// Created by Timofey Solomko on 16.10.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
//! Project version number for SWCompression.
diff --git a/Sources/XZArchive.swift b/Sources/XZArchive.swift
index 0cacc4ae..b5b9570f 100644
--- a/Sources/XZArchive.swift
+++ b/Sources/XZArchive.swift
@@ -3,14 +3,14 @@
// SWCompression
//
// Created by Timofey Solomko on 18.12.16.
-// Copyright © 2016 Timofey Solomko. All rights reserved.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
//
import Foundation
/**
- Error happened during unarchiving xz archive.
- It may indicate that either the data is damaged or it might not be xz archive at all.
+ Error happened during unarchiving XZ archive.
+ It may indicate that either the data is damaged or it might not be XZ archive at all.
- `WrongMagic`: 'magic' bytes in archive's header or footer weren't equal to predefined value.
- `WrongArchiveInfo`: incorrect value of one of archive's special field (in block, index, header or footer).
@@ -54,7 +54,7 @@ public enum XZError: Error {
case MultiByteIntegerError
}
-/// A class with unarchive function for xz archives.
+/// Provides unarchive function for XZ archives.
public final class XZArchive: Archive {
/**
diff --git a/Sources/ZipContainer.swift b/Sources/ZipContainer.swift
new file mode 100644
index 00000000..d1823292
--- /dev/null
+++ b/Sources/ZipContainer.swift
@@ -0,0 +1,418 @@
+//
+// ZipContainer.swift
+// SWCompression
+//
+// Created by Timofey Solomko on 14.01.17.
+// Copyright © 2017 Timofey Solomko. All rights reserved.
+//
+
+import Foundation
+
+/**
+ Error happened during processing ZIP archive (container).
+ It may indicate that either the data is damaged or it might not be ZIP archive (container) at all.
+
+ - `NotFoundCentralDirectoryEnd`: end of Central Directoty record wasn't found.
+ - `WrongSignature`: unsupported signature of one of ZIP container's structures.
+ - `WrongSize`: incorrect compressed or uncompressed size of a ZIP container's entry's data.
+ - `WrongVersion`: unsupported number of version needed to extract ZIP container
+ (unsupported features are required to open this file).
+ - `MultiVolumesNotSupported`: unsupported feature: multi-volumed or spanned container.
+ - `EncryptionNotSupported`: unsupported feature: encryption.
+ - `PatchingNotSupported`: unsupported feature: patched data.
+ - `CompressionNotSupported`: unsupported feature: specified compression method.
+ - `WrongLocalHeader`: local header of an entry wasn't consistent with Central Directory record.
+ - `WrongCRC32`: computed checksum of entry's data wasn't the same as the one stored in container.
+ */
+public enum ZipError: Error {
+ /// End of Central Directoty record was not found.
+ case NotFoundCentralDirectoryEnd
+ /// Wrong signature of one of ZIP container's structures.
+ case WrongSignature
+ /// Wrong either compressed or uncompressed size of a ZIP container's entry.
+ case WrongSize
+ /// Wrong number of version needed to extract ZIP container.
+ case WrongVersion
+ /// Archive either spanned or consists of several volumes. This feature is not supported.
+ case MultiVolumesNotSupported
+ /// Entry or record is encrypted. This feature is not supported.
+ case EncryptionNotSupported
+ /// Entry contains patched data. This feature is not supported.
+ case PatchingNotSupported
+ /// Wrong compression method of an entry.
+ case CompressionNotSupported
+ /// Wrong local header of an entry.
+ case WrongLocalHeader
+ /// Wrong computed CRC32 of an entry.
+ case WrongCRC32
+}
+
+/// Provides function to open ZIP archives (containers).
+public class ZipContainer {
+
+ /**
+ Processes ZIP archive (container) and returns an array of tuples `(String, Data)`.
+ First member of a tuple is entry's name, second member is entry's data.
+
+ - Important: The order of entries is defined by ZIP archive and, particularly, creator of given ZIP container.
+ It is likely that directories will be encountered earlier than files stored in those directories,
+ but one SHOULD NOT assume that this is the case.
+
+ - Note: Currently, there is no universal (platform and file system independent) method to determine if entry is a directory.
+ One can check this by looking at the size of entry's data (it should be 0 for directory) AND
+ the last character of entry's name (it should be '/'). If all of these is true then entry is likely to be a directory.
+
+ - Note: Only ZIP containers complying to ISO/IEC 21320-1 standard are supported.
+
+ - Parameter containerData: Data of ZIP container.
+
+ - Throws: `ZipError` or `DeflateError` depending on the type of inconsistency in data.
+ It may indicate that either the container is damaged or it might not be ZIP container or compressed with Deflate at all.
+
+ - Returns: Array of pairs (tuples) where first member is `entryName` and second member is `entryData`.
+ */
+ public static func open(containerData data: Data) throws -> [(entryName: String, entryData: Data)] {
+ /// Object with input data which supports convenient work with bit shifts.
+ var pointerData = DataWithPointer(data: data, bitOrder: .reversed)
+
+ // Looking for the end of central directory (CD) record.
+ var zip64RecordExists = false
+
+ pointerData.index = pointerData.size - 22 // 22 is a minimum amount which could take end of CD record.
+ while true {
+ // Check signature.
+ if pointerData.uint64FromAlignedBytes(count: 4) == 0x06054b50 {
+ // We found it!
+ break
+ }
+ if pointerData.index == 0 {
+ throw ZipError.NotFoundCentralDirectoryEnd
+ }
+ pointerData.index -= 5
+ }
+
+ /// Number of current disk.
+ var currentDiskNumber = pointerData.uint64FromAlignedBytes(count: 2)
+ /// Number of the disk with the start of CD.
+ var cdDiskNumber = pointerData.uint64FromAlignedBytes(count: 2)
+ if currentDiskNumber == 0xFFFF || cdDiskNumber == 0xFFFF {
+ zip64RecordExists = true
+ }
+ guard currentDiskNumber == cdDiskNumber
+ else { throw ZipError.MultiVolumesNotSupported }
+
+ /// Number of CD entries on the current disk.
+ var cdEntriesCurrentDisk = pointerData.uint64FromAlignedBytes(count: 2)
+ /// Total number of CD entries.
+ var cdEntries = pointerData.uint64FromAlignedBytes(count: 2)
+ if cdEntriesCurrentDisk == 0xFFFF || cdEntries == 0xFFFF {
+ zip64RecordExists = true
+ }
+ guard cdEntries == cdEntriesCurrentDisk
+ else { throw ZipError.MultiVolumesNotSupported }
+
+ /// Size of Central Directory.
+ var cdSize = pointerData.uint64FromAlignedBytes(count: 4)
+ /// Offset to the start of Central Directory.
+ var cdOffset = pointerData.uint64FromAlignedBytes(count: 4)
+ let zipCommentLength = pointerData.intFromAlignedBytes(count: 2)
+ if cdSize == 0xFFFFFFFF || cdOffset == 0xFFFFFFFF {
+ zip64RecordExists = true
+ }
+
+ // There is also a .ZIP file comment, but we don't need it.
+ // Here's how it can be processed:
+ // let zipComment = String(data: Data(bytes: pointerData.alignedBytes(count: zipCommentLength)),
+ // encoding: .utf8)
+
+ if zip64RecordExists { // We need to find Zip64 end of CD locator.
+ // Back to start of end of CD record.
+ pointerData.index -= zipCommentLength + 22
+ // Zip64 locator takes exactly 20 bytes.
+ pointerData.index -= 20
+
+ // Check signature.
+ guard pointerData.uint64FromAlignedBytes(count: 4) == 0x07064b50
+ else { throw ZipError.WrongSignature }
+
+ let zip64CDStartDisk = pointerData.uint64FromAlignedBytes(count: 4)
+ guard currentDiskNumber == zip64CDStartDisk
+ else { throw ZipError.MultiVolumesNotSupported }
+
+ let zip64CDEndOffset = pointerData.uint64FromAlignedBytes(count: 8)
+ let totalDisks = pointerData.uint64FromAlignedBytes(count: 1)
+ guard totalDisks == 1
+ else { throw ZipError.MultiVolumesNotSupported }
+
+ // Now we need to move to Zip64 End of CD.
+ pointerData.index = Int(UInt(truncatingBitPattern: zip64CDEndOffset))
+
+ // Check signature.
+ guard pointerData.uint64FromAlignedBytes(count: 4) == 0x06064b50
+ else { throw ZipError.WrongSignature }
+
+ // Following 8 bytes are size of end of zip64 CD, but we don't need it.
+ _ = pointerData.uint64FromAlignedBytes(count: 8)
+
+ // Next two bytes are version of compressor, but we don't need it.
+ _ = pointerData.uint64FromAlignedBytes(count: 2)
+ let versionNeeded = pointerData.uint64FromAlignedBytes(count: 2)
+ guard versionNeeded <= 45
+ else { throw ZipError.WrongVersion }
+
+ // Update values read from basic End of CD to the one from Zip64 End of CD.
+ currentDiskNumber = pointerData.uint64FromAlignedBytes(count: 4)
+ cdDiskNumber = pointerData.uint64FromAlignedBytes(count: 4)
+ guard currentDiskNumber == cdDiskNumber
+ else { throw ZipError.MultiVolumesNotSupported }
+
+ cdEntriesCurrentDisk = pointerData.uint64FromAlignedBytes(count: 8)
+ cdEntries = pointerData.uint64FromAlignedBytes(count: 8)
+ guard cdEntries == cdEntriesCurrentDisk
+ else { throw ZipError.MultiVolumesNotSupported }
+
+ cdSize = pointerData.uint64FromAlignedBytes(count: 8)
+ cdOffset = pointerData.uint64FromAlignedBytes(count: 8)
+
+ // Then, there might be 'zip64 extensible data sector' with 'special purpose data'.
+ // But we don't need them currently, so let's skip them.
+
+ // To find the size of these data:
+ // let specialPurposeDataSize = zip64EndCDSize - 56
+ }
+
+ // OK, now we are ready to read Central Directory itself.
+ pointerData.index = Int(UInt(truncatingBitPattern: cdOffset))
+
+ var result: [(entryName: String, entryData: Data)] = []
+ for _ in 0..
XZArchive
+
+ ZipContainer
+
ZlibArchive
@@ -87,6 +90,9 @@
XZError
+
+ ZipError
+
ZlibError
@@ -168,7 +174,7 @@
@@ -190,7 +196,7 @@
-
A class with unarchive function for gzip archives.
+
Provides unarchive function for GZip archives.
See more
@@ -203,7 +209,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Provides function to open ZIP archives (containers).
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public class ZipContainer
+
+
+
+
@@ -238,7 +279,7 @@
@@ -260,7 +301,7 @@
-
A class with unarchive function for Zlib archives.
+
Provides unarchive function for Zlib archives.
See more
@@ -273,7 +314,7 @@
@@ -295,7 +336,7 @@
-
Provides function to decompress data, which were compressed with DEFLATE
+
Provides function to decompress data, which were compressed with DEFLATE.
See more
@@ -308,7 +349,7 @@
@@ -330,7 +371,7 @@
-
Provides function to decompress data, which were compressed using BZip2
+
Provides function to decompress data, which were compressed using BZip2.
See more
@@ -343,7 +384,7 @@
@@ -365,7 +406,7 @@
-
A class with unarchive function for xz archives.
+
Provides unarchive function for XZ archives.
See more
@@ -378,7 +419,7 @@
@@ -391,7 +432,7 @@
+
+
+
+
+
+
+
+
+ SWCompression Reference
+
+ ZipContainer Class Reference
+
+
+
+
+
+
+
+
+
+
+
ZipContainer
+
+
+
public class ZipContainer
+
+
+
+
Provides function to open ZIP archives (containers).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Processes ZIP archive (container) and returns an array of tuples (String, Data).
+First member of a tuple is entry’s name, second member is entry’s data.
+
+
+
Important
+
The order of entries is defined by ZIP archive and, particularly, creator of given ZIP container.
+It is likely that directories will be encountered earlier than files stored in those directories,
+but one SHOULD NOT assume that this is the case.
+
+
+
+
+
Note
+
Currently, there is no universal (platform and file system independent) method to determine if entry is a directory.
+One can check this by looking at the size of entry’s data (it should be 0 for directory) AND
+the last character of entry’s name (it should be ‘/’). If all of these is true then entry is likely to be a directory.
+
+
+
+
+
Note
+
Only ZIP containers complying to ISO/IEC 21320-1 standard are supported.
+
+
+
+
+
Parameter
+
Parameter containerData: Data of ZIP container.
+
+
+
+
+
Throws
+
ZipError or DeflateError depending on the type of inconsistency in data.
+It may indicate that either the container is damaged or it might not be ZIP container or compressed with Deflate at all.
+
+
+
+
+
Returns
+
Array of pairs (tuples) where first member is entryName and second member is entryData.
+
+
+
+
+
+
Declaration
+
+
Swift
+
public static func open ( containerData data : Data ) throws -> [( entryName : String , entryData : Data )]
+
+
+
+
+
Parameters
+
+
+
+
+
+ containerData
+
+
+
+
+
Data of ZIP container.
+
+
+
+
+
+
+
+
+
Return Value
+
Array of pairs (tuples) where first member is entryName and second member is entryData.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Classes/BZip2.html b/docs/Classes/BZip2.html
index 5de39f64..a99476d9 100644
--- a/docs/Classes/BZip2.html
+++ b/docs/Classes/BZip2.html
@@ -62,6 +62,9 @@
Provides function to decompress data, which were compressed using BZip2.
@@ -220,7 +226,7 @@ It may indicate that either the data is damaged or it might not be compressed wi
@@ -233,7 +239,7 @@ It may indicate that either the data is damaged or it might not be compressed wi
diff --git a/docs/Classes/Deflate.html b/docs/Classes/Deflate.html
index 88c47c44..6c863702 100644
--- a/docs/Classes/Deflate.html
+++ b/docs/Classes/Deflate.html
@@ -62,6 +62,9 @@
Provides function to decompress data, which were compressed with DEFLATE.
@@ -220,7 +226,7 @@ It may indicate that either the data is damaged or it might not be compressed wi
@@ -233,7 +239,7 @@ It may indicate that either the data is damaged or it might not be compressed wi
diff --git a/docs/Classes/GzipArchive.html b/docs/Classes/GzipArchive.html
index 70b9a63f..d962fa55 100644
--- a/docs/Classes/GzipArchive.html
+++ b/docs/Classes/GzipArchive.html
@@ -62,6 +62,9 @@
A class with unarchive function for gzip archives.
Provides unarchive function for GZip archives.
@@ -228,7 +234,7 @@ It may indicate that either the data is damaged or it might not be compressed wi
@@ -241,7 +247,7 @@ It may indicate that either the data is damaged or it might not be compressed wi
diff --git a/docs/Classes/LZMA.html b/docs/Classes/LZMA.html
index 184097d0..7623d503 100644
--- a/docs/Classes/LZMA.html
+++ b/docs/Classes/LZMA.html
@@ -62,6 +62,9 @@
@@ -220,7 +226,7 @@ It may indicate that either the data is damaged or it might not be compressed wi
@@ -233,7 +239,7 @@ It may indicate that either the data is damaged or it might not be compressed wi
diff --git a/docs/Classes/LZMA2.html b/docs/Classes/LZMA2.html
index 23aba0b0..602fd158 100644
--- a/docs/Classes/LZMA2.html
+++ b/docs/Classes/LZMA2.html
@@ -62,6 +62,9 @@
@@ -220,7 +226,7 @@ It may indicate that either the data is damaged or it might not be compressed wi
@@ -233,7 +239,7 @@ It may indicate that either the data is damaged or it might not be compressed wi
diff --git a/docs/Classes/XZArchive.html b/docs/Classes/XZArchive.html
index 387bd0c0..a682cb4d 100644
--- a/docs/Classes/XZArchive.html
+++ b/docs/Classes/XZArchive.html
@@ -62,6 +62,9 @@
A class with unarchive function for xz archives.
Provides unarchive function for XZ archives.
@@ -224,7 +230,7 @@ It may indicate that either the data is damaged or it might not be compressed wi
@@ -237,7 +243,7 @@ It may indicate that either the data is damaged or it might not be compressed wi
diff --git a/docs/Classes/ZipContainer.html b/docs/Classes/ZipContainer.html
new file mode 100644
index 00000000..1f2b185b
--- /dev/null
+++ b/docs/Classes/ZipContainer.html
@@ -0,0 +1,268 @@
+
+
+