LCOV - code coverage report
Current view: top level - jdx - Page.cpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 50 54 92.6 %
Date: 2025-06-15 16:18:27 Functions: 8 8 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             : #include "jdx/Page.hpp"
      19             : #include "jdx/ParseException.hpp"
      20             : #include "util/DataParser.hpp"
      21             : #include "util/LdrUtils.hpp"
      22             : #include "util/PeakTableParser.hpp"
      23             : #include "util/StringUtils.hpp"
      24             : 
      25          71 : libjdx::jdx::Page::Page(std::string& label, std::string pageVar,
      26             :     const std::vector<NTuplesAttributes>& nTuplesAttributes,
      27             :     const std::vector<StringLdr>& blockLdrs, io::TextReader& reader,
      28          71 :     std::optional<std::string>& nextLine)
      29          80 :     : m_pageVariables{std::move(pageVar)}
      30             : {
      31          71 :     validateInput(label);
      32          71 :     parse(nTuplesAttributes, blockLdrs, reader, nextLine);
      33          68 : }
      34             : 
      35          71 : void libjdx::jdx::Page::validateInput(const std::string& label)
      36             : {
      37          71 :     if (label != s_label)
      38             :     {
      39           0 :         throw ParseException("Illegal label at " + std::string{s_label}
      40           0 :                              + " start encountered: " + label);
      41             :     }
      42          71 : }
      43             : 
      44          11 : const std::string& libjdx::jdx::Page::getPageVariables() const
      45             : {
      46          11 :     return m_pageVariables;
      47             : }
      48             : 
      49             : const std::vector<libjdx::jdx::StringLdr>&
      50           9 : libjdx::jdx::Page::getPageLdrs() const
      51             : {
      52           9 :     return m_pageLdrs;
      53             : }
      54             : 
      55             : const std::optional<libjdx::jdx::DataTable>&
      56          37 : libjdx::jdx::Page::getDataTable() const
      57             : {
      58          37 :     return m_dataTable;
      59             : }
      60             : 
      61          71 : void libjdx::jdx::Page::parse(
      62             :     const std::vector<NTuplesAttributes>& nTuplesAttributes,
      63             :     const std::vector<StringLdr>& blockLdrs, io::TextReader& reader,
      64             :     std::optional<std::string>& nextLine)
      65             : {
      66             :     // skip potential comment lines
      67          71 :     util::skipPureComments(reader, nextLine, false);
      68          71 :     m_pageLdrs = parsePageLdrs(reader, nextLine);
      69          71 :     if (!nextLine.has_value() || !util::isLdrStart(nextLine.value()))
      70             :     {
      71             :         throw ParseException(
      72             :             "Unexpected content found while parsing NTUPLES PAGE: "
      73           1 :             + nextLine.value_or("<end of file>"));
      74             :     }
      75             : 
      76          72 :     auto [label, value] = util::parseLdrStart(nextLine.value());
      77          70 :     if (label == "PAGE" || label == "ENDNTUPLES" || label == "END")
      78             :     {
      79             :         // end of page, page is empty
      80           2 :         return;
      81             :     }
      82          68 :     if (label != "DATATABLE")
      83             :     {
      84             :         throw ParseException(
      85             :             "Unexpected content found while parsing NTUPLES PAGE: "
      86           0 :             + nextLine.value());
      87             :     }
      88             : 
      89          69 :     auto [dataTableVarList, plotDesc] = parseDataTableVars(value);
      90         136 :     m_dataTable.emplace(DataTable(label, dataTableVarList, plotDesc, blockLdrs,
      91         133 :         nTuplesAttributes, m_pageLdrs, reader, nextLine));
      92             : }
      93             : 
      94          71 : std::vector<libjdx::jdx::StringLdr> libjdx::jdx::Page::parsePageLdrs(
      95             :     io::TextReader& reader, std::optional<std::string>& nextLine)
      96             : {
      97          71 :     std::vector<StringLdr> pageLdrs;
      98         100 :     while (nextLine.has_value())
      99             :     {
     100          99 :         auto [label, value] = util::parseLdrStart(nextLine.value());
     101         198 :         if (label == "PAGE" || label == "ENDNTUPLES" || label == "END"
     102         198 :             || label == "DATATABLE")
     103             :         {
     104             :             // end of page or start of DATA TABLE
     105          70 :             break;
     106             :         }
     107             :         // LDR is a regular LDR
     108          29 :         nextLine = parseStringValue(value, reader);
     109          29 :         pageLdrs.emplace_back(label, value);
     110             :     }
     111          71 :     return pageLdrs;
     112             : }
     113             : 
     114             : std::pair<std::string, std::optional<std::string>>
     115          68 : libjdx::jdx::Page::parseDataTableVars(const std::string& rawPageVars)
     116             : {
     117         136 :     auto rawPageVarsTrimmed = util::stripLineComment(rawPageVars, true).first;
     118          68 :     if (rawPageVarsTrimmed.empty())
     119             :     {
     120             :         // empty
     121             :         throw ParseException(
     122           1 :             "Missing variable list in DATA TABLE: " + rawPageVars);
     123             :     }
     124             :     // C++ does not support lookbehind syntax R"((?<=\))\s*,\s*)", so instead
     125             :     // use non capturing group for ")" and split at capturing group
     126             :     auto segments
     127         201 :         = util::split(rawPageVarsTrimmed, R"((?:\))(\s*,\s*))", true, 1);
     128          67 :     if (segments.empty() || segments.size() > 2)
     129             :     {
     130             :         throw ParseException(
     131           0 :             "Unexpected content found at DATA TABLE start: " + rawPageVars);
     132             :     }
     133             : 
     134          67 :     if (segments.size() == 1)
     135             :     {
     136           6 :         auto varList = util::stripLineComment(segments.at(0), true).first;
     137           3 :         return {varList, std::nullopt};
     138             :     }
     139             :     // plot descriptor is present
     140         128 :     auto varList = segments.at(0);
     141          64 :     util::trim(varList);
     142         128 :     auto plotDesc = util::stripLineComment(segments.at(1), true).first;
     143          64 :     return {varList, plotDesc};
     144             : }

Generated by: LCOV version 1.14