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