From 6c58ef40cda13f6298d3c95605f9000405f117a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Fri, 6 Dec 2024 14:05:03 +0100 Subject: [PATCH] Remove unused Minizip from ReadiumStreamer (#517) --- Package.swift | 1 - .../Toolkit/ZIPArchive/ZIPArchive.swift | 321 ------------------ Sources/Streamer/Toolkit/ZIPArchive/Zip.h | 19 -- Support/Carthage/.xcodegen | 5 +- .../Readium.xcodeproj/project.pbxproj | 27 -- Support/CocoaPods/ReadiumStreamer.podspec | 1 - 6 files changed, 1 insertion(+), 373 deletions(-) delete mode 100644 Sources/Streamer/Toolkit/ZIPArchive/ZIPArchive.swift delete mode 100644 Sources/Streamer/Toolkit/ZIPArchive/Zip.h diff --git a/Package.swift b/Package.swift index 2197b1092..1ce44f2a7 100644 --- a/Package.swift +++ b/Package.swift @@ -60,7 +60,6 @@ let package = Package( dependencies: [ "CryptoSwift", "Fuzi", - "Zip", "ReadiumShared", ], path: "Sources/Streamer", diff --git a/Sources/Streamer/Toolkit/ZIPArchive/ZIPArchive.swift b/Sources/Streamer/Toolkit/ZIPArchive/ZIPArchive.swift deleted file mode 100644 index 4dba299cf..000000000 --- a/Sources/Streamer/Toolkit/ZIPArchive/ZIPArchive.swift +++ /dev/null @@ -1,321 +0,0 @@ -// -// Copyright 2024 Readium Foundation. All rights reserved. -// Use of this source code is governed by the BSD-style license -// available in the top-level LICENSE file of the project. -// - -import Foundation -import Minizip -import ReadiumShared - -public struct ZipFileInfo { - let path: String - let length: UInt64 - let isCompressed: Bool - let compressionLevel: Int - let crypted: Bool - let compressedLength: UInt64 - let date: Date? - let crc32: UInt32 -} - -internal enum ZipArchiveError: Error { - /// Minizip internal error. - case minizipError - /// A parameter passed to the minizip function wasn't accepted. - case paramError - /// The archive is currently busy or unusable. - case archiveNotUsable - /// The archive is corrupted. - case badZipFile - /// An error occured while reading the file at offset. - case readError - /// File not found in the archive. - case fileNotFound -} - -/// Wrapper around Minizip C lib. (Minizip uses Zlib) -internal class ZipArchive: Loggable { - /// The minizip memory representation of the Archive. - internal var unzFile: unzFile - /// The informations about the Archive. - internal var fileInfos = [String: ZipFileInfo]() - internal let bufferLength = 1024 * 64 - - /// The current offset position in the archive. - internal var currentFileOffset: Int { - Int(unzGetOffset(unzFile)) - } - - /// The total number of files in the archive. - fileprivate var numberOfFiles: Int { - var globalInfo = unz_global_info64() - - memset(&globalInfo, 0, MemoryLayout.size) - guard unzGetGlobalInfo64(unzFile, &globalInfo) == UNZ_OK else { - return 0 - } - return Int(globalInfo.number_entry) - } - - /// Initialize the object checking that the archive exists and opening it. - internal init?(url: URL) { - let fileManager = FileManager.default - - // Check that archives exists then open it. - guard fileManager.fileExists(atPath: url.path) != false, - let unzFile = unzOpen64(url.path) - /* , try? goToFirestFile() Is that done by default? Tocheck */ - else { - return nil - } - self.unzFile = unzFile - } - - /// Close the archive on the object deallocation. - deinit { - unzClose(unzFile) - } - - // MARK: - Internal Methods. - - /// Build the file list of the archive (Not done by default as it's only - /// usef in the CBZ so far). - internal func buildFilesList() throws { - try goToFirstFile() - repeat { - let fileInfo = try informationsOfCurrentFile() - - fileInfos[fileInfo.path] = fileInfo - } while try goToNextFile() - } - - /// Reads the data of the file at offset. - /// - /// - Returns: The data of the file at offset. - /// - Throws: - internal func readDataOfCurrentFile() throws -> Data { - let fileInfo = try informationsOfCurrentFile() - - let range = Range(uncheckedBounds: (lower: 0, upper: fileInfo.length)) - return try readDataOfCurrentFile(range: range) - } - - /// Reads the range of data from offset to range. - /// - /// - Parameter range: - /// - Returns: <#return value description#> - /// - Throws: <#throws value description#> - fileprivate func readDataOfCurrentFile(range: Range) throws -> Data { - let length = range.count - var buffer = [CUnsignedChar](repeating: 0, count: bufferLength) - var data = Data(capacity: Int(length)) - - /// Skip the first bytes of the file until lowerBound is reached. - try seek(Int(range.lowerBound)) - // Read the current file and add it to the data - var totalBytesRead = 0 - while totalBytesRead < length { - let bytesToRead = min(bufferLength, length - totalBytesRead) - let bytesRead = unzReadCurrentFile(unzFile, &buffer, UInt32(bytesToRead)) - if bytesRead > 0 { - totalBytesRead += Int(bytesRead) - data.append(buffer, count: Int(bytesRead)) - } else if bytesRead == 0 { - break - } else { - throw ZipArchiveError.readError - } - } - return data - } - - /// <#Description#> - /// - /// - Parameters: - /// - buffer: <#buffer description#> - /// - maxLength: <#maxLength description#> - /// - Returns: <#return value description#> - /// - Throws: <#throws value description#> - public func readDataFromCurrentFile(_ buffer: UnsafeMutablePointer, maxLength: UInt64) -> UInt64 { - assert(maxLength < UInt64(UInt32.max), "maxLength must be less than \(UInt32.max)") - - let bytesRead = unzReadCurrentFile(unzFile, buffer, UInt32(maxLength)) - if bytesRead < 0 { - log(.error, "Nothing to read") - } -// if bytesRead >= 0 { -// currentFileOffset += UInt64(bytesRead) -// } else { -// throw ZipError.unzipFail -// } - return bytesRead > 0 ? UInt64(bytesRead) : 0 - } - - public func readData(path: String) throws -> Data { - if locateFile(path: path) { - try openCurrentFile() - defer { - closeCurrentFile() - } - return try readDataOfCurrentFile() - } else { - throw ZipArchiveError.fileNotFound - } - } - - // MARK: - Fileprivate Methods. - - /// Move the offset to the file at `path` in the archive. - /// - /// - Parameter path: The path of the file in the archive. - /// - Returns: Return true if found, else false. - /// - Throws: `ZipArchiveError.archiveNotUsable`, - /// `ZipArchiveError.paramError`. - internal func locateFile(path: String) -> Bool { - guard unzLocateFile(unzFile, path, nil) == UNZ_OK else { - return false - } - return true - } - - /// Moves offset to the first file of the archive. - fileprivate func goToFirstFile() throws { - guard unzGoToFirstFile(unzFile) == UNZ_OK else { - throw ZipArchiveError.minizipError - } - } - - /// Moves offset to the next file of the archive. - /// - /// - Returns: Return false when there is no next file. - /// - Throws: - fileprivate func goToNextFile() throws -> Bool { - let ret = unzGoToNextFile(unzFile) - - switch ret { - case UNZ_END_OF_LIST_OF_FILE: - return false - case UNZ_OK: - return true - default: - throw ZipArchiveError.minizipError - } - } - - /// UNZ Enum for the unzSeek function. Determining the offset reference. - /// - /// - set: Seek from beginning of file. - /// - current: Seek from current position. - /// - end: Set file pointer to EOF plus "offset" - enum Origin: Int32 { - case set = 0 - case current - case end - } - - /// Seek position x. - /// - /// - Parameter x: The number of bytes to advance the current offset to. - internal func seek(_ offset: Int) throws { - let isCompressed = try informationsOfCurrentFile().isCompressed - // FIXME: https://github.com/readium/r2-shared-swift/issues/98 - if true || isCompressed { - // Deflate is stream-based, so we need to read the bytes from the beginning and discard - // them until we reach the offset. - let ioffset = Int(offset) - var buffer = [CUnsignedChar](repeating: 0, count: bufferLength) - - // Read the current file to the desired offset - var offsetBytesRead = 0 - while offsetBytesRead < ioffset { - let bytesToRead = min(bufferLength, ioffset - offsetBytesRead) - // Data is discarded - let bytesRead = unzReadCurrentFile(unzFile, &buffer, UInt32(bytesToRead)) - if bytesRead == 0 { - break - } - if bytesRead > 0 { - offsetBytesRead += Int(bytesRead) - } else { - throw ZipArchiveError.minizipError - } - } - - } else { - // For non-compressed entries, we can seek directly in the content. - if unzseek(unzFile, offset, SEEK_CUR) != UNZ_OK { - throw ZipArchiveError.minizipError - } - } - } - - /// Open the file at offset. - /// - /// - Throws: `ZipArchiveError.paramError`, - /// `ZipArchiveError.badZipFile`, - /// `ZipArchiveError.minizipError`. - internal func openCurrentFile() throws { - let err = unzOpenCurrentFile(unzFile) - - switch err { - case UNZ_PARAMERROR: - throw ZipArchiveError.paramError - case UNZ_BADZIPFILE: - throw ZipArchiveError.badZipFile - case UNZ_OK: - break // Success. - default: // UNZ_INTERNALERROR.. - throw ZipArchiveError.minizipError - } - } - - /// Close the currently opened file in the archive. - public func closeCurrentFile() { - unzCloseCurrentFile(unzFile) - } - - /// Get the information about the file being at offset. - /// - /// - Returns: <#return value description#> - /// - Throws: <#throws value description#> - internal func informationsOfCurrentFile() throws -> ZipFileInfo { - let fileNameMaxSize = 1024 - var fileInfo = unz_file_info64() - let fileName = UnsafeMutablePointer.allocate(capacity: fileNameMaxSize) - defer { - free(fileName) - } - - memset(&fileInfo, 0, MemoryLayout.size) - guard unzGetCurrentFileInfo64(unzFile, &fileInfo, fileName, UInt(fileNameMaxSize), nil, 0, nil, 0) == UNZ_OK else { - // throw ZipError.unzipFail - throw ZipArchiveError.minizipError - } - let path = String(cString: fileName) - guard !path.isEmpty else { - throw ZipArchiveError.paramError - } - let crypted = ((fileInfo.flag & 1) != 0) - let dateComponents = DateComponents(calendar: Calendar.autoupdatingCurrent, - timeZone: TimeZone.autoupdatingCurrent, - year: Int(fileInfo.tmu_date.tm_year), - month: Int(fileInfo.tmu_date.tm_mon + 1), - day: Int(fileInfo.tmu_date.tm_mday), - hour: Int(fileInfo.tmu_date.tm_hour), - minute: Int(fileInfo.tmu_date.tm_min), - second: Int(fileInfo.tmu_date.tm_sec)) - let date = dateComponents.date - let zipFileInfo = ZipFileInfo( - path: path, - length: fileInfo.uncompressed_size, - isCompressed: fileInfo.compression_method != 0, - compressionLevel: 0, - crypted: crypted, - compressedLength: fileInfo.compressed_size, - date: date, - crc32: UInt32(fileInfo.crc) - ) - return zipFileInfo - } -} diff --git a/Sources/Streamer/Toolkit/ZIPArchive/Zip.h b/Sources/Streamer/Toolkit/ZIPArchive/Zip.h deleted file mode 100644 index 73180feb8..000000000 --- a/Sources/Streamer/Toolkit/ZIPArchive/Zip.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// Zip.h -// Zip -// -// Created by Roy Marmelstein on 13/12/2015. -// Copyright © 2015 Roy Marmelstein. All rights reserved. -// - -@import Foundation; - -//! Project version number for Zip. -FOUNDATION_EXPORT double ZipVersionNumber; - -//! Project version string for Zip. -FOUNDATION_EXPORT const unsigned char ZipVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/Support/Carthage/.xcodegen b/Support/Carthage/.xcodegen index b852e6146..7c32cfc16 100644 --- a/Support/Carthage/.xcodegen +++ b/Support/Carthage/.xcodegen @@ -14028,7 +14028,4 @@ ../../Sources/Streamer/Toolkit/Extensions ../../Sources/Streamer/Toolkit/Extensions/Bundle.swift ../../Sources/Streamer/Toolkit/Extensions/Container.swift -../../Sources/Streamer/Toolkit/StringExtension.swift -../../Sources/Streamer/Toolkit/ZIPArchive -../../Sources/Streamer/Toolkit/ZIPArchive/Zip.h -../../Sources/Streamer/Toolkit/ZIPArchive/ZIPArchive.swift" +../../Sources/Streamer/Toolkit/StringExtension.swift" diff --git a/Support/Carthage/Readium.xcodeproj/project.pbxproj b/Support/Carthage/Readium.xcodeproj/project.pbxproj index a98c86aec..0915c11fc 100644 --- a/Support/Carthage/Readium.xcodeproj/project.pbxproj +++ b/Support/Carthage/Readium.xcodeproj/project.pbxproj @@ -108,7 +108,6 @@ 3E9F244ACDA938D330B9EAEA /* Subject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98CD4C99103DC795E44F56AE /* Subject.swift */; }; 3ECB525CEB712CEC5EFCD26D /* WarningLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3510E7E84A5361BCECC90569 /* WarningLogger.swift */; }; 40A44414CC911BF49BB5EE60 /* Tokenizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DA31089FCAD8DFB9AC46E4E /* Tokenizer.swift */; }; - 4299A01EF9F64B562A234FF6 /* ZIPArchive.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA10E1438AE5AF459033776A /* ZIPArchive.swift */; }; 44152DBECE34F063AD0E93BC /* Link.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE3E6442F0C7FE2098D71F27 /* Link.swift */; }; 448374F2605586249A6CB4C8 /* FailureResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78FFDF8CF77437EDB41E4547 /* FailureResource.swift */; }; 46D29739FB017C62767CBE63 /* Presentation+EPUB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42EFF9139B59D763CE254F92 /* Presentation+EPUB.swift */; }; @@ -216,7 +215,6 @@ 8D6EFD7710BEB8539E4E64E6 /* DOMRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = C084C255A327387F36B97A62 /* DOMRange.swift */; }; 8E25FF2EEFA72D9B0F3025C5 /* PDFFormatSniffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B72B76AB39E09E4A2E465AF /* PDFFormatSniffer.swift */; }; 8F5B0B5B83BF7F1145556FF8 /* Properties+OPDS.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD79372361D085CA0500CF4 /* Properties+OPDS.swift */; }; - 8FEB56CBC27DE69E120F138C /* Zip.h in Headers */ = {isa = PBXBuildFile; fileRef = CE641F78FD99A426A80B3495 /* Zip.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9065C4C0F40B6A5601541EF7 /* Streamable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 622CB8B75A568846FECA44D6 /* Streamable.swift */; }; 90769CA2ABCBD1F7203697DC /* Minizip.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFFEBDFE931745C07DACD4A3 /* Minizip.xcframework */; }; 90CFD62B993F6759716C0AF0 /* LicensesService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56286133DD0AE093F2C5E9FD /* LicensesService.swift */; }; @@ -774,7 +772,6 @@ CBB57FCAEE605484A7290DBB /* Atomic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = ""; }; CC925E451D875E5F74748EDC /* Optional.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Optional.swift; sourceTree = ""; }; CDA8111A330AB4D7187DD743 /* LocatorService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocatorService.swift; sourceTree = ""; }; - CE641F78FD99A426A80B3495 /* Zip.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Zip.h; sourceTree = ""; }; CF31AEFB5FF0E7892C6D903E /* EPUBPreferences+Legacy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EPUBPreferences+Legacy.swift"; sourceTree = ""; }; CFE1142A6C038A35C527CE84 /* URITemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URITemplate.swift; sourceTree = ""; }; CFE34EA8AF2D815F7169CA45 /* Fuzi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fuzi.swift; sourceTree = ""; }; @@ -848,7 +845,6 @@ F820DAECA1FC23C42719CD68 /* EncryptionParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionParser.swift; sourceTree = ""; }; F8C32FDF5E2D35BE71E45ED0 /* AudioPreferencesEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPreferencesEditor.swift; sourceTree = ""; }; F90C4D94134D9F741D38D8AA /* Comparable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Comparable.swift; sourceTree = ""; }; - FA10E1438AE5AF459033776A /* ZIPArchive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZIPArchive.swift; sourceTree = ""; }; FC3996B9F88089C7F752C531 /* DefaultFormatSniffer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultFormatSniffer.swift; sourceTree = ""; }; FC6271FA7F282364A4E68C4C /* ComicFormatSniffer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComicFormatSniffer.swift; sourceTree = ""; }; FC9D0ACCBA7B6E4473A95D5E /* AudioSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioSettings.swift; sourceTree = ""; }; @@ -1247,7 +1243,6 @@ ACB32E55E1F3CAF1737979CC /* DataCompression.swift */, 125BAF5FDFA097BA5CC63539 /* StringExtension.swift */, C436D1FEFF82645FF9286F52 /* Extensions */, - C134ADFADD569A8A7471178E /* ZIPArchive */, ); path = Toolkit; sourceTree = ""; @@ -1794,15 +1789,6 @@ path = "Media Overlays"; sourceTree = ""; }; - C134ADFADD569A8A7471178E /* ZIPArchive */ = { - isa = PBXGroup; - children = ( - CE641F78FD99A426A80B3495 /* Zip.h */, - FA10E1438AE5AF459033776A /* ZIPArchive.swift */, - ); - path = ZIPArchive; - sourceTree = ""; - }; C42B511253C3D9C6DA8AA5CC /* Toolkit */ = { isa = PBXGroup; children = ( @@ -2084,17 +2070,6 @@ }; /* End PBXGroup section */ -/* Begin PBXHeadersBuildPhase section */ - 991EA4CF27076654ADC28E9E /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 8FEB56CBC27DE69E120F138C /* Zip.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - /* Begin PBXNativeTarget section */ 223AD2DC63611790F513E0C7 /* ReadiumAdapterLCPSQLite */ = { isa = PBXNativeTarget; @@ -2118,7 +2093,6 @@ isa = PBXNativeTarget; buildConfigurationList = E7578035C21EEC9C0AE298B2 /* Build configuration list for PBXNativeTarget "ReadiumStreamer" */; buildPhases = ( - 991EA4CF27076654ADC28E9E /* Headers */, 91B7510E2CDFC2FAD8619A77 /* Sources */, 587BC73C39EFB0296396D4E0 /* Resources */, B9FAF5D6C24FE948E42D98A1 /* Frameworks */, @@ -2420,7 +2394,6 @@ 25E7A4A839D3BDB07D8A7203 /* Streamer.swift in Sources */, 4AE70F783C07D9938B40E792 /* StringExtension.swift in Sources */, C1CD3DA1A9EF154667E5B50B /* WebServerResourceResponse.swift in Sources */, - 4299A01EF9F64B562A234FF6 /* ZIPArchive.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Support/CocoaPods/ReadiumStreamer.podspec b/Support/CocoaPods/ReadiumStreamer.podspec index fe4e7d085..e20c669f3 100644 --- a/Support/CocoaPods/ReadiumStreamer.podspec +++ b/Support/CocoaPods/ReadiumStreamer.podspec @@ -24,6 +24,5 @@ Pod::Spec.new do |s| s.dependency 'ReadiumInternal' s.dependency 'CryptoSwift', '~> 1.8.0' s.dependency 'Fuzi', '~> 3.1.0' - s.dependency 'Minizip', '~> 1.0.0' end