DCCL v3
field_codec_default_message.h
1 // Copyright 2009-2017 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (for 2013-)
3 // Massachusetts Institute of Technology (for 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 #ifndef DCCLFIELDCODECDEFAULTMESSAGE20110510H
23 #define DCCLFIELDCODECDEFAULTMESSAGE20110510H
24 
25 #include "dccl/field_codec.h"
26 #include "dccl/field_codec_manager.h"
27 
28 #include "dccl/option_extensions.pb.h"
29 
30 namespace dccl
31 {
32  namespace v2
33  {
36  {
37  private:
38 
39  void any_encode(Bitset* bits, const boost::any& wire_value);
40  void any_decode(Bitset* bits, boost::any* wire_value);
41  unsigned max_size();
42  unsigned min_size();
43  unsigned any_size(const boost::any& wire_value);
44 
45 
46  boost::shared_ptr<FieldCodecBase> find(const google::protobuf::FieldDescriptor* field_desc)
47  {
48  return FieldCodecManager::find(field_desc, has_codec_group(), codec_group());
49  }
50 
51 
52  void validate();
53  std::string info();
54  bool check_field(const google::protobuf::FieldDescriptor* field);
55 
56  struct Size
57  {
58  static void repeated(boost::shared_ptr<FieldCodecBase> codec,
59  unsigned* return_value,
60  const std::vector<boost::any>& field_values,
61  const google::protobuf::FieldDescriptor* field_desc)
62  {
63  codec->field_size_repeated(return_value, field_values, field_desc);
64  }
65 
66  static void single(boost::shared_ptr<FieldCodecBase> codec,
67  unsigned* return_value,
68  const boost::any& field_value,
69  const google::protobuf::FieldDescriptor* field_desc)
70  {
71  codec->field_size(return_value, field_value, field_desc);
72  }
73 
74  };
75 
76  struct Encoder
77  {
78  static void repeated(boost::shared_ptr<FieldCodecBase> codec,
79  Bitset* return_value,
80  const std::vector<boost::any>& field_values,
81  const google::protobuf::FieldDescriptor* field_desc)
82  {
83  codec->field_encode_repeated(return_value, field_values, field_desc);
84  }
85 
86  static void single(boost::shared_ptr<FieldCodecBase> codec,
87  Bitset* return_value,
88  const boost::any& field_value,
89  const google::protobuf::FieldDescriptor* field_desc)
90  {
91  codec->field_encode(return_value, field_value, field_desc);
92  }
93  };
94 
95  struct MaxSize
96  {
97  static void field(boost::shared_ptr<FieldCodecBase> codec,
98  unsigned* return_value,
99  const google::protobuf::FieldDescriptor* field_desc)
100  {
101  codec->field_max_size(return_value, field_desc);
102  }
103  };
104 
105  struct MinSize
106  {
107  static void field(boost::shared_ptr<FieldCodecBase> codec,
108  unsigned* return_value,
109  const google::protobuf::FieldDescriptor* field_desc)
110  {
111  codec->field_min_size(return_value, field_desc);
112  }
113  };
114 
115 
116  struct Validate
117  {
118  static void field(boost::shared_ptr<FieldCodecBase> codec,
119  bool* return_value,
120  const google::protobuf::FieldDescriptor* field_desc)
121  {
122  codec->field_validate(return_value, field_desc);
123  }
124  };
125 
126  struct Info
127  {
128  static void field(boost::shared_ptr<FieldCodecBase> codec,
129  std::stringstream* return_value,
130  const google::protobuf::FieldDescriptor* field_desc)
131  {
132  codec->field_info(return_value, field_desc);
133  }
134  };
135 
136 
137  template<typename Action, typename ReturnType>
138  void traverse_descriptor(ReturnType* return_value)
139  {
140  const google::protobuf::Descriptor* desc =
142  for(int i = 0, n = desc->field_count(); i < n; ++i)
143  {
144  const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
145 
146  if(!check_field(field_desc))
147  continue;
148 
149  Action::field(find(field_desc), return_value, field_desc);
150  }
151  }
152 
153 
154  template<typename Action, typename ReturnType>
155  ReturnType traverse_const_message(const boost::any& wire_value)
156  {
157  try
158  {
159  ReturnType return_value = ReturnType();
160 
161  const google::protobuf::Message* msg = boost::any_cast<const google::protobuf::Message*>(wire_value);
162  const google::protobuf::Descriptor* desc = msg->GetDescriptor();
163  const google::protobuf::Reflection* refl = msg->GetReflection();
164  for(int i = 0, n = desc->field_count(); i < n; ++i)
165  {
166  const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
167 
168  if(!check_field(field_desc))
169  continue;
170 
171  boost::shared_ptr<FieldCodecBase> codec = find(field_desc);
172  boost::shared_ptr<internal::FromProtoCppTypeBase> helper =
173  internal::TypeHelper::find(field_desc);
174 
175 
176  if(field_desc->is_repeated())
177  {
178  std::vector<boost::any> field_values;
179  for(int j = 0, m = refl->FieldSize(*msg, field_desc); j < m; ++j)
180  field_values.push_back(helper->get_repeated_value(field_desc, *msg, j));
181 
182  Action::repeated(codec, &return_value, field_values, field_desc);
183  }
184  else
185  {
186  Action::single(codec, &return_value, helper->get_value(field_desc, *msg), field_desc);
187  }
188  }
189  return return_value;
190  }
191  catch(boost::bad_any_cast& e)
192  {
193  throw(Exception("Bad type given to traverse const, expecting const google::protobuf::Message*, got " + std::string(wire_value.type().name())));
194  }
195 
196  }
197  };
198 
199  }
200 }
201 
202 //encode, size, etc.
203 
204 
205 
206 
207 #endif
dccl::FieldCodecBase
Provides a base class for defining DCCL field encoders / decoders. Most users who wish to define cust...
Definition: field_codec.h:47
dccl
Dynamic Compact Control Language namespace.
Definition: gen_units_class_plugin.h:49
dccl::Exception
Exception class for DCCL.
Definition: exception.h:31
dccl::FieldCodecBase::this_descriptor
static const google::protobuf::Descriptor * this_descriptor()
Returns the Descriptor (message schema meta-data) for the immediate parent Message.
Definition: field_codec.h:91
dccl::Bitset
A variable size container of bits (subclassed from std::deque<bool>) with an optional hierarchy....
Definition: bitset.h:38
dccl::v2::DefaultMessageCodec
Provides the default codec for encoding a base Google Protobuf message or an embedded message by call...
Definition: field_codec_default_message.h:35
dccl::FieldCodecManager::find
static boost::shared_ptr< FieldCodecBase > find(const google::protobuf::FieldDescriptor *field, bool has_codec_group, const std::string &codec_group)
Find the codec for a given field. For embedded messages, prefers (dccl.field).codec (inside field) ov...
Definition: field_codec_manager.h:121
Message