DCCL v4
Loading...
Searching...
No Matches
field_codec_default_message.h
1// Copyright 2014-2023:
2// GobySoft, LLC (2013-)
3// Massachusetts Institute of Technology (2007-2014)
4// Community contributors (see AUTHORS file)
5// File authors:
6// Toby Schneider <toby@gobysoft.org>
7// Chris Murphy <cmurphy@aphysci.com>
8//
9//
10// This file is part of the Dynamic Compact Control Language Library
11// ("DCCL").
12//
13// DCCL is free software: you can redistribute it and/or modify
14// it under the terms of the GNU Lesser General Public License as published by
15// the Free Software Foundation, either version 2.1 of the License, or
16// (at your option) any later version.
17//
18// DCCL is distributed in the hope that it will be useful,
19// but WITHOUT ANY WARRANTY; without even the implied warranty of
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21// GNU Lesser General Public License for more details.
22//
23// You should have received a copy of the GNU Lesser General Public License
24// along with DCCL. If not, see <http://www.gnu.org/licenses/>.
25#ifndef DCCLFIELDCODECDEFAULTMESSAGE20110510H
26#define DCCLFIELDCODECDEFAULTMESSAGE20110510H
27
28#include "../field_codec.h"
29#include "../field_codec_manager.h"
30
31#include "dccl/option_extensions.pb.h"
32
33namespace dccl
34{
35namespace v2
36{
39{
40 private:
41 void any_encode(Bitset* bits, const dccl::any& wire_value) override;
42 void any_decode(Bitset* bits, dccl::any* wire_value) override;
43 unsigned max_size() override;
44 unsigned min_size() override;
45 unsigned any_size(const dccl::any& wire_value) override;
46
47 std::shared_ptr<FieldCodecBase> find(const google::protobuf::FieldDescriptor* field_desc)
48 {
49 return manager().find(field_desc, this->codec_version(), has_codec_group(), codec_group());
50 }
51
52 void validate() override;
53 std::string info() override;
54 std::size_t hash() override;
55 bool check_field(const google::protobuf::FieldDescriptor* field);
56
57 struct Size
58 {
59 static void repeated(std::shared_ptr<FieldCodecBase> codec, unsigned* return_value,
60 const std::vector<dccl::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(std::shared_ptr<FieldCodecBase> codec, unsigned* return_value,
67 const dccl::any& field_value,
68 const google::protobuf::FieldDescriptor* field_desc)
69 {
70 codec->field_size(return_value, field_value, field_desc);
71 }
72 };
73
74 struct Encoder
75 {
76 static void repeated(std::shared_ptr<FieldCodecBase> codec, Bitset* return_value,
77 const std::vector<dccl::any>& field_values,
78 const google::protobuf::FieldDescriptor* field_desc)
79 {
80 codec->field_encode_repeated(return_value, field_values, field_desc);
81 }
82
83 static void single(std::shared_ptr<FieldCodecBase> codec, Bitset* return_value,
84 const dccl::any& field_value,
85 const google::protobuf::FieldDescriptor* field_desc)
86 {
87 codec->field_encode(return_value, field_value, field_desc);
88 }
89 };
90
91 struct MaxSize
92 {
93 static void field(std::shared_ptr<FieldCodecBase> codec, unsigned* return_value,
94 const google::protobuf::FieldDescriptor* field_desc)
95 {
96 codec->field_max_size(return_value, field_desc);
97 }
98 };
99
100 struct MinSize
101 {
102 static void field(std::shared_ptr<FieldCodecBase> codec, unsigned* return_value,
103 const google::protobuf::FieldDescriptor* field_desc)
104 {
105 codec->field_min_size(return_value, field_desc);
106 }
107 };
108
109 struct Validate
110 {
111 static void field(std::shared_ptr<FieldCodecBase> codec, bool* return_value,
112 const google::protobuf::FieldDescriptor* field_desc)
113 {
114 codec->field_validate(return_value, field_desc);
115 }
116 };
117
118 struct Info
119 {
120 static void field(std::shared_ptr<FieldCodecBase> codec, std::stringstream* return_value,
121 const google::protobuf::FieldDescriptor* field_desc)
122 {
123 codec->field_info(return_value, field_desc);
124 }
125 };
126
127 struct Hash
128 {
129 static void field(std::shared_ptr<FieldCodecBase> codec, std::size_t* return_value,
130 const google::protobuf::FieldDescriptor* field_desc)
131 {
132 codec->field_hash(return_value, field_desc);
133 }
134 };
135
136 template <typename Action, typename ReturnType>
137 void traverse_descriptor(ReturnType* return_value)
138 {
139 const google::protobuf::Descriptor* desc = FieldCodecBase::this_descriptor();
140 for (int i = 0, n = desc->field_count(); i < n; ++i)
141 {
142 const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
143
144 if (!check_field(field_desc))
145 continue;
146
147 Action::field(find(field_desc), return_value, field_desc);
148 }
149 }
150
151 template <typename Action, typename ReturnType>
152 ReturnType traverse_const_message(const dccl::any& wire_value)
153 {
154 try
155 {
156 ReturnType return_value = ReturnType();
157
158 const auto* msg = dccl::any_cast<const google::protobuf::Message*>(wire_value);
159 const google::protobuf::Descriptor* desc = msg->GetDescriptor();
160 const google::protobuf::Reflection* refl = msg->GetReflection();
161 for (int i = 0, n = desc->field_count(); i < n; ++i)
162 {
163 const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
164
165 if (!check_field(field_desc))
166 continue;
167
168 std::shared_ptr<FieldCodecBase> codec = find(field_desc);
169 std::shared_ptr<internal::FromProtoCppTypeBase> helper =
170 manager().type_helper().find(field_desc);
171
172 if (field_desc->is_repeated())
173 {
174 std::vector<dccl::any> field_values;
175 for (int j = 0, m = refl->FieldSize(*msg, field_desc); j < m; ++j)
176 field_values.push_back(helper->get_repeated_value(field_desc, *msg, j));
177
178 Action::repeated(codec, &return_value, field_values, field_desc);
179 }
180 else
181 {
182 Action::single(codec, &return_value, helper->get_value(field_desc, *msg),
183 field_desc);
184 }
185 }
186 return return_value;
187 }
188 catch (dccl::bad_any_cast& e)
189 {
190 throw(Exception("Bad type given to traverse const, expecting const "
191 "google::protobuf::Message*, got " +
192 std::string(wire_value.type().name())));
193 }
194 }
195};
196
197} // namespace v2
198} // namespace dccl
199
200//encode, size, etc.
201
202#endif
A variable size container of bits (subclassed from std::deque<bool>) with an optional hierarchy....
Definition bitset.h:43
Exception class for DCCL.
Definition exception.h:47
Provides a base class for defining DCCL field encoders / decoders. Most users who wish to define cust...
Definition field_codec.h:54
const google::protobuf::Descriptor * this_descriptor() const
Returns the Descriptor (message schema meta-data) for the immediate parent Message.
std::shared_ptr< FieldCodecBase > find(const google::protobuf::FieldDescriptor *field, int codec_version, bool has_codec_group, const std::string &codec_group) const
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...
Dynamic Compact Control Language namespace.
Definition any.h:47