Add StreamPuts(), don't make StreamVprintf() defer to IoVprintf().

This commit is contained in:
Jordan Bancino 2023-03-16 16:51:41 +00:00
parent 8539a03d5b
commit 27b3b6cdc6
2 changed files with 75 additions and 7 deletions

View file

@ -164,18 +164,58 @@ StreamClose(Stream * stream)
int int
StreamVprintf(Stream * stream, const char *fmt, va_list ap) StreamVprintf(Stream * stream, const char *fmt, va_list ap)
{ {
if (!stream) /* This might look like very similar code to IoVprintf(),
* but I chose not to defer to IoVprintf() because that
* would require us to immediately flush the buffer, since
* the Io API is unbuffered. StreamPuts() uses StreamPutc()
* under the hood, which is buffered. It therefore allows
* us to finish filling the buffer and then only flush it
* when necessary, preventing superfluous writes.
*/
char *buf;
ssize_t len;
int ret;
if (!stream || !fmt)
{ {
return -1; return -1;
} }
StreamFlush(stream); /* Flush the buffer out before doing buf = Malloc(IO_BUFFER);
* the printf */ if (!buf)
{
return -1;
}
/* Defer printf to underlying Io. We probably should buffer the len = vsnprintf(buf, IO_BUFFER, fmt, ap);
* printf operation just like StreamPutc() so we don't have to
* flush the buffer. */ if (len < 0)
return IoVprintf(stream->io, fmt, ap); {
Free(buf);
return len;
}
if (len >= IO_BUFFER)
{
char *new = Realloc(buf, len + 1);
if (!new)
{
Free(buf);
return -1;
}
buf = new;
vsnprintf(buf, len, fmt, ap);
}
ret = StreamPuts(stream, buf);
Free(buf);
return ret;
} }
int int
@ -341,6 +381,31 @@ StreamPutc(Stream * stream, int c)
return c; return c;
} }
int
StreamPuts(Stream *stream, char *str)
{
int ret = 0;
if (!stream)
{
errno = EBADF;
return -1;
}
while (*str)
{
if (StreamPutc(stream, *str) == EOF)
{
ret = -1;
break;
}
str++;
}
return ret;
}
int int
StreamEof(Stream * stream) StreamEof(Stream * stream)
{ {

View file

@ -60,6 +60,9 @@ extern int
extern int extern int
StreamPutc(Stream *, int); StreamPutc(Stream *, int);
extern int
StreamPuts(Stream *, char *);
extern int extern int
StreamEof(Stream *); StreamEof(Stream *);