DCCL v4
default_field_codec.h
1 // Copyright 2023:
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 //
6 //
7 // This file is part of the Dynamic Compact Control Language Library
8 // ("DCCL").
9 //
10 // DCCL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 2.1 of the License, or
13 // (at your option) any later version.
14 //
15 // DCCL is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
22 
23 #include "codec.h"
24 
25 #ifndef CODEC_VERSION
26 #error CODEC_VERSION must be set
27 #endif
28 
29 #ifndef CODEC_VERSION_NAMESPACE
30 #error CODEC_VERSION_NAMESPACE must be set
31 #endif
32 
33 #ifndef DCCL_DEFAULT_FIELD_CODEC_HEADER_H
34 #define DCCL_DEFAULT_FIELD_CODEC_HEADER_H
35 
36 namespace dccl
37 {
38 
39 namespace internal
40 {
41 
42 //
43 // Helper functions to reduce copy/paste in set_default_codecs()
44 //
45 template <int version> struct DefaultFieldCodecLoader
46 {
47  static_assert(sizeof(DefaultFieldCodecLoader) == 0,
48  "Must use specialization of DefaultFieldCodecLoader");
49 };
50 
51 template <int version> struct TimeCodecLoader
52 {
53  static_assert(sizeof(TimeCodecLoader) == 0, "Must use specialization of TimeCodecLoader");
54 };
55 
56 template <int version> struct StaticCodecLoader
57 {
58  static_assert(sizeof(StaticCodecLoader) == 0, "Must use specialization of StaticCodecLoader");
59 };
60 
61 template <int version> struct PresenceCodecLoader
62 {
63  static_assert(sizeof(PresenceCodecLoader) == 0,
64  "Must use specialization of PresenceCodecLoader");
65 };
66 
67 template <int version> struct VarBytesCodecLoader
68 {
69  static_assert(sizeof(VarBytesCodecLoader) == 0,
70  "Must use specialization of VarBytesCodecLoader");
71 };
72 
73 template <int version> struct HashCodecLoader
74 {
75  static_assert(sizeof(HashCodecLoader) == 0, "Must use specialization of HashCodecLoader");
76 };
77 
78 } // namespace internal
79 } // namespace dccl
80 #endif
81 
82 namespace dccl
83 {
84 namespace internal
85 {
86 // replace recursion with C++ 17 fold expression when we switch to C++ 17 or newer
87 template <> struct DefaultFieldCodecLoader<CODEC_VERSION>
88 {
89  // entry
90  static void add(FieldCodecManagerLocal& manager)
91  {
92  using namespace CODEC_VERSION_NAMESPACE;
93  using google::protobuf::FieldDescriptor;
94 
95  std::string name = ::dccl::Codec::default_codec_name(CODEC_VERSION);
96  manager.add<DefaultBoolCodec>(name);
97  manager.add<DefaultStringCodec, FieldDescriptor::TYPE_STRING>(name);
98  manager.add<DefaultBytesCodec, FieldDescriptor::TYPE_BYTES>(name);
99  manager.add<DefaultEnumCodec>(name);
100  manager.add<DefaultMessageCodec, FieldDescriptor::TYPE_MESSAGE>(name);
101 
102  add<true, double, float, int32, int64, uint32, uint64>(manager);
103  }
104 
105  // recurse
106  template <bool enable, typename T, typename... Types>
107  static void add(FieldCodecManagerLocal& manager)
108  {
109  using namespace CODEC_VERSION_NAMESPACE;
110  std::string name = ::dccl::Codec::default_codec_name(CODEC_VERSION);
111  manager.add<DefaultNumericFieldCodec<T>>(name);
112  // recurse
113  add<enable, Types...>(manager);
114  }
115 
116  // last
117  template <bool enable> static void add(FieldCodecManagerLocal& manager) {}
118 };
119 
120 template <int version> struct TimeCodecLoader;
121 template <> struct TimeCodecLoader<CODEC_VERSION>
122 {
123  static void add(FieldCodecManagerLocal& manager,
124  const std::string& name = "dccl.time" + std::to_string(CODEC_VERSION))
125  {
126  add<true, double, int64, uint64>(manager, name);
127  }
128 
129  template <bool enable, typename T, typename... Types>
130  static void add(FieldCodecManagerLocal& manager, const std::string& name)
131  {
132  using namespace CODEC_VERSION_NAMESPACE;
133  manager.add<TimeCodec<T>>(name);
134  add<enable, Types...>(manager, name);
135  }
136  template <bool enable> static void add(FieldCodecManagerLocal& manager, const std::string& name)
137  {
138  }
139 };
140 
141 template <> struct StaticCodecLoader<CODEC_VERSION>
142 {
143  static void add(FieldCodecManagerLocal& manager,
144  const std::string& name = "dccl.static" + std::to_string(CODEC_VERSION))
145  {
146  add<true, std::string, double, float, int32, int64, uint32, uint64>(manager, name);
147  }
148 
149  template <bool enable, typename T, typename... Types>
150  static void add(FieldCodecManagerLocal& manager, const std::string& name)
151  {
152  using namespace CODEC_VERSION_NAMESPACE;
153  manager.add<StaticCodec<T>>(name);
154  add<enable, Types...>(manager, name);
155  }
156 
157  template <bool enable> static void add(FieldCodecManagerLocal& manager, const std::string& name)
158  {
159  }
160 };
161 
162 #if CODEC_VERSION >= 3
163 template <> struct PresenceCodecLoader<CODEC_VERSION>
164 {
165  static void add(FieldCodecManagerLocal& manager)
166  {
167  using namespace CODEC_VERSION_NAMESPACE;
168  using google::protobuf::FieldDescriptor;
169 
170  manager.add<PresenceBitCodec<DefaultBoolCodec>>(name_);
171  manager.add<PresenceBitCodec<DefaultStringCodec>, FieldDescriptor::TYPE_STRING>(name_);
172  manager.add<PresenceBitCodec<DefaultBytesCodec>, FieldDescriptor::TYPE_BYTES>(name_);
173  manager.add<PresenceBitCodec<DefaultEnumCodec>>(name_);
174 
175  // use normal default meessage codec
176  manager.add<DefaultMessageCodec, FieldDescriptor::TYPE_MESSAGE>(name_);
177  add<true, double, float, int32, int64, uint32, uint64>(manager);
178  }
179 
180  template <bool enable, typename T, typename... Types>
181  static void add(FieldCodecManagerLocal& manager)
182  {
183  using namespace CODEC_VERSION_NAMESPACE;
184  std::string name = ::dccl::Codec::default_codec_name(CODEC_VERSION);
185  manager.add<PresenceBitCodec<DefaultNumericFieldCodec<T>>>(name_);
186  add<enable, Types...>(manager);
187  }
188 
189  template <bool enable> static void add(FieldCodecManagerLocal& manager) {}
190 
191  private:
192  static const std::string name_;
193 };
194 
195 const std::string PresenceCodecLoader<CODEC_VERSION>::name_{"dccl.presence" +
196  std::to_string(CODEC_VERSION)};
197 
198 template <> struct VarBytesCodecLoader<CODEC_VERSION>
199 {
200  static void add(FieldCodecManagerLocal& manager)
201  {
202  using namespace CODEC_VERSION_NAMESPACE;
203  manager.add<VarBytesCodec>("dccl.var_bytes" + std::to_string(CODEC_VERSION));
204  }
205 };
206 
207 #endif
208 
209 #if CODEC_VERSION >= 4
210 template <> struct HashCodecLoader<CODEC_VERSION>
211 {
212  static void add(FieldCodecManagerLocal& manager, std::set<int> versions = {CODEC_VERSION})
213  {
214  using namespace CODEC_VERSION_NAMESPACE;
215  // backport versions
216  for (int v : versions) manager.add<HashCodec>("dccl.hash" + std::to_string(v));
217  }
218 };
219 
220 #endif
221 
222 } // namespace internal
223 } // namespace dccl
224 
225 #undef CODEC_VERSION
226 #undef CODEC_VERSION_NAMESPACE
dccl::FieldCodecManagerLocal
A class for managing the various field codecs. Here you can add and remove field codecs....
Definition: field_codec_manager.h:39
dccl
Dynamic Compact Control Language namespace.
Definition: any.h:49
dccl::internal::DefaultFieldCodecLoader
Definition: default_field_codec.h:45
dccl::internal::StaticCodecLoader
Definition: default_field_codec.h:56
dccl::internal::HashCodecLoader
Definition: default_field_codec.h:73
dccl::FieldCodecManagerLocal::add
std::enable_if< std::is_base_of< google::protobuf::Message, typename Codec::wire_type >::value &&!std::is_same< google::protobuf::Message, typename Codec::wire_type >::value, void >::type add(const std::string &name)
Add a new field codec (used for codecs operating on statically generated Protobuf messages,...
Definition: field_codec_manager.h:313
dccl::internal::PresenceCodecLoader
Definition: default_field_codec.h:61
dccl::internal::VarBytesCodecLoader
Definition: default_field_codec.h:67
dccl::internal::TimeCodecLoader
Definition: default_field_codec.h:51