diff --git a/.jazzy.yaml b/.jazzy.yaml
index 2a57f2b1..2a023beb 100644
--- a/.jazzy.yaml
+++ b/.jazzy.yaml
@@ -3,11 +3,11 @@ sourcekitten_sourcefile: docs.json
clean: true
author: Timofey Solomko
module: SWCompression
-module_version: 4.5.9
+module_version: 4.5.10
copyright: '© 2021 Timofey Solomko'
readme: README.md
github_url: https://github.com/tsolomko/SWCompression
-github_file_prefix: https://github.com/tsolomko/SWCompression/tree/4.5.9
+github_file_prefix: https://github.com/tsolomko/SWCompression/tree/4.5.10
theme: fullwidth
custom_categories:
diff --git a/.markdownlint.json b/.markdownlint.json
deleted file mode 100644
index f520e6d4..00000000
--- a/.markdownlint.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "MD007": { "indent": 4 },
- "MD013": { "line_length": 120 },
- "MD024": false,
- "MD026": { "punctuation": ".,;:!"},
- "MD029": { "style": "ordered" }
-}
\ No newline at end of file
diff --git a/.swiftlint.yml b/.swiftlint.yml
deleted file mode 100644
index 13f4fa2f..00000000
--- a/.swiftlint.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-excluded:
- - .build/
- - Package.swift
- - Carthage/
-disabled_rules:
- - cyclomatic_complexity
- - file_length
- - for_where
- - function_body_length
- - identifier_name
- - type_body_length
-opt_in_rules:
- - array_init
- - block_based_kvo
- - conditional_returns_on_newline
- - contains_over_first_not_nil
- - discouraged_direct_init
- - discouraged_object_literal
- - discouraged_optional_boolean
- - explicit_init
- - fatal_error_message
- - first_where
- - implicit_return
- - implicitly_unwrapped_optional
- - joined_default_parameter
- - literal_expression_end_indentation
- - operator_usage_whitespace
- - pattern_matching_keywords
- - redundant_nil_coalescing
- - single_test_class
- - sorted_first_last
- - switch_case_on_newline
- - trailing_closure
diff --git a/.travis.yml b/.travis.yml
index 2feceae2..e47ec207 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,6 +3,10 @@ git:
depth: 1
submodules: false
jobs:
+ allow_failures:
+ # There is an issue with Swift 5.4 on Linux which fails the build. See https://bugs.swift.org/browse/SR-14594.
+ env:
+ - SWIFT_VERSION=5.4
include:
# We test only building using SPM with Swift 4.2 on macos since Carthage doesn't support multiple Swift language versions.
- stage: test
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 989429ba..d28dce1b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 4.5.10
+
+- Fixed compilation issues on Windows (PR #22 by @trametheka).
+- Performed minor optimizations to BZip2 and Deflate compression functionality.
+- Increased the lowest required version of BitByteData dependency to 1.4.4.
+
## 4.5.9
- Improved performance of LZMA/LZMA2 and, consequently, of XZ.
diff --git a/Cartfile b/Cartfile
index 934643de..2068ee10 100644
--- a/Cartfile
+++ b/Cartfile
@@ -1 +1 @@
-github "tsolomko/BitByteData" ~> 1.4.3
+github "tsolomko/BitByteData" ~> 1.4.4
diff --git a/Package.swift b/Package.swift
index d957f93e..769ea9f1 100644
--- a/Package.swift
+++ b/Package.swift
@@ -13,7 +13,7 @@ let package = Package(
// .package(url: "https://github.com/jakeheis/SwiftCLI",
// from: "5.2.0"),
.package(url: "https://github.com/tsolomko/BitByteData",
- from: "1.4.3"),
+ from: "1.4.4"),
],
targets: [
// SWCOMP: Uncomment the lines below to build swcomp example program.
diff --git a/Package@swift-4.2.swift b/Package@swift-4.2.swift
index 33ca19c7..d81037fa 100644
--- a/Package@swift-4.2.swift
+++ b/Package@swift-4.2.swift
@@ -13,7 +13,7 @@ let package = Package(
// .package(url: "https://github.com/jakeheis/SwiftCLI",
// from: "5.2.0"),
.package(url: "https://github.com/tsolomko/BitByteData",
- from: "1.4.3"),
+ from: "1.4.4"),
],
targets: [
// SWCOMP: Uncomment the lines below to build swcomp example program.
diff --git a/SWCompression.podspec b/SWCompression.podspec
index 719ef789..d02424bd 100644
--- a/SWCompression.podspec
+++ b/SWCompression.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "SWCompression"
- s.version = "4.5.9"
+ s.version = "4.5.10"
s.summary = "A framework with functions for working with compression, archives and containers."
s.description = "A framework with (de)compression algorithms and functions for processing various archives and containers."
@@ -22,7 +22,7 @@ Pod::Spec.new do |s|
s.swift_versions = ["4", "5"]
- s.dependency "BitByteData", "~> 1.4.3"
+ s.dependency "BitByteData", "~> 1.4.4"
s.subspec "Deflate" do |sp|
sp.source_files = "Sources/{Deflate/*,Common/*,Common/CodingTree/*}.swift"
diff --git a/SWCompression.xcodeproj/SWCompression.plist b/SWCompression.xcodeproj/SWCompression.plist
index ccfd150a..dc55faec 100644
--- a/SWCompression.xcodeproj/SWCompression.plist
+++ b/SWCompression.xcodeproj/SWCompression.plist
@@ -15,9 +15,9 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 4.5.9
+ 4.5.10
CFBundleVersion
- 76
+ 77
NSHumanReadableCopyright
Copyright © 2021 Timofey Solomko
diff --git a/SWCompression.xcodeproj/TestSWCompression.plist b/SWCompression.xcodeproj/TestSWCompression.plist
index fbfd44a0..1b2400fd 100644
--- a/SWCompression.xcodeproj/TestSWCompression.plist
+++ b/SWCompression.xcodeproj/TestSWCompression.plist
@@ -15,8 +15,8 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 4.5.9
+ 4.5.10
CFBundleVersion
- 76
+ 77
diff --git a/SWCompression.xcodeproj/project.pbxproj b/SWCompression.xcodeproj/project.pbxproj
index e445fdd4..7bcbf9eb 100644
--- a/SWCompression.xcodeproj/project.pbxproj
+++ b/SWCompression.xcodeproj/project.pbxproj
@@ -1258,7 +1258,7 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CURRENT_PROJECT_VERSION = 76;
+ CURRENT_PROJECT_VERSION = 77;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@@ -1339,7 +1339,7 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CURRENT_PROJECT_VERSION = 76;
+ CURRENT_PROJECT_VERSION = 77;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
"FRAMEWORK_SEARCH_PATHS[sdk=appletvos*]" = (
@@ -1400,7 +1400,7 @@
APPLICATION_EXTENSION_API_ONLY = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 76;
+ DYLIB_CURRENT_VERSION = 77;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = SWCompression.xcodeproj/SWCompression.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@@ -1427,7 +1427,7 @@
APPLICATION_EXTENSION_API_ONLY = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 76;
+ DYLIB_CURRENT_VERSION = 77;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = SWCompression.xcodeproj/SWCompression.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
diff --git a/Sources/BZip2/BZip2+Compress.swift b/Sources/BZip2/BZip2+Compress.swift
index 6222bd9a..d46d764e 100644
--- a/Sources/BZip2/BZip2+Compress.swift
+++ b/Sources/BZip2/BZip2+Compress.swift
@@ -79,10 +79,8 @@ extension BZip2: CompressionAlgorithm {
(out, pointer) = BurrowsWheeler.transform(bytes: out)
let usedBytes = Set(out).sorted()
- out = mtf(out, characters: usedBytes)
-
var maxSymbol = 0
- (out, maxSymbol) = rleOfMtf(out)
+ (out, maxSymbol) = mtfRle(out, characters: usedBytes)
// First, we analyze data and create Huffman trees and selectors.
// Then we will perform encoding itself.
@@ -258,16 +256,23 @@ extension BZip2: CompressionAlgorithm {
return out
}
- private static func rleOfMtf(_ array: [Int]) -> ([Int], Int) {
+ private static func mtfRle(_ array: [Int], characters: [Int]) -> ([Int], Int) {
var out = [Int]()
+ /// Mutable copy of `characters`.
+ var dictionary = characters
var lengthOfZerosRun = 0
var maxSymbol = 1
for i in 0.. 0 {
let digitsNumber = Int(floor(log2(Double(lengthOfZerosRun) + 1)))
var remainder = lengthOfZerosRun
@@ -285,16 +290,19 @@ extension BZip2: CompressionAlgorithm {
}
}
if byte != 0 {
+ // We add one, because 1 is used as RUNB.
let newSymbol = byte + 1
- // We add one because, 1 is used as RUNB.
- // We don't add two instead, because 0 is never encountered as separate symbol, without RUNA meaning.
out.append(newSymbol)
if newSymbol > maxSymbol {
maxSymbol = newSymbol
}
}
+
+ // Move to the front.
+ let old = dictionary.remove(at: byte)
+ dictionary.insert(old, at: 0)
}
- // Add 'end of stream' symbol.
+ // Add the 'end of stream' symbol.
out.append(maxSymbol + 1)
return (out, maxSymbol)
}
diff --git a/Sources/Common/CodingTree/EncodingTree.swift b/Sources/Common/CodingTree/EncodingTree.swift
index a0fc7f8f..5fe0a7bb 100644
--- a/Sources/Common/CodingTree/EncodingTree.swift
+++ b/Sources/Common/CodingTree/EncodingTree.swift
@@ -6,22 +6,29 @@
import Foundation
import BitByteData
+fileprivate struct CodingIndex {
+
+ let treeCode: Int
+ let bitSize: Int
+
+}
+
final class EncodingTree {
private let bitWriter: BitWriter
- private let codingIndices: [[Int]]
+ private let codingIndices: [CodingIndex]
init(codes: [Code], _ bitWriter: BitWriter, reverseCodes: Bool = false) {
self.bitWriter = bitWriter
- var codingIndices = Array(repeating: [-1, -1], count: codes.count)
+ var codingIndices = Array(repeating: CodingIndex(treeCode: -1, bitSize: -1), count: codes.count)
for code in codes {
// Codes have already been reversed.
// TODO: This assumption may be only correct for Huffman codes.
let treeCode = reverseCodes ? code.code : code.code.reversed(bits: code.bits)
- codingIndices[code.symbol] = [treeCode, code.bits]
+ codingIndices[code.symbol] = CodingIndex(treeCode: treeCode, bitSize: code.bits)
}
self.codingIndices = codingIndices
@@ -33,10 +40,10 @@ final class EncodingTree {
let codingIndex = self.codingIndices[symbol]
- guard codingIndex[0] > -1
+ guard codingIndex.treeCode > -1
else { fatalError("Symbol is not found.") }
- self.bitWriter.write(number: codingIndex[0], bitsCount: codingIndex[1])
+ self.bitWriter.write(number: codingIndex.treeCode, bitsCount: codingIndex.bitSize)
}
func bitSize(for stats: [Int]) -> Int {
@@ -45,10 +52,10 @@ final class EncodingTree {
guard symbol < self.codingIndices.count
else { fatalError("Symbol is not found.") }
let codingIndex = self.codingIndices[symbol]
- guard codingIndex[0] > -1
+ guard codingIndex.treeCode > -1
else { fatalError("Symbol is not found.") }
- totalSize += count * codingIndex[1]
+ totalSize += count * codingIndex.bitSize
}
return totalSize
}
diff --git a/Sources/ZIP/ByteReader+Zip.swift b/Sources/ZIP/ByteReader+Zip.swift
index 95faf57e..cd4a9637 100644
--- a/Sources/ZIP/ByteReader+Zip.swift
+++ b/Sources/ZIP/ByteReader+Zip.swift
@@ -21,8 +21,12 @@ extension ByteReader {
return String(data: stringData, encoding: .utf8)
}
if String.cp437Available && !stringData.needsUtf8() {
+ #if os(Windows)
+ return String(data: stringData, encoding: String.cp437Encoding)
+ #else
return String(data: stringData, encoding: String.Encoding(rawValue:
CFStringConvertEncodingToNSStringEncoding(String.cp437Encoding)))
+ #endif
} else {
return String(data: stringData, encoding: .utf8)
}
@@ -39,6 +43,10 @@ fileprivate extension String {
static let cp437Encoding: CFStringEncoding = UInt32(truncatingIfNeeded: UInt(kCFStringEncodingDOSLatinUS))
#endif
static let cp437Available: Bool = CFStringIsEncodingAvailable(cp437Encoding)
+ #elseif os(Windows)
+ // "Latin-US (DOS)" CP437-2147483120
+ static let cp437Encoding = String.Encoding(rawValue: 0x80000400)
+ static let cp437Available = String.availableStringEncodings.contains(cp437Encoding)
#else
static let cp437Encoding = CFStringEncoding(CFStringEncodings.dosLatinUS.rawValue)
static let cp437Available = CFStringIsEncodingAvailable(cp437Encoding)
diff --git a/Sources/ZIP/ZipLocalHeader.swift b/Sources/ZIP/ZipLocalHeader.swift
index 327a3f96..e7be7086 100644
--- a/Sources/ZIP/ZipLocalHeader.swift
+++ b/Sources/ZIP/ZipLocalHeader.swift
@@ -75,7 +75,7 @@ struct ZipLocalHeader {
case 0x0001: // Zip64
// Zip64 extra field is a special case, because it requires knowledge about local header fields,
// in particular, uncompressed and compressed sizes.
- // In local header both uncompressed size and compressed size fields are required.
+ // In the local header both uncompressed size and compressed size fields are required.
self.uncompSize = byteReader.uint64()
self.compSize = byteReader.uint64()
self.zip64FieldsArePresent = true
diff --git a/Sources/swcomp/main.swift b/Sources/swcomp/main.swift
index 3cf41ef9..3e8b1885 100644
--- a/Sources/swcomp/main.swift
+++ b/Sources/swcomp/main.swift
@@ -7,7 +7,7 @@ import Foundation
import SWCompression
import SwiftCLI
-let cli = CLI(name: "swcomp", version: "4.5.9",
+let cli = CLI(name: "swcomp", version: "4.5.10",
description: """
swcomp - small command-line client for SWCompression framework.
Serves as an example of SWCompression usage.