24 #ifndef DCCLFIELDCODEC20110322H
25 #define DCCLFIELDCODEC20110322H
30 #include <google/protobuf/descriptor.h>
31 #include <google/protobuf/descriptor.pb.h>
32 #include <google/protobuf/message.h>
37 #include "dynamic_conditions.h"
38 #include "exception.h"
39 #include "internal/field_codec_message_stack.h"
40 #include "internal/type_helper.h"
42 #include "option_extensions.pb.h"
65 std::string
name()
const {
return name_; }
70 google::protobuf::FieldDescriptor::Type
field_type()
const {
return field_type_; }
75 google::protobuf::FieldDescriptor::CppType
wire_type()
const {
return wire_type_; }
80 const google::protobuf::FieldDescriptor*
this_field()
const;
102 const google::protobuf::Descriptor* root_descriptor()
const;
108 bool has_codec_group();
110 static std::string codec_group(
const google::protobuf::Descriptor* desc);
112 std::string codec_group();
165 void base_max_size(
unsigned* bit_size,
const google::protobuf::Descriptor* desc,
173 void base_min_size(
unsigned* bit_size,
const google::protobuf::Descriptor* desc,
187 void base_info(std::ostream* os,
const google::protobuf::Descriptor* desc, MessagePart
part);
194 void base_hash(std::size_t*
hash,
const google::protobuf::Descriptor* desc, MessagePart
part);
223 const std::vector<dccl::any>& field_values)
225 any_pre_encode_repeated(wire_values, field_values);
236 const google::protobuf::FieldDescriptor* field);
244 const google::protobuf::FieldDescriptor* field);
251 void field_size(
unsigned* bit_size,
const dccl::any& field_value,
252 const google::protobuf::FieldDescriptor* field);
260 const google::protobuf::FieldDescriptor* field);
269 const google::protobuf::FieldDescriptor* field);
277 const google::protobuf::FieldDescriptor* field);
293 std::vector<dccl::any>* field_values)
295 any_post_decode_repeated(wire_values, field_values);
304 void field_max_size(
unsigned* bit_size,
const google::protobuf::FieldDescriptor* field);
309 void field_min_size(
unsigned* bit_size,
const google::protobuf::FieldDescriptor* field);
316 void field_validate(
bool* b,
const google::protobuf::FieldDescriptor* field);
322 void field_info(std::ostream* os,
const google::protobuf::FieldDescriptor* field);
328 void field_hash(std::size_t*
hash,
const google::protobuf::FieldDescriptor* field);
337 return this_field()->options().GetExtension(dccl::field);
340 "Cannot call dccl_field on base message (has no *field* option extension"));
348 void require(
bool b,
const std::string& description)
354 " failed validation: " + description,
358 " failed validation: " + description,
363 DynamicConditions& dynamic_conditions(
const google::protobuf::FieldDescriptor* field);
373 const FieldCodecManagerLocal& manager()
const
378 throw(Exception(
"FieldCodecManagerLocal is not set"), this->
this_descriptor());
381 virtual void set_manager(FieldCodecManagerLocal* manager) { manager_ = manager; }
390 const google::protobuf::FieldDescriptor* field =
this_field();
393 if (dc.has_required_if())
394 dc.regenerate(this_message(), root_message());
398 else if (codec_version() > 3)
399 return field->is_required() || field->is_repeated() ||
is_part_of_oneof(field) ||
400 (dc.has_required_if() && dc.required());
401 else if (codec_version() > 2)
402 return field->is_required() || field->is_repeated() ||
403 (dc.has_required_if() && dc.required());
405 return field->is_required();
431 *wire_value = field_value;
440 *field_value = wire_value;
447 virtual unsigned any_size(
const dccl::any& wire_value) = 0;
456 virtual std::string
info();
459 virtual std::size_t
hash() {
return 0; }
471 virtual void any_encode_repeated(
Bitset* bits,
const std::vector<dccl::any>& wire_values);
472 virtual void any_decode_repeated(
Bitset* repeated_bits, std::vector<dccl::any>* field_values);
474 virtual void any_pre_encode_repeated(std::vector<dccl::any>* wire_values,
475 const std::vector<dccl::any>& field_values);
477 virtual void any_post_decode_repeated(
const std::vector<dccl::any>& wire_values,
478 std::vector<dccl::any>* field_values);
480 virtual unsigned any_size_repeated(
const std::vector<dccl::any>& wire_values);
481 virtual unsigned max_size_repeated();
482 virtual unsigned min_size_repeated();
483 void check_repeat_settings()
const;
489 void set_name(
const std::string&
name) { name_ =
name; }
490 void set_field_type(google::protobuf::FieldDescriptor::Type type) { field_type_ = type; }
491 void set_wire_type(google::protobuf::FieldDescriptor::CppType type) { wire_type_ = type; }
496 return max_size_repeated() != min_size_repeated();
501 int repeated_vector_field_size(
int min_repeat,
int max_repeat)
506 void disp_size(
const google::protobuf::FieldDescriptor* field,
const Bitset& new_bits,
507 int depth,
int vector_size = -1);
514 BaseRAII(FieldCodecBase* field_codec, MessagePart
part,
515 const google::protobuf::Descriptor* root_descriptor,
bool strict =
false);
517 BaseRAII(FieldCodecBase* field_codec, MessagePart
part,
522 FieldCodecBase* field_codec_;
524 friend struct BaseRAII;
527 google::protobuf::FieldDescriptor::Type field_type_;
528 google::protobuf::FieldDescriptor::CppType wire_type_;
530 bool force_required_{
false};
532 FieldCodecManagerLocal* manager_{
nullptr};
535 std::ostream& operator<<(std::ostream& os,
const FieldCodecBase& field_codec);
537 inline Exception type_error(
const std::string& action,
const std::type_info& expected,
538 const std::type_info& got)
540 std::string e =
"error " + action +
", expected: ";
541 e += expected.name();
void base_encode(Bitset *bits, const google::protobuf::Message &msg, MessagePart part, bool strict)
Encode this part (body or head) of the base message.
void field_pre_encode(dccl::any *wire_value, const dccl::any &field_value)
Pre-encodes a non-repeated (i.e. optional or required) field by converting the FieldType representati...
A class for managing the various field codecs. Here you can add and remove field codecs....
const google::protobuf::Descriptor * this_descriptor() const
Returns the Descriptor (message schema meta-data) for the immediate parent Message.
virtual std::string info()
Write field specific information (in addition to general information such as sizes that are automatic...
virtual unsigned min_size()=0
Calculate minimum size of the field in bits.
Provides a base class for defining DCCL field encoders / decoders. Most users who wish to define cust...
void field_post_decode_repeated(const std::vector< dccl::any > &wire_values, std::vector< dccl::any > *field_values)
Post-decodes a repeated field.
void field_decode_repeated(Bitset *bits, std::vector< dccl::any > *field_values, const google::protobuf::FieldDescriptor *field)
Decode a repeated field.
void field_post_decode(const dccl::any &wire_value, dccl::any *field_value)
Post-decodes a non-repeated (i.e. optional or required) field by converting the WireType (the type us...
virtual unsigned max_size()=0
Calculate maximum size of the field in bits.
void field_hash(std::size_t *hash, const google::protobuf::FieldDescriptor *field)
Provide a hash for this field definition.
Dynamic Compact Control Language namespace.
const google::protobuf::FieldDescriptor * this_field() const
Returns the FieldDescriptor (field schema meta-data) for this field.
void field_decode(Bitset *bits, dccl::any *field_value, const google::protobuf::FieldDescriptor *field)
Decode a non-repeated field.
Exception class for DCCL.
virtual void any_pre_encode(dccl::any *wire_value, const dccl::any &field_value)
Virtual method used to pre-encode (convert from FieldType to WireType). The default implementation of...
virtual void any_post_decode(const dccl::any &wire_value, dccl::any *field_value)
Virtual method used to post-decode (convert from WireType to FieldType). The default implementation o...
void field_min_size(unsigned *bit_size, const google::protobuf::FieldDescriptor *field)
Calculate the lower bound on this field's size (in bits)
void base_min_size(unsigned *bit_size, const google::protobuf::Descriptor *desc, MessagePart part)
Calculate the minimum size of a message given its Descriptor alone (no data)
void base_max_size(unsigned *bit_size, const google::protobuf::Descriptor *desc, MessagePart part)
Calculate the maximum size of a message given its Descriptor alone (no data)
void require(bool b, const std::string &description)
Essentially an assertion to be used in the validate() virtual method.
void set_force_use_required(bool force_required=true)
Force the codec to always use the "required" field encoding, regardless of the FieldDescriptor settin...
void field_encode(Bitset *bits, const dccl::any &field_value, const google::protobuf::FieldDescriptor *field)
Encode a non-repeated field.
virtual void validate()
Validate a field. Use require() inside your overloaded validate() to assert requirements or throw Exc...
google::protobuf::FieldDescriptor::Type field_type() const
the type exposed to the user in the original and decoded Protobuf messages
unsigned ceil_log2(dccl::uint64 v)
void field_pre_encode_repeated(std::vector< dccl::any > *wire_values, const std::vector< dccl::any > &field_values)
Pre-encodes a repeated field.
A variable size container of bits (subclassed from std::deque<bool>) with an optional hierarchy....
virtual void any_decode(Bitset *bits, dccl::any *wire_value)=0
Virtual method used to decode.
void field_validate(bool *b, const google::protobuf::FieldDescriptor *field)
Validate this field, checking that all required option extensions are set (e.g. (dccl....
virtual void any_encode(Bitset *bits, const dccl::any &wire_value)=0
Virtual method used to encode.
void field_max_size(unsigned *bit_size, const google::protobuf::FieldDescriptor *field)
Calculate the upper bound on this field's size (in bits)
void field_size(unsigned *bit_size, const dccl::any &field_value, const google::protobuf::FieldDescriptor *field)
Calculate the size of a field.
void base_hash(std::size_t *hash, const google::protobuf::Descriptor *desc, MessagePart part)
Provide a hash of the DCCL message definition to detect changes in the DCCL message.
void field_encode_repeated(Bitset *bits, const std::vector< dccl::any > &field_values, const google::protobuf::FieldDescriptor *field)
Encode a repeated field.
void field_size_repeated(unsigned *bit_size, const std::vector< dccl::any > &field_values, const google::protobuf::FieldDescriptor *field)
Calculate the size of a repeated field.
void base_info(std::ostream *os, const google::protobuf::Descriptor *desc, MessagePart part)
Get human readable information (size of fields, etc.) about this part of the DCCL message.
virtual unsigned any_size(const dccl::any &wire_value)=0
Virtual method for calculating the size of a field (in bits).
void field_info(std::ostream *os, const google::protobuf::FieldDescriptor *field)
Write human readable information about the field and its bounds to the provided stream.
bool use_required()
Whether to use the required or optional encoding.
void base_validate(const google::protobuf::Descriptor *desc, MessagePart part)
Validate this part of the message to make sure all required extensions are set.
void base_size(unsigned *bit_size, const google::protobuf::Message &msg, MessagePart part)
Calculate the size (in bits) of a part of the base message when it is encoded.
MessagePart part()
the part of the message currently being encoded (head or body)
void base_decode(Bitset *bits, google::protobuf::Message *msg, MessagePart part)
Decode part of a message.
std::string name() const
the name of the codec used to identifier it in the .proto custom option extension
dccl::DCCLFieldOptions dccl_field_options() const
Get the DCCL field option extension value for the current field.
bool is_part_of_oneof(const google::protobuf::FieldDescriptor *field_desc)
Checks whether a given field is part to a oneof or not.
virtual std::size_t hash()
Generate a field specific hash to be combined with the descriptor hash.
google::protobuf::FieldDescriptor::CppType wire_type() const
the C++ type used "on the wire". This is the type visible after pre_encode and before post_decode fun...