1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-01-30 05:39:12 +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 typedef struct BlockIncr
{ {
MemContext *memContext; // Mem context of filter
unsigned int reference; // Current backup reference unsigned int reference; // Current backup reference
uint64_t bundleId; // Bundle id uint64_t bundleId; // Bundle id
@ -390,15 +388,14 @@ blockIncrNew(
FUNCTION_LOG_PARAM(IO_FILTER, encrypt); FUNCTION_LOG_PARAM(IO_FILTER, encrypt);
FUNCTION_LOG_END(); 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, .superBlockSize = (superBlockSize / blockSize + (superBlockSize % blockSize == 0 ? 0 : 1)) * blockSize,
.blockSize = blockSize, .blockSize = blockSize,
.checksumSize = checksumSize, .checksumSize = checksumSize,
@ -413,13 +410,13 @@ blockIncrNew(
// Duplicate compress filter // Duplicate compress filter
if (compress != NULL) if (compress != NULL)
{ {
driver->compressType = ioFilterType(compress); this->compressType = ioFilterType(compress);
driver->compressParam = pckDup(ioFilterParamList(compress)); this->compressParam = pckDup(ioFilterParamList(compress));
} }
// Duplicate encrypt filter // Duplicate encrypt filter
if (encrypt != NULL) if (encrypt != NULL)
driver->encryptParam = pckDup(ioFilterParamList(encrypt)); this->encryptParam = pckDup(ioFilterParamList(encrypt));
// Load prior block map // Load prior block map
if (blockMapPrior) if (blockMapPrior)
@ -430,47 +427,47 @@ blockIncrNew(
MEM_CONTEXT_PRIOR_BEGIN() MEM_CONTEXT_PRIOR_BEGIN()
{ {
driver->blockMapPrior = blockMapNewRead(read, blockSize, checksumSize); this->blockMapPrior = blockMapNewRead(read, blockSize, checksumSize);
} }
MEM_CONTEXT_PRIOR_END(); MEM_CONTEXT_PRIOR_END();
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();
} }
// Create param list
Pack *paramList = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteU64P(packWrite, driver->superBlockSize);
pckWriteU64P(packWrite, blockSize);
pckWriteU64P(packWrite, checksumSize);
pckWriteU32P(packWrite, reference);
pckWriteU64P(packWrite, bundleId);
pckWriteU64P(packWrite, bundleOffset);
pckWriteBinP(packWrite, blockMapPrior);
pckWritePackP(packWrite, driver->compressParam);
if (driver->compressParam != NULL)
pckWriteStrIdP(packWrite, driver->compressType);
pckWritePackP(packWrite, driver->encryptParam);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
this = ioFilterNewP(
BLOCK_INCR_FILTER_TYPE, driver, paramList, .done = blockIncrDone, .inOut = blockIncrProcess,
.inputSame = blockIncrInputSame, .result = blockIncrResult);
} }
OBJ_NEW_END(); OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this); // Create param list
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteU64P(packWrite, this->superBlockSize);
pckWriteU64P(packWrite, blockSize);
pckWriteU64P(packWrite, checksumSize);
pckWriteU32P(packWrite, reference);
pckWriteU64P(packWrite, bundleId);
pckWriteU64P(packWrite, bundleOffset);
pckWriteBinP(packWrite, blockMapPrior);
pckWritePackP(packWrite, this->compressParam);
if (this->compressParam != NULL)
pckWriteStrIdP(packWrite, this->compressType);
pckWritePackP(packWrite, this->encryptParam);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
BLOCK_INCR_FILTER_TYPE, this, paramList, .done = blockIncrDone, .inOut = blockIncrProcess,
.inputSame = blockIncrInputSame, .result = blockIncrResult));
} }
FN_EXTERN IoFilter * FN_EXTERN IoFilter *

View File

@ -19,8 +19,6 @@ Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
typedef struct PageChecksum typedef struct PageChecksum
{ {
MemContext *memContext; // Mem context of filter
unsigned int segmentPageTotal; // Total pages in a segment unsigned int segmentPageTotal; // Total pages in a segment
unsigned int pageNoOffset; // Page number offset for subsequent segments unsigned int pageNoOffset; // Page number offset for subsequent segments
const String *fileName; // Used to load the file to retry pages 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 // Create the error list if it does not exist yet
if (this->error == NULL) if (this->error == NULL)
{ {
MEM_CONTEXT_BEGIN(this->memContext) MEM_CONTEXT_OBJ_BEGIN(this)
{ {
this->error = pckWriteNewP(); this->error = pckWriteNewP();
pckWriteArrayBeginP(this->error); pckWriteArrayBeginP(this->error);
} }
MEM_CONTEXT_END(); MEM_CONTEXT_OBJ_END();
} }
// Add page number and lsn to the error list // Add page number and lsn to the error list
@ -194,7 +192,7 @@ pageChecksumResult(THIS_VOID)
Pack *result = NULL; Pack *result = NULL;
MEM_CONTEXT_BEGIN(this->memContext) MEM_CONTEXT_OBJ_BEGIN(this)
{ {
// End the error array // End the error array
if (this->error != NULL) if (this->error != NULL)
@ -218,7 +216,7 @@ pageChecksumResult(THIS_VOID)
result = pckMove(pckWriteResult(this->error), memContextPrior()); result = pckMove(pckWriteResult(this->error), memContextPrior());
} }
MEM_CONTEXT_END(); MEM_CONTEXT_OBJ_END();
FUNCTION_LOG_RETURN(PACK, result); 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_PARAM(STRING, fileName);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
IoFilter *this = NULL; PageChecksum *this;
OBJ_NEW_BEGIN(PageChecksum, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX) 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, .segmentPageTotal = segmentPageTotal,
.pageNoOffset = segmentNo * segmentPageTotal, .pageNoOffset = segmentNo * segmentPageTotal,
.fileName = strDup(fileName), .fileName = strDup(fileName),
@ -249,28 +246,28 @@ pageChecksumNew(const unsigned int segmentNo, const unsigned int segmentPageTota
.valid = true, .valid = true,
.align = true, .align = true,
}; };
// Create param list
Pack *paramList = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteU32P(packWrite, segmentNo);
pckWriteU32P(packWrite, segmentPageTotal);
pckWriteStrP(packWrite, fileName);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
this = ioFilterNewP(PAGE_CHECKSUM_FILTER_TYPE, driver, paramList, .in = pageChecksumProcess, .result = pageChecksumResult);
} }
OBJ_NEW_END(); OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this); // Create param list
Pack *paramList = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteU32P(packWrite, segmentNo);
pckWriteU32P(packWrite, segmentPageTotal);
pckWriteStrP(packWrite, fileName);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(PAGE_CHECKSUM_FILTER_TYPE, this, paramList, .in = pageChecksumProcess, .result = pageChecksumResult));
} }
FN_EXTERN IoFilter * FN_EXTERN IoFilter *

View File

@ -15,8 +15,6 @@ Object type
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
typedef struct BlockChecksum typedef struct BlockChecksum
{ {
MemContext *memContext; // Mem context of filter
size_t blockSize; // Block size for checksums size_t blockSize; // Block size for checksums
size_t checksumSize; // Checksum size size_t checksumSize; // Checksum size
size_t blockCurrent; // Size of current block size_t blockCurrent; // Size of current block
@ -56,12 +54,12 @@ blockChecksumProcess(THIS_VOID, const Buffer *const input)
// Create checksum object if needed // Create checksum object if needed
if (this->checksum == NULL) if (this->checksum == NULL)
{ {
MEM_CONTEXT_BEGIN(this->memContext) MEM_CONTEXT_OBJ_BEGIN(this)
{ {
this->checksum = xxHashNew(this->checksumSize); this->checksum = xxHashNew(this->checksumSize);
this->blockCurrent = 0; this->blockCurrent = 0;
} }
MEM_CONTEXT_END(); MEM_CONTEXT_OBJ_END();
} }
// Calculate how much data to checksum and perform checksum // Calculate how much data to checksum and perform checksum
@ -136,43 +134,42 @@ blockChecksumNew(const size_t blockSize, const size_t checksumSize)
FUNCTION_LOG_END(); FUNCTION_LOG_END();
ASSERT(blockSize != 0); ASSERT(blockSize != 0);
ASSERT(checksumSize != 0);
// Allocate memory to hold process state // 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, .blockSize = blockSize,
.checksumSize = checksumSize, .checksumSize = checksumSize,
.list = lstNewP(checksumSize), .list = lstNewP(checksumSize),
}; };
// Create param list
Pack *paramList = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteU64P(packWrite, blockSize);
pckWriteU64P(packWrite, checksumSize);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
this = ioFilterNewP(
BLOCK_CHECKSUM_FILTER_TYPE, driver, paramList, .in = blockChecksumProcess, .result = blockChecksumResult);
} }
OBJ_NEW_END(); OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this); // Create param list
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteU64P(packWrite, blockSize);
pckWriteU64P(packWrite, checksumSize);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(BLOCK_CHECKSUM_FILTER_TYPE, this, paramList, .in = blockChecksumProcess, .result = blockChecksumResult));
} }
/**********************************************************************************************************************************/ /**********************************************************************************************************************************/

View File

@ -166,43 +166,42 @@ bz2CompressNew(const int level, const bool raw)
ASSERT(level >= BZ2_COMPRESS_LEVEL_MIN && level <= BZ2_COMPRESS_LEVEL_MAX); 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}, .stream = {.bzalloc = NULL},
}; };
// Initialize context // 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 // Set callback to ensure bz2 stream is freed
memContextCallbackSet(objMemContext(driver), bz2CompressFreeResource, driver); memContextCallbackSet(objMemContext(this), bz2CompressFreeResource, this);
// Create param list
Pack *paramList = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteI32P(packWrite, level);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(
BZ2_COMPRESS_FILTER_TYPE, driver, paramList, .done = bz2CompressDone, .inOut = bz2CompressProcess,
.inputSame = bz2CompressInputSame);
} }
OBJ_NEW_END(); OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this); // Create param list
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteI32P(packWrite, level);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
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 (void)raw; // Raw unsupported
FUNCTION_LOG_END(); 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 this = OBJ_NEW_ALLOC();
Bz2Decompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::Bz2Decompress);
*driver = (Bz2Decompress) *this = (Bz2Decompress)
{ {
.stream = {.bzalloc = NULL}, .stream = {.bzalloc = NULL},
}; };
// Create bz2 stream // 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 // Set free callback to ensure bz2 context is freed
memContextCallbackSet(objMemContext(driver), bz2DecompressFreeResource, driver); memContextCallbackSet(objMemContext(this), bz2DecompressFreeResource, this);
// Create filter interface
this = ioFilterNewP(
BZ2_DECOMPRESS_FILTER_TYPE, driver, NULL, .done = bz2DecompressDone, .inOut = bz2DecompressProcess,
.inputSame = bz2DecompressInputSame);
} }
OBJ_NEW_END(); 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,44 +173,43 @@ gzCompressNew(const int level, const bool raw)
ASSERT(level >= GZ_COMPRESS_LEVEL_MIN && level <= GZ_COMPRESS_LEVEL_MAX); 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}, .stream = {.zalloc = NULL},
}; };
// Create gz stream // 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 // Set free callback to ensure gz context is freed
memContextCallbackSet(objMemContext(driver), gzCompressFreeResource, driver); memContextCallbackSet(objMemContext(this), gzCompressFreeResource, this);
// Create param list
Pack *paramList = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteI32P(packWrite, level);
pckWriteBoolP(packWrite, raw);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(
GZ_COMPRESS_FILTER_TYPE, driver, paramList, .done = gzCompressDone, .inOut = gzCompressProcess,
.inputSame = gzCompressInputSame);
} }
OBJ_NEW_END(); OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this); // Create param list
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteI32P(packWrite, level);
pckWriteBoolP(packWrite, raw);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
GZ_COMPRESS_FILTER_TYPE, this, paramList, .done = gzCompressDone, .inOut = gzCompressProcess,
.inputSame = gzCompressInputSame));
} }

View File

@ -152,44 +152,42 @@ gzDecompressNew(const bool raw)
FUNCTION_LOG_PARAM(BOOL, raw); FUNCTION_LOG_PARAM(BOOL, raw);
FUNCTION_LOG_END(); 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 this = OBJ_NEW_ALLOC();
GzDecompress *const driver = OBJ_NAME(OBJ_NEW_ALLOC(), IoFilter::GzDecompress);
*driver = (GzDecompress) *this = (GzDecompress)
{ {
.stream = {.zalloc = NULL}, .stream = {.zalloc = NULL},
}; };
// Create gz stream // 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 // Set free callback to ensure gz context is freed
memContextCallbackSet(objMemContext(driver), gzDecompressFreeResource, driver); memContextCallbackSet(objMemContext(this), gzDecompressFreeResource, this);
// Create param list
Pack *paramList = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteBoolP(packWrite, raw);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(
GZ_DECOMPRESS_FILTER_TYPE, driver, paramList, .done = gzDecompressDone, .inOut = gzDecompressProcess,
.inputSame = gzDecompressInputSame);
} }
OBJ_NEW_END(); OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this); // Create param list
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteBoolP(packWrite, raw);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
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); 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 = .prefs =
{ {
@ -270,34 +270,33 @@ lz4CompressNew(const int level, const bool raw)
}; };
// Create lz4 context // 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 // Set callback to ensure lz4 context is freed
memContextCallbackSet(objMemContext(driver), lz4CompressFreeResource, driver); memContextCallbackSet(objMemContext(this), lz4CompressFreeResource, this);
// Create param list
Pack *paramList = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteI32P(packWrite, level);
pckWriteBoolP(packWrite, raw);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(
LZ4_COMPRESS_FILTER_TYPE, driver, paramList, .done = lz4CompressDone, .inOut = lz4CompressProcess,
.inputSame = lz4CompressInputSame);
} }
OBJ_NEW_END(); OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this); // Create param list
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteI32P(packWrite, level);
pckWriteBoolP(packWrite, raw);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
LZ4_COMPRESS_FILTER_TYPE, this, paramList, .done = lz4CompressDone, .inOut = lz4CompressProcess,
.inputSame = lz4CompressInputSame));
} }
#endif // HAVE_LIBLZ4 #endif // HAVE_LIBLZ4

View File

@ -163,27 +163,26 @@ lz4DecompressNew(const bool raw)
(void)raw; // Not required for decompress (void)raw; // Not required for decompress
FUNCTION_LOG_END(); 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); this = OBJ_NEW_ALLOC();
*driver = (Lz4Decompress){0}; *this = (Lz4Decompress){0};
// Create lz4 context // 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 // Set callback to ensure lz4 context is freed
memContextCallbackSet(objMemContext(driver), lz4DecompressFreeResource, driver); memContextCallbackSet(objMemContext(this), lz4DecompressFreeResource, this);
// Create filter interface
this = ioFilterNewP(
LZ4_DECOMPRESS_FILTER_TYPE, driver, NULL, .done = lz4DecompressDone, .inOut = lz4DecompressProcess,
.inputSame = lz4DecompressInputSame);
} }
OBJ_NEW_END(); 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 #endif // HAVE_LIBLZ4

View File

@ -173,46 +173,45 @@ zstCompressNew(const int level, const bool raw)
ASSERT(level >= ZST_COMPRESS_LEVEL_MIN && level <= ZST_COMPRESS_LEVEL_MAX); 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) 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(), .context = ZSTD_createCStream(),
.level = level, .level = level,
}; };
// Set callback to ensure zst context is freed // Set callback to ensure zst context is freed
memContextCallbackSet(objMemContext(driver), zstCompressFreeResource, driver); memContextCallbackSet(objMemContext(this), zstCompressFreeResource, this);
// Initialize context // Initialize context
zstError(ZSTD_initCStream(driver->context, driver->level)); zstError(ZSTD_initCStream(this->context, this->level));
// Create param list
Pack *paramList = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteI32P(packWrite, level);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(
ZST_COMPRESS_FILTER_TYPE, driver, paramList, .done = zstCompressDone, .inOut = zstCompressProcess,
.inputSame = zstCompressInputSame);
} }
OBJ_NEW_END(); OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this); // Create param list
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteI32P(packWrite, level);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
ZST_COMPRESS_FILTER_TYPE, this, paramList, .done = zstCompressDone, .inOut = zstCompressProcess,
.inputSame = zstCompressInputSame));
} }
#endif // HAVE_LIBZST #endif // HAVE_LIBZST

View File

@ -162,31 +162,30 @@ zstDecompressNew(const bool raw)
(void)raw; // Raw unsupported (void)raw; // Raw unsupported
FUNCTION_LOG_END(); 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(), .context = ZSTD_createDStream(),
}; };
// Set callback to ensure zst context is freed // Set callback to ensure zst context is freed
memContextCallbackSet(objMemContext(driver), zstDecompressFreeResource, driver); memContextCallbackSet(objMemContext(this), zstDecompressFreeResource, this);
// Initialize context // Initialize context
zstError(ZSTD_initDStream(driver->context)); zstError(ZSTD_initDStream(this->context));
// Create filter interface
this = ioFilterNewP(
ZST_DECOMPRESS_FILTER_TYPE, driver, NULL, .done = zstDecompressDone, .inOut = zstDecompressProcess,
.inputSame = zstDecompressInputSame);
} }
OBJ_NEW_END(); 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 #endif // HAVE_LIBZST

View File

@ -386,7 +386,7 @@ cipherBlockInputSame(const THIS_VOID)
/**********************************************************************************************************************************/ /**********************************************************************************************************************************/
FN_EXTERN IoFilter * 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_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING_ID, mode); 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)); THROW_FMT(AssertError, "unable to load digest '%s'", strZ(param.digest));
// Allocate memory to hold process state // 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) 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, .mode = mode,
.raw = param.raw, .raw = param.raw,
@ -440,35 +440,34 @@ cipherBlockNew(CipherMode mode, CipherType cipherType, const Buffer *pass, Ciphe
}; };
// Store the passphrase // Store the passphrase
driver->pass = memNew(driver->passSize); this->pass = memNew(this->passSize);
memcpy(driver->pass, bufPtrConst(pass), driver->passSize); memcpy(this->pass, bufPtrConst(pass), this->passSize);
// Create param list
Pack *paramList = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteU64P(packWrite, mode);
pckWriteU64P(packWrite, cipherType);
pckWriteBinP(packWrite, pass);
pckWriteStrP(packWrite, param.digest);
pckWriteBoolP(packWrite, param.raw);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(
CIPHER_BLOCK_FILTER_TYPE, driver, paramList, .done = cipherBlockDone, .inOut = cipherBlockProcess,
.inputSame = cipherBlockInputSame);
} }
OBJ_NEW_END(); OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this); // Create param list
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteU64P(packWrite, mode);
pckWriteU64P(packWrite, cipherType);
pckWriteBinP(packWrite, pass);
pckWriteStrP(packWrite, param.digest);
pckWriteBoolP(packWrite, param.raw);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
FUNCTION_LOG_RETURN(
IO_FILTER,
ioFilterNewP(
CIPHER_BLOCK_FILTER_TYPE, this, paramList, .done = cipherBlockDone, .inOut = cipherBlockProcess,
.inputSame = cipherBlockInputSame));
} }
FN_EXTERN IoFilter * FN_EXTERN IoFilter *

View File

@ -180,21 +180,21 @@ cryptoHashNew(const HashType type)
cryptoInit(); cryptoInit();
// Allocate memory to hold process state // 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) 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); this = OBJ_NEW_ALLOC();
*driver = (CryptoHash){0}; *this = (CryptoHash){0};
// Use local MD5 implementation since FIPS-enabled systems do not allow MD5. This is a bit misguided since there are valid // 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 // 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. // MD5 for verifying payload integrity we are simply forced to provide MD5 functionality.
if (type == hashTypeMd5) 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 use the standard OpenSSL implementation
else else
@ -203,39 +203,37 @@ cryptoHashNew(const HashType type)
char typeZ[STRID_MAX + 1]; char typeZ[STRID_MAX + 1];
strIdToZ(type, typeZ); 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); THROW_FMT(AssertError, "unable to load hash '%s'", typeZ);
// Create context // 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 // Set free callback to ensure hash context is freed
memContextCallbackSet(objMemContext(driver), cryptoHashFreeResource, driver); memContextCallbackSet(objMemContext(this), cryptoHashFreeResource, this);
// Initialize context // 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");
} }
// Create param list
Pack *paramList = NULL;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteStrIdP(packWrite, type);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
// Create filter interface
this = ioFilterNewP(CRYPTO_HASH_FILTER_TYPE, driver, paramList, .in = cryptoHashProcess, .result = cryptoHashResult);
} }
OBJ_NEW_END(); OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this); // Create param list
Pack *paramList;
MEM_CONTEXT_TEMP_BEGIN()
{
PackWrite *const packWrite = pckWriteNewP();
pckWriteStrIdP(packWrite, type);
pckWriteEndP(packWrite);
paramList = pckMove(pckWriteResult(packWrite), memContextPrior());
}
MEM_CONTEXT_TEMP_END();
FUNCTION_LOG_RETURN(
IO_FILTER, ioFilterNewP(CRYPTO_HASH_FILTER_TYPE, this, paramList, .in = cryptoHashProcess, .result = cryptoHashResult));
} }
FN_EXTERN IoFilter * FN_EXTERN IoFilter *

View File

@ -117,25 +117,22 @@ xxHashNew(const size_t size)
ASSERT(size >= 1 && size <= XX_HASH_SIZE_MAX); ASSERT(size >= 1 && size <= XX_HASH_SIZE_MAX);
// Allocate memory to hold process state // 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); this = OBJ_NEW_ALLOC();
*driver = (XxHash){.size = size}; *this = (XxHash){.size = size};
driver->state = XXH3_createState(); this->state = XXH3_createState();
XXH3_128bits_reset(driver->state); XXH3_128bits_reset(this->state);
// Set free callback to ensure hash context is freed // Set free callback to ensure hash context is freed
memContextCallbackSet(objMemContext(driver), xxHashFreeResource, driver); memContextCallbackSet(objMemContext(this), xxHashFreeResource, this);
// Create filter interface
this = ioFilterNewP(XX_HASH_FILTER_TYPE, driver, NULL, .in = xxHashProcess, .result = xxHashResult);
} }
OBJ_NEW_END(); 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 * FN_EXTERN IoRead *
ioBufferReadNew(const Buffer *buffer) ioBufferReadNew(const Buffer *const buffer)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(BUFFER, buffer); FUNCTION_LOG_PARAM(BUFFER, buffer);
@ -92,20 +92,18 @@ ioBufferReadNew(const Buffer *buffer)
ASSERT(buffer != NULL); 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, .read = buffer,
}; };
this = ioReadNewP(driver, .eof = ioBufferReadEof, .read = ioBufferRead);
} }
OBJ_NEW_END(); 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 * FN_EXTERN IoWrite *
ioBufferWriteNew(Buffer *buffer) ioBufferWriteNew(Buffer *const buffer)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(BUFFER, buffer); FUNCTION_LOG_PARAM(BUFFER, buffer);
@ -56,20 +56,18 @@ ioBufferWriteNew(Buffer *buffer)
ASSERT(buffer != NULL); 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, .write = buffer,
}; };
this = ioWriteNewP(driver, .write = ioBufferWrite);
} }
OBJ_NEW_END(); 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); 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, .read = read,
}; };
this = ioReadNewP(driver, .eof = ioChunkedReadEof, .open = ioChunkedReadOpen, .read = ioChunkedRead);
} }
OBJ_NEW_END(); 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 * FN_EXTERN IoClient *
ioClientNew(void *driver, const IoClientInterface *interface) ioClientNew(void *const driver, const IoClientInterface *const interface)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM_P(VOID, driver); FUNCTION_LOG_PARAM_P(VOID, driver);
@ -31,17 +31,22 @@ ioClientNew(void *driver, const IoClientInterface *interface)
ASSERT(interface->open != NULL); ASSERT(interface->open != NULL);
ASSERT(interface->toLog != NULL); ASSERT(interface->toLog != NULL);
IoClient *this = memNew(sizeof(IoClient)); IoClient *this;
*this = (IoClient) OBJ_NEW_BEGIN(IoClient, .childQty = MEM_CONTEXT_QTY_MAX)
{ {
.pub = this = OBJ_NEW_ALLOC();
*this = (IoClient)
{ {
.memContext = memContextCurrent(), .pub =
.driver = driver, {
.interface = interface, .driver = objMoveToInterface(driver, this, memContextPrior()),
}, .interface = interface,
}; },
};
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_CLIENT, this); FUNCTION_LOG_RETURN(IO_CLIENT, this);
} }

View File

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

View File

@ -144,7 +144,7 @@ ioFdReadFd(const THIS_VOID)
/**********************************************************************************************************************************/ /**********************************************************************************************************************************/
FN_EXTERN IoRead * 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_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, name); FUNCTION_LOG_PARAM(STRING, name);
@ -154,22 +154,21 @@ ioFdReadNew(const String *name, int fd, TimeMSec timeout)
ASSERT(fd != -1); 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), .name = strDup(name),
.fd = fd, .fd = fd,
.timeout = timeout, .timeout = timeout,
}; };
this = ioReadNewP(driver, .block = true, .eof = ioFdReadEof, .fd = ioFdReadFd, .read = ioFdRead, .ready = ioFdReadReady);
} }
OBJ_NEW_END(); 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 * 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_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, name); 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_PARAM(TIME_MSEC, timeout);
FUNCTION_LOG_END(); 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), .name = strDup(name),
.fd = fd, .fd = fd,
.timeout = timeout, .timeout = timeout,
}; };
this = ioWriteNewP(driver, .fd = ioFdWriteFd, .ready = ioFdWriteReady, .write = ioFdWrite);
} }
OBJ_NEW_END(); 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); 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); this = OBJ_NEW_ALLOC();
*driver = (IoBuffer){0}; *this = (IoBuffer){0};
this = ioFilterNewP(BUFFER_FILTER_TYPE, driver, NULL, .inOut = ioBufferProcess, .inputSame = ioBufferInputSame);
} }
OBJ_NEW_END(); 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 typedef struct IoChunk
{ {
MemContext *memContext; // Mem context of filter
const uint8_t *buffer; // Internal buffer const uint8_t *buffer; // Internal buffer
size_t bufferSize; // Buffer size size_t bufferSize; // Buffer size
size_t bufferOffset; // Buffer offset size_t bufferOffset; // Buffer offset
@ -151,22 +149,16 @@ ioChunkNew(void)
{ {
FUNCTION_LOG_VOID(logLevelTrace); 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); this = OBJ_NEW_ALLOC();
*this = (IoChunk){0};
*driver = (IoChunk)
{
.memContext = memContextCurrent(),
};
this = ioFilterNewP(
CHUNK_FILTER_TYPE, driver, NULL, .done = ioChunkDone, .inOut = ioChunkProcess,
.inputSame = ioChunkInputSame);
} }
OBJ_NEW_END(); 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 // 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)); ASSERT(interface.in == NULL || (interface.result != NULL && interface.done == NULL && interface.inputSame == NULL));
IoFilter *this = memNew(sizeof(IoFilter)); IoFilter *this;
*this = (IoFilter) OBJ_NEW_BEGIN(IoFilter, .childQty = MEM_CONTEXT_QTY_MAX)
{ {
.pub = this = OBJ_NEW_ALLOC();
*this = (IoFilter)
{ {
.memContext = memContextCurrent(), .pub =
.type = type, {
.driver = driver, .type = type,
.paramList = paramList, .driver = objMoveToInterface(driver, this, memContextPrior()),
.interface = interface, .paramList = pckMove(paramList, objMemContext(this)),
}, .interface = interface,
}; },
};
}
OBJ_NEW_END();
FUNCTION_LOG_RETURN(IO_FILTER, this); FUNCTION_LOG_RETURN(IO_FILTER, this);
} }

View File

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

View File

@ -61,7 +61,6 @@ Getters/Setters
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
typedef struct IoFilterPub typedef struct IoFilterPub
{ {
MemContext *memContext; // Mem context
StringId type; // Filter type StringId type; // Filter type
IoFilterInterface interface; // Filter interface IoFilterInterface interface; // Filter interface
void *driver; // Filter driver 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 // Move filter to a new parent mem context
FN_INLINE_ALWAYS IoFilter * 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); 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 = OBJ_NEW_ALLOC();
this = ioFilterNewP(SINK_FILTER_TYPE, driver, NULL, .inOut = ioSinkProcess);
} }
OBJ_NEW_END(); 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 typedef struct IoSize
{ {
uint64_t size; // Total size of al input uint64_t size; // Total size of all input
} IoSize; } IoSize;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -91,16 +91,14 @@ ioSizeNew(void)
{ {
FUNCTION_LOG_VOID(logLevelTrace); 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); this = OBJ_NEW_ALLOC();
*driver = (IoSize){0}; *this = (IoSize){0};
this = ioFilterNewP(SIZE_FILTER_TYPE, driver, NULL, .in = ioSizeProcess, .result = ioSizeResult);
} }
OBJ_NEW_END(); 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 * FN_EXTERN IoRead *
ioReadNew(void *driver, IoReadInterface interface) ioReadNew(void *const driver, const IoReadInterface interface)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM_P(VOID, driver); FUNCTION_LOG_PARAM_P(VOID, driver);
@ -43,8 +43,7 @@ ioReadNew(void *driver, IoReadInterface interface)
{ {
.pub = .pub =
{ {
.memContext = memContextCurrent(), .driver = objMoveToInterface(driver, this, memContextPrior()),
.driver = driver,
.interface = interface, .interface = interface,
.filterGroup = ioFilterGroupNew(), .filterGroup = ioFilterGroupNew(),
}, },
@ -217,11 +216,11 @@ ioReadSmall(IoRead *this, Buffer *buffer)
// Allocate the internal output buffer if it has not already been allocated // Allocate the internal output buffer if it has not already been allocated
if (this->output == NULL) if (this->output == NULL)
{ {
MEM_CONTEXT_BEGIN(this->pub.memContext) MEM_CONTEXT_OBJ_BEGIN(this)
{ {
this->output = bufNew(ioBufferSize()); 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 // 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. // is not always used.
if (this->output == NULL) if (this->output == NULL)
{ {
MEM_CONTEXT_BEGIN(this->pub.memContext) MEM_CONTEXT_OBJ_BEGIN(this)
{ {
this->output = bufNew(ioBufferSize()); this->output = bufNew(ioBufferSize());
} }
MEM_CONTEXT_END(); MEM_CONTEXT_OBJ_END();
} }
// Search for a linefeed // Search for a linefeed
@ -366,11 +365,11 @@ ioReadVarIntU64(IoRead *const this)
// Allocate the internal output buffer if it has not already been allocated // Allocate the internal output buffer if it has not already been allocated
if (this->output == NULL) if (this->output == NULL)
{ {
MEM_CONTEXT_BEGIN(this->pub.memContext) MEM_CONTEXT_OBJ_BEGIN(this)
{ {
this->output = bufNew(ioBufferSize()); this->output = bufNew(ioBufferSize());
} }
MEM_CONTEXT_END(); MEM_CONTEXT_OBJ_END();
} }
uint64_t result = 0; uint64_t result = 0;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -33,7 +33,6 @@ Getters/Setters
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
typedef struct IoSessionPub typedef struct IoSessionPub
{ {
MemContext *memContext; // Mem context
void *driver; // Driver object void *driver; // Driver object
const IoSessionInterface *interface; // Driver interface const IoSessionInterface *interface; // Driver interface
const String *peerName; // Name of peer (exact meaning depends on driver) const String *peerName; // Name of peer (exact meaning depends on driver)
@ -102,7 +101,7 @@ ioSessionClose(IoSession *const this)
FN_INLINE_ALWAYS IoSession * FN_INLINE_ALWAYS IoSession *
ioSessionMove(IoSession *const this, MemContext *const parentNew) ioSessionMove(IoSession *const this, MemContext *const parentNew)
{ {
return objMoveContext(this, parentNew); return objMove(this, parentNew);
} }
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -111,7 +110,7 @@ Destructor
FN_INLINE_ALWAYS void FN_INLINE_ALWAYS void
ioSessionFree(IoSession *const this) 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); 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), .host = strDup(host),
.port = port, .port = port,
@ -184,12 +184,10 @@ sckClientNew(const String *const host, const unsigned int port, const TimeMSec t
.timeoutConnect = timeoutConnect, .timeoutConnect = timeoutConnect,
.timeoutSession = timeoutSession, .timeoutSession = timeoutSession,
}; };
statInc(SOCKET_STAT_CLIENT_STR);
this = ioClientNew(driver, &sckClientInterface);
} }
OBJ_NEW_END(); 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(address != NULL);
ASSERT(port > 0); 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), .address = strDup(address),
.port = port, .port = port,
@ -168,27 +168,27 @@ sckServerNew(const String *const address, const unsigned int port, const TimeMSe
}; };
// Lookup address // Lookup address
struct addrinfo *addressFound = sckHostLookup(driver->address, driver->port); struct addrinfo *const addressFound = sckHostLookup(this->address, this->port);
TRY_BEGIN() TRY_BEGIN()
{ {
// Create socket // Create socket
THROW_ON_SYS_ERROR( 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 // Set the address as reusable so we can bind again quickly after a restart or crash
int reuseAddr = 1; int reuseAddr = 1;
THROW_ON_SYS_ERROR( 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"); "unable to set SO_REUSEADDR");
// Ensure file descriptor is closed // Ensure file descriptor is closed
memContextCallbackSet(objMemContext(driver), sckServerFreeResource, driver); memContextCallbackSet(objMemContext(this), sckServerFreeResource, this);
// Bind the address // Bind the address
THROW_ON_SYS_ERROR( 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"); "unable to bind socket");
} }
FINALLY() FINALLY()
@ -198,13 +198,11 @@ sckServerNew(const String *const address, const unsigned int port, const TimeMSe
TRY_END(); TRY_END();
// Listen for client connections. It might be a good idea to make the backlog configurable but this value seems OK for now. // 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"); THROW_ON_SYS_ERROR(listen(this->socket, 100) == -1, FileOpenError, "unable to listen on socket");
statInc(SOCKET_STAT_SERVER_STR);
this = ioServerNew(driver, &sckServerInterface);
} }
OBJ_NEW_END(); 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 * 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_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STRING_ID, role); 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(fd != -1);
ASSERT(host != NULL); 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); *this = (SocketSession)
*driver = (SocketSession)
{ {
.role = role, .role = role,
.fd = fd, .fd = fd,
@ -199,11 +198,9 @@ sckSessionNew(IoSessionRole role, int fd, const String *host, unsigned int port,
strFree(name); strFree(name);
// Ensure file descriptor is closed // Ensure file descriptor is closed
memContextCallbackSet(objMemContext(driver), sckSessionFreeResource, driver); memContextCallbackSet(objMemContext(this), sckSessionFreeResource, this);
this = ioSessionNew(driver, &sckSessionInterface);
} }
OBJ_NEW_END(); 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); ASSERT(ioClient != NULL);
IoClient *this = NULL; TlsClient *this;
OBJ_NEW_BEGIN(TlsClient, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1) 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()), .ioClient = ioClientMove(ioClient, MEM_CONTEXT_NEW()),
.host = strDup(host), .host = strDup(host),
@ -383,40 +383,36 @@ tlsClientNew(
}; };
// Set callback to free context // Set callback to free context
memContextCallbackSet(objMemContext(driver), tlsClientFreeResource, driver); memContextCallbackSet(objMemContext(this), tlsClientFreeResource, this);
// Enable safe compatibility options // 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 // 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 the user specified a location
if (param.caFile != NULL || param.caPath != NULL) // {vm_covered} if (param.caFile != NULL || param.caPath != NULL) // {vm_covered}
{ {
cryptoError( // {vm_covered} cryptoError( // {vm_covered}
SSL_CTX_load_verify_locations( // {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} "unable to set user-defined CA certificate location"); // {vm_covered}
} }
// Else use the defaults // Else use the defaults
else else
{ {
cryptoError( 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 // Load certificate and key, if specified
tlsCertKeyLoad(driver->context, param.certFile, param.keyFile); tlsCertKeyLoad(this->context, param.certFile, param.keyFile);
// Increment stat
statInc(TLS_STAT_CLIENT_STR);
// Create client interface
this = ioClientNew(driver, &tlsClientInterface);
} }
OBJ_NEW_END(); 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(keyFile != NULL);
ASSERT(certFile != 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) 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), .host = strDup(host),
.context = tlsContext(), .context = tlsContext(),
@ -308,11 +308,11 @@ tlsServerNew(
}; };
// Set callback to free context // Set callback to free context
memContextCallbackSet(objMemContext(driver), tlsServerFreeResource, driver); memContextCallbackSet(objMemContext(this), tlsServerFreeResource, this);
// Set options // Set options
SSL_CTX_set_options( SSL_CTX_set_options(
driver->context, this->context,
// Disable SSL and TLS v1/v1.1 // Disable SSL and TLS v1/v1.1
SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
// Let server set cipher order // Let server set cipher order
@ -326,14 +326,14 @@ tlsServerNew(
SSL_OP_NO_TICKET); SSL_OP_NO_TICKET);
// Disable session caching // 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 // Setup ephemeral DH and ECDH keys
tlsServerDh(driver->context); tlsServerDh(this->context);
tlsServerEcdh(driver->context); tlsServerEcdh(this->context);
// Load certificate and key // 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 // If a CA store is specified then client certificates will be verified
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
@ -341,7 +341,7 @@ tlsServerNew(
{ {
// Load CA store // Load CA store
cryptoError( // {vm_covered} 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} 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 // 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} 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} 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 // 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 // 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. // 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 // 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(); 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 * 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_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM_P(VOID, session); FUNCTION_LOG_PARAM_P(VOID, session);
@ -361,13 +361,13 @@ tlsSessionNew(SSL *session, IoSession *ioSession, TimeMSec timeout)
ASSERT(session != NULL); ASSERT(session != NULL);
ASSERT(ioSession != 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, .session = session,
.ioSession = ioSessionMove(ioSession, MEM_CONTEXT_NEW()), .ioSession = ioSessionMove(ioSession, MEM_CONTEXT_NEW()),
@ -376,10 +376,10 @@ tlsSessionNew(SSL *session, IoSession *ioSession, TimeMSec timeout)
}; };
// Ensure session is freed // Ensure session is freed
memContextCallbackSet(objMemContext(driver), tlsSessionFreeResource, driver); memContextCallbackSet(objMemContext(this), tlsSessionFreeResource, this);
// Assign file descriptor to TLS session // 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. // Negotiate TLS session. The error queue must be cleared before this operation.
int result = 0; int result = 0;
@ -388,22 +388,19 @@ tlsSessionNew(SSL *session, IoSession *ioSession, TimeMSec timeout)
{ {
ERR_clear_error(); ERR_clear_error();
if (ioSessionRole(driver->ioSession) == ioSessionRoleClient) if (ioSessionRole(this->ioSession) == ioSessionRoleClient)
result = tlsSessionResult(driver, SSL_connect(driver->session), false); result = tlsSessionResult(this, SSL_connect(this->session), false);
else else
result = tlsSessionResult(driver, SSL_accept(driver->session), false); result = tlsSessionResult(this, SSL_accept(this->session), false);
} }
// Create read and write interfaces // Create read and write interfaces
driver->write = ioWriteNewP(driver, .write = tlsSessionWrite); this->write = ioWriteNewP(this, .write = tlsSessionWrite);
ioWriteOpen(driver->write); ioWriteOpen(this->write);
driver->read = ioReadNewP(driver, .block = true, .eof = tlsSessionEof, .read = tlsSessionRead); this->read = ioReadNewP(this, .block = true, .eof = tlsSessionEof, .read = tlsSessionRead);
ioReadOpen(driver->read); ioReadOpen(this->read);
// Create session interface
this = ioSessionNew(driver, &tlsSessionInterface);
} }
OBJ_NEW_END(); 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 * FN_EXTERN IoWrite *
ioWriteNew(void *driver, IoWriteInterface interface) ioWriteNew(void *const driver, const IoWriteInterface interface)
{ {
FUNCTION_LOG_BEGIN(logLevelTrace); FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM_P(VOID, driver); FUNCTION_LOG_PARAM_P(VOID, driver);
@ -39,7 +39,7 @@ ioWriteNew(void *driver, IoWriteInterface interface)
ASSERT(driver != NULL); ASSERT(driver != NULL);
ASSERT(interface.write != NULL); ASSERT(interface.write != NULL);
IoWrite *this = NULL; IoWrite *this;
OBJ_NEW_BEGIN(IoWrite, .childQty = MEM_CONTEXT_QTY_MAX) OBJ_NEW_BEGIN(IoWrite, .childQty = MEM_CONTEXT_QTY_MAX)
{ {
@ -49,10 +49,9 @@ ioWriteNew(void *driver, IoWriteInterface interface)
{ {
.pub = .pub =
{ {
.memContext = memContextCurrent(),
.filterGroup = ioFilterGroupNew(), .filterGroup = ioFilterGroupNew(),
}, },
.driver = driver, .driver = objMoveToInterface(driver, this, memContextPrior()),
.interface = interface, .interface = interface,
.output = bufNew(ioBufferSize()), .output = bufNew(ioBufferSize()),
}; };

View File

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

View File

@ -17,12 +17,9 @@ objMove(THIS_VOID, MemContext *parentNew)
/**********************************************************************************************************************************/ /**********************************************************************************************************************************/
FN_EXTERN void * FN_EXTERN void *
objMoveContext(THIS_VOID, MemContext *parentNew) objMoveToInterface(THIS_VOID, void *const interfaceVoid, const MemContext *const current)
{ {
if (thisVoid != NULL) return objMemContext(thisVoid) != current ? objMove(thisVoid, objMemContext(interfaceVoid)) : thisVoid;
memContextMove(*(MemContext **)thisVoid, parentNew);
return thisVoid;
} }
/**********************************************************************************************************************************/ /**********************************************************************************************************************************/
@ -32,11 +29,3 @@ objFree(THIS_VOID)
if (thisVoid != NULL) if (thisVoid != NULL)
memContextFree(memContextFromAllocExtra(thisVoid)); 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 // Move an object to a new context if this != NULL
FN_EXTERN void *objMove(THIS_VOID, MemContext *parentNew); 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 // Move driver object into an interface object when required. This is the general case, but sometimes an object will expose its
// pattern is typically used by interfaces. // interfaces in a different way, e.g. methods, so the object retains ownership of the interfaces. If this function is called in the
FN_EXTERN void *objMoveContext(THIS_VOID, MemContext *parentNew); // 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 // Free the object mem context if this != NULL
FN_EXTERN void objFree(THIS_VOID); 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 #endif

View File

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

View File

@ -734,7 +734,7 @@ storageAzureNew(
ASSERT(key != NULL); ASSERT(key != NULL);
ASSERT(blockSize != 0); ASSERT(blockSize != 0);
StorageAzure *this = NULL; StorageAzure *this;
OBJ_NEW_BEGIN(StorageAzure, .childQty = MEM_CONTEXT_QTY_MAX) 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(storage != NULL);
ASSERT(name != NULL); ASSERT(name != NULL);
StorageWriteAzure *this = NULL; StorageWriteAzure *this;
OBJ_NEW_BEGIN(StorageWriteAzure, .childQty = MEM_CONTEXT_QTY_MAX) OBJ_NEW_BEGIN(StorageWriteAzure, .childQty = MEM_CONTEXT_QTY_MAX)
{ {

View File

@ -130,7 +130,7 @@ storageReadGcsNew(
ASSERT(storage != NULL); ASSERT(storage != NULL);
ASSERT(name != NULL); ASSERT(name != NULL);
StorageReadGcs *this = NULL; StorageReadGcs *this;
OBJ_NEW_BEGIN(StorageReadGcs, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX) 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(keyType == storageGcsKeyTypeAuto || key != NULL);
ASSERT(chunkSize != 0); ASSERT(chunkSize != 0);
StorageGcs *this = NULL; StorageGcs *this;
OBJ_NEW_BEGIN(StorageGcs, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX) 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(storage != NULL);
ASSERT(name != NULL); ASSERT(name != NULL);
StorageWriteGcs *this = NULL; StorageWriteGcs *this;
OBJ_NEW_BEGIN(StorageWriteGcs, .childQty = MEM_CONTEXT_QTY_MAX) OBJ_NEW_BEGIN(StorageWriteGcs, .childQty = MEM_CONTEXT_QTY_MAX)
{ {

View File

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

View File

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

View File

@ -245,7 +245,7 @@ storageWritePosixNew(
ASSERT(modeFile != 0); ASSERT(modeFile != 0);
ASSERT(modePath != 0); ASSERT(modePath != 0);
StorageWritePosix *this = NULL; StorageWritePosix *this;
OBJ_NEW_BEGIN(StorageWritePosix, .childQty = MEM_CONTEXT_QTY_MAX, .callbackQty = 1) 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(driver != NULL);
ASSERT(interface != NULL); ASSERT(interface != NULL);
StorageRead *this = NULL; StorageRead *this;
OBJ_NEW_BEGIN(StorageRead, .childQty = MEM_CONTEXT_QTY_MAX) OBJ_NEW_BEGIN(StorageRead, .childQty = MEM_CONTEXT_QTY_MAX)
{ {
@ -52,7 +52,7 @@ storageReadNew(void *const driver, const StorageReadInterface *const interface)
.interface = interface, .interface = interface,
.io = ioReadNew(driver, interface->ioInterface), .io = ioReadNew(driver, interface->ioInterface),
}, },
.driver = objMove(driver, objMemContext(this)), .driver = objMoveToInterface(driver, this, memContextPrior()),
}; };
} }
OBJ_NEW_END(); OBJ_NEW_END();

View File

@ -303,7 +303,7 @@ storageReadRemoteNew(
ASSERT(client != NULL); ASSERT(client != NULL);
ASSERT(name != 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) 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(modePath != 0);
ASSERT(client != NULL); ASSERT(client != NULL);
StorageRemote *this = NULL; StorageRemote *this;
const String *path = NULL; const String *path;
OBJ_NEW_BEGIN(StorageRemote, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX) 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(modeFile != 0);
ASSERT(modePath != 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) 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(name != NULL);
ASSERT(limit == NULL || varUInt64(limit) > 0); 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) 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(region != NULL);
ASSERT(partSize != 0); ASSERT(partSize != 0);
StorageS3 *this = NULL; StorageS3 *this;
OBJ_NEW_BEGIN(StorageS3, .childQty = MEM_CONTEXT_QTY_MAX) 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(storage != NULL);
ASSERT(name != NULL); ASSERT(name != NULL);
StorageWriteS3 *this = NULL; StorageWriteS3 *this;
OBJ_NEW_BEGIN(StorageWriteS3, .childQty = MEM_CONTEXT_QTY_MAX, .allocQty = MEM_CONTEXT_QTY_MAX) 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.pathRemove != NULL);
ASSERT(interface.remove != NULL); ASSERT(interface.remove != NULL);
Storage *this = NULL; Storage *this;
OBJ_NEW_BEGIN(Storage, .childQty = MEM_CONTEXT_QTY_MAX) OBJ_NEW_BEGIN(Storage, .childQty = MEM_CONTEXT_QTY_MAX)
{ {
@ -68,7 +68,7 @@ storageNew(
.pub = .pub =
{ {
.type = type, .type = type,
.driver = objMove(driver, objMemContext(this)), .driver = objMoveToInterface(driver, this, memContextPrior()),
.interface = interface, .interface = interface,
}, },
.path = strDup(path), .path = strDup(path),

View File

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

View File

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

View File

@ -11,11 +11,6 @@ typedef struct TestObject
bool data; // Test data bool data; // Test data
} TestObject; } TestObject;
typedef struct TestObjectContext
{
MemContext *memContext; // Mem context
} TestObjectContext;
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Standard object methods Standard object methods
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@ -31,25 +26,13 @@ testObjectFree(TestObject *this)
objFree(this); objFree(this);
} }
static TestObjectContext *
testObjectContextMove(TestObjectContext *this, MemContext *parentNew)
{
return objMoveContext(this, parentNew);
}
static void
testObjectContextFree(TestObjectContext *this)
{
objFreeContext(this);
}
/**********************************************************************************************************************************/ /**********************************************************************************************************************************/
static TestObject * static TestObject *
testObjectNew(void) testObjectNew(void)
{ {
TestObject *this = NULL; TestObject *this = NULL;
OBJ_NEW_BEGIN(TestObject) OBJ_NEW_BEGIN(TestObject, .childQty = 1)
{ {
this = OBJ_NEW_ALLOC(); this = OBJ_NEW_ALLOC();
@ -63,26 +46,6 @@ testObjectNew(void)
return this; 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 Test Run
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@ -94,7 +57,7 @@ testRun(void)
// ***************************************************************************************************************************** // *****************************************************************************************************************************
if (testBegin("OBJECT_DEFINE*()")) 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; TestObject *testObject = NULL;
@ -111,20 +74,16 @@ testRun(void)
TEST_RESULT_VOID(testObjectFree(NULL), "free null object"); 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(testInterface, testObjectNew(), "new interface object");
{ TEST_ASSIGN(testObject, testObjectNew(), "new test object");
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_RESULT_VOID(testObjectContextFree(testObjectContext), "free object"); // Only one of these can success since the interface only accepts one child
TEST_RESULT_VOID(testObjectContextFree(NULL), "free null object"); 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(); FUNCTION_HARNESS_RETURN_VOID();

View File

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