Matter SDK Coverage Report
Current view: top level - setup_payload - Base38Encode.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 100.0 % 26 26
Test Date: 2025-01-17 19:00:11 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2021 Project CHIP Authors
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : 
      18              : /**
      19              :  *    @file
      20              :  *      This file implements converting an array of bytes into a Base38 String.
      21              :  *
      22              :  *      The encoding chosen is: treat every 3 bytes of input data as a little-endian
      23              :  *        uint32_t, then div and mod that into 5 base38 characters, with the least-significant
      24              :  *        encoding bits in the first character of the resulting string. If a number of bytes
      25              :  *        is used that is not multiple of 3, then last 2 bytes are encoded to 4 base38 characters
      26              :  *        or last 1 byte is encoded to 2 base38 characters. Algoritm considers worst case size
      27              :  *        of bytes chunks and does not introduce code length optimization.
      28              :  *
      29              :  */
      30              : 
      31              : #include "Base38Encode.h"
      32              : 
      33              : #include <climits>
      34              : #include <cstring>
      35              : 
      36              : namespace {
      37              : 
      38              : static const uint8_t kMaxBytesSingleChunkLen = 3;
      39              : 
      40              : } // unnamed namespace
      41              : 
      42              : namespace chip {
      43              : 
      44           53 : CHIP_ERROR base38Encode(ByteSpan in_buf, MutableCharSpan & out_buf)
      45              : {
      46           53 :     CHIP_ERROR err             = CHIP_NO_ERROR;
      47           53 :     const uint8_t * in_buf_ptr = in_buf.data();
      48           53 :     size_t in_buf_len          = in_buf.size();
      49           53 :     size_t out_idx             = 0;
      50              : 
      51          248 :     while (in_buf_len > 0)
      52              :     {
      53          197 :         uint32_t value = 0;
      54              :         static_assert((sizeof(value) * CHAR_BIT) >= (kMaxBytesSingleChunkLen * 8), "Type for value is too small for conversions");
      55              : 
      56          197 :         size_t bytesInChunk = (in_buf_len >= kMaxBytesSingleChunkLen) ? kMaxBytesSingleChunkLen : in_buf_len;
      57              : 
      58          735 :         for (size_t byte_idx = 0; byte_idx < bytesInChunk; byte_idx++)
      59              :         {
      60          538 :             value += static_cast<uint32_t>(in_buf_ptr[byte_idx] << (8 * byte_idx));
      61              :         }
      62          197 :         in_buf_len -= bytesInChunk;
      63          197 :         in_buf_ptr += bytesInChunk;
      64              : 
      65              :         // Without code length optimization there is constant characters number needed for specific chunk size.
      66          197 :         const uint8_t base38CharactersNeeded = kBase38CharactersNeededInNBytesChunk[bytesInChunk - 1];
      67              : 
      68          197 :         if ((out_idx + base38CharactersNeeded) >= out_buf.size())
      69              :         {
      70            2 :             err = CHIP_ERROR_BUFFER_TOO_SMALL;
      71            2 :             break;
      72              :         }
      73              : 
      74         1108 :         for (uint8_t character = 0; character < base38CharactersNeeded; character++)
      75              :         {
      76          913 :             out_buf.data()[out_idx++] = kCodes[value % kRadix];
      77          913 :             value /= kRadix;
      78              :         }
      79              :     }
      80              : 
      81           53 :     if (out_idx < out_buf.size())
      82              :     {
      83           51 :         out_buf.data()[out_idx] = '\0';
      84              :         // Reduce output span size to be the size of written data and to not include null-terminator.
      85           51 :         out_buf.reduce_size(out_idx);
      86              :     }
      87              :     else
      88              :     {
      89              :         // out_buf size is zero.
      90            2 :         err = CHIP_ERROR_BUFFER_TOO_SMALL;
      91              :     }
      92              : 
      93           53 :     return err;
      94              : }
      95              : 
      96           33 : size_t base38EncodedLength(size_t num_bytes)
      97              : {
      98              :     // Each group of 3 bytes converts to 5 chars, and each remaining byte converts to 2 chars.
      99              :     // Add one for the null terminator.
     100           33 :     return (num_bytes / 3) * 5 + (num_bytes % 3) * 2 + 1;
     101              : }
     102              : 
     103              : } // namespace chip
        

Generated by: LCOV version 2.0-1