From c98d050d652d08d8ce99bed5487cd7544b2b25cc Mon Sep 17 00:00:00 2001 From: Mark Slee Date: Wed, 6 Sep 2006 02:42:25 +0000 Subject: [PATCH] Thrift: Added support for double type across all languages Summary: Just for completeness cause I'm crazy. Let's never use these! Notes: Also made thrift grammar support # style comments, so you can do this at the top of your files #!/usr/local/bin/thrift --cpp /** * This is a thrift def file youc an invoke directly and gen code! */ blah git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664789 13f79535-47bb-0310-9956-ffa450edef68 --- compiler/cpp/src/generate/t_cpp_generator.cc | 13 +++++++ compiler/cpp/src/generate/t_java_generator.cc | 13 +++++++ compiler/cpp/src/generate/t_php_generator.cc | 30 +++++++++++++--- compiler/cpp/src/generate/t_py_generator.cc | 13 +++++++ compiler/cpp/src/parse/t_base_type.h | 7 ++-- compiler/cpp/src/parse/t_program.h | 4 +++ compiler/cpp/src/thrift.l | 2 ++ compiler/cpp/src/thrift.y | 5 +++ lib/cpp/src/protocol/TBinaryProtocol.cc | 34 +++++++++++++++++++ lib/cpp/src/protocol/TBinaryProtocol.h | 7 ++++ lib/cpp/src/protocol/TProtocol.h | 14 +++++++- lib/java/src/protocol/TBinaryProtocol.java | 8 +++++ lib/java/src/protocol/TProtocol.java | 6 ++++ lib/java/src/protocol/TProtocolUtil.java | 4 +++ lib/java/src/protocol/TType.java | 1 + lib/php/src/protocol/TBinaryProtocol.php | 13 +++++++ lib/php/src/protocol/TProtocol.php | 6 ++++ lib/php/src/protocol/TType.php | 3 +- lib/py/src/protocol/TBinaryProtocol.py | 9 +++++ lib/py/src/protocol/TProtocol.py | 11 +++++- lib/py/src/server/TServer.py | 5 ++- lib/py/src/transport/TSocket.py | 2 +- test/ThriftTest.thrift | 1 + test/cpp/src/TestClient.cc | 7 ++++ test/cpp/src/TestServer.cc | 5 +++ test/java/src/TestClient.java | 7 ++++ test/java/src/TestServer.java | 5 +++ test/php/TestClient.php | 7 ++++ test/py/TestClient.py | 6 ++++ test/py/TestServer.py | 29 +++++++++++++--- 30 files changed, 262 insertions(+), 15 deletions(-) diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc index b43ee16b..56980e42 100644 --- a/compiler/cpp/src/generate/t_cpp_generator.cc +++ b/compiler/cpp/src/generate/t_cpp_generator.cc @@ -1125,6 +1125,9 @@ void t_cpp_generator::generate_deserialize_field(ofstream& out, case t_base_type::TYPE_I64: out << "readI64(itrans, " << name << ");"; break; + case t_base_type::TYPE_DOUBLE: + out << "readDouble(itrans, " << name << ");"; + break; default: throw "compiler error: no C++ reader for base type " + tbase + name; } @@ -1331,6 +1334,9 @@ void t_cpp_generator::generate_serialize_field(ofstream& out, case t_base_type::TYPE_I64: out << "writeI64(otrans, " << name << ");"; break; + case t_base_type::TYPE_DOUBLE: + out << "writeDouble(otrans, " << name << ");"; + break; default: throw "compiler error: no C++ writer for base type " + tbase + name; } @@ -1540,6 +1546,8 @@ string t_cpp_generator::base_type_name(t_base_type::t_base tbase) { return "int32_t"; case t_base_type::TYPE_I64: return "int64_t"; + case t_base_type::TYPE_DOUBLE: + return "double"; default: throw "compiler error: no C++ base type name for base type " + tbase; } @@ -1576,6 +1584,9 @@ string t_cpp_generator::declare_field(t_field* tfield, bool init) { case t_base_type::TYPE_I64: result += " = 0"; break; + case t_base_type::TYPE_DOUBLE: + result += " = (double)0"; + break; default: throw "compiler error: no C++ initializer for base type " + tbase; } @@ -1645,6 +1656,8 @@ string t_cpp_generator::type_to_enum(t_type* type) { return "facebook::thrift::protocol::T_I32"; case t_base_type::TYPE_I64: return "facebook::thrift::protocol::T_I64"; + case t_base_type::TYPE_DOUBLE: + return "facebook::thrift::protocol::T_DOUBLE"; } } else if (type->is_enum()) { return "facebook::thrift::protocol::T_I32"; diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc index 390c563b..6d12dcec 100644 --- a/compiler/cpp/src/generate/t_java_generator.cc +++ b/compiler/cpp/src/generate/t_java_generator.cc @@ -867,6 +867,9 @@ void t_java_generator::generate_deserialize_field(ofstream& out, case t_base_type::TYPE_I64: out << "readI64(_itrans);"; break; + case t_base_type::TYPE_DOUBLE: + out << "readDouble(_itrans);"; + break; default: throw "compiler error: no Java name for base type " + tbase; } @@ -1068,6 +1071,9 @@ void t_java_generator::generate_serialize_field(ofstream& out, case t_base_type::TYPE_I64: out << "writeI64(_otrans, " << name << ");"; break; + case t_base_type::TYPE_DOUBLE: + out << "writeDouble(_otrans, " << name << ");"; + break; default: throw "compiler error: no Java name for base type " + tbase; } @@ -1256,6 +1262,8 @@ string t_java_generator::base_type_name(t_base_type::t_base tbase, return (in_container ? "Integer" : "int"); case t_base_type::TYPE_I64: return (in_container ? "Long" : "long"); + case t_base_type::TYPE_DOUBLE: + return (in_container ? "Double" : "double"); default: throw "compiler error: no C++ name for base type " + tbase; } @@ -1292,6 +1300,9 @@ string t_java_generator::declare_field(t_field* tfield, bool init) { case t_base_type::TYPE_I64: result += " = 0"; break; + case t_base_type::TYPE_DOUBLE: + result += " = (double)0"; + break; } } else if (ttype->is_enum()) { @@ -1372,6 +1383,8 @@ string t_java_generator::type_to_enum(t_type* type) { return "TType.I32"; case t_base_type::TYPE_I64: return "TType.I64"; + case t_base_type::TYPE_DOUBLE: + return "TType.DOUBLE"; } } else if (type->is_enum()) { return "TType.I32"; diff --git a/compiler/cpp/src/generate/t_php_generator.cc b/compiler/cpp/src/generate/t_php_generator.cc index 8b05f706..6ac0b334 100644 --- a/compiler/cpp/src/generate/t_php_generator.cc +++ b/compiler/cpp/src/generate/t_php_generator.cc @@ -622,7 +622,7 @@ void t_php_generator::generate_service_client(t_service* tservice) { "return;" << endl; } else { f_service_ << - indent() << "throw Exception(\"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl; + indent() << "throw new Exception(\"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl; } } @@ -722,6 +722,11 @@ void t_php_generator::generate_deserialize_field(ofstream &out, 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 " + tbase + tfield->get_name(); } @@ -764,6 +769,9 @@ void t_php_generator::generate_deserialize_field(ofstream &out, case t_base_type::TYPE_I64: out << "readI64($itrans, $" << name << ");"; break; + case t_base_type::TYPE_DOUBLE: + out << "readDouble($itrans, $" << name << ");"; + break; default: throw "compiler error: no PHP name for base type " + tbase; } @@ -808,9 +816,9 @@ void t_php_generator::generate_deserialize_container(ofstream &out, t_field fvtype(g_program->get_byte_type(), vtype); t_field fetype(g_program->get_byte_type(), etype); - indent(out) << - prefix << " = array();" << endl << - "$" << size << " = 0;" << endl; + out << + indent() << "$" << prefix << " = array();" << endl << + indent() << "$" << size << " = 0;" << endl; // Declare variables, read header if (ttype->is_map()) { @@ -1000,6 +1008,10 @@ void t_php_generator::generate_serialize_field(ofstream &out, out << indent() << "$_output .= pack('N2', $" << name << " >> 32, $" << name << " & 0xFFFFFFFF);" << endl; break; + case t_base_type::TYPE_DOUBLE: + out << + indent() << "$_output .= strrev(pack('d', $" << name << "));" << endl; + break; default: throw "compiler error: no PHP name for base type " + tbase; } @@ -1037,6 +1049,9 @@ void t_php_generator::generate_serialize_field(ofstream &out, case t_base_type::TYPE_I64: out << "writeI64($otrans, $" << name << ");"; break; + case t_base_type::TYPE_DOUBLE: + out << "writeDouble($otrans, $" << name << ");"; + break; default: throw "compiler error: no PHP name for base type " + tbase; } @@ -1247,6 +1262,8 @@ string t_php_generator::base_type_name(t_base_type::t_base tbase) { return "Int32"; case t_base_type::TYPE_I64: return "Int64"; + case t_base_type::TYPE_DOUBLE: + return "Double"; default: throw "compiler error: no PHP name for base type " + tbase; } @@ -1281,6 +1298,9 @@ string t_php_generator::declare_field(t_field* tfield, bool init, bool obj) { case t_base_type::TYPE_I64: result += " = 0"; break; + case t_base_type::TYPE_DOUBLE: + result += " = 0.0"; + break; default: throw "compiler error: no PHP initializer for base type " + tbase; } @@ -1357,6 +1377,8 @@ string t_php_generator ::type_to_enum(t_type* type) { return "TType::I32"; case t_base_type::TYPE_I64: return "TType::I64"; + case t_base_type::TYPE_DOUBLE: + return "TType::DOUBLE"; } } else if (type->is_enum()) { return "TType::I32"; diff --git a/compiler/cpp/src/generate/t_py_generator.cc b/compiler/cpp/src/generate/t_py_generator.cc index 53e5b3bf..522ce381 100644 --- a/compiler/cpp/src/generate/t_py_generator.cc +++ b/compiler/cpp/src/generate/t_py_generator.cc @@ -784,6 +784,9 @@ void t_py_generator::generate_deserialize_field(ofstream &out, case t_base_type::TYPE_I64: out << "readI64(itrans);"; break; + case t_base_type::TYPE_DOUBLE: + out << "readDouble(itrans);"; + break; default: throw "compiler error: no PHP name for base type " + tbase; } @@ -988,6 +991,9 @@ void t_py_generator::generate_serialize_field(ofstream &out, case t_base_type::TYPE_I64: out << "writeI64(otrans, " << name << ")"; break; + case t_base_type::TYPE_DOUBLE: + out << "writeDouble(otrans, " << name << ")"; + break; default: throw "compiler error: no PHP name for base type " + tbase; } @@ -1161,6 +1167,8 @@ string t_py_generator::base_type_name(t_base_type::t_base tbase) { return "Int32"; case t_base_type::TYPE_I64: return "Int64"; + case t_base_type::TYPE_DOUBLE: + return "Double"; default: throw "compiler error: no PHP name for base type " + tbase; } @@ -1195,6 +1203,9 @@ string t_py_generator::declare_field(t_field* tfield, bool init, bool obj) { case t_base_type::TYPE_I64: result += " = 0"; break; + case t_base_type::TYPE_DOUBLE: + result += " = 0.0"; + break; default: throw "compiler error: no PHP initializer for base type " + tbase; } @@ -1275,6 +1286,8 @@ string t_py_generator::type_to_enum(t_type* type) { return "TType.I32"; case t_base_type::TYPE_I64: return "TType.I64"; + case t_base_type::TYPE_DOUBLE: + return "TType.DOUBLE"; } } else if (type->is_enum()) { return "TType.I32"; diff --git a/compiler/cpp/src/parse/t_base_type.h b/compiler/cpp/src/parse/t_base_type.h index 1429d1c8..0e97207a 100644 --- a/compiler/cpp/src/parse/t_base_type.h +++ b/compiler/cpp/src/parse/t_base_type.h @@ -10,7 +10,9 @@ */ class t_base_type : public t_type { public: - /** Enumeration of thrift base types */ + /** + * Enumeration of thrift base types + */ enum t_base { TYPE_VOID, TYPE_STRING, @@ -18,7 +20,8 @@ class t_base_type : public t_type { TYPE_BYTE, TYPE_I16, TYPE_I32, - TYPE_I64 + TYPE_I64, + TYPE_DOUBLE }; t_base_type(std::string name, t_base base) : diff --git a/compiler/cpp/src/parse/t_program.h b/compiler/cpp/src/parse/t_program.h index abb368bf..9fa42711 100644 --- a/compiler/cpp/src/parse/t_program.h +++ b/compiler/cpp/src/parse/t_program.h @@ -37,6 +37,7 @@ class t_program { type_i16 = new t_base_type("i16", t_base_type::TYPE_I16); type_i32 = new t_base_type("i32", t_base_type::TYPE_I32); type_i64 = new t_base_type("i64", t_base_type::TYPE_I64); + type_double = new t_base_type("double", t_base_type::TYPE_DOUBLE); } ~t_program() { @@ -46,6 +47,7 @@ class t_program { delete type_i16; delete type_i32; delete type_i64; + delete type_double; } // Name accessor @@ -69,6 +71,7 @@ class t_program { t_type* get_i16_type() const { return type_i16; } t_type* get_i32_type() const { return type_i32; } t_type* get_i64_type() const { return type_i64; } + t_type* get_double_type() const { return type_double; } // Custom data type lookup t_type* get_custom_type(std::string name) { @@ -130,6 +133,7 @@ class t_program { t_type* type_i16; t_type* type_i32; t_type* type_i64; + t_type* type_double; }; #endif diff --git a/compiler/cpp/src/thrift.l b/compiler/cpp/src/thrift.l index 1ff7708e..484e43b1 100644 --- a/compiler/cpp/src/thrift.l +++ b/compiler/cpp/src/thrift.l @@ -23,6 +23,7 @@ identifier ([a-zA-Z_][\.a-zA-Z_0-9]*) whitespace ([ \t\r\n]*) multicomm ("/*""/"*([^*/]|[^*]"/"|"*"[^/])*"*"*"*/") comment ("//"[^\n]*) +unixcomment ("#"[^\n]*) symbol ([\,\{\}\(\)\=<>]) %% @@ -30,6 +31,7 @@ symbol ([\,\{\}\(\)\=<>]) {whitespace} { /* do nothing */ } {multicomm} { /* do nothing */ } {comment} { /* do nothing */ } +{unixcomment} { /* do nothing */ } {symbol} { return yytext[0]; } diff --git a/compiler/cpp/src/thrift.y b/compiler/cpp/src/thrift.y index e7381809..f2fd790f 100644 --- a/compiler/cpp/src/thrift.y +++ b/compiler/cpp/src/thrift.y @@ -394,6 +394,11 @@ BaseType: pdebug("BaseType -> tok_i64"); $$ = g_program->get_i64_type(); } +| tok_double + { + pdebug("BaseType -> tok_double"); + $$ = g_program->get_double_type(); + } ContainerType: MapType diff --git a/lib/cpp/src/protocol/TBinaryProtocol.cc b/lib/cpp/src/protocol/TBinaryProtocol.cc index 51c93068..9fb2ec36 100644 --- a/lib/cpp/src/protocol/TBinaryProtocol.cc +++ b/lib/cpp/src/protocol/TBinaryProtocol.cc @@ -116,7 +116,24 @@ uint32_t TBinaryProtocol::writeI64(shared_ptr out, out->write((uint8_t*)&net, 8); return 8; } + +uint32_t TBinaryProtocol::writeDouble(shared_ptr out, + const double dub) const { + uint8_t b[8]; + uint8_t* d = (uint8_t*)&dub; + b[0] = d[7]; + b[1] = d[6]; + b[2] = d[5]; + b[3] = d[4]; + b[4] = d[3]; + b[5] = d[2]; + b[6] = d[1]; + b[7] = d[0]; + out->write((uint8_t*)b, 8); + return 8; +} + uint32_t TBinaryProtocol::writeString(shared_ptr out, const string& str) const { uint32_t result = writeI32(out, str.size()); @@ -276,6 +293,23 @@ uint32_t TBinaryProtocol::readI64(shared_ptr in, return 8; } +uint32_t TBinaryProtocol::readDouble(shared_ptr in, + double& dub) const { + uint8_t b[8]; + uint8_t d[8]; + in->readAll(b, 8); + d[0] = b[7]; + d[1] = b[6]; + d[2] = b[5]; + d[3] = b[4]; + d[4] = b[3]; + d[5] = b[2]; + d[6] = b[1]; + d[7] = b[0]; + dub = *(double*)d; + return 8; +} + uint32_t TBinaryProtocol::readString(shared_ptr in, string& str) const { uint32_t result; diff --git a/lib/cpp/src/protocol/TBinaryProtocol.h b/lib/cpp/src/protocol/TBinaryProtocol.h index 5bca6dd0..7f36a578 100644 --- a/lib/cpp/src/protocol/TBinaryProtocol.h +++ b/lib/cpp/src/protocol/TBinaryProtocol.h @@ -80,6 +80,10 @@ using namespace boost; uint32_t writeI64(shared_ptr out, const int64_t i64) const; + uint32_t writeDouble(shared_ptr out, + const double dub) const; + + uint32_t writeString(shared_ptr out, const std::string& str) const; @@ -141,6 +145,9 @@ using namespace boost; uint32_t readI64(shared_ptr in, int64_t& i64) const; + uint32_t readDouble(shared_ptr in, + double& dub) const; + uint32_t readString(shared_ptr in, std::string& str) const; }; diff --git a/lib/cpp/src/protocol/TProtocol.h b/lib/cpp/src/protocol/TProtocol.h index 65d6f3c2..89c7f48c 100644 --- a/lib/cpp/src/protocol/TProtocol.h +++ b/lib/cpp/src/protocol/TProtocol.h @@ -16,7 +16,7 @@ using namespace boost; using namespace facebook::thrift::transport; -#define ntohll(x) (((uint64_t)(ntohl((int)((x << 32) >> 32))) << 32) | (uint32_t)ntohl(((int)(x >> 32)))) +#define ntohll(x) (((uint64_t)(ntohl((int)((x & 0x00000000FFFFFFFF)))) << 32) | (uint32_t)ntohl(((int)(x >> 32 & 0x00000000FFFFFFFF)))) #define htonll(x) ntohll(x) @@ -38,6 +38,7 @@ enum TType { T_I32 = 8, T_U64 = 9, T_I64 = 10, + T_DOUBLE = 4, T_STRING = 11, T_UTF7 = 11, T_STRUCT = 12, @@ -133,6 +134,9 @@ class TProtocol { virtual uint32_t writeI64(shared_ptr out, const int64_t i64) const = 0; + virtual uint32_t writeDouble(shared_ptr out, + const double dub) const = 0; + virtual uint32_t writeString(shared_ptr out, const std::string& str) const = 0; @@ -193,6 +197,9 @@ class TProtocol { virtual uint32_t readI64(shared_ptr in, int64_t& i64) const = 0; + virtual uint32_t readDouble(shared_ptr in, + double& dub) const = 0; + virtual uint32_t readString(shared_ptr in, std::string& str) const = 0; @@ -226,6 +233,11 @@ class TProtocol { int64_t i64; return readI64(in, i64); } + case T_DOUBLE: + { + double dub; + return readDouble(in, dub); + } case T_STRING: { std::string str; diff --git a/lib/java/src/protocol/TBinaryProtocol.java b/lib/java/src/protocol/TBinaryProtocol.java index d90decef..4d6c3459 100644 --- a/lib/java/src/protocol/TBinaryProtocol.java +++ b/lib/java/src/protocol/TBinaryProtocol.java @@ -95,6 +95,10 @@ public class TBinaryProtocol implements TProtocol { out.write(i64out, 0, 8); } + public void writeDouble(TTransport out, double dub) throws TException { + writeI64(out, Double.doubleToLongBits(dub)); + } + public void writeString(TTransport out, String str) throws TException { byte[] dat = str.getBytes(); writeI32(out, dat.length); @@ -203,6 +207,10 @@ public class TBinaryProtocol implements TProtocol { ((long)(i64rd[7] & 0xff)); } + public double readDouble(TTransport in) throws TException { + return Double.longBitsToDouble(readI64(in)); + } + public String readString(TTransport in) throws TException { int size = readI32(in); byte[] buf = new byte[size]; diff --git a/lib/java/src/protocol/TProtocol.java b/lib/java/src/protocol/TProtocol.java index 69fe885f..0831d123 100644 --- a/lib/java/src/protocol/TProtocol.java +++ b/lib/java/src/protocol/TProtocol.java @@ -61,6 +61,10 @@ public interface TProtocol { public void writeI64 (TTransport out, long i64) throws TException; + public void writeDouble (TTransport out, + double dub) throws TException; + + public void writeString (TTransport out, String str) throws TException; @@ -102,6 +106,8 @@ public interface TProtocol { public long readI64 (TTransport in) throws TException; + public double readDouble (TTransport in) throws TException; + public String readString (TTransport in) throws TException; } diff --git a/lib/java/src/protocol/TProtocolUtil.java b/lib/java/src/protocol/TProtocolUtil.java index 52236398..1c88f8a1 100644 --- a/lib/java/src/protocol/TProtocolUtil.java +++ b/lib/java/src/protocol/TProtocolUtil.java @@ -34,6 +34,10 @@ public class TProtocolUtil { { prot.readI64(in); } + case TType.DOUBLE: + { + prot.readDouble(in); + } case TType.STRING: { prot.readString(in); diff --git a/lib/java/src/protocol/TType.java b/lib/java/src/protocol/TType.java index 37b53bd9..bed9a214 100644 --- a/lib/java/src/protocol/TType.java +++ b/lib/java/src/protocol/TType.java @@ -10,6 +10,7 @@ public final class TType { public static final byte VOID = 1; public static final byte BOOL = 2; public static final byte BYTE = 3; + public static final byte DOUBLE = 4; public static final byte I16 = 6; public static final byte I32 = 8; public static final byte I64 = 10; diff --git a/lib/php/src/protocol/TBinaryProtocol.php b/lib/php/src/protocol/TBinaryProtocol.php index 4bb02977..2b1384f6 100644 --- a/lib/php/src/protocol/TBinaryProtocol.php +++ b/lib/php/src/protocol/TBinaryProtocol.php @@ -136,6 +136,12 @@ class TBinaryProtocol extends TProtocol { return 8; } + public function writeDouble($out, $value) { + $data = pack('d', $value); + $out->write(strrev($data), 8); + return 8; + } + public function writeString($out, $value) { $len = strlen($value); $result = $this->writeI32($out, $len); @@ -302,6 +308,13 @@ class TBinaryProtocol extends TProtocol { return 8; } + public function readDouble($in, &$value) { + $data = strrev($in->readAll(8)); + $arr = unpack('d', $data); + $value = $arr[1]; + return 8; + } + public function readString($in, &$value) { $result = $this->readI32($in, $len); $value = $in->readAll($len); diff --git a/lib/php/src/protocol/TProtocol.php b/lib/php/src/protocol/TProtocol.php index 855d5889..6101f578 100644 --- a/lib/php/src/protocol/TProtocol.php +++ b/lib/php/src/protocol/TProtocol.php @@ -89,6 +89,8 @@ abstract class TProtocol { public abstract function writeI64($out, $i64); + public abstract function writeDouble($out, $dub); + public abstract function writeString($out, $str); @@ -139,6 +141,8 @@ abstract class TProtocol { public abstract function readI64($in, &$i64); + public abstract function readDouble($in, &$dub); + public abstract function readString($in, &$str); /** @@ -160,6 +164,8 @@ abstract class TProtocol { return $this->readI32($in, $i32); case TType::I64: return $this->readI64($in, $i64); + case TType::DOUBLE: + return $this->readDouble($in, $dub); case TType::STRING: return $this->readString($in, $str); case TType::STRUCT: diff --git a/lib/php/src/protocol/TType.php b/lib/php/src/protocol/TType.php index 6ef09355..aa930ce2 100644 --- a/lib/php/src/protocol/TType.php +++ b/lib/php/src/protocol/TType.php @@ -15,7 +15,8 @@ class TType { const VOID = 1; const BOOL = 2; const BYTE = 3; - const I08 = 4; + const I08 = 3; + const DOUBLE = 4; const I16 = 6; const I32 = 8; const I64 = 10; diff --git a/lib/py/src/protocol/TBinaryProtocol.py b/lib/py/src/protocol/TBinaryProtocol.py index 860f4611..25f3218a 100644 --- a/lib/py/src/protocol/TBinaryProtocol.py +++ b/lib/py/src/protocol/TBinaryProtocol.py @@ -73,6 +73,10 @@ class TBinaryProtocol(TProtocolBase): buff = pack("!q", i64) otrans.write(buff) + def writeDouble(self, otrans, dub): + buff = pack("!d", dub) + otrans.write(buff) + def writeString(self, otrans, str): self.writeI32(otrans, len(str)) otrans.write(str) @@ -153,6 +157,11 @@ class TBinaryProtocol(TProtocolBase): val, = unpack('!q', buff) return val + def readDouble(self, itrans): + buff = itrans.readAll(8) + val, = unpack('!d', buff) + return val + def readString(self, itrans): len = self.readI32(itrans) str = itrans.readAll(len) diff --git a/lib/py/src/protocol/TProtocol.py b/lib/py/src/protocol/TProtocol.py index 3105e254..0b480d30 100644 --- a/lib/py/src/protocol/TProtocol.py +++ b/lib/py/src/protocol/TProtocol.py @@ -3,7 +3,8 @@ class TType: VOID = 1 BOOL = 2 BYTE = 3 - I08 = 4 + I08 = 3 + DOUBLE = 4 I16 = 6 I32 = 8 I64 = 10 @@ -78,6 +79,9 @@ class TProtocolBase: def writeI64(self, otrans, i64): pass + def writeDouble(self, otrans, dub): + pass + def writeString(self, otrans, str): pass @@ -132,6 +136,9 @@ class TProtocolBase: def readI64(self, itrans): pass + def readDouble(self, itrans): + pass + def readString(self, itrans): pass @@ -148,6 +155,8 @@ class TProtocolBase: self.readI32(itrans) elif type == TType.I64: self.readI64(itrans) + elif type == TType.DOUBLE: + self.readDouble(itrans) elif type == TType.STRING: self.readString(itrans) elif type == TType.STRUCT: diff --git a/lib/py/src/server/TServer.py b/lib/py/src/server/TServer.py index 69be2606..a5d5621b 100644 --- a/lib/py/src/server/TServer.py +++ b/lib/py/src/server/TServer.py @@ -1,3 +1,6 @@ +import sys +import traceback + from thrift.Thrift import TProcessor from thrift.transport import TTransport @@ -27,6 +30,6 @@ class TSimpleServer(TServer): while True: self.processor.process(client, client) except Exception, x: - print x + print '%s, %s, %s' % (type(x), x, traceback.format_exc()) print 'Client died.' client.close() diff --git a/lib/py/src/transport/TSocket.py b/lib/py/src/transport/TSocket.py index 4ef35d9b..61f1cff8 100644 --- a/lib/py/src/transport/TSocket.py +++ b/lib/py/src/transport/TSocket.py @@ -36,7 +36,7 @@ class TSocket(TTransportBase): def read(self, sz): buff = self.handle.recv(sz) if len(buff) == 0: - raise Exception('TScket read 0 bytes') + raise Exception('TSocket read 0 bytes') return buff def write(self, buff): diff --git a/test/ThriftTest.thrift b/test/ThriftTest.thrift index 897d707f..414dceab 100644 --- a/test/ThriftTest.thrift +++ b/test/ThriftTest.thrift @@ -56,6 +56,7 @@ service ThriftTest byte testByte(byte thing = 1), i32 testI32(i32 thing = 1), i64 testI64(i64 thing = 1), + double testDouble(double thing = 1), Xtruct testStruct(Xtruct thing = 1), Xtruct2 testNest(Xtruct2 thing = 1), map testMap(map thing = 1), diff --git a/test/cpp/src/TestClient.cc b/test/cpp/src/TestClient.cc index d340e268..e12b65b7 100644 --- a/test/cpp/src/TestClient.cc +++ b/test/cpp/src/TestClient.cc @@ -99,6 +99,13 @@ int main(int argc, char** argv) { printf("testI64(-34359738368)"); int64_t i64 = testClient.testI64(-34359738368LL); printf(" = %ld\n", i64); + + /** + * DOUBLE TEST + */ + printf("testDouble(-5.2098523)"); + double dub = testClient.testDouble(-5.2098523); + printf(" = %lf\n", dub); /** * STRUCT TEST diff --git a/test/cpp/src/TestServer.cc b/test/cpp/src/TestServer.cc index 63a75945..97d34401 100644 --- a/test/cpp/src/TestServer.cc +++ b/test/cpp/src/TestServer.cc @@ -47,6 +47,11 @@ class TestHandler : public ThriftTestIf { return thing; } + double testDouble(double thing) { + printf("testDouble(%lf)\n", thing); + return thing; + } + Xtruct testStruct(Xtruct thing) { printf("testStruct({\"%s\", %d, %d, %ld})\n", thing.string_thing.c_str(), diff --git a/test/java/src/TestClient.java b/test/java/src/TestClient.java index 686920c7..74fbfefc 100644 --- a/test/java/src/TestClient.java +++ b/test/java/src/TestClient.java @@ -93,6 +93,13 @@ public class TestClient { long i64 = testClient.testI64(-34359738368L); System.out.print(" = " + i64 + "\n"); + /** + * DOUBLE TEST + */ + System.out.print("testDouble(5.325098235)"); + double dub = testClient.testDouble(5.325098235); + System.out.print(" = " + dub + "\n"); + /** * STRUCT TEST */ diff --git a/test/java/src/TestServer.java b/test/java/src/TestServer.java index 7418cbb2..8e3e4ed3 100644 --- a/test/java/src/TestServer.java +++ b/test/java/src/TestServer.java @@ -45,6 +45,11 @@ public class TestServer { System.out.print("testI64(" + thing + ")\n"); return thing; } + + public double testDouble(double thing) { + System.out.print("testDouble(" + thing + ")\n"); + return thing; + } public Xtruct testStruct(Xtruct thing) { System.out.print("testStruct({" + diff --git a/test/php/TestClient.php b/test/php/TestClient.php index 6dd40d7f..a92adcca 100644 --- a/test/php/TestClient.php +++ b/test/php/TestClient.php @@ -84,6 +84,13 @@ print_r("testI64(-34359738368)"); $i64 = $testClient->testI64(-34359738368); print_r(" = $i64\n"); +/** + * DOUBLE TEST + */ +print_r("testDouble(-852.234234234)"); +$dub = $testClient->testDouble(-852.234234234); +print_r(" = $dub\n"); + /** * STRUCT TEST */ diff --git a/test/py/TestClient.py b/test/py/TestClient.py index 21d19908..3edff1cb 100755 --- a/test/py/TestClient.py +++ b/test/py/TestClient.py @@ -32,9 +32,15 @@ print client.testByte(63) print "testI32(-1)" print client.testI32(-1) +print "testI32(0)" +print client.testI32(0) + print "testI64(-34359738368)" print client.testI64(-34359738368) +print "testDouble(-5.235098235)" +print client.testDouble(-5.235098235) + print "testStruct({Zero, 1, -3, -5})" x = Xtruct() x.string_thing = "Zero" diff --git a/test/py/TestServer.py b/test/py/TestServer.py index 4b571c7a..525ffee3 100755 --- a/test/py/TestServer.py +++ b/test/py/TestServer.py @@ -22,12 +22,33 @@ class TestHandler: print 'testByte(%d)' % byte return byte + def testI16(self, i16): + print 'testI16(%d)' % i16 + return i16 + + def testI32(self, i32): + print 'testI32(%d)' % i32 + return i32 + + def testI64(self, i64): + print 'testI64(%d)' % i64 + return i64 + + def testDouble(self, dub): + print 'testDouble(%f)' % dub + return dub + + def testStruct(self, thing): + print 'testStruct({%s, %d, %d, %d})' % (thing.string_thing, thing.byte_thing, thing.i32_thing, thing.i64_thing) + return thing + def testException(self, str): print 'testException(%s)' % str - x = Xception() - x.errorCode = 1001 - x.message = str - raise x + if str == 'Xception': + x = Xception() + x.errorCode = 1001 + x.message = str + raise x transport = TSocket.TServerSocket(9090) protocol = TBinaryProtocol.TBinaryProtocol() -- 2.17.1