<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">&lt;<a href="mailto:brent@architechies.com" target="_blank">brent@architechies.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">&gt; Looks good, but you&#39;ll want some error handling. There&#39;s no clean way to integrate it with Generator because the protocol doesn&#39;t allow the implementation to throw, unfortunately. (I&#39;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&#39;ve made these private, and will use them to implement this safe public API.<br>
                public func withByteGenerator&lt;R&gt;(blockSize: Int = 1024, iterate: @noescape (NSInputStream.ByteGenerator) throws -&gt; R) throws -&gt; 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(&quot;\(i+1): \(line)&quot;)<br>
                }<br>
        }<br>
<br>
(I&#39;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>