[racket] get-pure-port/seekable

From: Greg Hendershott (greghendershott at gmail.com)
Date: Tue Sep 28 22:45:24 EDT 2010

I figured out I could use make-custom-binary-input-port from r6rs,
which is also cleaner (provide a name and 3 funcs: read, get-position,
set-position). The input ports created by that seem to work just fine
with Racket funcs like read-bytes. The only catch is that Racket's
file-position complains, not a file port. I have to replace that with
port-position and set-port-position!, but otherwise the existing code
that worked with file input ports works fine unmodified.

On Tue, Sep 28, 2010 at 5:01 PM, Greg Hendershott
<greghendershott at gmail.com> wrote:
> Hi, all.
> I want to make a custom input port that behaves like one returned from
> get-pure-port, but, also handles file-position.
> Simple use example:
> (let ([in (get-pure-port/seekable uri)])
>  (display (read-bytes 16 in))
>  (file-position in 0)
>  (display (read-bytes 16 in)) ; gets same bytes as above
> To handle (file-position N) where N isn't already the current
> position, it abandons and reopens the connection using the HTTP header
> "Range: bytes=N-" (when servers support it). Subsequent reads from the
> port get the entity from N onward.
> Simple, and I have some code that works correctly. But using it
> requires special open/read/position/close functions. Instead, I want
> any code that knows how to use open-input-file ports and
> file-position, to be able to use this transparently. So it doesn't
> need to know or care if the port is a local file or an HTTP entity.
> So I need a custom port, right? But of the various callback functions
> I may provide to make-input-port, I don't see the one I need: A way to
> set the current position. Gah.
> I've been through the docs many times and I'm stumped.  Any ideas?  Thank you.

Posted on the users mailing list.