LCOV - code coverage report
Current view: top level - src/MIDI_Parsers - HexPuller.hpp (source / functions) Coverage Total Hit
Test: 73449d9b107c772cf65493691543348214e5d5eb Lines: 94.4 % 18 17
Test Date: 2026-06-06 17:44:35 Functions: 100.0 % 3 3
Legend: Lines:     hit not hit

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include <AH/STL/utility> // std::forward
       4              : #include <AH/STL/vector>  // std::vector
       5              : #include <Settings/NamespaceSettings.hpp>
       6              : #include <ctype.h> // isxdigit, tolower
       7              : 
       8              : BEGIN_CS_NAMESPACE
       9              : 
      10              : /**
      11              :  * @brief   Class that parses hexadecimal ASCII text to bytes.
      12              :  *
      13              :  * For example, parses the string `"7f A 123456"` to the bytes 
      14              :  * `{0x7F, 0x0A, 0x12, 0x34, 0x56}`.
      15              :  *
      16              :  * @tparam  CharPuller
      17              :  *          Class that supplies the ASCII characters to parse.
      18              :  *
      19              :  * @see     @ref BufferPuller
      20              :  * @see     @ref StreamPuller
      21              :  * 
      22              :  * @ingroup MIDIParsers
      23              :  */
      24              : template <class CharPuller>
      25              : class HexPuller {
      26              :   public:
      27           16 :     HexPuller(CharPuller &&puller) : puller(std::forward<CharPuller>(puller)) {}
      28              : 
      29              :     /// Pull out a new byte. Pulls characters from the `CharPuller` until a
      30              :     /// hexadecimal number was found, decodes it, and returns it.
      31              :     ///
      32              :     /// @param[out] output
      33              :     ///             A new byte (if available).
      34              :     /// @return True if a byte was available, false otherwise.
      35           21 :     bool pull(uint8_t &output) {
      36           21 :         uint8_t input;
      37           53 :         while (puller.pull(input)) {
      38              :             // If we receive a hexadecimal digit
      39           53 :             if (isxdigit(input)) {
      40           40 :                 (char1 ? char2 : char1) = tolower(input);
      41              :             }
      42              :             // If we received two hex characters
      43           53 :             if (char1 && char2) {
      44           19 :                 output = hex2int(char1) << 4 | hex2int(char2);
      45           19 :                 char1 = '\0';
      46           19 :                 char2 = '\0';
      47           19 :                 return true;
      48              :             }
      49              :             // If we received one hex character followed by whitespace/other
      50           34 :             else if (!isxdigit(input) && char1) {
      51            2 :                 output = hex2int(char1);
      52            2 :                 char1 = '\0';
      53            2 :                 return true;
      54              :             }
      55              :         }
      56            0 :         return false;
      57              :     }
      58              : 
      59              :   private:
      60              :     /// Convert a hexadecimal character to a 4-bit nibble.
      61           40 :     static uint8_t hex2int(char hex) {
      62           40 :         return hex < 'a' ? hex - '0' : hex - 'a' + 10;
      63              :     }
      64              : 
      65              :   public:
      66              :     CharPuller puller;
      67              : 
      68              :   private:
      69              :     char char1 = '\0';
      70              :     char char2 = '\0';
      71              : };
      72              : 
      73              : END_CS_NAMESPACE
        

Generated by: LCOV version 2.4-beta