25#ifndef DCCLFIELDCODECTYPED20120312H
26#define DCCLFIELDCODECTYPED20120312H
30#include "field_codec.h"
36template <
typename WireType,
typename FieldType,
class Enable =
void>
44 virtual WireType
pre_encode(
const FieldType& field_value) = 0;
50 virtual FieldType
post_decode(
const WireType& wire_value) = 0;
54template <
typename WireType,
typename FieldType>
56 std::enable_if_t<std::is_same<WireType, FieldType>::value>>
61 virtual WireType
pre_encode(
const FieldType& field_value) {
return field_value; }
63 virtual FieldType
post_decode(
const WireType& wire_value) {
return wire_value; }
71template <
typename WireType,
typename FieldType = WireType>
75 using wire_type = WireType;
76 using field_type = FieldType;
99 virtual unsigned size() = 0;
105 virtual unsigned size(
const WireType& wire_value) = 0;
108 unsigned any_size(
const dccl::any& wire_value)
override
112 return is_empty(wire_value) ?
size() :
size(dccl::any_cast<WireType>(wire_value));
114 catch (dccl::bad_any_cast&)
116 throw(type_error(
"size",
typeid(WireType), wire_value.type()));
120 void any_encode(
Bitset* bits,
const dccl::any& wire_value)
override
124 *bits = is_empty(wire_value) ?
encode() :
encode(
dccl::any_cast<WireType>(wire_value));
126 catch (dccl::bad_any_cast&)
128 throw(type_error(
"encode",
typeid(WireType), wire_value.type()));
132 void any_decode(Bitset* bits, dccl::any* wire_value)
override
134 any_decode_specific<WireType>(bits, wire_value);
137 void any_pre_encode(dccl::any* wire_value,
const dccl::any& field_value)
override
141 if (!is_empty(field_value))
142 *wire_value = this->
pre_encode(dccl::any_cast<FieldType>(field_value));
144 catch (dccl::bad_any_cast&)
146 throw(type_error(
"pre_encode",
typeid(FieldType), field_value.type()));
148 catch (NullValueException&)
150 *wire_value = dccl::any();
154 void any_post_decode(
const dccl::any& wire_value, dccl::any* field_value)
override
156 any_post_decode_specific<WireType>(wire_value, field_value);
160 template <
typename T>
161 typename std::enable_if_t<std::is_base_of<google::protobuf::Message, T>::value,
void>
162 any_post_decode_specific(
const dccl::any& wire_value, dccl::any* field_value)
164 *field_value = wire_value;
167 template <
typename T>
168 typename std::enable_if_t<!std::is_base_of<google::protobuf::Message, T>::value,
void>
169 any_post_decode_specific(
const dccl::any& wire_value, dccl::any* field_value)
173 if (!is_empty(wire_value))
174 *field_value = this->
post_decode(dccl::any_cast<WireType>(wire_value));
176 catch (dccl::bad_any_cast&)
178 throw(type_error(
"post_decode",
typeid(WireType), wire_value.type()));
180 catch (NullValueException&)
182 *field_value = dccl::any();
186 template <
typename T>
187 typename std::enable_if_t<std::is_base_of<google::protobuf::Message, T>::value,
void>
188 any_decode_specific(Bitset* bits, dccl::any* wire_value)
192 auto* msg = dccl::any_cast<google::protobuf::Message*>(*wire_value);
193 msg->CopyFrom(
decode(bits));
195 catch (NullValueException&)
198 *wire_value = dccl::any();
202 template <
typename T>
203 typename std::enable_if_t<!std::is_base_of<google::protobuf::Message, T>::value,
void>
204 any_decode_specific(Bitset* bits, dccl::any* wire_value)
208 *wire_value =
decode(bits);
210 catch (NullValueException&)
212 *wire_value = dccl::any();
222template <
typename WireType,
typename FieldType = WireType>
226 using wire_type = WireType;
227 using field_type = FieldType;
237 virtual unsigned size_repeated(
const std::vector<WireType>& wire_values) = 0;
266 if (is_empty(return_vec))
269 return return_vec.at(0);
281 unsigned size(
const WireType& wire_value)
override
291 void any_encode_repeated(
Bitset* bits,
const std::vector<dccl::any>& wire_values)
override
295 std::vector<WireType> in;
296 for (
const auto& wire_value : wire_values)
297 { in.push_back(dccl::any_cast<WireType>(wire_value)); } *bits =
encode_repeated(in);
299 catch (dccl::bad_any_cast&)
301 throw(type_error(
"encode_repeated",
typeid(WireType), wire_values.at(0).type()));
305 void any_decode_repeated(Bitset* repeated_bits, std::vector<dccl::any>* field_values)
override
307 any_decode_repeated_specific<WireType>(repeated_bits, field_values);
310 template <
typename T>
311 typename std::enable_if_t<std::is_base_of<google::protobuf::Message, T>::value,
void>
312 any_decode_repeated_specific(Bitset* repeated_bits, std::vector<dccl::any>* wire_values)
315 wire_values->resize(decoded_msgs.size(), WireType());
317 for (
int i = 0, n = decoded_msgs.size(); i < n; ++i)
319 auto* msg = dccl::any_cast<google::protobuf::Message*>(wire_values->at(i));
320 msg->CopyFrom(decoded_msgs[i]);
324 template <
typename T>
325 typename std::enable_if_t<!std::is_base_of<google::protobuf::Message, T>::value,
void>
326 any_decode_repeated_specific(Bitset* repeated_bits, std::vector<dccl::any>* wire_values)
329 wire_values->resize(decoded.size(), WireType());
331 for (
int i = 0, n = decoded.size(); i < n; ++i) wire_values->at(i) = decoded[i];
334 void any_pre_encode(dccl::any* wire_value,
const dccl::any& field_value)
override
338 if (!is_empty(field_value))
339 *wire_value = this->
pre_encode(dccl::any_cast<FieldType>(field_value));
341 catch (dccl::bad_any_cast&)
343 throw(type_error(
"pre_encode",
typeid(FieldType), field_value.type()));
345 catch (NullValueException&)
347 *wire_value = dccl::any();
351 void any_post_decode(
const dccl::any& wire_value, dccl::any* field_value)
override
355 if (!is_empty(wire_value))
356 *field_value = this->
post_decode(dccl::any_cast<WireType>(wire_value));
358 catch (dccl::bad_any_cast&)
360 throw(type_error(
"post_decode",
typeid(WireType), wire_value.type()));
362 catch (NullValueException&)
364 *field_value = dccl::any();
374 unsigned any_size_repeated(
const std::vector<dccl::any>& wire_values)
override
378 std::vector<WireType> in;
379 for (
const auto& wire_value : wire_values)
380 { in.push_back(dccl::any_cast<WireType>(wire_value)); }
return size_repeated(in);
382 catch (dccl::bad_any_cast&)
384 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.