Matter SDK Coverage Report
Current view: top level - app - SafeAttributePersistenceProvider.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 100.0 % 2 2
Test Date: 2025-01-17 19:00:11 Functions: 66.7 % 3 2

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2021 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              : #pragma once
      17              : 
      18              : #include <app/ConcreteAttributePath.h>
      19              : #include <app/data-model/Nullable.h>
      20              : #include <app/util/attribute-metadata.h>
      21              : #include <lib/support/BufferReader.h>
      22              : #include <lib/support/BufferWriter.h>
      23              : #include <lib/support/Span.h>
      24              : 
      25              : #include <cstring>
      26              : #include <inttypes.h>
      27              : 
      28              : namespace chip {
      29              : namespace app {
      30              : 
      31              : /**
      32              :  * Interface for persisting attribute values. This will always write attributes in storage as little-endian
      33              :  * and uses a different key space from AttributePersistenceProvider.
      34              :  */
      35              : 
      36              : class SafeAttributePersistenceProvider
      37              : {
      38              : public:
      39            1 :     virtual ~SafeAttributePersistenceProvider() = default;
      40            1 :     SafeAttributePersistenceProvider()          = default;
      41              : 
      42              :     // The following API provides helper functions to simplify the access of commonly used types.
      43              :     // The API may not be complete.
      44              :     // Currently implemented write and read types are: bool, uint8_t, uint16_t, uint32_t, unit64_t and
      45              :     // their nullable varieties, as well as ByteSpans.
      46              : 
      47              :     /**
      48              :      * Write an attribute value of type intX, uintX or bool to non-volatile memory.
      49              :      *
      50              :      * @param [in] aPath the attribute path for the data being written.
      51              :      * @param [in] aValue the data to write.
      52              :      */
      53              :     template <typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
      54              :     CHIP_ERROR WriteScalarValue(const ConcreteAttributePath & aPath, T aValue)
      55              :     {
      56              :         uint8_t value[sizeof(T)];
      57              :         auto w = Encoding::LittleEndian::BufferWriter(value, sizeof(T));
      58              :         if constexpr (std::is_signed_v<T>)
      59              :         {
      60              :             w.EndianPutSigned(aValue, sizeof(T));
      61              :         }
      62              :         else
      63              :         {
      64              :             w.EndianPut(aValue, sizeof(T));
      65              :         }
      66              : 
      67              :         return SafeWriteValue(aPath, ByteSpan(value));
      68              :     }
      69              : 
      70              :     /**
      71              :      * Read an attribute of type intX, uintX or bool from non-volatile memory.
      72              :      *
      73              :      * @param [in]     aPath the attribute path for the data being persisted.
      74              :      * @param [in,out] aValue where to place the data.
      75              :      *
      76              :      * @retval CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND if no stored value exists for the attribute
      77              :      */
      78              :     template <typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
      79              :     CHIP_ERROR ReadScalarValue(const ConcreteAttributePath & aPath, T & aValue)
      80              :     {
      81              :         uint8_t attrData[sizeof(T)];
      82              :         MutableByteSpan tempVal(attrData);
      83              :         ReturnErrorOnFailure(SafeReadValue(aPath, tempVal));
      84              :         VerifyOrReturnError(tempVal.size() == sizeof(T), CHIP_ERROR_INCORRECT_STATE);
      85              :         Encoding::LittleEndian::Reader r(tempVal.data(), tempVal.size());
      86              :         r.RawReadLowLevelBeCareful(&aValue);
      87              :         return r.StatusCode();
      88              :     }
      89              : 
      90              :     /**
      91              :      * Write an attribute value of type nullable intX, uintX to non-volatile memory.
      92              :      *
      93              :      * @param [in] aPath the attribute path for the data being written.
      94              :      * @param [in] aValue the data to write.
      95              :      */
      96              :     template <typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
      97              :     CHIP_ERROR WriteScalarValue(const ConcreteAttributePath & aPath, const DataModel::Nullable<T> & aValue)
      98              :     {
      99              :         typename NumericAttributeTraits<T>::StorageType storageValue;
     100              :         if (aValue.IsNull())
     101              :         {
     102              :             NumericAttributeTraits<T>::SetNull(storageValue);
     103              :         }
     104              :         else
     105              :         {
     106              :             NumericAttributeTraits<T>::WorkingToStorage(aValue.Value(), storageValue);
     107              :         }
     108              :         return WriteScalarValue(aPath, storageValue);
     109              :     }
     110              : 
     111              :     /**
     112              :      * Read an attribute of type nullable intX, uintX from non-volatile memory.
     113              :      *
     114              :      * @param [in]     aPath the attribute path for the data being persisted.
     115              :      * @param [in,out] aValue where to place the data.
     116              :      *
     117              :      * @retval CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND if no stored value exists for the attribute
     118              :      */
     119              :     template <typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
     120              :     CHIP_ERROR ReadScalarValue(const ConcreteAttributePath & aPath, DataModel::Nullable<T> & aValue)
     121              :     {
     122              :         typename NumericAttributeTraits<T>::StorageType storageValue;
     123              :         ReturnErrorOnFailure(ReadScalarValue(aPath, storageValue));
     124              : 
     125              :         if (NumericAttributeTraits<T>::IsNullValue(storageValue))
     126              :         {
     127              :             aValue.SetNull();
     128              :             return CHIP_NO_ERROR;
     129              :         }
     130              : 
     131              :         // Consider checking CanRepresentValue here, so we don't produce invalid data
     132              :         // if the storage hands us invalid values.
     133              :         aValue.SetNonNull(NumericAttributeTraits<T>::StorageToWorking(storageValue));
     134              :         return CHIP_NO_ERROR;
     135              :     }
     136              : 
     137              :     /**
     138              :      * Write an attribute value from the attribute store (i.e. not a struct or
     139              :      * list) to non-volatile memory.
     140              :      *
     141              :      * @param [in] aPath the attribute path for the data being written.
     142              :      * @param [in] aValue the data to write. The value will be stored as-is.
     143              :      */
     144              :     virtual CHIP_ERROR SafeWriteValue(const ConcreteAttributePath & aPath, const ByteSpan & aValue) = 0;
     145              : 
     146              :     /**
     147              :      * Read an attribute value as a raw sequence of bytes from non-volatile memory.
     148              :      *
     149              :      * @param [in]     aPath the attribute path for the data being persisted.
     150              :      * @param [in,out] aValue where to place the data.  The size of the buffer
     151              :      *                 will be equal to `aValue.size()`. On success aValue.size()
     152              :      *                 will be the actual number of bytes read.
     153              :      *
     154              :      * @retval CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND if no stored value exists for the attribute
     155              :      * @retval CHIP_ERROR_BUFFER_TOO_SMALL aValue.size() is too small to hold the value.
     156              :      */
     157              :     virtual CHIP_ERROR SafeReadValue(const ConcreteAttributePath & aPath, MutableByteSpan & aValue) = 0;
     158              : };
     159              : 
     160              : /**
     161              :  * Instance getter for the global SafeAttributePersistenceProvider.
     162              :  *
     163              :  * Callers have to externally synchronize usage of this function.
     164              :  *
     165              :  * @return The global SafeAttributePersistenceProvider.  This must never be null.
     166              :  */
     167              : SafeAttributePersistenceProvider * GetSafeAttributePersistenceProvider();
     168              : 
     169              : /**
     170              :  * Instance setter for the global SafeAttributePersistenceProvider.
     171              :  *
     172              :  * Callers have to externally synchronize usage of this function.
     173              :  *
     174              :  * If the `provider` is nullptr, the value is not changed.
     175              :  *
     176              :  * @param[in] aProvider the SafeAttributePersistenceProvider implementation to use.
     177              :  */
     178              : void SetSafeAttributePersistenceProvider(SafeAttributePersistenceProvider * aProvider);
     179              : 
     180              : } // namespace app
     181              : } // namespace chip
        

Generated by: LCOV version 2.0-1