Skip to content

Commit

Permalink
Switch DataModel::Provider to a span-based list iterator - flash and …
Browse files Browse the repository at this point in the history
…ram savings, simpler interface (#37033)

* Copied over the new AttributePathExpandIterator and will incrementally use it (so I can validate tests)

* Rename AttributePathExpandIterator to legacy

* Prepare for using new style iterators ... checking NOT YET enabled though

* Enabled checks ... and unit tests fail, but this now can be debugged

* Fix some of the underlying bugs: read handling logic assumes we are ok to undo

* Unit tests pass now

* Restyle

* Use new iterator in IME

* Update logic to use the new iterator on testRead

* more updates

* Restyle

* Remove the legacy attribute path expand iterator

* Update naming

* Restyle

* Remove extra argument for ReadHandler constructor

* Restyle

* Slight flash improvement

* Fix up includes

* Removed empty line

* added comment on why state is a friend class

* Comment updates

* Restyle, add some comments and add extra checks on validity check only for expansion. This saves a tiny amount of flash (32 bytes)

* Remove an include

* Comment updates, renamed mLastOutputPath to mOutputPath

* Fix one typo

* Re-arrange members of ReadHandler to optimize for memory layout. This saves 8 bytes for struct. We still have a 20-byte padding which I am unsure how to get rid of

* Restyle

* Rename State to Position

* One more rename

* Remove redundant assigment ...we are at a net 0 txt increase now on qpg

* Add more unit tests for non-obvious requirement that wildcard expansion checks path validity, however non-wildcard does not check it

* Update src/app/AttributePathExpandIterator.cpp

Co-authored-by: Tennessee Carmel-Veilleux <tennessee.carmelveilleux@gmail.com>

* Update src/app/AttributePathExpandIterator.h

Co-authored-by: Tennessee Carmel-Veilleux <tennessee.carmelveilleux@gmail.com>

* Update src/app/AttributePathExpandIterator.h

Co-authored-by: Tennessee Carmel-Veilleux <tennessee.carmelveilleux@gmail.com>

* Update src/app/AttributePathExpandIterator.h

Co-authored-by: Tennessee Carmel-Veilleux <tennessee.carmelveilleux@gmail.com>

* Update src/app/ReadHandler.h

Co-authored-by: Tennessee Carmel-Veilleux <tennessee.carmelveilleux@gmail.com>

* Update src/app/ReadHandler.cpp

Co-authored-by: Tennessee Carmel-Veilleux <tennessee.carmelveilleux@gmail.com>

* Update src/app/AttributePathExpandIterator.h

Co-authored-by: Tennessee Carmel-Veilleux <tennessee.carmelveilleux@gmail.com>

* Use different values for the cluster ids for testing

* One more state to position change

* mExpanded is now set during output path returning. Removed 2 more sets to save another tinier amount of .text

* Import metadatalist class and test

* Remove some tests that seem redundant, keep only one

* Start with generated commands, see if we can replace its usage...

* Unit tests for GeneratedCommands pass

* Start with an implementation of accepted commands (no testing yet)

* More tests pass

* Updated AcceptedCommands as well .. unit tests pass

* Restyle

* Fix namespaces

* Slight refactor. Code is still very much ugly

* A bit of refactor, code looks better and tests pass now

* Code compile for semantic tag ... made std::optional support non-trivial destructors

* Update test

* Make chip::Optional be trivially destructible if the underlying type is.

Previous implementation always had a destructor, so it was never
trivially destructible.

* Update src/app/AttributePathExpandIterator.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/AttributePathExpandIterator.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/AttributePathExpandIterator.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/AttributePathExpandIterator.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/InteractionModelEngine.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/ReadHandler.h

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/AttributePathExpandIterator.h

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/ReadHandler.h

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Use mCompletePosition

* Another rename

* Undo submodule update

* Restyle

* Remove extra char

* Remove unused variable

* Update comment text to not sound like graph parsing

* Rename method to be more descriptive

* Remove one more unused variable

* Update peek attribute iterator to rollback and update code logic a bit. Hoping for cleaner code

* Semantic tags conversion is done

* Restyle

* Migrate device types to the new format

* update comment a bit

* Add unused marker for chip errors used for logging only

* Fix descriptor cluster

* Fix microwave oven

* Restyle

* Fix intentional bugprone-use-after-move

* Fix intentional bugprone-use-after-move

* Restyle

* Fix based on clang feedback

* Move endpoints to the new style of iteration

* Fix includes

* Fix includes

* Fix includes

* make it standard that test Providers are for now CodegenDataModelProvider. Saves me some typing as I move things around

* Restyle

* Minor update in logic: do the endpoint selection when next is called

* Allow startup to try to mark attributes dirty even if no provider exists yet

* Fix typo

* start implementing client clusters

* Update ClientCluster logic

* Restyle

* Start defining the server cluster query

* Actually use the new server cluster functionality

* Fix an include

* More include fixes

* implement the get attributes and adapt unit tests

* Restyle

* more updates to cleanup code. I am a bit concerned about O(n^2) attribute access...

* A rename and moved finder methods out of inline. Saves 650 bytes of flash

* Update logic to centralize metadata list code with less templating

* move the generic metadata list to detail, add an assert on trivial destruction

* Fix namespace prefix

* Save 70 bytes by using references in condensed for loops

* Replace count-if because it seems to result in smaller code (46 bytes)

* Another find_if replacement

* Replaced some find_if...we are down to 92 bytes on qpg

* Replaced one more find-if, saving another 88 bytes of flash

* Removed algorithm includes: these are slow and would like compile to fail if used

* Save more flash ... we should be at a net negative now

* This seems to save even more

* More savings by more encode overrides ... this is silly...

* Fix typos

* More explicit casting, removed 64-bit overrides

* Added one more check for freeing memory .Still need to track a leak that darwin finds

* Fix memory leak in assignment

* Self-review: fix includes

* Self-review: fix includes

* Self-review: fix includes

* Self-review: fix includes

* Update src/data-model-providers/codegen/CodegenDataModelProvider.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/data-model-providers/codegen/CodegenDataModelProvider.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/AttributePathExpandIterator.h

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/AttributePathExpandIterator.h

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/clusters/descriptor/descriptor.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/clusters/descriptor/descriptor.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/data-model-provider/MetadataList.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Fix spelling for acquire

* Update src/app/data-model-provider/MetadataList.h

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/data-model-provider/MetadataList.h

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/data-model-provider/MetadataList.h

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Fix is_trivially_destructible

* Update src/app/data-model-provider/MetadataSearch.h

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* More fixes

* Fix includes

* Fix invalid check typo

* Fix comment

* Correct comment

* Updated comment

* Make logic between clusters/attributes/endpoints the same regarding nullopt and wildcards

* Restyle

* Update logic for IsDescentantof

* Help compiler generate efficient code as we keep reusing the same pointer

* clearer logic that we handle all cases

* Fixes

* Use calloc

* Update comment

* Fix include

* Fix casting

* Make cluster count functions from ember public API since they seem reusable

* Also fix dynamic dispatch

* update enumeration entry

* another comment update

* Undo submodule update

* Rename metadata search to metadta lookup

* Update metadata list methods to be all uppercase

* Fix more renames

* Fix invalid cast

* Update src/data-model-providers/codegen/CodegenDataModelProvider.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/data-model-providers/codegen/CodegenDataModelProvider.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/data-model-providers/codegen/CodegenDataModelProvider.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/data-model-provider/MetadataList.h

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Address comments

* fix bug

* Update src/app/AttributePathExpandIterator.cpp

Co-authored-by: Mathieu Kardous <84793247+mkardous-silabs@users.noreply.github.com>

* Update src/app/WriteHandler.cpp

Co-authored-by: Mathieu Kardous <84793247+mkardous-silabs@users.noreply.github.com>

* Update src/app/AttributePathExpandIterator.cpp

Co-authored-by: Mathieu Kardous <84793247+mkardous-silabs@users.noreply.github.com>

* Restyle and include update

---------

Co-authored-by: Andrei Litvin <andreilitvin@google.com>
Co-authored-by: Tennessee Carmel-Veilleux <tennessee.carmelveilleux@gmail.com>
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
Co-authored-by: Mathieu Kardous <84793247+mkardous-silabs@users.noreply.github.com>
  • Loading branch information
5 people authored Jan 20, 2025
1 parent f19f44a commit 2ecbcc2
Show file tree
Hide file tree
Showing 38 changed files with 1,920 additions and 1,925 deletions.
5 changes: 4 additions & 1 deletion examples/common/pigweed/rpc_services/Attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <app/InteractionModelEngine.h>
#include <app/MessageDef/AttributeReportIBs.h>
#include <app/data-model-provider/ActionReturnStatus.h>
#include <app/data-model-provider/MetadataLookup.h>
#include <app/data-model-provider/OperationTypes.h>
#include <app/data-model-provider/Provider.h>
#include <app/util/attribute-storage.h>
Expand Down Expand Up @@ -221,7 +222,9 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service<Attributes>
request.operationFlags.Set(app::DataModel::OperationFlags::kInternal);
request.subjectDescriptor = &subjectDescriptor;

std::optional<app::DataModel::ClusterInfo> info = provider->GetServerClusterInfo(path);
app::DataModel::ServerClusterFinder serverClusterFinder(provider);
auto info = serverClusterFinder.Find(path);

if (!info.has_value())
{
return ::pw::Status::NotFound();
Expand Down
6 changes: 3 additions & 3 deletions src/access/ProviderDeviceTypeResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ class DynamicProviderDeviceTypeResolver : public chip::Access::AccessControl::De

bool IsDeviceTypeOnEndpoint(chip::DeviceTypeId deviceType, chip::EndpointId endpoint) override
{
app::DataModel::Provider * model = mModelGetter();
for (auto type = model->FirstDeviceType(endpoint); type.has_value(); type = model->NextDeviceType(endpoint, *type))
auto deviceTypes = mModelGetter()->DeviceTypes(endpoint);
for (auto & type : deviceTypes.GetSpanValidForLifetime())
{
if (type->deviceTypeId == deviceType)
if (type.deviceTypeId == deviceType)
{
return true;
}
Expand Down
173 changes: 132 additions & 41 deletions src/app/AttributePathExpandIterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#include <app/AttributePathExpandIterator.h>

#include <app/GlobalAttributes.h>
#include <app/data-model-provider/MetadataLookup.h>
#include <app/data-model-provider/MetadataTypes.h>
#include <lib/core/DataModelTypes.h>
#include <lib/support/CodeUtils.h>

#include <optional>
Expand All @@ -26,6 +29,10 @@ using namespace chip::app::DataModel;
namespace chip {
namespace app {

AttributePathExpandIterator::AttributePathExpandIterator(DataModel::Provider * dataModel, Position & position) :
mDataModelProvider(dataModel), mPosition(position)
{}

bool AttributePathExpandIterator::AdvanceOutputPath()
{
/// Output path invariants
Expand Down Expand Up @@ -113,34 +120,61 @@ bool AttributePathExpandIterator::IsValidAttributeId(AttributeId attributeId)
break;
}

DataModel::AttributeFinder finder(mDataModelProvider);

const ConcreteAttributePath attributePath(mPosition.mOutputPath.mEndpointId, mPosition.mOutputPath.mClusterId, attributeId);
return mDataModelProvider->GetAttributeInfo(attributePath).has_value();
return finder.Find(attributePath).has_value();
}

std::optional<AttributeId> AttributePathExpandIterator::NextAttributeId()
{
if (mPosition.mOutputPath.mAttributeId == kInvalidAttributeId)
{
if (mPosition.mAttributePath->mValue.HasWildcardAttributeId())
// Attribute ID is tied to attribute index. If no attribute id is available yet
// this means the index is invalid. Processing logic in output advance only resets
// attribute ID to invalid when resetting iteration.
mAttributeIndex = kInvalidIndex;
}

if (mAttributeIndex == kInvalidIndex)
{
// start a new iteration of attributes on the current cluster path.
mAttributes = mDataModelProvider->Attributes(mPosition.mOutputPath);

if (mPosition.mOutputPath.mAttributeId != kInvalidAttributeId)
{
AttributeEntry entry = mDataModelProvider->FirstAttribute(mPosition.mOutputPath);
return entry.IsValid() //
? entry.path.mAttributeId //
: Clusters::Globals::Attributes::GeneratedCommandList::Id; //
// Position on the correct attribute if we have a start point
mAttributeIndex = 0;
while ((mAttributeIndex < mAttributes.Size()) &&
(mAttributes[mAttributeIndex].attributeId != mPosition.mOutputPath.mAttributeId))
{
mAttributeIndex++;
}
}
}

// At this point, the attributeID is NOT a wildcard (i.e. it is fixed).
//
// For wildcard expansion, we validate that this is a valid attribute for the given
// cluster on the given endpoint. If not a wildcard expansion, return it as-is.
if (mPosition.mAttributePath->mValue.IsWildcardPath())
if (mPosition.mOutputPath.mAttributeId == kInvalidAttributeId)
{
if (!mPosition.mAttributePath->mValue.HasWildcardAttributeId())
{
if (!IsValidAttributeId(mPosition.mAttributePath->mValue.mAttributeId))
// The attributeID is NOT a wildcard (i.e. it is fixed).
//
// For wildcard expansion, we validate that this is a valid attribute for the given
// cluster on the given endpoint. If not a wildcard expansion, return it as-is.
if (mPosition.mAttributePath->mValue.IsWildcardPath())
{
return std::nullopt;
if (!IsValidAttributeId(mPosition.mAttributePath->mValue.mAttributeId))
{
return std::nullopt;
}
}
return mPosition.mAttributePath->mValue.mAttributeId;
}
return mPosition.mAttributePath->mValue.mAttributeId;
mAttributeIndex = 0;
}
else
{
mAttributeIndex++;
}

// Advance the existing attribute id if it can be advanced.
Expand All @@ -165,10 +199,9 @@ std::optional<AttributeId> AttributePathExpandIterator::NextAttributeId()
return std::nullopt;
}

AttributeEntry entry = mDataModelProvider->NextAttribute(mPosition.mOutputPath);
if (entry.IsValid())
if (mAttributeIndex < mAttributes.Size())
{
return entry.path.mAttributeId;
return mAttributes[mAttributeIndex].attributeId;
}

// Finished the data model, start with global attributes
Expand All @@ -178,55 +211,113 @@ std::optional<AttributeId> AttributePathExpandIterator::NextAttributeId()

std::optional<ClusterId> AttributePathExpandIterator::NextClusterId()
{

if (mPosition.mOutputPath.mClusterId == kInvalidClusterId)
{
if (mPosition.mAttributePath->mValue.HasWildcardClusterId())
// Cluster ID is tied to cluster index. If no cluster id available yet
// this means index is invalid. Processing logic in output advance only resets
// cluster ID to invalid when resetting iteration.
mClusterIndex = kInvalidIndex;
}

if (mClusterIndex == kInvalidIndex)
{
// start a new iteration on the current endpoint
mClusters = mDataModelProvider->ServerClusters(mPosition.mOutputPath.mEndpointId);

if (mPosition.mOutputPath.mClusterId != kInvalidClusterId)
{
ClusterEntry entry = mDataModelProvider->FirstServerCluster(mPosition.mOutputPath.mEndpointId);
return entry.IsValid() ? std::make_optional(entry.path.mClusterId) : std::nullopt;
// Position on the correct cluster if we have a start point
mClusterIndex = 0;
while ((mClusterIndex < mClusters.Size()) && (mClusters[mClusterIndex].clusterId != mPosition.mOutputPath.mClusterId))
{
mClusterIndex++;
}
}
}

// At this point, the clusterID is NOT a wildcard (i.e. is fixed).
//
// For wildcard expansion, we validate that this is a valid cluster for the endpoint.
// If non-wildcard expansion, we return as-is.
if (mPosition.mAttributePath->mValue.IsWildcardPath())
if (mPosition.mOutputPath.mClusterId == kInvalidClusterId)
{

if (!mPosition.mAttributePath->mValue.HasWildcardClusterId())
{
const ConcreteClusterPath clusterPath(mPosition.mOutputPath.mEndpointId, mPosition.mAttributePath->mValue.mClusterId);
if (!mDataModelProvider->GetServerClusterInfo(clusterPath).has_value())
// The clusterID is NOT a wildcard (i.e. is fixed).
//
// For wildcard expansion, we validate that this is a valid cluster for the endpoint.
// If non-wildcard expansion, we return as-is.
if (mPosition.mAttributePath->mValue.IsWildcardPath())
{
return std::nullopt;
const ClusterId clusterId = mPosition.mAttributePath->mValue.mClusterId;

auto span = mClusters.GetSpanValidForLifetime();

bool found = false;
for (auto & entry : span)
{
if (entry.clusterId == clusterId)
{
found = true;
break;
}
}

if (!found)
{
return std::nullopt;
}
}
}

return mPosition.mAttributePath->mValue.mClusterId;
return mPosition.mAttributePath->mValue.mClusterId;
}
mClusterIndex = 0;
}
else
{
mClusterIndex++;
}

VerifyOrReturnValue(mPosition.mAttributePath->mValue.HasWildcardClusterId(), std::nullopt);
VerifyOrReturnValue(mClusterIndex < mClusters.Size(), std::nullopt);

ClusterEntry entry = mDataModelProvider->NextServerCluster(mPosition.mOutputPath);
return entry.IsValid() ? std::make_optional(entry.path.mClusterId) : std::nullopt;
return mClusters[mClusterIndex].clusterId;
}

std::optional<ClusterId> AttributePathExpandIterator::NextEndpointId()
std::optional<EndpointId> AttributePathExpandIterator::NextEndpointId()
{
if (mEndpointIndex == kInvalidIndex)
{
// index is missing, have to start a new iteration
mEndpoints = mDataModelProvider->Endpoints();

if (mPosition.mOutputPath.mEndpointId != kInvalidEndpointId)
{
// Position on the correct endpoint if we have a start point
mEndpointIndex = 0;
while ((mEndpointIndex < mEndpoints.Size()) && (mEndpoints[mEndpointIndex].id != mPosition.mOutputPath.mEndpointId))
{
mEndpointIndex++;
}
}
}

if (mPosition.mOutputPath.mEndpointId == kInvalidEndpointId)
{
if (mPosition.mAttributePath->mValue.HasWildcardEndpointId())
if (!mPosition.mAttributePath->mValue.HasWildcardEndpointId())
{
EndpointEntry ep = mDataModelProvider->FirstEndpoint();
return (ep.id != kInvalidEndpointId) ? std::make_optional(ep.id) : std::nullopt;
return mPosition.mAttributePath->mValue.mEndpointId;
}

return mPosition.mAttributePath->mValue.mEndpointId;
// start from the beginning
mEndpointIndex = 0;
}
else
{
mEndpointIndex++;
}

// Expand endpoints only if it is a wildcard on the endpoint specifically.
VerifyOrReturnValue(mPosition.mAttributePath->mValue.HasWildcardEndpointId(), std::nullopt);
VerifyOrReturnValue(mEndpointIndex < mEndpoints.Size(), std::nullopt);

EndpointEntry ep = mDataModelProvider->NextEndpoint(mPosition.mOutputPath.mEndpointId);
return (ep.id != kInvalidEndpointId) ? std::make_optional(ep.id) : std::nullopt;
return mEndpoints[mEndpointIndex].id;
}

} // namespace app
Expand Down
22 changes: 18 additions & 4 deletions src/app/AttributePathExpandIterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@

#include <app/AttributePathParams.h>
#include <app/ConcreteAttributePath.h>
#include <app/data-model-provider/MetadataList.h>
#include <app/data-model-provider/MetadataTypes.h>
#include <app/data-model-provider/Provider.h>
#include <lib/core/DataModelTypes.h>
#include <lib/support/LinkedList.h>
#include <lib/support/Span.h>

#include <limits>

namespace chip {
namespace app {
Expand Down Expand Up @@ -96,9 +101,7 @@ class AttributePathExpandIterator
ConcreteAttributePath mOutputPath;
};

AttributePathExpandIterator(DataModel::Provider * dataModel, Position & position) :
mDataModelProvider(dataModel), mPosition(position)
{}
AttributePathExpandIterator(DataModel::Provider * dataModel, Position & position);

// This class may not be copied. A new one should be created when needed and they
// should not overlap.
Expand All @@ -113,9 +116,20 @@ class AttributePathExpandIterator
bool Next(ConcreteAttributePath & path);

private:
static constexpr size_t kInvalidIndex = std::numeric_limits<size_t>::max();

DataModel::Provider * mDataModelProvider;
Position & mPosition;

DataModel::MetadataList<DataModel::EndpointEntry> mEndpoints; // all endpoints
size_t mEndpointIndex = kInvalidIndex;

DataModel::MetadataList<DataModel::ServerClusterEntry> mClusters; // all clusters ON THE CURRENT endpoint
size_t mClusterIndex = kInvalidIndex;

DataModel::MetadataList<DataModel::AttributeEntry> mAttributes; // all attributes ON THE CURRENT cluster
size_t mAttributeIndex = kInvalidIndex;

/// Move to the next endpoint/cluster/attribute triplet that is valid given
/// the current mOutputPath and mpAttributePath.
///
Expand All @@ -140,7 +154,7 @@ class AttributePathExpandIterator
/// Will start from the beginning if current mOutputPath.mEndpointId is kInvalidEndpointId
///
/// Respects path expansion/values in mpAttributePath
std::optional<ClusterId> NextEndpointId();
std::optional<EndpointId> NextEndpointId();

/// Checks if the given attributeId is valid for the current mOutputPath(endpoint/cluster)
///
Expand Down
28 changes: 28 additions & 0 deletions src/app/AttributeValueEncoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,34 @@ class AttributeValueEncoder
return mAttributeValueEncoder.EncodeListItem(mCheckpoint, aArg);
}

// overrides that save flash: no need to care about the extra const
// Without this, we have a usage of:
// chip::ChipError chip::app::AttributeValueEncoder::EncodeListItem<unsigned long const&>
// Overall we tend to have very similar code expand (from nm):
// chip::ChipError chip::app::AttributeValueEncoder::Encode<unsigned char>(unsigned char&&)
// chip::ChipError chip::app::AttributeValueEncoder::Encode<unsigned char&>(unsigned char&)
// chip::ChipError chip::app::AttributeValueEncoder::Encode<unsigned char const&>(unsigned char const&)
// chip::ChipError chip::app::AttributeValueEncoder::Encode<unsigned short const&>(unsigned short const&)
// chip::ChipError chip::app::AttributeValueEncoder::Encode<unsigned long&>(unsigned long&)
// chip::ChipError chip::app::AttributeValueEncoder::Encode<unsigned short&>(unsigned short&)
// chip::ChipError chip::app::AttributeValueEncoder::Encode<unsigned long long&>(unsigned long long&)
// chip::ChipError chip::app::AttributeValueEncoder::Encode<unsigned short>(unsigned short&&)
// chip::ChipError chip::app::AttributeValueEncoder::Encode<unsigned long long>(unsigned long long&&)
// that we try to reduce
//
// TODO:
// - we should figure where the extra const override is used
// - we should try to avoid having such footguns. This list template-explosion seems
// dangerous for flash.
//
// This relies on TLV numbers always being encoded as 64-bit value
inline CHIP_ERROR Encode(uint32_t const & aArg) const { return Encode<uint64_t>(aArg); }
inline CHIP_ERROR Encode(uint32_t & aArg) const { return Encode<uint64_t>(aArg); }
inline CHIP_ERROR Encode(uint16_t const & aArg) const { return Encode<uint64_t>(aArg); }
inline CHIP_ERROR Encode(uint16_t & aArg) const { return Encode<uint64_t>(aArg); }
inline CHIP_ERROR Encode(uint8_t const & aArg) const { return Encode<uint64_t>(aArg); }
inline CHIP_ERROR Encode(uint8_t & aArg) const { return Encode<uint64_t>(aArg); }

private:
AttributeValueEncoder & mAttributeValueEncoder;
// Avoid calling the TLVWriter constructor for every instantiation of
Expand Down
Loading

0 comments on commit 2ecbcc2

Please sign in to comment.