From d81447526cde6fa98dfa792a65f71acb78ef1398 Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Fri, 2 Jul 2021 22:01:59 +0000 Subject: Start work on input/output streams --- streams.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 streams.c (limited to 'streams.c') diff --git a/streams.c b/streams.c new file mode 100644 index 0000000..d089b23 --- /dev/null +++ b/streams.c @@ -0,0 +1,204 @@ +#include +#include + +#include "dat.h" +#include "fns.h" + +typedef struct Stream Stream; + +struct Stream +{ + ulong fd; + int type; + int mode; + int nalias; + Rune **aliases; + Stream *next; +}; + +enum { + TextStream, + BinaryStream, +}; + +enum { + ReadStream, + WriteStream, + AppendStream +}; + +static Stream *streams; +static Stream *currentinput; +static Stream *currentoutput; + +Stream *openstreamfd(int, int, int); +Stream *getstreambyfd(int); +Stream *getstreambyalias(Rune *); +Stream *getstream(Term *); + +void +initstreams(void) +{ + currentinput = openstreamfd(0, TextStream, ReadStream); + currentoutput = openstreamfd(1, TextStream, WriteStream); +} + +int +openstream(Rune *sourcesink, Rune *mode, Term *options, Term **stream) +{ + USED(options); + int omode; + int smode; + if(runestrcmp(mode, L"read") == 0){ + omode = OREAD; + smode = ReadStream; + }else if(runestrcmp(mode, L"write") == 0){ + omode = OWRITE; + smode = WriteStream; + }else if(runestrcmp(mode, L"append") == 0){ + omode = OWRITE; /* Is this correct? */ + smode = AppendStream; + }else{ + *stream = existenceerror(L"source_sink", mkatom(sourcesink)); + return 1; + } + + char *filename = smprint("%S", sourcesink); + int fd = open(filename, omode); + if(fd < 0){ + *stream = permissionerror(L"open", L"source_sink", mkatom(sourcesink)); + return 1; + } + Stream *s = openstreamfd(fd, TextStream, smode); + *stream = mknumber(NumberInt, s->fd, 0); + return 0; +} + +void +closestream(Term *t) +{ + Stream *s = getstream(t); + if(s == nil) + return; + + Stream *tmp; + Stream *prev = nil; + for(tmp = streams; tmp != nil; tmp = tmp->next){ + if(tmp == s){ + if(prev == nil) + streams = tmp->next; + else + prev->next = tmp->next; + break; + } + if(prev == nil) + prev = tmp; + } +} + +Term * +currentinputstream(void) +{ + return mknumber(NumberInt, currentinput->fd, 0); +} + +Term * +currentoutputstream(void) +{ + return mknumber(NumberInt, currentoutput->fd, 0); +} + +void +setcurrentinputstream(Term *t) +{ + Stream *s = getstream(t); + if(s) + currentinput = s; +} + +void +setcurrentoutputstream(Term *t) +{ + Stream *s = getstream(t); + if(s) + currentoutput = s; +} + +int +isopenstream(Term *t) +{ + Stream *s = getstream(t); + if(s) + return 1; + else + return 0; +} + +int +isinputstream(Term *t) +{ + Stream *s = getstream(t); + if(s && s->mode == ReadStream) + return 1; + else + return 0; +} + +int +isoutputstream(Term *t) +{ + Stream *s = getstream(t); + if(s && (s->mode == WriteStream || s->mode == AppendStream)) + return 1; + else + return 0; +} + +Stream * +openstreamfd(int fd, int type, int mode) +{ + Stream *s = malloc(sizeof(Stream)); + s->fd = fd; + s->type = type; + s->mode = mode; + s->nalias = 0; + s->aliases = nil; + s->next = streams; + streams = s; + return s; +} + +Stream * +getstreambyfd(int fd) +{ + Stream *s; + for(s = streams; s != nil; s = s->next) + if(s->fd == fd) + return s; + return nil; +} + +Stream * +getstreambyalias(Rune *alias) +{ + Stream *s; + for(s = streams; s != nil; s = s->next){ + int i; + for(i = 0; i < s->nalias; i++){ + if(runestrcmp(alias, s->aliases[i]) == 0) + return s; + } + } + return nil; +} + +Stream * +getstream(Term *t) +{ + Stream *s = nil; + if(t->tag == NumberTerm && t->numbertype == NumberInt) + s = getstreambyfd(t->ival); + else if(t->tag == AtomTerm) + s = getstreambyalias(t->text); + return s; +} \ No newline at end of file -- cgit v1.2.3