LCOV - code coverage report
Current view: top level - tao_builds/jenkins/workspace/dds_doc_ace6tao2_wiro_linux_gcc_d1o0s1/OpenDDS/tools/dds/rtpsrelaylib - Name.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 102 102 100.0 %
Date: 2023-04-30 01:32:43 Functions: 8 8 100.0 %

          Line data    Source code
       1             : #include "Name.h"
       2             : 
       3             : #include <ostream>
       4             : 
       5             : namespace RtpsRelay {
       6             : 
       7          22 : static void output_character(std::ostream& out, char c) {
       8          22 :   switch (c) {
       9           6 :   case '[':
      10             :   case ']':
      11             :   case '!':
      12             :   case '\\':
      13             :   case '?':
      14             :   case '*':
      15           6 :     out << '\\';
      16             :   }
      17          22 :   out << c;
      18          22 : }
      19             : 
      20          18 : std::ostream& operator<<(std::ostream& out, const Atom& atom)
      21             : {
      22          18 :   switch (atom.kind()) {
      23           8 :   case Atom::CHARACTER:
      24           8 :     output_character(out, atom.character());
      25           8 :     break;
      26           3 :   case Atom::CHARACTER_CLASS:
      27           3 :     out << '[';
      28          10 :     for (char c : atom.characters()) {
      29           7 :       output_character(out, c);
      30             :     }
      31           3 :     out << ']';
      32           3 :     break;
      33           3 :   case Atom::NEGATED_CHARACTER_CLASS:
      34           3 :     out << "[!";
      35          10 :     for (char c : atom.characters()) {
      36           7 :       output_character(out, c);
      37             :     }
      38           3 :     out << ']';
      39           3 :     break;
      40           2 :   case Atom::WILDCARD:
      41           2 :     out << '?';
      42           2 :     break;
      43           2 :   case Atom::GLOB:
      44           2 :     out << '*';
      45           2 :     break;
      46             :   }
      47             : 
      48          18 :   return out;
      49             : }
      50             : 
      51         256 : void Name::parse(Name& name, const std::string& buffer, size_t& idx)
      52             : {
      53         256 :   if (!name.is_valid_ || idx == buffer.size()) {
      54          60 :     return;
      55             :   }
      56             : 
      57         196 :   char c = buffer[idx];
      58         196 :   if (c == '?') {
      59           8 :     name.push_back(Atom(Atom::WILDCARD));
      60           8 :     ++idx;
      61         188 :   } else if (c == '*') {
      62          38 :     name.push_back(Atom(Atom::GLOB));
      63          38 :     ++idx;
      64         150 :   } else if (c == '[') {
      65          25 :     name.push_back(parse_character_class(name, buffer, idx));
      66             :   } else {
      67         125 :     name.push_back(Atom(parse_character(name, buffer, idx)));
      68             :   }
      69             : 
      70         196 :   parse(name, buffer, idx);
      71             : }
      72             : 
      73         174 : char Name::parse_character(Name& name, const std::string& buffer, size_t& idx)
      74             : {
      75         174 :   char c = buffer[idx++];
      76         174 :   if (c == '\\') {
      77           4 :     if (idx == buffer.size()) {
      78           1 :       name.is_valid_ = false;
      79           1 :       return 0;
      80             :     }
      81           3 :     return buffer[idx++];
      82             :   } else {
      83         170 :     return c;
      84             :   }
      85             : }
      86             : 
      87          25 : Atom Name::parse_character_class(Name& name, const std::string& buffer, size_t& idx)
      88             : {
      89          25 :   name.is_pattern_ = true;
      90             : 
      91             :   // Skip '[']
      92          25 :   ++idx;
      93             : 
      94          25 :   bool negated = false;
      95             : 
      96          25 :   if (idx == buffer.size()) {
      97           1 :     name.is_valid_ = false;
      98           1 :     return Atom(0);
      99             :   }
     100             : 
     101          24 :   if (buffer[idx] == '!') {
     102           9 :     negated = true;
     103           9 :     ++idx;
     104             :   }
     105             : 
     106             :   // One character is required.
     107          24 :   if (idx == buffer.size()) {
     108           1 :     name.is_valid_ = false;
     109           1 :     return Atom(0);
     110             :   }
     111             : 
     112          23 :   std::set<char> characters;
     113          23 :   parse_character_or_range(name, buffer, idx, characters);
     114          23 :   parse_character_class_tail(name, buffer, idx, characters);
     115             : 
     116          23 :   return Atom(negated, characters);
     117          23 : }
     118             : 
     119          42 : void Name::parse_character_class_tail(Name& name, const std::string& buffer, size_t& idx, std::set<char>& characters)
     120             : {
     121          42 :   if (idx == buffer.size()) {
     122           4 :     name.is_valid_ = false;
     123           4 :     return;
     124             :   }
     125             : 
     126          38 :   char c = buffer[idx];
     127          38 :   if (c == ']') {
     128          19 :     ++idx;
     129          19 :     return;
     130             :   }
     131             : 
     132          19 :   parse_character_or_range(name, buffer, idx, characters);
     133          19 :   parse_character_class_tail(name, buffer, idx, characters);
     134             : }
     135             : 
     136          42 : void Name::parse_character_or_range(Name& name, const std::string& buffer, size_t& idx, std::set<char>& characters)
     137             : {
     138          42 :   char first = parse_character(name, buffer, idx);
     139             : 
     140          42 :   if (idx == buffer.size()) {
     141           2 :     name.is_valid_ = false;
     142          37 :     return;
     143             :   }
     144             : 
     145          40 :   if (buffer[idx] != '-') {
     146          32 :     characters.insert(first);
     147          32 :     return;
     148             :   }
     149             : 
     150           8 :   ++idx;
     151             : 
     152           8 :   if (idx == buffer.size()) {
     153           1 :     name.is_valid_ = false;
     154           1 :     return;
     155             :   }
     156             : 
     157           7 :   char last = parse_character(name, buffer, idx);
     158           7 :   if (first > last) {
     159           2 :     name.is_valid_ = false;
     160           2 :     return;
     161             :   }
     162             : 
     163          37 :   for (; first <= last; ++first) {
     164          32 :     characters.insert(first);
     165             :   }
     166             : }
     167             : 
     168           1 : std::ostream& operator<<(std::ostream& out, const Name& name) {
     169           8 :   for (const auto& atom : name) {
     170           7 :     out << atom;
     171             :   }
     172           1 :   return out;
     173             : }
     174             : 
     175             : }

Generated by: LCOV version 1.16