# Drive Stream

A drive stream is, drum roll, a stream [io/stream] interface to a drive
[io/drive] .

It maintains a byte based position within it and that position advances at each
read or write.

It maintains a single sector buffer which contains the sector that is the target
of the previous read or write operation.

Writing to the stream will set the a "dirty" flag, which will trigger a write
of the buffer to the sector either when the buffer's target sector changes or
when "flush" is called.

## API

### Struct

extends Stream struct DriveStream
  fields tgtdrv pos bufsec dirty buf(
endstruct

tgtdrv  Target drive [io/drive]
pos     Current byte-based position
bufsec  Sector currently in buffer
dirty   Whether the buffer is dirty
buf(    Pointer to buffer

### Words

newdrivestream ( tgtdrv -- drvstr )
  Create a new drivestream targeting "tgtdrv".

load ( sec drvstr -- )
  Load sector "sec" in the buffer. Aborts if outside the window.

flush ( drvstr -- )
  If buffer is dirty, save it.

invalidate ( drvstr -- )
  Flush and then set "bufsec" to -1 to indicate that buf( has nothing. This can
  be useful when the underlying drive is a dynamic view (for example
  [io/secwin] ) that is being reframed.

window ( pos drvstr -- a? n-or-0 )
  Load, if needed, the correct sector so that the position "pos" is available in
  the buffer. Returns its address in "a" as well as the number of bytes that can
  be read before the end of the buffer is reaches, as "n". If "pos" is outside
  the window, "n" is 0 and "a" is absent.

dirty! ( drvstr -- )
  Make the buffer dirty.
