Updates delta cores + replaces ZipZap with ZIPFoundation

Replaces ZipZap with ZIPFoundation due to DeltaCore now using ZIPFoundation
This commit is contained in:
Riley Testut 2018-11-08 17:13:39 -08:00
parent f293a2843f
commit 15b23c13e7
7 changed files with 22 additions and 213 deletions

@ -1 +1 @@
Subproject commit 4947d10713ba31017e40df275f40a315cf0da897
Subproject commit ec24fdbd721a8a21636916797f65c2a97f1b0ac5

@ -1 +1 @@
Subproject commit 54d064d34a4d856fd34a49308f42f1aefac8eaad
Subproject commit f958a29481557135ffaf3d7f4c50b43edacffb7e

@ -1 +1 @@
Subproject commit 9c295a2a287821544fec4b29d2b3f1205f965275
Subproject commit 1a45f455c2fb89a81fad1eea4abb198084a4e41a

@ -1 +1 @@
Subproject commit a3f0547bc57c14b548105020136a9ead56f73470
Subproject commit 4641bfc256383817cbded045eaf214aacea6ac6d

View File

@ -85,8 +85,6 @@
BF6BF3271EB87EB8008E83CD /* PhotoLibraryImportOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6BF3261EB87EB8008E83CD /* PhotoLibraryImportOption.swift */; };
BF6EE5E91F7C5F860051AD6C /* _GameControllerInputMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6EE5E81F7C5F860051AD6C /* _GameControllerInputMapping.swift */; };
BF6EE5EB1F7C5F8F0051AD6C /* GameControllerInputMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6EE5EA1F7C5F8F0051AD6C /* GameControllerInputMapping.swift */; };
BF70798C1B6B464B0019077C /* ZipZap.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF70798B1B6B464B0019077C /* ZipZap.framework */; };
BF70798D1B6B464B0019077C /* ZipZap.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BF70798B1B6B464B0019077C /* ZipZap.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
BF71CF871FE90006001F1613 /* AppIconShortcutsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF71CF861FE90006001F1613 /* AppIconShortcutsViewController.swift */; };
BF71CF8A1FE904B1001F1613 /* GameTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF71CF891FE904B1001F1613 /* GameTableViewCell.xib */; };
BF797A2D1C2D339F00F1A000 /* UILabel+FontSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF797A2C1C2D339F00F1A000 /* UILabel+FontSize.swift */; };
@ -118,7 +116,6 @@
BFF0742C1E9DC17500ACDF4A /* GBCDeltaCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFF0742B1E9DC17500ACDF4A /* GBCDeltaCore.framework */; };
BFF0742D1E9DC17500ACDF4A /* GBCDeltaCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BFF0742B1E9DC17500ACDF4A /* GBCDeltaCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
BFF6452E1F7CC5060056533E /* GameControllerInputMappingTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6B82A41F7CC2A300042BFB /* GameControllerInputMappingTransformer.swift */; };
BFF93AA01E0FB036005EC865 /* InputStreamOutputWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF93A9F1E0FB036005EC865 /* InputStreamOutputWriter.swift */; };
BFFA4C091E8A24D600D87934 /* GameTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFA4C081E8A24D600D87934 /* GameTableViewCell.swift */; };
BFFA71DD1AAC406100EE9DD1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFA71DC1AAC406100EE9DD1 /* AppDelegate.swift */; };
BFFA71E21AAC406100EE9DD1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFFA71E01AAC406100EE9DD1 /* Main.storyboard */; };
@ -140,7 +137,6 @@
BF9F4FD01AAD7B87004C9500 /* DeltaCore.framework in Embed Frameworks */,
BFF0742D1E9DC17500ACDF4A /* GBCDeltaCore.framework in Embed Frameworks */,
BFEC732E1AAECC4A00650035 /* Roxas.framework in Embed Frameworks */,
BF70798D1B6B464B0019077C /* ZipZap.framework in Embed Frameworks */,
BF0418151D01E93400E85BCF /* GBADeltaCore.framework in Embed Frameworks */,
BF99C6951D0A9AA600BA92BC /* SNESDeltaCore.framework in Embed Frameworks */,
);
@ -250,7 +246,6 @@
BFEC732C1AAECC4A00650035 /* Roxas.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Roxas.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BFEF24F21F7DD4FB00454C62 /* SaveStateMigrationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveStateMigrationPolicy.swift; sourceTree = "<group>"; };
BFF0742B1E9DC17500ACDF4A /* GBCDeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = GBCDeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BFF93A9F1E0FB036005EC865 /* InputStreamOutputWriter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputStreamOutputWriter.swift; sourceTree = "<group>"; };
BFFA4C081E8A24D600D87934 /* GameTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameTableViewCell.swift; sourceTree = "<group>"; };
BFFA71D71AAC406100EE9DD1 /* Delta.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Delta.app; sourceTree = BUILT_PRODUCTS_DIR; };
BFFA71DB1AAC406100EE9DD1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -273,7 +268,6 @@
BF9F4FCF1AAD7B87004C9500 /* DeltaCore.framework in Frameworks */,
BFEC732D1AAECC4A00650035 /* Roxas.framework in Frameworks */,
BF99C6941D0A9AA600BA92BC /* SNESDeltaCore.framework in Frameworks */,
BF70798C1B6B464B0019077C /* ZipZap.framework in Frameworks */,
BF0418141D01E93400E85BCF /* GBADeltaCore.framework in Frameworks */,
BFF0742C1E9DC17500ACDF4A /* GBCDeltaCore.framework in Frameworks */,
4FE8465FD28810191C3E5212 /* Pods_Delta.framework in Frameworks */,
@ -394,7 +388,6 @@
isa = PBXGroup;
children = (
BF59426D1E09BC5D0051894B /* DatabaseManager.swift */,
BFF93A9F1E0FB036005EC865 /* InputStreamOutputWriter.swift */,
BF5942711E09BC690051894B /* Model */,
BF95E2751E49763D0030E7AD /* OpenVGDB */,
);
@ -968,7 +961,6 @@
BF696B801D9B2B02009639E0 /* Theme.swift in Sources */,
BF7AE8081C2E858400B1B5BC /* GridMenuViewController.swift in Sources */,
BF6BF31A1EB82146008E83CD /* ClipboardImportOption.swift in Sources */,
BFF93AA01E0FB036005EC865 /* InputStreamOutputWriter.swift in Sources */,
BF59427F1E09BC830051894B /* GameCollection.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -11,7 +11,7 @@ import CoreData
// Workspace
import DeltaCore
import ZipZap
import ZIPFoundation
// Pods
import FileMD5Hash
@ -346,7 +346,6 @@ extension DatabaseManager
{
DispatchQueue.global().async {
var semaphores = Set<DispatchSemaphore>()
var outputURLs = Set<URL>()
var errors = Set<ImportError>()
@ -354,17 +353,20 @@ extension DatabaseManager
{
var archiveContainsValidGameFile = false
do
guard let archive = Archive(url: url, accessMode: .read) else {
errors.insert(.invalid(url))
continue
}
for entry in archive
{
let archive = try ZZArchive(url: url)
for entry in archive.entries
do
{
// Ensure entry is not in a subdirectory
guard !entry.fileName.contains("/") else { continue }
guard !entry.path.contains("/") else { continue }
let fileExtension = (entry.path as NSString).pathExtension
let fileExtension = (entry.fileName as NSString).pathExtension
guard GameType(fileExtension: fileExtension) != nil else { continue }
// At least one entry is a valid game file, so we set archiveContainsValidGameFile to true
@ -372,54 +374,22 @@ extension DatabaseManager
// However, if this game file does turn out to be invalid when extracting, we'll return an ImportError.invalid error specific to this game file
archiveContainsValidGameFile = true
// ROMs may potentially be very large, so we extract using file streams and not raw Data
let inputStream = try entry.newStream()
// Must use temporary directory, and not the directory containing zip file, since the latter might be read-only (such as when importing from Safari)
let outputURL = FileManager.default.temporaryDirectory.appendingPathComponent(entry.fileName)
let outputURL = FileManager.default.temporaryDirectory.appendingPathComponent(entry.path)
if FileManager.default.fileExists(atPath: outputURL.path)
{
try FileManager.default.removeItem(at: outputURL)
}
guard let outputStream = OutputStream(url: outputURL, append: false) else { continue }
_ = try archive.extract(entry, to: outputURL)
let semaphore = DispatchSemaphore(value: 0)
semaphores.insert(semaphore)
let outputWriter = InputStreamOutputWriter(inputStream: inputStream, outputStream: outputStream)
outputWriter.start { (error) in
if let error = error
{
if FileManager.default.fileExists(atPath: outputURL.path)
{
do
{
try FileManager.default.removeItem(at: outputURL)
}
catch
{
print(error)
}
}
print(error)
errors.insert(.invalid(outputURL))
}
else
{
outputURLs.insert(outputURL)
}
semaphore.signal()
}
outputURLs.insert(outputURL)
}
catch
{
print(error)
}
}
catch
{
print(error)
}
if !archiveContainsValidGameFile
@ -428,11 +398,6 @@ extension DatabaseManager
}
}
for semaphore in semaphores
{
semaphore.wait()
}
for url in urls
{
if FileManager.default.fileExists(atPath: url.path)

View File

@ -1,148 +0,0 @@
//
// InputStreamOutputWriter.swift
// Delta
//
// Created by Riley Testut on 12/25/16.
// Copyright © 2016 Riley Testut. All rights reserved.
//
import Foundation
private let MaximumBufferLength = 4 * 1024 // 4 KB
class InputStreamOutputWriter: NSObject
{
let inputStream: InputStream
let outputStream: OutputStream
private var completion: ((Error?) -> Void)?
private var dataBuffer = Data(capacity: MaximumBufferLength * 2)
init(inputStream: InputStream, outputStream: OutputStream)
{
self.inputStream = inputStream
self.outputStream = outputStream
super.init()
self.inputStream.delegate = self
self.outputStream.delegate = self
}
func start(with completion: @escaping ((Error?) -> Void))
{
guard self.completion == nil else { return }
self.completion = completion
let writingQueue = DispatchQueue(label: "com.rileytestut.InputStreamOutputWriter.writingQueue", qos: .userInitiated)
writingQueue.async {
self.inputStream.schedule(in: .current, forMode: .defaultRunLoopMode)
self.outputStream.schedule(in: .current, forMode: .defaultRunLoopMode)
self.outputStream.open()
self.inputStream.open()
RunLoop.current.run()
}
}
}
private extension InputStreamOutputWriter
{
func writeDataBuffer()
{
while self.outputStream.hasSpaceAvailable && self.dataBuffer.count > 0
{
self.dataBuffer.withUnsafeMutableBytes { (buffer: UnsafeMutablePointer<UInt8>) -> Void in
let writtenBytesCount = self.outputStream.write(buffer, maxLength: self.dataBuffer.count)
if writtenBytesCount >= 0
{
self.dataBuffer.removeSubrange(0 ..< writtenBytesCount)
}
}
}
}
func finishWriting()
{
self.inputStream.close()
self.outputStream.close()
self.inputStream.remove(from: .current, forMode: .commonModes)
self.outputStream.remove(from: .current, forMode: .commonModes)
self.completion?(self.inputStream.streamError ?? self.outputStream.streamError)
CFRunLoopStop(CFRunLoopGetCurrent())
}
}
extension InputStreamOutputWriter: StreamDelegate
{
func stream(_ aStream: Stream, handle eventCode: Stream.Event)
{
if let inputStream = aStream as? InputStream
{
self.inputStream(inputStream, handle: eventCode)
}
else if let outputStream = aStream as? OutputStream
{
self.outputStream(outputStream, handle: eventCode)
}
}
private func inputStream(_ inputStream: InputStream, handle eventCode: Stream.Event)
{
switch eventCode
{
case Stream.Event.hasBytesAvailable:
guard inputStream.streamError == nil else { return }
while inputStream.hasBytesAvailable
{
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: MaximumBufferLength)
let readBytesCount = inputStream.read(buffer, maxLength: MaximumBufferLength)
guard readBytesCount >= 0 else { break }
self.dataBuffer.append(buffer, count: readBytesCount)
buffer.deallocate(capacity: MaximumBufferLength)
self.writeDataBuffer()
}
case Stream.Event.endEncountered:
if self.dataBuffer.count == 0
{
self.finishWriting()
}
case Stream.Event.errorOccurred: self.finishWriting()
default: break
}
}
private func outputStream(_ outputStream: OutputStream, handle eventCode: Stream.Event)
{
switch eventCode
{
case Stream.Event.hasSpaceAvailable:
self.writeDataBuffer()
if self.inputStream.streamStatus == .atEnd
{
self.finishWriting()
}
case Stream.Event.errorOccurred: self.finishWriting()
default: break
}
}
}