26 #ifndef DCCLFIELDCODECTYPED20120312H
27 #define DCCLFIELDCODECTYPED20120312H
29 #include <type_traits>
31 #include "field_codec.h"
37 template <
typename WireType,
typename FieldType,
class Enable =
void>
45 virtual WireType
pre_encode(
const FieldType& field_value) = 0;
51 virtual FieldType
post_decode(
const WireType& wire_value) = 0;
55 template <
typename WireType,
typename FieldType>
57 std::enable_if_t<std::is_same<WireType, FieldType>::value>>
62 virtual WireType
pre_encode(
const FieldType& field_value) {
return field_value; }
64 virtual FieldType
post_decode(
const WireType& wire_value) {
return wire_value; }
72 template <
typename WireType,
typename FieldType = WireType>
76 using wire_type = WireType;
77 using field_type = FieldType;
106 virtual unsigned size(
const WireType& wire_value) = 0;
109 unsigned any_size(
const dccl::any& wire_value)
override
113 return is_empty(wire_value) ?
size() :
size(dccl::any_cast<WireType>(wire_value));
115 catch (dccl::bad_any_cast&)
117 throw(type_error(
"size",
typeid(WireType), wire_value.type()));
121 void any_encode(
Bitset* bits,
const dccl::any& wire_value)
override
125 *bits = is_empty(wire_value) ?
encode() :
encode(
dccl::any_cast<WireType>(wire_value));
127 catch (dccl::bad_any_cast&)
129 throw(type_error(
"encode",
typeid(WireType), wire_value.type()));
133 void any_decode(Bitset* bits, dccl::any* wire_value)
override
135 any_decode_specific<WireType>(bits, wire_value);
138 void any_pre_encode(dccl::any* wire_value,
const dccl::any& field_value)
override
142 if (!is_empty(field_value))
143 *wire_value = this->
pre_encode(dccl::any_cast<FieldType>(field_value));
145 catch (dccl::bad_any_cast&)
147 throw(type_error(
"pre_encode",
typeid(FieldType), field_value.type()));
149 catch (NullValueException&)
151 *wire_value = dccl::any();
155 void any_post_decode(
const dccl::any& wire_value, dccl::any* field_value)
override
157 any_post_decode_specific<WireType>(wire_value, field_value);
161 template <
typename T>
162 typename std::enable_if_t<std::is_base_of<google::protobuf::Message, T>::value,
void>
163 any_post_decode_specific(
const dccl::any& wire_value, dccl::any* field_value)
165 *field_value = wire_value;
168 template <
typename T>
169 typename std::enable_if_t<!std::is_base_of<google::protobuf::Message, T>::value,
void>
170 any_post_decode_specific(
const dccl::any& wire_value, dccl::any* field_value)
174 if (!is_empty(wire_value))
175 *field_value = this->
post_decode(dccl::any_cast<WireType>(wire_value));
177 catch (dccl::bad_any_cast&)
179 throw(type_error(
"post_decode",
typeid(WireType), wire_value.type()));
181 catch (NullValueException&)
183 *field_value = dccl::any();
187 template <
typename T>
188 typename std::enable_if_t<std::is_base_of<google::protobuf::Message, T>::value,
void>
189 any_decode_specific(Bitset* bits, dccl::any* wire_value)
193 auto* msg = dccl::any_cast<google::protobuf::Message*>(*wire_value);
194 msg->CopyFrom(
decode(bits));
196 catch (NullValueException&)
199 *wire_value = dccl::any();
203 template <
typename T>
204 typename std::enable_if_t<!std::is_base_of<google::protobuf::Message, T>::value,
void>
205 any_decode_specific(Bitset* bits, dccl::any* wire_value)
209 *wire_value =
decode(bits);
211 catch (NullValueException&)
213 *wire_value = dccl::any();
223 template <
typename WireType,
typename FieldType = WireType>
227 using wire_type = WireType;
228 using field_type = FieldType;
238 virtual unsigned size_repeated(
const std::vector<WireType>& wire_values) = 0;
267 if (is_empty(return_vec))
270 return return_vec.at(0);
282 unsigned size(
const WireType& wire_value)
override
292 void any_encode_repeated(
Bitset* bits,
const std::vector<dccl::any>& wire_values)
override
296 std::vector<WireType> in;
297 for (
const auto& wire_value : wire_values)
298 { in.push_back(dccl::any_cast<WireType>(wire_value)); } *bits =
encode_repeated(in);
300 catch (dccl::bad_any_cast&)
302 throw(type_error(
"encode_repeated",
typeid(WireType), wire_values.at(0).type()));
306 void any_decode_repeated(Bitset* repeated_bits, std::vector<dccl::any>* field_values)
override
308 any_decode_repeated_specific<WireType>(repeated_bits, field_values);
311 template <
typename T>
312 typename std::enable_if_t<std::is_base_of<google::protobuf::Message, T>::value,
void>
313 any_decode_repeated_specific(Bitset* repeated_bits, std::vector<dccl::any>* wire_values)
316 wire_values->resize(decoded_msgs.size(), WireType());
318 for (
int i = 0, n = decoded_msgs.size(); i < n; ++i)
320 auto* msg = dccl::any_cast<google::protobuf::Message*>(wire_values->at(i));
321 msg->CopyFrom(decoded_msgs[i]);
325 template <
typename T>
326 typename std::enable_if_t<!std::is_base_of<google::protobuf::Message, T>::value,
void>
327 any_decode_repeated_specific(Bitset* repeated_bits, std::vector<dccl::any>* wire_values)
330 wire_values->resize(decoded.size(), WireType());
332 for (
int i = 0, n = decoded.size(); i < n; ++i) wire_values->at(i) = decoded[i];
335 void any_pre_encode(dccl::any* wire_value,
const dccl::any& field_value)
override
339 if (!is_empty(field_value))
340 *wire_value = this->
pre_encode(dccl::any_cast<FieldType>(field_value));
342 catch (dccl::bad_any_cast&)
344 throw(type_error(
"pre_encode",
typeid(FieldType), field_value.type()));
346 catch (NullValueException&)
348 *wire_value = dccl::any();
352 void any_post_decode(
const dccl::any& wire_value, dccl::any* field_value)
override
356 if (!is_empty(wire_value))
357 *field_value = this->
post_decode(dccl::any_cast<WireType>(wire_value));
359 catch (dccl::bad_any_cast&)
361 throw(type_error(
"post_decode",
typeid(WireType), wire_value.type()));
363 catch (NullValueException&)
365 *field_value = dccl::any();
375 unsigned any_size_repeated(
const std::vector<dccl::any>& wire_values)
override
379 std::vector<WireType> in;
380 for (
const auto& wire_value : wire_values)
381 { in.push_back(dccl::any_cast<WireType>(wire_value)); }
return size_repeated(in);
383 catch (dccl::bad_any_cast&)
385 throw(type_error(
"size_repeated",
typeid(WireType), wire_values.at(0).type()));
A variable size container of bits (subclassed from std::deque<bool>) with an optional hierarchy....
Provides a base class for defining DCCL field encoders / decoders. Most users who wish to define cust...
const google::protobuf::FieldDescriptor * this_field() const
Returns the FieldDescriptor (field schema meta-data) for this field.
virtual WireType pre_encode(const FieldType &field_value)
No-op version of pre_encode (since FieldType == WireType)
virtual FieldType post_decode(const WireType &wire_value)
No-op version of post_encode (since FieldType == WireType)
A class that goes between FieldCodecBase and TypedFieldCodec to determine if the pre_encode() and pos...
virtual FieldType post_decode(const WireType &wire_value)=0
Convert from the WireType representation (used with encode() and decode(), i.e. "on the wire") to the...
virtual WireType pre_encode(const FieldType &field_value)=0
Convert from the FieldType representation (used in the Google Protobuf message) to the WireType repre...
Exception used to signal null (non-existent) value within field codecs during decode.
Base class for "repeated" (multiple value) static-typed (no dccl::any) field encoders/decoders....
unsigned max_size() override
Calculate maximum size of the field in bits.
virtual std::vector< WireType > decode_repeated(Bitset *bits)=0
Decode a repeated field.
virtual Bitset encode_repeated(const std::vector< WireType > &wire_value)=0
Encode a repeated field.
WireType decode(dccl::Bitset *bits) override
Decode a field. If the field is empty (i.e. was encoded using the zero-argument encode()),...
unsigned max_size_repeated() override=0
Give the max size of a repeated field.
virtual unsigned size_repeated(const std::vector< WireType > &wire_values)=0
Give the size of a repeated field.
Bitset encode() override
Encode an empty field.
unsigned min_size() override
Calculate minimum size of the field in bits.
Bitset encode(const WireType &wire_value) override
Encode a non-empty field.
unsigned size() override
Calculate the size (in bits) of an empty field.
unsigned min_size_repeated() override=0
Give the min size of a repeated field.
unsigned size(const WireType &wire_value) override
Calculate the size (in bits) of a non-empty field.
Base class for static-typed (no dccl::any) field encoders/decoders. Most single-valued user defined v...
virtual Bitset encode()=0
Encode an empty field.
virtual unsigned size(const WireType &wire_value)=0
Calculate the size (in bits) of a non-empty field.
virtual unsigned size()=0
Calculate the size (in bits) of an empty field.
virtual WireType decode(Bitset *bits)=0
Decode a field. If the field is empty (i.e. was encoded using the zero-argument encode()),...
virtual Bitset encode(const WireType &wire_value)=0
Encode a non-empty field.
Dynamic Compact Control Language namespace.