1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-12 10:04:14 +02:00

Improve interface handling in remaining modules.

As in f6e30736, make the interface object the parent of the driver object rather than the interface being allocated directly in the driver object. Allow exceptions to this general rule for objects that need to retain ownership of their interfaces.
This commit is contained in:
David Steele 2023-03-27 14:32:37 +06:00
parent 5f001248cc
commit 9ca9c8e4c9
66 changed files with 585 additions and 695 deletions

View File

@ -24,8 +24,6 @@ Object type
***********************************************************************************************************************************/
typedef struct BlockIncr
{
MemContext *memContext; // Mem context of filter
unsigned int reference; // Current backup reference
uint64_t bundleId; // Bundle id
@ -390,15 +388,14 @@ blockIncrNew(
FUNCTION_LOG_PARAM(IO_FILTER, encrypt);
FUNCTION_LOG_END();
IoFilter *this = NULL;
BlockIncr *this = NULL;
OBJ_NEW_BEGIN(BlockIncr, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
OBJ_NEW_BEGIN(BlockIncr, .childQty = MEM_CONTEXT_QTY_MAX)
{
BlockIncr *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::BlockIncr);
this = OBJ_NEW_ALLOC();
*driver = (BlockIncr)
*this = (BlockIncr)
{
.memContext = memContextCurrent(),
.superBlockSize = (superBlockSize / blockSize + (superBlockSize % blockSize == 0 ? 0 : 1)) * blockSize,
.blockSize = blockSize,
.checksumSize = checksumSize,
@ -413,13 +410,13 @@ blockIncrNew(
// Duplicate compress filter
if (compress != NULL)
{
driver->compressType = ioFilterType(compress);
driver->compressParam = pckDup(ioFilterParamList(compress));
this->compressType = ioFilterType(compress);
this->compressParam = pckDup(ioFilterParamList(compress));
}
// Duplicate encrypt filter
if (encrypt != NULL)
driver->encryptParam = pckDup(ioFilterParamList(encrypt));
this->encryptParam = pckDup(ioFilterParamList(encrypt));
// Load prior block map
if (blockMapPrior)
@ -430,33 +427,35 @@ blockIncrNew(
MEM_CONTEXT_PRIOR_BEGIN()
{
driver->blockMapPrior = blockMapNewRead(read, blockSize, checksumSize);
this->blockMapPrior = blockMapNewRead(read, blockSize, checksumSize);
}
MEM_CONTEXT_PRIOR_END();
}
MEM_CONTEXT_TEMP_END();
}
}
OBJ_NEW_END();
// Create param list
Pack *paramList = NULL;
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteU64P(packWrite, driver->superBlockSize);
pckWriteU64P(packWrite, this->superBlockSize);
pckWriteU64P(packWrite, blockSize);
pckWriteU64P(packWrite, checksumSize);
pckWriteU32P(packWrite, reference);
pckWriteU64P(packWrite, bundleId);
pckWriteU64P(packWrite, bundleOffset);
pckWriteBinP(packWrite, blockMapPrior);
pckWritePackP(packWrite, driver->compressParam);
pckWritePackP(packWrite, this->compressParam);
if (driver->compressParam != NULL)
pckWriteStrIdP(packWrite, driver->compressType);
if (this->compressParam != NULL)
pckWriteStrIdP(packWrite, this->compressType);
pckWritePackP(packWrite, driver->encryptParam);
pckWritePackP(packWrite, this->encryptParam);
pckWriteEndP(packWrite);
@ -464,13 +463,11 @@ blockIncrNew(
}
MEM_CONTEXT_TEMP_END();
this = ioFilterNewP(
BLOCK_INCR_FILTER_TYPE, driver, paramList, .done = blockIncrDone, .inOut = blockIncrProcess,
.inputSame = blockIncrInputSame, .result = blockIncrResult);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
BLOCK_INCR_FILTER_TYPE, this, paramList, .done = blockIncrDone, .inOut = blockIncrProcess,
.inputSame = blockIncrInputSame, .result = blockIncrResult));
}
FN_EXTERN IoFilter *

View File

@ -19,8 +19,6 @@ Object type
***********************************************************************************************************************************/
typedef struct PageChecksum
{
MemContext *memContext; // Mem context of filter
unsigned int segmentPageTotal; // Total pages in a segment
unsigned int pageNoOffset; // Page number offset for subsequent segments
const String *fileName; // Used to load the file to retry pages
@ -159,12 +157,12 @@ pageChecksumProcess(THIS_VOID, const Buffer *input)
// Create the error list if it does not exist yet
if (this->error == NULL)
{
MEM_CONTEXT_BEGIN(this->memContext)
MEM_CONTEXT_OBJ_BEGIN(this)
{
this->error = pckWriteNewP();
pckWriteArrayBeginP(this->error);
}
MEM_CONTEXT_END();
MEM_CONTEXT_OBJ_END();
}
// Add page number and lsn to the error list
@ -194,7 +192,7 @@ pageChecksumResult(THIS_VOID)
Pack *result = NULL;
MEM_CONTEXT_BEGIN(this->memContext)
MEM_CONTEXT_OBJ_BEGIN(this)
{
// End the error array
if (this->error != NULL)
@ -218,7 +216,7 @@ pageChecksumResult(THIS_VOID)
result = pckMove(pckWriteResult(this->error), memContextPrior());
}
MEM_CONTEXT_END();
MEM_CONTEXT_OBJ_END();
FUNCTION_LOG_RETURN(PACK, result);
}
@ -233,15 +231,14 @@ pageChecksumNew(const unsigned int segmentNo, const unsigned int segmentPageTota
FUNCTION_LOG_PARAM(STRING, fileName);
FUNCTION_LOG_END();
IoFilter *this = NULL;
PageChecksum *this;
OBJ_NEW_BEGIN(PageChecksum, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
{
PageChecksum *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::PageChecksum);
this = OBJ_NEW_ALLOC();
*driver = (PageChecksum)
*this = (PageChecksum)
{
.memContext = memContextCurrent(),
.segmentPageTotal = segmentPageTotal,
.pageNoOffset = segmentNo * segmentPageTotal,
.fileName = strDup(fileName),
@ -249,6 +246,8 @@ pageChecksumNew(const unsigned int segmentNo, const unsigned int segmentPageTota
.valid = true,
.align = true,
};
}
OBJ_NEW_END();
// Create param list
Pack *paramList = NULL;
@ -266,11 +265,9 @@ pageChecksumNew(const unsigned int segmentNo, const unsigned int segmentPageTota
}
MEM_CONTEXT_TEMP_END();
this = ioFilterNewP(PAGE_CHECKSUM_FILTER_TYPE, driver, paramList, .in = pageChecksumProcess, .result = pageChecksumResult);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(PAGE_CHECKSUM_FILTER_TYPE, this, paramList, .in = pageChecksumProcess, .result = pageChecksumResult));
}
FN_EXTERN IoFilter *

View File

@ -15,8 +15,6 @@ Object type
***********************************************************************************************************************************/
typedef struct BlockChecksum
{
MemContext *memContext; // Mem context of filter
size_t blockSize; // Block size for checksums
size_t checksumSize; // Checksum size
size_t blockCurrent; // Size of current block
@ -56,12 +54,12 @@ blockChecksumProcess(THIS_VOID, const Buffer *const input)
// Create checksum object if needed
if (this->checksum == NULL)
{
MEM_CONTEXT_BEGIN(this->memContext)
MEM_CONTEXT_OBJ_BEGIN(this)
{
this->checksum = xxHashNew(this->checksumSize);
this->blockCurrent = 0;
}
MEM_CONTEXT_END();
MEM_CONTEXT_OBJ_END();
}
// Calculate how much data to checksum and perform checksum
@ -136,24 +134,26 @@ blockChecksumNew(const size_t blockSize, const size_t checksumSize)
FUNCTION_LOG_END();
ASSERT(blockSize != 0);
ASSERT(checksumSize != 0);
// Allocate memory to hold process state
IoFilter *this = NULL;
BlockChecksum *this;
OBJ_NEW_BEGIN(BlockChecksum, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
OBJ_NEW_BEGIN(BlockChecksum, .childQty = MEM_CONTEXT_QTY_MAX)
{
BlockChecksum *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::BlockChecksum);
this = OBJ_NEW_ALLOC();
*driver = (BlockChecksum)
*this = (BlockChecksum)
{
.memContext = memContextCurrent(),
.blockSize = blockSize,
.checksumSize = checksumSize,
.list = lstNewP(checksumSize),
};
}
OBJ_NEW_END();
// Create param list
Pack *paramList = NULL;
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
@ -167,12 +167,9 @@ blockChecksumNew(const size_t blockSize, const size_t checksumSize)
}
MEM_CONTEXT_TEMP_END();
this = ioFilterNewP(
BLOCK_CHECKSUM_FILTER_TYPE, driver, paramList, .in = blockChecksumProcess, .result = blockChecksumResult);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(BLOCK_CHECKSUM_FILTER_TYPE, this, paramList, .in = blockChecksumProcess, .result = blockChecksumResult));
}
/**********************************************************************************************************************************/

View File

@ -166,25 +166,27 @@ bz2CompressNew(const int level, const bool raw)
ASSERT(level >= BZ2_COMPRESS_LEVEL_MIN && level <= BZ2_COMPRESS_LEVEL_MAX);
IoFilter *this = NULL;
Bz2Compress *this;
OBJ_NEW_BEGIN(Bz2Compress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
OBJ_NEW_BEGIN(Bz2Compress, .childQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
Bz2Compress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::Bz2Compress);
this = OBJ_NEW_ALLOC();
*driver = (Bz2Compress)
*this = (Bz2Compress)
{
.stream = {.bzalloc = NULL},
};
// Initialize context
bz2Error(BZ2_bzCompressInit(&driver->stream, level, 0, 0));
bz2Error(BZ2_bzCompressInit(&this->stream, level, 0, 0));
// Set callback to ensure bz2 stream is freed
memContextCallbackSet(objMemContext(driver), bz2CompressFreeResource, driver);
memContextCallbackSet(objMemContext(this), bz2CompressFreeResource, this);
}
OBJ_NEW_END();
// Create param list
Pack *paramList = NULL;
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
@ -197,12 +199,9 @@ bz2CompressNew(const int level, const bool raw)
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(
BZ2_COMPRESS_FILTER_TYPE, driver, paramList, .done = bz2CompressDone, .inOut = bz2CompressProcess,
.inputSame = bz2CompressInputSame);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
BZ2_COMPRESS_FILTER_TYPE, this, paramList, .done = bz2CompressDone, .inOut = bz2CompressProcess,
.inputSame = bz2CompressInputSame));
}

View File

@ -150,30 +150,28 @@ bz2DecompressNew(const bool raw)
(void)raw; // Raw unsupported
FUNCTION_LOG_END();
IoFilter *this = NULL;
Bz2Decompress *this;
OBJ_NEW_BEGIN(Bz2Decompress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
OBJ_NEW_BEGIN(Bz2Decompress, .childQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
// Allocate state and set context
Bz2Decompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::Bz2Decompress);
this = OBJ_NEW_ALLOC();
*driver = (Bz2Decompress)
*this = (Bz2Decompress)
{
.stream = {.bzalloc = NULL},
};
// Create bz2 stream
bz2Error(driver->result = BZ2_bzDecompressInit(&driver->stream, 0, 0));
bz2Error(this->result = BZ2_bzDecompressInit(&this->stream, 0, 0));
// Set free callback to ensure bz2 context is freed
memContextCallbackSet(objMemContext(driver), bz2DecompressFreeResource, driver);
// Create filter interface
this = ioFilterNewP(
BZ2_DECOMPRESS_FILTER_TYPE, driver, NULL, .done = bz2DecompressDone, .inOut = bz2DecompressProcess,
.inputSame = bz2DecompressInputSame);
memContextCallbackSet(objMemContext(this), bz2DecompressFreeResource, this);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
BZ2_DECOMPRESS_FILTER_TYPE, this, NULL, .done = bz2DecompressDone, .inOut = bz2DecompressProcess,
.inputSame = bz2DecompressInputSame));
}

View File

@ -173,25 +173,27 @@ gzCompressNew(const int level, const bool raw)
ASSERT(level >= GZ_COMPRESS_LEVEL_MIN && level <= GZ_COMPRESS_LEVEL_MAX);
IoFilter *this = NULL;
GzCompress *this;
OBJ_NEW_BEGIN(GzCompress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
OBJ_NEW_BEGIN(GzCompress, .childQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
GzCompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::GzCompress);
this = OBJ_NEW_ALLOC();
*driver = (GzCompress)
*this = (GzCompress)
{
.stream = {.zalloc = NULL},
};
// Create gz stream
gzError(deflateInit2(&driver->stream, level, Z_DEFLATED, (raw ? 0 : WANT_GZ) | WINDOW_BITS, MEM_LEVEL, Z_DEFAULT_STRATEGY));
gzError(deflateInit2(&this->stream, level, Z_DEFLATED, (raw ? 0 : WANT_GZ) | WINDOW_BITS, MEM_LEVEL, Z_DEFAULT_STRATEGY));
// Set free callback to ensure gz context is freed
memContextCallbackSet(objMemContext(driver), gzCompressFreeResource, driver);
memContextCallbackSet(objMemContext(this), gzCompressFreeResource, this);
}
OBJ_NEW_END();
// Create param list
Pack *paramList = NULL;
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
@ -205,12 +207,9 @@ gzCompressNew(const int level, const bool raw)
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(
GZ_COMPRESS_FILTER_TYPE, driver, paramList, .done = gzCompressDone, .inOut = gzCompressProcess,
.inputSame = gzCompressInputSame);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
GZ_COMPRESS_FILTER_TYPE, this, paramList, .done = gzCompressDone, .inOut = gzCompressProcess,
.inputSame = gzCompressInputSame));
}

View File

@ -152,26 +152,27 @@ gzDecompressNew(const bool raw)
FUNCTION_LOG_PARAM(BOOL, raw);
FUNCTION_LOG_END();
IoFilter *this = NULL;
GzDecompress *this;
OBJ_NEW_BEGIN(GzDecompress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
OBJ_NEW_BEGIN(GzDecompress, .childQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
// Allocate state and set context
GzDecompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::GzDecompress);
this = OBJ_NEW_ALLOC();
*driver = (GzDecompress)
*this = (GzDecompress)
{
.stream = {.zalloc = NULL},
};
// Create gz stream
gzError(driver->result = inflateInit2(&driver->stream, (raw ? 0 : WANT_GZ) | WINDOW_BITS));
gzError(this->result = inflateInit2(&this->stream, (raw ? 0 : WANT_GZ) | WINDOW_BITS));
// Set free callback to ensure gz context is freed
memContextCallbackSet(objMemContext(driver), gzDecompressFreeResource, driver);
memContextCallbackSet(objMemContext(this), gzDecompressFreeResource, this);
}
OBJ_NEW_END();
// Create param list
Pack *paramList = NULL;
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
@ -184,12 +185,9 @@ gzDecompressNew(const bool raw)
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(
GZ_DECOMPRESS_FILTER_TYPE, driver, paramList, .done = gzDecompressDone, .inOut = gzDecompressProcess,
.inputSame = gzDecompressInputSame);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
GZ_DECOMPRESS_FILTER_TYPE, this, paramList, .done = gzDecompressDone, .inOut = gzDecompressProcess,
.inputSame = gzDecompressInputSame));
}

View File

@ -252,13 +252,13 @@ lz4CompressNew(const int level, const bool raw)
ASSERT(level >= LZ4_COMPRESS_LEVEL_MIN && level <= LZ4_COMPRESS_LEVEL_MAX);
IoFilter *this = NULL;
Lz4Compress *this;
OBJ_NEW_BEGIN(Lz4Compress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
OBJ_NEW_BEGIN(Lz4Compress, .childQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
Lz4Compress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::Lz4Compress);
this = OBJ_NEW_ALLOC();
*driver = (Lz4Compress)
*this = (Lz4Compress)
{
.prefs =
{
@ -270,13 +270,15 @@ lz4CompressNew(const int level, const bool raw)
};
// Create lz4 context
lz4Error(LZ4F_createCompressionContext(&driver->context, LZ4F_VERSION));
lz4Error(LZ4F_createCompressionContext(&this->context, LZ4F_VERSION));
// Set callback to ensure lz4 context is freed
memContextCallbackSet(objMemContext(driver), lz4CompressFreeResource, driver);
memContextCallbackSet(objMemContext(this), lz4CompressFreeResource, this);
}
OBJ_NEW_END();
// Create param list
Pack *paramList = NULL;
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
@ -290,14 +292,11 @@ lz4CompressNew(const int level, const bool raw)
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(
LZ4_COMPRESS_FILTER_TYPE, driver, paramList, .done = lz4CompressDone, .inOut = lz4CompressProcess,
.inputSame = lz4CompressInputSame);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
LZ4_COMPRESS_FILTER_TYPE, this, paramList, .done = lz4CompressDone, .inOut = lz4CompressProcess,
.inputSame = lz4CompressInputSame));
}
#endif // HAVE_LIBLZ4

View File

@ -163,27 +163,26 @@ lz4DecompressNew(const bool raw)
(void)raw; // Not required for decompress
FUNCTION_LOG_END();
IoFilter *this = NULL;
Lz4Decompress *this;
OBJ_NEW_BEGIN(Lz4Decompress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
OBJ_NEW_BEGIN(Lz4Decompress, .childQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
Lz4Decompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::Lz4Decompress);
*driver = (Lz4Decompress){0};
this = OBJ_NEW_ALLOC();
*this = (Lz4Decompress){0};
// Create lz4 context
lz4Error(LZ4F_createDecompressionContext(&driver->context, LZ4F_VERSION));
lz4Error(LZ4F_createDecompressionContext(&this->context, LZ4F_VERSION));
// Set callback to ensure lz4 context is freed
memContextCallbackSet(objMemContext(driver), lz4DecompressFreeResource, driver);
// Create filter interface
this = ioFilterNewP(
LZ4_DECOMPRESS_FILTER_TYPE, driver, NULL, .done = lz4DecompressDone, .inOut = lz4DecompressProcess,
.inputSame = lz4DecompressInputSame);
memContextCallbackSet(objMemContext(this), lz4DecompressFreeResource, this);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
LZ4_DECOMPRESS_FILTER_TYPE, this, NULL, .done = lz4DecompressDone, .inOut = lz4DecompressProcess,
.inputSame = lz4DecompressInputSame));
}
#endif // HAVE_LIBLZ4

View File

@ -173,26 +173,28 @@ zstCompressNew(const int level, const bool raw)
ASSERT(level >= ZST_COMPRESS_LEVEL_MIN && level <= ZST_COMPRESS_LEVEL_MAX);
IoFilter *this = NULL;
ZstCompress *this;
OBJ_NEW_BEGIN(ZstCompress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
ZstCompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::ZstCompress);
this = OBJ_NEW_ALLOC();
*driver = (ZstCompress)
*this = (ZstCompress)
{
.context = ZSTD_createCStream(),
.level = level,
};
// Set callback to ensure zst context is freed
memContextCallbackSet(objMemContext(driver), zstCompressFreeResource, driver);
memContextCallbackSet(objMemContext(this), zstCompressFreeResource, this);
// Initialize context
zstError(ZSTD_initCStream(driver->context, driver->level));
zstError(ZSTD_initCStream(this->context, this->level));
}
OBJ_NEW_END();
// Create param list
Pack *paramList = NULL;
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
@ -205,14 +207,11 @@ zstCompressNew(const int level, const bool raw)
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(
ZST_COMPRESS_FILTER_TYPE, driver, paramList, .done = zstCompressDone, .inOut = zstCompressProcess,
.inputSame = zstCompressInputSame);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
ZST_COMPRESS_FILTER_TYPE, this, paramList, .done = zstCompressDone, .inOut = zstCompressProcess,
.inputSame = zstCompressInputSame));
}
#endif // HAVE_LIBZST

View File

@ -162,31 +162,30 @@ zstDecompressNew(const bool raw)
(void)raw; // Raw unsupported
FUNCTION_LOG_END();
IoFilter *this = NULL;
ZstDecompress *this;
OBJ_NEW_BEGIN(ZstDecompress, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
OBJ_NEW_BEGIN(ZstDecompress, .childQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
ZstDecompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::ZstDecompress);
this = OBJ_NEW_ALLOC();
*driver = (ZstDecompress)
*this = (ZstDecompress)
{
.context = ZSTD_createDStream(),
};
// Set callback to ensure zst context is freed
memContextCallbackSet(objMemContext(driver), zstDecompressFreeResource, driver);
memContextCallbackSet(objMemContext(this), zstDecompressFreeResource, this);
// Initialize context
zstError(ZSTD_initDStream(driver->context));
// Create filter interface
this = ioFilterNewP(
ZST_DECOMPRESS_FILTER_TYPE, driver, NULL, .done = zstDecompressDone, .inOut = zstDecompressProcess,
.inputSame = zstDecompressInputSame);
zstError(ZSTD_initDStream(this->context));
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
ZST_DECOMPRESS_FILTER_TYPE, this, NULL, .done = zstDecompressDone, .inOut = zstDecompressProcess,
.inputSame = zstDecompressInputSame));
}
#endif // HAVE_LIBZST

View File

@ -386,7 +386,7 @@ cipherBlockInputSame(const THIS_VOID)
/**********************************************************************************************************************************/
FN_EXTERN IoFilter *
cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, CipherBlockNewParam param)
cipherBlockNew(const CipherMode mode, const CipherType cipherType, const Buffer *const pass, const CipherBlockNewParam param)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING_ID, mode);
@ -424,13 +424,13 @@ cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, Ciphe
THROW_FMT(AssertError, "unable to load digest '%s'", strZ(param.digest));
// Allocate memory to hold process state
IoFilter *this = NULL;
CipherBlock *this;
OBJ_NEW_BEGIN(CipherBlock, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
CipherBlock *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::CipherBlock);
this = OBJ_NEW_ALLOC();
*driver = (CipherBlock)
*this = (CipherBlock)
{
.mode = mode,
.raw = param.raw,
@ -440,11 +440,13 @@ cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, Ciphe
};
// Store the passphrase
driver->pass = memNew(driver->passSize);
memcpy(driver->pass, bufPtrConst(pass), driver->passSize);
this->pass = memNew(this->passSize);
memcpy(this->pass, bufPtrConst(pass), this->passSize);
}
OBJ_NEW_END();
// Create param list
Pack *paramList = NULL;
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
@ -461,14 +463,11 @@ cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, Ciphe
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(
CIPHER_BLOCK_FILTER_TYPE, driver, paramList, .done = cipherBlockDone, .inOut = cipherBlockProcess,
.inputSame = cipherBlockInputSame);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
CIPHER_BLOCK_FILTER_TYPE, this, paramList, .done = cipherBlockDone, .inOut = cipherBlockProcess,
.inputSame = cipherBlockInputSame));
}
FN_EXTERN IoFilter *

View File

@ -180,21 +180,21 @@ cryptoHashNew(const HashType type)
cryptoInit();
// Allocate memory to hold process state
IoFilter *this = NULL;
CryptoHash *this;
OBJ_NEW_BEGIN(CryptoHash, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
CryptoHash *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::CryptoHash);
*driver = (CryptoHash){0};
this = OBJ_NEW_ALLOC();
*this = (CryptoHash){0};
// Use local MD5 implementation since FIPS-enabled systems do not allow MD5. This is a bit misguided since there are valid
// cases for using MD5 which do not involve, for example, password hashes. Since popular object stores, e.g. S3, require
// MD5 for verifying payload integrity we are simply forced to provide MD5 functionality.
if (type == hashTypeMd5)
{
driver->md5Context = memNew(sizeof(MD5_CTX));
this->md5Context = memNew(sizeof(MD5_CTX));
MD5_Init(driver->md5Context);
MD5_Init(this->md5Context);
}
// Else use the standard OpenSSL implementation
else
@ -203,21 +203,23 @@ cryptoHashNew(const HashType type)
char typeZ[STRID_MAX + 1];
strIdToZ(type, typeZ);
if ((driver->hashType = EVP_get_digestbyname(typeZ)) == NULL)
if ((this->hashType = EVP_get_digestbyname(typeZ)) == NULL)
THROW_FMT(AssertError, "unable to load hash '%s'", typeZ);
// Create context
cryptoError((driver->hashContext = EVP_MD_CTX_create()) == NULL, "unable to create hash context");
cryptoError((this->hashContext = EVP_MD_CTX_create()) == NULL, "unable to create hash context");
// Set free callback to ensure hash context is freed
memContextCallbackSet(objMemContext(driver), cryptoHashFreeResource, driver);
memContextCallbackSet(objMemContext(this), cryptoHashFreeResource, this);
// Initialize context
cryptoError(!EVP_DigestInit_ex(driver->hashContext, driver->hashType, NULL), "unable to initialize hash context");
cryptoError(!EVP_DigestInit_ex(this->hashContext, this->hashType, NULL), "unable to initialize hash context");
}
}
OBJ_NEW_END();
// Create param list
Pack *paramList = NULL;
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
@ -230,12 +232,8 @@ cryptoHashNew(const HashType type)
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(CRYPTO_HASH_FILTER_TYPE, driver, paramList, .in = cryptoHashProcess, .result = cryptoHashResult);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER, ioFilterNewP(CRYPTO_HASH_FILTER_TYPE, this, paramList, .in = cryptoHashProcess, .result = cryptoHashResult));
}
FN_EXTERN IoFilter *

View File

@ -117,25 +117,22 @@ xxHashNew(const size_t size)
ASSERT(size >= 1 && size <= XX_HASH_SIZE_MAX);
// Allocate memory to hold process state
IoFilter *this = NULL;
XxHash *this;
OBJ_NEW_BEGIN(XxHash, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
OBJ_NEW_BEGIN(XxHash, .callbackQty = 1)
{
XxHash *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::XxHash);
*driver = (XxHash){.size = size};
this = OBJ_NEW_ALLOC();
*this = (XxHash){.size = size};
driver->state = XXH3_createState();
XXH3_128bits_reset(driver->state);
this->state = XXH3_createState();
XXH3_128bits_reset(this->state);
// Set free callback to ensure hash context is freed
memContextCallbackSet(objMemContext(driver), xxHashFreeResource, driver);
// Create filter interface
this = ioFilterNewP(XX_HASH_FILTER_TYPE, driver, NULL, .in = xxHashProcess, .result = xxHashResult);
memContextCallbackSet(objMemContext(this), xxHashFreeResource, this);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(IO_FILTER, ioFilterNewP(XX_HASH_FILTER_TYPE, this, NULL, .in = xxHashProcess, .result = xxHashResult));
}
/**********************************************************************************************************************************/

View File

@ -84,7 +84,7 @@ ioBufferReadEof(THIS_VOID)
/**********************************************************************************************************************************/
FN_EXTERN IoRead *
ioBufferReadNew(const Buffer *buffer)
ioBufferReadNew(const Buffer *const buffer)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(BUFFER, buffer);
@ -92,20 +92,18 @@ ioBufferReadNew(const Buffer *buffer)
ASSERT(buffer != NULL);
IoRead *this = NULL;
IoBufferRead *this;
OBJ_NEW_BEGIN(IoBufferRead, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
OBJ_NEW_BEGIN(IoBufferRead, .childQty = MEM_CONTEXT_QTY_MAX)
{
IoBufferRead *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoRead::IoBufferRead);
this = OBJ_NEW_ALLOC();
*driver = (IoBufferRead)
*this = (IoBufferRead)
{
.read = buffer,
};
this = ioReadNewP(driver, .eof = ioBufferReadEof, .read = ioBufferRead);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_READ, this);
FUNCTION_LOG_RETURN(IO_READ, ioReadNewP(this, .eof = ioBufferReadEof, .read = ioBufferRead));
}

View File

@ -48,7 +48,7 @@ ioBufferWrite(THIS_VOID, const Buffer *buffer)
/**********************************************************************************************************************************/
FN_EXTERN IoWrite *
ioBufferWriteNew(Buffer *buffer)
ioBufferWriteNew(Buffer *const buffer)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(BUFFER, buffer);
@ -56,20 +56,18 @@ ioBufferWriteNew(Buffer *buffer)
ASSERT(buffer != NULL);
IoWrite *this = NULL;
IoBufferWrite *this;
OBJ_NEW_BEGIN(IoBufferWrite, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
OBJ_NEW_BEGIN(IoBufferWrite, .childQty = MEM_CONTEXT_QTY_MAX)
{
IoBufferWrite *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoWrite::IoBufferWrite);
this = OBJ_NEW_ALLOC();
*driver = (IoBufferWrite)
*this = (IoBufferWrite)
{
.write = buffer,
};
this = ioWriteNewP(driver, .write = ioBufferWrite);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_WRITE, this);
FUNCTION_LOG_RETURN(IO_WRITE, ioWriteNewP(this, .write = ioBufferWrite));
}

View File

@ -154,20 +154,18 @@ ioChunkedReadNew(IoRead *const read)
ASSERT(read != NULL);
IoRead *this = NULL;
IoChunkedRead *this;
OBJ_NEW_BEGIN(IoChunkedRead, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
OBJ_NEW_BEGIN(IoChunkedRead, .childQty = MEM_CONTEXT_QTY_MAX)
{
IoChunkedRead *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoRead::IoChunkedRead);
this = OBJ_NEW_ALLOC();
*driver = (IoChunkedRead)
*this = (IoChunkedRead)
{
.read = read,
};
this = ioReadNewP(driver, .eof = ioChunkedReadEof, .open = ioChunkedReadOpen, .read = ioChunkedRead);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_READ, this);
FUNCTION_LOG_RETURN(IO_READ, ioReadNewP(this, .eof = ioChunkedReadEof, .open = ioChunkedReadOpen, .read = ioChunkedRead));
}

View File

@ -17,7 +17,7 @@ struct IoClient
/**********************************************************************************************************************************/
FN_EXTERN IoClient *
ioClientNew(void *driver, const IoClientInterface *interface)
ioClientNew(void *const driver, const IoClientInterface *const interface)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM_P(VOID, driver);
@ -31,17 +31,22 @@ ioClientNew(void *driver, const IoClientInterface *interface)
ASSERT(interface->open != NULL);
ASSERT(interface->toLog != NULL);
IoClient *this = memNew(sizeof(IoClient));
IoClient *this;
OBJ_NEW_BEGIN(IoClient, .childQty = MEM_CONTEXT_QTY_MAX)
{
this = OBJ_NEW_ALLOC();
*this = (IoClient)
{
.pub =
{
.memContext = memContextCurrent(),
.driver = driver,
.driver = objMoveToInterface(driver, this, memContextPrior()),
.interface = interface,
},
};
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_CLIENT, this);
}

View File

@ -21,7 +21,6 @@ Getters/Setters
***********************************************************************************************************************************/
typedef struct IoClientPub
{
MemContext *memContext; // Mem context
void *driver; // Driver object
const IoClientInterface *interface; // Driver interface
} IoClientPub;
@ -40,7 +39,7 @@ Functions
FN_INLINE_ALWAYS IoClient *
ioClientMove(IoClient *const this, MemContext *const parentNew)
{
return objMoveContext(this, parentNew);
return objMove(this, parentNew);
}
// Open session
@ -56,7 +55,7 @@ Destructor
FN_INLINE_ALWAYS void
ioClientFree(IoClient *const this)
{
objFreeContext(this);
objFree(this);
}
/***********************************************************************************************************************************

View File

@ -144,7 +144,7 @@ ioFdReadFd(const THIS_VOID)
/**********************************************************************************************************************************/
FN_EXTERN IoRead *
ioFdReadNew(const String *name, int fd, TimeMSec timeout)
ioFdReadNew(const String *const name, const int fd, const TimeMSec timeout)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, name);
@ -154,22 +154,21 @@ ioFdReadNew(const String *name, int fd, TimeMSec timeout)
ASSERT(fd != -1);
IoRead *this = NULL;
IoFdRead *this;
OBJ_NEW_BEGIN(IoFdRead, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
OBJ_NEW_BEGIN(IoFdRead, .childQty = MEM_CONTEXT_QTY_MAX)
{
IoFdRead *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoRead::IoFdRead);
this = OBJ_NEW_ALLOC();
*driver = (IoFdRead)
*this = (IoFdRead)
{
.name = strDup(name),
.fd = fd,
.timeout = timeout,
};
this = ioReadNewP(driver, .block = true, .eof = ioFdReadEof, .fd = ioFdReadFd, .read = ioFdRead, .ready = ioFdReadReady);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_READ, this);
FUNCTION_LOG_RETURN(
IO_READ, ioReadNewP(this, .block = true, .eof = ioFdReadEof, .fd = ioFdReadFd, .read = ioFdRead, .ready = ioFdReadReady));
}

View File

@ -102,7 +102,7 @@ ioFdWriteFd(const THIS_VOID)
/**********************************************************************************************************************************/
FN_EXTERN IoWrite *
ioFdWriteNew(const String *name, int fd, TimeMSec timeout)
ioFdWriteNew(const String *const name, const int fd, const TimeMSec timeout)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, name);
@ -110,24 +110,22 @@ ioFdWriteNew(const String *name, int fd, TimeMSec timeout)
FUNCTION_LOG_PARAM(TIME_MSEC, timeout);
FUNCTION_LOG_END();
IoWrite *this = NULL;
IoFdWrite *this;
OBJ_NEW_BEGIN(IoFdWrite, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
OBJ_NEW_BEGIN(IoFdWrite, .childQty = MEM_CONTEXT_QTY_MAX)
{
IoFdWrite *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoWrite::IoFdWrite);
this = OBJ_NEW_ALLOC();
*driver = (IoFdWrite)
*this = (IoFdWrite)
{
.name = strDup(name),
.fd = fd,
.timeout = timeout,
};
this = ioWriteNewP(driver, .fd = ioFdWriteFd, .ready = ioFdWriteReady, .write = ioFdWrite);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_WRITE, this);
FUNCTION_LOG_RETURN(IO_WRITE, ioWriteNewP(this, .fd = ioFdWriteFd, .ready = ioFdWriteReady, .write = ioFdWrite));
}
/**********************************************************************************************************************************/

View File

@ -108,16 +108,15 @@ ioBufferNew(void)
{
FUNCTION_LOG_VOID(logLevelTrace);
IoFilter *this = NULL;
IoBuffer *this;
OBJ_NEW_BEGIN(IoBuffer, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
OBJ_NEW_BEGIN(IoBuffer)
{
IoBuffer *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::IoBuffer);
*driver = (IoBuffer){0};
this = ioFilterNewP(BUFFER_FILTER_TYPE, driver, NULL, .inOut = ioBufferProcess, .inputSame = ioBufferInputSame);
this = OBJ_NEW_ALLOC();
*this = (IoBuffer){0};
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER, ioFilterNewP(BUFFER_FILTER_TYPE, this, NULL, .inOut = ioBufferProcess, .inputSame = ioBufferInputSame));
}

View File

@ -13,8 +13,6 @@ Object type
***********************************************************************************************************************************/
typedef struct IoChunk
{
MemContext *memContext; // Mem context of filter
const uint8_t *buffer; // Internal buffer
size_t bufferSize; // Buffer size
size_t bufferOffset; // Buffer offset
@ -151,22 +149,16 @@ ioChunkNew(void)
{
FUNCTION_LOG_VOID(logLevelTrace);
IoFilter *this = NULL;
IoChunk *this;
OBJ_NEW_BEGIN(IoChunk, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
OBJ_NEW_BEGIN(IoChunk)
{
IoChunk *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::IoChunk);
*driver = (IoChunk)
{
.memContext = memContextCurrent(),
};
this = ioFilterNewP(
CHUNK_FILTER_TYPE, driver, NULL, .done = ioChunkDone, .inOut = ioChunkProcess,
.inputSame = ioChunkInputSame);
this = OBJ_NEW_ALLOC();
*this = (IoChunk){0};
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(CHUNK_FILTER_TYPE, this, NULL, .done = ioChunkDone, .inOut = ioChunkProcess, .inputSame = ioChunkInputSame));
}

View File

@ -39,19 +39,24 @@ ioFilterNew(const StringId type, void *const driver, Pack *const paramList, cons
// If the filter does not produce output then it should produce a result
ASSERT(interface.in == NULL || (interface.result != NULL && interface.done == NULL && interface.inputSame == NULL));
IoFilter *this = memNew(sizeof(IoFilter));
IoFilter *this;
OBJ_NEW_BEGIN(IoFilter, .childQty = MEM_CONTEXT_QTY_MAX)
{
this = OBJ_NEW_ALLOC();
*this = (IoFilter)
{
.pub =
{
.memContext = memContextCurrent(),
.type = type,
.driver = driver,
.paramList = paramList,
.driver = objMoveToInterface(driver, this, memContextPrior()),
.paramList = pckMove(paramList, objMemContext(this)),
.interface = interface,
},
};
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
}

View File

@ -39,7 +39,7 @@ Destructor
FN_INLINE_ALWAYS void
ioFilterFree(IoFilter *const this)
{
objFreeContext(this);
objFree(this);
}
/***********************************************************************************************************************************

View File

@ -61,7 +61,6 @@ Getters/Setters
***********************************************************************************************************************************/
typedef struct IoFilterPub
{
MemContext *memContext; // Mem context
StringId type; // Filter type
IoFilterInterface interface; // Filter interface
void *driver; // Filter driver
@ -114,9 +113,9 @@ FN_EXTERN void ioFilterProcessInOut(IoFilter *this, const Buffer *input, Buffer
// Move filter to a new parent mem context
FN_INLINE_ALWAYS IoFilter *
ioFilterMove(IoFilter *this, MemContext *parentNew)
ioFilterMove(IoFilter *const this, MemContext *const parentNew)
{
return objMoveContext(this, parentNew);
return objMove(this, parentNew);
}
/***********************************************************************************************************************************

View File

@ -52,14 +52,13 @@ ioSinkNew(void)
{
FUNCTION_LOG_VOID(logLevelTrace);
IoFilter *this = NULL;
IoSink *this;
OBJ_NEW_BEGIN(IoSink, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
OBJ_NEW_BEGIN(IoSink)
{
IoSink *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::IoSink);
this = ioFilterNewP(SINK_FILTER_TYPE, driver, NULL, .inOut = ioSinkProcess);
this = OBJ_NEW_ALLOC();
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(IO_FILTER, ioFilterNewP(SINK_FILTER_TYPE, this, NULL, .inOut = ioSinkProcess));
}

View File

@ -17,7 +17,7 @@ Object type
***********************************************************************************************************************************/
typedef struct IoSize
{
uint64_t size; // Total size of al input
uint64_t size; // Total size of all input
} IoSize;
/***********************************************************************************************************************************
@ -91,16 +91,14 @@ ioSizeNew(void)
{
FUNCTION_LOG_VOID(logLevelTrace);
IoFilter *this = NULL;
IoSize *this;
OBJ_NEW_BEGIN(IoSize, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
OBJ_NEW_BEGIN(IoSize)
{
IoSize *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::IoSize);
*driver = (IoSize){0};
this = ioFilterNewP(SIZE_FILTER_TYPE, driver, NULL, .in = ioSizeProcess, .result = ioSizeResult);
this = OBJ_NEW_ALLOC();
*this = (IoSize){0};
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this);
FUNCTION_LOG_RETURN(IO_FILTER, ioFilterNewP(SIZE_FILTER_TYPE, this, NULL, .in = ioSizeProcess, .result = ioSizeResult));
}

View File

@ -23,7 +23,7 @@ struct IoRead
/**********************************************************************************************************************************/
FN_EXTERN IoRead *
ioReadNew(void *driver, IoReadInterface interface)
ioReadNew(void *const driver, const IoReadInterface interface)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM_P(VOID, driver);
@ -43,8 +43,7 @@ ioReadNew(void *driver, IoReadInterface interface)
{
.pub =
{
.memContext = memContextCurrent(),
.driver = driver,
.driver = objMoveToInterface(driver, this, memContextPrior()),
.interface = interface,
.filterGroup = ioFilterGroupNew(),
},
@ -217,11 +216,11 @@ ioReadSmall(IoRead *this, Buffer *buffer)
// Allocate the internal output buffer if it has not already been allocated
if (this->output == NULL)
{
MEM_CONTEXT_BEGIN(this->pub.memContext)
MEM_CONTEXT_OBJ_BEGIN(this)
{
this->output = bufNew(ioBufferSize());
}
MEM_CONTEXT_END();
MEM_CONTEXT_OBJ_END();
}
// Store size of remaining portion of buffer to calculate total read at the end
@ -285,11 +284,11 @@ ioReadLineParam(IoRead *this, bool allowEof)
// is not always used.
if (this->output == NULL)
{
MEM_CONTEXT_BEGIN(this->pub.memContext)
MEM_CONTEXT_OBJ_BEGIN(this)
{
this->output = bufNew(ioBufferSize());
}
MEM_CONTEXT_END();
MEM_CONTEXT_OBJ_END();
}
// Search for a linefeed
@ -366,11 +365,11 @@ ioReadVarIntU64(IoRead *const this)
// Allocate the internal output buffer if it has not already been allocated
if (this->output == NULL)
{
MEM_CONTEXT_BEGIN(this->pub.memContext)
MEM_CONTEXT_OBJ_BEGIN(this)
{
this->output = bufNew(ioBufferSize());
}
MEM_CONTEXT_END();
MEM_CONTEXT_OBJ_END();
}
uint64_t result = 0;

View File

@ -94,7 +94,7 @@ Destructor
FN_INLINE_ALWAYS void
ioReadFree(IoRead *const this)
{
objFreeContext(this);
objFree(this);
}
/***********************************************************************************************************************************

View File

@ -37,7 +37,6 @@ Getters/Setters
***********************************************************************************************************************************/
typedef struct IoReadPub
{
MemContext *memContext; // Mem context
void *driver; // Driver object
IoReadInterface interface; // Driver interface
IoFilterGroup *filterGroup; // IO filters

View File

@ -32,17 +32,22 @@ ioServerNew(void *const driver, const IoServerInterface *const interface)
ASSERT(interface->accept != NULL);
ASSERT(interface->toLog != NULL);
IoServer *this = memNew(sizeof(IoServer));
IoServer *this;
OBJ_NEW_BEGIN(IoServer, .childQty = MEM_CONTEXT_QTY_MAX)
{
this = OBJ_NEW_ALLOC();
*this = (IoServer)
{
.pub =
{
.memContext = memContextCurrent(),
.driver = driver,
.driver = objMoveToInterface(driver, this, memContextPrior()),
.interface = interface,
},
};
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_SERVER, this);
}

View File

@ -21,7 +21,6 @@ Getters/Setters
***********************************************************************************************************************************/
typedef struct IoServerPub
{
MemContext *memContext; // Mem context
void *driver; // Driver object
const IoServerInterface *interface; // Driver interface
} IoServerPub;
@ -40,7 +39,7 @@ Functions
FN_INLINE_ALWAYS IoServer *
ioServerMove(IoServer *const this, MemContext *const parentNew)
{
return objMoveContext(this, parentNew);
return objMove(this, parentNew);
}
// Open session
@ -56,7 +55,7 @@ Destructor
FN_INLINE_ALWAYS void
ioServerFree(IoServer *const this)
{
objFreeContext(this);
objFree(this);
}
/***********************************************************************************************************************************

View File

@ -17,7 +17,7 @@ struct IoSession
/**********************************************************************************************************************************/
FN_EXTERN IoSession *
ioSessionNew(void *driver, const IoSessionInterface *interface)
ioSessionNew(void *const driver, const IoSessionInterface *const interface)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM_P(VOID, driver);
@ -33,17 +33,22 @@ ioSessionNew(void *driver, const IoSessionInterface *interface)
ASSERT(interface->role != NULL);
ASSERT(interface->toLog != NULL);
IoSession *this = memNew(sizeof(IoSession));
IoSession *this;
OBJ_NEW_BEGIN(IoSession, .childQty = MEM_CONTEXT_QTY_MAX)
{
this = OBJ_NEW_ALLOC();
*this = (IoSession)
{
.pub =
{
.memContext = memContextCurrent(),
.driver = driver,
.driver = objMoveToInterface(driver, this, memContextPrior()),
.interface = interface,
},
};
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_SESSION, this);
}
@ -84,7 +89,7 @@ ioSessionPeerNameSet(IoSession *const this, const String *const peerName)
FUNCTION_TEST_PARAM(STRING, peerName); // {vm_covered}
FUNCTION_TEST_END(); // {vm_covered}
MEM_CONTEXT_BEGIN(this->pub.memContext) // {vm_covered}
MEM_CONTEXT_OBJ_BEGIN(this) // {vm_covered}
{
this->pub.peerName = strDup(peerName); // {vm_covered}
}

View File

@ -33,7 +33,6 @@ Getters/Setters
***********************************************************************************************************************************/
typedef struct IoSessionPub
{
MemContext *memContext; // Mem context
void *driver; // Driver object
const IoSessionInterface *interface; // Driver interface
const String *peerName; // Name of peer (exact meaning depends on driver)
@ -102,7 +101,7 @@ ioSessionClose(IoSession *const this)
FN_INLINE_ALWAYS IoSession *
ioSessionMove(IoSession *const this, MemContext *const parentNew)
{
return objMoveContext(this, parentNew);
return objMove(this, parentNew);
}
/***********************************************************************************************************************************
@ -111,7 +110,7 @@ Destructor
FN_INLINE_ALWAYS void
ioSessionFree(IoSession *const this)
{
objFreeContext(this);
objFree(this);
}
/***********************************************************************************************************************************

View File

@ -170,13 +170,13 @@ sckClientNew(const String *const host, const unsigned int port, const TimeMSec t
ASSERT(host != NULL);
IoClient *this = NULL;
SocketClient *this;
OBJ_NEW_BEGIN(SocketClient, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
OBJ_NEW_BEGIN(SocketClient, .childQty = MEM_CONTEXT_QTY_MAX)
{
SocketClient *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoClient::SocketClient);
this = OBJ_NEW_ALLOC();
*driver = (SocketClient)
*this = (SocketClient)
{
.host = strDup(host),
.port = port,
@ -184,12 +184,10 @@ sckClientNew(const String *const host, const unsigned int port, const TimeMSec t
.timeoutConnect = timeoutConnect,
.timeoutSession = timeoutSession,
};
statInc(SOCKET_STAT_CLIENT_STR);
this = ioClientNew(driver, &sckClientInterface);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_CLIENT, this);
statInc(SOCKET_STAT_CLIENT_STR);
FUNCTION_LOG_RETURN(IO_CLIENT, ioClientNew(this, &sckClientInterface));
}

View File

@ -153,13 +153,13 @@ sckServerNew(const String *const address, const unsigned int port, const TimeMSe
ASSERT(address != NULL);
ASSERT(port > 0);
IoServer *this = NULL;
SocketServer *this;
OBJ_NEW_BEGIN(SocketServer, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
OBJ_NEW_BEGIN(SocketServer, .childQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
SocketServer *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoServer::SocketServer);
this = OBJ_NEW_ALLOC();
*driver = (SocketServer)
*this = (SocketServer)
{
.address = strDup(address),
.port = port,
@ -168,27 +168,27 @@ sckServerNew(const String *const address, const unsigned int port, const TimeMSe
};
// Lookup address
struct addrinfo *addressFound = sckHostLookup(driver->address, driver->port);
struct addrinfo *const addressFound = sckHostLookup(this->address, this->port);
TRY_BEGIN()
{
// Create socket
THROW_ON_SYS_ERROR(
(driver->socket = socket(addressFound->ai_family, SOCK_STREAM, 0)) == -1, FileOpenError, "unable to create socket");
(this->socket = socket(addressFound->ai_family, SOCK_STREAM, 0)) == -1, FileOpenError, "unable to create socket");
// Set the address as reusable so we can bind again quickly after a restart or crash
int reuseAddr = 1;
THROW_ON_SYS_ERROR(
setsockopt(driver->socket, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr)) == -1, ProtocolError,
setsockopt(this->socket, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr)) == -1, ProtocolError,
"unable to set SO_REUSEADDR");
// Ensure file descriptor is closed
memContextCallbackSet(objMemContext(driver), sckServerFreeResource, driver);
memContextCallbackSet(objMemContext(this), sckServerFreeResource, this);
// Bind the address
THROW_ON_SYS_ERROR(
bind(driver->socket, addressFound->ai_addr, addressFound->ai_addrlen) == -1, FileOpenError,
bind(this->socket, addressFound->ai_addr, addressFound->ai_addrlen) == -1, FileOpenError,
"unable to bind socket");
}
FINALLY()
@ -198,13 +198,11 @@ sckServerNew(const String *const address, const unsigned int port, const TimeMSe
TRY_END();
// Listen for client connections. It might be a good idea to make the backlog configurable but this value seems OK for now.
THROW_ON_SYS_ERROR(listen(driver->socket, 100) == -1, FileOpenError, "unable to listen on socket");
statInc(SOCKET_STAT_SERVER_STR);
this = ioServerNew(driver, &sckServerInterface);
THROW_ON_SYS_ERROR(listen(this->socket, 100) == -1, FileOpenError, "unable to listen on socket");
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_SERVER, this);
statInc(SOCKET_STAT_SERVER_STR);
FUNCTION_LOG_RETURN(IO_SERVER, ioServerNew(this, &sckServerInterface));
}

View File

@ -164,7 +164,7 @@ static const IoSessionInterface sckSessionInterface =
};
FN_EXTERN IoSession *
sckSessionNew(IoSessionRole role, int fd, const String *host, unsigned int port, TimeMSec timeout)
sckSessionNew(const IoSessionRole role, const int fd, const String *const host, const unsigned int port, const TimeMSec timeout)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STRING_ID, role);
@ -177,15 +177,14 @@ sckSessionNew(IoSessionRole role, int fd, const String *host, unsigned int port,
ASSERT(fd != -1);
ASSERT(host != NULL);
IoSession *this = NULL;
SocketSession *this;
OBJ_NEW_BEGIN(SocketSession, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
OBJ_NEW_BEGIN(SocketSession, .childQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
SocketSession *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoSession::SocketSession);
this = OBJ_NEW_ALLOC();
String *const name = strNewFmt("%s:%u", strZ(host), port);
String *name = strNewFmt("%s:%u", strZ(host), port);
*driver = (SocketSession)
*this = (SocketSession)
{
.role = role,
.fd = fd,
@ -199,11 +198,9 @@ sckSessionNew(IoSessionRole role, int fd, const String *host, unsigned int port,
strFree(name);
// Ensure file descriptor is closed
memContextCallbackSet(objMemContext(driver), sckSessionFreeResource, driver);
this = ioSessionNew(driver, &sckSessionInterface);
memContextCallbackSet(objMemContext(this), sckSessionFreeResource, this);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_SESSION, this);
FUNCTION_LOG_RETURN(IO_SESSION, ioSessionNew(this, &sckSessionInterface));
}

View File

@ -366,13 +366,13 @@ tlsClientNew(
ASSERT(ioClient != NULL);
IoClient *this = NULL;
TlsClient *this;
OBJ_NEW_BEGIN(TlsClient, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
TlsClient *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoClient::TlsClient);
this = OBJ_NEW_ALLOC();
*driver = (TlsClient)
*this = (TlsClient)
{
.ioClient = ioClientMove(ioClient, MEM_CONTEXT_NEW()),
.host = strDup(host),
@ -383,40 +383,36 @@ tlsClientNew(
};
// Set callback to free context
memContextCallbackSet(objMemContext(driver), tlsClientFreeResource, driver);
memContextCallbackSet(objMemContext(this), tlsClientFreeResource, this);
// Enable safe compatibility options
SSL_CTX_set_options(driver->context, SSL_OP_ALL);
SSL_CTX_set_options(this->context, SSL_OP_ALL);
// Set location of CA certificates if the server certificate will be verified
if (driver->verifyPeer)
if (this->verifyPeer)
{
// If the user specified a location
if (param.caFile != NULL || param.caPath != NULL) // {vm_covered}
{
cryptoError( // {vm_covered}
SSL_CTX_load_verify_locations( // {vm_covered}
driver->context, strZNull(param.caFile), strZNull(param.caPath)) != 1, // {vm_covered}
this->context, strZNull(param.caFile), strZNull(param.caPath)) != 1, // {vm_covered}
"unable to set user-defined CA certificate location"); // {vm_covered}
}
// Else use the defaults
else
{
cryptoError(
SSL_CTX_set_default_verify_paths(driver->context) != 1, "unable to set default CA certificate location");
SSL_CTX_set_default_verify_paths(this->context) != 1, "unable to set default CA certificate location");
}
}
// Load certificate and key, if specified
tlsCertKeyLoad(driver->context, param.certFile, param.keyFile);
// Increment stat
statInc(TLS_STAT_CLIENT_STR);
// Create client interface
this = ioClientNew(driver, &tlsClientInterface);
tlsCertKeyLoad(this->context, param.certFile, param.keyFile);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_CLIENT, this);
statInc(TLS_STAT_CLIENT_STR);
FUNCTION_LOG_RETURN(IO_CLIENT, ioClientNew(this, &tlsClientInterface));
}

View File

@ -294,13 +294,13 @@ tlsServerNew(
ASSERT(keyFile != NULL);
ASSERT(certFile != NULL);
IoServer *this = NULL;
TlsServer *this;
OBJ_NEW_BEGIN(TlsServer, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
TlsServer *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoServer::TlsServer);
this = OBJ_NEW_ALLOC();
*driver = (TlsServer)
*this = (TlsServer)
{
.host = strDup(host),
.context = tlsContext(),
@ -308,11 +308,11 @@ tlsServerNew(
};
// Set callback to free context
memContextCallbackSet(objMemContext(driver), tlsServerFreeResource, driver);
memContextCallbackSet(objMemContext(this), tlsServerFreeResource, this);
// Set options
SSL_CTX_set_options(
driver->context,
this->context,
// Disable SSL and TLS v1/v1.1
SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
// Let server set cipher order
@ -326,14 +326,14 @@ tlsServerNew(
SSL_OP_NO_TICKET);
// Disable session caching
SSL_CTX_set_session_cache_mode(driver->context, SSL_SESS_CACHE_OFF);
SSL_CTX_set_session_cache_mode(this->context, SSL_SESS_CACHE_OFF);
// Setup ephemeral DH and ECDH keys
tlsServerDh(driver->context);
tlsServerEcdh(driver->context);
tlsServerDh(this->context);
tlsServerEcdh(this->context);
// Load certificate and key
tlsCertKeyLoad(driver->context, certFile, keyFile);
tlsCertKeyLoad(this->context, certFile, keyFile);
// If a CA store is specified then client certificates will be verified
// -------------------------------------------------------------------------------------------------------------------------
@ -341,7 +341,7 @@ tlsServerNew(
{
// Load CA store
cryptoError( // {vm_covered}
SSL_CTX_load_verify_locations(driver->context, strZ(caFile), NULL) != 1, // {vm_covered}
SSL_CTX_load_verify_locations(this->context, strZ(caFile), NULL) != 1, // {vm_covered}
zNewFmt("unable to load CA file '%s'", strZ(caFile))); // {vm_covered}
// Tell OpenSSL to send the list of root certs we trust to clients in CertificateRequests. This lets a client with a
@ -350,22 +350,20 @@ tlsServerNew(
STACK_OF(X509_NAME) *rootCertList = SSL_load_client_CA_file(strZ(caFile)); // {vm_covered}
cryptoError(rootCertList == NULL, zNewFmt("unable to generate CA list from '%s'", strZ(caFile))); // {vm_covered}
SSL_CTX_set_client_CA_list(driver->context, rootCertList); // {vm_covered}
SSL_CTX_set_client_CA_list(this->context, rootCertList); // {vm_covered}
// Always ask for SSL client cert, but don't fail when not presented. In this case the server will disconnect after
// sending a data end message to the client. The client can use this to verify that the server is running without the
// need to authenticate.
SSL_CTX_set_verify(driver->context, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL); // {vm_covered}
SSL_CTX_set_verify(this->context, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL); // {vm_covered}
// Set a flag so the client cert will be checked later
driver->verifyPeer = true; // {vm_covered}
this->verifyPeer = true; // {vm_covered}
}
statInc(TLS_STAT_SERVER_STR);
this = ioServerNew(driver, &tlsServerInterface);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_SERVER, this);
statInc(TLS_STAT_SERVER_STR);
FUNCTION_LOG_RETURN(IO_SERVER, ioServerNew(this, &tlsServerInterface));
}

View File

@ -350,7 +350,7 @@ static const IoSessionInterface tlsSessionInterface =
};
FN_EXTERN IoSession *
tlsSessionNew(SSL *session, IoSession *ioSession, TimeMSec timeout)
tlsSessionNew(SSL *const session, IoSession *const ioSession, const TimeMSec timeout)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM_P(VOID, session);
@ -361,13 +361,13 @@ tlsSessionNew(SSL *session, IoSession *ioSession, TimeMSec timeout)
ASSERT(session != NULL);
ASSERT(ioSession != NULL);
IoSession *this = NULL;
TlsSession *this;
OBJ_NEW_BEGIN(TlsSession, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
OBJ_NEW_BEGIN(TlsSession, .childQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{
TlsSession *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoSession::TlsSession);
this = OBJ_NEW_ALLOC();
*driver = (TlsSession)
*this = (TlsSession)
{
.session = session,
.ioSession = ioSessionMove(ioSession, MEM_CONTEXT_NEW()),
@ -376,10 +376,10 @@ tlsSessionNew(SSL *session, IoSession *ioSession, TimeMSec timeout)
};
// Ensure session is freed
memContextCallbackSet(objMemContext(driver), tlsSessionFreeResource, driver);
memContextCallbackSet(objMemContext(this), tlsSessionFreeResource, this);
// Assign file descriptor to TLS session
cryptoError(SSL_set_fd(driver->session, ioSessionFd(driver->ioSession)) != 1, "unable to add fd to TLS session");
cryptoError(SSL_set_fd(this->session, ioSessionFd(this->ioSession)) != 1, "unable to add fd to TLS session");
// Negotiate TLS session. The error queue must be cleared before this operation.
int result = 0;
@ -388,22 +388,19 @@ tlsSessionNew(SSL *session, IoSession *ioSession, TimeMSec timeout)
{
ERR_clear_error();
if (ioSessionRole(driver->ioSession) == ioSessionRoleClient)
result = tlsSessionResult(driver, SSL_connect(driver->session), false);
if (ioSessionRole(this->ioSession) == ioSessionRoleClient)
result = tlsSessionResult(this, SSL_connect(this->session), false);
else
result = tlsSessionResult(driver, SSL_accept(driver->session), false);
result = tlsSessionResult(this, SSL_accept(this->session), false);
}
// Create read and write interfaces
driver->write = ioWriteNewP(driver, .write = tlsSessionWrite);
ioWriteOpen(driver->write);
driver->read = ioReadNewP(driver, .block = true, .eof = tlsSessionEof, .read = tlsSessionRead);
ioReadOpen(driver->read);
// Create session interface
this = ioSessionNew(driver, &tlsSessionInterface);
this->write = ioWriteNewP(this, .write = tlsSessionWrite);
ioWriteOpen(this->write);
this->read = ioReadNewP(this, .block = true, .eof = tlsSessionEof, .read = tlsSessionRead);
ioReadOpen(this->read);
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_SESSION, this);
FUNCTION_LOG_RETURN(IO_SESSION, ioSessionNew(this, &tlsSessionInterface));
}

View File

@ -29,7 +29,7 @@ struct IoWrite
/**********************************************************************************************************************************/
FN_EXTERN IoWrite *
ioWriteNew(void *driver, IoWriteInterface interface)
ioWriteNew(void *const driver, const IoWriteInterface interface)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM_P(VOID, driver);
@ -39,7 +39,7 @@ ioWriteNew(void *driver, IoWriteInterface interface)
ASSERT(driver != NULL);
ASSERT(interface.write != NULL);
IoWrite *this = NULL;
IoWrite *this;
OBJ_NEW_BEGIN(IoWrite, .childQty = MEM_CONTEXT_QTY_MAX)
{
@ -49,10 +49,9 @@ ioWriteNew(void *driver, IoWriteInterface interface)
{
.pub =
{
.memContext = memContextCurrent(),
.filterGroup = ioFilterGroupNew(),
},
.driver = driver,
.driver = objMoveToInterface(driver, this, memContextPrior()),
.interface = interface,
.output = bufNew(ioBufferSize()),
};

View File

@ -23,7 +23,6 @@ Getters/Setters
***********************************************************************************************************************************/
typedef struct IoWritePub
{
MemContext *memContext; // Mem context
IoFilterGroup *filterGroup; // IO filters
} IoWritePub;
@ -82,7 +81,7 @@ Destructor
FN_INLINE_ALWAYS void
ioWriteFree(IoWrite *const this)
{
objFreeContext(this);
objFree(this);
}
/***********************************************************************************************************************************

View File

@ -17,12 +17,9 @@ objMove(THIS_VOID, MemContext *parentNew)
/**********************************************************************************************************************************/
FN_EXTERN void *
objMoveContext(THIS_VOID, MemContext *parentNew)
objMoveToInterface(THIS_VOID, void *const interfaceVoid, const MemContext *const current)
{
if (thisVoid != NULL)
memContextMove(*(MemContext **)thisVoid, parentNew);
return thisVoid;
return objMemContext(thisVoid) != current ? objMove(thisVoid, objMemContext(interfaceVoid)) : thisVoid;
}
/**********************************************************************************************************************************/
@ -32,11 +29,3 @@ objFree(THIS_VOID)
if (thisVoid != NULL)
memContextFree(memContextFromAllocExtra(thisVoid));
}
/**********************************************************************************************************************************/
FN_EXTERN void
objFreeContext(THIS_VOID)
{
if (thisVoid != NULL)
memContextFree(*(MemContext **)thisVoid);
}

View File

@ -112,15 +112,13 @@ objMemContext(void *const this)
// Move an object to a new context if this != NULL
FN_EXTERN void *objMove(THIS_VOID, MemContext *parentNew);
// Move an object to a new context if this != NULL. The mem context to move must be the first member of the object struct. This
// pattern is typically used by interfaces.
FN_EXTERN void *objMoveContext(THIS_VOID, MemContext *parentNew);
// Move driver object into an interface object when required. This is the general case, but sometimes an object will expose its
// interfaces in a different way, e.g. methods, so the object retains ownership of the interfaces. If this function is called in the
// driver object context then the driver object will retain ownership of the interface. Otherwise, the interface object will become
// the owner of the driver object.
FN_EXTERN void *objMoveToInterface(THIS_VOID, void *interfaceVoid, const MemContext *current);
// Free the object mem context if this != NULL
FN_EXTERN void objFree(THIS_VOID);
// Free the object mem context if not NULL. The mem context to be freed must be the first member of the object struct. This pattern
// is typically used by interfaces.
FN_EXTERN void objFreeContext(THIS_VOID);
#endif

View File

@ -123,7 +123,7 @@ storageReadAzureNew(
ASSERT(storage != NULL);
ASSERT(name != NULL);
StorageReadAzure *this = NULL;
StorageReadAzure *this;
OBJ_NEW_BEGIN(StorageReadAzure, .childQty = MEM_CONTEXT_QTY_MAX)
{

View File

@ -734,7 +734,7 @@ storageAzureNew(
ASSERT(key != NULL);
ASSERT(blockSize != 0);
StorageAzure *this = NULL;
StorageAzure *this;
OBJ_NEW_BEGIN(StorageAzure, .childQty = MEM_CONTEXT_QTY_MAX)
{

View File

@ -274,7 +274,7 @@ storageWriteAzureNew(StorageAzure *const storage, const String *const name, cons
ASSERT(storage != NULL);
ASSERT(name != NULL);
StorageWriteAzure *this = NULL;
StorageWriteAzure *this;
OBJ_NEW_BEGIN(StorageWriteAzure, .childQty = MEM_CONTEXT_QTY_MAX)
{

View File

@ -130,7 +130,7 @@ storageReadGcsNew(
ASSERT(storage != NULL);
ASSERT(name != NULL);
StorageReadGcs *this = NULL;
StorageReadGcs *this;
OBJ_NEW_BEGIN(StorageReadGcs, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
{

View File

@ -970,7 +970,7 @@ storageGcsNew(
ASSERT(keyType == storageGcsKeyTypeAuto || key != NULL);
ASSERT(chunkSize != 0);
StorageGcs *this = NULL;
StorageGcs *this;
OBJ_NEW_BEGIN(StorageGcs, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
{

View File

@ -332,7 +332,7 @@ storageWriteGcsNew(StorageGcs *const storage, const String *const name, const si
ASSERT(storage != NULL);
ASSERT(name != NULL);
StorageWriteGcs *this = NULL;
StorageWriteGcs *this;
OBJ_NEW_BEGIN(StorageWriteGcs, .childQty = MEM_CONTEXT_QTY_MAX)
{

View File

@ -220,7 +220,7 @@ storageReadPosixNew(
ASSERT(name != NULL);
StorageReadPosix *this = NULL;
StorageReadPosix *this;
OBJ_NEW_BEGIN(StorageReadPosix, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{

View File

@ -612,7 +612,7 @@ storagePosixNewInternal(
userInit();
// Create the object
StoragePosix *this = NULL;
StoragePosix *this;
OBJ_NEW_BEGIN(StoragePosix, .childQty = MEM_CONTEXT_QTY_MAX)
{

View File

@ -245,7 +245,7 @@ storageWritePosixNew(
ASSERT(modeFile != 0);
ASSERT(modePath != 0);
StorageWritePosix *this = NULL;
StorageWritePosix *this;
OBJ_NEW_BEGIN(StorageWritePosix, .childQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{

View File

@ -39,7 +39,7 @@ storageReadNew(void *const driver, const StorageReadInterface *const interface)
ASSERT(driver != NULL);
ASSERT(interface != NULL);
StorageRead *this = NULL;
StorageRead *this;
OBJ_NEW_BEGIN(StorageRead, .childQty = MEM_CONTEXT_QTY_MAX)
{
@ -52,7 +52,7 @@ storageReadNew(void *const driver, const StorageReadInterface *const interface)
.interface = interface,
.io = ioReadNew(driver, interface->ioInterface),
},
.driver = objMove(driver, objMemContext(this)),
.driver = objMoveToInterface(driver, this, memContextPrior()),
};
}
OBJ_NEW_END();

View File

@ -303,7 +303,7 @@ storageReadRemoteNew(
ASSERT(client != NULL);
ASSERT(name != NULL);
StorageReadRemote *this = NULL;
StorageReadRemote *this;
OBJ_NEW_BEGIN(StorageReadRemote, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{

View File

@ -486,8 +486,8 @@ storageRemoteNew(
ASSERT(modePath != 0);
ASSERT(client != NULL);
StorageRemote *this = NULL;
const String *path = NULL;
StorageRemote *this;
const String *path;
OBJ_NEW_BEGIN(StorageRemote, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
{

View File

@ -209,7 +209,7 @@ storageWriteRemoteNew(
ASSERT(modeFile != 0);
ASSERT(modePath != 0);
StorageWriteRemote *this = NULL;
StorageWriteRemote *this;
OBJ_NEW_BEGIN(StorageWriteRemote, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1)
{

View File

@ -126,7 +126,7 @@ storageReadS3New(
ASSERT(name != NULL);
ASSERT(limit == NULL || varUInt64(limit) > 0);
StorageReadS3 *this = NULL;
StorageReadS3 *this;
OBJ_NEW_BEGIN(StorageReadS3, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
{

View File

@ -1130,7 +1130,7 @@ storageS3New(
ASSERT(region != NULL);
ASSERT(partSize != 0);
StorageS3 *this = NULL;
StorageS3 *this;
OBJ_NEW_BEGIN(StorageS3, .childQty = MEM_CONTEXT_QTY_MAX)
{

View File

@ -278,7 +278,7 @@ storageWriteS3New(StorageS3 *const storage, const String *const name, const size
ASSERT(storage != NULL);
ASSERT(name != NULL);
StorageWriteS3 *this = NULL;
StorageWriteS3 *this;
OBJ_NEW_BEGIN(StorageWriteS3, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
{

View File

@ -57,7 +57,7 @@ storageNew(
ASSERT(interface.pathRemove != NULL);
ASSERT(interface.remove != NULL);
Storage *this = NULL;
Storage *this;
OBJ_NEW_BEGIN(Storage, .childQty = MEM_CONTEXT_QTY_MAX)
{
@ -68,7 +68,7 @@ storageNew(
.pub =
{
.type = type,
.driver = objMove(driver, objMemContext(this)),
.driver = objMoveToInterface(driver, this, memContextPrior()),
.interface = interface,
},
.path = strDup(path),

View File

@ -42,7 +42,7 @@ storageWriteNew(void *const driver, const StorageWriteInterface *const interface
ASSERT(driver != NULL);
ASSERT(interface != NULL);
StorageWrite *this = NULL;
StorageWrite *this;
OBJ_NEW_BEGIN(StorageWrite, .childQty = MEM_CONTEXT_QTY_MAX)
{
@ -55,7 +55,7 @@ storageWriteNew(void *const driver, const StorageWriteInterface *const interface
.interface = interface,
.io = ioWriteNew(driver, interface->ioInterface),
},
.driver = objMove(driver, objMemContext(this)),
.driver = objMoveToInterface(driver, this, memContextPrior()),
};
}
OBJ_NEW_END();

View File

@ -15,7 +15,7 @@ Test functions for IoRead that are not covered by testing the IoBufferRead objec
static bool
testIoReadOpen(void *driver)
{
if (driver == (void *)998)
if (strEqZ(driver, "998"))
return false;
return true;
@ -24,7 +24,7 @@ testIoReadOpen(void *driver)
static size_t
testIoRead(void *driver, Buffer *buffer, bool block)
{
ASSERT(driver == (void *)999);
ASSERT(strEqZ(driver, "999"));
(void)block;
bufCat(buffer, BUFSTRDEF("Z"));
@ -37,7 +37,7 @@ static bool testIoReadCloseCalled = false;
static void
testIoReadClose(void *driver)
{
ASSERT(driver == (void *)999);
ASSERT(strEqZ(driver, "999"));
testIoReadCloseCalled = true;
}
@ -49,14 +49,14 @@ static bool testIoWriteOpenCalled = false;
static void
testIoWriteOpen(void *driver)
{
ASSERT(driver == (void *)999);
ASSERT(strEqZ(driver, "999"));
testIoWriteOpenCalled = true;
}
static void
testIoWrite(void *const driver, const Buffer *const buffer)
{
ASSERT(driver == (void *)999);
ASSERT(strEqZ(driver, "999"));
ASSERT(strncmp((const char *)bufPtrConst(buffer), "ABC", bufSize(buffer)) == 0);
}
@ -65,7 +65,7 @@ static bool testIoWriteCloseCalled = false;
static void
testIoWriteClose(void *driver)
{
ASSERT(driver == (void *)999);
ASSERT(strEqZ(driver, "999"));
testIoWriteCloseCalled = true;
}
@ -116,18 +116,16 @@ ioTestFilterSizeResult(THIS_VOID)
static IoFilter *
ioTestFilterSizeNew(const StringId type)
{
IoFilter *this = NULL;
IoTestFilterSize *this;
OBJ_NEW_BEGIN(IoTestFilterSize, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
OBJ_NEW_BEGIN(IoTestFilterSize, .childQty = MEM_CONTEXT_QTY_MAX)
{
IoTestFilterSize *driver = OBJ_NEW_ALLOC();
*driver = (IoTestFilterSize){0};
this = ioFilterNewP(type, driver, NULL, .in = ioTestFilterSizeProcess, .result = ioTestFilterSizeResult);
this = OBJ_NEW_ALLOC();
*this = (IoTestFilterSize){0};
}
OBJ_NEW_END();
return this;
return ioFilterNewP(type, this, NULL, .in = ioTestFilterSizeProcess, .result = ioTestFilterSizeResult);
}
/***********************************************************************************************************************************
@ -221,19 +219,21 @@ ioTestFilterMultiplyInputSame(const THIS_VOID)
static IoFilter *
ioTestFilterMultiplyNew(const StringId type, unsigned int multiplier, unsigned int flushTotal, char flushChar)
{
IoFilter *this = NULL;
IoTestFilterMultiply *this;
OBJ_NEW_BEGIN(IoTestFilterMultiply, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
OBJ_NEW_BEGIN(IoTestFilterMultiply, .childQty = MEM_CONTEXT_QTY_MAX)
{
IoTestFilterMultiply *driver = OBJ_NEW_ALLOC();
this = OBJ_NEW_ALLOC();
*driver = (IoTestFilterMultiply)
*this = (IoTestFilterMultiply)
{
.bufferFilter = ioBufferNew(),
.multiplier = multiplier,
.flushTotal = flushTotal,
.flushChar = flushChar,
};
}
OBJ_NEW_END();
PackWrite *const packWrite = pckWriteNewP();
pckWriteStrIdP(packWrite, type);
@ -241,14 +241,10 @@ ioTestFilterMultiplyNew(const StringId type, unsigned int multiplier, unsigned i
pckWriteU32P(packWrite, flushTotal);
pckWriteEndP(packWrite);
this = ioFilterNewP(
type, driver, pckWriteResult(packWrite), .done = ioTestFilterMultiplyDone, .inOut = ioTestFilterMultiplyProcess,
return ioFilterNewP(
type, this, pckWriteResult(packWrite), .done = ioTestFilterMultiplyDone, .inOut = ioTestFilterMultiplyProcess,
.inputSame = ioTestFilterMultiplyInputSame);
}
OBJ_NEW_END();
return this;
}
/***********************************************************************************************************************************
Test Run
@ -278,13 +274,13 @@ testRun(void)
ioBufferSizeSet(2);
TEST_ASSIGN(
read, ioReadNewP((void *)998, .close = testIoReadClose, .open = testIoReadOpen, .read = testIoRead),
read, ioReadNewP(strNewZ("998"), .close = testIoReadClose, .open = testIoReadOpen, .read = testIoRead),
"create io read object");
TEST_RESULT_BOOL(ioReadOpen(read), false, " open io object");
TEST_ASSIGN(
read, ioReadNewP((void *)999, .close = testIoReadClose, .open = testIoReadOpen, .read = testIoRead),
read, ioReadNewP(strNewZ("999"), .close = testIoReadClose, .open = testIoReadOpen, .read = testIoRead),
"create io read object");
TEST_RESULT_BOOL(ioReadOpen(read), true, " open io object");
@ -523,7 +519,7 @@ testRun(void)
// Cannot open file
TEST_ASSIGN(
read, ioReadNewP((void *)998, .close = testIoReadClose, .open = testIoReadOpen, .read = testIoRead),
read, ioReadNewP(strNewZ("998"), .close = testIoReadClose, .open = testIoReadOpen, .read = testIoRead),
"create io read object");
TEST_RESULT_BOOL(ioReadDrain(read), false, "cannot open");
}
@ -535,7 +531,7 @@ testRun(void)
ioBufferSizeSet(3);
TEST_ASSIGN(
write, ioWriteNewP((void *)999, .close = testIoWriteClose, .open = testIoWriteOpen, .write = testIoWrite),
write, ioWriteNewP(strNewZ("999"), .close = testIoWriteClose, .open = testIoWriteOpen, .write = testIoWrite),
"create io write object");
TEST_RESULT_VOID(ioWriteOpen(write), " open io object");

View File

@ -11,11 +11,6 @@ typedef struct TestObject
bool data; // Test data
} TestObject;
typedef struct TestObjectContext
{
MemContext *memContext; // Mem context
} TestObjectContext;
/***********************************************************************************************************************************
Standard object methods
***********************************************************************************************************************************/
@ -31,25 +26,13 @@ testObjectFree(TestObject *this)
objFree(this);
}
static TestObjectContext *
testObjectContextMove(TestObjectContext *this, MemContext *parentNew)
{
return objMoveContext(this, parentNew);
}
static void
testObjectContextFree(TestObjectContext *this)
{
objFreeContext(this);
}
/**********************************************************************************************************************************/
static TestObject *
testObjectNew(void)
{
TestObject *this = NULL;
OBJ_NEW_BEGIN(TestObject)
OBJ_NEW_BEGIN(TestObject, .childQty = 1)
{
this = OBJ_NEW_ALLOC();
@ -63,26 +46,6 @@ testObjectNew(void)
return this;
}
/**********************************************************************************************************************************/
static TestObjectContext *
testObjectContextNew(void)
{
TestObjectContext *this = NULL;
OBJ_NEW_BEGIN(TestObjectContext)
{
this = OBJ_NEW_ALLOC();
*this = (TestObjectContext)
{
.memContext = MEM_CONTEXT_NEW(),
};
}
OBJ_NEW_END();
return this;
}
/***********************************************************************************************************************************
Test Run
***********************************************************************************************************************************/
@ -94,7 +57,7 @@ testRun(void)
// *****************************************************************************************************************************
if (testBegin("OBJECT_DEFINE*()"))
{
TEST_TITLE("Object with mem context and allocation together");
TEST_TITLE("object with mem context and allocation together");
TestObject *testObject = NULL;
@ -111,20 +74,16 @@ testRun(void)
TEST_RESULT_VOID(testObjectFree(NULL), "free null object");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("Object with mem context as first member of struct");
TEST_TITLE("move object to interface");
TestObjectContext *testObjectContext = NULL;
TestObject *testInterface = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
TEST_ASSIGN(testObjectContext, testObjectContextNew(), "new test object");
TEST_RESULT_VOID(testObjectContextMove(testObjectContext, memContextPrior()), "move object to parent context");
TEST_RESULT_VOID(testObjectContextMove(NULL, memContextPrior()), "move null object");
}
MEM_CONTEXT_TEMP_END();
TEST_ASSIGN(testInterface, testObjectNew(), "new interface object");
TEST_ASSIGN(testObject, testObjectNew(), "new test object");
TEST_RESULT_VOID(testObjectContextFree(testObjectContext), "free object");
TEST_RESULT_VOID(testObjectContextFree(NULL), "free null object");
// Only one of these can success since the interface only accepts one child
TEST_RESULT_VOID(objMoveToInterface(testObject, testInterface, objMemContext(testObject)), "no move to interface");
TEST_RESULT_VOID(objMoveToInterface(testObject, testInterface, memContextCurrent()), "move to interface");
}
FUNCTION_HARNESS_RETURN_VOID();

View File

@ -97,23 +97,21 @@ testIoRateProcess(THIS_VOID, const Buffer *input)
static IoFilter *
testIoRateNew(uint64_t bytesPerSec)
{
IoFilter *this = NULL;
TestIoRate *this;
OBJ_NEW_BEGIN(TestIoRate, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX)
{
TestIoRate *driver = OBJ_NEW_ALLOC();
this = OBJ_NEW_ALLOC();
*driver = (TestIoRate)
*this = (TestIoRate)
{
.memContext = memContextCurrent(),
.bytesPerSec = bytesPerSec,
};
this = ioFilterNewP(STRID5("test-io-rate", 0x2d032dbd3ba4cb40), driver, NULL, .in = testIoRateProcess);
}
OBJ_NEW_END();
return this;
return ioFilterNewP(STRID5("test-io-rate", 0x2d032dbd3ba4cb40), this, NULL, .in = testIoRateProcess);
}
/***********************************************************************************************************************************