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
|
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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue