Skip to content

Commit

Permalink
Some interface cleanup on AttributeValueEncoder. (#12661)
Browse files Browse the repository at this point in the history
1) Address unaddressed or deferred review comments from #12019.
2) Add a simpler way to encode a null value.
  • Loading branch information
bzbarsky-apple authored and pull[bot] committed Dec 28, 2023
1 parent 384af2a commit 3bb4001
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
4 changes: 4 additions & 0 deletions src/app/AttributeAccessInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ CHIP_ERROR AttributeValueEncoder::EncodeEmptyList()
// Put an empty array before encoding the first array element for list chunking.
AttributeReportBuilder builder;

mPath.mListOp = ConcreteDataAttributePath::ListOperation::ReplaceAll;
ReturnErrorOnFailure(builder.PrepareAttribute(mAttributeReportIBsBuilder, mPath, mDataVersion));
ReturnErrorOnFailure(builder.EncodeValue(mAttributeReportIBsBuilder, DataModel::List<uint8_t>()));

Expand All @@ -82,6 +83,9 @@ CHIP_ERROR AttributeValueEncoder::EncodeEmptyList()
// revert partial data.
mEncodeState.mAllowPartialData = true;

// For all elements in the list, a report with append operation will be generated. This will not be changed during encoding
// of each report since the users cannot access mPath.
mPath.mListOp = ConcreteDataAttributePath::ListOperation::AppendItem;
return CHIP_NO_ERROR;
}

Expand Down
31 changes: 22 additions & 9 deletions src/app/AttributeAccessInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,9 @@ class AttributeValueEncoder
{}

/**
* Encode builds a single AttributeReportIB in AttributeReportIBs.
* When we are encoding a single element in the list, the actual path in the report contains a null list index as "append"
* operation.
* Encode a single value. This value will not be chunked; it will either be
* entirely encoded or fail to be encoded. Consumers are allowed to make
* either one call to Encode or one call to EncodeList to handle a read.
*/
template <typename... Ts>
CHIP_ERROR Encode(Ts &&... aArgs)
Expand All @@ -158,6 +158,15 @@ class AttributeValueEncoder
return EncodeAttributeReportIB(std::forward<Ts>(aArgs)...);
}

/**
* Encode an explicit null value.
*/
CHIP_ERROR EncodeNull()
{
// Doesn't matter what type Nullable we use here.
return Encode(DataModel::Nullable<uint8_t>());
}

/**
* aCallback is expected to take a const auto & argument and Encode() on it as many times as needed to encode all the list
* elements one by one. If any of those Encode() calls returns failure, aCallback must stop encoding and return failure. When
Expand All @@ -181,11 +190,7 @@ class AttributeValueEncoder
// EmptyList acts as the beginning of the whole array type attribute report.
// An empty list is encoded iff both mCurrentEncodingListIndex and mEncodeState.mCurrentEncodingListIndex are invalid
// values. After encoding the empty list, mEncodeState.mCurrentEncodingListIndex and mCurrentEncodingListIndex are set to 0.
mPath.mListOp = ConcreteDataAttributePath::ListOperation::ReplaceAll;
ReturnErrorOnFailure(EncodeEmptyList());
// For all elements in the list, a report with append operation will be generated. This will not be changed during encoding
// of each report since the users cannot access mPath.
mPath.mListOp = ConcreteDataAttributePath::ListOperation::AppendItem;
ReturnErrorOnFailure(aCallback(ListEncodeHelper(*this)));
// The Encode procedure finished without any error, clear the state.
mEncodeState = AttributeEncodeState();
Expand Down Expand Up @@ -239,12 +244,16 @@ class AttributeValueEncoder
}

/**
* Actual logic for encoding a single AttributeReportIB in AttributeReportIBs.
* Builds a single AttributeReportIB in AttributeReportIBs. The caller is
* responsible for setting up mPath correctly.
*
* In particular, when we are encoding a single element in the list, mPath
* must indicate a null list index to represent an "append" operation.
* operation.
*/
template <typename... Ts>
CHIP_ERROR EncodeAttributeReportIB(Ts &&... aArgs)
{
mTriedEncode = true;
AttributeReportBuilder builder;

ReturnErrorOnFailure(builder.PrepareAttribute(mAttributeReportIBsBuilder, mPath, mDataVersion));
Expand All @@ -258,6 +267,10 @@ class AttributeValueEncoder
*
* If internal state indicates we have already encoded the empty list, this function will encode nothing, set
* mCurrentEncodingListIndex to 0 and return CHIP_NO_ERROR.
*
* In all cases this function guarantees that mPath.mListOp is AppendItem
* after it returns, because at that point we will be encoding the list
* items.
*/
CHIP_ERROR EncodeEmptyList();

Expand Down

0 comments on commit 3bb4001

Please sign in to comment.