Add the deplete operation at the data stream

It's used to read the content file up to the end to verify its CRC.
This commit is contained in:
Andrea Mazzoleni 2015-10-28 19:36:24 +01:00
parent 104c47d106
commit 7e1d9138b5
3 changed files with 65 additions and 28 deletions

View file

@ -1564,26 +1564,7 @@ static void decoding_error(const char* path, STREAM* f)
log_fatal("Decoding error in '%s' at offset %" PRIi64 "\n", path, stell(f));
buf[0] = 0;
buf[1] = 0;
buf[2] = 0;
buf[3] = 0;
/* read until the end of the file */
while (1) {
int c = sgetc(f);
if (c == EOF) {
break;
}
/* keep the last four bytes */
buf[0] = buf[1];
buf[1] = buf[2];
buf[2] = buf[3];
buf[3] = c;
}
if (serror(f)) {
if (sdeplete(f, buf) != 0) {
/* LCOV_EXCL_START */
log_fatal("Error flushing the content file '%s' at offset %" PRIi64 "\n", path, stell(f));
exit(EXIT_FAILURE);

View file

@ -174,7 +174,11 @@ int shandle(STREAM* s)
return s->handle[0].f;
}
int sfill(STREAM* s)
/**
* Fill the read stream buffer.
* \return 0 if at least on char is read, or EOF on error.
*/
static int sfill(STREAM* s)
{
ssize_t ret;
@ -208,7 +212,45 @@ int sfill(STREAM* s)
s->pos = s->buffer;
s->end = s->buffer + ret;
return *s->pos++;
return 0;
}
int sdeplete(STREAM* s, unsigned char* last)
{
/* last four bytes */
last[0] = 0;
last[1] = 0;
last[2] = 0;
last[3] = 0;
while (1) {
/* increase the position up to 4 bytes before the end */
if (s->pos + 4 <= s->end)
s->pos = s->end - 4;
/* insert the last 4 bytes */
while (s->pos < s->end) {
last[0] = last[1];
last[1] = last[2];
last[2] = last[3];
last[3] = *s->pos++;
}
/* fill again the buffer until the end of the file */
if (sfill(s) != 0) {
/* on error fail */
if (serror(s)) {
/* LCOV_EXCL_START */
return EOF;
/* LCOV_EXCL_STOP */
}
/* on EOF terminate */
break;
}
}
return 0;
}
int sflush(STREAM* s)
@ -267,6 +309,14 @@ uint32_t scrc_stream(STREAM*s)
return s->crc_stream ^ CRC_IV;
}
int sgetc_uncached(STREAM* s)
{
/* if at the end of the buffer, fill it */
if (s->pos == s->end && sfill(s) != 0)
return EOF;
return *s->pos++;
}
int sgettok(STREAM* f, char* str, int size)
{
char* i = str;

View file

@ -129,11 +129,11 @@ int sclose(STREAM* s);
int shandle(STREAM* s);
/**
* Fill the read stream buffer and read a char.
* \note Don't call this directly, but use sgetc().
* \return The char read, or EOF on error.
* Read the stream until the end, and return the latest 4 chars.
* The CRC of the file is also computed, and you can get it using scrc().
* \return 0 on success, or EOF on error.
*/
int sfill(STREAM* s);
int sdeplete(STREAM* s, unsigned char* last);
/**
* Flush the write stream buffer.
@ -220,13 +220,19 @@ int ssync(STREAM* s);
/****************************************************************************/
/* get */
/**
* \internal Used by sgetc().
* \note Don't call this directly, but use sgetc().
*/
int sgetc_uncached(STREAM* s);
/**
* Read a char. Like fgetc().
*/
static inline int sgetc(STREAM* s)
{
if (s->pos == s->end)
return sfill(s);
if (tommy_unlikely(s->pos == s->end))
return sgetc_uncached(s);
return *s->pos++;
}