LCOV - code coverage report
Current view: top level - jdx/util - LdrUtils.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 15 15 100.0 %
Date: 2025-06-15 16:18:27 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /* Copyright (C) 2025 Robert Schiwon
       2             :  *
       3             :  * This file is part of libjdx.
       4             :  *
       5             :  * libjdx is free software: you can redistribute it and/or modify it under the
       6             :  * terms of the GNU Lesser General Public License as published by the Free
       7             :  * Software Foundation, either version 3 of the License, or (at your option) any
       8             :  * later version.
       9             :  *
      10             :  * libjdx is distributed in the hope that it will be useful, but WITHOUT ANY
      11             :  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      12             :  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
      13             :  * details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public License
      16             :  * along with libjdx. If not, see <https://www.gnu.org/licenses/>.
      17             :  */
      18             : #ifndef JDX_LDRUTILS_HPP
      19             : #define JDX_LDRUTILS_HPP
      20             : 
      21             : #include "io/TextReader.hpp"
      22             : #include "jdx/StringLdr.hpp"
      23             : #include "util/StringUtils.hpp"
      24             : 
      25             : #include <limits>
      26             : #include <optional>
      27             : #include <string>
      28             : #include <type_traits>
      29             : #include <vector>
      30             : 
      31             : /**
      32             :  * @brief Helper functions for parsing JCAMP-DX labeled data records (LDRs).
      33             :  */
      34             : namespace libjdx::jdx::util
      35             : {
      36             : bool isLdrStart(const std::string& line);
      37             : std::string normalizeLdrStart(const std::string& ldr);
      38             : std::string normalizeLdrLabel(const std::string& label);
      39             : std::pair<std::string, std::string> parseLdrStart(const std::string& ldrStart);
      40             : std::pair<std::string, std::optional<std::string>> stripLineComment(
      41             :     const std::string& line, bool trimContent = false,
      42             :     bool trimComment = false);
      43             : std::optional<const StringLdr> findLdr(
      44             :     const std::vector<StringLdr>& ldrs, const std::string& label);
      45             : std::optional<std::string> findLdrValue(
      46             :     const std::vector<StringLdr>& ldrs, const std::string& label);
      47             : void skipToNextLdr(io::TextReader& reader, std::optional<std::string>& nextLine,
      48             :     bool forceSkipFirstLine);
      49             : void skipPureComments(io::TextReader& reader,
      50             :     std::optional<std::string>& nextLine, bool mustPrecedeLdr);
      51             : bool isPureComment(const std::string& line);
      52             : bool isBrukerSpecificSectionStart(const std::string& line);
      53             : bool isBrukerSpecificSectionEnd(const std::string& line);
      54             : 
      55             : template<typename T> struct LdrValueParser
      56             : {
      57             :     // for std::string
      58         136 :     static std::optional<T> parse(const std::string& value)
      59             :     {
      60             :         // see:
      61             :         // https://stackoverflow.com/questions/49330687/how-do-i-restrict-templates-to-specific-types
      62             :         // https://stackoverflow.com/questions/44847559/is-stdis-samet-tvalue-always-true
      63             :         static_assert(std::is_same_v<T, std::string>,
      64             :             "LdrValueParser template for string used with wrong type.");
      65             :         // could be empty string which is also a valid string
      66         136 :         return value;
      67             :     };
      68             : };
      69             : template<> struct LdrValueParser<double>
      70             : {
      71         315 :     static std::optional<double> parse(const std::string& value)
      72             :     {
      73         315 :         return value.empty() ? std::nullopt
      74         630 :                              : std::optional<double>{std::stod(value)};
      75             :     };
      76             : };
      77             : template<> struct LdrValueParser<uint64_t>
      78             : {
      79          65 :     static std::optional<uint64_t> parse(const std::string& value)
      80             :     {
      81             :         // we parse uint64_t as unsigned long and assign it to uint64_t
      82             :         static_assert(std::numeric_limits<unsigned long>::max()
      83             :                           // NOLINTNEXTLINE(misc-redundant-expression)
      84             :                           <= std::numeric_limits<uint64_t>::max(),
      85             :             "unsigned long max larger than uint_64_t max");
      86          65 :         return value.empty() ? std::nullopt
      87         130 :                              : std::optional<uint64_t>{std::stoul(value)};
      88             :     };
      89             : };
      90             : 
      91             : template<typename T>
      92         938 : std::optional<T> parseLdrValue(
      93             :     const std::vector<StringLdr>& ldrs, const std::string& label)
      94             : {
      95        1876 :     auto stringValueOptional = findLdrValue(ldrs, label);
      96         938 :     if (!stringValueOptional.has_value())
      97             :     {
      98             :         // LDR not found
      99         422 :         return std::nullopt;
     100             :     }
     101        1032 :     auto stringValue
     102         516 :         = stripLineComment(stringValueOptional.value(), true).first;
     103         516 :     return LdrValueParser<T>::parse(stringValue);
     104             : }
     105             : } // namespace libjdx::jdx::utils
     106             : 
     107             : #endif

Generated by: LCOV version 1.14