mirror of
https://github.com/GayPizzaSpecifications/darwin-apk.git
synced 2025-08-03 13:31:32 +00:00
yep steam classes are faster...
This commit is contained in:
@ -73,11 +73,11 @@ public struct ApkIndexUpdater {
|
|||||||
|
|
||||||
var tars = [Data]()
|
var tars = [Data]()
|
||||||
do {
|
do {
|
||||||
var file: any InputStream = try FileInputStream(indexURL)
|
var file = try FileInputStream(indexURL)
|
||||||
//var file: any InputStream = try MemoryInputStream(buffer: try Data(contentsOf: indexURL))
|
//var file = try MemoryInputStream(buffer: try Data(contentsOf: indexURL))
|
||||||
var gzip = GZipReader()
|
var gzip = GZipReader()
|
||||||
tars.append(try gzip.read(inStream: &file))
|
tars.append(try gzip.read(inStream: file))
|
||||||
tars.append(try gzip.read(inStream: &file))
|
tars.append(try gzip.read(inStream: file))
|
||||||
} catch {
|
} catch {
|
||||||
fatalError(error.localizedDescription)
|
fatalError(error.localizedDescription)
|
||||||
}
|
}
|
||||||
@ -85,10 +85,10 @@ public struct ApkIndexUpdater {
|
|||||||
print("Gzip time: \((ContinuousClock.now - gzipStart).formatted(durFormat))")
|
print("Gzip time: \((ContinuousClock.now - gzipStart).formatted(durFormat))")
|
||||||
let untarStart = ContinuousClock.now
|
let untarStart = ContinuousClock.now
|
||||||
|
|
||||||
var signatureStream = MemoryInputStream(buffer: tars[0])
|
let signatureStream = MemoryInputStream(buffer: tars[0])
|
||||||
tarSignature = try TarReader.read(&signatureStream)
|
tarSignature = try TarReader.read(signatureStream)
|
||||||
var recordsStream = MemoryInputStream(buffer: tars[1])
|
let recordsStream = MemoryInputStream(buffer: tars[1])
|
||||||
tarRecords = try TarReader.read(&recordsStream)
|
tarRecords = try TarReader.read(recordsStream)
|
||||||
|
|
||||||
guard case .file(let signatureName, _) = tarSignature.first
|
guard case .file(let signatureName, _) = tarSignature.first
|
||||||
else { fatalError("Missing signature") }
|
else { fatalError("Missing signature") }
|
||||||
|
@ -7,14 +7,14 @@ import Foundation
|
|||||||
import Darwin
|
import Darwin
|
||||||
import System
|
import System
|
||||||
|
|
||||||
public struct FileInputStream: InputStream {
|
public class FileInputStream: InputStream {
|
||||||
private var _hnd: FileHandle
|
private var _hnd: FileHandle
|
||||||
|
|
||||||
public init(_ fileURL: URL) throws {
|
public init(_ fileURL: URL) throws {
|
||||||
self._hnd = try FileHandle(forReadingFrom: fileURL)
|
self._hnd = try FileHandle(forReadingFrom: fileURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func seek(_ whence: StreamWhence) throws(StreamError) {
|
public override func seek(_ whence: Whence) throws(StreamError) {
|
||||||
let applyOffset = { (position: UInt64, offset: Int) throws(StreamError) -> UInt64 in
|
let applyOffset = { (position: UInt64, offset: Int) throws(StreamError) -> UInt64 in
|
||||||
if offset < 0 {
|
if offset < 0 {
|
||||||
let (newPosition, overflow) = position.subtractingReportingOverflow(UInt64(-offset))
|
let (newPosition, overflow) = position.subtractingReportingOverflow(UInt64(-offset))
|
||||||
@ -55,7 +55,7 @@ public struct FileInputStream: InputStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public var tell: Int {
|
public override var tell: Int {
|
||||||
get throws(StreamError) {
|
get throws(StreamError) {
|
||||||
let offset: UInt64
|
let offset: UInt64
|
||||||
do { offset = try self._hnd.offset() }
|
do { offset = try self._hnd.offset() }
|
||||||
@ -67,7 +67,7 @@ public struct FileInputStream: InputStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func read(_ count: Int) throws(StreamError) -> Data {
|
public override func read(_ count: Int) throws(StreamError) -> Data {
|
||||||
do {
|
do {
|
||||||
return try self._hnd.read(upToCount: count) ?? Data()
|
return try self._hnd.read(upToCount: count) ?? Data()
|
||||||
} catch {
|
} catch {
|
||||||
@ -75,7 +75,7 @@ public struct FileInputStream: InputStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func read(_ buffer: UnsafeMutablePointer<UInt8>, maxLength len: Int) throws(StreamError) -> Int {
|
public override func read(_ buffer: UnsafeMutablePointer<UInt8>, maxLength len: Int) throws(StreamError) -> Int {
|
||||||
let res = unistd.read(self._hnd.fileDescriptor, buffer, len)
|
let res = unistd.read(self._hnd.fileDescriptor, buffer, len)
|
||||||
if res < 0 {
|
if res < 0 {
|
||||||
throw .fileHandleError(Errno(rawValue: errno))
|
throw .fileHandleError(Errno(rawValue: errno))
|
||||||
|
@ -18,7 +18,7 @@ struct GZipReader: ~Copyable {
|
|||||||
inflateEnd(&zstream)
|
inflateEnd(&zstream)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func read(inStream stream: inout any InputStream) throws(GZipError) -> Data {
|
mutating func read(inStream stream: InputStream) throws(GZipError) -> Data {
|
||||||
// Initialise zlib if this is the first time we're called
|
// Initialise zlib if this is the first time we're called
|
||||||
// otherwise reset the stream in anticipation of reading the next concatenated stream
|
// otherwise reset the stream in anticipation of reading the next concatenated stream
|
||||||
var zerr = if self.zstream.state == nil {
|
var zerr = if self.zstream.state == nil {
|
||||||
|
@ -5,19 +5,24 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol InputStream: Stream, IteratorProtocol where Element == UInt8 {
|
public class InputStream: Stream, IteratorProtocol {
|
||||||
mutating func read(_ count: Int) throws(StreamError) -> Data
|
public typealias Element = UInt8
|
||||||
mutating func read(_ buffer: UnsafeMutablePointer<UInt8>, maxLength len: Int) throws(StreamError) -> Int
|
|
||||||
}
|
|
||||||
|
|
||||||
public extension InputStream {
|
public func read(_ count: Int) throws(StreamError) -> Data {
|
||||||
mutating func read(_ size: Int, items: Int) throws(StreamError) -> Data {
|
throw .notImplemented
|
||||||
try self.read(size * items)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public extension InputStream {
|
public func read(_ buffer: UnsafeMutablePointer<UInt8>, maxLength len: Int) throws(StreamError) -> Int {
|
||||||
mutating func next() -> UInt8? {
|
throw .notImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
public func next() -> UInt8? {
|
||||||
try? self.read(1).first
|
try? self.read(1).first
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public extension InputStream {
|
||||||
|
func read(_ size: Int, items: Int) throws(StreamError) -> Data {
|
||||||
|
try self.read(size * items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import System
|
import System
|
||||||
|
|
||||||
public struct MemoryInputStream: InputStream {
|
public class MemoryInputStream: InputStream {
|
||||||
private var _buf: ContiguousArray<UInt8>! = nil
|
private var _buf: ContiguousArray<UInt8>! = nil
|
||||||
private let _sli: ArraySlice<UInt8>
|
private let _sli: ArraySlice<UInt8>
|
||||||
private let _ptr: UnsafeBufferPointer<UInt8>
|
private let _ptr: UnsafeBufferPointer<UInt8>
|
||||||
@ -50,7 +50,7 @@ public struct MemoryInputStream: InputStream {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public mutating func seek(_ whence: StreamWhence) throws(StreamError) {
|
public override func seek(_ whence: Whence) throws(StreamError) {
|
||||||
let (position, overflow) = switch whence {
|
let (position, overflow) = switch whence {
|
||||||
case .set(let position): (position, false)
|
case .set(let position): (position, false)
|
||||||
case .current(let offset): self._idx.addingReportingOverflow(offset)
|
case .current(let offset): self._idx.addingReportingOverflow(offset)
|
||||||
@ -65,13 +65,13 @@ public struct MemoryInputStream: InputStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public var tell: Int {
|
public override var tell: Int {
|
||||||
get throws(StreamError) {
|
get throws(StreamError) {
|
||||||
self._idx
|
self._idx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func read(_ count: Int) throws(StreamError) -> Data {
|
public override func read(_ count: Int) throws(StreamError) -> Data {
|
||||||
let beg = min(self._idx, self._len)
|
let beg = min(self._idx, self._len)
|
||||||
let end = min(self._idx + count, self._len)
|
let end = min(self._idx + count, self._len)
|
||||||
let bytes = Data(self._ptr[beg..<end])
|
let bytes = Data(self._ptr[beg..<end])
|
||||||
@ -79,7 +79,7 @@ public struct MemoryInputStream: InputStream {
|
|||||||
return bytes
|
return bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func read(_ buffer: UnsafeMutablePointer<UInt8>, maxLength count: Int) throws(StreamError) -> Int {
|
public override func read(_ buffer: UnsafeMutablePointer<UInt8>, maxLength count: Int) throws(StreamError) -> Int {
|
||||||
let beg = min(self._idx, self._len)
|
let beg = min(self._idx, self._len)
|
||||||
let end = min(self._idx + count, self._len)
|
let end = min(self._idx + count, self._len)
|
||||||
let len = beg.distance(to: end)
|
let len = beg.distance(to: end)
|
||||||
@ -88,7 +88,7 @@ public struct MemoryInputStream: InputStream {
|
|||||||
return self._ptr.copyBytes(to: buf, from: beg..<end)
|
return self._ptr.copyBytes(to: buf, from: beg..<end)
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func next() -> UInt8? {
|
public override func next() -> UInt8? {
|
||||||
if _fastPath(self._idx < self._len) {
|
if _fastPath(self._idx < self._len) {
|
||||||
defer { self._idx += 1 }
|
defer { self._idx += 1 }
|
||||||
return self._ptr[self._idx]
|
return self._ptr[self._idx]
|
||||||
|
@ -6,19 +6,29 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import System
|
import System
|
||||||
|
|
||||||
public protocol Stream {
|
public class Stream {
|
||||||
mutating func seek(_ whence: StreamWhence) throws(StreamError)
|
func seek(_ whence: Whence) throws(StreamError) {
|
||||||
var tell: Int { get throws(StreamError) }
|
throw .unsupported
|
||||||
|
}
|
||||||
|
|
||||||
|
var tell: Int {
|
||||||
|
get throws(StreamError) {
|
||||||
|
throw .unsupported
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum StreamWhence {
|
extension Stream {
|
||||||
case set(_ position: Int)
|
public enum Whence {
|
||||||
case current(_ offset: Int)
|
case set(_ position: Int)
|
||||||
case end(_ offset: Int)
|
case current(_ offset: Int)
|
||||||
|
case end(_ offset: Int)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum StreamError: Error, LocalizedError {
|
public enum StreamError: Error, LocalizedError {
|
||||||
case unsupported
|
case unsupported
|
||||||
|
case notImplemented
|
||||||
case seekRange
|
case seekRange
|
||||||
case overflow
|
case overflow
|
||||||
case fileHandleError(_ error: any Error)
|
case fileHandleError(_ error: any Error)
|
||||||
@ -27,6 +37,7 @@ public enum StreamError: Error, LocalizedError {
|
|||||||
public var errorDescription: String? {
|
public var errorDescription: String? {
|
||||||
switch self {
|
switch self {
|
||||||
case .unsupported: "Unsupported operation"
|
case .unsupported: "Unsupported operation"
|
||||||
|
case .notImplemented: "The stream object doesn't implement this function"
|
||||||
case .seekRange: "Seek out of range"
|
case .seekRange: "Seek out of range"
|
||||||
case .overflow: "Stream position overflowed"
|
case .overflow: "Stream position overflowed"
|
||||||
case .fileHandleError(let error): "Error from file handle: \(error.localizedDescription)"
|
case .fileHandleError(let error): "Error from file handle: \(error.localizedDescription)"
|
||||||
|
@ -18,7 +18,7 @@ public struct TarReader {
|
|||||||
case directory(name: String)
|
case directory(name: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func read<S: InputStream>(_ stream: inout S) throws -> [Entry] {
|
public static func read(_ stream: InputStream) throws -> [Entry] {
|
||||||
var entries = [Entry]()
|
var entries = [Entry]()
|
||||||
|
|
||||||
while true {
|
while true {
|
||||||
|
Reference in New Issue
Block a user