You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-12-07 20:22:23 +03:00
The function pointer casting used when creating drivers made changing interfaces difficult and led to slightly divergent driver implementations. Unit testing caught production-level errors but there were a lot of small issues and the process was harder than it should have been. Use void pointers instead so that no casts are required. Introduce the THIS_VOID and THIS() macros to make dealing with void pointers a little safer. Since we don't want to expose void pointers in header files, driver functions have been removed from the headers and the various driver objects return their interface type. This cuts down on accessor methods and the vast majority of those functions were not being used. Move functions that are still required to .intern.h. Remove the special "C" crypto functions that were used in libc and instead use the standard interface.
113 lines
4.3 KiB
C
113 lines
4.3 KiB
C
/***********************************************************************************************************************************
|
|
Buffer IO Read
|
|
***********************************************************************************************************************************/
|
|
#include "build.auto.h"
|
|
|
|
#include "common/debug.h"
|
|
#include "common/io/bufferRead.h"
|
|
#include "common/io/read.intern.h"
|
|
#include "common/log.h"
|
|
#include "common/memContext.h"
|
|
#include "common/object.h"
|
|
|
|
/***********************************************************************************************************************************
|
|
Object type
|
|
***********************************************************************************************************************************/
|
|
typedef struct IoBufferRead
|
|
{
|
|
MemContext *memContext; // Object memory context
|
|
const Buffer *read; // Buffer to read data from
|
|
|
|
size_t readPos; // Current position in the read buffer
|
|
bool eof; // Has the end of the buffer been reached?
|
|
} IoBufferRead;
|
|
|
|
/***********************************************************************************************************************************
|
|
Macros for function logging
|
|
***********************************************************************************************************************************/
|
|
#define FUNCTION_LOG_IO_BUFFER_READ_TYPE \
|
|
IoBufferRead *
|
|
#define FUNCTION_LOG_IO_BUFFER_READ_FORMAT(value, buffer, bufferSize) \
|
|
objToLog(value, "IoBufferRead", buffer, bufferSize)
|
|
|
|
/***********************************************************************************************************************************
|
|
Read data from the buffer
|
|
***********************************************************************************************************************************/
|
|
static size_t
|
|
ioBufferRead(THIS_VOID, Buffer *buffer, bool block)
|
|
{
|
|
THIS(IoBufferRead);
|
|
|
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
|
FUNCTION_LOG_PARAM(IO_BUFFER_READ, this);
|
|
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
|
FUNCTION_LOG_PARAM(BOOL, block);
|
|
FUNCTION_LOG_END();
|
|
|
|
ASSERT(this != NULL);
|
|
ASSERT(buffer != NULL);
|
|
|
|
size_t actualBytes = 0;
|
|
|
|
if (!this->eof)
|
|
{
|
|
// Determine how many bytes can actually be read from the buffer (if all bytes will be read then EOF)
|
|
actualBytes = bufUsed(this->read) - this->readPos;
|
|
|
|
if (actualBytes > bufRemains(buffer))
|
|
actualBytes = bufRemains(buffer);
|
|
else
|
|
this->eof = true;
|
|
|
|
// Copy bytes to buffer
|
|
bufCatSub(buffer, this->read, this->readPos, actualBytes);
|
|
this->readPos += actualBytes;
|
|
}
|
|
|
|
FUNCTION_LOG_RETURN(SIZE, actualBytes);
|
|
}
|
|
|
|
/***********************************************************************************************************************************
|
|
Have all bytes been read from the buffer?
|
|
***********************************************************************************************************************************/
|
|
static bool
|
|
ioBufferReadEof(THIS_VOID)
|
|
{
|
|
THIS(IoBufferRead);
|
|
|
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
|
FUNCTION_LOG_PARAM(IO_BUFFER_READ, this);
|
|
FUNCTION_LOG_END();
|
|
|
|
ASSERT(this != NULL);
|
|
|
|
FUNCTION_LOG_RETURN(BOOL, this->eof);
|
|
}
|
|
|
|
/***********************************************************************************************************************************
|
|
New object
|
|
***********************************************************************************************************************************/
|
|
IoRead *
|
|
ioBufferReadNew(const Buffer *buffer)
|
|
{
|
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
|
FUNCTION_LOG_PARAM(BUFFER, buffer);
|
|
FUNCTION_LOG_END();
|
|
|
|
ASSERT(buffer != NULL);
|
|
|
|
IoRead *this = NULL;
|
|
|
|
MEM_CONTEXT_NEW_BEGIN("IoBufferRead")
|
|
{
|
|
IoBufferRead *driver = memNew(sizeof(IoBufferRead));
|
|
driver->memContext = memContextCurrent();
|
|
driver->read = buffer;
|
|
|
|
this = ioReadNewP(driver, .eof = ioBufferReadEof, .read = ioBufferRead);
|
|
}
|
|
MEM_CONTEXT_NEW_END();
|
|
|
|
FUNCTION_LOG_RETURN(IO_READ, this);
|
|
}
|