forked from Telodendria/Telodendria
Add StreamPuts(), don't make StreamVprintf() defer to IoVprintf().
This commit is contained in:
parent
8539a03d5b
commit
27b3b6cdc6
2 changed files with 75 additions and 7 deletions
79
src/Stream.c
79
src/Stream.c
|
@ -164,18 +164,58 @@ StreamClose(Stream * stream)
|
|||
int
|
||||
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;
|
||||
}
|
||||
|
||||
StreamFlush(stream); /* Flush the buffer out before doing
|
||||
* the printf */
|
||||
buf = Malloc(IO_BUFFER);
|
||||
if (!buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Defer printf to underlying Io. We probably should buffer the
|
||||
* printf operation just like StreamPutc() so we don't have to
|
||||
* flush the buffer. */
|
||||
return IoVprintf(stream->io, fmt, ap);
|
||||
len = vsnprintf(buf, IO_BUFFER, fmt, ap);
|
||||
|
||||
if (len < 0)
|
||||
{
|
||||
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
|
||||
|
@ -341,6 +381,31 @@ StreamPutc(Stream * stream, int 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
|
||||
StreamEof(Stream * stream)
|
||||
{
|
||||
|
|
|
@ -60,6 +60,9 @@ extern int
|
|||
extern int
|
||||
StreamPutc(Stream *, int);
|
||||
|
||||
extern int
|
||||
StreamPuts(Stream *, char *);
|
||||
|
||||
extern int
|
||||
StreamEof(Stream *);
|
||||
|
||||
|
|
Loading…
Reference in a new issue