22 #include "dccl/codec.h"
23 #include "field_codec_default_message.h"
31 void dccl::v2::DefaultMessageCodec::any_encode(Bitset* bits,
const boost::any& wire_value)
33 if(wire_value.empty())
34 *bits = Bitset(min_size());
36 *bits = traverse_const_message<Encoder, Bitset>(wire_value);
41 unsigned dccl::v2::DefaultMessageCodec::any_size(
const boost::any& wire_value)
43 if(wire_value.empty())
46 return traverse_const_message<Size, unsigned>(wire_value);
50 void dccl::v2::DefaultMessageCodec::any_decode(Bitset* bits, boost::any* wire_value)
57 const google::protobuf::Descriptor* desc = msg->GetDescriptor();
58 const google::protobuf::Reflection* refl = msg->GetReflection();
60 for(
int i = 0, n = desc->field_count(); i < n; ++i)
63 const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
65 if(!check_field(field_desc))
69 boost::shared_ptr<FieldCodecBase> codec = find(field_desc);
70 boost::shared_ptr<internal::FromProtoCppTypeBase> helper =
71 internal::TypeHelper::find(field_desc);
73 if(field_desc->is_repeated())
75 std::vector<boost::any> wire_values;
76 if(field_desc->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
78 for(
unsigned j = 0, m = field_desc->options().GetExtension(dccl::field).max_repeat(); j < m; ++j)
79 wire_values.push_back(refl->AddMessage(msg, field_desc));
81 codec->field_decode_repeated(bits, &wire_values, field_desc);
83 for(
int j = 0, m = wire_values.size(); j < m; ++j)
85 if(wire_values[j].empty()) refl->RemoveLast(msg, field_desc);
91 codec->field_decode_repeated(bits, &wire_values, field_desc);
92 for(
int j = 0, m = wire_values.size(); j < m; ++j)
93 helper->add_value(field_desc, msg, wire_values[j]);
98 boost::any wire_value;
99 if(field_desc->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
102 wire_value = refl->MutableMessage(msg, field_desc);
103 codec->field_decode(bits, &wire_value, field_desc);
104 if(wire_value.empty()) refl->ClearField(msg, field_desc);
109 codec->field_decode(bits, &wire_value, field_desc);
110 helper->set_value(field_desc, msg, wire_value);
115 std::vector< const google::protobuf::FieldDescriptor* > set_fields;
116 refl->ListFields(*msg, &set_fields);
117 if(set_fields.empty() && this_field()) *wire_value = boost::any();
118 else *wire_value = msg;
120 catch(boost::bad_any_cast& e)
122 throw(Exception(
"Bad type given to traverse mutable, expecting google::protobuf::Message*, got " + std::string(wire_value->type().name())));
128 unsigned dccl::v2::DefaultMessageCodec::max_size()
131 traverse_descriptor<MaxSize>(&u);
135 unsigned dccl::v2::DefaultMessageCodec::min_size()
138 traverse_descriptor<MinSize>(&u);
143 void dccl::v2::DefaultMessageCodec::validate()
146 traverse_descriptor<Validate>(&b);
149 std::string dccl::v2::DefaultMessageCodec::info()
151 std::stringstream ss;
152 traverse_descriptor<Info>(&ss);
156 bool dccl::v2::DefaultMessageCodec::check_field(
const google::protobuf::FieldDescriptor* field)
165 if(dccl_field_options.omit())
169 else if(internal::MessageStack::current_part() == UNKNOWN)
171 if(field->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE &&
172 find(field)->name() == Codec::default_codec_name())
174 else if((part() == HEAD && !dccl_field_options.in_head())
175 || (part() == BODY && dccl_field_options.in_head()))
180 else if(internal::MessageStack::current_part() != part())