~rabbits/uxn

File device: allow write-after-read without reset v1 PROPOSED

Nathan Korth: 1
 File device: allow write-after-read without reset

 1 files changed, 12 insertions(+), 1 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~rabbits/uxn/patches/37773/mbox | git am -3
Learn more about email & git

[PATCH] File device: allow write-after-read without reset Export this patch

After thinking about the various proposed seek features for the file
device, I came up with what I think is the simplest possible solution.

(The problem as I see it, for context: there's no good way to update --
as opposed to truncate or append -- a large file. *Reading* a large file
is easy enough, you can "seek" using repeated throwaway reads. The
trouble is when writing a file, you have to either rewrite the entire
thing or append to it, which is difficult to do with files that don't
fit in memory.)

By way of explanation, here's potential new docs for write(addr)*:

Writing files is performed by writing to write(addr)*. If append is set
to 0x01, then the data in the memory region will be written after the
end of the file. If append is set to 0x00 (the default), it will either
replace or update the contents of the file: perform at least one read of
any length first in order to update the file, starting after the read
position. The contents of the file will be replaced if, after writing to
name*, there are no reads before the first write. In all cases, if the
file doesn't previously exist then it will be created and written from
the beginning.

The current docs for comparison:

Writing files is performed by writing to write(addr)*. If append is set
to 0x01, then the data in the memory region will be written after the
end of the file, if it is 0x00 (the default) it will replace the
contents of the file. If the file doesn't previously exist then it will
be created and append makes no difference.

---
 src/devices/file.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/devices/file.c b/src/devices/file.c
index 658ac7c..b36b89d 100644
--- a/src/devices/file.c
+++ b/src/devices/file.c
@@ -122,10 +122,21 @@ static Uint16
file_write(UxnFile *c, void *src, Uint16 len, Uint8 flags)
{
	Uint16 ret = 0;
	const char *openmode = "wb";
	long pos = -1L;
	if(c->state != FILE_WRITE) {
		if(flags & 0x01) {
			openmode = "ab";
		} else if(c->state == FILE_READ) {
			openmode = "r+b";
			pos = ftell(c->f);
		}
		reset(c);
		if((c->f = fopen(c->current_filename, (flags & 0x01) ? "ab" : "wb")) != NULL)
		if((c->f = fopen(c->current_filename, openmode)) != NULL) {
			if(pos != -1L)
				fseek(c->f, pos, SEEK_SET);
			c->state = FILE_WRITE;
		}
	}
	if(c->state == FILE_WRITE) {
		if((ret = fwrite(src, 1, len, c->f)) > 0 && fflush(c->f) != 0)
-- 
2.30.1 (Apple Git-130)