From: Mark Slee Date: Wed, 30 Jan 2008 23:23:15 +0000 (+0000) Subject: Improve Thrift map deserialization code X-Git-Tag: 0.2.0~1024 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=61959f5d9deb0e3535ee727f0c3ca694f3b40173;p=common%2Fthrift.git Improve Thrift map deserialization code Summary: Instead of copy-constructing map values into the map, alter the code such that we insert default-constructed elements into the map and then deserialize them by reference. Reviewed By: hzhao Test Plan: Ran the test in test/cpp which include serialization and deserialization of nested maps. git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665448 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc index 1b560bc8..2518509e 100644 --- a/compiler/cpp/src/generate/t_cpp_generator.cc +++ b/compiler/cpp/src/generate/t_cpp_generator.cc @@ -70,7 +70,7 @@ void t_cpp_generator::init_generator() { // Include the types file f_types_impl_ << - "#include \"" << get_include_prefix(*get_program()) << program_name_ << + "#include \"" << get_include_prefix(*get_program()) << program_name_ << "_types.h\"" << endl << endl; @@ -185,14 +185,14 @@ void t_cpp_generator::generate_consts(std::vector consts) { "#ifndef " << program_name_ << "_CONSTANTS_H" << endl << "#define " << program_name_ << "_CONSTANTS_H" << endl << endl << - "#include \"" << get_include_prefix(*get_program()) << program_name_ << + "#include \"" << get_include_prefix(*get_program()) << program_name_ << "_types.h\"" << endl << endl << ns_open_ << endl << endl; f_consts_impl << - "#include \"" << get_include_prefix(*get_program()) << program_name_ << + "#include \"" << get_include_prefix(*get_program()) << program_name_ << "_constants.h\"" << endl << endl << ns_open_ << endl << @@ -2308,14 +2308,14 @@ void t_cpp_generator::generate_deserialize_map_element(ofstream& out, t_field fval(tmap->get_val_type(), val); out << - indent() << declare_field(&fkey) << endl << - indent() << declare_field(&fval) << endl; + indent() << declare_field(&fkey) << endl; generate_deserialize_field(out, &fkey); - generate_deserialize_field(out, &fval); - indent(out) << - prefix << ".insert(std::make_pair(" << key << ", " << val << "));" << endl; + declare_field(&fval, false, false, false, true) << " = " << + prefix << "[" << key << "];" << endl; + + generate_deserialize_field(out, &fval); } void t_cpp_generator::generate_deserialize_set_element(ofstream& out, @@ -2701,7 +2701,7 @@ string t_cpp_generator::base_type_name(t_base_type::t_base tbase) { * @param ttype The type * @return Field declaration, i.e. int x = 0; */ -string t_cpp_generator::declare_field(t_field* tfield, bool init, bool pointer, bool constant) { +string t_cpp_generator::declare_field(t_field* tfield, bool init, bool pointer, bool constant, bool reference) { // TODO(mcslee): do we ever need to initialize the field? string result = ""; if (constant) { @@ -2711,6 +2711,9 @@ string t_cpp_generator::declare_field(t_field* tfield, bool init, bool pointer, if (pointer) { result += "*"; } + if (reference) { + result += "&"; + } result += " " + tfield->get_name(); if (init) { t_type* type = get_true_type(tfield->get_type()); @@ -2742,7 +2745,10 @@ string t_cpp_generator::declare_field(t_field* tfield, bool init, bool pointer, result += " = (" + type_name(type) + ")0"; } } - return result + ";"; + if (!reference) { + result += ";"; + } + return result; } /** @@ -2887,6 +2893,6 @@ string t_cpp_generator::get_include_prefix(const t_program& program) const { if ((last_slash = include_prefix.rfind("/")) != string::npos) { return include_prefix.substr(0, last_slash) + "/" + out_dir_base_ + "/"; } - + return ""; } diff --git a/compiler/cpp/src/generate/t_cpp_generator.h b/compiler/cpp/src/generate/t_cpp_generator.h index 4bc9783c..ba19c1cf 100644 --- a/compiler/cpp/src/generate/t_cpp_generator.h +++ b/compiler/cpp/src/generate/t_cpp_generator.h @@ -86,18 +86,18 @@ class t_cpp_generator : public t_oop_generator { */ void generate_deserialize_field (std::ofstream& out, - t_field* tfield, + t_field* tfield, std::string prefix="", std::string suffix=""); - + void generate_deserialize_struct (std::ofstream& out, t_struct* tstruct, std::string prefix=""); - + void generate_deserialize_container (std::ofstream& out, t_type* ttype, std::string prefix=""); - + void generate_deserialize_set_element (std::ofstream& out, t_set* tset, std::string prefix=""); @@ -144,7 +144,7 @@ class t_cpp_generator : public t_oop_generator { std::string namespace_close(std::string ns); std::string type_name(t_type* ttype, bool in_typedef=false, bool arg=false); std::string base_type_name(t_base_type::t_base tbase); - std::string declare_field(t_field* tfield, bool init=false, bool pointer=false, bool constant=false); + std::string declare_field(t_field* tfield, bool init=false, bool pointer=false, bool constant=false, bool reference=false); std::string function_signature(t_function* tfunction, std::string prefix=""); std::string argument_list(t_struct* tstruct); std::string type_to_enum(t_type* ttype); @@ -158,7 +158,7 @@ class t_cpp_generator : public t_oop_generator { ttype = get_true_type(ttype); return - ttype->is_container() || + ttype->is_container() || ttype->is_struct() || ttype->is_xception() || (ttype->is_base_type() && (((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING));