hGetContents reads the entire contents of the stream till the end (although lazily). The return value of hGetContents is logically the entire contents of the stream. That it has not read it completely is only a part of its laziness, so the result does not depend upon when the caller stops consuming the result. That is why the handle is semi-closed; logically the handle is already at the end of the stream.<br>
<br>A complete parser to parse the header and the body has to be used on the entire contents, or some function which knows how to find the header end and stop there has to be used.<br><br>Regards,<br>Abhay<br><br><div class="gmail_quote">
On Sat, Jun 14, 2008 at 9:48 PM, Sebastiaan Visser &lt;<a href="mailto:sfvisser@cs.uu.nl">sfvisser@cs.uu.nl</a>&gt; wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi,<br>
<br>
I&#39;ve got a question about lazy IO in Haskell. The most well known<br>
function to do lazy IO is the `hGetContents&#39;, which lazily reads all the<br>
contents from a handle and returns this as a regular [Char].<br>
<br>
The thing with hGetContents is that is puts the Handle in a semi-closed<br>
state, no one can use the handle anymore. This behaviour is<br>
understandable from the point of safety; it is not yet determined when<br>
the result of hGetContents will actually be computed, using the handle<br>
in the meantime is undesirable.<br>
<br>
The point is, I think I really have a situation in which I want to use<br>
the handle again `after&#39; a call to hGetContents. I think I can best<br>
explain this using a code example.<br>
<br>
 &nbsp;readHttpMessage :: IO (Headers, Data.ByteString.Lazy.ByteString)<br>
 &nbsp;readHttpMessage = do<br>
 &nbsp; &nbsp;myStream &lt;- &lt;accept http connection from client&gt;<br>
 &nbsp; &nbsp;request &lt;- hGetContents myStream<br>
 &nbsp; &nbsp;header &lt;- parseHttpHeader request<br>
 &nbsp; &nbsp;bs &lt;- Data.ByteString.Lazy.hGetContents myStream<br>
 &nbsp; &nbsp;return (header, body)<br>
<br>
The Data.ByteString.Lazy.hGetContents in the example above obviously<br>
fails because the handle is semi-closed.<br>
<br>
So, what I am trying to do here is apply a parser (on that consumes<br>
Char&#39;s) to the input stream until it has succeeded. After this I want to<br>
collect the remainings of the stream in a lazy ByteString, or maybe even<br>
something else.<br>
<br>
I tried to open the handler again using some internal handle hackery,<br>
but this failed (luckily). In the module <a href="http://GHC.IO" target="_blank">GHC.IO</a> there is a function<br>
`lazyRead&#39; that more or less seems to do what I want. But I&#39;ll guess<br>
there is a good reason for not exporting it.<br>
<br>
Does anyone know a pattern in which I can do this easily?<br>
<br>
Thanks,<br><font color="#888888">
<br>
--<br>
Sebastiaan<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</font></blockquote></div><br>