LCOV - code coverage report
Current view: top level - source/common/formatter - substitution_format_utility.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 21 21 100.0 %
Date: 2024-01-05 06:35:25 Functions: 11 11 100.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <string>
       4             : #include <vector>
       5             : 
       6             : #include "envoy/http/protocol.h"
       7             : #include "envoy/stream_info/stream_info.h"
       8             : 
       9             : #include "absl/strings/str_format.h"
      10             : #include "absl/strings/str_replace.h"
      11             : #include "absl/strings/str_split.h"
      12             : #include "absl/types/optional.h"
      13             : #include "fmt/format.h"
      14             : 
      15             : namespace Envoy {
      16             : namespace Formatter {
      17             : 
      18             : class CommandSyntaxChecker {
      19             : public:
      20             :   using CommandSyntaxFlags = std::bitset<4>;
      21             :   static constexpr CommandSyntaxFlags COMMAND_ONLY = 0;
      22             :   static constexpr CommandSyntaxFlags PARAMS_REQUIRED = 1 << 0;
      23             :   static constexpr CommandSyntaxFlags PARAMS_OPTIONAL = 1 << 1;
      24             :   static constexpr CommandSyntaxFlags LENGTH_ALLOWED = 1 << 2;
      25             : 
      26             :   static void verifySyntax(CommandSyntaxChecker::CommandSyntaxFlags flags,
      27             :                            const std::string& command, const std::string& subcommand,
      28             :                            const absl::optional<size_t>& length);
      29             : };
      30             : 
      31             : /**
      32             :  * Context independent utility class for the formatter.
      33             :  */
      34             : class SubstitutionFormatUtils {
      35             : public:
      36             :   // Optional references are not supported, but this method has large performance
      37             :   // impact, so using reference_wrapper.
      38             :   static const absl::optional<std::reference_wrapper<const std::string>>
      39             :   protocolToString(const absl::optional<Http::Protocol>& protocol);
      40             :   static const std::string&
      41             :   protocolToStringOrDefault(const absl::optional<Http::Protocol>& protocol);
      42             :   static const absl::optional<std::string> getHostname();
      43             :   static const std::string getHostnameOrDefault();
      44             : 
      45             :   /**
      46             :    * Unspecified value for protobuf.
      47             :    */
      48             :   static const ProtobufWkt::Value& unspecifiedValue();
      49             : 
      50             :   /**
      51             :    * Truncate a string to a maximum length. Do nothing if max_length is not set or
      52             :    * max_length is greater than the length of the string.
      53             :    */
      54             :   static void truncate(std::string& str, absl::optional<size_t> max_length);
      55             : 
      56             :   /**
      57             :    * Parse a header subcommand of the form: X?Y .
      58             :    * Will populate a main_header and an optional alternative header if specified.
      59             :    * See doc:
      60             :    * https://envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/access_log#format-rules
      61             :    */
      62             :   static void parseSubcommandHeaders(const std::string& subcommand, std::string& main_header,
      63             :                                      std::string& alternative_header);
      64             : 
      65             :   /* Variadic function template to parse the
      66             :      subcommand and assign found tokens to sequence of params.
      67             :      subcommand must be a sequence
      68             :      of tokens separated by the same separator, like: header1:header2 or header1?header2?header3.
      69             :      params must be a sequence of std::string& with optional container storing std::string. Here are
      70             :      examples of params:
      71             :      - std::string& token1
      72             :      - std::string& token1, std::string& token2
      73             :      - std::string& token1, std::string& token2, std::vector<std::string>& remaining
      74             : 
      75             :      If command contains more tokens than number of passed params, unassigned tokens will be
      76             :      ignored. If command contains less tokens than number of passed params, some params will be left
      77             :      untouched.
      78             :   */
      79             :   template <typename... Tokens>
      80             :   static void parseSubcommand(const std::string& subcommand, const char separator,
      81        1705 :                               Tokens&&... params) {
      82        1705 :     std::vector<absl::string_view> tokens;
      83        1705 :     tokens = absl::StrSplit(subcommand, separator);
      84        1705 :     std::vector<absl::string_view>::iterator it = tokens.begin();
      85        1705 :     (
      86        5063 :         [&](auto& param) {
      87        5063 :           if (it != tokens.end()) {
      88        2030 :             if constexpr (std::is_same_v<typename std::remove_reference<decltype(param)>::type,
      89        2030 :                                          std::string>) {
      90             :               // Compile time handler for std::string.
      91        2004 :               param = std::string(*it);
      92        2004 :               it++;
      93        2004 :             } else {
      94             :               // Compile time handler for container type. It will catch all remaining tokens and
      95             :               // move iterator to the end.
      96          38 :               do {
      97          38 :                 param.push_back(std::string(*it));
      98          38 :                 it++;
      99          38 :               } while (it != tokens.end());
     100          26 :             }
     101        2030 :           }
     102        5063 :         }(params),
     103        1705 :         ...);
     104        1705 :   }
     105             : };
     106             : 
     107             : } // namespace Formatter
     108             : } // namespace Envoy

Generated by: LCOV version 1.15