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

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2021-2022 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              : #pragma once
      19              : 
      20              : #include <lib/core/CHIPError.h>
      21              : #include <lib/support/BitFlags.h>
      22              : #include <lib/support/Span.h>
      23              : 
      24              : #include <stdint.h>
      25              : #include <stdlib.h>
      26              : 
      27              : namespace chip {
      28              : namespace Encoding {
      29              : 
      30              : enum class HexFlags : int
      31              : {
      32              :     kNone = 0u,
      33              :     // Use uppercase A-F if set otherwise, lowercase a-f
      34              :     kUppercase = (1u << 0),
      35              :     // Null-terminate buffer
      36              :     kNullTerminate = (1u << 1),
      37              :     // Both use uppercase and null-termination.
      38              :     // Separately stated to avoid casts for common case.
      39              :     kUppercaseAndNullTerminate = ((1u << 0) | (1u << 1))
      40              : };
      41              : 
      42              : /**
      43              :  * Encode a buffer of bytes into hexadecimal, with or without null-termination
      44              :  * and using either lowercase or uppercase hex. The input bytes are assumed to be
      45              :  * in a big-engian order. The output is also in a big-endian order.
      46              :  *
      47              :  * Default is lowercase output, not null-terminated.
      48              :  *
      49              :  * If `flags` has `HexFlags::kNullTerminate` set, treat `dest_hex` as a
      50              :  * null-terminated string buffer. The function returns CHIP_ERROR_BUFFER_TOO_SMALL
      51              :  * if `dest_size_max` can't fit the entire encoded buffer, and the
      52              :  * null-terminator if enabled. This function will never output truncated data.
      53              :  * The result either fits and is written, or does not fit and nothing is written
      54              :  * to `dest_hex`.
      55              :  *
      56              :  * If `src_bytes` and `dest_hex` overlap, the results may be incorrect, depending
      57              :  * on overlap, but only the core validity checks are done and it's possible to
      58              :  * get CHIP_NO_ERROR with erroneous output.
      59              :  *
      60              :  * On success, number of bytes written to destination is always:
      61              :  *   output_size = (src_size * 2) + ((flags & HexFlags::kNullTerminate) ? 1 : 0);
      62              :  *
      63              :  * @param src_bytes Pointer to buffer to convert.  Only allowed to be null if
      64              :  *                  src_size is 0.
      65              :  * @param src_size Number of bytes to convert from src_bytes
      66              :  * @param [out] dest_hex Destination buffer to receive hex encoding
      67              :  * @param dest_size_max Maximum buffer size for the hex encoded `dest_hex` buffer
      68              :  *                      including null-terminator if needed.
      69              :  * @param flags Flags from `HexFlags` for formatting options
      70              :  *
      71              :  * @return CHIP_ERROR_BUFFER_TOO_SMALL on dest_max_size too small to fit output
      72              :  * @return CHIP_ERROR_INVALID_ARGUMENT if either src_bytes or dest_hex is
      73              :  *                                     nullptr without the corresponding size
      74              :  *                                     being 0.
      75              :  * @return CHIP_NO_ERROR on success
      76              :  */
      77              : 
      78              : CHIP_ERROR BytesToHex(const uint8_t * src_bytes, size_t src_size, char * dest_hex, size_t dest_size_max, BitFlags<HexFlags> flags);
      79              : 
      80              : /**
      81              :  * Encode a uint64_t into hexadecimal, with or without null-termination
      82              :  * and using either lowercase or uppercase hex. The output will be in a big-engian
      83              :  * order.
      84              :  *
      85              :  * Default is lowercase output, not null-terminated.
      86              :  *
      87              :  * If `flags` has `HexFlags::kNullTerminate` set, treat `dest_hex` as a
      88              :  * null-terminated string buffer. The function returns CHIP_ERROR_BUFFER_TOO_SMALL
      89              :  * if `dest_size_max` can't fit the entire encoded buffer, and the
      90              :  * null-terminator if enabled. This function will never output truncated data.
      91              :  * The result either fits and is written, or does not fit and nothing is written
      92              :  * to `dest_hex`.
      93              :  *
      94              :  * On success, number of bytes written to destination is always
      95              :  *   output_size = 16 + ((flags & HexFlags::kNullTerminate) ? 1 : 0);
      96              :  *
      97              :  * @param src 64-bit number to convert
      98              :  * @param [out] dest_hex Destination buffer to receive hex encoding
      99              :  * @param dest_size_max Maximum buffer size for the hex encoded `dest_hex` buffer
     100              :  *                      including null-terminator if needed.
     101              :  * @param flags Flags from `HexFlags` for formatting options
     102              :  *
     103              :  * @return CHIP_ERROR_BUFFER_TOO_SMALL on dest_max_size too small to fit output
     104              :  * @return CHIP_ERROR_INVALID_ARGUMENT if either src_bytes or dest_hex is nullptr
     105              :  * @return CHIP_NO_ERROR on success
     106              :  */
     107              : CHIP_ERROR Uint64ToHex(uint64_t src, char * dest_hex, size_t dest_size_max, BitFlags<HexFlags> flags);
     108              : 
     109              : /** Same as Uint64ToHex() but for uint32_t. */
     110              : CHIP_ERROR Uint32ToHex(uint32_t src, char * dest_hex, size_t dest_size_max, BitFlags<HexFlags> flags);
     111              : 
     112              : /** Same as Uint64ToHex() but for uint16_t. */
     113              : CHIP_ERROR Uint16ToHex(uint16_t src, char * dest_hex, size_t dest_size_max, BitFlags<HexFlags> flags);
     114              : 
     115              : // Alias for Uppercase option, no null-termination
     116            2 : inline CHIP_ERROR BytesToUppercaseHexBuffer(const uint8_t * src_bytes, size_t src_size, char * dest_hex_buf, size_t dest_size_max)
     117              : {
     118            2 :     return BytesToHex(src_bytes, src_size, dest_hex_buf, dest_size_max, HexFlags::kUppercase);
     119              : }
     120              : 
     121              : // Alias for Lowercase option, no null-termination
     122              : inline CHIP_ERROR BytesToLowercaseHexBuffer(const uint8_t * src_bytes, size_t src_size, char * dest_hex_buf, size_t dest_size_max)
     123              : {
     124              :     return BytesToHex(src_bytes, src_size, dest_hex_buf, dest_size_max, HexFlags::kNone);
     125              : }
     126              : 
     127              : // Alias for Uppercase option, with null-termination
     128           13 : inline CHIP_ERROR BytesToUppercaseHexString(const uint8_t * src_bytes, size_t src_size, char * dest_hex_str, size_t dest_size_max)
     129              : {
     130           13 :     return BytesToHex(src_bytes, src_size, dest_hex_str, dest_size_max, HexFlags::kUppercaseAndNullTerminate);
     131              : }
     132              : 
     133              : // Alias for Lowercase option, with null-termination
     134              : inline CHIP_ERROR BytesToLowercaseHexString(const uint8_t * src_bytes, size_t src_size, char * dest_hex_str, size_t dest_size_max)
     135              : {
     136              :     return BytesToHex(src_bytes, src_size, dest_hex_str, dest_size_max, HexFlags::kNullTerminate);
     137              : }
     138              : 
     139              : /**
     140              :  * @brief Dumps a binary buffer to log as hexadecimal
     141              :  *
     142              :  * Output is 32 bytes per line of uppercase hex, prepended with a given label.
     143              :  *
     144              :  * This function is useful to dump binary buffers such as certificates
     145              :  * which may need to be extracted from logs during debugging.
     146              :  *
     147              :  * Format is organized to allow easy extraction by searching the regex
     148              :  * `LABEL>>>[0-9A-F]+$` where LABEL is the `label` argument passed.
     149              :  *
     150              :  * Format looks like:
     151              :  *
     152              :  * ```
     153              :  * label>>>A54A39294B28886E8BFC15B44105A3FD22745225983A753E6BB82DA7C62493BF
     154              :  * label>>>02C3ED03D41B6F7874E7E887321DE7B4872CEB9F080B6ECE14A8ABFA260573A3
     155              :  * label>>>8D759C
     156              :  * ```
     157              :  *
     158              :  * If buffer is empty, at least one line with the `LABEL>>>` will be logged,
     159              :  * with no data.
     160              :  *
     161              :  * @param label - label to prepend. If nullptr, no label will be prepended
     162              :  * @param span - Span over buffer that needs to be dumped.
     163              :  */
     164              : void LogBufferAsHex(const char * label, const ByteSpan & span);
     165              : 
     166              : /**
     167              :  * Convert a buffer of hexadecimal characters to bytes. Supports both lowercase
     168              :  * and uppercase (or a mix of cases) hexadecimal characters. Supported input is
     169              :  * [0-9a-fA-F]. The input is assumed to be in a big-endian order. The output is
     170              :  * also in a big-endian order.
     171              :  *
     172              :  * @param src_hex a pointer to the character buffer to convert. It is not
     173              :  *                assumed to be null-terminated.
     174              :  * @param src_size the number of characters to convert from src_hex.
     175              :  * @param dest_bytes the buffer to fill with the decoded bytes.
     176              :  * @param dest_size_max the total size of the buffer to be filled.
     177              :  *
     178              :  * @return 0 on errors:
     179              :  *           - dest_size_max not big enough.
     180              :  *           - src_size not even.
     181              :  *           - Some character not in [0-9a-fA-F] is present in src_hex.
     182              :  *         Otherwise, returns number of bytes actually decoded from the string on success.
     183              :  */
     184              : size_t HexToBytes(const char * src_hex, const size_t src_size, uint8_t * dest_bytes, size_t dest_size_max);
     185              : 
     186              : /**
     187              :  * Convert a buffer of hexadecimal characters into uint64_t. Supports only
     188              :  * uppercase hexadecimal input characters. Supported input is [0-9A-F].
     189              :  * The input is assumed to be in a big-endian order.
     190              :  *
     191              :  * @param src_hex a pointer to the character buffer to convert. It is not
     192              :  *                assumed to be null-terminated.
     193              :  * @param src_size the number of characters to convert from src_hex.
     194              :  * @param dest 64-bit number to output.
     195              :  *
     196              :  * @return 0 on errors:
     197              :  *           - src_size not even.
     198              :  *           - Some character not in [0-9A-F] is present in src_hex.
     199              :  *         Otherwise, returns 8 (number of bytes actually decoded from the string) on success.
     200              :  */
     201              : size_t UppercaseHexToUint64(const char * src_hex, const size_t src_size, uint64_t & dest);
     202              : 
     203              : /** Same as UppercaseHexToUint64() but for uint32_t. */
     204              : size_t UppercaseHexToUint32(const char * src_hex, const size_t src_size, uint32_t & dest);
     205              : 
     206              : /** Same as UppercaseHexToUint64() but for uint16_t. */
     207              : size_t UppercaseHexToUint16(const char * src_hex, const size_t src_size, uint16_t & dest);
     208              : 
     209              : /**
     210              :  * Computes the hex encoded length for a given input length.
     211              :  * Left shift to generate optimized equivalent of LEN*2.
     212              :  */
     213              : #define HEX_ENCODED_LENGTH(LEN) ((LEN) << 1)
     214              : 
     215              : /**
     216              :  * Computes the maximum possible decoded length for a given hex string input length.
     217              :  * Right shift to generate optimized equivalent of LEN/2.
     218              :  */
     219              : #define HEX_MAX_DECODED_LENGTH(LEN) ((LEN) >> 1)
     220              : 
     221              : } // namespace Encoding
     222              : } // namespace chip
        

Generated by: LCOV version 2.0-1