LCOV - code coverage report
Current view: top level - src/microsim/cfmodels - ParBuffer.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 0.0 % 70 0
Test Date: 2024-12-21 15:45:41 Functions: 0.0 % 11 0

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    ParBuffer.h
      15              : /// @author  Michele Segata
      16              : /// @date    Wed, 18 Apr 2012
      17              : ///
      18              : // Class for the string serialization and deserialization of parameters
      19              : /****************************************************************************/
      20              : 
      21              : #pragma once
      22              : #include <config.h>
      23              : 
      24              : #include <cstddef>
      25              : #include <string>
      26              : #include <sstream>
      27              : #include <algorithm>
      28              : 
      29            0 : class ParBuffer {
      30              : public:
      31            0 :     ParBuffer() : SEP(':'), ESC('\\'), QUO('"'), was_empty(false) {}
      32            0 :     ParBuffer(std::string buf) : SEP(':'), ESC('\\'), QUO('"'),
      33            0 :         was_empty(false) {
      34            0 :         inBuffer = buf;
      35            0 :     }
      36              : 
      37            0 :     template<typename T> ParBuffer& operator <<(const T& v) {
      38            0 :         std::stringstream ss;
      39              :         std::string str_value;
      40            0 :         ss << v;
      41            0 :         str_value = escape(ss.str());
      42            0 :         if (outBuffer.str().length() == 0) {
      43            0 :             outBuffer << str_value;
      44              :         } else {
      45            0 :             outBuffer << SEP << str_value;
      46              :         }
      47            0 :         return *this;
      48            0 :     }
      49              : 
      50            0 :     size_t next_escape(std::string str, size_t pos) {
      51            0 :         size_t c_pos = str.find(SEP, pos);
      52            0 :         size_t e_pos = str.find(ESC, pos);
      53            0 :         if (c_pos == std::string::npos) {
      54              :             return e_pos;
      55              :         }
      56            0 :         if (e_pos == std::string::npos) {
      57              :             return c_pos;
      58              :         }
      59            0 :         return std::min(c_pos, e_pos);
      60              :     }
      61              : 
      62            0 :     std::string escape(std::string str) {
      63              :         size_t pos, last_pos = 0;
      64            0 :         std::stringstream escaping;
      65              :         std::string escaped;
      66            0 :         while ((pos = next_escape(str, last_pos)) != std::string::npos) {
      67            0 :             escaping << str.substr(last_pos, pos - last_pos);
      68            0 :             escaping << ESC << str.substr(pos, 1);
      69            0 :             last_pos = pos + 1;
      70              :         }
      71            0 :         if (last_pos != str.size()) {
      72            0 :             escaping << str.substr(last_pos);
      73              :         }
      74            0 :         escaped = escaping.str();
      75            0 :         if (escaped.empty() || (escaped.c_str()[0] == QUO && escaped.c_str()[escaped.length() - 1] == QUO)) {
      76            0 :             escaping.str("");
      77            0 :             escaping.clear();
      78            0 :             escaping << QUO << escaped << QUO;
      79            0 :             escaped = escaping.str();
      80              :         }
      81            0 :         return escaped;
      82            0 :     }
      83              : 
      84            0 :     std::string unescape(std::string str) {
      85              :         size_t pos, last_pos = 0;
      86            0 :         std::stringstream unescaped;
      87              :         std::string escaped;
      88            0 :         if (str.c_str()[0] == QUO && str.c_str()[str.length() - 1] == QUO) {
      89            0 :             str = str.substr(1, str.length() - 2);
      90              :         }
      91            0 :         while ((pos = str.find(ESC, last_pos)) != std::string::npos) {
      92            0 :             unescaped << str.substr(last_pos, pos - last_pos);
      93            0 :             unescaped << str.substr(pos + 1, 1);
      94            0 :             last_pos = pos + 2;
      95              :         }
      96            0 :         if (last_pos != str.size()) {
      97            0 :             unescaped << str.substr(last_pos);
      98              :         }
      99            0 :         return unescaped.str();
     100            0 :     }
     101              : 
     102            0 :     std::string next() {
     103            0 :         if (inBuffer.size() == 0) {
     104            0 :             return "";
     105              :         }
     106              : 
     107              :         size_t sep = std::string::npos;
     108              :         do {
     109            0 :             sep = inBuffer.find(SEP, sep + 1);
     110            0 :         } while (!(sep == std::string::npos || sep == 0 || inBuffer.c_str()[sep - 1] != ESC));
     111              : 
     112              :         std::string value;
     113            0 :         if (sep == std::string::npos) {
     114            0 :             value = unescape(inBuffer);
     115              :             inBuffer = "";
     116              :         } else {
     117            0 :             value = unescape(inBuffer.substr(0, sep));
     118            0 :             inBuffer = inBuffer.substr(sep + 1);
     119              :         }
     120            0 :         return value;
     121              :     }
     122              : 
     123            0 :     template <typename T> ParBuffer& operator>>(T& v) {
     124            0 :         std::string value = next();
     125            0 :         std::stringstream ss(value);
     126            0 :         ss >> v;
     127              :         // stringstream doesn't write to v if value is an empty string. the
     128              :         // only solution is letting the user know that the last parsed
     129              :         // portion was empty
     130            0 :         if (value == "") {
     131            0 :             was_empty = true;
     132              :         } else {
     133            0 :             was_empty = false;
     134              :         }
     135            0 :         return *this;
     136            0 :     }
     137              : 
     138              :     bool last_empty() {
     139            0 :         return was_empty;
     140              :     }
     141              : 
     142              :     void set(std::string buf) {
     143              :         inBuffer = buf;
     144              :     }
     145              :     void clear() {
     146              :         outBuffer.clear();
     147              :     }
     148              :     std::string str() const {
     149            0 :         return outBuffer.str();
     150              :     }
     151              : 
     152              : private:
     153              :     const char SEP;
     154              :     const char ESC;
     155              :     const char QUO;
     156              :     std::stringstream outBuffer;
     157              :     std::string inBuffer;
     158              :     bool was_empty;
     159              : 
     160              : };
        

Generated by: LCOV version 2.0-1