THRIFT-2704 - compiler: T_ONEWAY type used for oneway methods instead of T_CALL
Patch: Konrad Grochowski
This closes #216
diff --git a/compiler/cpp/src/generate/t_as3_generator.cc b/compiler/cpp/src/generate/t_as3_generator.cc
index a965aab..42486d6 100644
--- a/compiler/cpp/src/generate/t_as3_generator.cc
+++ b/compiler/cpp/src/generate/t_as3_generator.cc
@@ -1677,7 +1677,9 @@
// Serialize the request
f_service_ <<
- indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname << "\", TMessageType.CALL, seqid_));" << endl <<
+ indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname << "\", " <<
+ ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") <<
+ ", seqid_));" << endl <<
indent() << "var args:" << argsname << " = new " << argsname << "();" << endl;
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
diff --git a/compiler/cpp/src/generate/t_c_glib_generator.cc b/compiler/cpp/src/generate/t_c_glib_generator.cc
index c726b0c..dbb8a2a 100644
--- a/compiler/cpp/src/generate/t_c_glib_generator.cc
+++ b/compiler/cpp/src/generate/t_c_glib_generator.cc
@@ -1517,6 +1517,8 @@
function_signature (&send_function) << endl;
scope_up(f_service_);
+ string reqType = (*f_iter)->is_oneway() ? "T_ONEWAY" : "T_CALL";
+
// Serialize the request
f_service_ <<
indent() << "gint32 cseqid = 0;" << endl <<
@@ -1524,8 +1526,8 @@
this->nspace_uc << base_service_name_uc <<
"_CLIENT (iface)->output_protocol;" << endl <<
endl <<
- indent() << "if (thrift_protocol_write_message_begin (protocol, \"" <<
- name << "\", T_CALL, cseqid, error) < 0)" << endl <<
+ indent() << "if (thrift_protocol_write_message_begin (protocol, \""
+ << name << "\", " << reqType << ", cseqid, error) < 0)" << endl <<
indent() << " return FALSE;" << endl <<
endl;
diff --git a/compiler/cpp/src/generate/t_cocoa_generator.cc b/compiler/cpp/src/generate/t_cocoa_generator.cc
index 20973a3..f765f7d 100644
--- a/compiler/cpp/src/generate/t_cocoa_generator.cc
+++ b/compiler/cpp/src/generate/t_cocoa_generator.cc
@@ -1401,7 +1401,7 @@
// Serialize the request
out <<
indent() << "[outProtocol writeMessageBeginWithName: @\"" << funname << "\"" <<
- " type: TMessageType_CALL" <<
+ ((*f_iter)->is_oneway() ? " type: TMessageType_ONEWAY" : " type: TMessageType_CALL") <<
" sequenceID: 0];" << endl;
out <<
diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc
index f019ba8..ce298ad 100755
--- a/compiler/cpp/src/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/generate/t_cpp_generator.cc
@@ -2756,7 +2756,9 @@
indent() << "int32_t cseqid = 0;" << endl <<
indent() << _this << "oprot_->writeMessageBegin(\"" <<
(*f_iter)->get_name() <<
- "\", ::apache::thrift::protocol::T_CALL, cseqid);" << endl <<
+ "\", ::apache::thrift::protocol::" <<
+ ((*f_iter)->is_oneway() ? "T_ONEWAY" : "T_CALL") <<
+ ", cseqid);" << endl <<
endl <<
indent() << argsname << " args;" << endl;
diff --git a/compiler/cpp/src/generate/t_csharp_generator.cc b/compiler/cpp/src/generate/t_csharp_generator.cc
index 7944df0..1d66cef 100644
--- a/compiler/cpp/src/generate/t_csharp_generator.cc
+++ b/compiler/cpp/src/generate/t_csharp_generator.cc
@@ -1718,7 +1718,9 @@
scope_up(f_service_);
f_service_ <<
- indent() << "oprot_.WriteMessageBegin(new TMessage(\"" << funname << "\", TMessageType.Call, seqid_));" << endl <<
+ indent() << "oprot_.WriteMessageBegin(new TMessage(\"" << funname << "\", " <<
+ ((*f_iter)->is_oneway() ? "TMessageType.Oneway" : "TMessageType.Call") <<
+ ", seqid_));" << endl <<
indent() << argsname << " args = new " << argsname << "();" << endl;
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
diff --git a/compiler/cpp/src/generate/t_delphi_generator.cc b/compiler/cpp/src/generate/t_delphi_generator.cc
index 5f378f0..19b8272 100644
--- a/compiler/cpp/src/generate/t_delphi_generator.cc
+++ b/compiler/cpp/src/generate/t_delphi_generator.cc
@@ -1777,7 +1777,9 @@
indent_impl(s_service_impl) <<
"seqid_ := seqid_ + 1;" << endl;
indent_impl(s_service_impl) <<
- msgvar << " := Thrift.Protocol.TMessageImpl.Create('" << funname << "', TMessageType.Call, seqid_);" << endl;
+ msgvar << " := Thrift.Protocol.TMessageImpl.Create('" << funname << "', " <<
+ ((*f_iter)->is_oneway() ? "TMessageType.Oneway" : "TMessageType.Call") <<
+ ", seqid_);" << endl;
indent_impl(s_service_impl) <<
"oprot_.WriteMessageBegin( " << msgvar << " );" << endl;
diff --git a/compiler/cpp/src/generate/t_go_generator.cc b/compiler/cpp/src/generate/t_go_generator.cc
index 9a3e909..54ad887 100644
--- a/compiler/cpp/src/generate/t_go_generator.cc
+++ b/compiler/cpp/src/generate/t_go_generator.cc
@@ -1803,7 +1803,10 @@
indent() << " p.OutputProtocol = oprot" << endl <<
indent() << "}" << endl <<
indent() << "p.SeqId++" << endl <<
- indent() << "if err = oprot.WriteMessageBegin(\"" << (*f_iter)->get_name() << "\", thrift.CALL, p.SeqId); err != nil {" << endl;
+ indent() << "if err = oprot.WriteMessageBegin(\""
+ << (*f_iter)->get_name() << "\", "
+ << ((*f_iter)->is_oneway() ? "thrift.ONEWAY" : "thrift.CALL")
+ << ", p.SeqId); err != nil {" << endl;
indent_up();
f_service_ <<
indent() << "return" << endl;
diff --git a/compiler/cpp/src/generate/t_hs_generator.cc b/compiler/cpp/src/generate/t_hs_generator.cc
index fff7e53..2f75daf 100644
--- a/compiler/cpp/src/generate/t_hs_generator.cc
+++ b/compiler/cpp/src/generate/t_hs_generator.cc
@@ -1113,7 +1113,8 @@
// Serialize the request header
string fname = (*f_iter)->get_name();
- indent(f_client_) << "T.writeMessageBegin op (\"" << fname << "\", T.M_CALL, seqn)" << endl;
+ string msgType = (*f_iter)->is_oneway() ? "T.M_ONEWAY" : "T.M_CALL";
+ indent(f_client_) << "T.writeMessageBegin op (\"" << fname << "\", " << msgType << ", seqn)" << endl;
indent(f_client_) << "write_" << argsname << " op (" << argsname << "{";
bool first = true;
diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc
index 3a556a5..ddf4c91 100644
--- a/compiler/cpp/src/generate/t_java_generator.cc
+++ b/compiler/cpp/src/generate/t_java_generator.cc
@@ -2814,7 +2814,10 @@
// Serialize request
// NOTE we are leaving seqid as 0, for now (see above)
f_service_ <<
- indent() << "prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage(\"" << funname << "\", org.apache.thrift.protocol.TMessageType.CALL, 0));" << endl <<
+ indent() << "prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage(\"" <<
+ funname << "\", org.apache.thrift.protocol." <<
+ ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") <<
+ ", 0));" << endl <<
indent() << args_name << " args = new " << args_name << "();" << endl;
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
diff --git a/compiler/cpp/src/generate/t_javame_generator.cc b/compiler/cpp/src/generate/t_javame_generator.cc
index 6d02979..c28571e 100644
--- a/compiler/cpp/src/generate/t_javame_generator.cc
+++ b/compiler/cpp/src/generate/t_javame_generator.cc
@@ -2109,7 +2109,9 @@
// Serialize the request
f_service_ <<
- indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname << "\", TMessageType.CALL, ++seqid_));" << endl <<
+ indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname << "\", " <<
+ ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") <<
+ ", ++seqid_));" << endl <<
indent() << argsname << " args = new " << argsname << "();" << endl;
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
diff --git a/compiler/cpp/src/generate/t_js_generator.cc b/compiler/cpp/src/generate/t_js_generator.cc
index 32cb162..7711aa5 100644
--- a/compiler/cpp/src/generate/t_js_generator.cc
+++ b/compiler/cpp/src/generate/t_js_generator.cc
@@ -1350,12 +1350,20 @@
std::string argsname = js_namespace(program_)+ service_name_ + "_" + (*f_iter)->get_name() + "_args";
+ std::string messageType
+ = (*f_iter)->is_oneway() ? "Thrift.MessageType.ONEWAY" : "Thrift.MessageType.CALL";
+
// Serialize the request header
if (gen_node_) {
- f_service_ << indent() << outputVar << ".writeMessageBegin('" << (*f_iter)->get_name() << "', Thrift.MessageType.CALL, this.seqid());" << endl;
+ f_service_ <<
+ indent() << outputVar << ".writeMessageBegin('" << (*f_iter)->get_name()
+ << "', " << messageType << ", this.seqid());" << endl;
}
else {
- f_service_ << indent() << outputVar << ".writeMessageBegin('" << (*f_iter)->get_name() << "', Thrift.MessageType.CALL, this.seqid);" << endl;
+ f_service_ <<
+ indent() << outputVar << ".writeMessageBegin('"
+ << (*f_iter)->get_name() << "', "
+ << messageType << ", this.seqid);" << endl;
}
f_service_ <<
diff --git a/compiler/cpp/src/generate/t_lua_generator.cc b/compiler/cpp/src/generate/t_lua_generator.cc
index b7fdad4..0246797 100644
--- a/compiler/cpp/src/generate/t_lua_generator.cc
+++ b/compiler/cpp/src/generate/t_lua_generator.cc
@@ -601,8 +601,9 @@
indent(out) << endl << "function " << classname << ":send_" << sig << endl;
indent_up();
- indent(out) << "self.oprot:writeMessageBegin('" << funcname <<
- "', TMessageType.CALL, self._seqid)" << endl;
+ indent(out) << "self.oprot:writeMessageBegin('" << funcname << "', "
+ << ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL")
+ << ", self._seqid)" << endl;
indent(out) << "local args = " << funcname << "_args:new{}" << endl;
// Set the args
diff --git a/compiler/cpp/src/generate/t_ocaml_generator.cc b/compiler/cpp/src/generate/t_ocaml_generator.cc
index f3df4e3..6607f6e 100644
--- a/compiler/cpp/src/generate/t_ocaml_generator.cc
+++ b/compiler/cpp/src/generate/t_ocaml_generator.cc
@@ -1105,7 +1105,9 @@
// Serialize the request header
f_service_ <<
- indent() << "oprot#writeMessageBegin (\"" << (*f_iter)->get_name() << "\", Protocol.CALL, seqid);" << endl;
+ indent() << "oprot#writeMessageBegin (\"" << (*f_iter)->get_name() << "\", "
+ << ((*f_iter)->is_oneway() ? "Protocol.ONEWAY" : "Protocol.CALL")
+ << ", seqid);" << endl;
f_service_ <<
indent() << "let args = new " << argsname << " in" << endl;
diff --git a/compiler/cpp/src/generate/t_perl_generator.cc b/compiler/cpp/src/generate/t_perl_generator.cc
index a40f85b..6059ee8 100644
--- a/compiler/cpp/src/generate/t_perl_generator.cc
+++ b/compiler/cpp/src/generate/t_perl_generator.cc
@@ -1161,7 +1161,9 @@
// Serialize the request header
f_service_ <<
- indent() << "$self->{output}->writeMessageBegin('" << (*f_iter)->get_name() << "', TMessageType::CALL, $self->{seqid});" << endl;
+ indent() << "$self->{output}->writeMessageBegin('" << (*f_iter)->get_name() << "', " <<
+ ((*f_iter)->is_oneway() ? "TMessageType::ONEWAY" : "TMessageType::CALL") <<
+ ", $self->{seqid});" << endl;
f_service_ <<
indent() << "my $args = new " << argsname << "();" << endl;
diff --git a/compiler/cpp/src/generate/t_php_generator.cc b/compiler/cpp/src/generate/t_php_generator.cc
index 9bf1139..a787f70 100644
--- a/compiler/cpp/src/generate/t_php_generator.cc
+++ b/compiler/cpp/src/generate/t_php_generator.cc
@@ -1665,8 +1665,12 @@
indent() << "if ($bin_accel)" << endl;
scope_up(f_service_);
+ string messageType = (*f_iter)->is_oneway() ? "TMessageType::ONEWAY" : "TMessageType::CALL";
+
f_service_ <<
- indent() << "thrift_protocol_write_binary($this->output_, '" << (*f_iter)->get_name() << "', " << "TMessageType::CALL, $args, $this->seqid_, $this->output_->isStrictWrite());" << endl;
+ indent() << "thrift_protocol_write_binary($this->output_, '"
+ << (*f_iter)->get_name() << "', " << messageType
+ << ", $args, $this->seqid_, $this->output_->isStrictWrite());" << endl;
scope_down(f_service_);
f_service_ <<
@@ -1676,13 +1680,15 @@
// Serialize the request header
if (binary_inline_) {
f_service_ <<
- indent() << "$buff = pack('N', (0x80010000 | " << "TMessageType::CALL));" << endl <<
+ indent() << "$buff = pack('N', (0x80010000 | " << messageType
+ << "));" << endl <<
indent() << "$buff .= pack('N', strlen('" << funname << "'));" << endl <<
indent() << "$buff .= '" << funname << "';" << endl <<
indent() << "$buff .= pack('N', $this->seqid_);" << endl;
} else {
f_service_ <<
- indent() << "$this->output_->writeMessageBegin('" << (*f_iter)->get_name() << "', " << "TMessageType::CALL, $this->seqid_);" << endl;
+ indent() << "$this->output_->writeMessageBegin('" << (*f_iter)->get_name() << "', "
+ << messageType << ", $this->seqid_);" << endl;
}
// Write to the stream
diff --git a/compiler/cpp/src/generate/t_py_generator.cc b/compiler/cpp/src/generate/t_py_generator.cc
index f0c31a4..eb558ad 100644
--- a/compiler/cpp/src/generate/t_py_generator.cc
+++ b/compiler/cpp/src/generate/t_py_generator.cc
@@ -1344,17 +1344,18 @@
indent_up();
std::string argsname = (*f_iter)->get_name() + "_args";
+ std::string messageType = (*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL";
// Serialize the request header
if (gen_twisted_ || gen_tornado_) {
f_service_ <<
indent() << "oprot = self._oprot_factory.getProtocol(self._transport)" << endl <<
- indent() <<
- "oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', TMessageType.CALL, self._seqid)"
- << endl;
+ indent() << "oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', "
+ << messageType << ", self._seqid)" << endl;
} else {
f_service_ <<
- indent() << "self._oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', TMessageType.CALL, self._seqid)" << endl;
+ indent() << "self._oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', "
+ << messageType << ", self._seqid)" << endl;
}
f_service_ <<
diff --git a/doc/specs/thrift-protocol-spec.md b/doc/specs/thrift-protocol-spec.md
index 24d83f6..48ee827 100644
--- a/doc/specs/thrift-protocol-spec.md
+++ b/doc/specs/thrift-protocol-spec.md
@@ -43,7 +43,7 @@
<method-name> ::= STRING
- <message-type> ::= T_CALL | T_REPLY | T_EXCEPTION
+ <message-type> ::= T_CALL | T_REPLY | T_EXCEPTION | T_ONEWAY
<message-seqid> ::= I32
diff --git a/lib/cpp/src/thrift/processor/PeekProcessor.cpp b/lib/cpp/src/thrift/processor/PeekProcessor.cpp
index bfc4ac7..9303a13 100644
--- a/lib/cpp/src/thrift/processor/PeekProcessor.cpp
+++ b/lib/cpp/src/thrift/processor/PeekProcessor.cpp
@@ -66,7 +66,7 @@
int32_t seqid;
in->readMessageBegin(fname, mtype, seqid);
- if (mtype != T_CALL) {
+ if (mtype != T_CALL && mtype != T_ONEWAY) {
throw TException("Unexpected message type");
}
diff --git a/lib/cpp/src/thrift/processor/StatsProcessor.h b/lib/cpp/src/thrift/processor/StatsProcessor.h
index 58cd1dc..0fc123e 100644
--- a/lib/cpp/src/thrift/processor/StatsProcessor.h
+++ b/lib/cpp/src/thrift/processor/StatsProcessor.h
@@ -50,7 +50,7 @@
int32_t seqid;
piprot_->readMessageBegin(fname, mtype, seqid);
- if (mtype != apache::thrift::protocol::T_CALL) {
+ if (mtype != apache::thrift::protocol::T_CALL && mtype != apache::thrift::protocol::T_ONEWAY) {
if (print_) {
printf("Unknown message type\n");
}
diff --git a/lib/cpp/src/thrift/protocol/TCompactProtocol.h b/lib/cpp/src/thrift/protocol/TCompactProtocol.h
index d6da745..ce60b45 100644
--- a/lib/cpp/src/thrift/protocol/TCompactProtocol.h
+++ b/lib/cpp/src/thrift/protocol/TCompactProtocol.h
@@ -39,6 +39,7 @@
static const int8_t VERSION_N = 1;
static const int8_t VERSION_MASK = 0x1f; // 0001 1111
static const int8_t TYPE_MASK = (int8_t)0xE0u; // 1110 0000
+ static const int8_t TYPE_BITS = 0x07; // 0000 0111
static const int32_t TYPE_SHIFT_AMOUNT = 5;
Transport_* trans_;
diff --git a/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc b/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc
index a0955fc..85dde6c 100644
--- a/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc
+++ b/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc
@@ -433,7 +433,7 @@
throw TProtocolException(TProtocolException::BAD_VERSION, "Bad protocol version");
}
- messageType = (TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & 0x03);
+ messageType = (TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS);
rsize += readVarint32(seqid);
rsize += readString(name);
diff --git a/lib/cpp/test/AllProtocolTests.tcc b/lib/cpp/test/AllProtocolTests.tcc
index 7ccaef5..3c98943 100644
--- a/lib/cpp/test/AllProtocolTests.tcc
+++ b/lib/cpp/test/AllProtocolTests.tcc
@@ -97,14 +97,16 @@
const char* name;
TMessageType type;
int32_t seqid;
- } messages[4] = {
+ } messages[] = {
{"short message name", T_CALL, 0},
{"1", T_REPLY, 12345},
{"loooooooooooooooooooooooooooooooooong", T_EXCEPTION, 1 << 16},
+ {"one way push", T_ONEWAY, 12},
{"Janky", T_CALL, 0}
};
+ const int messages_count = sizeof(messages) / sizeof(TMessage);
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < messages_count; i++) {
shared_ptr<TTransport> transport(new TMemoryBuffer());
shared_ptr<TProtocol> protocol(new TProto(transport));
diff --git a/lib/csharp/src/Protocol/TCompactProtocol.cs b/lib/csharp/src/Protocol/TCompactProtocol.cs
index 2c94c0c..c992e9b 100644
--- a/lib/csharp/src/Protocol/TCompactProtocol.cs
+++ b/lib/csharp/src/Protocol/TCompactProtocol.cs
@@ -41,6 +41,7 @@
private const byte VERSION = 1;
private const byte VERSION_MASK = 0x1f; // 0001 1111
private const byte TYPE_MASK = 0xE0; // 1110 0000
+ private const byte TYPE_BITS = 0x07; // 0000 0111
private const int TYPE_SHIFT_AMOUNT = 5;
/**
@@ -490,7 +491,7 @@
{
throw new TProtocolException("Expected version " + VERSION + " but got " + version);
}
- byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & 0x03);
+ byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS);
int seqid = (int)ReadVarint32();
String messageName = ReadString();
return new TMessage(messageName, (TMessageType)type, seqid);
diff --git a/lib/d/src/thrift/protocol/compact.d b/lib/d/src/thrift/protocol/compact.d
index e970fd1..e03b67d 100644
--- a/lib/d/src/thrift/protocol/compact.d
+++ b/lib/d/src/thrift/protocol/compact.d
@@ -259,7 +259,7 @@
TProtocolException.Type.BAD_VERSION);
}
- msg.type = cast(TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & 0x03);
+ msg.type = cast(TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS);
msg.seqid = readVarint32();
msg.name = readString();
@@ -589,6 +589,7 @@
enum VERSION_N = 1;
enum VERSION_MASK = 0b0001_1111;
enum TYPE_MASK = 0b1110_0000;
+ enum TYPE_BITS = 0b0000_0111;
enum TYPE_SHIFT_AMOUNT = 5;
// Probably need to implement a better stack at some point.
diff --git a/lib/go/thrift/compact_protocol.go b/lib/go/thrift/compact_protocol.go
index c275cf4..0857a7a 100644
--- a/lib/go/thrift/compact_protocol.go
+++ b/lib/go/thrift/compact_protocol.go
@@ -31,6 +31,7 @@
COMPACT_VERSION = 1
COMPACT_VERSION_MASK = 0x1f
COMPACT_TYPE_MASK = 0x0E0
+ COMPACT_TYPE_BITS = 0x07
COMPACT_TYPE_SHIFT_AMOUNT = 5
)
@@ -335,7 +336,7 @@
}
versionAndType, err := p.ReadByte()
version := versionAndType & COMPACT_VERSION_MASK
- typeId = TMessageType((versionAndType >> COMPACT_TYPE_SHIFT_AMOUNT) & 0x03)
+ typeId = TMessageType((versionAndType >> COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_BITS)
if err != nil {
return
}
diff --git a/lib/hs/src/Thrift/Protocol/Compact.hs b/lib/hs/src/Thrift/Protocol/Compact.hs
index c3bd22d..a329f4e 100644
--- a/lib/hs/src/Thrift/Protocol/Compact.hs
+++ b/lib/hs/src/Thrift/Protocol/Compact.hs
@@ -60,6 +60,7 @@
version = 0x01
versionMask = 0x1f -- 0001 1111
typeMask = 0xe0 -- 1110 0000
+typeBits = 0x07 -- 0000 0111
typeShiftAmount :: Int
typeShiftAmount = 5
@@ -81,7 +82,7 @@
w <- fromIntegral <$> P.anyWord8
let ver = w .&. versionMask
when (ver /= version) $ error "Bad Protocol version"
- let typ = (w `shiftR` typeShiftAmount) .&. 0x03
+ let typ = (w `shiftR` typeShiftAmount) .&. typeBits
seqId <- parseVarint zigZagToI32
TString name <- parseCompactValue T_STRING
return (decodeUtf8 name, toEnum $ fromIntegral $ typ, seqId)
diff --git a/lib/hs/src/Thrift/Types.hs b/lib/hs/src/Thrift/Types.hs
index b014ac6..b90c42c 100644
--- a/lib/hs/src/Thrift/Types.hs
+++ b/lib/hs/src/Thrift/Types.hs
@@ -113,17 +113,20 @@
= M_CALL
| M_REPLY
| M_EXCEPTION
+ | M_ONEWAY
deriving ( Eq, Show )
instance Enum MessageType where
fromEnum M_CALL = 1
fromEnum M_REPLY = 2
fromEnum M_EXCEPTION = 3
+ fromEnum M_ONEWAY = 4
toEnum 1 = M_CALL
toEnum 2 = M_REPLY
toEnum 3 = M_EXCEPTION
+ toEnum 4 = M_ONEWAY
toEnum t = error $ "Invalid MessageType " ++ show t
instance Arbitrary MessageType where
- arbitrary = elements [M_CALL, M_REPLY, M_EXCEPTION]
+ arbitrary = elements [M_CALL, M_REPLY, M_EXCEPTION, M_ONEWAY]
diff --git a/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java b/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java
index 0a653a1..5973fcd 100644
--- a/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java
+++ b/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java
@@ -89,6 +89,7 @@
private static final byte VERSION = 1;
private static final byte VERSION_MASK = 0x1f; // 0001 1111
private static final byte TYPE_MASK = (byte)0xE0; // 1110 0000
+ private static final byte TYPE_BITS = 0x07; // 0000 0111
private static final int TYPE_SHIFT_AMOUNT = 5;
/**
@@ -506,7 +507,7 @@
if (version != VERSION) {
throw new TProtocolException("Expected version " + VERSION + " but got " + version);
}
- byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & 0x03);
+ byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS);
int seqid = readVarint32();
String messageName = readString();
return new TMessage(messageName, type, seqid);
diff --git a/lib/nodejs/lib/thrift/protocol.js b/lib/nodejs/lib/thrift/protocol.js
index 9bfe268..6c4d9e6 100644
--- a/lib/nodejs/lib/thrift/protocol.js
+++ b/lib/nodejs/lib/thrift/protocol.js
@@ -425,6 +425,13 @@
TCompactProtocol.TYPE_MASK = -32; //1110 0000
/**
+ * Compact Protocol message type bits for ensuring message type bit size.
+ * @readonly
+ * @const {number} TYPE_BITS
+ */
+TCompactProtocol.TYPE_BITS = 7; //0000 0111
+
+/**
* Compact Protocol message type shift amount for combining protocol version and message type in one byte.
* @readonly
* @const {number} TYPE_SHIFT_AMOUNT
@@ -837,7 +844,7 @@
if (version != TCompactProtocol.VERSION_N) {
throw new TProtocolException(BAD_VERSION, "Bad protocol version " + version);
}
- var type = ((versionAndType >> TCompactProtocol.TYPE_SHIFT_AMOUNT) & 0x03);
+ var type = ((versionAndType >> TCompactProtocol.TYPE_SHIFT_AMOUNT) & TCompactProtocol.TYPE_BITS);
//Read SeqId
var seqid = this.readVarint32();
diff --git a/lib/php/lib/Thrift/Protocol/TCompactProtocol.php b/lib/php/lib/Thrift/Protocol/TCompactProtocol.php
index 880da25..337511e 100644
--- a/lib/php/lib/Thrift/Protocol/TCompactProtocol.php
+++ b/lib/php/lib/Thrift/Protocol/TCompactProtocol.php
@@ -61,6 +61,7 @@
const VERSION = 1;
const PROTOCOL_ID = 0x82;
const TYPE_MASK = 0xe0;
+ const TYPE_BITS = 0x07;
const TYPE_SHIFT_AMOUNT = 5;
protected static $ctypes = array(
@@ -381,8 +382,7 @@
}
$verType = 0;
$result += $this->readUByte($verType);
- $type = ($verType & TCompactProtocol::TYPE_MASK) >>
- TCompactProtocol::TYPE_SHIFT_AMOUNT;
+ $type = ($verType >> TCompactProtocol::TYPE_SHIFT_AMOUNT) & TCompactProtocol::TYPE_BITS;
$version = $verType & TCompactProtocol::VERSION_MASK;
if ($version != TCompactProtocol::VERSION) {
throw new TProtocolException('Bad version in TCompact message');
diff --git a/lib/py/src/protocol/TCompactProtocol.py b/lib/py/src/protocol/TCompactProtocol.py
index c34edb8..79deda8 100644
--- a/lib/py/src/protocol/TCompactProtocol.py
+++ b/lib/py/src/protocol/TCompactProtocol.py
@@ -120,6 +120,7 @@
VERSION = 1
VERSION_MASK = 0x1f
TYPE_MASK = 0xe0
+ TYPE_BITS = 0x07
TYPE_SHIFT_AMOUNT = 5
def __init__(self, trans):
@@ -310,7 +311,7 @@
raise TProtocolException(TProtocolException.BAD_VERSION,
'Bad protocol id in the message: %d' % proto_id)
ver_type = self.__readUByte()
- type = (ver_type & self.TYPE_MASK) >> self.TYPE_SHIFT_AMOUNT
+ type = (ver_type >> self.TYPE_SHIFT_AMOUNT) & self.TYPE_BITS
version = ver_type & self.VERSION_MASK
if version != self.VERSION:
raise TProtocolException(TProtocolException.BAD_VERSION,
diff --git a/lib/rb/ext/compact_protocol.c b/lib/rb/ext/compact_protocol.c
index 725d338..c0f46b9 100644
--- a/lib/rb/ext/compact_protocol.c
+++ b/lib/rb/ext/compact_protocol.c
@@ -40,6 +40,7 @@
static int VERSION;
static int VERSION_MASK;
static int TYPE_MASK;
+static int TYPE_BITS;
static int TYPE_SHIFT_AMOUNT;
static int PROTOCOL_ID;
@@ -450,7 +451,7 @@
rb_exc_raise(get_protocol_exception(INT2FIX(-1), rb_str_new2(buf)));
}
- int8_t type = (version_and_type >> TYPE_SHIFT_AMOUNT) & 0x03;
+ int8_t type = (version_and_type >> TYPE_SHIFT_AMOUNT) & TYPE_BITS;
int32_t seqid = read_varint64(self);
VALUE messageName = rb_thrift_compact_proto_read_string(self);
return rb_ary_new3(3, messageName, INT2FIX(type), INT2NUM(seqid));
@@ -570,6 +571,7 @@
VERSION = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("VERSION")));
VERSION_MASK = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("VERSION_MASK")));
TYPE_MASK = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("TYPE_MASK")));
+ TYPE_BITS = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("TYPE_BITS")));
TYPE_SHIFT_AMOUNT = FIX2INT(rb_const_get(thrift_compact_protocol_class, rb_intern("TYPE_SHIFT_AMOUNT")));
PROTOCOL_ID = FIX2INT(rb_const_get(thrift_compact_protocol_class, rb_intern("PROTOCOL_ID")));
diff --git a/lib/rb/lib/thrift/protocol/compact_protocol.rb b/lib/rb/lib/thrift/protocol/compact_protocol.rb
index 07a6792..605eea6 100644
--- a/lib/rb/lib/thrift/protocol/compact_protocol.rb
+++ b/lib/rb/lib/thrift/protocol/compact_protocol.rb
@@ -24,6 +24,7 @@
VERSION = 1
VERSION_MASK = 0x1f
TYPE_MASK = 0xE0
+ TYPE_BITS = 0x07
TYPE_SHIFT_AMOUNT = 5
TSTOP = ["", Types::STOP, 0]
@@ -231,7 +232,7 @@
raise ProtocolException.new("Expected version #{VERSION} but got #{version}");
end
- type = (version_and_type >> TYPE_SHIFT_AMOUNT) & 0x03
+ type = (version_and_type >> TYPE_SHIFT_AMOUNT) & TYPE_BITS
seqid = read_varint32()
messageName = read_string()
[messageName, type, seqid]