Goby3 3.2.3
2025.05.13
Loading...
Searching...
No Matches
log_entry.h
Go to the documentation of this file.
1// Copyright 2017-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_LOG_LOG_ENTRY_H
25#define GOBY_MIDDLEWARE_LOG_LOG_ENTRY_H
26
27#include <boost/bimap.hpp> // for bimap
28#include <boost/crc.hpp> // for crc_32_type
29#include <cstdint> // for uint16_t, uint32_t, uint64_t, uin...
30#include <functional> // for function
31#include <istream> // for ostream, istream, basic_ostream::...
32#include <limits> // for numeric_limits
33#include <map> // for map
34#include <stdexcept> // for runtime_error
35#include <string> // for string, allocator, operator+, ope...
36#include <utility> // for move
37#include <vector> // for vector
38
39#include "goby/middleware/group.h" // for Group, DynamicGroup
41
42namespace goby
43{
44namespace middleware
45{
46namespace log
47{
48class LogException : public std::runtime_error
49{
50 public:
51 LogException(const std::string& s) : std::runtime_error(s){};
52};
53
54template <int Bytes> struct uint
55{
56};
57template <> struct uint<1>
58{
59 using type = std::uint8_t;
60};
61template <> struct uint<2>
62{
63 using type = std::uint16_t;
64};
65template <> struct uint<4>
66{
67 using type = std::uint32_t;
68};
69template <> struct uint<8>
70{
71 using type = std::uint64_t;
72};
73
75{
76 int scheme;
77 std::string group;
78 std::string type;
79};
80
81inline bool operator<(const LogFilter& a, const LogFilter& b)
82{
83 if (a.scheme == b.scheme)
84 {
85 if (a.group == b.group)
86 return a.type < b.type;
87 else
88 return a.group < b.group;
89 }
90 else
91 {
92 return a.scheme < b.scheme;
93 }
94}
95
96//inline bool operator==(const LogFilter& a, const LogFilter& b)
97//{ return a.scheme == b.scheme && a.group == b.group && a.type == b.type; }
98
100{
101 public:
102 static constexpr int magic_bytes_{4};
103 static constexpr int size_bytes_{4};
104 static constexpr int scheme_bytes_{2};
105 static constexpr int group_bytes_{2};
106 static constexpr int type_bytes_{2};
107 static constexpr int timestamp_bytes_{8};
108 static constexpr int crc_bytes_{4};
111
112 static constexpr int version_bytes_{4};
113 static constexpr int compiled_current_version{3};
115 // "invalid_version" until version is read or written
117 static constexpr decltype(version_) invalid_version{0};
118
119 static std::map<int, std::function<void(const std::string& type)>> new_type_hook;
120 static std::map<int, std::function<void(const Group& group)>> new_group_hook;
121
122 static std::map<LogFilter, std::function<void(const std::vector<unsigned char>& data)>>
124
125 public:
126 LogEntry(std::vector<unsigned char> data, int scheme, std::string type, const Group& group,
128 : data_(std::move(data)),
129 scheme_(scheme),
130 type_(std::move(type)),
131 group_(std::string(group)),
132 timestamp_(std::move(timestamp))
133 {
134 }
135
136 LogEntry() : group_("") {}
137 void parse_version(std::istream* s);
138 void parse(std::istream* s);
139
140 // used by the unit tests to override version numbers
141 static void set_current_version(decltype(version_) version) { current_version_ = version; }
142
143 // [GBY3][size: 4][scheme: 2][group: 2][type: 2][timestamp: 8][data][crc32: 4]
144 // if scheme == 0xFFFF what follows is not data, but the string value for the group index
145 // if scheme == 0xFFFE what follows is not data, but the string value for the group index
146 void serialize(std::ostream* s) const;
147
148 const std::vector<unsigned char>& data() const { return data_; }
149 int scheme() const { return scheme_; }
150 const std::string& type() const { return type_; }
151 const Group& group() const { return group_; }
152 const goby::time::SystemClock::time_point& timestamp() const { return timestamp_; }
153
154 static void reset()
155 {
156 groups_.clear();
157 types_.clear();
158 new_type_hook.clear();
159 new_group_hook.clear();
160 filter_hook.clear();
161
162 group_index_ = 1;
163 type_index_ = 1;
166 }
167
168 private:
169 void _serialize(std::ostream* s, uint<scheme_bytes_>::type scheme,
171 const char* data, int data_size) const;
172
173 template <typename Unsigned>
174 Unsigned read_one(std::istream* s, boost::crc_32_type* crc = nullptr)
175 {
176 auto size = std::numeric_limits<Unsigned>::digits / 8;
177 std::string str(size, '\0');
178 s->read(&str[0], size);
179 if (crc)
180 crc->process_bytes(&str[0], size);
181
182 return string_to_netint<Unsigned>(str);
183 }
184
185 template <typename Unsigned> std::string netint_to_string(Unsigned u) const
186 {
187 auto size = std::numeric_limits<Unsigned>::digits / 8;
188 std::string s(size, '\0');
189 for (int i = 0; i < size; ++i) s[i] = (u >> (size - (i + 1)) * 8) & 0xff;
190 return s;
191 }
192
193 template <typename Unsigned> Unsigned string_to_netint(std::string s) const
194 {
195 Unsigned u(0);
196 std::string::size_type size = std::numeric_limits<Unsigned>::digits / 8;
197 if (s.size() > size)
198 s.erase(0, s.size() - size);
199 if (s.size() < size)
200 s.insert(0, size - s.size(), '\0');
201
202 for (decltype(size) i = 0; i < size; ++i)
203 u |= static_cast<Unsigned>(s[i] & 0xff) << ((size - (i + 1)) * 8);
204 return u;
205 }
206
207 private:
208 std::vector<unsigned char> data_;
209 uint<scheme_bytes_>::type scheme_;
210 std::string type_;
211 DynamicGroup group_;
213
214 // map (scheme -> map (group_name -> group_index)
215 static std::map<int, boost::bimap<std::string, uint<group_bytes_>::type>> groups_;
216 static uint<group_bytes_>::type group_index_;
217
218 // map (scheme -> map (group_name -> group_index)
219 static std::map<int, boost::bimap<std::string, uint<type_bytes_>::type>> types_;
220 static uint<type_bytes_>::type type_index_;
221
222 const std::string magic_{"GBY3"};
223};
224
225} // namespace log
226} // namespace middleware
227} // namespace goby
228
229#endif
Class for grouping publications in the Goby middleware. Analogous to "topics" in ROS,...
Definition group.h:60
static uint< version_bytes_ >::type version_
Definition log_entry.h:116
void parse_version(std::istream *s)
static constexpr int group_bytes_
Definition log_entry.h:105
static constexpr int type_bytes_
Definition log_entry.h:106
static void set_current_version(decltype(version_) version)
Definition log_entry.h:141
const goby::time::SystemClock::time_point & timestamp() const
Definition log_entry.h:152
void parse(std::istream *s)
static constexpr int timestamp_bytes_
Definition log_entry.h:107
static constexpr int compiled_current_version
Definition log_entry.h:113
const std::string & type() const
Definition log_entry.h:150
static std::map< int, std::function< void(const Group &group)> > new_group_hook
Definition log_entry.h:120
static constexpr int crc_bytes_
Definition log_entry.h:108
const Group & group() const
Definition log_entry.h:151
static constexpr int scheme_bytes_
Definition log_entry.h:104
static constexpr uint< scheme_bytes_ >::type scheme_type_index_
Definition log_entry.h:110
static constexpr uint< scheme_bytes_ >::type scheme_group_index_
Definition log_entry.h:109
static std::map< int, std::function< void(const std::string &type)> > new_type_hook
Definition log_entry.h:119
static std::map< LogFilter, std::function< void(const std::vector< unsigned char > &data)> > filter_hook
Definition log_entry.h:123
void serialize(std::ostream *s) const
static constexpr int size_bytes_
Definition log_entry.h:103
const std::vector< unsigned char > & data() const
Definition log_entry.h:148
static constexpr int version_bytes_
Definition log_entry.h:112
static constexpr decltype(version_) invalid_version
Definition log_entry.h:117
static constexpr int magic_bytes_
Definition log_entry.h:102
LogEntry(std::vector< unsigned char > data, int scheme, std::string type, const Group &group, goby::time::SystemClock::time_point timestamp=goby::time::SystemClock::now())
Definition log_entry.h:126
LogException(const std::string &s)
Definition log_entry.h:51
bool operator<(const LogFilter &a, const LogFilter &b)
Definition log_entry.h:81
The global namespace for the Goby project.
STL namespace.
std::chrono::time_point< SystemClock > time_point
static time_point now() noexcept
Returns the current system time unless SimulatorSettings::using_sim_time is set to true,...