Inline buffered reads and use memcpy for the fast path

This commit is contained in:
Andrea Mazzoleni 2026-09-09 18:15:41 +02:00
parent 17b24c8d21
commit e103590f21
2 changed files with 26 additions and 23 deletions

View file

@ -435,32 +435,20 @@ ssize_t sgettok(STREAM* f, char* str, int size)
return i - str;
}
int sread(STREAM* f, void* void_data, size_t size)
int sread_uncached(STREAM* f, void* void_data, size_t size)
{
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);
/* copy it */
while (size--)
*data++ = *pos++;
sptrset(f, pos);
} else {
/* standard version using sgetc() */
while (size--) {
int c = sgetc(f);
if (c == EOF) {
/* LCOV_EXCL_START */
return -1;
/* LCOV_EXCL_STOP */
}
*data++ = c;
/* standard version using sgetc() */
while (size--) {
int c = sgetc(f);
if (c == EOF) {
/* LCOV_EXCL_START */
return -1;
/* LCOV_EXCL_STOP */
}
*data++ = c;
}
return 0;

View file

@ -245,11 +245,26 @@ static inline void sungetc(int c, STREAM* s)
--s->pos;
}
/**
* \internal Used by sread() when the requested data crosses the buffered range.
* \note Don't call this directly, but use sread().
*/
int sread_uncached(STREAM* f, void* void_data, size_t size);
/**
* Read a fixed amount of chars.
* Return 0 on success, or -1 on error.
*/
int sread(STREAM* f, void* void_data, size_t size);
static inline int sread(STREAM* f, void* void_data, size_t size)
{
if (tommy_unlikely(!sptrlookup(f, size)))
return sread_uncached(f, void_data, size);
memcpy(void_data, f->pos, size);
f->pos += size;
return 0;
}
/**
* Get a char from a stream, ignoring one '\r'.