mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-01-18 04:58:51 +02:00
Add const buffer functions to Pack type.
These allow packs to be created without allocating a buffer in the case that the buffer already exists or the data is in a global constant. Also fix a rendering issue in hrnPackReadToStr().
This commit is contained in:
parent
66bfd1327e
commit
144469b977
@ -391,9 +391,22 @@ pckReadNew(const Pack *const pack)
|
||||
if (pack == NULL)
|
||||
FUNCTION_TEST_RETURN(NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(pckReadNewC(bufPtrConst((const Buffer *)pack), bufUsed((const Buffer *)pack)));
|
||||
}
|
||||
|
||||
PackRead *
|
||||
pckReadNewC(const unsigned char *const buffer, size_t size)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM_P(VOID, buffer);
|
||||
FUNCTION_TEST_PARAM(SIZE, size);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
PackRead *this = pckReadNewInternal();
|
||||
this->bufferPtr = bufPtrConst((const Buffer *)pack);
|
||||
this->bufferUsed = bufUsed((const Buffer *)pack);
|
||||
this->bufferPtr = buffer;
|
||||
this->bufferUsed = size;
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -720,6 +733,54 @@ pckReadId(PackRead *this)
|
||||
FUNCTION_TEST_RETURN(this->tagNextId);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
size_t
|
||||
pckReadSize(PackRead *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(PACK_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(packTypeMapData[this->tagNextTypeMap].size);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->tagNextSize);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
pckReadConsume(PackRead *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(PACK_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
unsigned int id = 0;
|
||||
|
||||
pckReadTag(this, &id, pckTypeMapUnknown, true);
|
||||
pckReadTag(this, &id, this->tagNextTypeMap, false);
|
||||
pckReadConsumeBuffer(this);
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
const unsigned char *
|
||||
pckReadBufPtr(PackRead *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(PACK_READ, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(packTypeMapData[this->tagNextTypeMap].size);
|
||||
ASSERT(this->buffer == NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->bufferPtr + this->bufferPos);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
// Internal version of pckReadNull() that does not require a PackIdParam struct. Some functions already have an id variable so
|
||||
// assigning that to a PackIdParam struct and then copying it back is wasteful.
|
||||
@ -991,6 +1052,27 @@ pckReadPackRead(PackRead *this, PckReadPackParam param)
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
}
|
||||
|
||||
PackRead *
|
||||
pckReadPackReadConst(PackRead *this, PckReadPackParam param)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(PACK_READ, this);
|
||||
FUNCTION_TEST_PARAM(UINT, param.id);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
if (pckReadNullInternal(this, ¶m.id))
|
||||
FUNCTION_TEST_RETURN(NULL);
|
||||
|
||||
// Read the tag
|
||||
pckReadTag(this, ¶m.id, pckTypeMapPack, false);
|
||||
|
||||
PackRead *const result = pckReadNewC(pckReadBufPtr(this), pckReadSize(this));
|
||||
|
||||
pckReadConsumeBuffer(this);
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
}
|
||||
|
||||
Pack *
|
||||
pckReadPack(PackRead *const this, PckReadPackParam param)
|
||||
{
|
||||
|
@ -167,6 +167,7 @@ Read Constructors
|
||||
***********************************************************************************************************************************/
|
||||
// Note that the pack is not moved into the PackRead mem context and must be moved explicitly if the PackRead object is moved.
|
||||
PackRead *pckReadNew(const Pack *pack);
|
||||
PackRead *pckReadNewC(const unsigned char *const buffer, size_t size);
|
||||
|
||||
PackRead *pckReadNewIo(IoRead *read);
|
||||
|
||||
@ -183,9 +184,19 @@ typedef struct PackIdParam
|
||||
// debugging. If you just need to know if the field exists or not, then use pckReadNullP().
|
||||
bool pckReadNext(PackRead *this);
|
||||
|
||||
// Current field buffer for fields that have a size, e.g. bin. Can only be used when the pack was created with pckReadNew(). Note
|
||||
// that this pointer is tied to the buffer the pack was created with so be careful not to free it too soon.
|
||||
const unsigned char *pckReadBufPtr(PackRead *this);
|
||||
|
||||
// Consume the next field regardless of type.
|
||||
void pckReadConsume(PackRead *this);
|
||||
|
||||
// Current field id. Set after a call to pckReadNext().
|
||||
unsigned int pckReadId(PackRead *this);
|
||||
|
||||
// Current field size for fields that have a size, e.g. bin
|
||||
size_t pckReadSize(PackRead *this);
|
||||
|
||||
// Current field type. Set after a call to pckReadNext().
|
||||
PackType pckReadType(PackRead *this);
|
||||
|
||||
@ -301,6 +312,13 @@ typedef struct PckReadPackParam
|
||||
|
||||
PackRead *pckReadPackRead(PackRead *this, PckReadPackParam param);
|
||||
|
||||
// Read pack using the same buffer passed to pckReadNew(). Note that this pointer is tied to the buffer the pack was created with so
|
||||
// be careful not to free it too soon.
|
||||
#define pckReadPackReadConstP(this, ...) \
|
||||
pckReadPackReadConst(this, (PckReadPackParam){VAR_PARAM_INIT, __VA_ARGS__})
|
||||
|
||||
PackRead *pckReadPackReadConst(PackRead *this, PckReadPackParam param);
|
||||
|
||||
// Read pack buffer
|
||||
#define pckReadPackP(this, ...) \
|
||||
pckReadPack(this, (PckReadPackParam){VAR_PARAM_INIT, __VA_ARGS__})
|
||||
|
@ -77,7 +77,7 @@ String *hrnPackReadToStr(PackRead *read)
|
||||
|
||||
case pckTypePack:
|
||||
{
|
||||
strCatFmt(result, "<%s>", strZ(hrnPackReadToStr(pckReadPackReadP(read))));
|
||||
strCatFmt(result, "<%s>", strZ(hrnPackReadToStr(pckReadPackReadP(read, .id = id))));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -350,6 +350,39 @@ testRun(void)
|
||||
|
||||
TEST_RESULT_PTR(pckWriteResult(NULL), NULL, "null pack result");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("read const packs");
|
||||
|
||||
TEST_ASSIGN(packWrite, pckWriteNewP(), "new write");
|
||||
|
||||
// Write pack to read as ptr/size
|
||||
packSub = pckWriteNewP();
|
||||
pckWriteU64P(packSub, 777);
|
||||
pckWriteEndP(packSub);
|
||||
|
||||
TEST_RESULT_VOID(pckWritePackP(packWrite, pckWriteResult(packSub)), "write pack");
|
||||
|
||||
// Write pack to read as const
|
||||
TEST_RESULT_VOID(pckWritePackP(packWrite, NULL), "write pack");
|
||||
|
||||
packSub = pckWriteNewP();
|
||||
pckWriteU64P(packSub, 99);
|
||||
pckWriteEndP(packSub);
|
||||
|
||||
TEST_RESULT_VOID(pckWritePackP(packWrite, pckWriteResult(packSub)), "write pack");
|
||||
TEST_RESULT_VOID(pckWriteEndP(packWrite), "write pack end");
|
||||
|
||||
TEST_ASSIGN(packRead, pckReadNew(pckWriteResult(packWrite)), "new read");
|
||||
|
||||
TEST_RESULT_BOOL(pckReadNext(packRead), true, "next pack");
|
||||
TEST_RESULT_UINT(pckReadSize(packRead), 4, "pack size");
|
||||
TEST_RESULT_STR_Z(bufHex(BUF(pckReadBufPtr(packRead), pckReadSize(packRead))), "98890600", "pack hex");
|
||||
TEST_RESULT_UINT(pckReadU64P(pckReadNewC(pckReadBufPtr(packRead), pckReadSize(packRead))), 777, "u64 value");
|
||||
TEST_RESULT_VOID(pckReadConsume(packRead), "consume pack");
|
||||
|
||||
TEST_RESULT_PTR(pckReadPackReadConstP(packRead), NULL, "const null pack");
|
||||
TEST_RESULT_UINT(pckReadU64P(pckReadPackReadConstP(packRead)), 99, "const pack");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("pack/unpack write internal buffer empty");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user