DCCL v4
Loading...
Searching...
No Matches
default_field_codec.h
1// Copyright 2023:
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 Dynamic Compact Control Language Library
9// ("DCCL").
10//
11// DCCL is free software: you can redistribute it and/or modify
12// it 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// DCCL is distributed in the hope that it 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 DCCL. If not, see <http://www.gnu.org/licenses/>.
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
36namespace dccl
37{
38
39namespace internal
40{
41
42//
43// Helper functions to reduce copy/paste in set_default_codecs()
44//
45template <int version> struct DefaultFieldCodecLoader
46{
47 static_assert(sizeof(DefaultFieldCodecLoader) == 0,
48 "Must use specialization of DefaultFieldCodecLoader");
49};
50
51template <int version> struct TimeCodecLoader
52{
53 static_assert(sizeof(TimeCodecLoader) == 0, "Must use specialization of TimeCodecLoader");
54};
55
56template <int version> struct StaticCodecLoader
57{
58 static_assert(sizeof(StaticCodecLoader) == 0, "Must use specialization of StaticCodecLoader");
59};
60
61template <int version> struct PresenceCodecLoader
62{
63 static_assert(sizeof(PresenceCodecLoader) == 0,
64 "Must use specialization of PresenceCodecLoader");
65};
66
67template <int version> struct VarBytesCodecLoader
68{
69 static_assert(sizeof(VarBytesCodecLoader) == 0,
70 "Must use specialization of VarBytesCodecLoader");
71};
72
73template <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
82namespace dccl
83{
84namespace internal
85{
86// replace recursion with C++ 17 fold expression when we switch to C++ 17 or newer
87template <> 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
120template <int version> struct TimeCodecLoader;
121template <> 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
141template <> 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
163template <> 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
195const std::string PresenceCodecLoader<CODEC_VERSION>::name_{"dccl.presence" +
196 std::to_string(CODEC_VERSION)};
197
198template <> 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
210template <> 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
A class for managing the various field codecs. Here you can add and remove field codecs....
std::enable_if< std::is_base_of< google::protobuf::Message, typenameCodec::wire_type >::value &&!std::is_same< google::protobuf::Message, typenameCodec::wire_type >::value, void >::type add(const std::string &name)
Add a new field codec (used for codecs operating on statically generated Protobuf messages,...
Dynamic Compact Control Language namespace.
Definition any.h:47