22 #include "dccl/codec.h"
23 #include "dccl/codecs3/field_codec_default_message.h"
31 void dccl::v3::DefaultMessageCodec::any_encode(Bitset* bits,
const boost::any& wire_value)
33 if(wire_value.empty())
35 *bits = Bitset(min_size());
39 *bits = traverse_const_message<Encoder, Bitset>(wire_value);
42 bits->push_front(
true);
47 unsigned dccl::v3::DefaultMessageCodec::any_size(
const boost::any& wire_value)
49 if(wire_value.empty())
55 unsigned size = traverse_const_message<Size, unsigned>(wire_value);
58 const unsigned presence_bit = 1;
67 void dccl::v3::DefaultMessageCodec::any_decode(Bitset* bits, boost::any* wire_value)
78 *wire_value = boost::any();
87 const google::protobuf::Descriptor* desc = msg->GetDescriptor();
88 const google::protobuf::Reflection* refl = msg->GetReflection();
90 for(
int i = 0, n = desc->field_count(); i < n; ++i)
93 const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
95 if(!check_field(field_desc))
99 boost::shared_ptr<FieldCodecBase> codec = find(field_desc);
100 boost::shared_ptr<internal::FromProtoCppTypeBase> helper =
101 internal::TypeHelper::find(field_desc);
103 if(field_desc->is_repeated())
105 std::vector<boost::any> field_values;
106 if(field_desc->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
108 unsigned max_repeat = field_desc->options().GetExtension(dccl::field).max_repeat();
109 for(
unsigned j = 0, m = max_repeat; j < m; ++j)
110 field_values.push_back(refl->AddMessage(msg, field_desc));
112 codec->field_decode_repeated(bits, &field_values, field_desc);
115 for(
int j = field_values.size(), m = max_repeat; j < m; ++j)
117 refl->RemoveLast(msg, field_desc);
123 codec->field_decode_repeated(bits, &field_values, field_desc);
124 for(
int j = 0, m = field_values.size(); j < m; ++j)
125 helper->add_value(field_desc, msg, field_values[j]);
130 boost::any field_value;
131 if(field_desc->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
134 field_value = refl->MutableMessage(msg, field_desc);
135 codec->field_decode(bits, &field_value, field_desc);
136 if(field_value.empty()) refl->ClearField(msg, field_desc);
141 codec->field_decode(bits, &field_value, field_desc);
142 helper->set_value(field_desc, msg, field_value);
147 std::vector< const google::protobuf::FieldDescriptor* > set_fields;
148 refl->ListFields(*msg, &set_fields);
151 catch(boost::bad_any_cast& e)
153 throw(Exception(
"Bad type given to traverse mutable, expecting google::protobuf::Message*, got " + std::string(wire_value->type().name())));
159 unsigned dccl::v3::DefaultMessageCodec::max_size()
162 traverse_descriptor<MaxSize>(&u);
166 const unsigned presence_bit = 1;
173 unsigned dccl::v3::DefaultMessageCodec::min_size()
177 const unsigned presence_bit = 1;
183 traverse_descriptor<MinSize>(&u);
189 void dccl::v3::DefaultMessageCodec::validate()
193 const google::protobuf::Descriptor* desc =
196 if(desc->oneof_decl_count() != 0)
197 throw(Exception(
"DCCL Codec Version 3 does not support 'oneof' declarations"));
199 traverse_descriptor<Validate>(&b);
202 std::string dccl::v3::DefaultMessageCodec::info()
204 std::stringstream ss;
205 traverse_descriptor<Info>(&ss);
209 bool dccl::v3::DefaultMessageCodec::check_field(
const google::protobuf::FieldDescriptor* field)
218 if(dccl_field_options.omit())
222 else if(internal::MessageStack::current_part() == UNKNOWN)
224 if((part() == HEAD && !dccl_field_options.in_head())
225 || (part() == BODY && dccl_field_options.in_head()))
230 else if(internal::MessageStack::current_part() != part())