@@ -27,14 +27,14 @@ namespace app {
27
27
namespace {
28
28
29
29
// Determine how much space a StatusIB takes up on the wire.
30
- size_t SizeOfStatusIB (const StatusIB & aStatus)
30
+ uint32_t SizeOfStatusIB (const StatusIB & aStatus)
31
31
{
32
32
// 1 byte: anonymous tag control byte for struct.
33
33
// 1 byte: control byte for uint8 value.
34
34
// 1 byte: context-specific tag for uint8 value.
35
35
// 1 byte: the uint8 value.
36
36
// 1 byte: end of container.
37
- size_t size = 5 ;
37
+ uint32_t size = 5 ;
38
38
39
39
if (aStatus.mClusterStatus .HasValue ())
40
40
{
@@ -49,7 +49,8 @@ size_t SizeOfStatusIB(const StatusIB & aStatus)
49
49
50
50
} // anonymous namespace
51
51
52
- CHIP_ERROR ClusterStateCache::GetElementTLVSize (TLV::TLVReader * apData, size_t & aSize)
52
+ template <bool CanEnableDataCaching>
53
+ CHIP_ERROR ClusterStateCacheT<CanEnableDataCaching>::GetElementTLVSize(TLV::TLVReader * apData, uint32_t & aSize)
53
54
{
54
55
Platform::ScopedMemoryBufferWithSize<uint8_t > backingBuffer;
55
56
TLV::TLVReader reader;
@@ -64,8 +65,9 @@ CHIP_ERROR ClusterStateCache::GetElementTLVSize(TLV::TLVReader * apData, size_t
64
65
return CHIP_NO_ERROR;
65
66
}
66
67
67
- CHIP_ERROR ClusterStateCache::UpdateCache (const ConcreteDataAttributePath & aPath, TLV::TLVReader * apData,
68
- const StatusIB & aStatus)
68
+ template <bool CanEnableDataCaching>
69
+ CHIP_ERROR ClusterStateCacheT<CanEnableDataCaching>::UpdateCache(const ConcreteDataAttributePath & aPath, TLV::TLVReader * apData,
70
+ const StatusIB & aStatus)
69
71
{
70
72
AttributeState state;
71
73
bool endpointIsNew = false ;
@@ -82,24 +84,32 @@ CHIP_ERROR ClusterStateCache::UpdateCache(const ConcreteDataAttributePath & aPat
82
84
83
85
if (apData)
84
86
{
85
- size_t elementSize = 0 ;
87
+ uint32_t elementSize = 0 ;
86
88
ReturnErrorOnFailure (GetElementTLVSize (apData, elementSize));
87
89
88
- if ( mCacheData )
90
+ if constexpr (CanEnableDataCaching )
89
91
{
90
- Platform::ScopedMemoryBufferWithSize<uint8_t > backingBuffer;
91
- backingBuffer.Calloc (elementSize);
92
- VerifyOrReturnError (backingBuffer.Get () != nullptr , CHIP_ERROR_NO_MEMORY);
93
- TLV::ScopedBufferTLVWriter writer (std::move (backingBuffer), elementSize);
94
- ReturnErrorOnFailure (writer.CopyElement (TLV::AnonymousTag (), *apData));
95
- ReturnErrorOnFailure (writer.Finalize (backingBuffer));
96
-
97
- state.Set <AttributeData>(std::move (backingBuffer));
92
+ if (mCacheData )
93
+ {
94
+ Platform::ScopedMemoryBufferWithSize<uint8_t > backingBuffer;
95
+ backingBuffer.Calloc (elementSize);
96
+ VerifyOrReturnError (backingBuffer.Get () != nullptr , CHIP_ERROR_NO_MEMORY);
97
+ TLV::ScopedBufferTLVWriter writer (std::move (backingBuffer), elementSize);
98
+ ReturnErrorOnFailure (writer.CopyElement (TLV::AnonymousTag (), *apData));
99
+ ReturnErrorOnFailure (writer.Finalize (backingBuffer));
100
+
101
+ state.template Set <AttributeData>(std::move (backingBuffer));
102
+ }
103
+ else
104
+ {
105
+ state.template Set <uint32_t >(elementSize);
106
+ }
98
107
}
99
108
else
100
109
{
101
- state. Set < size_t >( elementSize) ;
110
+ state = elementSize;
102
111
}
112
+
103
113
//
104
114
// Clear out the committed data version and only set it again once we have received all data for this cluster.
105
115
// Otherwise, we may have incomplete data that looks like it's complete since it has a valid data version.
@@ -132,13 +142,20 @@ CHIP_ERROR ClusterStateCache::UpdateCache(const ConcreteDataAttributePath & aPat
132
142
}
133
143
else
134
144
{
135
- if ( mCacheData )
145
+ if constexpr (CanEnableDataCaching )
136
146
{
137
- state.Set <StatusIB>(aStatus);
147
+ if (mCacheData )
148
+ {
149
+ state.template Set <StatusIB>(aStatus);
150
+ }
151
+ else
152
+ {
153
+ state.template Set <uint32_t >(SizeOfStatusIB (aStatus));
154
+ }
138
155
}
139
156
else
140
157
{
141
- state. Set < size_t >( SizeOfStatusIB (aStatus) );
158
+ state = SizeOfStatusIB (aStatus);
142
159
}
143
160
}
144
161
@@ -161,7 +178,9 @@ CHIP_ERROR ClusterStateCache::UpdateCache(const ConcreteDataAttributePath & aPat
161
178
return CHIP_NO_ERROR;
162
179
}
163
180
164
- CHIP_ERROR ClusterStateCache::UpdateEventCache (const EventHeader & aEventHeader, TLV::TLVReader * apData, const StatusIB * apStatus)
181
+ template <bool CanEnableDataCaching>
182
+ CHIP_ERROR ClusterStateCacheT<CanEnableDataCaching>::UpdateEventCache(const EventHeader & aEventHeader, TLV::TLVReader * apData,
183
+ const StatusIB * apStatus)
165
184
{
166
185
if (apData)
167
186
{
@@ -208,15 +227,17 @@ CHIP_ERROR ClusterStateCache::UpdateEventCache(const EventHeader & aEventHeader,
208
227
return CHIP_NO_ERROR;
209
228
}
210
229
211
- void ClusterStateCache::OnReportBegin ()
230
+ template <bool CanEnableDataCaching>
231
+ void ClusterStateCacheT<CanEnableDataCaching>::OnReportBegin()
212
232
{
213
233
mLastReportDataPath = ConcreteClusterPath (kInvalidEndpointId , kInvalidClusterId );
214
234
mChangedAttributeSet .clear ();
215
235
mAddedEndpoints .clear ();
216
236
mCallback .OnReportBegin ();
217
237
}
218
238
219
- void ClusterStateCache::CommitPendingDataVersion ()
239
+ template <bool CanEnableDataCaching>
240
+ void ClusterStateCacheT<CanEnableDataCaching>::CommitPendingDataVersion()
220
241
{
221
242
if (!mLastReportDataPath .IsValidConcreteClusterPath ())
222
243
{
@@ -231,7 +252,8 @@ void ClusterStateCache::CommitPendingDataVersion()
231
252
}
232
253
}
233
254
234
- void ClusterStateCache::OnReportEnd ()
255
+ template <bool CanEnableDataCaching>
256
+ void ClusterStateCacheT<CanEnableDataCaching>::OnReportEnd()
235
257
{
236
258
CommitPendingDataVersion ();
237
259
mLastReportDataPath = ConcreteClusterPath (kInvalidEndpointId , kInvalidClusterId );
@@ -260,26 +282,35 @@ void ClusterStateCache::OnReportEnd()
260
282
mCallback .OnReportEnd ();
261
283
}
262
284
263
- CHIP_ERROR ClusterStateCache::Get (const ConcreteAttributePath & path, TLV::TLVReader & reader) const
285
+ template <>
286
+ CHIP_ERROR ClusterStateCacheT<true >::Get(const ConcreteAttributePath & path, TLV::TLVReader & reader) const
264
287
{
265
288
CHIP_ERROR err;
266
289
auto attributeState = GetAttributeState (path.mEndpointId , path.mClusterId , path.mAttributeId , err);
267
290
ReturnErrorOnFailure (err);
268
- if (attributeState->Is <StatusIB>())
291
+
292
+ if (attributeState->template Is <StatusIB>())
269
293
{
270
294
return CHIP_ERROR_IM_STATUS_CODE_RECEIVED;
271
295
}
272
296
273
- if (!attributeState->Is <AttributeData>())
297
+ if (!attributeState->template Is <AttributeData>())
274
298
{
275
299
return CHIP_ERROR_KEY_NOT_FOUND;
276
300
}
277
301
278
- reader.Init (attributeState->Get <AttributeData>().Get (), attributeState->Get <AttributeData>().AllocatedSize ());
302
+ reader.Init (attributeState->template Get <AttributeData>().Get (), attributeState->template Get <AttributeData>().AllocatedSize ());
279
303
return reader.Next ();
280
304
}
281
305
282
- CHIP_ERROR ClusterStateCache::Get (EventNumber eventNumber, TLV::TLVReader & reader) const
306
+ template <>
307
+ CHIP_ERROR ClusterStateCacheT<false >::Get(const ConcreteAttributePath & path, TLV::TLVReader & reader) const
308
+ {
309
+ return CHIP_ERROR_KEY_NOT_FOUND;
310
+ }
311
+
312
+ template <bool CanEnableDataCaching>
313
+ CHIP_ERROR ClusterStateCacheT<CanEnableDataCaching>::Get(EventNumber eventNumber, TLV::TLVReader & reader) const
283
314
{
284
315
CHIP_ERROR err;
285
316
@@ -295,7 +326,9 @@ CHIP_ERROR ClusterStateCache::Get(EventNumber eventNumber, TLV::TLVReader & read
295
326
return CHIP_NO_ERROR;
296
327
}
297
328
298
- const ClusterStateCache::EndpointState * ClusterStateCache::GetEndpointState (EndpointId endpointId, CHIP_ERROR & err) const
329
+ template <bool CanEnableDataCaching>
330
+ const typename ClusterStateCacheT<CanEnableDataCaching>::EndpointState *
331
+ ClusterStateCacheT<CanEnableDataCaching>::GetEndpointState(EndpointId endpointId, CHIP_ERROR & err) const
299
332
{
300
333
auto endpointIter = mCache .find (endpointId);
301
334
if (endpointIter == mCache .end ())
@@ -308,8 +341,9 @@ const ClusterStateCache::EndpointState * ClusterStateCache::GetEndpointState(End
308
341
return &endpointIter->second ;
309
342
}
310
343
311
- const ClusterStateCache::ClusterState * ClusterStateCache::GetClusterState (EndpointId endpointId, ClusterId clusterId,
312
- CHIP_ERROR & err) const
344
+ template <bool CanEnableDataCaching>
345
+ const typename ClusterStateCacheT<CanEnableDataCaching>::ClusterState *
346
+ ClusterStateCacheT<CanEnableDataCaching>::GetClusterState(EndpointId endpointId, ClusterId clusterId, CHIP_ERROR & err) const
313
347
{
314
348
auto endpointState = GetEndpointState (endpointId, err);
315
349
if (err != CHIP_NO_ERROR)
@@ -328,8 +362,10 @@ const ClusterStateCache::ClusterState * ClusterStateCache::GetClusterState(Endpo
328
362
return &clusterState->second ;
329
363
}
330
364
331
- const ClusterStateCache::AttributeState * ClusterStateCache::GetAttributeState (EndpointId endpointId, ClusterId clusterId,
332
- AttributeId attributeId, CHIP_ERROR & err) const
365
+ template <bool CanEnableDataCaching>
366
+ const typename ClusterStateCacheT<CanEnableDataCaching>::AttributeState *
367
+ ClusterStateCacheT<CanEnableDataCaching>::GetAttributeState(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId,
368
+ CHIP_ERROR & err) const
333
369
{
334
370
auto clusterState = GetClusterState (endpointId, clusterId, err);
335
371
if (err != CHIP_NO_ERROR)
@@ -348,7 +384,9 @@ const ClusterStateCache::AttributeState * ClusterStateCache::GetAttributeState(E
348
384
return &attributeState->second ;
349
385
}
350
386
351
- const ClusterStateCache::EventData * ClusterStateCache::GetEventData (EventNumber eventNumber, CHIP_ERROR & err) const
387
+ template <bool CanEnableDataCaching>
388
+ const typename ClusterStateCacheT<CanEnableDataCaching>::EventData *
389
+ ClusterStateCacheT<CanEnableDataCaching>::GetEventData(EventNumber eventNumber, CHIP_ERROR & err) const
352
390
{
353
391
EventData compareKey;
354
392
@@ -364,7 +402,9 @@ const ClusterStateCache::EventData * ClusterStateCache::GetEventData(EventNumber
364
402
return &(*eventData);
365
403
}
366
404
367
- void ClusterStateCache::OnAttributeData (const ConcreteDataAttributePath & aPath, TLV::TLVReader * apData, const StatusIB & aStatus)
405
+ template <bool CanEnableDataCaching>
406
+ void ClusterStateCacheT<CanEnableDataCaching>::OnAttributeData(const ConcreteDataAttributePath & aPath, TLV::TLVReader * apData,
407
+ const StatusIB & aStatus)
368
408
{
369
409
//
370
410
// Since the cache itself is a ReadClient::Callback, it may be incorrectly passed in directly when registering with the
@@ -394,7 +434,9 @@ void ClusterStateCache::OnAttributeData(const ConcreteDataAttributePath & aPath,
394
434
mCallback .OnAttributeData (aPath, apData ? &dataSnapshot : nullptr , aStatus);
395
435
}
396
436
397
- CHIP_ERROR ClusterStateCache::GetVersion (const ConcreteClusterPath & aPath, Optional<DataVersion> & aVersion) const
437
+ template <bool CanEnableDataCaching>
438
+ CHIP_ERROR ClusterStateCacheT<CanEnableDataCaching>::GetVersion(const ConcreteClusterPath & aPath,
439
+ Optional<DataVersion> & aVersion) const
398
440
{
399
441
VerifyOrReturnError (aPath.IsValidConcreteClusterPath (), CHIP_ERROR_INVALID_ARGUMENT);
400
442
CHIP_ERROR err;
@@ -404,7 +446,9 @@ CHIP_ERROR ClusterStateCache::GetVersion(const ConcreteClusterPath & aPath, Opti
404
446
return CHIP_NO_ERROR;
405
447
}
406
448
407
- void ClusterStateCache::OnEventData (const EventHeader & aEventHeader, TLV::TLVReader * apData, const StatusIB * apStatus)
449
+ template <bool CanEnableDataCaching>
450
+ void ClusterStateCacheT<CanEnableDataCaching>::OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData,
451
+ const StatusIB * apStatus)
408
452
{
409
453
VerifyOrDie (apData != nullptr || apStatus != nullptr );
410
454
@@ -418,23 +462,31 @@ void ClusterStateCache::OnEventData(const EventHeader & aEventHeader, TLV::TLVRe
418
462
mCallback .OnEventData (aEventHeader, apData ? &dataSnapshot : nullptr , apStatus);
419
463
}
420
464
421
- CHIP_ERROR ClusterStateCache::GetStatus (const ConcreteAttributePath & path, StatusIB & status) const
465
+ template <>
466
+ CHIP_ERROR ClusterStateCacheT<true >::GetStatus(const ConcreteAttributePath & path, StatusIB & status) const
422
467
{
423
468
CHIP_ERROR err;
424
469
425
470
auto attributeState = GetAttributeState (path.mEndpointId , path.mClusterId , path.mAttributeId , err);
426
471
ReturnErrorOnFailure (err);
427
472
428
- if (!attributeState->Is <StatusIB>())
473
+ if (!attributeState->template Is <StatusIB>())
429
474
{
430
475
return CHIP_ERROR_INVALID_ARGUMENT;
431
476
}
432
477
433
- status = attributeState->Get <StatusIB>();
478
+ status = attributeState->template Get <StatusIB>();
434
479
return CHIP_NO_ERROR;
435
480
}
436
481
437
- CHIP_ERROR ClusterStateCache::GetStatus (const ConcreteEventPath & path, StatusIB & status) const
482
+ template <>
483
+ CHIP_ERROR ClusterStateCacheT<false >::GetStatus(const ConcreteAttributePath & path, StatusIB & status) const
484
+ {
485
+ return CHIP_ERROR_INVALID_ARGUMENT;
486
+ }
487
+
488
+ template <bool CanEnableDataCaching>
489
+ CHIP_ERROR ClusterStateCacheT<CanEnableDataCaching>::GetStatus(const ConcreteEventPath & path, StatusIB & status) const
438
490
{
439
491
auto statusIter = mEventStatusCache .find (path);
440
492
if (statusIter == mEventStatusCache .end ())
@@ -446,7 +498,8 @@ CHIP_ERROR ClusterStateCache::GetStatus(const ConcreteEventPath & path, StatusIB
446
498
return CHIP_NO_ERROR;
447
499
}
448
500
449
- void ClusterStateCache::GetSortedFilters (std::vector<std::pair<DataVersionFilter, size_t >> & aVector) const
501
+ template <bool CanEnableDataCaching>
502
+ void ClusterStateCacheT<CanEnableDataCaching>::GetSortedFilters(std::vector<std::pair<DataVersionFilter, size_t >> & aVector) const
450
503
{
451
504
for (auto const & endpointIter : mCache )
452
505
{
@@ -463,26 +516,33 @@ void ClusterStateCache::GetSortedFilters(std::vector<std::pair<DataVersionFilter
463
516
464
517
for (auto const & attributeIter : clusterIter.second .mAttributes )
465
518
{
466
- if (attributeIter.second .Is <StatusIB>())
467
- {
468
- clusterSize += SizeOfStatusIB (attributeIter.second .Get <StatusIB>());
469
- }
470
- else if (attributeIter.second .Is <size_t >())
519
+ if constexpr (CanEnableDataCaching)
471
520
{
472
- clusterSize += attributeIter.second .Get <size_t >();
521
+ if (attributeIter.second .template Is <StatusIB>())
522
+ {
523
+ clusterSize += SizeOfStatusIB (attributeIter.second .template Get <StatusIB>());
524
+ }
525
+ else if (attributeIter.second .template Is <uint32_t >())
526
+ {
527
+ clusterSize += attributeIter.second .template Get <uint32_t >();
528
+ }
529
+ else
530
+ {
531
+ VerifyOrDie (attributeIter.second .template Is <AttributeData>());
532
+ TLV::TLVReader bufReader;
533
+ bufReader.Init (attributeIter.second .template Get <AttributeData>().Get (),
534
+ attributeIter.second .template Get <AttributeData>().AllocatedSize ());
535
+ ReturnOnFailure (bufReader.Next ());
536
+ // Skip to the end of the element.
537
+ ReturnOnFailure (bufReader.Skip ());
538
+
539
+ // Compute the amount of value data
540
+ clusterSize += bufReader.GetLengthRead ();
541
+ }
473
542
}
474
543
else
475
544
{
476
- VerifyOrDie (attributeIter.second .Is <AttributeData>());
477
- TLV::TLVReader bufReader;
478
- bufReader.Init (attributeIter.second .Get <AttributeData>().Get (),
479
- attributeIter.second .Get <AttributeData>().AllocatedSize ());
480
- ReturnOnFailure (bufReader.Next ());
481
- // Skip to the end of the element.
482
- ReturnOnFailure (bufReader.Skip ());
483
-
484
- // Compute the amount of value data
485
- clusterSize += bufReader.GetLengthRead ();
545
+ clusterSize += attributeIter.second ;
486
546
}
487
547
}
488
548
@@ -505,9 +565,10 @@ void ClusterStateCache::GetSortedFilters(std::vector<std::pair<DataVersionFilter
505
565
});
506
566
}
507
567
508
- CHIP_ERROR ClusterStateCache::OnUpdateDataVersionFilterList (DataVersionFilterIBs::Builder & aDataVersionFilterIBsBuilder,
509
- const Span<AttributePathParams> & aAttributePaths,
510
- bool & aEncodedDataVersionList)
568
+ template <bool CanEnableDataCaching>
569
+ CHIP_ERROR ClusterStateCacheT<CanEnableDataCaching>::OnUpdateDataVersionFilterList(
570
+ DataVersionFilterIBs::Builder & aDataVersionFilterIBsBuilder, const Span<AttributePathParams> & aAttributePaths,
571
+ bool & aEncodedDataVersionList)
511
572
{
512
573
CHIP_ERROR err = CHIP_NO_ERROR;
513
574
TLV::TLVWriter backup;
@@ -587,7 +648,8 @@ CHIP_ERROR ClusterStateCache::OnUpdateDataVersionFilterList(DataVersionFilterIBs
587
648
return err;
588
649
}
589
650
590
- CHIP_ERROR ClusterStateCache::GetLastReportDataPath (ConcreteClusterPath & aPath)
651
+ template <bool CanEnableDataCaching>
652
+ CHIP_ERROR ClusterStateCacheT<CanEnableDataCaching>::GetLastReportDataPath(ConcreteClusterPath & aPath)
591
653
{
592
654
if (mLastReportDataPath .IsValidConcreteClusterPath ())
593
655
{
@@ -596,5 +658,10 @@ CHIP_ERROR ClusterStateCache::GetLastReportDataPath(ConcreteClusterPath & aPath)
596
658
}
597
659
return CHIP_ERROR_INCORRECT_STATE;
598
660
}
661
+
662
+ // Ensure that our out-of-line template methods actually get compiled.
663
+ template class ClusterStateCacheT <true >;
664
+ template class ClusterStateCacheT <false >;
665
+
599
666
} // namespace app
600
667
} // namespace chip
0 commit comments