mirror of
https://github.com/GayPizzaSpecifications/darwin-apk.git
synced 2025-08-03 21:41:31 +00:00
Initial implementation of APKINDEX, fetching, reading, parsing, & merging
This commit is contained in:
85
Sources/apk/Utility/TextInputStream.swift
Normal file
85
Sources/apk/Utility/TextInputStream.swift
Normal file
@ -0,0 +1,85 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//FIXME: I don't like this, also SLOWWW
|
||||
struct TextInputStream<InStream: InputStream> where InStream.Element == UInt8 {
|
||||
private var _stream: InStream
|
||||
|
||||
public init(binaryStream: InStream) {
|
||||
_stream = binaryStream
|
||||
}
|
||||
|
||||
public var lines: LineSequence {
|
||||
LineSequence(_stream: self._stream)
|
||||
}
|
||||
|
||||
public struct LineSequence: Sequence {
|
||||
public typealias Element = String
|
||||
|
||||
fileprivate var _stream: InStream
|
||||
|
||||
public struct Iterator: IteratorProtocol where InStream.Element == UInt8 {
|
||||
public typealias Element = String
|
||||
|
||||
fileprivate init(stream: InStream) {
|
||||
self._stream = stream
|
||||
}
|
||||
|
||||
private var _stream: InStream
|
||||
private var _utf8Decoder = UTF8()
|
||||
private var _scalars = [Unicode.Scalar]()
|
||||
private var _lastChar: UnicodeScalar = "\0"
|
||||
private var _eof = false
|
||||
|
||||
private mutating func decodeScalarsLine() {
|
||||
Decode: while true {
|
||||
switch self._utf8Decoder.decode(&self._stream) {
|
||||
case .scalarValue(let value):
|
||||
if value == "\n" {
|
||||
if self._lastChar == "\n" { break }
|
||||
else { break Decode }
|
||||
} else if value == "\r" {
|
||||
break Decode
|
||||
}
|
||||
self._scalars.append(value)
|
||||
self._lastChar = value
|
||||
case .emptyInput:
|
||||
self._eof = true
|
||||
break Decode
|
||||
case .error:
|
||||
break Decode
|
||||
//FIXME: repair like the stdlib does
|
||||
//scalars.append(UTF8.encodedReplacementCharacter)
|
||||
//lastChar = UTF8.encodedReplacementCharacter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public mutating func next() -> String? {
|
||||
// Return early if we already hit the end of the stream
|
||||
guard !self._eof else {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a line of scalars
|
||||
self.decodeScalarsLine()
|
||||
defer {
|
||||
self._scalars.removeAll(keepingCapacity: true)
|
||||
}
|
||||
|
||||
// Ignore the final empty newline
|
||||
guard !self._eof || !self._scalars.isEmpty else {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert to string and return
|
||||
var string = String()
|
||||
string.unicodeScalars.append(contentsOf: self._scalars)
|
||||
return string
|
||||
}
|
||||
}
|
||||
|
||||
public func makeIterator() -> Iterator {
|
||||
Iterator(stream: self._stream)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user