Inline buffered writes and process stream boundaries in bulk

This commit is contained in:
Andrea Mazzoleni 2026-09-09 18:50:39 +02:00
parent 574b491c5d
commit 1ef5aa9822
2 changed files with 39 additions and 27 deletions

View file

@ -711,40 +711,33 @@ int sgetbs(STREAM* f, char* str, size_t size)
return sread(f, str, len);
}
int swrite(const void* void_data, size_t size, STREAM* f)
int swrite_uncached(const void* void_data, size_t size, STREAM* f)
{
const unsigned char* data = void_data;
/* if there is enough space in memory */
if (sptrlookup(f, size)) {
/* optimized version with all the data in memory */
unsigned char* pos = sptrget(f);
while (size) {
size_t available;
/**
* Update the crc *before* writing the data in the buffer
*
* This must be done before the memory write,
* to be able to detect memory errors on the buffer,
* happening before we write it on the file.
*/
if (f->flags & STREAM_FLAGS_CRC) {
f->crc_stream = crc32c_plain(f->crc_stream, data, size);
}
/* copy it */
while (size--)
*pos++ = *data++;
sptrset(f, pos);
} else {
/* standard version using sputc() */
while (size--) {
if (sputc(*data++, f) != 0) {
if (f->pos == f->end) {
if (sflush(f) != 0) {
/* LCOV_EXCL_START */
return -1;
/* LCOV_EXCL_STOP */
}
}
available = (size_t)(f->end - f->pos);
if (available > size)
available = size;
/* compute the independent CRC before copying to detect buffer corruption */
if (f->flags & STREAM_FLAGS_CRC)
f->crc_stream = crc32c_plain(f->crc_stream, data, available);
memcpy(f->pos, data, available);
f->pos += available;
data += available;
size -= available;
}
return 0;

View file

@ -395,10 +395,29 @@ static inline int sputeol(STREAM* s)
}
/**
* Write a sized string.
* \internal Used by swrite() when the data crosses the buffered range.
* \note Don't call this directly, but use swrite().
*/
int swrite_uncached(const void* data, size_t size, STREAM* f);
/**
* Write a sized buffer.
* Return 0 on success or -1 on error.
*/
int swrite(const void* data, size_t size, STREAM* f);
static __always_inline int swrite(const void* data, size_t size, STREAM* f)
{
if (tommy_unlikely(!sptrlookup(f, size)))
return swrite_uncached(data, size, f);
/* compute the independent CRC before copying to detect buffer corruption */
if (f->flags & STREAM_FLAGS_CRC)
f->crc_stream = crc32c_plain(f->crc_stream, data, size);
memcpy(f->pos, data, size);
f->pos += size;
return 0;
}
/****************************************************************************/
/* binary put */