Skip to content

Commit

Permalink
Try again with swift-system
Browse files Browse the repository at this point in the history
  • Loading branch information
fpseverino committed Sep 22, 2024
1 parent cefe774 commit 776bfa8
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 38 deletions.
4 changes: 4 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ let package = Package(
products: [
.library(name: "Zip", targets: ["Zip"])
],
dependencies: [
.package(url: "https://github.com/apple/swift-system", from: "1.3.2"),
],
targets: [
.target(
name: "CMinizip",
Expand All @@ -26,6 +29,7 @@ let package = Package(
name: "Zip",
dependencies: [
.target(name: "CMinizip"),
.product(name: "SystemPackage", package: "swift-system"),
],
cSettings: [
.define("_CRT_SECURE_NO_WARNINGS", .when(platforms: [.windows])),
Expand Down
63 changes: 25 additions & 38 deletions Sources/Zip/Zip.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import FoundationEssentials
#else
import Foundation
#endif
import SystemPackage
@_implementationOnly import CMinizip

/// Main class that handles zipping and unzipping of files.
Expand Down Expand Up @@ -69,7 +70,7 @@ public class Zip {
progressTracker.kind = ProgressKind.file

// Begin unzipping
let zip = unzOpen64(path)
let zip = unzOpen64(FilePath(path).string)
defer { unzClose(zip) }
if unzGoToFirstFile(zip) != UNZ_OK {
throw ZipError.unzipFail
Expand Down Expand Up @@ -99,11 +100,6 @@ public class Zip {

var pathString = String(cString: fileName)

#if os(Windows)
// Colons are not allowed in Windows file names.
pathString = pathString.replacingOccurrences(of: ":", with: "_")
#endif

guard !pathString.isEmpty else {
throw ZipError.unzipFail
}
Expand All @@ -121,44 +117,41 @@ public class Zip {
throw ZipError.unzipFail
}

let directoryAttributes: [FileAttributeKey: Any]?
#if (os(Linux) || os(Windows)) && swift(<6.0)
// On Linux and Windows, setting attributes is not yet really implemented.
directoryAttributes = nil
#else
let creationDate = Date()
directoryAttributes = [
.creationDate: creationDate,
.modificationDate: creationDate
]
#endif

do {
if isDirectory {
try FileManager.default.createDirectory(atPath: fullPath, withIntermediateDirectories: true, attributes: directoryAttributes)
try FileManager.default.createDirectory(atPath: fullPath, withIntermediateDirectories: true)
} else {
let parentDirectory = (fullPath as NSString).deletingLastPathComponent
try FileManager.default.createDirectory(atPath: parentDirectory, withIntermediateDirectories: true, attributes: directoryAttributes)
try FileManager.default.createDirectory(atPath: parentDirectory, withIntermediateDirectories: true)
}
} catch {}
if FileManager.default.fileExists(atPath: fullPath) && !isDirectory && !overwrite {
unzCloseCurrentFile(zip)
ret = unzGoToNextFile(zip)
}

var writeBytes: UInt64 = 0
let filePointer: UnsafeMutablePointer<FILE>? = fopen(fullPath, "wb")
while let filePointer {
let readBytes = unzReadCurrentFile(zip, &buffer, bufferSize)
guard readBytes > 0 else { break }
guard fwrite(buffer, Int(readBytes), 1, filePointer) == 1 else {
throw ZipError.unzipFail
var writeBytes: Int = 0
do {
let fd = try FileDescriptor.open(
FilePath(fullPath),
.writeOnly,
options: [.append, .create],
permissions: .ownerReadWrite
)
try fd.closeAfter {
while true {
let readBytes = unzReadCurrentFile(zip, &buffer, bufferSize)
guard readBytes > 0 else { break }
writeBytes += try fd.writeAll(buffer[..<Int(readBytes)])
}
}
writeBytes += UInt64(readBytes)
} catch let error as Errno where error == .isDirectory {
// Skip files that are directories
} catch {
// If they are not directories, re-throw any other error
throw error
}

if let filePointer { fclose(filePointer) }

if unzCloseCurrentFile(zip) == UNZ_CRCERROR {
throw ZipError.unzipFail
}
Expand Down Expand Up @@ -187,15 +180,9 @@ public class Zip {
}

if let fileHandler = fileOutputHandler,
let encodedString = fullPath.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
#if os(Windows)
let fileUrlString = "file:///\(encodedString)"
#else
let fileUrlString = encodedString
#endif
if let fileUrl = URL(string: fileUrlString) {
let encodedString = fullPath.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let fileUrl = URL(string: FilePath(encodedString).string) {
fileHandler(fileUrl)
}
}

progressTracker.completedUnitCount = Int64(currentPosition)
Expand Down

0 comments on commit 776bfa8

Please sign in to comment.