Matter SDK Coverage Report
Current view: top level - app/persistence - AttributePersistence.cpp (source / functions) Coverage Total Hit
Test: SHA:3f9cd168e84cd831b7699126f5296f5c5498690f Lines: 100.0 % 46 46
Test Date: 2026-04-27 19:52:19 Functions: 100.0 % 6 6

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2025 Project CHIP Authors
       3              :  *
       4              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       5              :  *    you may not use this file except in compliance with the License.
       6              :  *    You may obtain a copy of the License at
       7              :  *
       8              :  *        http://www.apache.org/licenses/LICENSE-2.0
       9              :  *
      10              :  *    Unless required by applicable law or agreed to in writing, software
      11              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      12              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13              :  *    See the License for the specific language governing permissions and
      14              :  *    limitations under the License.
      15              :  */
      16              : #include <app/persistence/AttributePersistence.h>
      17              : 
      18              : #include <app/ConcreteAttributePath.h>
      19              : #include <app/data-model/Nullable.h>
      20              : #include <app/persistence/AttributePersistenceProvider.h>
      21              : #include <app/persistence/String.h>
      22              : #include <lib/core/CHIPError.h>
      23              : #include <lib/support/Span.h>
      24              : 
      25              : namespace chip::app {
      26              : 
      27              : namespace {
      28              : 
      29          343 : bool VerifySuccessLogOnFailure(const ConcreteAttributePath & path, CHIP_ERROR err)
      30              : {
      31          686 :     VerifyOrReturnValue(err != CHIP_NO_ERROR, true);
      32              : 
      33              :     // Value not found is typical. Not an error worth logging.
      34          564 :     VerifyOrReturnValue(err != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, false);
      35              : 
      36            3 :     ChipLogError(Zcl, "Failed to load attribute %u/" ChipLogFormatMEI "/" ChipLogFormatMEI ": %" CHIP_ERROR_FORMAT,
      37              :                  path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId), err.Format());
      38            3 :     return false;
      39              : }
      40              : 
      41              : } // namespace
      42              : 
      43          303 : bool AttributePersistence::InternalRawLoadNativeEndianValue(const ConcreteAttributePath & path, void * data,
      44              :                                                             const void * valueOnLoadFailure, size_t size)
      45              : {
      46          303 :     MutableByteSpan rawBytes(reinterpret_cast<uint8_t *>(data), size);
      47          303 :     if (!VerifySuccessLogOnFailure(path, mProvider.ReadValue(path, rawBytes)))
      48              :     {
      49              :         // in case of failure, set the default value
      50          252 :         memcpy(data, valueOnLoadFailure, size);
      51          252 :         return false;
      52              :     }
      53              : 
      54           51 :     if (rawBytes.size() != size)
      55              :     {
      56              :         // short read: the value is not valid
      57            1 :         memcpy(data, valueOnLoadFailure, size);
      58            1 :         return false;
      59              :     }
      60              : 
      61           50 :     return true;
      62              : }
      63              : 
      64           40 : bool AttributePersistence::LoadString(const ConcreteAttributePath & path, Storage::Internal::ShortString & value)
      65              : {
      66           40 :     Storage::Internal::ShortStringInputAdapter io(value);
      67           40 :     MutableByteSpan rawBytes = io.ReadBuffer();
      68              : 
      69           40 :     if (!VerifySuccessLogOnFailure(path, mProvider.ReadValue(path, rawBytes)))
      70              :     {
      71           30 :         value.SetContent(""_span);
      72           30 :         return false;
      73              :     }
      74           10 :     return io.FinalizeRead(rawBytes);
      75              : }
      76              : 
      77           36 : CHIP_ERROR AttributePersistence::StoreString(const ConcreteAttributePath & path, const Storage::Internal::ShortString & value)
      78              : {
      79           36 :     Storage::Internal::ShortStringOutputAdapter io(value);
      80           36 :     return mProvider.WriteValue(path, io.ContentWithPrefix());
      81              : }
      82              : 
      83           10 : CHIP_ERROR AttributePersistence::InternalStoreTLV(const ConcreteAttributePath & path, MutableByteSpan buffer, const void * context,
      84              :                                                   TLVEncoderCallback encoder)
      85              : {
      86           10 :     TLV::TLVWriter writer;
      87           10 :     writer.Init(buffer);
      88              : 
      89              :     TLV::TLVType container;
      90              :     // We wrap the value in an Anonymous Structure to ensure a single valid top-level element.
      91           10 :     ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, container));
      92           10 :     ReturnErrorOnFailure(encoder(context, writer));
      93            9 :     ReturnErrorOnFailure(writer.EndContainer(container));
      94            9 :     ReturnErrorOnFailure(writer.Finalize());
      95              : 
      96            9 :     return mProvider.WriteValue(path, ByteSpan(buffer.data(), writer.GetLengthWritten()));
      97              : }
      98              : 
      99           11 : CHIP_ERROR AttributePersistence::InternalLoadTLV(const ConcreteAttributePath & path, MutableByteSpan buffer, void * context,
     100              :                                                  TLVDecoderCallback decoder)
     101              : {
     102           11 :     ReturnErrorOnFailure(mProvider.ReadValue(path, buffer));
     103              : 
     104            7 :     TLV::TLVReader reader;
     105            7 :     reader.Init(buffer);
     106              : 
     107            7 :     ReturnErrorOnFailure(reader.Next());
     108            7 :     VerifyOrReturnError(reader.GetType() == TLV::kTLVType_Structure, CHIP_ERROR_WRONG_TLV_TYPE);
     109              : 
     110              :     {
     111              :         TLV::TLVType container;
     112            6 :         ReturnErrorOnFailure(reader.EnterContainer(container));
     113            6 :         ReturnErrorOnFailure(reader.Next()); // Move to the element inside structure (Context Tag 1)
     114            5 :         VerifyOrReturnError(reader.GetTag() == kTLVEncodingTag, CHIP_ERROR_INVALID_ARGUMENT);
     115            4 :         ReturnErrorOnFailure(decoder(context, reader));
     116            4 :         ReturnErrorOnFailure(reader.VerifyEndOfContainer());
     117            3 :         ReturnErrorOnFailure(reader.ExitContainer(container));
     118              :     }
     119            3 :     ReturnErrorOnFailure(reader.VerifyEndOfContainer());
     120              : 
     121            2 :     return CHIP_NO_ERROR;
     122              : }
     123              : 
     124              : } // namespace chip::app
        

Generated by: LCOV version 2.0-1