Skip to content

Instantly share code, notes, and snippets.

@objecthub
Last active June 5, 2016 20:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save objecthub/ada1f852924b2c253653d6949fd3555d to your computer and use it in GitHub Desktop.
Save objecthub/ada1f852924b2c253653d6949fd3555d to your computer and use it in GitHub Desktop.
//
// TextStreams.swift
//
// Created by Matthias Zenger on 05/06/2016.
// Copyright © 2016 ObjectHub. All rights reserved.
//
import Foundation
class ByteGenerator: GeneratorType {
typealias Element = UInt8
let input: NSInputStream
var buffer: [UInt8]
var index: Int = 0
var eof: Bool = true
init?(path: String, capacity: Int = 1024) {
guard let input = NSInputStream(fileAtPath: path) else {
return nil
}
self.buffer = [UInt8](count: capacity, repeatedValue: 0)
input.open()
if input.hasBytesAvailable {
self.eof = input.read(&self.buffer, maxLength: self.buffer.count * sizeof(UInt8)) <= 0
}
self.input = input
}
deinit {
input.close()
}
func next() -> UInt8? {
guard !self.eof else {
return nil
}
if self.index >= self.buffer.count {
self.index = 0
self.eof = !input.hasBytesAvailable ||
input.read(&self.buffer, maxLength: self.buffer.count * sizeof(UInt8)) <= 0
guard !self.eof else {
return nil
}
}
self.index += 1
return self.buffer[self.index - 1]
}
}
struct CharacterGenerator<G: GeneratorType, U: UnicodeCodecType where G.Element == U.CodeUnit>: GeneratorType {
typealias Element = Character
var source: G
var decoder: U
mutating func next() -> Character? {
guard case .Result(let scalar) = self.decoder.decode(&self.source) else {
return nil
}
return Character(scalar)
}
}
struct LineGenerator<G: GeneratorType where G.Element == Character>: GeneratorType {
typealias Element = String
var source: G
mutating func next() -> String? {
guard let fst = source.next() else {
return nil
}
guard fst != "\n" else {
return ""
}
var line = String(fst)
while let ch = source.next() {
if (ch == "\n") {
return line
}
line.append(ch)
}
return line
}
}
if let input = ByteGenerator(path: "/Users/username/Desktop/filename.txt") {
var generator = LineGenerator(source: CharacterGenerator(source: input, decoder: UTF8()))
var i = 0
while let line = generator.next() {
print("\(i): \(line)")
i += 1
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment