cvs commit: fptools/ghc/lib/std IO.lhs PrelHandle.hsc

Simon Marlow simonmar@microsoft.com
Mon, 11 Jun 2001 12:19:58 +0100


> Yes, in C. The trouble is that when we implement attaching
> conversions to handles ourselves, there is no good general way
> to write hGetPosn/hSetPosn.
>=20
> There are at least two reasons. The conversion implementation=20
> might not
> allow storing the state and later starting back from it (for example
> iconv doesn't and my Haskell's conversion API doesn't). And when
> converting buffered blocks, we don't know which converted positions
> correspond to which unconverted positions.
>=20
> The first problem can be partially solved by assuming that we will be
> able to seek only when the conversion is stateless; almost all are
> stateless. I would have to change the way of handling incomplete
> multibyte sequences at the end of the buffer, because now they
> contribute to the implicit conversion state.
>=20
> The second problem can be solved by storing the current=20
> buffer contents
> in HandlePosn (the type would have to be abstract again, as Haskell 98
> says). It can also be solved by restricting when seeking is possible:
> for text handles with a conversion attached, seeking is possible for
> unbuffered handles and for line-buffered handles at the beginning of
> a line.
>=20
> BTW, changing the conversion of a handle on the fly should have a
> similar restriction: only at the beginning of the file, or when it's
> unbuffered, or when it's line-buffered and we are at the beginning
> of a line, or after hFlush in the case of output.
>=20
> It would be easier if seeking was restricted to binary files (which
> don't have the conversion issue).

One other small complication: even an unbuffered handle or a
line-buffered handle at the beginning of a line can have a single
buffered character if you happen to have called hLookAhead or hIsEOF on
the handle.

Storing the buffer contents in HandlePosn is reasonable, and should be
straightforward to implement in GHC's new I/O infrastructure (a buffer
is a first-class functional object).  So I'm happy to disallow
hSeek/hTell on a non-binary handle but allow hGetPosn/hSetPosn.  We also
need to mention in the documentation that any operation which requires
the current buffer contents to be discarded will leave the file position
at an undefined position - this currently applies to hSetBuffering, and
in GHC when switching from reading to writing on a read/write handle.

Cheers,
	Simon