Skip to content

Commit

Permalink
Add a lighweight size-computation method on DecodableList. (#10801)
Browse files Browse the repository at this point in the history
Just computes an optimistic size, without checking whether the
individual items decode properly.
  • Loading branch information
bzbarsky-apple authored and pull[bot] committed Oct 25, 2021
1 parent 551494b commit 4204893
Show file tree
Hide file tree
Showing 9 changed files with 556 additions and 574 deletions.
2 changes: 2 additions & 0 deletions examples/chip-tool/commands/tests/TestCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ class TestCommand : public CHIPCommand
template <typename T>
bool CheckValueAsListLength(const char * itemName, chip::app::DataModel::DecodableList<T> list, uint64_t expectedLength)
{
// We don't just use list.ComputeSize(), because we want to check that
// all the values in the list correctly decode to our type too.
auto iter = list.begin();
uint64_t count = 0;
while (iter.Next())
Expand Down
17 changes: 6 additions & 11 deletions examples/chip-tool/templates/commands.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -139,16 +139,12 @@ static void On{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}ListAttri
ModelCommand * command = static_cast<ModelCommand *>(context);

size_t count = 0;
{
auto iter = list.begin();
while (iter.Next()) {
++count;
}
if (iter.GetStatus() != CHIP_NO_ERROR) {
command->SetCommandExitStatus(iter.GetStatus());
return;
}
CHIP_ERROR err = list.ComputeSize(&count);
if (err != CHIP_NO_ERROR) {
command->SetCommandExitStatus(err);
return;
}

ChipLogProgress(chipTool, "On{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}ListAttributeResponse: %zu entries", count);

auto iter = list.begin();
Expand Down Expand Up @@ -180,8 +176,7 @@ static void On{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}ListAttri
{{/if}}
{{/if}}
}

command->SetCommandExitStatus(CHIP_NO_ERROR);
command->SetCommandExitStatus(iter.GetStatus());
}

{{/if}}
Expand Down
12 changes: 3 additions & 9 deletions src/app/clusters/test-cluster-server/test-cluster-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,15 +394,9 @@ bool emberAfTestClusterClusterTestListInt8UReverseRequestCallback(
CommandHandler * commandObj, ConcreteCommandPath const & commandPath,
Commands::TestListInt8UReverseRequest::DecodableType const & commandData)
{
size_t count = 0;
{
auto iter = commandData.arg1.begin();
while (iter.Next())
{
++count;
}
VerifyOrExit(iter.GetStatus() == CHIP_NO_ERROR, );
}
size_t count = 0;
CHIP_ERROR err = commandData.arg1.ComputeSize(&count);
VerifyOrExit(err == CHIP_NO_ERROR, );

{
auto iter = commandData.arg1.begin();
Expand Down
8 changes: 8 additions & 0 deletions src/app/data-model/DecodableList.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ class DecodableList

Iterator begin() const { return Iterator(mReader); }

/*
* Compute the size of the list. This can fail if the TLV is malformed. If
* this succeeds, that does not guarantee that the individual items can be
* successfully decoded; consumers should check Iterator::GetStatus() when
* actually decoding them.
*/
CHIP_ERROR ComputeSize(size_t * size) const { return mReader.CountRemainingInContainer(size); }

private:
TLV::TLVReader mReader;
};
Expand Down

0 comments on commit 4204893

Please sign in to comment.