Goby3  3.1.5a
2024.05.23
common.h
Go to the documentation of this file.
1 // Copyright 2020-2021:
2 // GobySoft, LLC (2013-)
3 // Community contributors (see AUTHORS file)
4 // File authors:
5 // Toby Schneider <toby@gobysoft.org>
6 //
7 //
8 // This file is part of the Goby Underwater Autonomy Project Libraries
9 // ("The Goby Libraries").
10 //
11 // The Goby Libraries are free software: you can redistribute them and/or modify
12 // them under the terms of the GNU Lesser General Public License as published by
13 // the Free Software Foundation, either version 2.1 of the License, or
14 // (at your option) any later version.
15 //
16 // The Goby Libraries are distributed in the hope that they will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public License
22 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
23 
24 #ifndef GOBY_MIDDLEWARE_IO_LINE_BASED_COMMON_H
25 #define GOBY_MIDDLEWARE_IO_LINE_BASED_COMMON_H
26 
27 #include <atomic> // for atomic
28 #include <locale> // for ctype, use_facet, locale
29 #include <map> // for map
30 #include <regex> // for _NFA, match_results, regex, regex_search
31 #include <sstream> // for basic_stringbuf<>::int_type, basic_stringbuf<>::...
32 #include <stddef.h> // for size_t
33 #include <string> // for string
34 #include <utility> // for make_pair, pair
35 #include <vector> // for vector
36 
37 namespace boost
38 {
39 namespace asio
40 {
41 template <typename T> struct is_match_condition;
42 }
43 } // namespace boost
44 
45 namespace goby
46 {
47 namespace middleware
48 {
49 namespace io
50 {
53 {
54  public:
55  explicit match_regex(std::string eol) : eol_regex_(ctype_narrow_workaround(eol)) {}
56 
57  template <typename Iterator>
58  std::pair<Iterator, bool> operator()(Iterator begin, Iterator end) const
59  {
60  std::match_results<Iterator> result;
61  if (std::regex_search(begin, end, result, eol_regex_))
62  return std::make_pair(begin + result.position() + result.length(), true);
63  else
64  return std::make_pair(begin, false);
65  }
66 
67  private:
68  std::string ctype_narrow_workaround(std::string eol)
69  {
70  // Thanks to Boris Kolpackov:
71  // A data race happens in the libstdc++ (as of GCC 7.2) implementation of the
72  // ctype<ctype>::narrow() function (bug #77704).
73  // We work around this by pre-initializing the global locale
74  // facet internal cache.
75  static std::atomic<bool> ctype_narrow_initialized{false};
76  if (!ctype_narrow_initialized)
77  {
78  const std::ctype<char>& ct(std::use_facet<std::ctype<char>>(std::locale()));
79  for (size_t i(0); i != 256; ++i) ct.narrow(static_cast<char>(i), '\0');
80  ctype_narrow_initialized = true;
81  }
82  return eol;
83  }
84 
85  private:
86  std::regex eol_regex_;
87 };
88 
89 } // namespace io
90 } // namespace middleware
91 } // namespace goby
92 
93 namespace boost
94 {
95 namespace asio
96 {
97 template <> struct is_match_condition<goby::middleware::io::match_regex> : public boost::true_type
98 {
99 };
100 } // namespace asio
101 } // namespace boost
102 
103 #endif
goby
The global namespace for the Goby project.
Definition: acomms_constants.h:33
boost
Definition: udp_driver.h:41
boost::asio::is_match_condition
Definition: common.h:41
goby::middleware::io::match_regex::operator()
std::pair< Iterator, bool > operator()(Iterator begin, Iterator end) const
Definition: common.h:58
goby::middleware::io::match_regex::match_regex
match_regex(std::string eol)
Definition: common.h:55
goby::middleware::io::match_regex
Provides a matching function object for the boost::asio::async_read_until based on a std::regex.
Definition: common.h:52