Implement `atari` `fgetpos` and `fsetpos` using `NOTE`/`POINT`
The Atari DOS NOTE/POINT functionality isn't expressive enough to implement fseek, since the former use sector/offset, while the latter uses byte offsets from start/end of file. It is expressive enough to implement fgetpos and fsetpos, since these operate on an opaque fpos_t value, which could be interpreted as a sector/offset pair.
I'd like to implement this.
How to handle FILE buffer?
NOTE will tell us sector/offset after the whole buffer we read.
Writing is easier: just flush the buffer, then NOTE.
I can only think of using NOTE at every entry of fill_buffer. The time overhead should be acceptable. Unfortunately, that grows all binaries that do not use fgetpos.
Then fsetpos does a POINT followed by skipping as many bytes as we had in the buffer. Possibly by just filling the buffer and moving the pointer.
NOTE-ing on every fill_buffer SGTM; there's already quite a bit of stuff brought in just for standards compliance, and it shouldn't break the bank comparatively.
I'm thinking of:
typedef struct {
unsigned short sector; // at the beginning of the buffer
unsigned char offset_in_sector; // at the beginning of the buffer
size_t offset_in_buffer; // size_t because of setvbuf
} fpos_t;
I'm thinking of:
typedef struct { unsigned short sector; // at the beginning of the buffer unsigned char offset_in_sector; // at the beginning of the buffer size_t offset_in_buffer; // size_t because of setvbuf } fpos_t;
Providing a custom fpos_t type per target may be... tricky, since stdio-full.c is currently built as part of common. But code also currently assumes that it's a file offset, and that's probably not tenable long-term. Some design and experimentation work is probably prudent around this.
Another idea (in pseudocode):
int fgetpos(FILE *stream, fpos_t *pos)
{
if (stream->bufidx == 0)
*pos = stream->position_at_last_fill_buffer;
else {
POINT(stream->position_at_last_fill_buffer);
SKIP(stream->bufidx); // implemented as READ to buffer
*pos = NOTE();
}
}
This only needs 24-bit fpos_t.
For the default BUFSIZ=256 it would re-read a sector or two. But no need to do that in fsetpos.
I started coding it. Shall I add a fpos_t field in FILE ?
My first thought was repurposing the pos field, but that would break ftell.