mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
Centralize and optimize tag stack management.
The push and pop code was duplicated in four places, so centralize the code into pckTagStackPop() and pckTagStackPush(). Also create a default bottom item for the stack to avoid allocating a list if there will only ever be the default container, which is very common. This avoids the extra time and memory to allocate a list.
This commit is contained in:
parent
15e7ff10d3
commit
ac1f6db4a2
@ -220,11 +220,19 @@ static const PackTypeMapData packTypeMapData[] =
|
|||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Object types
|
Object types
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
typedef struct PackTagStack
|
typedef struct PackTagStackItem
|
||||||
{
|
{
|
||||||
PackTypeMap typeMap; // Tag type map
|
PackTypeMap typeMap; // Tag type map
|
||||||
unsigned int idLast; // Last id in the container
|
unsigned int idLast; // Last id in the container
|
||||||
unsigned int nullTotal; // Total nulls since last tag written
|
unsigned int nullTotal; // Total nulls since last tag written
|
||||||
|
} PackTagStackItem;
|
||||||
|
|
||||||
|
typedef struct PackTagStack
|
||||||
|
{
|
||||||
|
List *stack; // Stack of object/array tags
|
||||||
|
PackTagStackItem bottom; // Static bottom of the stack
|
||||||
|
PackTagStackItem *top; // Top tag on the stack
|
||||||
|
unsigned int depth; // Stack depth
|
||||||
} PackTagStack;
|
} PackTagStack;
|
||||||
|
|
||||||
struct PackRead
|
struct PackRead
|
||||||
@ -239,8 +247,7 @@ struct PackRead
|
|||||||
PackTypeMap tagNextTypeMap; // Next tag type map
|
PackTypeMap tagNextTypeMap; // Next tag type map
|
||||||
uint64_t tagNextValue; // Next tag value
|
uint64_t tagNextValue; // Next tag value
|
||||||
|
|
||||||
List *tagStack; // Stack of object/array tags
|
PackTagStack tagStack; // Stack of object/array tags
|
||||||
PackTagStack *tagStackTop; // Top tag on the stack
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PackWrite
|
struct PackWrite
|
||||||
@ -248,10 +255,84 @@ struct PackWrite
|
|||||||
IoWrite *write; // Write pack to
|
IoWrite *write; // Write pack to
|
||||||
Buffer *buffer; // Buffer to contain write data
|
Buffer *buffer; // Buffer to contain write data
|
||||||
|
|
||||||
List *tagStack; // Stack of object/array tags
|
PackTagStack tagStack; // Stack of object/array tags
|
||||||
PackTagStack *tagStackTop; // Top tag on the stack
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Push a container onto the tag stack
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static void
|
||||||
|
pckTagStackPush(MemContext *const memContext, PackTagStack *const tagStack, const PackTypeMap typeMap)
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN();
|
||||||
|
FUNCTION_TEST_PARAM(MEM_CONTEXT, memContext);
|
||||||
|
FUNCTION_TEST_PARAM_P(VOID, tagStack);
|
||||||
|
FUNCTION_TEST_PARAM(ENUM, typeMap);
|
||||||
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
|
ASSERT(tagStack != NULL);
|
||||||
|
ASSERT(typeMap == pckTypeMapArray || typeMap == pckTypeMapObj);
|
||||||
|
|
||||||
|
if (tagStack->stack == NULL)
|
||||||
|
{
|
||||||
|
MEM_CONTEXT_BEGIN(memContext)
|
||||||
|
{
|
||||||
|
tagStack->stack = lstNewP(sizeof(PackTagStackItem));
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
tagStack->top = lstAdd(tagStack->stack, &(PackTagStackItem){.typeMap = typeMap});
|
||||||
|
tagStack->depth++;
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Check that a container can be popped off the stack
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static void
|
||||||
|
pckTagStackPopCheck(PackTagStack *const tagStack, const PackTypeMap typeMap)
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN();
|
||||||
|
FUNCTION_TEST_PARAM_P(VOID, tagStack);
|
||||||
|
FUNCTION_TEST_PARAM(ENUM, typeMap);
|
||||||
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
|
ASSERT(tagStack != NULL);
|
||||||
|
ASSERT(typeMap == pckTypeMapArray || typeMap == pckTypeMapObj);
|
||||||
|
|
||||||
|
if (tagStack->depth == 0 || tagStack->top->typeMap != typeMap)
|
||||||
|
THROW_FMT(FormatError, "not in %s", strZ(strIdToStr(packTypeMapData[typeMap].type)));
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Pop a container off the tag stack
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static void
|
||||||
|
pckTagStackPop(PackTagStack *const tagStack)
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN();
|
||||||
|
FUNCTION_TEST_PARAM_P(VOID, tagStack);
|
||||||
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
|
ASSERT(tagStack != NULL);
|
||||||
|
ASSERT(tagStack->depth != 0);
|
||||||
|
ASSERT(tagStack->stack != NULL);
|
||||||
|
|
||||||
|
lstRemoveLast(tagStack->stack);
|
||||||
|
tagStack->depth--;
|
||||||
|
|
||||||
|
if (tagStack->depth == 0)
|
||||||
|
tagStack->top = &tagStack->bottom;
|
||||||
|
else
|
||||||
|
tagStack->top = lstGetLast(tagStack->stack);
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
// Helper to create common data
|
// Helper to create common data
|
||||||
static PackRead *
|
static PackRead *
|
||||||
@ -267,10 +348,10 @@ pckReadNewInternal(void)
|
|||||||
|
|
||||||
*this = (PackRead)
|
*this = (PackRead)
|
||||||
{
|
{
|
||||||
.tagStack = lstNewP(sizeof(PackTagStack)),
|
.tagStack = {.bottom = {.typeMap = pckTypeMapObj}},
|
||||||
};
|
};
|
||||||
|
|
||||||
this->tagStackTop = lstAdd(this->tagStack, &(PackTagStack){.typeMap = pckTypeMapObj});
|
this->tagStack.top = &this->tagStack.bottom;
|
||||||
}
|
}
|
||||||
OBJ_NEW_END();
|
OBJ_NEW_END();
|
||||||
|
|
||||||
@ -496,7 +577,7 @@ pckReadTagNext(PackRead *this)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Increment the next tag id
|
// Increment the next tag id
|
||||||
this->tagNextId += this->tagStackTop->idLast + 1;
|
this->tagNextId += this->tagStack.top->idLast + 1;
|
||||||
|
|
||||||
// Tag was found
|
// Tag was found
|
||||||
result = true;
|
result = true;
|
||||||
@ -527,10 +608,10 @@ pckReadTag(PackRead *this, unsigned int *id, PackTypeMap typeMap, bool peek)
|
|||||||
// Increment the id by one if no id was specified
|
// Increment the id by one if no id was specified
|
||||||
if (*id == 0)
|
if (*id == 0)
|
||||||
{
|
{
|
||||||
*id = this->tagStackTop->idLast + 1;
|
*id = this->tagStack.top->idLast + 1;
|
||||||
}
|
}
|
||||||
// Else check that the id has been incremented
|
// Else check that the id has been incremented
|
||||||
else if (*id <= this->tagStackTop->idLast)
|
else if (*id <= this->tagStack.top->idLast)
|
||||||
THROW_FMT(FormatError, "field %u was already read", *id);
|
THROW_FMT(FormatError, "field %u was already read", *id);
|
||||||
|
|
||||||
// Search for the requested id
|
// Search for the requested id
|
||||||
@ -559,7 +640,7 @@ pckReadTag(PackRead *this, unsigned int *id, PackTypeMap typeMap, bool peek)
|
|||||||
strZ(strIdToStr(packTypeMapData[typeMap].type)));
|
strZ(strIdToStr(packTypeMapData[typeMap].type)));
|
||||||
}
|
}
|
||||||
|
|
||||||
this->tagStackTop->idLast = this->tagNextId;
|
this->tagStack.top->idLast = this->tagNextId;
|
||||||
this->tagNextId = 0;
|
this->tagNextId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -580,7 +661,7 @@ pckReadTag(PackRead *this, unsigned int *id, PackTypeMap typeMap, bool peek)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Increment the last id to the id just read
|
// Increment the last id to the id just read
|
||||||
this->tagStackTop->idLast = this->tagNextId;
|
this->tagStack.top->idLast = this->tagNextId;
|
||||||
|
|
||||||
// Read tag on the next iteration
|
// Read tag on the next iteration
|
||||||
this->tagNextId = 0;
|
this->tagNextId = 0;
|
||||||
@ -636,7 +717,7 @@ pckReadNullInternal(PackRead *this, unsigned int *id)
|
|||||||
// If the field is NULL then set idLast (to avoid rechecking the same id on the next call) and return true
|
// If the field is NULL then set idLast (to avoid rechecking the same id on the next call) and return true
|
||||||
if (*id < this->tagNextId)
|
if (*id < this->tagNextId)
|
||||||
{
|
{
|
||||||
this->tagStackTop->idLast = *id;
|
this->tagStack.top->idLast = *id;
|
||||||
FUNCTION_TEST_RETURN(true);
|
FUNCTION_TEST_RETURN(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -685,7 +766,7 @@ pckReadArrayBegin(PackRead *this, PackIdParam param)
|
|||||||
pckReadTag(this, ¶m.id, pckTypeMapArray, false);
|
pckReadTag(this, ¶m.id, pckTypeMapArray, false);
|
||||||
|
|
||||||
// Add array to the tag stack so IDs can be tracked separately from the parent container
|
// Add array to the tag stack so IDs can be tracked separately from the parent container
|
||||||
this->tagStackTop = lstAdd(this->tagStack, &(PackTagStack){.typeMap = pckTypeMapArray});
|
pckTagStackPush(objMemContext(this), &this->tagStack, pckTypeMapArray);
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN_VOID();
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
}
|
}
|
||||||
@ -699,16 +780,15 @@ pckReadArrayEnd(PackRead *this)
|
|||||||
|
|
||||||
ASSERT(this != NULL);
|
ASSERT(this != NULL);
|
||||||
|
|
||||||
if (lstSize(this->tagStack) == 1 || this->tagStackTop->typeMap != pckTypeMapArray)
|
// Check tag stack pop
|
||||||
THROW(FormatError, "not in array");
|
pckTagStackPopCheck(&this->tagStack, pckTypeMapArray);
|
||||||
|
|
||||||
// Make sure we are at the end of the array
|
// Make sure we are at the end of the array
|
||||||
unsigned int id = UINT_MAX - 1;
|
unsigned int id = UINT_MAX - 1;
|
||||||
pckReadTag(this, &id, pckTypeMapUnknown, true);
|
pckReadTag(this, &id, pckTypeMapUnknown, true);
|
||||||
|
|
||||||
// Pop array off the stack
|
// Pop array off the stack
|
||||||
lstRemoveLast(this->tagStack);
|
pckTagStackPop(&this->tagStack);
|
||||||
this->tagStackTop = lstGetLast(this->tagStack);
|
|
||||||
|
|
||||||
// Reset tagNextId to keep reading
|
// Reset tagNextId to keep reading
|
||||||
this->tagNextId = 0;
|
this->tagNextId = 0;
|
||||||
@ -840,7 +920,7 @@ pckReadObjBegin(PackRead *this, PackIdParam param)
|
|||||||
pckReadTag(this, ¶m.id, pckTypeMapObj, false);
|
pckReadTag(this, ¶m.id, pckTypeMapObj, false);
|
||||||
|
|
||||||
// Add object to the tag stack so IDs can be tracked separately from the parent container
|
// Add object to the tag stack so IDs can be tracked separately from the parent container
|
||||||
this->tagStackTop = lstAdd(this->tagStack, &(PackTagStack){.typeMap = pckTypeMapObj});
|
pckTagStackPush(objMemContext(this), &this->tagStack, pckTypeMapObj);
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN_VOID();
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
}
|
}
|
||||||
@ -854,16 +934,15 @@ pckReadObjEnd(PackRead *this)
|
|||||||
|
|
||||||
ASSERT(this != NULL);
|
ASSERT(this != NULL);
|
||||||
|
|
||||||
if (lstSize(this->tagStack) == 1 || ((PackTagStack *)lstGetLast(this->tagStack))->typeMap != pckTypeMapObj)
|
// Check tag stack pop
|
||||||
THROW(FormatError, "not in object");
|
pckTagStackPopCheck(&this->tagStack, pckTypeMapObj);
|
||||||
|
|
||||||
// Make sure we are at the end of the object
|
// Make sure we are at the end of the object
|
||||||
unsigned id = UINT_MAX - 1;
|
unsigned id = UINT_MAX - 1;
|
||||||
pckReadTag(this, &id, pckTypeMapUnknown, true);
|
pckReadTag(this, &id, pckTypeMapUnknown, true);
|
||||||
|
|
||||||
// Pop object off the stack
|
// Pop object off the stack
|
||||||
lstRemoveLast(this->tagStack);
|
pckTagStackPop(&this->tagStack);
|
||||||
this->tagStackTop = lstGetLast(this->tagStack);
|
|
||||||
|
|
||||||
// Reset tagNextId to keep reading
|
// Reset tagNextId to keep reading
|
||||||
this->tagNextId = 0;
|
this->tagNextId = 0;
|
||||||
@ -1083,19 +1162,13 @@ pckReadEnd(PackRead *this)
|
|||||||
FUNCTION_TEST_END();
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
ASSERT(this != NULL);
|
||||||
|
CHECK(this->tagStack.depth == 0);
|
||||||
|
|
||||||
// Read object end markers
|
// Make sure we are at the end of the pack
|
||||||
while (!lstEmpty(this->tagStack))
|
|
||||||
{
|
|
||||||
// Make sure we are at the end of the container
|
|
||||||
unsigned int id = UINT_MAX - 1;
|
unsigned int id = UINT_MAX - 1;
|
||||||
pckReadTag(this, &id, pckTypeMapUnknown, true);
|
pckReadTag(this, &id, pckTypeMapUnknown, true);
|
||||||
|
|
||||||
// Remove from stack
|
this->tagStack.top = NULL;
|
||||||
lstRemoveLast(this->tagStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->tagStackTop = NULL;
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN_VOID();
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
}
|
}
|
||||||
@ -1105,8 +1178,8 @@ String *
|
|||||||
pckReadToLog(const PackRead *this)
|
pckReadToLog(const PackRead *this)
|
||||||
{
|
{
|
||||||
return strNewFmt(
|
return strNewFmt(
|
||||||
"{depth: %u, idLast: %u, tagNextId: %u, tagNextType: %u, tagNextValue %" PRIu64 "}", lstSize(this->tagStack),
|
"{depth: %u, idLast: %u, tagNextId: %u, tagNextType: %u, tagNextValue %" PRIu64 "}", this->tagStack.depth,
|
||||||
this->tagStackTop->idLast, this->tagNextId, this->tagNextTypeMap, this->tagNextValue);
|
this->tagStack.top->idLast, this->tagNextId, this->tagNextTypeMap, this->tagNextValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
@ -1124,10 +1197,10 @@ pckWriteNewInternal(void)
|
|||||||
|
|
||||||
*this = (PackWrite)
|
*this = (PackWrite)
|
||||||
{
|
{
|
||||||
.tagStack = lstNewP(sizeof(PackTagStack)),
|
.tagStack = {.bottom = {.typeMap = pckTypeMapObj}},
|
||||||
};
|
};
|
||||||
|
|
||||||
this->tagStackTop = lstAdd(this->tagStack, &(PackTagStack){.typeMap = pckTypeMapObj});
|
this->tagStack.top = &this->tagStack.bottom;
|
||||||
}
|
}
|
||||||
OBJ_NEW_END();
|
OBJ_NEW_END();
|
||||||
|
|
||||||
@ -1281,17 +1354,17 @@ pckWriteTag(PackWrite *this, PackTypeMap typeMap, unsigned int id, uint64_t valu
|
|||||||
// If id is not specified then add one to previous tag (and include all NULLs)
|
// If id is not specified then add one to previous tag (and include all NULLs)
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
{
|
{
|
||||||
id = this->tagStackTop->idLast + this->tagStackTop->nullTotal + 1;
|
id = this->tagStack.top->idLast + this->tagStack.top->nullTotal + 1;
|
||||||
}
|
}
|
||||||
// Else the id must be greater than the last one
|
// Else the id must be greater than the last one
|
||||||
else
|
else
|
||||||
CHECK(id > this->tagStackTop->idLast);
|
CHECK(id > this->tagStack.top->idLast);
|
||||||
|
|
||||||
// Clear NULLs now that field id has been calculated
|
// Clear NULLs now that field id has been calculated
|
||||||
this->tagStackTop->nullTotal = 0;
|
this->tagStack.top->nullTotal = 0;
|
||||||
|
|
||||||
// Calculate field ID delta
|
// Calculate field ID delta
|
||||||
unsigned int tagId = id - this->tagStackTop->idLast - 1;
|
unsigned int tagId = id - this->tagStack.top->idLast - 1;
|
||||||
|
|
||||||
// Write field type map (e.g. int64, string)
|
// Write field type map (e.g. int64, string)
|
||||||
uint64_t tag = typeMap >= 0xF ? 0xF0 : typeMap << 4;
|
uint64_t tag = typeMap >= 0xF ? 0xF0 : typeMap << 4;
|
||||||
@ -1375,7 +1448,7 @@ pckWriteTag(PackWrite *this, PackTypeMap typeMap, unsigned int id, uint64_t valu
|
|||||||
pckWriteU64Internal(this, value);
|
pckWriteU64Internal(this, value);
|
||||||
|
|
||||||
// Set last field id
|
// Set last field id
|
||||||
this->tagStackTop->idLast = id;
|
this->tagStack.top->idLast = id;
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN_VOID();
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
}
|
}
|
||||||
@ -1397,7 +1470,7 @@ pckWriteDefaultNull(PackWrite *this, bool defaultWrite, bool defaultEqual)
|
|||||||
// Write a NULL if not forcing the default to be written and the value passed equals the default
|
// Write a NULL if not forcing the default to be written and the value passed equals the default
|
||||||
if (!defaultWrite && defaultEqual)
|
if (!defaultWrite && defaultEqual)
|
||||||
{
|
{
|
||||||
this->tagStackTop->nullTotal++;
|
this->tagStack.top->nullTotal++;
|
||||||
FUNCTION_TEST_RETURN(true);
|
FUNCTION_TEST_RETURN(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1413,7 +1486,7 @@ pckWriteNull(PackWrite *this)
|
|||||||
FUNCTION_TEST_PARAM(PACK_WRITE, this);
|
FUNCTION_TEST_PARAM(PACK_WRITE, this);
|
||||||
FUNCTION_TEST_END();
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
this->tagStackTop->nullTotal++;
|
this->tagStack.top->nullTotal++;
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(this);
|
FUNCTION_TEST_RETURN(this);
|
||||||
}
|
}
|
||||||
@ -1433,7 +1506,7 @@ pckWriteArrayBegin(PackWrite *this, PackIdParam param)
|
|||||||
pckWriteTag(this, pckTypeMapArray, param.id, 0);
|
pckWriteTag(this, pckTypeMapArray, param.id, 0);
|
||||||
|
|
||||||
// Add array to the tag stack so IDs can be tracked separately from the parent container
|
// Add array to the tag stack so IDs can be tracked separately from the parent container
|
||||||
this->tagStackTop = lstAdd(this->tagStack, &(PackTagStack){.typeMap = pckTypeMapArray});
|
pckTagStackPush(objMemContext(this), &this->tagStack, pckTypeMapArray);
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(this);
|
FUNCTION_TEST_RETURN(this);
|
||||||
}
|
}
|
||||||
@ -1446,15 +1519,15 @@ pckWriteArrayEnd(PackWrite *this)
|
|||||||
FUNCTION_TEST_END();
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
ASSERT(this != NULL);
|
||||||
ASSERT(lstSize(this->tagStack) != 1);
|
|
||||||
ASSERT(((PackTagStack *)lstGetLast(this->tagStack))->typeMap == pckTypeMapArray);
|
// Check tag stack pop
|
||||||
|
pckTagStackPopCheck(&this->tagStack, pckTypeMapArray);
|
||||||
|
|
||||||
// Write end of array tag
|
// Write end of array tag
|
||||||
pckWriteU64Internal(this, 0);
|
pckWriteU64Internal(this, 0);
|
||||||
|
|
||||||
// Pop array off the stack to revert to ID tracking for the prior container
|
// Pop array off the stack to revert to ID tracking for the prior container
|
||||||
lstRemoveLast(this->tagStack);
|
pckTagStackPop(&this->tagStack);
|
||||||
this->tagStackTop = lstGetLast(this->tagStack);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(this);
|
FUNCTION_TEST_RETURN(this);
|
||||||
}
|
}
|
||||||
@ -1584,7 +1657,7 @@ pckWriteObjBegin(PackWrite *this, PackIdParam param)
|
|||||||
pckWriteTag(this, pckTypeMapObj, param.id, 0);
|
pckWriteTag(this, pckTypeMapObj, param.id, 0);
|
||||||
|
|
||||||
// Add object to the tag stack so IDs can be tracked separately from the parent container
|
// Add object to the tag stack so IDs can be tracked separately from the parent container
|
||||||
this->tagStackTop = lstAdd(this->tagStack, &(PackTagStack){.typeMap = pckTypeMapObj});
|
pckTagStackPush(objMemContext(this), &this->tagStack, pckTypeMapObj);
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(this);
|
FUNCTION_TEST_RETURN(this);
|
||||||
}
|
}
|
||||||
@ -1597,15 +1670,15 @@ pckWriteObjEnd(PackWrite *this)
|
|||||||
FUNCTION_TEST_END();
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
ASSERT(this != NULL);
|
||||||
ASSERT(lstSize(this->tagStack) != 1);
|
|
||||||
ASSERT(((PackTagStack *)lstGetLast(this->tagStack))->typeMap == pckTypeMapObj);
|
// Check tag stack pop
|
||||||
|
pckTagStackPopCheck(&this->tagStack, pckTypeMapObj);
|
||||||
|
|
||||||
// Write end of object tag
|
// Write end of object tag
|
||||||
pckWriteU64Internal(this, 0);
|
pckWriteU64Internal(this, 0);
|
||||||
|
|
||||||
// Pop object off the stack to revert to ID tracking for the prior container
|
// Pop object off the stack to revert to ID tracking for the prior container
|
||||||
lstRemoveLast(this->tagStack);
|
pckTagStackPop(&this->tagStack);
|
||||||
this->tagStackTop = lstGetLast(this->tagStack);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(this);
|
FUNCTION_TEST_RETURN(this);
|
||||||
}
|
}
|
||||||
@ -1799,10 +1872,10 @@ pckWriteEnd(PackWrite *this)
|
|||||||
FUNCTION_TEST_END();
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
ASSERT(this != NULL);
|
||||||
ASSERT(lstSize(this->tagStack) == 1);
|
ASSERT(this->tagStack.depth == 0);
|
||||||
|
|
||||||
pckWriteU64Internal(this, 0);
|
pckWriteU64Internal(this, 0);
|
||||||
this->tagStackTop = NULL;
|
this->tagStack.top = NULL;
|
||||||
|
|
||||||
// If writing to io flush the internal buffer
|
// If writing to io flush the internal buffer
|
||||||
if (this->write != NULL)
|
if (this->write != NULL)
|
||||||
@ -1829,7 +1902,7 @@ pckWriteResult(PackWrite *const this)
|
|||||||
|
|
||||||
if (this != NULL)
|
if (this != NULL)
|
||||||
{
|
{
|
||||||
ASSERT(this->tagStackTop == NULL);
|
ASSERT(this->tagStack.top == NULL);
|
||||||
|
|
||||||
result = (Pack *)this->buffer;
|
result = (Pack *)this->buffer;
|
||||||
}
|
}
|
||||||
@ -1841,5 +1914,5 @@ pckWriteResult(PackWrite *const this)
|
|||||||
String *
|
String *
|
||||||
pckWriteToLog(const PackWrite *this)
|
pckWriteToLog(const PackWrite *this)
|
||||||
{
|
{
|
||||||
return strNewFmt("{depth: %u, idLast: %u}", lstSize(this->tagStack), this->tagStackTop == NULL ? 0 : this->tagStackTop->idLast);
|
return strNewFmt("{depth: %u, idLast: %u}", this->tagStack.depth, this->tagStack.top == NULL ? 0 : this->tagStack.top->idLast);
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,9 @@ testRun(void)
|
|||||||
}
|
}
|
||||||
MEM_CONTEXT_TEMP_END();
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
|
||||||
TEST_RESULT_STR_Z(pckWriteToLog(packWrite), "{depth: 1, idLast: 0}", "log");
|
TEST_RESULT_STR_Z(pckWriteToLog(packWrite), "{depth: 0, idLast: 0}", "log");
|
||||||
TEST_RESULT_VOID(pckWriteU64P(packWrite, 0750), "write mode");
|
TEST_RESULT_VOID(pckWriteU64P(packWrite, 0750), "write mode");
|
||||||
TEST_RESULT_STR_Z(pckWriteToLog(packWrite), "{depth: 1, idLast: 1}", "log");
|
TEST_RESULT_STR_Z(pckWriteToLog(packWrite), "{depth: 0, idLast: 1}", "log");
|
||||||
TEST_RESULT_VOID(pckWriteU64P(packWrite, 1911246845), "write timestamp");
|
TEST_RESULT_VOID(pckWriteU64P(packWrite, 1911246845), "write timestamp");
|
||||||
TEST_RESULT_VOID(pckWriteU64P(packWrite, 0xFFFFFFFFFFFFFFFF, .id = 7), "write max u64");
|
TEST_RESULT_VOID(pckWriteU64P(packWrite, 0xFFFFFFFFFFFFFFFF, .id = 7), "write max u64");
|
||||||
TEST_RESULT_VOID(pckWriteU64P(packWrite, 1, .id = 10), "write 1");
|
TEST_RESULT_VOID(pckWriteU64P(packWrite, 1, .id = 10), "write 1");
|
||||||
@ -252,7 +252,7 @@ testRun(void)
|
|||||||
TEST_RESULT_BOOL(pckReadBoolP(packRead, .id = 15), true, "read true");
|
TEST_RESULT_BOOL(pckReadBoolP(packRead, .id = 15), true, "read true");
|
||||||
TEST_RESULT_BOOL(pckReadBoolP(packRead, .id = 20), false, "read false");
|
TEST_RESULT_BOOL(pckReadBoolP(packRead, .id = 20), false, "read false");
|
||||||
|
|
||||||
TEST_ERROR(pckReadObjEndP(packRead), FormatError, "not in object");
|
TEST_ERROR(pckReadObjEndP(packRead), FormatError, "not in obj");
|
||||||
TEST_RESULT_VOID(pckReadObjBeginP(packRead, .id = 28), "read object begin");
|
TEST_RESULT_VOID(pckReadObjBeginP(packRead, .id = 28), "read object begin");
|
||||||
TEST_ERROR(pckReadArrayEndP(packRead), FormatError, "not in array");
|
TEST_ERROR(pckReadArrayEndP(packRead), FormatError, "not in array");
|
||||||
TEST_RESULT_BOOL(pckReadBoolP(packRead), true, "read true");
|
TEST_RESULT_BOOL(pckReadBoolP(packRead), true, "read true");
|
||||||
@ -271,7 +271,7 @@ testRun(void)
|
|||||||
TEST_RESULT_UINT(pckReadId(packRead), 37, "check array id");
|
TEST_RESULT_UINT(pckReadId(packRead), 37, "check array id");
|
||||||
TEST_RESULT_VOID(pckReadArrayBeginP(packRead, .id = pckReadId(packRead)), "read array begin");
|
TEST_RESULT_VOID(pckReadArrayBeginP(packRead, .id = pckReadId(packRead)), "read array begin");
|
||||||
|
|
||||||
TEST_ERROR(pckReadObjEndP(packRead), FormatError, "not in object");
|
TEST_ERROR(pckReadObjEndP(packRead), FormatError, "not in obj");
|
||||||
|
|
||||||
unsigned int value = 0;
|
unsigned int value = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user