You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
2.2 KiB
C

// SPDX-License-Identifier: LGPL-3.0-or-later
/**
* \file bufio.c
*
* I/O stream buffering utilities implementation.
*
* \copyright The DoubleFourteen Code Forge (C) All Rights Reserved
* \author Lorenzo Cogotti
*/
#include "sys/sys_local.h" // for Sys_SetErrStat() - vsnprintf()
#include "bufio.h"
#include "numlib.h"
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
Sint64 Bufio_Flush(Stmbuf *sb)
{
assert(sb->ops->Write);
while (sb->len > 0) {
Sint64 n = sb->ops->Write(sb->streamp, sb->buf, sb->len);
if (n < 0)
return NG;
memmove(sb->buf, sb->buf + n, sb->len - n);
sb->len -= n;
sb->total += n;
}
return sb->total;
}
Sint64 _Bufio_Putsn(Stmbuf *sb, const char *s, size_t nbytes)
{
if (sb->len + nbytes > sizeof(sb->buf) && Bufio_Flush(sb) == -1)
return -1;
if (nbytes > sizeof(sb->buf))
return sb->ops->Write(sb->streamp, sb, nbytes);
memcpy(sb->buf + sb->len, s, nbytes);
sb->len += nbytes;
return nbytes;
}
Sint64 Bufio_Putu(Stmbuf *sb, unsigned long long val)
{
char buf[DIGS(val) + 1];
char *eptr = Utoa(val, buf);
return Bufio_Putsn(sb, buf, eptr - buf);
}
Sint64 Bufio_Putx(Stmbuf *sb, unsigned long long val)
{
char buf[XDIGS(val) + 1];
char *eptr = Xtoa(val, buf);
return Bufio_Putsn(sb, buf, eptr - buf);
}
Sint64 Bufio_Puti(Stmbuf *sb, long long val)
{
char buf[1 + DIGS(val) + 1];
char *eptr = Itoa(val, buf);
return Bufio_Putsn(sb, buf, eptr - buf);
}
Sint64 Bufio_Putf(Stmbuf *sb, double val)
{
char buf[DOUBLE_STRLEN + 1];
char *eptr = Ftoa(val, buf);
return Bufio_Putsn(sb, buf, eptr - buf);
}
Sint64 Bufio_Printf(Stmbuf *sb, const char *fmt, ...)
{
va_list va;
Sint64 n;
va_start(va, fmt);
n = Bufio_Vprintf(sb, fmt, va);
va_end(va);
return n;
}
Sint64 Bufio_Vprintf(Stmbuf *sb, const char *fmt, va_list va)
{
va_list vc;
char *buf;
int n1, n2;
va_copy(vc, va);
n1 = vsnprintf(NULL, 0, fmt, vc);
va_end(vc);
if (n1 < 0) {
Sys_SetErrStat(errno, "vsnprintf() failed");
return -1;
}
buf = (char *) alloca(n1 + 1);
n2 = vsnprintf(buf, n1 + 1, fmt, va);
if (n2 < 0) {
Sys_SetErrStat(errno, "vsnprintf() failed");
return -1;
}
assert(n1 == n2);
return Bufio_Putsn(sb, buf, n2);
}