Goby3 3.2.3
2025.05.13
Loading...
Searching...
No Matches
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
37namespace boost
38{
39namespace asio
40{
41template <typename T> struct is_match_condition;
42}
43} // namespace boost
44
45namespace goby
46{
47namespace middleware
48{
49namespace 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
93namespace boost
94{
95namespace asio
96{
97template <> struct is_match_condition<goby::middleware::io::match_regex> : public boost::true_type
98{
99};
100} // namespace asio
101} // namespace boost
102
103#endif
Provides a matching function object for the boost::asio::async_read_until based on a std::regex.
Definition common.h:53
std::pair< Iterator, bool > operator()(Iterator begin, Iterator end) const
Definition common.h:58
match_regex(std::string eol)
Definition common.h:55
The global namespace for the Goby project.