diff --git a/src/app/AttributeEncodeState.h b/src/app/AttributeEncodeState.h index 762faf8416d75d..f91c0081a7a92c 100644 --- a/src/app/AttributeEncodeState.h +++ b/src/app/AttributeEncodeState.h @@ -21,14 +21,38 @@ namespace chip { namespace app { -/** - * Maintains the internal state of list encoding - */ +/// Maintains the internal state of list encoding +/// +/// List encoding is generally assumed incremental and chunkable (i.e. +/// partial encoding is ok.). For this purpose the class maintains two +/// pieces of data: +/// - AllowPartialData tracks if partial encoding is acceptable in the +/// current encoding state (to be used for atomic/non-atomic list item writes) +/// - CurrentEncodingListIndex representing the list index that is next +/// to be encoded in the output. kInvalidListIndex means that a new list +/// encoding has been started. class AttributeEncodeState { public: AttributeEncodeState() = default; + /// Allows the encode state to be initialized from an OPTIONAL + /// other encoding state + /// + /// if other is nullptr, this is the same as the default initializer. + AttributeEncodeState(AttributeEncodeState * other) + { + if (other != nullptr) + { + *this = *other; + } + else + { + mCurrentEncodingListIndex = kInvalidListIndex; + mAllowPartialData = false; + } + } + bool AllowPartialData() const { return mAllowPartialData; } ListIndex CurrentEncodingListIndex() const { return mCurrentEncodingListIndex; } diff --git a/src/app/AttributeValueEncoder.h b/src/app/AttributeValueEncoder.h index c2593c9ccecd20..52999e912dbd24 100644 --- a/src/app/AttributeValueEncoder.h +++ b/src/app/AttributeValueEncoder.h @@ -17,8 +17,8 @@ #pragma once #include -#include #include +#include #include #include #include @@ -141,7 +141,7 @@ class AttributeValueEncoder if (err == CHIP_NO_ERROR) { // The Encode procedure finished without any error, clear the state. - mEncodeState = AttributeEncodeState(); + mEncodeState.Reset(); } return err; } diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index 5534fb13ce05bb..e40847403cd01f 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -277,8 +277,8 @@ source_set("events") { static_library("attribute-access") { sources = [ - "AttributeAccessInterfaceCache.h", "AttributeAccessInterface.h", + "AttributeAccessInterfaceCache.h", "AttributeAccessInterfaceRegistry.cpp", "AttributeAccessInterfaceRegistry.h", "AttributeEncodeState.h", diff --git a/src/app/util/ember-compatibility-functions.cpp b/src/app/util/ember-compatibility-functions.cpp index b2b3d2dc929412..392404d084d8a6 100644 --- a/src/app/util/ember-compatibility-functions.cpp +++ b/src/app/util/ember-compatibility-functions.cpp @@ -430,12 +430,7 @@ CHIP_ERROR ReadViaAccessInterface(SubjectDescriptor subjectDescriptor, bool aIsF AttributeEncodeState * aEncoderState, AttributeAccessInterface * aAccessInterface, bool * aTriedEncode) { - AttributeEncodeState state; - if (aEncoderState != nullptr) - { - state = *aEncoderState; - } - + AttributeEncodeState state(aEncoderState); DataVersion version = 0; ReturnErrorOnFailure(ReadClusterDataVersion(aPath, version)); AttributeValueEncoder valueEncoder(aAttributeReports, subjectDescriptor, aPath, version, aIsFabricFiltered, state); diff --git a/src/app/util/mock/attribute-storage.cpp b/src/app/util/mock/attribute-storage.cpp index b7f93ed0da301a..2293a48a8403e4 100644 --- a/src/app/util/mock/attribute-storage.cpp +++ b/src/app/util/mock/attribute-storage.cpp @@ -350,11 +350,7 @@ CHIP_ERROR ReadSingleMockClusterData(FabricIndex aAccessingFabricIndex, const Co // Attribute 4 acts as a large attribute to trigger chunking. if (aPath.mAttributeId == MockAttributeId(4)) { - AttributeEncodeState state; - if (apEncoderState != nullptr) - { - state = *apEncoderState; - } + AttributeEncodeState state(apEncoderState); Access::SubjectDescriptor subject; subject.fabricIndex = aAccessingFabricIndex; diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index 4413e619fe6395..bcf0233662d2bc 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -109,11 +109,7 @@ CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescr // Use an incorrect attribute id for some of the responses. path.mAttributeId = static_cast(path.mAttributeId + (i / 2) + (responseDirective == kSendManyDataResponsesWrongPath)); - AttributeEncodeState state; - if (apEncoderState != nullptr) - { - state = *apEncoderState; - } + AttributeEncodeState state(apEncoderState); AttributeValueEncoder valueEncoder(aAttributeReports, aSubjectDescriptor, path, kDataVersion, aIsFabricFiltered, state); ReturnErrorOnFailure(valueEncoder.Encode(true)); } @@ -126,11 +122,7 @@ CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescr if (aPath.mClusterId == app::Clusters::UnitTesting::Id && aPath.mAttributeId == app::Clusters::UnitTesting::Attributes::ListFabricScoped::Id) { - AttributeEncodeState state; - if (apEncoderState != nullptr) - { - state = *apEncoderState; - } + AttributeEncodeState state(apEncoderState); AttributeValueEncoder valueEncoder(aAttributeReports, aSubjectDescriptor, aPath, kDataVersion, aIsFabricFiltered, state); @@ -146,11 +138,7 @@ CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescr if (aPath.mClusterId == app::Clusters::UnitTesting::Id && aPath.mAttributeId == app::Clusters::UnitTesting::Attributes::Int16u::Id) { - AttributeEncodeState state; - if (apEncoderState != nullptr) - { - state = *apEncoderState; - } + AttributeEncodeState state(apEncoderState); AttributeValueEncoder valueEncoder(aAttributeReports, aSubjectDescriptor, aPath, kDataVersion, aIsFabricFiltered, state); @@ -182,11 +170,7 @@ CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescr if (aPath.mClusterId == app::Clusters::IcdManagement::Id && aPath.mAttributeId == app::Clusters::IcdManagement::Attributes::OperatingMode::Id) { - AttributeEncodeState state; - if (apEncoderState != nullptr) - { - state = *apEncoderState; - } + AttributeEncodeState state(apEncoderState); AttributeValueEncoder valueEncoder(aAttributeReports, aSubjectDescriptor, aPath, kDataVersion, aIsFabricFiltered, state);