1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-01-30 05:39:12 +02:00

Refactor remaining common/io modules with inline getters/setters.

Extend the pattern introduced in 79a2d02c to the remaining common/io modules.
This commit is contained in:
David Steele 2021-04-13 14:37:02 -04:00
parent 5bf160643b
commit 9fec4ce98c
30 changed files with 263 additions and 328 deletions

View File

@ -17,8 +17,8 @@ Execute Process
#include "common/io/fdRead.h"
#include "common/io/fdWrite.h"
#include "common/io/io.h"
#include "common/io/read.intern.h"
#include "common/io/write.intern.h"
#include "common/io/read.h"
#include "common/io/write.h"
#include "common/wait.h"
/***********************************************************************************************************************************

View File

@ -5,7 +5,7 @@ Buffer IO Read
#include "common/debug.h"
#include "common/io/bufferRead.h"
#include "common/io/read.intern.h"
#include "common/io/read.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/type/object.h"

View File

@ -5,7 +5,7 @@ Buffer IO Write
#include "common/debug.h"
#include "common/io/bufferWrite.h"
#include "common/io/write.intern.h"
#include "common/io/write.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/type/object.h"

View File

@ -4,7 +4,7 @@ Io Client Interface
#include "build.auto.h"
#include "common/debug.h"
#include "common/io/client.intern.h"
#include "common/io/client.h"
#include "common/log.h"
#include "common/memContext.h"
@ -13,9 +13,7 @@ Object type
***********************************************************************************************************************************/
struct IoClient
{
MemContext *memContext; // Mem context
void *driver; // Driver object
const IoClientInterface *interface; // Driver interface
IoClientPub pub; // Publicly accessible variables
};
/**********************************************************************************************************************************/
@ -38,43 +36,21 @@ ioClientNew(void *driver, const IoClientInterface *interface)
*this = (IoClient)
{
.memContext = memContextCurrent(),
.driver = driver,
.interface = interface,
.pub =
{
.memContext = memContextCurrent(),
.driver = driver,
.interface = interface,
},
};
FUNCTION_LOG_RETURN(IO_CLIENT, this);
}
/**********************************************************************************************************************************/
IoSession *
ioClientOpen(IoClient *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_CLIENT, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
FUNCTION_LOG_RETURN(IO_SESSION, this->interface->open(this->driver));
}
/**********************************************************************************************************************************/
const String *
ioClientName(IoClient *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_CLIENT, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
FUNCTION_LOG_RETURN_CONST(STRING, this->interface->name(this->driver));
}
/**********************************************************************************************************************************/
String *
ioClientToLog(const IoClient *this)
{
return strNewFmt("{type: %s, driver: %s}", strZ(*this->interface->type), strZ(this->interface->toLog(this->driver)));
return strNewFmt(
"{type: %s, driver: %s}", strZ(*this->pub.interface->type), strZ(this->pub.interface->toLog(this->pub.driver)));
}

View File

@ -12,9 +12,28 @@ Object type
***********************************************************************************************************************************/
typedef struct IoClient IoClient;
#include "common/io/client.intern.h"
#include "common/io/session.h"
#include "common/type/object.h"
/***********************************************************************************************************************************
Getters/Setters
***********************************************************************************************************************************/
typedef struct IoClientPub
{
MemContext *memContext; // Mem context
void *driver; // Driver object
const IoClientInterface *interface; // Driver interface
} IoClientPub;
// Name that identifies the client
__attribute__((always_inline)) static inline const String *
ioClientName(const IoClient *const this)
{
ASSERT_INLINE(this != NULL);
return ((const IoClientPub *)this)->interface->name(((const IoClientPub *)this)->driver);
}
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
@ -26,13 +45,12 @@ ioClientMove(IoClient *this, MemContext *parentNew)
}
// Open session
IoSession *ioClientOpen(IoClient *this);
/***********************************************************************************************************************************
Getters/Setters
***********************************************************************************************************************************/
// Name that identifies the client
const String *ioClientName(IoClient *this);
__attribute__((always_inline)) static inline IoSession *
ioClientOpen(IoClient *const this)
{
ASSERT_INLINE(this != NULL);
return ((const IoClientPub *)this)->interface->open(((const IoClientPub *)this)->driver);
}
/***********************************************************************************************************************************
Destructor

View File

@ -5,6 +5,8 @@ Io Client Interface Internal
#define COMMON_IO_CLIENT_INTERN_H
#include "common/io/client.h"
#include "common/io/session.h"
#include "common/type/string.h"
/***********************************************************************************************************************************
Interface

View File

@ -8,7 +8,7 @@ File Descriptor Io Read
#include "common/debug.h"
#include "common/io/fd.h"
#include "common/io/fdRead.h"
#include "common/io/read.intern.h"
#include "common/io/read.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/type/object.h"

View File

@ -8,7 +8,7 @@ File Descriptor Io Write
#include "common/debug.h"
#include "common/io/fd.h"
#include "common/io/fdWrite.h"
#include "common/io/write.intern.h"
#include "common/io/write.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/type/object.h"

View File

@ -9,7 +9,7 @@ HTTP Response
#include "common/io/http/request.h"
#include "common/io/http/response.h"
#include "common/io/io.h"
#include "common/io/read.intern.h"
#include "common/io/read.h"
#include "common/log.h"
#include "common/stat.h"
#include "common/wait.h"

View File

@ -7,7 +7,7 @@ IO Read Interface
#include "common/debug.h"
#include "common/io/io.h"
#include "common/io/read.intern.h"
#include "common/io/read.h"
#include "common/log.h"
#include "common/memContext.h"
@ -16,20 +16,10 @@ Object type
***********************************************************************************************************************************/
struct IoRead
{
MemContext *memContext; // Mem context
void *driver; // Driver object
IoReadInterface interface; // Driver interface
IoFilterGroup *filterGroup; // IO filters
IoReadPub pub; // Publicly accessible variables
Buffer *input; // Input buffer
Buffer *output; // Internal output buffer (extra output from buffered reads)
size_t outputPos; // Current position in the internal output buffer
bool eofAll; // Is the read done (read and filters complete)?
#ifdef DEBUG
bool opened; // Has the io been opened?
bool closed; // Has the io been closed?
#endif
};
/**********************************************************************************************************************************/
@ -52,10 +42,13 @@ ioReadNew(void *driver, IoReadInterface interface)
*this = (IoRead)
{
.memContext = memContextCurrent(),
.driver = driver,
.interface = interface,
.filterGroup = ioFilterGroupNew(),
.pub =
{
.memContext = memContextCurrent(),
.driver = driver,
.interface = interface,
.filterGroup = ioFilterGroupNew(),
},
.input = bufNew(ioBufferSize()),
};
}
@ -73,18 +66,18 @@ ioReadOpen(IoRead *this)
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(!this->opened && !this->closed);
ASSERT(ioFilterGroupSize(this->filterGroup) == 0 || !ioReadBlock(this));
ASSERT(!this->pub.opened && !this->pub.closed);
ASSERT(ioFilterGroupSize(this->pub.filterGroup) == 0 || !ioReadBlock(this));
// Open if the driver has an open function
bool result = this->interface.open != NULL ? this->interface.open(this->driver) : true;
bool result = this->pub.interface.open != NULL ? this->pub.interface.open(this->pub.driver) : true;
// Only open the filter group if the read was opened
if (result)
ioFilterGroupOpen(this->filterGroup);
ioFilterGroupOpen(this->pub.filterGroup);
#ifdef DEBUG
this->opened = result;
this->pub.opened = result;
#endif
FUNCTION_LOG_RETURN(BOOL, result);
@ -103,9 +96,9 @@ ioReadEofDriver(const IoRead *this)
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->opened && !this->closed);
ASSERT(this->pub.opened && !this->pub.closed);
FUNCTION_LOG_RETURN(BOOL, this->interface.eof != NULL ? this->interface.eof(this->driver) : false);
FUNCTION_LOG_RETURN(BOOL, this->pub.interface.eof != NULL ? this->pub.interface.eof(this->pub.driver) : false);
}
/**********************************************************************************************************************************/
@ -120,17 +113,17 @@ ioReadInternal(IoRead *this, Buffer *buffer, bool block)
ASSERT(this != NULL);
ASSERT(buffer != NULL);
ASSERT(this->opened && !this->closed);
ASSERT(this->pub.opened && !this->pub.closed);
// Loop until EOF or the output buffer is full
size_t bufferUsedBegin = bufUsed(buffer);
while (!this->eofAll && bufRemains(buffer) > 0)
while (!ioReadEof(this) && bufRemains(buffer) > 0)
{
// Process input buffer again to get more output
if (ioFilterGroupInputSame(this->filterGroup))
if (ioFilterGroupInputSame(this->pub.filterGroup))
{
ioFilterGroupProcess(this->filterGroup, this->input, buffer);
ioFilterGroupProcess(this->pub.filterGroup, this->input, buffer);
}
// Else new input can be accepted
else
@ -146,7 +139,7 @@ ioReadInternal(IoRead *this, Buffer *buffer, bool block)
if (ioReadBlock(this) && bufRemains(this->input) > bufRemains(buffer))
bufLimitSet(this->input, bufRemains(buffer));
this->interface.read(this->driver, this->input, block);
this->pub.interface.read(this->pub.driver, this->input, block);
bufLimitClear(this->input);
}
// Set input to NULL and flush (no need to actually free the buffer here as it will be freed with the mem context)
@ -156,7 +149,7 @@ ioReadInternal(IoRead *this, Buffer *buffer, bool block)
// Process the input buffer (or flush if NULL)
if (this->input == NULL || !bufEmpty(this->input))
ioFilterGroupProcess(this->filterGroup, this->input, buffer);
ioFilterGroupProcess(this->pub.filterGroup, this->input, buffer);
// Stop if not blocking -- we don't need to fill the buffer as long as we got some data
if (!block && bufUsed(buffer) > bufferUsedBegin)
@ -164,7 +157,7 @@ ioReadInternal(IoRead *this, Buffer *buffer, bool block)
}
// Eof when no more input and the filter group is done
this->eofAll = ioReadEofDriver(this) && ioFilterGroupDone(this->filterGroup);
this->pub.eofAll = ioReadEofDriver(this) && ioFilterGroupDone(this->pub.filterGroup);
}
FUNCTION_LOG_RETURN_VOID();
@ -184,7 +177,7 @@ ioRead(IoRead *this, Buffer *buffer)
ASSERT(this != NULL);
ASSERT(buffer != NULL);
ASSERT(this->opened && !this->closed);
ASSERT(this->pub.opened && !this->pub.closed);
// Store size of remaining portion of buffer to calculate total read at the end
size_t outputRemains = bufRemains(buffer);
@ -220,12 +213,12 @@ ioReadSmall(IoRead *this, Buffer *buffer)
ASSERT(this != NULL);
ASSERT(buffer != NULL);
ASSERT(this->opened && !this->closed);
ASSERT(this->pub.opened && !this->pub.closed);
// Allocate the internal output buffer if it has not already been allocated
if (this->output == NULL)
{
MEM_CONTEXT_BEGIN(this->memContext)
MEM_CONTEXT_BEGIN(this->pub.memContext)
{
this->output = bufNew(ioBufferSize());
}
@ -287,13 +280,13 @@ ioReadLineParam(IoRead *this, bool allowEof)
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->opened && !this->closed);
ASSERT(this->pub.opened && !this->pub.closed);
// Allocate the output buffer if it has not already been allocated. This buffer is not allocated at object creation because it
// is not always used.
if (this->output == NULL)
{
MEM_CONTEXT_BEGIN(this->memContext)
MEM_CONTEXT_BEGIN(this->pub.memContext)
{
this->output = bufNew(ioBufferSize());
}
@ -363,17 +356,6 @@ ioReadLineParam(IoRead *this, bool allowEof)
FUNCTION_LOG_RETURN(STRING, result);
}
/**********************************************************************************************************************************/
String *
ioReadLine(IoRead *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_READ, this);
FUNCTION_LOG_END();
FUNCTION_LOG_RETURN(STRING, ioReadLineParam(this, false));
}
/**********************************************************************************************************************************/
bool
ioReadReady(IoRead *this, IoReadReadyParam param)
@ -387,8 +369,8 @@ ioReadReady(IoRead *this, IoReadReadyParam param)
bool result = true;
if (this->interface.ready != NULL)
result = this->interface.ready(this->driver, param.error);
if (this->pub.interface.ready != NULL)
result = this->pub.interface.ready(this->pub.driver, param.error);
FUNCTION_LOG_RETURN(BOOL, result);
}
@ -402,75 +384,22 @@ ioReadClose(IoRead *this)
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->opened && !this->closed);
ASSERT(this->pub.opened && !this->pub.closed);
// Close the filter group and gather results
ioFilterGroupClose(this->filterGroup);
ioFilterGroupClose(this->pub.filterGroup);
// Close the driver if there is a close function
if (this->interface.close != NULL)
this->interface.close(this->driver);
if (this->pub.interface.close != NULL)
this->pub.interface.close(this->pub.driver);
#ifdef DEBUG
this->closed = true;
this->pub.closed = true;
#endif
FUNCTION_LOG_RETURN_VOID();
}
/**********************************************************************************************************************************/
bool
ioReadBlock(const IoRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface.block);
}
/**********************************************************************************************************************************/
void *
ioReadDriver(IoRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->driver);
}
/**********************************************************************************************************************************/
bool
ioReadEof(const IoRead *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_READ, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->opened && !this->closed);
FUNCTION_LOG_RETURN(BOOL, this->eofAll);
}
/**********************************************************************************************************************************/
IoFilterGroup *
ioReadFilterGroup(const IoRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->filterGroup);
}
/**********************************************************************************************************************************/
int
ioReadFd(const IoRead *this)
@ -481,18 +410,5 @@ ioReadFd(const IoRead *this)
ASSERT(this != NULL);
FUNCTION_LOG_RETURN(INT, this->interface.fd == NULL ? -1 : this->interface.fd(this->driver));
}
/**********************************************************************************************************************************/
const IoReadInterface *
ioReadInterface(const IoRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(&this->interface);
FUNCTION_LOG_RETURN(INT, this->pub.interface.fd == NULL ? -1 : this->pub.interface.fd(this->pub.driver));
}

View File

@ -15,9 +15,41 @@ Object type
typedef struct IoRead IoRead;
#include "common/io/filter/group.h"
#include "common/io/read.intern.h"
#include "common/type/buffer.h"
#include "common/type/object.h"
/***********************************************************************************************************************************
Getters/Setters
***********************************************************************************************************************************/
// Do reads block when more bytes are requested than are available to read?
__attribute__((always_inline)) static inline bool
ioReadBlock(const IoRead *const this)
{
ASSERT_INLINE(this != NULL);
return ((IoReadPub *)this)->interface.block;
}
// Is IO at EOF? All driver reads are complete and all data has been flushed from the filters (if any).
__attribute__((always_inline)) static inline bool
ioReadEof(const IoRead *const this)
{
ASSERT_INLINE(this != NULL);
ASSERT_INLINE(((IoReadPub *)this)->opened && !((IoReadPub *)this)->closed);
return ((const IoReadPub *)this)->eofAll;
}
// Get filter group if filters need to be added
__attribute__((always_inline)) static inline IoFilterGroup *
ioReadFilterGroup(IoRead *const this)
{
ASSERT_INLINE(this != NULL);
return ((IoReadPub *)this)->filterGroup;
}
// File descriptor for the read object. Not all read objects have a file descriptor and -1 will be returned in that case.
int ioReadFd(const IoRead *this);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
@ -30,12 +62,17 @@ size_t ioRead(IoRead *this, Buffer *buffer);
// Same as ioRead() but optimized for small reads (intended for making repetitive reads that are smaller than ioBufferSize())
size_t ioReadSmall(IoRead *this, Buffer *buffer);
// Read linefeed-terminated string
String *ioReadLine(IoRead *this);
// Read linefeed-terminated string and optionally error on eof
String *ioReadLineParam(IoRead *this, bool allowEof);
// Read linefeed-terminated string
__attribute__((always_inline)) static inline String *
ioReadLine(IoRead *const this)
{
ASSERT_INLINE(this != NULL);
return ioReadLineParam(this, false);
}
// Are there bytes ready to read immediately? There are no guarantees on how much data is available to read but it must be at least
// one byte.
typedef struct IoReadReadyParam
@ -52,21 +89,6 @@ bool ioReadReady(IoRead *this, IoReadReadyParam param);
// Close the IO
void ioReadClose(IoRead *this);
/***********************************************************************************************************************************
Getters/Setters
***********************************************************************************************************************************/
// Do reads block when more bytes are requested than are available to read?
bool ioReadBlock(const IoRead *this);
// Is IO at EOF? All driver reads are complete and all data has been flushed from the filters (if any).
bool ioReadEof(const IoRead *this);
// Get filter group if filters need to be added
IoFilterGroup *ioReadFilterGroup(const IoRead *this);
// File descriptor for the read object. Not all read objects have a file descriptor and -1 will be returned in that case.
int ioReadFd(const IoRead *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/

View File

@ -35,11 +35,35 @@ IoRead *ioReadNew(void *driver, IoReadInterface interface);
/***********************************************************************************************************************************
Getters/Setters
***********************************************************************************************************************************/
typedef struct IoReadPub
{
MemContext *memContext; // Mem context
void *driver; // Driver object
IoReadInterface interface; // Driver interface
IoFilterGroup *filterGroup; // IO filters
bool eofAll; // Is the read done (read and filters complete)?
#ifndef NDEBUG
bool opened; // Has the io been opened?
bool closed; // Has the io been closed?
#endif
} IoReadPub;
// Driver for the read object
void *ioReadDriver(IoRead *this);
__attribute__((always_inline)) static inline void *
ioReadDriver(IoRead *const this)
{
ASSERT_INLINE(this != NULL);
return ((IoReadPub *)this)->driver;
}
// Interface for the read object
const IoReadInterface *ioReadInterface(const IoRead *this);
__attribute__((always_inline)) static inline const IoReadInterface *
ioReadInterface(const IoRead *this)
{
ASSERT_INLINE(this != NULL);
return &((IoReadPub *)this)->interface;
}
/***********************************************************************************************************************************
Macros for function logging

View File

@ -4,7 +4,7 @@ Io Session Interface
#include "build.auto.h"
#include "common/debug.h"
#include "common/io/session.intern.h"
#include "common/io/session.h"
#include "common/log.h"
#include "common/memContext.h"
@ -13,9 +13,7 @@ Object type
***********************************************************************************************************************************/
struct IoSession
{
MemContext *memContext; // Mem context
void *driver; // Driver object
const IoSessionInterface *interface; // Driver interface
IoSessionPub pub; // Publicly accessible variables
};
/**********************************************************************************************************************************/
@ -40,29 +38,17 @@ ioSessionNew(void *driver, const IoSessionInterface *interface)
*this = (IoSession)
{
.memContext = memContextCurrent(),
.driver = driver,
.interface = interface,
.pub =
{
.memContext = memContextCurrent(),
.driver = driver,
.interface = interface,
},
};
FUNCTION_LOG_RETURN(IO_SESSION, this);
}
/**********************************************************************************************************************************/
void
ioSessionClose(IoSession *this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(IO_SESSION, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
this->interface->close(this->driver);
FUNCTION_LOG_RETURN_VOID();
}
/**********************************************************************************************************************************/
int
ioSessionFd(IoSession *this)
@ -73,46 +59,7 @@ ioSessionFd(IoSession *this)
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->fd == NULL ? -1 : this->interface->fd(this->driver));
}
/**********************************************************************************************************************************/
IoRead *
ioSessionIoRead(IoSession *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_SESSION, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->ioRead(this->driver));
}
/**********************************************************************************************************************************/
IoWrite *
ioSessionIoWrite(IoSession *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_SESSION, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->ioWrite(this->driver));
}
/**********************************************************************************************************************************/
IoSessionRole
ioSessionRole(const IoSession *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_SESSION, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->role(this->driver));
FUNCTION_TEST_RETURN(this->pub.interface->fd == NULL ? -1 : this->pub.interface->fd(this->pub.driver));
}
/**********************************************************************************************************************************/
@ -120,6 +67,6 @@ String *
ioSessionToLog(const IoSession *this)
{
return strNewFmt(
"{type: %s, role: %s, driver: %s}", strZ(*this->interface->type),
ioSessionRole(this) == ioSessionRoleClient ? "client" : "server", strZ(this->interface->toLog(this->driver)));
"{type: %s, role: %s, driver: %s}", strZ(*this->pub.interface->type),
ioSessionRole(this) == ioSessionRoleClient ? "client" : "server", strZ(this->pub.interface->toLog(this->pub.driver)));
}

View File

@ -12,10 +12,6 @@ Object type
***********************************************************************************************************************************/
typedef struct IoSession IoSession;
#include "common/io/read.h"
#include "common/io/write.h"
#include "common/type/object.h"
/***********************************************************************************************************************************
Session roles
***********************************************************************************************************************************/
@ -25,11 +21,58 @@ typedef enum
ioSessionRoleServer, // Server session
} IoSessionRole;
#include "common/io/read.h"
#include "common/io/session.intern.h"
#include "common/io/write.h"
#include "common/type/object.h"
/***********************************************************************************************************************************
Getters/Setters
***********************************************************************************************************************************/
typedef struct IoSessionPub
{
MemContext *memContext; // Mem context
void *driver; // Driver object
const IoSessionInterface *interface; // Driver interface
} IoSessionPub;
// Session file descriptor, -1 if none
int ioSessionFd(IoSession *this);
// Read interface
__attribute__((always_inline)) static inline IoRead *
ioSessionIoRead(IoSession *const this)
{
ASSERT_INLINE(this != NULL);
return ((IoSessionPub *)this)->interface->ioRead(((IoSessionPub *)this)->driver);
}
// Write interface
__attribute__((always_inline)) static inline IoWrite *
ioSessionIoWrite(IoSession *const this)
{
ASSERT_INLINE(this != NULL);
return ((IoSessionPub *)this)->interface->ioWrite(((IoSessionPub *)this)->driver);
}
// Session role
__attribute__((always_inline)) static inline IoSessionRole
ioSessionRole(const IoSession *const this)
{
ASSERT_INLINE(this != NULL);
return ((const IoSessionPub *)this)->interface->role(((const IoSessionPub *)this)->driver);
}
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
// Close the session
void ioSessionClose(IoSession *this);
__attribute__((always_inline)) static inline void
ioSessionClose(IoSession *const this)
{
ASSERT_INLINE(this != NULL);
return ((IoSessionPub *)this)->interface->close(((IoSessionPub *)this)->driver);
}
// Move to a new parent mem context
__attribute__((always_inline)) static inline IoSession *
@ -38,21 +81,6 @@ ioSessionMove(IoSession *this, MemContext *parentNew)
return objMove(this, parentNew);
}
/***********************************************************************************************************************************
Getters/Setters
***********************************************************************************************************************************/
// Session file descriptor, -1 if none
int ioSessionFd(IoSession *this);
// Read interface
IoRead *ioSessionIoRead(IoSession *this);
// Write interface
IoWrite *ioSessionIoWrite(IoSession *this);
// Session role
IoSessionRole ioSessionRole(const IoSession *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/

View File

@ -5,6 +5,7 @@ Io Session Interface Internal
#define COMMON_IO_SESSION_INTERN_H
#include "common/io/session.h"
#include "common/io/write.h"
/***********************************************************************************************************************************
Interface

View File

@ -10,7 +10,7 @@ Socket Client
#include "common/debug.h"
#include "common/log.h"
#include "common/io/client.intern.h"
#include "common/io/client.h"
#include "common/io/socket/client.h"
#include "common/io/socket/common.h"
#include "common/io/socket/session.h"

View File

@ -10,7 +10,7 @@ Socket Session
#include "common/io/fdRead.h"
#include "common/io/fdWrite.h"
#include "common/io/socket/client.h"
#include "common/io/session.intern.h"
#include "common/io/session.h"
#include "common/memContext.h"
#include "common/type/object.h"

View File

@ -11,7 +11,7 @@ TLS Client
#include "common/crypto/common.h"
#include "common/debug.h"
#include "common/log.h"
#include "common/io/client.intern.h"
#include "common/io/client.h"
#include "common/io/io.h"
#include "common/io/tls/client.h"
#include "common/io/tls/session.h"

View File

@ -8,11 +8,11 @@ TLS Session
#include "common/crypto/common.h"
#include "common/debug.h"
#include "common/io/io.h"
#include "common/io/read.intern.h"
#include "common/io/session.intern.h"
#include "common/io/read.h"
#include "common/io/session.h"
#include "common/io/tls/client.h"
#include "common/io/tls/session.h"
#include "common/io/write.intern.h"
#include "common/io/write.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/type/object.h"

View File

@ -7,7 +7,7 @@ IO Write Interface
#include "common/debug.h"
#include "common/io/io.h"
#include "common/io/write.intern.h"
#include "common/io/write.h"
#include "common/log.h"
#include "common/memContext.h"
@ -16,10 +16,9 @@ Object type
***********************************************************************************************************************************/
struct IoWrite
{
MemContext *memContext; // Mem context
IoWritePub pub; // Publicly accessible variables
void *driver; // Driver object
IoWriteInterface interface; // Driver interface
IoFilterGroup *filterGroup; // IO filters
Buffer *output; // Output buffer
#ifdef DEBUG
@ -49,10 +48,13 @@ ioWriteNew(void *driver, IoWriteInterface interface)
*this = (IoWrite)
{
.memContext = memContextCurrent(),
.pub =
{
.memContext = memContextCurrent(),
.filterGroup = ioFilterGroupNew(),
},
.driver = driver,
.interface = interface,
.filterGroup = ioFilterGroupNew(),
.output = bufNew(ioBufferSize()),
};
}
@ -77,11 +79,11 @@ ioWriteOpen(IoWrite *this)
// Track whether filters were added to prevent flush() from being called later since flush() won't work with most filters
#ifdef DEBUG
this->filterGroupSet = ioFilterGroupSize(this->filterGroup) > 0;
this->filterGroupSet = ioFilterGroupSize(this->pub.filterGroup) > 0;
#endif
// Open the filter group
ioFilterGroupOpen(this->filterGroup);
ioFilterGroupOpen(this->pub.filterGroup);
#ifdef DEBUG
this->opened = true;
@ -107,7 +109,7 @@ ioWrite(IoWrite *this, const Buffer *buffer)
{
do
{
ioFilterGroupProcess(this->filterGroup, buffer, this->output);
ioFilterGroupProcess(this->pub.filterGroup, buffer, this->output);
// Write data if the buffer is full
if (bufRemains(this->output) == 0)
@ -116,7 +118,7 @@ ioWrite(IoWrite *this, const Buffer *buffer)
bufUsedZero(this->output);
}
}
while (ioFilterGroupInputSame(this->filterGroup));
while (ioFilterGroupInputSame(this->pub.filterGroup));
}
FUNCTION_LOG_RETURN_VOID();
@ -229,19 +231,19 @@ ioWriteClose(IoWrite *this)
// Flush remaining data
do
{
ioFilterGroupProcess(this->filterGroup, NULL, this->output);
ioFilterGroupProcess(this->pub.filterGroup, NULL, this->output);
// Write data if the buffer is full or if this is the last buffer to be written
if (bufRemains(this->output) == 0 || (ioFilterGroupDone(this->filterGroup) && !bufEmpty(this->output)))
if (bufRemains(this->output) == 0 || (ioFilterGroupDone(this->pub.filterGroup) && !bufEmpty(this->output)))
{
this->interface.write(this->driver, this->output);
bufUsedZero(this->output);
}
}
while (!ioFilterGroupDone(this->filterGroup));
while (!ioFilterGroupDone(this->pub.filterGroup));
// Close the filter group and gather results
ioFilterGroupClose(this->filterGroup);
ioFilterGroupClose(this->pub.filterGroup);
// Close the driver if there is a close function
if (this->interface.close != NULL)
@ -254,19 +256,6 @@ ioWriteClose(IoWrite *this)
FUNCTION_LOG_RETURN_VOID();
}
/**********************************************************************************************************************************/
IoFilterGroup *
ioWriteFilterGroup(const IoWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->filterGroup);
}
/**********************************************************************************************************************************/
int
ioWriteFd(const IoWrite *this)

View File

@ -14,9 +14,30 @@ Object type
typedef struct IoWrite IoWrite;
#include "common/io/filter/group.h"
#include "common/io/write.intern.h"
#include "common/type/buffer.h"
#include "common/type/object.h"
/***********************************************************************************************************************************
Getters/Setters
***********************************************************************************************************************************/
typedef struct IoWritePub
{
MemContext *memContext; // Mem context
IoFilterGroup *filterGroup; // IO filters
} IoWritePub;
// Filter group. Filters must be set before open and cannot be reset
__attribute__((always_inline)) static inline IoFilterGroup *
ioWriteFilterGroup(IoWrite *const this)
{
ASSERT_INLINE(this != NULL);
return ((IoWritePub *)this)->filterGroup;
}
// File descriptor for the write object. Not all write objects have a file descriptor and -1 will be returned in that case.
int ioWriteFd(const IoWrite *this);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
@ -53,15 +74,6 @@ void ioWriteFlush(IoWrite *this);
// Close the IO and write any additional data that has not been written yet
void ioWriteClose(IoWrite *this);
/***********************************************************************************************************************************
Getters/Setters
***********************************************************************************************************************************/
// Filter group. Filters must be set before open and cannot be reset
IoFilterGroup *ioWriteFilterGroup(const IoWrite *this);
// File descriptor for the write object. Not all write objects have a file descriptor and -1 will be returned in that case.
int ioWriteFd(const IoWrite *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/

View File

@ -5,7 +5,7 @@ GCS Storage Read
#include "common/debug.h"
#include "common/io/http/client.h"
#include "common/io/read.intern.h"
#include "common/io/read.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/type/object.h"

View File

@ -7,7 +7,7 @@ Posix Storage Read
#include <unistd.h>
#include "common/debug.h"
#include "common/io/read.intern.h"
#include "common/io/read.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/type/object.h"

View File

@ -9,7 +9,7 @@ Posix Storage File write
#include <utime.h>
#include "common/debug.h"
#include "common/io/write.intern.h"
#include "common/io/write.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/type/object.h"

View File

@ -4,7 +4,7 @@ Storage Read Interface Internal
#ifndef STORAGE_READ_INTERN_H
#define STORAGE_READ_INTERN_H
#include "common/io/read.intern.h"
#include "common/io/read.h"
/***********************************************************************************************************************************
Constructors

View File

@ -8,7 +8,7 @@ Remote Storage Read
#include "common/compress/helper.h"
#include "common/debug.h"
#include "common/io/read.intern.h"
#include "common/io/read.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/type/convert.h"

View File

@ -5,7 +5,7 @@ Remote Storage File write
#include "common/compress/helper.h"
#include "common/debug.h"
#include "common/io/write.intern.h"
#include "common/io/write.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/type/object.h"

View File

@ -4,7 +4,7 @@ Storage Write Interface Internal
#ifndef STORAGE_WRITE_INTERN_H
#define STORAGE_WRITE_INTERN_H
#include "common/io/write.intern.h"
#include "common/io/write.h"
#include "version.h"
/***********************************************************************************************************************************

View File

@ -316,7 +316,7 @@ testRun(void)
ioFilterGroupAdd(ioReadFilterGroup(bufferRead), ioTestFilterMultiplyNew("double", 2, 3, 'X')),
" add filter to filter group");
TEST_RESULT_PTR(
ioFilterGroupInsert(ioReadFilterGroup(bufferRead), 0, sizeFilter), bufferRead->filterGroup,
ioFilterGroupInsert(ioReadFilterGroup(bufferRead), 0, sizeFilter), bufferRead->pub.filterGroup,
" add filter to filter group");
TEST_RESULT_VOID(ioFilterGroupAdd(ioReadFilterGroup(bufferRead), ioSizeNew()), " add filter to filter group");
IoFilter *bufferFilter = ioBufferNew();
@ -572,8 +572,8 @@ testRun(void)
ioReadOpen(read);
TEST_RESULT_INT(ioReadFd(read), ((IoFdRead *)ioReadDriver(read))->fd, "check fd");
TEST_RESULT_PTR(ioReadInterface(read), &read->interface, "check interface");
TEST_RESULT_PTR(ioReadDriver(read), read->driver, "check driver");
TEST_RESULT_PTR(ioReadInterface(read), &read->pub.interface, "check interface");
TEST_RESULT_PTR(ioReadDriver(read), read->pub.driver, "check driver");
// Read a string
TEST_RESULT_STR_Z(ioReadLine(read), "test string 1", "read test string");
@ -581,9 +581,9 @@ testRun(void)
// Only part of the buffer is written before timeout
Buffer *buffer = bufNew(16);
((IoFdRead *)read->driver)->timeout = 1;
((IoFdRead *)read->pub.driver)->timeout = 1;
TEST_RESULT_BOOL(ioReadReadyP(read), false, "read is not ready (without throwing error)");
((IoFdRead *)read->driver)->timeout = 1000;
((IoFdRead *)read->pub.driver)->timeout = 1000;
TEST_ERROR(ioRead(read, buffer), FileReadError, "timeout after 1000ms waiting for read from 'read test'");
TEST_RESULT_UINT(bufSize(buffer), 16, "buffer is only partially read");

View File

@ -393,7 +393,7 @@ testRun(void)
hrnServerScriptAccept(tls);
TEST_ASSIGN(session, ioClientOpen(client), "open client");
TlsSession *tlsSession = (TlsSession *)session->driver;
TlsSession *tlsSession = (TlsSession *)session->pub.driver;
TEST_RESULT_INT(ioSessionFd(session), -1, "no fd for tls session");
@ -445,11 +445,11 @@ testRun(void)
hrnServerScriptSleep(tls, 500);
output = bufNew(12);
((IoFdRead *)((SocketSession *)tlsSession->ioSession->driver)->read->driver)->timeout = 100;
((IoFdRead *)((SocketSession *)tlsSession->ioSession->pub.driver)->read->pub.driver)->timeout = 100;
TEST_ERROR_FMT(
ioRead(ioSessionIoRead(session), output), FileReadError,
"timeout after 100ms waiting for read from '%s:%u'", strZ(hrnServerHost()), hrnServerPort(0));
((IoFdRead *)((SocketSession *)tlsSession->ioSession->driver)->read->driver)->timeout = 5000;
((IoFdRead *)((SocketSession *)tlsSession->ioSession->pub.driver)->read->pub.driver)->timeout = 5000;
// -----------------------------------------------------------------------------------------------------------------
TEST_TITLE("second protocol exchange");