Matter SDK Coverage Report
Current view: top level - lib/support - CHIPMemString.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 82.1 % 39 32
Test Date: 2025-01-17 19:00:11 Functions: 75.0 % 12 9

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020 Project CHIP Authors
       4              :  *    All rights reserved.
       5              :  *
       6              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7              :  *    you may not use this file except in compliance with the License.
       8              :  *    You may obtain a copy of the License at
       9              :  *
      10              :  *        http://www.apache.org/licenses/LICENSE-2.0
      11              :  *
      12              :  *    Unless required by applicable law or agreed to in writing, software
      13              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15              :  *    See the License for the specific language governing permissions and
      16              :  *    limitations under the License.
      17              :  */
      18              : 
      19              : /**
      20              :  *    @file
      21              :  *      This file defines string operations that allocate heap memory.
      22              :  */
      23              : 
      24              : #pragma once
      25              : 
      26              : #include <algorithm>
      27              : #include <stdlib.h>
      28              : #include <string.h>
      29              : 
      30              : #include <lib/support/ScopedBuffer.h>
      31              : #include <lib/support/Span.h>
      32              : 
      33              : namespace chip {
      34              : namespace Platform {
      35              : 
      36              : /**
      37              :  * Copies a C-style string.
      38              :  *
      39              :  * This differs from `strncpy()` in some important ways:
      40              :  *  - `dest` can be nullptr, in which case no copy is attempted, and the function returns nullptr.
      41              :  *  - A non-nullptr result is always null-terminated.
      42              :  *
      43              :  * @param[in]  dest             Destination string buffer or nullptr.
      44              :  *
      45              :  * @param[in]  destLength       Maximum length to be copied. Will need space for null terminator as
      46              :  *                              well (string will be truncated if it does not fit). If 0 this method
      47              :  *                              is a noop.
      48              :  *
      49              :  * @param[in]  source           String to be copied.
      50              :  *
      51              :  * @retval  Same as `dest`.
      52              :  */
      53         7594 : inline void CopyString(char * dest, size_t destLength, const char * source)
      54              : {
      55         7594 :     if (dest && destLength)
      56              :     {
      57         7594 :         strncpy(dest, source, destLength);
      58         7594 :         dest[destLength - 1] = 0;
      59              :     }
      60         7594 : }
      61              : 
      62              : /**
      63              :  * Convenience method for CopyString to auto-detect destination size.
      64              :  */
      65              : template <size_t N>
      66         7887 : inline void CopyString(char (&dest)[N], const char * source)
      67              : {
      68         7887 :     CopyString(dest, N, source);
      69         7887 : }
      70              : 
      71              : /**
      72              :  * Creates a null-terminated string from a ByteSpan.
      73              :  * If dest is nullptr, no copy happens. Non-nullptr result is always null-terminated.
      74              :  *
      75              :  * @param[in]  dest             Destination string buffer or nullptr.
      76              :  *
      77              :  * @param[in]  destLength       Maximum length to be copied. Will need space for null terminator as
      78              :  *                              well (string will be truncated if it does not fit). If 0 this method
      79              :  *                              is a noop.
      80              :  *
      81              :  * @param[in]  source           Data to be copied.
      82              :  */
      83          169 : inline void CopyString(char * dest, size_t destLength, ByteSpan source)
      84              : {
      85          169 :     if ((dest == nullptr) || (destLength == 0))
      86              :     {
      87            0 :         return; // no space to copy anything, not even a null terminator
      88              :     }
      89              : 
      90          169 :     if (source.empty())
      91              :     {
      92           13 :         *dest = '\0'; // just a null terminator, we are copying empty data
      93           13 :         return;
      94              :     }
      95              : 
      96          156 :     size_t maxChars = std::min(destLength - 1, source.size());
      97          156 :     memcpy(dest, source.data(), maxChars);
      98          156 :     dest[maxChars] = '\0';
      99              : }
     100              : 
     101              : /**
     102              :  * Convenience method for CopyString to auto-detect destination size.
     103              :  */
     104              : template <size_t N>
     105              : inline void CopyString(char (&dest)[N], ByteSpan source)
     106              : {
     107              :     CopyString(dest, N, source);
     108              : }
     109              : 
     110              : /**
     111              :  * Creates a null-terminated string from a CharSpan.
     112              :  * If dest is nullptr, no copy happens. Non-nullptr result is always null-terminated.
     113              :  *
     114              :  * @param[in]  dest             Destination string buffer or nullptr.
     115              :  *
     116              :  * @param[in]  destLength       Maximum length to be copied. Will need space for null terminator as
     117              :  *                              well (string will be truncated if it does not fit). If 0 this method
     118              :  *                              is a noop.
     119              :  *
     120              :  * @param[in]  source           Data to be copied.
     121              :  */
     122          736 : inline void CopyString(char * dest, size_t destLength, CharSpan source)
     123              : {
     124          736 :     if ((dest == nullptr) || (destLength == 0))
     125              :     {
     126            0 :         return; // no space to copy anything, not even a null terminator
     127              :     }
     128              : 
     129          736 :     if (source.empty())
     130              :     {
     131          728 :         *dest = '\0'; // just a null terminator, we are copying empty data
     132          728 :         return;
     133              :     }
     134              : 
     135            8 :     size_t maxChars = std::min(destLength - 1, source.size());
     136            8 :     memcpy(dest, source.data(), maxChars);
     137            8 :     dest[maxChars] = '\0';
     138              : }
     139              : 
     140              : /**
     141              :  * Convenience method for CopyString to auto-detect destination size.
     142              :  */
     143              : template <size_t N>
     144          732 : inline void CopyString(char (&dest)[N], CharSpan source)
     145              : {
     146          732 :     CopyString(dest, N, source);
     147          732 : }
     148              : 
     149              : /**
     150              :  * This function copies a C-style string to memory newly allocated by Platform::MemoryAlloc().
     151              :  *
     152              :  * @param[in]  string           String to be copied.
     153              :  *
     154              :  * @param[in]  length           Length to be copied. Like `strncpy()`, if the `string` is shorter
     155              :  *                              than `length`, then the remaining space will be filled with null
     156              :  *                              bytes. Like `strndup()` but unlike `strncpy()`, the result is always
     157              :  *                              null-terminated.
     158              :  *
     159              :  * @retval  Pointer to a null-terminated string in case of success.
     160              :  * @retval  `nullptr` if memory allocation fails.
     161              :  *
     162              :  */
     163            0 : inline char * MemoryAllocString(const char * string, size_t length)
     164              : {
     165            0 :     size_t lengthWithNull = length + 1;
     166            0 :     char * result         = static_cast<char *>(MemoryAlloc(lengthWithNull));
     167            0 :     CopyString(result, lengthWithNull, string);
     168            0 :     return result;
     169              : }
     170              : 
     171              : /**
     172              :  * Represents a C string in a ScopedMemoryBuffer.
     173              :  */
     174              : 
     175              : class ScopedMemoryString : public ScopedMemoryBuffer<char>
     176              : {
     177              : public:
     178              :     /**
     179              :      * Create a ScopedMemoryString.
     180              :      *
     181              :      * @param[in]  string           String to be copied.
     182              :      *
     183              :      * @param[in]  length           Length to be copied. Like `strncpy()`, if the `string` is shorter than
     184              :      *                              `length`, then the remaining space will be filled with null bytes. Like
     185              :      *                              `strndup()` but unlike `strncpy()`, the result is always null-terminated.
     186              :      */
     187            4 :     ScopedMemoryString(const char * string, size_t length)
     188            4 :     {
     189            4 :         size_t lengthWithNull = length + 1;
     190              : 
     191              :         // We must convert the source string to a CharSpan, so we call the
     192              :         // version of CopyString that handles unterminated strings.
     193            4 :         CopyString(Alloc(lengthWithNull).Get(), lengthWithNull, CharSpan(string, length));
     194            4 :     }
     195              : };
     196              : 
     197              : } // namespace Platform
     198              : } // namespace chip
        

Generated by: LCOV version 2.0-1