Fix missing comma for empty arrays/sets
When an array or a set is empty, and if it's not the last property
within an object, we need to add a comma after empty brackets/braces.
This change fix this issue. Also updated a test case to capture this.
Signed-off-by: Kasun Athukorala <kasunath@google.com>
Change-Id: Ia087f341d052660191f2614add2060c81be67f61
diff --git a/src/bej_decoder_core.c b/src/bej_decoder_core.c
index b1688a9..e8fba00 100644
--- a/src/bej_decoder_core.c
+++ b/src/bej_decoder_core.c
@@ -344,38 +344,44 @@
RETURN_IF_CALLBACK_IERROR(params->decodedCallback->callbackSetStart,
propName, params->callbacksDataPtr);
+ // Move the offset to the next SFLV tuple (or end). Make sure that this is
+ // called before calling bejProcessEnding.
+ params->state.encodedStreamOffset = bejGetFirstTupleOffset(params);
+
uint64_t elements = bejGetNnint(params->sflv.value);
// If its an empty set, we are done here.
if (elements == 0)
{
RETURN_IF_CALLBACK_IERROR(params->decodedCallback->callbackSetEnd,
params->callbacksDataPtr);
+ // Since this is an ending of a property (empty array), we should call
+ // bejProcessEnding. Unless the whole JSON object is an empty set (which
+ // shouldn't be the case), stack cannot be empty.
+ bejProcessEnding(params, /*canBeEmpty=*/false);
+ return 0;
+ }
+
+ // Update the states for the next encoding segment.
+ struct BejStackProperty newEnding = {
+ .sectionType = bejSectionSet,
+ .addPropertyName = params->state.addPropertyName,
+ .mainDictPropOffset = params->state.mainDictPropOffset,
+ .annoDictPropOffset = params->state.annoDictPropOffset,
+ .streamEndOffset = params->sflv.valueEndOffset,
+ };
+ RETURN_IF_IERROR(
+ params->stackCallback->stackPush(&newEnding, params->stackDataPtr));
+ params->state.addPropertyName = true;
+ if (params->sflv.tupleS.schema == bejAnnotation)
+ {
+ // Since this set is an annotated type, we need to advance the
+ // annotation dictionary for decoding the next segment.
+ params->state.annoDictPropOffset = prop->childPointerOffset;
}
else
{
- // Update the states for the next encoding segment.
- struct BejStackProperty newEnding = {
- .sectionType = bejSectionSet,
- .addPropertyName = params->state.addPropertyName,
- .mainDictPropOffset = params->state.mainDictPropOffset,
- .annoDictPropOffset = params->state.annoDictPropOffset,
- .streamEndOffset = params->sflv.valueEndOffset,
- };
- RETURN_IF_IERROR(
- params->stackCallback->stackPush(&newEnding, params->stackDataPtr));
- params->state.addPropertyName = true;
- if (params->sflv.tupleS.schema == bejAnnotation)
- {
- // Since this set is an annotated type, we need to advance the
- // annotation dictionary for decoding the next segment.
- params->state.annoDictPropOffset = prop->childPointerOffset;
- }
- else
- {
- params->state.mainDictPropOffset = prop->childPointerOffset;
- }
+ params->state.mainDictPropOffset = prop->childPointerOffset;
}
- params->state.encodedStreamOffset = bejGetFirstTupleOffset(params);
return 0;
}
@@ -403,39 +409,45 @@
RETURN_IF_CALLBACK_IERROR(params->decodedCallback->callbackArrayStart,
propName, params->callbacksDataPtr);
+ // Move the offset to the next SFLV tuple (or end). Make sure that this is
+ // called before calling bejProcessEnding.
+ params->state.encodedStreamOffset = bejGetFirstTupleOffset(params);
+
uint64_t elements = bejGetNnint(params->sflv.value);
// If its an empty array, we are done here.
if (elements == 0)
{
RETURN_IF_CALLBACK_IERROR(params->decodedCallback->callbackArrayEnd,
params->callbacksDataPtr);
+ // Since this is an ending of a property (empty array), we should call
+ // bejProcessEnding. Stack cannot be empty since there should be at
+ // least 1 parent in the stack.
+ bejProcessEnding(params, /*canBeEmpty=*/false);
+ return 0;
+ }
+
+ // Update the state for next segment decoding.
+ struct BejStackProperty newEnding = {
+ .sectionType = bejSectionArray,
+ .addPropertyName = params->state.addPropertyName,
+ .mainDictPropOffset = params->state.mainDictPropOffset,
+ .annoDictPropOffset = params->state.annoDictPropOffset,
+ .streamEndOffset = params->sflv.valueEndOffset,
+ };
+ RETURN_IF_IERROR(
+ params->stackCallback->stackPush(&newEnding, params->stackDataPtr));
+ // We do not add property names for array elements.
+ params->state.addPropertyName = false;
+ if (params->sflv.tupleS.schema == bejAnnotation)
+ {
+ // Since this array is an annotated type, we need to advance the
+ // annotation dictionary for decoding the next segment.
+ params->state.annoDictPropOffset = prop->childPointerOffset;
}
else
{
- // Update the state for next segment decoding.
- struct BejStackProperty newEnding = {
- .sectionType = bejSectionArray,
- .addPropertyName = params->state.addPropertyName,
- .mainDictPropOffset = params->state.mainDictPropOffset,
- .annoDictPropOffset = params->state.annoDictPropOffset,
- .streamEndOffset = params->sflv.valueEndOffset,
- };
- RETURN_IF_IERROR(
- params->stackCallback->stackPush(&newEnding, params->stackDataPtr));
- // We do not add property names for array elements.
- params->state.addPropertyName = false;
- if (params->sflv.tupleS.schema == bejAnnotation)
- {
- // Since this array is an annotated type, we need to advance the
- // annotation dictionary for decoding the next segment.
- params->state.annoDictPropOffset = prop->childPointerOffset;
- }
- else
- {
- params->state.mainDictPropOffset = prop->childPointerOffset;
- }
+ params->state.mainDictPropOffset = prop->childPointerOffset;
}
- params->state.encodedStreamOffset = bejGetFirstTupleOffset(params);
return 0;
}
diff --git a/test/encoded/storage_enc.bin b/test/encoded/storage_enc.bin
index b530533..62dbb0c 100644
--- a/test/encoded/storage_enc.bin
+++ b/test/encoded/storage_enc.bin
Binary files differ
diff --git a/test/json/storage.json b/test/json/storage.json
index 007c4ff..df43ead 100644
--- a/test/json/storage.json
+++ b/test/json/storage.json
@@ -10,6 +10,7 @@
"Health": "OK",
"HealthRollup": "OK"
},
+ "@Message.ExtendedInfo": [],
"StorageControllers": [
{
"@odata.id": "/redfish/v1/Systems/1/Storage/1#/StorageControllers/0",
@@ -75,5 +76,5 @@
"@Redfish.CollectionCapabilities": {
"MaxMembers": 0
},
- "@Message.ExtendedInfo": []
+ "Redundancy" : []
}