From 5afc0aae324e8ad31ff2122ae33d6963ebf75c1d Mon Sep 17 00:00:00 2001 From: dweatherford Date: Wed, 31 Oct 2007 06:03:54 +0000 Subject: [PATCH] [thrift] PHP generator: extension support Summary: Adds php code generation to take advantage of the php 'thrift_protocol' extension (currently for deserialization only) Requires you to swap your protocol for a TBinaryProtocolAccelerated (which just inherits TBinaryProtocol without actually adding any new functionality) and that you use a TFramedTransport or wrap your transport in a TBufferedTransport. TBinaryProtocolAccelerated is currently only in tfb/www/lib (or will be momentarily). Reviewed By: mcslee Test Plan: synapse_feed uses this in my sandbox, works fine Revert: svn git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665313 13f79535-47bb-0310-9956-ffa450edef68 --- compiler/cpp/src/generate/t_php_generator.cc | 276 +++++++++++-------- compiler/cpp/src/parse/t_base_type.h | 2 +- 2 files changed, 161 insertions(+), 117 deletions(-) diff --git a/compiler/cpp/src/generate/t_php_generator.cc b/compiler/cpp/src/generate/t_php_generator.cc index 0a680a56..62900a03 100644 --- a/compiler/cpp/src/generate/t_php_generator.cc +++ b/compiler/cpp/src/generate/t_php_generator.cc @@ -1167,131 +1167,153 @@ void t_php_generator::generate_deserialize_field(ofstream &out, generate_deserialize_struct(out, (t_struct*)type, name); - } else if (type->is_container()) { - generate_deserialize_container(out, type, name); - } else if (type->is_base_type() || type->is_enum()) { + } else { - if (binary_inline_) { - std::string itrans = (inclass ? "$this->input_" : "$input"); + if (type->is_container()) { + generate_deserialize_container(out, type, name); + } else if (type->is_base_type() || type->is_enum()) { - if (type->is_base_type()) { - t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); - switch (tbase) { - case t_base_type::TYPE_VOID: - throw "compiler error: cannot serialize void field in a struct: " + - name; - break; - case t_base_type::TYPE_STRING: - out << - indent() << "$len = unpack('N', " << itrans << "->readAll(4));" << endl << - indent() << "$len = $len[1];" << endl << - indent() << "if ($len > 0x7fffffff) {" << endl << - indent() << " $len = 0 - (($len - 1) ^ 0xffffffff);" << endl << - indent() << "}" << endl << - indent() << "$" << name << " = " << itrans << "->readAll($len);" << endl; - break; - case t_base_type::TYPE_BOOL: - out << - indent() << "$" << name << " = unpack('c', " << itrans << "->readAll(1));" << endl << - indent() << "$" << name << " = (bool)$" << name << "[1];" << endl; - break; - case t_base_type::TYPE_BYTE: - out << - indent() << "$" << name << " = unpack('c', " << itrans << "->readAll(1));" << endl << - indent() << "$" << name << " = $" << name << "[1];" << endl; - break; - case t_base_type::TYPE_I16: - out << - indent() << "$val = unpack('n', " << itrans << "->readAll(2));" << endl << - indent() << "$val = $val[1];" << endl << - indent() << "if ($val > 0x7fff) {" << endl << - indent() << " $val = 0 - (($val - 1) ^ 0xffff);" << endl << - indent() << "}" << endl << - indent() << "$" << name << " = $val;" << endl; - break; - case t_base_type::TYPE_I32: - out << - indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << endl << - indent() << "$val = $val[1];" << endl << - indent() << "if ($val > 0x7fffffff) {" << endl << - indent() << " $val = 0 - (($val - 1) ^ 0xffffffff);" << endl << - indent() << "}" << endl << - indent() << "$" << name << " = $val;" << endl; - break; - case t_base_type::TYPE_I64: - out << - indent() << "$arr = unpack('N2', " << itrans << "->readAll(8));" << endl << - indent() << "if ($arr[1] & 0x80000000) {" << endl << - indent() << " $arr[1] = $arr[1] ^ 0xFFFFFFFF;" << endl << - indent() << " $arr[2] = $arr[2] ^ 0xFFFFFFFF;" << endl << - indent() << " $" << name << " = 0 - $arr[1]*4294967296 - $arr[2] - 1;" << endl << - indent() << "} else {" << endl << - indent() << " $" << name << " = $arr[1]*4294967296 + $arr[2];" << endl << - indent() << "}" << endl; - break; - case t_base_type::TYPE_DOUBLE: - out << - indent() << "$arr = unpack('d', strrev(" << itrans << "->readAll(8)));" << endl << - indent() << "$" << name << " = $arr[1];" << endl; - break; - default: - throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase) + tfield->get_name(); + out << indent() << "if (is_a($input,'TBinaryProtocolAccelerated') && function_exists('thrift_protocol_binary_deserialize')) {" << endl; + indent_up(); + string ttype_name; + if (type->is_enum()) { + ttype_name = "I32"; + } else { + ttype_name = t_base_type::t_base_name(static_cast(type)->get_base()); + for (size_t _s = 0; _s < ttype_name.size(); ++_s) { + ttype_name[_s] = toupper(ttype_name[_s]); } - } else if (type->is_enum()) { - out << - indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << endl << - indent() << "$val = $val[1];" << endl << - indent() << "if ($val > 0x7fffffff) {" << endl << - indent() << " $val = 0 - (($val - 1) ^ 0xffffffff);" << endl << - indent() << "}" << endl << - indent() << "$" << name << " = $val;" << endl; } - } else { - indent(out) << - "$xfer += $input->"; - - if (type->is_base_type()) { - t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); - switch (tbase) { - case t_base_type::TYPE_VOID: - throw "compiler error: cannot serialize void field in a struct: " + - name; - break; - case t_base_type::TYPE_STRING: - out << "readString($" << name << ");"; - break; - case t_base_type::TYPE_BOOL: - out << "readBool($" << name << ");"; - break; - case t_base_type::TYPE_BYTE: - out << "readByte($" << name << ");"; - break; - case t_base_type::TYPE_I16: - out << "readI16($" << name << ");"; - break; - case t_base_type::TYPE_I32: + out << indent() << "$" << name << " = thrift_protocol_binary_deserialize(TType::" << ttype_name << ", $input);" << endl; + indent_down(); + out << indent() << "} else {" << endl; + indent_up(); + + + if (binary_inline_) { + std::string itrans = (inclass ? "$this->input_" : "$input"); + + if (type->is_base_type()) { + t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); + switch (tbase) { + case t_base_type::TYPE_VOID: + throw "compiler error: cannot serialize void field in a struct: " + + name; + break; + case t_base_type::TYPE_STRING: + out << + indent() << "$len = unpack('N', " << itrans << "->readAll(4));" << endl << + indent() << "$len = $len[1];" << endl << + indent() << "if ($len > 0x7fffffff) {" << endl << + indent() << " $len = 0 - (($len - 1) ^ 0xffffffff);" << endl << + indent() << "}" << endl << + indent() << "$" << name << " = " << itrans << "->readAll($len);" << endl; + break; + case t_base_type::TYPE_BOOL: + out << + indent() << "$" << name << " = unpack('c', " << itrans << "->readAll(1));" << endl << + indent() << "$" << name << " = (bool)$" << name << "[1];" << endl; + break; + case t_base_type::TYPE_BYTE: + out << + indent() << "$" << name << " = unpack('c', " << itrans << "->readAll(1));" << endl << + indent() << "$" << name << " = $" << name << "[1];" << endl; + break; + case t_base_type::TYPE_I16: + out << + indent() << "$val = unpack('n', " << itrans << "->readAll(2));" << endl << + indent() << "$val = $val[1];" << endl << + indent() << "if ($val > 0x7fff) {" << endl << + indent() << " $val = 0 - (($val - 1) ^ 0xffff);" << endl << + indent() << "}" << endl << + indent() << "$" << name << " = $val;" << endl; + break; + case t_base_type::TYPE_I32: + out << + indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << endl << + indent() << "$val = $val[1];" << endl << + indent() << "if ($val > 0x7fffffff) {" << endl << + indent() << " $val = 0 - (($val - 1) ^ 0xffffffff);" << endl << + indent() << "}" << endl << + indent() << "$" << name << " = $val;" << endl; + break; + case t_base_type::TYPE_I64: + out << + indent() << "$arr = unpack('N2', " << itrans << "->readAll(8));" << endl << + indent() << "if ($arr[1] & 0x80000000) {" << endl << + indent() << " $arr[1] = $arr[1] ^ 0xFFFFFFFF;" << endl << + indent() << " $arr[2] = $arr[2] ^ 0xFFFFFFFF;" << endl << + indent() << " $" << name << " = 0 - $arr[1]*4294967296 - $arr[2] - 1;" << endl << + indent() << "} else {" << endl << + indent() << " $" << name << " = $arr[1]*4294967296 + $arr[2];" << endl << + indent() << "}" << endl; + break; + case t_base_type::TYPE_DOUBLE: + out << + indent() << "$arr = unpack('d', strrev(" << itrans << "->readAll(8)));" << endl << + indent() << "$" << name << " = $arr[1];" << endl; + break; + default: + throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase) + tfield->get_name(); + } + } else if (type->is_enum()) { + out << + indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << endl << + indent() << "$val = $val[1];" << endl << + indent() << "if ($val > 0x7fffffff) {" << endl << + indent() << " $val = 0 - (($val - 1) ^ 0xffffffff);" << endl << + indent() << "}" << endl << + indent() << "$" << name << " = $val;" << endl; + } + } else { + + indent(out) << + "$xfer += $input->"; + + if (type->is_base_type()) { + t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); + switch (tbase) { + case t_base_type::TYPE_VOID: + throw "compiler error: cannot serialize void field in a struct: " + + name; + break; + case t_base_type::TYPE_STRING: + out << "readString($" << name << ");"; + break; + case t_base_type::TYPE_BOOL: + out << "readBool($" << name << ");"; + break; + case t_base_type::TYPE_BYTE: + out << "readByte($" << name << ");"; + break; + case t_base_type::TYPE_I16: + out << "readI16($" << name << ");"; + break; + case t_base_type::TYPE_I32: + out << "readI32($" << name << ");"; + break; + case t_base_type::TYPE_I64: + out << "readI64($" << name << ");"; + break; + case t_base_type::TYPE_DOUBLE: + out << "readDouble($" << name << ");"; + break; + default: + throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase); + } + } else if (type->is_enum()) { out << "readI32($" << name << ");"; - break; - case t_base_type::TYPE_I64: - out << "readI64($" << name << ");"; - break; - case t_base_type::TYPE_DOUBLE: - out << "readDouble($" << name << ");"; - break; - default: - throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase); } - } else if (type->is_enum()) { - out << "readI32($" << name << ");"; + out << endl; } - out << endl; + out << indent() << "}" << endl; + indent_down(); + } else { + printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", + tfield->get_name().c_str(), type->get_name().c_str()); } - - } else { - printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", - tfield->get_name().c_str(), type->get_name().c_str()); - } + } } /** @@ -1311,6 +1333,28 @@ void t_php_generator::generate_deserialize_struct(ofstream &out, void t_php_generator::generate_deserialize_container(ofstream &out, t_type* ttype, string prefix) { + out << indent() << "if (is_a($input, 'TBinaryProtocolAccelerated') && function_exists('thrift_protocol_binary_deserialize'))" << endl; + scope_up(out); + + string ttype_name; + t_type* tvaluetype = NULL; + if (ttype->is_map()) { + ttype_name = "MAP"; + tvaluetype = reinterpret_cast(ttype)->get_val_type(); + } else if (ttype->is_set()) { + ttype_name = "SET"; + tvaluetype = reinterpret_cast(ttype)->get_elem_type(); + } else if (ttype->is_list()) { + ttype_name = "LST"; + tvaluetype = reinterpret_cast(ttype)->get_elem_type(); + } + if (tvaluetype->is_struct()) { + out << indent() << "$" << prefix << " = thrift_protocol_binary_deserialize(TType::" << ttype_name << ", $input, '" << tvaluetype->get_name() << "');" << endl; + } else { + out << indent() << "$" << prefix << " = thrift_protocol_binary_deserialize(TType::" << ttype_name << ", $input);" << endl; + } + scope_down(out); + out << indent() << "else" << endl; scope_up(out); string size = tmp("_size"); diff --git a/compiler/cpp/src/parse/t_base_type.h b/compiler/cpp/src/parse/t_base_type.h index 1c69c2eb..929bf74f 100644 --- a/compiler/cpp/src/parse/t_base_type.h +++ b/compiler/cpp/src/parse/t_base_type.h @@ -102,7 +102,7 @@ class t_base_type : public t_type { case TYPE_BYTE : return "byte"; break; case TYPE_I16 : return "i16"; break; case TYPE_I32 : return "i32"; break; - case TYPE_I64 : return "164"; break; + case TYPE_I64 : return "i64"; break; case TYPE_DOUBLE : return "double"; break; default : return "(unknown)"; break; } -- 2.17.1