Skip to content

Instantly share code, notes, and snippets.

@oliverepper
Created February 6, 2021 10:53
Show Gist options
  • Save oliverepper/a5c4cd726031d217e552509d43871cf6 to your computer and use it in GitHub Desktop.
Save oliverepper/a5c4cd726031d217e552509d43871cf6 to your computer and use it in GitHub Desktop.
LineReader
public struct LineReader {
enum Error: Swift.Error {
case cannotOpenFile(URL)
}
private let subject = PassthroughSubject<String, LineReader.Error>()
var linePublisher: AnyPublisher<String, LineReader.Error> {
subject.eraseToAnyPublisher()
}
public func read(file: URL, lines linesToRead: Int? = nil) {
guard let filePointer: UnsafeMutablePointer<FILE> = fopen(file.path, "r") else {
subject.send(completion: .failure(.cannotOpenFile(file)))
return
}
var buffer: UnsafeMutablePointer<CChar>? = nil
var cap: Int = 0
var bytesRead = getline(&buffer, &cap, filePointer)
var readLines = 0
while bytesRead > 0 {
if linesToRead == readLines {
break
}
let str = String(cString: buffer!).trimmingCharacters(in: .newlines)
subject.send(str)
bytesRead = getline(&buffer, &cap, filePointer)
readLines += 1
}
subject.send(completion: .finished)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment