Matter SDK Coverage Report
Current view: top level - lib/support - ReadOnlyBuffer.cpp (source / functions) Coverage Total Hit
Test: SHA:4cbce7f768f16e614f5a8ccb8cd93c92cbeae70d Lines: 100.0 % 84 84
Test Date: 2025-04-26 07:09:35 Functions: 100.0 % 10 10

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2024 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 <lib/support/ReadOnlyBuffer.h>
      17              : 
      18              : #include <lib/core/CHIPError.h>
      19              : #include <lib/support/CHIPMem.h>
      20              : #include <lib/support/CodeUtils.h>
      21              : #include <lib/support/ScopedBuffer.h>
      22              : 
      23              : namespace chip {
      24              : namespace detail {
      25              : 
      26        36233 : GenericAppendOnlyBuffer::~GenericAppendOnlyBuffer()
      27              : {
      28        36233 :     if (mBufferIsAllocated && (mBuffer != nullptr))
      29              :     {
      30            1 :         Platform::MemoryFree(mBuffer);
      31              :     }
      32        36233 : }
      33              : 
      34            6 : GenericAppendOnlyBuffer::GenericAppendOnlyBuffer(GenericAppendOnlyBuffer && other) : mElementSize(other.mElementSize)
      35              : {
      36              :     // take over the data
      37            6 :     mBuffer            = other.mBuffer;
      38            6 :     mElementCount      = other.mElementCount;
      39            6 :     mCapacity          = other.mCapacity;
      40            6 :     mBufferIsAllocated = other.mBufferIsAllocated;
      41              : 
      42              :     // clear other
      43            6 :     other.mBuffer            = nullptr;
      44            6 :     other.mElementCount      = 0;
      45            6 :     other.mCapacity          = 0;
      46            6 :     other.mBufferIsAllocated = false;
      47            6 : }
      48              : 
      49            1 : GenericAppendOnlyBuffer & GenericAppendOnlyBuffer::operator=(GenericAppendOnlyBuffer && other)
      50              : {
      51            1 :     VerifyOrDie(mElementSize == other.mElementSize);
      52              : 
      53            1 :     if (mBufferIsAllocated && (mBuffer != nullptr))
      54              :     {
      55            1 :         Platform::Impl::PlatformMemoryManagement::MemoryFree(mBuffer);
      56              :     }
      57              : 
      58              :     // take over the data
      59            1 :     mBuffer            = other.mBuffer;
      60            1 :     mElementCount      = other.mElementCount;
      61            1 :     mCapacity          = other.mCapacity;
      62            1 :     mBufferIsAllocated = other.mBufferIsAllocated;
      63              : 
      64              :     // clear other
      65            1 :     other.mBuffer            = nullptr;
      66            1 :     other.mElementCount      = 0;
      67            1 :     other.mCapacity          = 0;
      68            1 :     other.mBufferIsAllocated = false;
      69              : 
      70            1 :     return *this;
      71              : }
      72              : 
      73        43226 : CHIP_ERROR GenericAppendOnlyBuffer::EnsureAppendCapacity(size_t numElements)
      74              : {
      75        43226 :     if (mCapacity >= mElementCount + numElements)
      76              :     {
      77              :         // Sufficient capacity already exists
      78        16929 :         return CHIP_NO_ERROR;
      79              :     }
      80              : 
      81        26297 :     if (mBuffer == nullptr)
      82              :     {
      83        26293 :         mBuffer = static_cast<uint8_t *>(Platform::MemoryCalloc(numElements, mElementSize));
      84        26293 :         VerifyOrReturnError(mBuffer != nullptr, CHIP_ERROR_NO_MEMORY);
      85        26293 :         mCapacity          = numElements;
      86        26293 :         mBufferIsAllocated = true;
      87        26293 :         return CHIP_NO_ERROR;
      88              :     }
      89              : 
      90              :     // we already have the data in buffer. we have two choices:
      91              :     //   - allocated buffer needs to be extended
      92              :     //   - re-used const buffer needs to be copied over
      93            4 :     if (mBufferIsAllocated)
      94              :     {
      95            3 :         auto new_buffer = static_cast<uint8_t *>(Platform::MemoryRealloc(mBuffer, (mElementCount + numElements) * mElementSize));
      96            3 :         VerifyOrReturnError(new_buffer != nullptr, CHIP_ERROR_NO_MEMORY);
      97            3 :         mBuffer = new_buffer;
      98              :     }
      99              :     else
     100              :     {
     101              :         // this is NOT an allocated buffer, but it should become one
     102            1 :         auto new_buffer = static_cast<uint8_t *>(Platform::MemoryCalloc(mElementCount + numElements, mElementSize));
     103            1 :         VerifyOrReturnError(new_buffer != nullptr, CHIP_ERROR_NO_MEMORY);
     104            1 :         mBufferIsAllocated = true;
     105            1 :         memcpy(new_buffer, mBuffer, mElementCount * mElementSize);
     106            1 :         mBuffer = new_buffer;
     107              :     }
     108            4 :     mCapacity = mElementCount + numElements;
     109              : 
     110            4 :     return CHIP_NO_ERROR;
     111              : }
     112              : 
     113       129153 : CHIP_ERROR GenericAppendOnlyBuffer::AppendSingleElementRaw(const void * buffer)
     114              : {
     115       129153 :     VerifyOrReturnError(mElementCount < mCapacity, CHIP_ERROR_BUFFER_TOO_SMALL);
     116       129148 :     memcpy(mBuffer + mElementCount * mElementSize, buffer, mElementSize);
     117       129148 :     mElementCount++;
     118       129148 :     return CHIP_NO_ERROR;
     119              : }
     120              : 
     121            4 : CHIP_ERROR GenericAppendOnlyBuffer::AppendElementArrayRaw(const void * __restrict__ buffer, size_t numElements)
     122              : {
     123            4 :     ReturnErrorOnFailure(EnsureAppendCapacity(numElements));
     124              : 
     125            4 :     memcpy(mBuffer + mElementCount * mElementSize, buffer, numElements * mElementSize);
     126            4 :     mElementCount += numElements;
     127              : 
     128            4 :     return CHIP_NO_ERROR;
     129              : }
     130              : 
     131           14 : CHIP_ERROR GenericAppendOnlyBuffer::ReferenceExistingElementArrayRaw(const void * buffer, size_t numElements)
     132              : {
     133           14 :     if (mBuffer == nullptr)
     134              :     {
     135              :         // we can NEVER append with 0 capacity, so const cast is safe
     136           11 :         mBuffer       = const_cast<uint8_t *>(static_cast<const uint8_t *>(buffer));
     137           11 :         mElementCount = numElements;
     138              :         // The assertions below are because we know the buffer is null/not allocated yet
     139           11 :         VerifyOrDie(mCapacity == 0);
     140           11 :         VerifyOrDie(!mBufferIsAllocated);
     141           11 :         return CHIP_NO_ERROR;
     142              :     }
     143              : 
     144            3 :     return AppendElementArrayRaw(buffer, numElements);
     145              : }
     146              : 
     147        36232 : void GenericAppendOnlyBuffer::ReleaseBuffer(void *& buffer, size_t & size, bool & allocated)
     148              : {
     149        36232 :     buffer    = mBuffer;
     150        36232 :     size      = mElementCount;
     151        36232 :     allocated = mBufferIsAllocated;
     152              : 
     153              :     // we release the ownership
     154        36232 :     mBuffer            = nullptr;
     155        36232 :     mCapacity          = 0;
     156        36232 :     mElementCount      = 0;
     157        36232 :     mBufferIsAllocated = false;
     158        36232 : }
     159              : 
     160        59477 : ScopedBuffer::~ScopedBuffer()
     161              : {
     162        59477 :     if (mBuffer != nullptr)
     163              :     {
     164        22042 :         Platform::MemoryFree(mBuffer);
     165              :     }
     166        59477 : }
     167              : 
     168        26525 : ScopedBuffer & ScopedBuffer::operator=(ScopedBuffer && other)
     169              : {
     170        26525 :     if (mBuffer != nullptr)
     171              :     {
     172         4250 :         Platform::MemoryFree(mBuffer);
     173              :     }
     174              : 
     175        26525 :     mBuffer       = other.mBuffer;
     176        26525 :     other.mBuffer = nullptr;
     177        26525 :     return *this;
     178              : }
     179              : 
     180              : } // namespace detail
     181              : } // namespace chip
        

Generated by: LCOV version 2.0-1