[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
diff --git a/compiler/cpp/src/generate/t_php_generator.cc b/compiler/cpp/src/generate/t_php_generator.cc
index 0a680a5..62900a0 100644
--- a/compiler/cpp/src/generate/t_php_generator.cc
+++ b/compiler/cpp/src/generate/t_php_generator.cc
@@ -1167,131 +1167,153 @@
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()) {
-
- 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 << ");";
- }
- out << endl;
- }
-
} else {
- printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n",
- tfield->get_name().c_str(), type->get_name().c_str());
- }
+
+ if (type->is_container()) {
+ generate_deserialize_container(out, type, name);
+ } else if (type->is_base_type() || type->is_enum()) {
+
+ 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<t_base_type*>(type)->get_base());
+ for (size_t _s = 0; _s < ttype_name.size(); ++_s) {
+ ttype_name[_s] = toupper(ttype_name[_s]);
+ }
+ }
+
+ 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 << ");";
+ }
+ 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());
+ }
+ }
}
/**
@@ -1311,6 +1333,28 @@
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<t_map*>(ttype)->get_val_type();
+ } else if (ttype->is_set()) {
+ ttype_name = "SET";
+ tvaluetype = reinterpret_cast<t_set*>(ttype)->get_elem_type();
+ } else if (ttype->is_list()) {
+ ttype_name = "LST";
+ tvaluetype = reinterpret_cast<t_list*>(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 1c69c2e..929bf74 100644
--- a/compiler/cpp/src/parse/t_base_type.h
+++ b/compiler/cpp/src/parse/t_base_type.h
@@ -102,7 +102,7 @@
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;
}