diff --git a/doc/xml/release.xml b/doc/xml/release.xml index a7d1b999d..5b968cd52 100644 --- a/doc/xml/release.xml +++ b/doc/xml/release.xml @@ -19,6 +19,7 @@ + diff --git a/src/common/io/chunkedRead.c b/src/common/io/chunkedRead.c index de4c3835d..6368c387c 100644 --- a/src/common/io/chunkedRead.c +++ b/src/common/io/chunkedRead.c @@ -23,13 +23,64 @@ typedef struct IoChunkedRead /*********************************************************************************************************************************** Macros for function logging ***********************************************************************************************************************************/ -#define FUNCTION_LOG_IO_CHUNKED_READ_TYPE \ +#define FUNCTION_LOG_IO_CHUNKED_READ_TYPE \ IoChunkedRead * -#define FUNCTION_LOG_IO_CHUNKED_READ_FORMAT(value, buffer, bufferSize) \ +#define FUNCTION_LOG_IO_CHUNKED_READ_FORMAT(value, buffer, bufferSize) \ objNameToLog(value, "IoChunkedRead", buffer, bufferSize) /*********************************************************************************************************************************** -Read data from the buffer +Read next chunk size +***********************************************************************************************************************************/ +static bool +ioChunkedReadNext(THIS_VOID) +{ + THIS(IoChunkedRead); + + FUNCTION_TEST_BEGIN(); + FUNCTION_TEST_PARAM(IO_CHUNKED_READ, this); + FUNCTION_TEST_END(); + + const uint64_t chunkDelta = ioReadVarIntU64(this->read); + + // Stop when chunk delta is zero, which indicates the end of the chunk list + if (chunkDelta == 0) + { + this->eof = true; + FUNCTION_TEST_RETURN(BOOL, false); + } + + // Calculate next chunk size from delta + if (this->chunkLast == 0) + this->chunkRemains = (size_t)chunkDelta; + else + this->chunkRemains = (size_t)(cvtInt64FromZigZag(chunkDelta - 1) + (int64_t)this->chunkLast); + + this->chunkLast = this->chunkRemains; + + FUNCTION_TEST_RETURN(BOOL, true); +} + +/*********************************************************************************************************************************** +Read first chunk size +***********************************************************************************************************************************/ +static bool +ioChunkedReadOpen(THIS_VOID) +{ + THIS(IoChunkedRead); + + FUNCTION_LOG_BEGIN(logLevelTrace); + FUNCTION_LOG_PARAM(IO_CHUNKED_READ, this); + FUNCTION_LOG_END(); + + ASSERT(this != NULL); + + ioChunkedReadNext(this); + + FUNCTION_LOG_RETURN(BOOL, true); +} + +/*********************************************************************************************************************************** +Read next chunk or partial chunk ***********************************************************************************************************************************/ static size_t ioChunkedRead(THIS_VOID, Buffer *const buffer, const bool block) @@ -50,27 +101,6 @@ ioChunkedRead(THIS_VOID, Buffer *const buffer, const bool block) // Keep reading until the output buffer is full while (!bufFull(buffer)) { - // If no data remaining in chunk then read the next chunk header - if (this->chunkRemains == 0) - { - const uint64_t chunkDelta = ioReadVarIntU64(this->read); - - // Stop when chunk delta is zero, which indicates the end of the chunk list - if (chunkDelta == 0) - { - this->eof = true; - break; - } - - // Calculate next chunk size from delta - if (this->chunkLast == 0) - this->chunkRemains = (size_t)chunkDelta; - else - this->chunkRemains = (size_t)(cvtInt64FromZigZag(chunkDelta - 1) + (int64_t)this->chunkLast); - - this->chunkLast = this->chunkRemains; - } - // If the entire chunk will fit in the output buffer if (this->chunkRemains < bufRemains(buffer)) { @@ -79,6 +109,10 @@ ioChunkedRead(THIS_VOID, Buffer *const buffer, const bool block) actualBytes += this->chunkRemains; this->chunkRemains = 0; + + // Read the next chunk header + if (!ioChunkedReadNext(this)) + break; } // Else only part of the chunk will fit in the output else @@ -94,7 +128,7 @@ ioChunkedRead(THIS_VOID, Buffer *const buffer, const bool block) } /*********************************************************************************************************************************** -Have all bytes been read from the buffer? +Have all chunks been read? ***********************************************************************************************************************************/ static bool ioChunkedReadEof(THIS_VOID) @@ -131,7 +165,7 @@ ioChunkedReadNew(IoRead *const read) .read = read, }; - this = ioReadNewP(driver, .eof = ioChunkedReadEof, .read = ioChunkedRead); + this = ioReadNewP(driver, .eof = ioChunkedReadEof, .open = ioChunkedReadOpen, .read = ioChunkedRead); } OBJ_NEW_END();