<div dir="ltr">Yes, error reporting is missing (errors are treated like EOF), but your proposal breaks encapsulation. By not making `NSInputStream` a hidden implementation detail, you make it possible for clients to interfere with the caching logic (e.g. by directly invoking `read`, or prematurely closing the steam).<div><br></div><div>== Matthias</div><div> </div></div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><font face="arial, helvetica, sans-serif"><br></font><table width="100%" bgcolor="#efefef" style="color:rgb(102,102,102);font-size:11px;padding:3px 8px;border-top-width:1px;border-top-style:solid;border-top-color:rgb(170,170,170);border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(170,170,170)"><tbody><tr><td align="left"><b style="color:rgb(119,119,119)"><font face="arial, helvetica, sans-serif">Matthias Zenger</font></b></td><td align="right"><a href="mailto:matthias@objecthub.net" style="text-decoration:none;color:rgb(102,102,102)" target="_blank"><font face="arial, helvetica, sans-serif">matthias@objecthub.net</font></a></td></tr></tbody></table></div><div><br></div></div></div></div>
<br><div class="gmail_quote">On Mon, Jun 6, 2016 at 1:49 AM, Brent Royal-Gordon <span dir="ltr"><<a href="mailto:brent@architechies.com" target="_blank">brent@architechies.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">> Looks good, but you'll want some error handling. There's no clean way to integrate it with Generator because the protocol doesn't allow the implementation to throw, unfortunately. (I've run into the same problem building a Generator around a database query.) I think the best solution is to add a property that returns the NSStream.streamError, or a checkError() method that throws the current error if any, and have the caller use those at the end of the iteration.<br>
<br>
</span>You can do better.<br>
<br>
extension NSInputStream {<br>
// I will assume you already have a byteGenerator method (which you can use with a for loop)<br>
// with a checkError() method (which throws if the generation terminated due to an error). However,<br>
// you've made these private, and will use them to implement this safe public API.<br>
public func withByteGenerator<R>(blockSize: Int = 1024, iterate: @noescape (NSInputStream.ByteGenerator) throws -> R) throws -> R {<br>
let generator = byteGenerator(blockSize: blockSize)<br>
let result = iterate(generator)<br>
try generator.checkError()<br>
return result<br>
}<br>
}<br>
<br>
Now you write:<br>
<br>
guard let stream = NSInputStream(fileAtPath: path) else {<br>
…<br>
}<br>
try stream.withByteGenerator {<br>
// XXX This would all be more complicated if CharacterGenerator can throw, too.<br>
for (i, line) in LineGenerator(source: CharacterGenerator(source: $0, decoder: UTF8())).enumerate() {<br>
print("\(i+1): \(line)")<br>
}<br>
}<br>
<br>
(I'm assuming that these generators take their almost-automatic Sequence conformance, of course.)<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Brent Royal-Gordon<br>
Architechies<br>
<br>
</font></span></blockquote></div><br></div>