summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Geyer <jensg@apache.org>2021-02-25 09:42:52 +0100
committerJens Geyer <jensg@apache.org>2021-03-17 20:42:29 +0100
commit2dcefadba853c9ad0ab5e908894213826ec3b43a (patch)
tree2b5f791d79d67538dbb7001673b43203fecea339
parent62beb6751d3c70f8db8fed4a3bb76e4ff3765c22 (diff)
downloadthrift-2dcefadba853c9ad0ab5e908894213826ec3b43a.tar.gz
THRIFT-5370 Haxe 4 compatibility incl TConfiguration & MAX_MESSAGE_SIZE
Client: haxe Patch: Jens Geyer This closes #2349
-rw-r--r--.gitignore1
-rw-r--r--compiler/cpp/src/thrift/generate/t_haxe_generator.cc409
-rwxr-xr-xconfigure.ac2
-rw-r--r--lib/haxe/README.md51
-rw-r--r--lib/haxe/haxelib.json12
-rw-r--r--lib/haxe/src/org/apache/thrift/Limits.hx4
-rw-r--r--lib/haxe/src/org/apache/thrift/TConfiguration.hx36
-rw-r--r--lib/haxe/src/org/apache/thrift/TException.hx5
-rw-r--r--lib/haxe/src/org/apache/thrift/helper/Int64Map.hx47
-rw-r--r--lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx81
-rw-r--r--lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx88
-rw-r--r--lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx94
-rw-r--r--lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx3
-rw-r--r--lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx6
-rw-r--r--lib/haxe/src/org/apache/thrift/protocol/TProtocolImplBase.hx86
-rw-r--r--lib/haxe/src/org/apache/thrift/protocol/TRecursionTracker.hx48
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/TBufferedTransport.hx36
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/TBufferedTransportFactory.hx2
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/TEndpointTransport.hx95
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/TFramedTransport.hx55
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/TFramedTransportFactory.hx10
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/TFullDuplexHttpClient.hx420
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/THttpClient.hx60
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/TLayeredTransport.hx50
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx13
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/TServerTransport.hx9
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/TSocket.hx37
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/TStreamTransport.hx9
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/TTransport.hx6
-rw-r--r--lib/haxe/src/org/apache/thrift/transport/TWrappingServerTransport.hx30
-rw-r--r--test/haxe/Makefile.am16
-rw-r--r--test/haxe/TestClientServer.hxproj4
-rw-r--r--test/haxe/make_all.bat17
-rw-r--r--test/haxe/php-web-server.hxml4
-rw-r--r--test/haxe/php.hxml4
-rw-r--r--test/haxe/src/Arguments.hx2
-rw-r--r--test/haxe/src/TestClient.hx2
-rw-r--r--test/haxe/src/TestServer.hx26
-rw-r--r--test/haxe/src/TestServerHandler.hx4
-rw-r--r--tutorial/haxe/Tutorial.hxproj4
-rw-r--r--tutorial/haxe/php-web-server.hxml2
-rw-r--r--tutorial/haxe/php.hxml2
-rw-r--r--tutorial/haxe/src/CalculatorHandler.hx2
-rw-r--r--tutorial/haxe/src/Main.hx35
44 files changed, 1172 insertions, 757 deletions
diff --git a/.gitignore b/.gitignore
index 603838fca..c34d9f643 100644
--- a/.gitignore
+++ b/.gitignore
@@ -355,6 +355,7 @@ project.lock.json
/test/go/src/gen/
/test/go/src/thrift
/test/haxe/bin
+/test/haxe/.buildtemp
/test/hs/TestClient
/test/hs/TestServer
/test/php/php_ext_dir/
diff --git a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
index 725a5344e..9f8e9468d 100644
--- a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
@@ -52,12 +52,11 @@ public:
(void)option_string;
std::map<std::string, std::string>::const_iterator iter;
- callbacks_ = false;
rtti_ = false;
buildmacro_ = "";
for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
if( iter->first.compare("callbacks") == 0) {
- callbacks_ = true;
+ printf("Hint: The 'callbacks' option is no longer necessary.\n");
} else if( iter->first.compare("rtti") == 0) {
rtti_ = true;
} else if( iter->first.compare("buildmacro") == 0) {
@@ -115,7 +114,7 @@ public:
void generate_haxe_validator(std::ostream& out, t_struct* tstruct);
void generate_haxe_struct_result_writer(std::ostream& out, t_struct* tstruct);
void generate_haxe_struct_writer(std::ostream& out, t_struct* tstruct);
- void generate_haxe_struct_tostring(std::ostream& out, t_struct* tstruct);
+ void generate_haxe_struct_tostring(std::ostream& out, t_struct* tstruct, bool is_override);
void generate_haxe_meta_data_map(std::ostream& out, t_struct* tstruct);
void generate_field_value_meta_data(std::ostream& out, t_type* type);
std::string get_haxe_type_string(t_type* type);
@@ -138,12 +137,12 @@ public:
void generate_isset_set(ostream& out, t_field* field);
// removed std::string isset_field_id(t_field* field);
- void generate_service_interface(t_service* tservice);
+ void generate_service_interface(t_service* tservice, bool combined);
void generate_service_helpers(t_service* tservice);
void generate_service_client(t_service* tservice);
void generate_service_server(t_service* tservice);
void generate_process_function(t_service* tservice, t_function* tfunction);
- void generate_service_method_signature(t_function* tfunction, bool is_interface);
+ void generate_service_method_signature(t_function* tfunction, bool is_interface, bool combined);
/**
* Serialization constructs
@@ -186,13 +185,13 @@ public:
std::string type_name(t_type* ttype, bool in_container = false, bool in_init = false);
std::string base_type_name(t_base_type* tbase, bool in_container = false);
std::string declare_field(t_field* tfield, bool init = false);
- std::string function_signature_callback(t_function* tfunction);
+ std::string function_signature_combined(t_function* tfunction);
std::string function_signature_normal(t_function* tfunction);
std::string argument_list(t_struct* tstruct);
std::string type_to_enum(t_type* ttype);
std::string get_enum_class_name(t_type* type) override;
string generate_service_method_onsuccess(t_function* tfunction, bool as_type, bool omit_name);
- void generate_service_method_signature_callback(t_function* tfunction, bool is_interface);
+ void generate_service_method_signature_combined(t_function* tfunction, bool is_interface);
void generate_service_method_signature_normal(t_function* tfunction, bool is_interface);
bool type_can_be_null(t_type* ttype) {
@@ -220,7 +219,6 @@ public:
std::string constant_name(std::string name);
private:
- bool callbacks_;
bool rtti_;
string buildmacro_;
@@ -290,10 +288,17 @@ string t_haxe_generator::haxe_package() {
* @return List of imports for haxe types that are used in here
*/
string t_haxe_generator::haxe_type_imports() {
- return string() + "import org.apache.thrift.helper.*;\n" + "import haxe.io.Bytes;\n"
- + "import haxe.ds.IntMap;\n" + "import haxe.ds.StringMap;\n"
- + "import haxe.ds.ObjectMap;\n" + "\n" + "#if flash\n"
- + "import flash.errors.ArgumentError;\n" + "#end\n" + "\n";
+ return string()
+ + "import org.apache.thrift.helper.*;\n"
+ + "import haxe.io.Bytes;\n"
+ + "import haxe.ds.IntMap;\n"
+ + "import haxe.ds.StringMap;\n"
+ + "import haxe.ds.ObjectMap;\n"
+ + "\n"
+ + "#if flash\n"
+ + "import flash.errors.ArgumentError;\n"
+ + "#end\n"
+ + "\n";
}
/**
@@ -302,8 +307,11 @@ string t_haxe_generator::haxe_type_imports() {
* @return List of imports necessary for thrift
*/
string t_haxe_generator::haxe_thrift_imports() {
- return string() + "import org.apache.thrift.*;\n" + "import org.apache.thrift.meta_data.*;\n"
- + "import org.apache.thrift.protocol.*;\n" + "\n";
+ return string()
+ + "import org.apache.thrift.*;\n"
+ + "import org.apache.thrift.meta_data.*;\n"
+ + "import org.apache.thrift.protocol.*;\n"
+ + "\n";
}
/**
@@ -348,8 +356,7 @@ string t_haxe_generator::haxe_thrift_gen_imports(t_service* tservice) {
string package = program->get_namespace("haxe");
if (!package.empty()) {
if (imports.find(package + "." + (*f_iter)->get_returntype()->get_name()) == string::npos) {
- imports.append("import " + package + "." + (*f_iter)->get_returntype()->get_name()
- + ";\n");
+ imports.append("import " + package + "." + (*f_iter)->get_returntype()->get_name()+ ";\n");
}
}
}
@@ -718,10 +725,8 @@ void t_haxe_generator::generate_haxe_struct_definition(ostream& out,
if (is_exception) {
out << "extends TException ";
}
- out << "implements TBase ";
-
- scope_up(out);
- indent(out) << endl;
+ out << "implements TBase {" << endl << endl;
+ indent_up();
indent(out) << "static var STRUCT_DESC = { new TStruct(\"" << tstruct->get_name() << "\"); };"
<< endl;
@@ -806,7 +811,7 @@ void t_haxe_generator::generate_haxe_struct_definition(ostream& out,
} else {
generate_haxe_struct_writer(out, tstruct);
}
- generate_haxe_struct_tostring(out, tstruct);
+ generate_haxe_struct_tostring(out, tstruct, is_exception);
generate_haxe_validator(out, tstruct);
scope_down(out);
out << endl;
@@ -1272,9 +1277,12 @@ void t_haxe_generator::generate_property_getters_setters(ostream& out, t_struct*
*
* @param tstruct The struct definition
*/
-void t_haxe_generator::generate_haxe_struct_tostring(ostream& out, t_struct* tstruct) {
- out << indent() << "public "
- << "function toString() : String {" << endl;
+void t_haxe_generator::generate_haxe_struct_tostring(ostream& out, t_struct* tstruct, bool is_override) {
+ out << indent() << "public ";
+ if( is_override) {
+ out << "override ";
+ }
+ out << "function toString() : String {" << endl;
indent_up();
out << indent() << "var ret : String = \"" << tstruct->get_name() << "(\";" << endl;
@@ -1474,8 +1482,8 @@ void t_haxe_generator::generate_field_value_meta_data(std::ostream& out, t_type*
* @param tservice The service definition
*/
void t_haxe_generator::generate_service(t_service* tservice) {
- // Make interface file
- string f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + ".hx";
+ // Make service interface file with only "normal" calls
+ string f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + "_service.hx";
f_service_.open(f_service_name.c_str());
f_service_ << autogen_comment() << haxe_package() << ";" << endl;
@@ -1487,14 +1495,35 @@ void t_haxe_generator::generate_service(t_service* tservice) {
t_type* parent = tservice->get_extends();
string parent_namespace = parent->get_program()->get_namespace("haxe");
if (!parent_namespace.empty() && parent_namespace != package_name_) {
- f_service_ << "import " << type_name(parent) << ";" << endl;
+ f_service_ << "import " << type_name(parent) << "_service;" << endl;
}
}
f_service_ << endl;
- generate_service_interface(tservice);
+ generate_service_interface(tservice,false);
+ f_service_.close();
+ // Client interface file with dual suppport ("normal" and "callback" style)
+ f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + ".hx";
+ f_service_.open(f_service_name.c_str());
+
+ f_service_ << autogen_comment() << haxe_package() << ";" << endl;
+
+ f_service_ << endl << haxe_type_imports() << haxe_thrift_imports()
+ << haxe_thrift_gen_imports(tservice);
+
+ if (tservice->get_extends() != nullptr) {
+ t_type* parent = tservice->get_extends();
+ string parent_namespace = parent->get_program()->get_namespace("haxe");
+ if (!parent_namespace.empty() && parent_namespace != package_name_) {
+ f_service_ << "import " << type_name(parent) << ";" << endl;
+ }
+ }
+
+ f_service_ << endl;
+
+ generate_service_interface(tservice,true);
f_service_.close();
// Now make the implementation/client file
@@ -1515,7 +1544,6 @@ void t_haxe_generator::generate_service(t_service* tservice) {
f_service_ << endl;
generate_service_client(tservice);
-
f_service_.close();
// Now make the helper class files
@@ -1525,18 +1553,20 @@ void t_haxe_generator::generate_service(t_service* tservice) {
f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + "Processor.hx";
f_service_.open(f_service_name.c_str());
- f_service_ << autogen_comment() << haxe_package() << ";" << endl << endl << haxe_type_imports()
- << haxe_thrift_imports() << haxe_thrift_gen_imports(tservice) << endl;
+ f_service_ << autogen_comment() << haxe_package() << ";" << endl
+ << endl
+ << haxe_type_imports()
+ << haxe_thrift_imports()
+ << haxe_thrift_gen_imports(tservice)
+ << endl;
if (!package_name_.empty()) {
f_service_ << "import " << package_name_ << ".*;" << endl;
- f_service_ << "import " << package_name_ << "." << get_cap_name(service_name_).c_str()
- << "Impl;" << endl;
+ f_service_ << "import " << package_name_ << "." << get_cap_name(service_name_).c_str() << "Impl;" << endl;
f_service_ << endl;
}
generate_service_server(tservice);
-
f_service_.close();
}
@@ -1580,9 +1610,9 @@ string t_haxe_generator::generate_service_method_onsuccess(t_function* tfunction
*
* @param tfunction The service function to generate code for.
*/
-void t_haxe_generator::generate_service_method_signature(t_function* tfunction, bool is_interface) {
- if (callbacks_) {
- generate_service_method_signature_callback(tfunction, is_interface);
+void t_haxe_generator::generate_service_method_signature(t_function* tfunction, bool is_interface, bool combined) {
+ if( combined) {
+ generate_service_method_signature_combined(tfunction, is_interface);
} else {
generate_service_method_signature_normal(tfunction, is_interface);
}
@@ -1607,7 +1637,7 @@ void t_haxe_generator::generate_service_method_signature_normal(t_function* tfun
*
* @param tfunction The service function to generate code for.
*/
-void t_haxe_generator::generate_service_method_signature_callback(t_function* tfunction,
+void t_haxe_generator::generate_service_method_signature_combined(t_function* tfunction,
bool is_interface) {
if (!tfunction->is_oneway()) {
std::string on_success_impl = generate_service_method_onsuccess(tfunction, false, false);
@@ -1616,9 +1646,9 @@ void t_haxe_generator::generate_service_method_signature_callback(t_function* tf
}
if (is_interface) {
- indent(f_service_) << function_signature_callback(tfunction) << ";" << endl << endl;
+ indent(f_service_) << function_signature_combined(tfunction) << ";" << endl << endl;
} else {
- indent(f_service_) << "public " << function_signature_callback(tfunction) << " {" << endl;
+ indent(f_service_) << "public " << function_signature_combined(tfunction) << " {" << endl;
}
}
@@ -1627,24 +1657,26 @@ void t_haxe_generator::generate_service_method_signature_callback(t_function* tf
*
* @param tservice The service to generate a header definition for
*/
-void t_haxe_generator::generate_service_interface(t_service* tservice) {
+void t_haxe_generator::generate_service_interface(t_service* tservice, bool combined) {
+ string cbk_postfix = combined ? "" : "_service";
+
string extends_iface = "";
if (tservice->get_extends() != nullptr) {
- extends_iface = " extends " + tservice->get_extends()->get_name();
+ extends_iface = " extends " + tservice->get_extends()->get_name() + cbk_postfix;
}
+ vector<t_function*> functions = tservice->get_functions();
+ vector<t_function*>::iterator f_iter;
+
generate_haxe_doc(f_service_, tservice);
- // generate_rtti_decoration(f_service_); - not yet, because of
- // https://github.com/HaxeFoundation/haxe/issues/3626
+ generate_rtti_decoration(f_service_);
generate_macro_decoration(f_service_);
- f_service_ << indent() << "interface " << get_cap_name(service_name_) << extends_iface << " {"
+ f_service_ << indent() << "interface " << get_cap_name(service_name_) << cbk_postfix << extends_iface << " {"
<< endl << endl;
indent_up();
- vector<t_function*> functions = tservice->get_functions();
- vector<t_function*>::iterator f_iter;
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
generate_haxe_doc(f_service_, *f_iter);
- generate_service_method_signature(*f_iter, true);
+ generate_service_method_signature(*f_iter, true, combined);
}
indent_down();
f_service_ << indent() << "}" << endl << endl;
@@ -1729,7 +1761,7 @@ void t_haxe_generator::generate_service_client(t_service* tservice) {
string funname = (*f_iter)->get_name();
// Open function
- generate_service_method_signature(*f_iter, false);
+ generate_service_method_signature(*f_iter, false, true);
indent_up();
@@ -1741,21 +1773,23 @@ void t_haxe_generator::generate_service_client(t_service* tservice) {
const vector<t_field*>& fields = arg_struct->get_members();
// Serialize the request
+ string args = tmp("args");
string calltype = (*f_iter)->is_oneway() ? "ONEWAY" : "CALL";
f_service_ << indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname
<< "\", TMessageType." << calltype << ", seqid_));" << endl << indent()
- << "var args : " << argsname << " = new " << argsname << "();" << endl;
+ << "var " << args << " : " << argsname << " = new " << argsname << "();" << endl;
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
- f_service_ << indent() << "args." << (*fld_iter)->get_name() << " = "
+ f_service_ << indent() << args << "." << (*fld_iter)->get_name() << " = "
<< (*fld_iter)->get_name() << ";" << endl;
}
- f_service_ << indent() << "args.write(oprot_);" << endl << indent()
+ f_service_ << indent() << args << ".write(oprot_);" << endl << indent()
<< "oprot_.writeMessageEnd();" << endl;
+ string retval = tmp("retval");
if (!((*f_iter)->is_oneway() || (*f_iter)->get_returntype()->is_void())) {
- f_service_ << indent() << "var retval : " << type_name((*f_iter)->get_returntype()) << ";"
+ f_service_ << indent() << "var " << retval << " : " << type_name((*f_iter)->get_returntype()) << ";"
<< endl;
}
@@ -1764,109 +1798,108 @@ void t_haxe_generator::generate_service_client(t_service* tservice) {
} else {
indent(f_service_) << "oprot_.getTransport().flush(function(error:Dynamic) : Void {" << endl;
indent_up();
- if (callbacks_) {
- indent(f_service_) << "try {" << endl;
- indent_up();
- }
+ indent(f_service_) << "try {" << endl;
+ indent_up();
+ string appex = tmp("appex");
+ indent(f_service_) << "var " << appex << " : TApplicationException;" << endl;
string resultname = get_cap_name((*f_iter)->get_name() + "_result");
indent(f_service_) << "if (error != null) {" << endl;
indent_up();
- if (callbacks_) {
- indent(f_service_) << "if (onError != null) onError(error);" << endl;
- indent(f_service_) << "return;" << endl;
- } else {
- indent(f_service_) << "throw error;" << endl;
- }
+ indent(f_service_) << "if (onError == null)" << endl;
+ indent_up();
+ indent(f_service_) << "throw error;" << endl;
indent_down();
- indent(f_service_) << "}" << endl;
- indent(f_service_) << "var msg : TMessage = iprot_.readMessageBegin();" << endl;
- indent(f_service_) << "if (msg.type == TMessageType.EXCEPTION) {" << endl;
+ indent(f_service_) << "onError(error);" << endl;
+ indent(f_service_) << "return;" << endl;
+ indent_down();
+ indent(f_service_) << "}" << endl << endl;
+ string msg = tmp("msg");
+ indent(f_service_) << "var " << msg << " : TMessage = iprot_.readMessageBegin();" << endl;
+ indent(f_service_) << "if (" << msg << ".type == TMessageType.EXCEPTION) {" << endl;
indent_up();
- indent(f_service_) << "var x = TApplicationException.read(iprot_);" << endl;
+ indent(f_service_) << appex << " = TApplicationException.read(iprot_);" << endl;
indent(f_service_) << "iprot_.readMessageEnd();" << endl;
- if (callbacks_) {
- indent(f_service_) << "if (onError != null) onError(x);" << endl;
- indent(f_service_) << "return;" << endl;
- } else {
- indent(f_service_) << "throw x;" << endl;
- }
+ indent(f_service_) << "if (onError == null)" << endl;
+ indent_up();
+ indent(f_service_) << "throw " << appex << ";" << endl;
indent_down();
- indent(f_service_) << "}" << endl;
- indent(f_service_) << "var result : " << resultname << " = new " << resultname << "();"
- << endl;
- indent(f_service_) << "result.read(iprot_);" << endl;
+ indent(f_service_) << "onError(" << appex << ");" << endl;
+ indent(f_service_) << "return;" << endl;
+ indent_down();
+ indent(f_service_) << "}" << endl << endl;
+ string result = tmp("result");
+ indent(f_service_) << "var " << result << " : " << resultname << " = new " << resultname << "();" << endl;
+ indent(f_service_) << "" << result << ".read(iprot_);" << endl;
indent(f_service_) << "iprot_.readMessageEnd();" << endl;
// Careful, only return _result if not a void function
if (!(*f_iter)->get_returntype()->is_void()) {
- indent(f_service_) << "if (result." << generate_isset_check("success") << ") {" << endl;
+ indent(f_service_) << "if (" << result << "." << generate_isset_check("success") << ") {" << endl;
indent_up();
- if (callbacks_) {
- indent(f_service_) << "if (onSuccess != null) onSuccess(result.success);" << endl;
- indent(f_service_) << "return;" << endl;
- } else {
- indent(f_service_) << "retval = result.success;" << endl;
- indent(f_service_) << "return;" << endl;
- }
+ indent(f_service_) << "if (onSuccess != null)" << endl;
+ indent_up();
+ indent(f_service_) << "onSuccess(" << result << ".success);" << endl;
indent_down();
- indent(f_service_) << "}" << endl;
+ indent(f_service_) << retval << " = " << result << ".success;" << endl;
+ indent(f_service_) << "return;" << endl;
+ indent_down();
+ indent(f_service_) << "}" << endl << endl;
}
t_struct* xs = (*f_iter)->get_xceptions();
const std::vector<t_field*>& xceptions = xs->get_members();
vector<t_field*>::const_iterator x_iter;
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
- indent(f_service_) << "if (result." << (*x_iter)->get_name() << " != null) {" << endl;
+ indent(f_service_) << "if (" << result << "." << (*x_iter)->get_name() << " != null) {" << endl;
indent_up();
- if (callbacks_) {
- indent(f_service_) << "if (onError != null) onError(result." << (*x_iter)->get_name()
- << ");" << endl;
- indent(f_service_) << "return;" << endl;
- } else {
- indent(f_service_) << "throw result." << (*x_iter)->get_name() << ";" << endl;
- }
+ indent(f_service_) << "if (onError == null)" << endl;
+ indent_up();
+ indent(f_service_) << "throw " << result << "." << (*x_iter)->get_name() << ";" << endl;
+ indent_down();
+ indent(f_service_) << "onError(" << result << "." << (*x_iter)->get_name() << ");" << endl;
+ indent(f_service_) << "return;" << endl;
indent_down();
- indent(f_service_) << "}" << endl;
+ indent(f_service_) << "}" << endl << endl;
}
// If you get here it's an exception, unless a void function
if ((*f_iter)->get_returntype()->is_void()) {
- if (callbacks_) {
- indent(f_service_) << "if (onSuccess != null) onSuccess();" << endl;
- }
+ indent(f_service_) << "if (onSuccess != null)" << endl;
+ indent_up();
+ indent(f_service_) << "onSuccess();" << endl;
+ indent_down();
indent(f_service_) << "return;" << endl;
} else {
- if (callbacks_) {
- indent(f_service_) << "if (onError != null)" << endl;
- indent_up();
- indent(f_service_)
- << "onError( new TApplicationException(TApplicationException.MISSING_RESULT," << endl;
- indent(f_service_) << " \"" << (*f_iter)->get_name()
- << " failed: unknown result\"));" << endl;
- indent_down();
- } else {
- indent(f_service_)
- << "throw new TApplicationException(TApplicationException.MISSING_RESULT," << endl;
- indent(f_service_) << " \"" << (*f_iter)->get_name()
- << " failed: unknown result\");" << endl;
- }
- }
-
- if (callbacks_) {
- indent_down();
- indent(f_service_) << "} catch( e : TException) {" << endl;
+ indent(f_service_) << appex << " = new TApplicationException("
+ << "TApplicationException.MISSING_RESULT,"
+ << "\"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl;
+ indent(f_service_) << "if (onError == null)" << endl;
indent_up();
- indent(f_service_) << "if (onError != null) onError(e);" << endl;
+ indent(f_service_) << "throw " << appex << ";" << endl;
indent_down();
- indent(f_service_) << "}" << endl;
+ indent(f_service_) << "onError(" << appex << ");" << endl;
+ indent(f_service_) << "return;" << endl;
}
indent_down();
- indent(f_service_) << "});" << endl;
+ indent(f_service_) << endl;
+ indent(f_service_) << "} catch( e : TException) {" << endl;
+ indent_up();
+ indent(f_service_) << "if (onError == null)" << endl;
+ indent_up();
+ indent(f_service_) << "throw e;" << endl;
+ indent_down();
+ indent(f_service_) << "onError(e);" << endl;
+ indent(f_service_) << "return;" << endl;
+ indent_down();
+ indent(f_service_) << "}" << endl;
+
+ indent_down();
+ indent(f_service_) << "});" << endl << endl;
}
if (!((*f_iter)->is_oneway() || (*f_iter)->get_returntype()->is_void())) {
- f_service_ << indent() << "return retval;" << endl;
+ f_service_ << indent() << "return " << retval << ";" << endl;
}
// Close function
@@ -1904,7 +1937,7 @@ void t_haxe_generator::generate_service_server(t_service* tservice) {
indent_up();
f_service_ << indent() << "private var " << get_cap_name(service_name_)
- << "_iface_ : " << get_cap_name(service_name_) << ";" << endl;
+ << "_iface_ : " << get_cap_name(service_name_) << "_service;" << endl;
if (extends.empty()) {
f_service_ << indent()
@@ -1914,7 +1947,7 @@ void t_haxe_generator::generate_service_server(t_service* tservice) {
f_service_ << endl;
- indent(f_service_) << "public function new( iface : " << get_cap_name(service_name_) << ")"
+ indent(f_service_) << "public function new( iface : " << get_cap_name(service_name_) << "_service)"
<< endl;
scope_up(f_service_);
if (!extends.empty()) {
@@ -1943,20 +1976,20 @@ void t_haxe_generator::generate_service_server(t_service* tservice) {
f_service_ << indent() << "var msg : TMessage = iprot.readMessageBegin();" << endl;
// TODO(mcslee): validate message, was the seqid etc. legit?
- // AS- If all method is oneway:
- // do you have an oprot?
- // do you you need nullcheck?
+
f_service_
- << indent() << "var fn = PROCESS_MAP.get(msg.name);" << endl << indent()
- << "if (fn == null) {" << endl << indent() << " TProtocolUtil.skip(iprot, TType.STRUCT);"
- << endl << indent() << " iprot.readMessageEnd();" << endl << indent()
- << " var x = new TApplicationException(TApplicationException.UNKNOWN_METHOD, \"Invalid "
- "method name: '\"+msg.name+\"'\");" << endl << indent()
- << " oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));"
- << endl << indent() << " x.write(oprot);" << endl << indent() << " oprot.writeMessageEnd();"
- << endl << indent() << " oprot.getTransport().flush();" << endl << indent()
- << " return true;" << endl << indent() << "}" << endl << indent()
- << "fn( msg.seqid, iprot, oprot);" << endl;
+ << indent() << "var fn = PROCESS_MAP.get(msg.name);" << endl
+ << indent() << "if (fn == null) {" << endl
+ << indent() << " TProtocolUtil.skip(iprot, TType.STRUCT);" << endl
+ << indent() << " iprot.readMessageEnd();" << endl
+ << indent() << " var appex = new TApplicationException(TApplicationException.UNKNOWN_METHOD, "
+ << "\"Invalid method name: '\"+msg.name+\"'\");" << endl
+ << indent() << " oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));" << endl
+ << indent() << " appex.write(oprot);" << endl << indent() << " oprot.writeMessageEnd();" << endl
+ << indent() << " oprot.getTransport().flush();" << endl
+ << indent() << " return true;" << endl << indent() << "}" << endl
+ << indent() << "fn( msg.seqid, iprot, oprot);" << endl
+ ;
f_service_ << indent() << "return true;" << endl;
@@ -2029,84 +2062,36 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function
// Declare result for non oneway function
if (!tfunction->is_oneway()) {
- f_service_ << indent() << "var result : " << resultname << " = new " << resultname << "();"
- << endl;
+ f_service_ << indent() << "var result : " << resultname << " = new " << resultname << "();" << endl;
}
// Try block for any function to catch (defined or undefined) exceptions
f_service_ << indent() << "try {" << endl;
indent_up();
- if (callbacks_) {
- // callback function style onError/onSuccess
- // Generate the function call
- t_struct* arg_struct = tfunction->get_arglist();
- const std::vector<t_field*>& fields = arg_struct->get_members();
- vector<t_field*>::const_iterator f_iter;
+ // normal function():result style
- f_service_ << indent();
- f_service_ << get_cap_name(service_name_) << "_iface_." << tfunction->get_name() << "(";
- bool first = true;
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- if (first) {
- first = false;
- } else {
- f_service_ << ", ";
- }
- f_service_ << "args." << (*f_iter)->get_name();
- }
+ // Generate the function call
+ t_struct* arg_struct = tfunction->get_arglist();
+ const std::vector<t_field*>& fields = arg_struct->get_members();
+ vector<t_field*>::const_iterator f_iter;
- if (tfunction->is_oneway()) {
- f_service_ << ");" << endl;
+ f_service_ << indent();
+ if (!(tfunction->is_oneway() || tfunction->get_returntype()->is_void())) {
+ f_service_ << "result.success = ";
+ }
+ f_service_ << get_cap_name(service_name_) << "_iface_." << tfunction->get_name() << "(";
+ bool first = true;
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+ if (first) {
+ first = false;
} else {
- if (first) {
- first = false;
- } else {
- f_service_ << ", ";
- }
- string on_success = generate_service_method_onsuccess(tfunction, false, true);
- indent_up();
- f_service_ << endl;
- indent(f_service_) << "null, // errors are thrown by the handler" << endl;
- if (tfunction->get_returntype()->is_void()) {
- indent(f_service_) << "null); // no retval" << endl;
- } else {
- indent(f_service_) << "function" << on_success.c_str() << " {" << endl;
- if (!tfunction->get_returntype()->is_void()) {
- indent_up();
- indent(f_service_) << "result.success = retval;" << endl;
- indent_down();
- }
- indent(f_service_) << "});" << endl;
- }
- indent_down();
- }
-
- } else {
- // normal function():result style
-
- // Generate the function call
- t_struct* arg_struct = tfunction->get_arglist();
- const std::vector<t_field*>& fields = arg_struct->get_members();
- vector<t_field*>::const_iterator f_iter;
-
- f_service_ << indent();
- if (!(tfunction->is_oneway() || tfunction->get_returntype()->is_void())) {
- f_service_ << "result.success = ";
+ f_service_ << ", ";
}
- f_service_ << get_cap_name(service_name_) << "_iface_." << tfunction->get_name() << "(";
- bool first = true;
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- if (first) {
- first = false;
- } else {
- f_service_ << ", ";
- }
- f_service_ << "args." << (*f_iter)->get_name();
- }
- f_service_ << ");" << endl;
+ f_service_ << "args." << (*f_iter)->get_name();
}
+ f_service_ << ");" << endl;
indent_down();
f_service_ << indent() << "}";
@@ -2128,16 +2113,16 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function
}
// always catch all exceptions to prevent from service denial
+ string appex = tmp("appex");
f_service_ << " catch (th : Dynamic) {" << endl;
indent_up();
- indent(f_service_) << "trace(\"Internal error processing " << tfunction->get_name() << "\", th);"
- << endl;
+ indent(f_service_) << "trace(\"Internal error processing " << tfunction->get_name() << "\", th);" << endl;
if (!tfunction->is_oneway()) {
- indent(f_service_) << "var x = new TApplicationException(TApplicationException.INTERNAL_ERROR, "
+ indent(f_service_) << "var appex = new TApplicationException(TApplicationException.INTERNAL_ERROR, "
"\"Internal error processing " << tfunction->get_name() << "\");" << endl;
indent(f_service_) << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name()
<< "\", TMessageType.EXCEPTION, seqid));" << endl;
- indent(f_service_) << "x.write(oprot);" << endl;
+ indent(f_service_) << "appex.write(oprot);" << endl;
indent(f_service_) << "oprot.writeMessageEnd();" << endl;
indent(f_service_) << "oprot.getTransport().flush();" << endl;
}
@@ -2702,7 +2687,7 @@ string t_haxe_generator::declare_field(t_field* tfield, bool init) {
* @param tfunction Function definition
* @return String of rendered function definition
*/
-string t_haxe_generator::function_signature_callback(t_function* tfunction) {
+string t_haxe_generator::function_signature_combined(t_function* tfunction) {
std::string on_error_success = "onError : Dynamic->Void = null, "
+ generate_service_method_onsuccess(tfunction, true, false);
@@ -2714,7 +2699,14 @@ string t_haxe_generator::function_signature_callback(t_function* tfunction) {
arguments += on_error_success; //"onError : Function, onSuccess : Function";
}
- std::string result = "function " + tfunction->get_name() + "(" + arguments + ") : Void";
+ std::string resulttype;
+ if (tfunction->is_oneway() || tfunction->get_returntype()->is_void()) {
+ resulttype = "Void";
+ } else {
+ resulttype = type_name(tfunction->get_returntype());
+ }
+
+ std::string result = "function " + tfunction->get_name() + "(" + arguments + ") : "+resulttype;
return result;
}
@@ -2975,7 +2967,6 @@ std::string t_haxe_generator::get_enum_class_name(t_type* type) {
THRIFT_REGISTER_GENERATOR(
haxe,
"Haxe",
- " callbacks Use onError()/onSuccess() callbacks for service methods\n"
" rtti Enable @:rtti for generated classes and interfaces\n"
" buildmacro=my.macros.Class.method(args)\n"
" Add @:build macro calls to generated classes and interfaces\n")
diff --git a/configure.ac b/configure.ac
index 98327f43b..2d6d62ba2 100755
--- a/configure.ac
+++ b/configure.ac
@@ -467,7 +467,7 @@ AX_THRIFT_LIB(haxe, [Haxe], yes)
if test "$with_haxe" = "yes"; then
AC_PATH_PROG([HAXE], [haxe])
if [[ -x "$HAXE" ]] ; then
- AX_PROG_HAXE_VERSION( [3.1.3], have_haxe="yes", have_haxe="no")
+ AX_PROG_HAXE_VERSION( [4.2.1], have_haxe="yes", have_haxe="no")
fi
fi
AM_CONDITIONAL(WITH_HAXE, [test "$have_haxe" = "yes"])
diff --git a/lib/haxe/README.md b/lib/haxe/README.md
index c9f74b578..1f09c2c79 100644
--- a/lib/haxe/README.md
+++ b/lib/haxe/README.md
@@ -26,16 +26,14 @@ Using Thrift with Haxe
Haxe setup
---------------
-Thrift requires Haxe 3.1.3. Installers for Windows and OSX
+Thrift requires Haxe 4.2.1. Installers for Windows and OSX
platforms are available at `http://haxe.org/download`.
Depending on the desired targets, you may have to install the appropriate HaxeLibs
-after installing Haxe itself. For example, if you plan to target C#, Java and C++,
-enter the following commands after installing Haxe:
+after installing Haxe itself. For example, if you plan to target C++, enter the
+following command after installing Haxe:
haxelib install hxcpp
- haxelib install hxjava
- haxelib install hxcs
For other targets, please consult the Haxe documentation whether or not any additional
target libraries need to be installed and how to achieve this.
@@ -66,12 +64,12 @@ or
Thrift Haxe bindings
-------------------
-Thrift Haxe bindings can be set up via the `haxelib` tool
-either from the official ASF repo, or via the github mirror.
+Thrift Haxe bindings can be set up via the `haxelib` tool as usual.
+Alternatively, the "github" method can be used.
-- To set up any **stable version**, choose the appropriate branch (e.g. `0.12.0`):
+- To set up any **stable version**, choose the appropriate branch (e.g. `0.14.1`):
- - `haxelib git thrift https://github.com/apache/thrift.git 0.12.0 lib/haxe`
+ - `haxelib git thrift https://github.com/apache/thrift.git 0.14.1 lib/haxe`
- To set up the current **development version**, use the `master` branch:
@@ -85,35 +83,24 @@ or build from source, depending on your operating system. Appropriate
downloads and more information can be found at http://thrift.apache.org
To get started, visit the /tutorial/haxe and /test/haxe dirs for examples.
-If you are using HIDE or the FlashDevelop IDE, you'll find appropriate
-project files in these folders.
+If you are using the HaxeDevelop IDE, you'll find appropriate project files
+in these folders.
-Current status
+Breaking changes
========================
-- tested with Haxe C++ target
-- tested with Haxe PHP target (console/web server, binary protocols)
-- transports: Socket, HTTP (servers run inside PHP server/PHP target only), Stream
-- protocols: Binary, JSON, Multiplex, Compact
-- tutorial client and server available
-- cross-test client and server available
+This version requires Haxe 4 and cannot be used with earlier versions.
+It is recommended to clear out all gen-haxe contents once before switching
+to the new version. Otherwise you may run into troubles with leftovers from
+previous versions.
-Further developments
-========================
-- improve to work with C#, Java and JavaScript Haxe/OpenFL targets
-- improve to work with more (ideally all) Haxe/OpenFL targets
-- add HTTP server, update tutorial and tests accordingly
-
-
-Known restrictions
-========================
-
-Although designed with maximum portability in mind, for technical reasons some platforms
-may only support parts of the library, or not be compatible at all.
+The compiler option ```callbacks``` is now obsolete. The compiler will always
+generate a dual interface (i.e. with optional callback style) for use on the
+client side, plus a new ```_service``` interface to be used for server
+implementations. Consequentially, your client and server implementations will
+need some manual intervention.
-Javascript:
-- tutorial fails to build because of unsupported Sys.args
PHP HTTP Server notes
========================
diff --git a/lib/haxe/haxelib.json b/lib/haxe/haxelib.json
index 14d0dcb79..61448dab5 100644
--- a/lib/haxe/haxelib.json
+++ b/lib/haxe/haxelib.json
@@ -2,11 +2,19 @@
"name": "thrift",
"url" : "http://thrift.apache.org",
"license": "Apache",
- "tags": ["thrift", "rpc", "serialization", "cross", "framework"],
+ "tags": [
+ "thrift",
+ "rpc",
+ "serialization",
+ "cross",
+ "framework"
+ ],
"description": "Haxe bindings for the Apache Thrift RPC and serialization framework",
"version": "0.15.0",
"releasenote": "Licensed under Apache License, Version 2.0. The Apache Thrift compiler needs to be installed separately.",
"contributors": ["ApacheThrift"],
- "dependencies": { },
+ "dependencies": {
+ "crypto": ""
+ },
"classPath": "src"
}
diff --git a/lib/haxe/src/org/apache/thrift/Limits.hx b/lib/haxe/src/org/apache/thrift/Limits.hx
index 44eec3a61..3a7807dbd 100644
--- a/lib/haxe/src/org/apache/thrift/Limits.hx
+++ b/lib/haxe/src/org/apache/thrift/Limits.hx
@@ -23,9 +23,9 @@ class Limits {
// Haxe limits are not fixed values, they depend on the target platform
// For example, neko limits an int to 31 bits instead of 32. So we detect
- // the values once during intialisation in order to
+ // the values once during initialization in order to
// (a) get the right values for the current platform, and
- // (b) prevent us from dependecies to a bunch of defines
+ // (b) prevent us from dependencies to a bunch of defines
public static var I32_MAX = {
var last : Int = 0;
diff --git a/lib/haxe/src/org/apache/thrift/TConfiguration.hx b/lib/haxe/src/org/apache/thrift/TConfiguration.hx
new file mode 100644
index 000000000..c5ec4e561
--- /dev/null
+++ b/lib/haxe/src/org/apache/thrift/TConfiguration.hx
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.thrift;
+
+class TConfiguration
+{
+ public static inline var DEFAULT_MAX_MESSAGE_SIZE = 100 * 1024 * 1024;
+ public static inline var DEFAULT_MAX_FRAME_SIZE = 16384000; // this value is used consistently across all Thrift libraries
+ public static inline var DEFAULT_RECURSION_DEPTH = 64;
+
+ public var MaxMessageSize(default,null) : Int = DEFAULT_MAX_MESSAGE_SIZE;
+ public var MaxFrameSize(default,null) : Int = DEFAULT_MAX_FRAME_SIZE;
+ public var RecursionLimit(default,null) : Int = DEFAULT_RECURSION_DEPTH;
+
+ // TODO(JensG): add connection and i/o timeouts
+
+ public function new() {
+ // CTOR
+ }
+}
+
diff --git a/lib/haxe/src/org/apache/thrift/TException.hx b/lib/haxe/src/org/apache/thrift/TException.hx
index 54fa1ffef..8bd9fcc3f 100644
--- a/lib/haxe/src/org/apache/thrift/TException.hx
+++ b/lib/haxe/src/org/apache/thrift/TException.hx
@@ -32,5 +32,10 @@ class TException {
errorMsg = msg;
}
+ public function toString() : String {
+ var clsname = Type.getClassName( Type.getClass(this));
+ return '${clsname}: ${errorMsg} (code ${errorID})';
+ }
+
}
\ No newline at end of file
diff --git a/lib/haxe/src/org/apache/thrift/helper/Int64Map.hx b/lib/haxe/src/org/apache/thrift/helper/Int64Map.hx
index 8845fd095..a8e735f81 100644
--- a/lib/haxe/src/org/apache/thrift/helper/Int64Map.hx
+++ b/lib/haxe/src/org/apache/thrift/helper/Int64Map.hx
@@ -137,6 +137,17 @@ class Int64Map<T> implements IMap< Int64, T> {
return lomap.exists( GetLowIndex(key));
}
+ public function clear() : Void {
+ SubMaps.clear();
+ }
+
+ public function copy() : IMap< Int64, T> {
+ var retval = new Int64Map<T>();
+ for( key in this.keys())
+ retval.set( key, this.get(key));
+ return retval;
+ }
+
/**
Removes the mapping of `key` and returns true if such a mapping existed,
false otherwise. If `key` is null, the result is unspecified.
@@ -172,6 +183,14 @@ class Int64Map<T> implements IMap< Int64, T> {
}
/**
+ Returns an Iterator over the values of `this` Map.
+ The order of values is undefined.
+ **/
+ public function keyValueIterator() : KeyValueIterator<Int64, T> {
+ return new Int64KeyValueIterator<T>(SubMaps);
+ }
+
+ /**
Returns a String representation of `this` Map.
The exact representation depends on the platform and key-type.
**/
@@ -246,7 +265,7 @@ private class Int64MapIteratorBase<T> {
// internal helper class for Int64Map<T>
// all class with matching methods can be used as iterator (duck typing)
-private class Int64KeyIterator<T>extends Int64MapIteratorBase<T> {
+private class Int64KeyIterator<T> extends Int64MapIteratorBase<T> {
public function new( data : IntMap< IntMap< T>>) : Void {
super(data);
@@ -270,6 +289,32 @@ private class Int64KeyIterator<T>extends Int64MapIteratorBase<T> {
// internal helper class for Int64Map<T>
// all class with matching methods can be used as iterator (duck typing)
+private class Int64KeyValueIterator<T> extends Int64MapIteratorBase<T> {
+
+ public function new( data : IntMap< IntMap< T>>) : Void {
+ super(data);
+ };
+
+ /**
+ Returns the current key/item pair and advances to the next one.
+
+ This method is not required to check hasNext() first. A call to this
+ method while hasNext() is false yields unspecified behavior.
+ **/
+ public function next() : {value:T,key:Int64} {
+ if( ! hasNext())
+ throw "no more elements";
+
+ return {
+ key: Int64.make( CurrentHi, LoIterator.next()),
+ value: SubMaps.get(CurrentHi).get(LoIterator.next())
+ };
+ }
+}
+
+
+// internal helper class for Int64Map<T>
+// all class with matching methods can be used as iterator (duck typing)
private class Int64ValueIterator<T> extends Int64MapIteratorBase<T> {
public function new( data : IntMap< IntMap< T>>) : Void {
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx
index 7ef291c0e..2cc254b5e 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx
@@ -31,7 +31,7 @@ import org.apache.thrift.transport.TTransport;
/**
* Binary protocol implementation for thrift.
*/
-class TBinaryProtocol extends TRecursionTracker implements TProtocol {
+class TBinaryProtocol extends TProtocolImplBase implements TProtocol {
private static var ANONYMOUS_STRUCT:TStruct = new TStruct();
@@ -40,19 +40,14 @@ class TBinaryProtocol extends TRecursionTracker implements TProtocol {
private var strictRead_ : Bool = false;
private var strictWrite_ : Bool = true;
- private var trans_ : TTransport;
/**
* Constructor
*/
- public function new(trans:TTransport, strictRead : Bool=false, strictWrite : Bool=true) {
- trans_ = trans;
- strictRead_ = strictRead;
- strictWrite_ = strictWrite;
- }
-
- public function getTransport():TTransport {
- return trans_;
+ public function new(transport:TTransport, strictRead : Bool = false, strictWrite : Bool = true) {
+ super(transport);
+ strictRead_ = strictRead;
+ strictWrite_ = strictWrite;
}
public function writeMessageBegin(message:TMessage) : Void {
@@ -116,21 +111,21 @@ class TBinaryProtocol extends TRecursionTracker implements TProtocol {
var out = new BytesOutput();
out.bigEndian = true;
out.writeByte(b);
- trans_.write(out.getBytes(), 0, 1);
+ Transport.write(out.getBytes(), 0, 1);
}
public function writeI16(i16 : Int) : Void {
var out = new BytesOutput();
out.bigEndian = true;
out.writeInt16(i16);
- trans_.write(out.getBytes(), 0, 2);
+ Transport.write(out.getBytes(), 0, 2);
}
public function writeI32(i32 : Int) : Void {
var out = new BytesOutput();
out.bigEndian = true;
out.writeInt32(i32);
- trans_.write(out.getBytes(), 0, 4);
+ Transport.write(out.getBytes(), 0, 4);
}
public function writeI64(i64 : haxe.Int64) : Void {
@@ -145,14 +140,14 @@ class TBinaryProtocol extends TRecursionTracker implements TProtocol {
out.writeInt32(i64.high);
out.writeInt32(i64.low);
#end
- trans_.write(out.getBytes(), 0, 8);
+ Transport.write(out.getBytes(), 0, 8);
}
public function writeDouble(dub:Float) : Void {
var out = new BytesOutput();
out.bigEndian = true;
out.writeDouble(dub);
- trans_.write(out.getBytes(), 0, 8);
+ Transport.write(out.getBytes(), 0, 8);
}
public function writeString(str : String) : Void {
@@ -161,12 +156,12 @@ class TBinaryProtocol extends TRecursionTracker implements TProtocol {
out.writeString(str);
var bytes = out.getBytes();
writeI32( bytes.length);
- trans_.write( bytes, 0, bytes.length);
+ Transport.write( bytes, 0, bytes.length);
}
public function writeBinary(bin:Bytes) : Void {
writeI32(bin.length);
- trans_.write(bin, 0, bin.length);
+ Transport.write(bin, 0, bin.length);
}
/**
@@ -210,19 +205,25 @@ class TBinaryProtocol extends TRecursionTracker implements TProtocol {
public function readFieldEnd() : Void {}
public function readMapBegin() : TMap {
- return new TMap(readByte(), readByte(), readI32());
+ var map = new TMap(readByte(), readByte(), readI32());
+ CheckReadBytesAvailableMap(map);
+ return map;
}
public function readMapEnd() : Void {}
public function readListBegin():TList {
- return new TList(readByte(), readI32());
+ var list = new TList(readByte(), readI32());
+ CheckReadBytesAvailableList(list);
+ return list;
}
public function readListEnd() : Void {}
public function readSetBegin() : TSet {
- return new TSet(readByte(), readI32());
+ var set = new TSet(readByte(), readI32());
+ CheckReadBytesAvailableSet(set);
+ return set;
}
public function readSetEnd() : Void {}
@@ -234,7 +235,7 @@ class TBinaryProtocol extends TRecursionTracker implements TProtocol {
public function readByte() : Int {
var buffer = new BytesBuffer();
- var len = trans_.readAll( buffer, 0, 1);
+ var len = Transport.readAll( buffer, 0, 1);
var inp = new BytesInput( buffer.getBytes(), 0, 1);
inp.bigEndian = true;
return inp.readByte();
@@ -242,7 +243,7 @@ class TBinaryProtocol extends TRecursionTracker implements TProtocol {
public function readI16() : Int {
var buffer = new BytesBuffer();
- var len = trans_.readAll( buffer, 0, 2);
+ var len = Transport.readAll( buffer, 0, 2);
var inp = new BytesInput( buffer.getBytes(), 0, 2);
inp.bigEndian = true;
return inp.readInt16();
@@ -250,7 +251,7 @@ class TBinaryProtocol extends TRecursionTracker implements TProtocol {
public function readI32() : Int {
var buffer = new BytesBuffer();
- var len = trans_.readAll( buffer, 0, 4);
+ var len = Transport.readAll( buffer, 0, 4);
var inp = new BytesInput( buffer.getBytes(), 0, 4);
inp.bigEndian = true;
return inp.readInt32();
@@ -258,7 +259,7 @@ class TBinaryProtocol extends TRecursionTracker implements TProtocol {
public function readI64() : haxe.Int64 {
var buffer = new BytesBuffer();
- var len = trans_.readAll( buffer, 0, 8);
+ var len = Transport.readAll( buffer, 0, 8);
var inp = new BytesInput( buffer.getBytes(), 0, 8);
inp.bigEndian = true;
var hi = inp.readInt32();
@@ -268,7 +269,7 @@ class TBinaryProtocol extends TRecursionTracker implements TProtocol {
public function readDouble():Float {
var buffer = new BytesBuffer();
- var len = trans_.readAll( buffer, 0, 8);
+ var len = Transport.readAll( buffer, 0, 8);
var inp = new BytesInput( buffer.getBytes(), 0, 8);
inp.bigEndian = true;
return inp.readDouble();
@@ -279,9 +280,10 @@ class TBinaryProtocol extends TRecursionTracker implements TProtocol {
}
public function readStringBody(len : Int) : String {
+ Transport.CheckReadBytesAvailable(len);
if( len > 0) {
var buffer = new BytesBuffer();
- trans_.readAll( buffer, 0, len);
+ Transport.readAll( buffer, 0, len);
var inp = new BytesInput( buffer.getBytes(), 0, len);
inp.bigEndian = true;
return inp.readString(len);
@@ -292,10 +294,33 @@ class TBinaryProtocol extends TRecursionTracker implements TProtocol {
public function readBinary() : Bytes {
var len : Int = readI32();
- var buffer = new BytesBuffer();
- trans_.readAll( buffer, 0, len);
+ Transport.CheckReadBytesAvailable(len);
+ var buffer = new BytesBuffer();
+ Transport.readAll( buffer, 0, len);
return buffer.getBytes();
}
+ // Return the minimum number of bytes a type will consume on the wire
+ public override function GetMinSerializedSize(type : TType) : Int
+ {
+ switch (type)
+ {
+ case TType.STOP: return 0;
+ case TType.VOID: return 0;
+ case TType.BOOL: return 1;
+ case TType.BYTE: return 1;
+ case TType.DOUBLE: return 8;
+ case TType.I16: return 2;
+ case TType.I32: return 4;
+ case TType.I64: return 8;
+ case TType.STRING: return 4; // string length
+ case TType.STRUCT: return 0; // empty struct
+ case TType.MAP: return 4; // element count
+ case TType.SET: return 4; // element count
+ case TType.LIST: return 4; // element count
+ default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
+ }
+ }
+
}
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx
index 03b13e2f6..ae626b5f0 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx
@@ -23,10 +23,10 @@ import haxe.io.Bytes;
import haxe.io.BytesInput;
import haxe.io.BytesOutput;
import haxe.io.BytesBuffer;
+import haxe.io.Encoding;
import haxe.ds.GenericStack;
import haxe.Int32;
import haxe.Int64;
-import haxe.Utf8;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransport;
@@ -37,7 +37,7 @@ import org.apache.thrift.helper.BitConverter;
/**
* Compact protocol implementation for thrift.
*/
-class TCompactProtocol extends TRecursionTracker implements TProtocol {
+class TCompactProtocol extends TProtocolImplBase implements TProtocol {
private static var ANONYMOUS_STRUCT : TStruct = new TStruct("");
private static var TSTOP : TField = new TField("", TType.STOP, 0);
@@ -102,24 +102,11 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
private var boolValue_ : Null<Bool>;
- // whether the underlying system holds Strings as UTF-8
- // http://old.haxe.org/manual/encoding
- private static var utf8Strings = haxe.Utf8.validate("Ç-ß-Æ-Ю-Ш");
-
- // the transport used
- public var trans(default,null) : TTransport;
-
-
// TCompactProtocol Constructor
- public function new( trans : TTransport) {
- this.trans = trans;
- }
-
- public function getTransport() : TTransport {
- return trans;
+ public function new( transport : TTransport) {
+ super(transport);
}
-
public function Reset() : Void{
while ( ! lastField_.isEmpty()) {
lastField_.pop();
@@ -135,7 +122,7 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
private function WriteByteDirect( b : Int) : Void {
var buf = Bytes.alloc(1);
buf.set( 0, b);
- trans.write( buf, 0, 1);
+ Transport.write( buf, 0, 1);
}
/**
@@ -158,7 +145,7 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
}
var tmp = i32buf.getBytes();
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
}
/**
@@ -329,7 +316,7 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
*/
public function writeDouble( dub : Float) : Void {
var data = BitConverter.fixedLongToBytes( BitConverter.DoubleToInt64Bits(dub));
- trans.write( data, 0, data.length);
+ Transport.write( data, 0, data.length);
}
/**
@@ -337,10 +324,7 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
*/
public function writeString(str : String) : Void {
var buf = new BytesBuffer();
- if( utf8Strings)
- buf.addString( str); // no need to encode on UTF8 targets, the string is just fine
- else
- buf.addString( Utf8.encode( str));
+ buf.addString( str, Encoding.UTF8);
var tmp = buf.getBytes();
writeBinary( tmp);
}
@@ -350,7 +334,7 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
*/
public function writeBinary( bin : Bytes) : Void {
WriteVarint32( cast(bin.length,UInt));
- trans.write( bin, 0, bin.length);
+ Transport.write( bin, 0, bin.length);
}
@@ -408,7 +392,7 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
}
}
var tmp = varint64out.getBytes();
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
}
@@ -497,7 +481,9 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
var keyAndValueType : Int = ((size == 0) ? 0 : readByte());
var key : Int = cast( getTType( (keyAndValueType & 0xF0) >> 4), Int);
var val : Int = cast( getTType( keyAndValueType & 0x0F), Int);
- return new TMap( key, val, size);
+ var map = new TMap( key, val, size);
+ CheckReadBytesAvailableMap(map);
+ return map;
}
/**
@@ -515,7 +501,9 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
}
var type = getTType(size_and_type);
- return new TList( type, size);
+ var list = new TList( type, size);
+ CheckReadBytesAvailableList(list);
+ return list;
}
/**
@@ -533,7 +521,9 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
}
var type = getTType(size_and_type);
- return new TSet( type, size);
+ var set = new TSet( type, size);
+ CheckReadBytesAvailableSet(set);
+ return set;
}
/**
@@ -556,7 +546,7 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
*/
public function readByte() : Int {
var byteRawBuf = new BytesBuffer();
- trans.readAll( byteRawBuf, 0, 1);
+ Transport.readAll( byteRawBuf, 0, 1);
return byteRawBuf.getBytes().get(0);
}
@@ -586,7 +576,7 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
*/
public function readDouble():Float {
var longBits = new BytesBuffer();
- trans.readAll( longBits, 0, 8);
+ Transport.readAll( longBits, 0, 8);
return BitConverter.Int64BitsToDouble( BitConverter.bytesToLong( longBits.getBytes()));
}
@@ -595,21 +585,19 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
*/
public function readString() : String {
var length : Int = cast( ReadVarint32(), Int);
+ Transport.CheckReadBytesAvailable(length);
if (length == 0) {
return "";
}
var buf = new BytesBuffer();
- trans.readAll( buf, 0, length);
+ Transport.readAll( buf, 0, length);
length = buf.length;
var inp = new BytesInput( buf.getBytes());
- var str = inp.readString( length);
- if( utf8Strings)
- return str; // no need to decode on UTF8 targets, the string is just fine
- else
- return Utf8.decode( str);
+ var str = inp.readString( length, Encoding.UTF8);
+ return str;
}
/**
@@ -617,12 +605,13 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
*/
public function readBinary() : Bytes {
var length : Int = cast( ReadVarint32(), Int);
+ Transport.CheckReadBytesAvailable(length);
if (length == 0) {
return Bytes.alloc(0);
}
var buf = new BytesBuffer();
- trans.readAll( buf, 0, length);
+ Transport.readAll( buf, 0, length);
return buf.getBytes();
}
@@ -715,4 +704,27 @@ class TCompactProtocol extends TRecursionTracker implements TProtocol {
{
return cast( ttypeToCompactType[ttype], Int);
}
+
+ // Return the minimum number of bytes a type will consume on the wire
+ public override function GetMinSerializedSize(type : TType) : Int
+ {
+ switch (type)
+ {
+ case TType.STOP: return 0;
+ case TType.VOID: return 0;
+ case TType.BOOL: return 1;
+ case TType.DOUBLE: return 8; // uses fixedLongToBytes() which always writes 8 bytes
+ case TType.BYTE: return 1;
+ case TType.I16: return 1; // zigzag
+ case TType.I32: return 1; // zigzag
+ case TType.I64: return 1; // zigzag
+ case TType.STRING: return 1; // string length
+ case TType.STRUCT: return 0; // empty struct
+ case TType.MAP: return 1; // element count
+ case TType.SET: return 1; // element count
+ case TType.LIST: return 1; // element count
+ default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
+ }
+ }
+
}
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx
index e20ff33c5..145eab911 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx
@@ -23,8 +23,8 @@ import haxe.io.Bytes;
import haxe.io.BytesInput;
import haxe.io.BytesOutput;
import haxe.io.BytesBuffer;
+import haxe.io.Encoding;
import haxe.ds.GenericStack;
-import haxe.Utf8;
import haxe.crypto.Base64;
import haxe.Int64;
@@ -45,9 +45,7 @@ import org.apache.thrift.transport.TTransport;
*
* Adapted from the Java version.
*/
-class TJSONProtocol extends TRecursionTracker implements TProtocol {
-
- public var trans(default,null) : TTransport;
+class TJSONProtocol extends TProtocolImplBase implements TProtocol {
// Stack of nested contexts that we may be in
private var contextStack : GenericStack<JSONBaseContext> = new GenericStack<JSONBaseContext>();
@@ -58,22 +56,14 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
// Reader that manages a 1-byte buffer
private var reader : LookaheadReader;
- // whether the underlying system holds Strings as UTF-8
- // http://old.haxe.org/manual/encoding
- private static var utf8Strings = haxe.Utf8.validate("Ç-ß-Æ-Ю-Ш");
-
// TJSONProtocol Constructor
- public function new( trans : TTransport)
+ public function new( transport : TTransport)
{
- this.trans = trans;
+ super(transport);
this.context = new JSONBaseContext(this);
this.reader = new LookaheadReader(this);
}
- public function getTransport() : TTransport {
- return trans;
- }
-
public function writeMessageBegin(message:TMessage) : Void {
WriteJSONArrayStart();
WriteJSONInteger( JSONConstants.VERSION);
@@ -230,7 +220,8 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
ReadJSONObjectStart();
var map = new TMap( KeyType, ValueType, Count);
- return map;
+ CheckReadBytesAvailableMap(map);
+ return map;
}
public function readMapEnd() : Void {
@@ -244,6 +235,7 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
var Count : Int = ReadJSONInteger();
var list = new TList( ElementType, Count);
+ CheckReadBytesAvailableList(list);
return list;
}
@@ -257,6 +249,7 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
var Count : Int = ReadJSONInteger();
var set = new TSet( ElementType, Count);
+ CheckReadBytesAvailableSet(set);
return set;
}
@@ -313,7 +306,7 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
context.Write();
var tmp = BytesFromString( JSONConstants.QUOTE);
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
for (i in 0 ... b.length) {
var value = b.get(i);
@@ -323,11 +316,11 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
if (String.fromCharCode(value) == JSONConstants.BACKSLASH.charAt(0))
{
tmp = BytesFromString( JSONConstants.BACKSLASH + JSONConstants.BACKSLASH);
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
}
else
{
- trans.write( b, i, 1);
+ Transport.write( b, i, 1);
}
}
else
@@ -335,7 +328,7 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
var num = JSONConstants.JSON_CHAR_TABLE[value];
if (num == 1)
{
- trans.write( b, i, 1);
+ Transport.write( b, i, 1);
}
else if (num > 1)
{
@@ -343,7 +336,7 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
buf.addString( JSONConstants.BACKSLASH);
buf.addByte( num);
tmp = buf.getBytes();
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
}
else
{
@@ -354,13 +347,13 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
buf.addString( HexChar( (value & 0x0000FF00) >> 4));
buf.addString( HexChar( value & 0x000000FF));
tmp = buf.getBytes();
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
}
}
}
tmp = BytesFromString( JSONConstants.QUOTE);
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
}
// Write out number as a JSON value. If the context dictates so,
@@ -382,7 +375,7 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
}
var tmp = BytesFromString( str);
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
}
// Write out number as a JSON value. If the context dictates so,
@@ -404,7 +397,7 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
}
var tmp = BytesFromString( str);
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
}
// Write out a double as a JSON value. If it is NaN or infinity or if the
@@ -441,7 +434,7 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
}
var tmp = BytesFromString( str);
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
}
// Write out contents of byte array b as a JSON string with base-64 encoded data
@@ -454,33 +447,33 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
buf.addString( JSONConstants.QUOTE);
var tmp = buf.getBytes();
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
}
private function WriteJSONObjectStart() : Void {
context.Write();
var tmp = BytesFromString( JSONConstants.LBRACE);
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
PushContext( new JSONPairContext(this));
}
private function WriteJSONObjectEnd() : Void {
PopContext();
var tmp = BytesFromString( JSONConstants.RBRACE);
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
}
private function WriteJSONArrayStart() : Void {
context.Write();
var tmp = BytesFromString( JSONConstants.LBRACKET);
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
PushContext( new JSONListContext(this));
}
private function WriteJSONArrayEnd() : Void {
PopContext();
var tmp = BytesFromString( JSONConstants.RBRACKET);
- trans.write( tmp, 0, tmp.length);
+ Transport.write( tmp, 0, tmp.length);
}
@@ -545,7 +538,7 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
// it's \uXXXX
var hexbuf = new BytesBuffer();
- var hexlen = trans.readAll( hexbuf, 0, 4);
+ var hexlen = Transport.readAll( hexbuf, 0, 4);
if( hexlen != 4)
{
throw new TProtocolException( TProtocolException.INVALID_DATA, "Not enough data for \\uNNNN sequence");
@@ -756,10 +749,7 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
public static function BytesFromString( str : String) : Bytes {
var buf = new BytesBuffer();
- if( utf8Strings)
- buf.addString( str); // no need to encode on UTF8 targets, the string is just fine
- else
- buf.addString( Utf8.encode( str));
+ buf.addString( str, Encoding.UTF8);
return buf.getBytes();
}
@@ -767,11 +757,7 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
var inp = new BytesInput( buf);
if( buf.length == 0)
return ""; // readString() would return null in that case, which is wrong
- var str = inp.readString( buf.length);
- if( utf8Strings)
- return str; // no need to decode on UTF8 targets, the string is just fine
- else
- return Utf8.decode( str);
+ return inp.readString( buf.length, Encoding.UTF8);
}
// Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its corresponding hex value
@@ -790,6 +776,28 @@ class TJSONProtocol extends TRecursionTracker implements TProtocol {
}
+ // Return the minimum number of bytes a type will consume on the wire
+ public override function GetMinSerializedSize(type : TType) : Int
+ {
+ switch (type)
+ {
+ case TType.STOP: return 0;
+ case TType.VOID: return 0;
+ case TType.BOOL: return 1; // written as int
+ case TType.BYTE: return 1;
+ case TType.DOUBLE: return 1;
+ case TType.I16: return 1;
+ case TType.I32: return 1;
+ case TType.I64: return 1;
+ case TType.STRING: return 2; // empty string
+ case TType.STRUCT: return 2; // empty struct
+ case TType.MAP: return 2; // empty map
+ case TType.SET: return 2; // empty set
+ case TType.LIST: return 2; // empty list
+ default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
+ }
+ }
+
}
@@ -971,7 +979,7 @@ class JSONListContext extends JSONBaseContext
var buf = new BytesBuffer();
buf.addString( JSONConstants.COMMA);
var tmp = buf.getBytes();
- proto.trans.write( tmp, 0, tmp.length);
+ proto.Transport.write( tmp, 0, tmp.length);
}
}
@@ -1014,7 +1022,7 @@ class JSONPairContext extends JSONBaseContext
var buf = new BytesBuffer();
buf.addString( colon ? JSONConstants.COLON : JSONConstants.COMMA);
var tmp = buf.getBytes();
- proto.trans.write( tmp, 0, tmp.length);
+ proto.Transport.write( tmp, 0, tmp.length);
colon = !colon;
}
}
@@ -1064,7 +1072,7 @@ class LookaheadReader {
public function Peek() : Bytes {
if (data == null) {
var buf = new BytesBuffer();
- proto.trans.readAll(buf, 0, 1);
+ proto.Transport.readAll(buf, 0, 1);
data = buf.getBytes();
}
return data;
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx
index b7f3842d0..316067a38 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx
@@ -82,4 +82,7 @@ interface TProtocol {
// recursion tracking
function IncrementRecursionDepth() : Void;
function DecrementRecursionDepth() : Void;
+
+ // message size
+ function GetMinSerializedSize(type : TType) : Int;
}
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx b/lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx
index 769e93cc5..011f42b80 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx
@@ -223,4 +223,10 @@ class TProtocolDecorator implements TProtocol
public function DecrementRecursionDepth() : Void {
return wrapped.DecrementRecursionDepth();
}
+
+ // Returns the minimum amount of bytes needed to store the smallest possible instance of TType.
+ public function GetMinSerializedSize(type : TType) : Int
+ {
+ return wrapped.GetMinSerializedSize(type);
+ }
}
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TProtocolImplBase.hx b/lib/haxe/src/org/apache/thrift/protocol/TProtocolImplBase.hx
new file mode 100644
index 000000000..60e4a1f70
--- /dev/null
+++ b/lib/haxe/src/org/apache/thrift/protocol/TProtocolImplBase.hx
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.thrift.protocol;
+
+import org.apache.thrift.*;
+import org.apache.thrift.transport.TTransport;
+
+
+class TProtocolImplBase {
+
+ private var Configuration : TConfiguration;
+ public var Transport(default,null) : TTransport;
+
+ public function new( transport : TTransport)
+ {
+ Transport = transport;
+ Configuration = (transport.Configuration != null) ? transport.Configuration : new TConfiguration();
+ }
+
+
+ public function getTransport() : TTransport {
+ return Transport;
+ }
+
+
+ // limit and actual value
+ public var recursionLimit(get,never) : Int;
+ private var recursionDepth : Int = 0;
+
+ public function get_recursionLimit() : Int
+ {
+ return Configuration.RecursionLimit;
+ }
+
+
+ public function IncrementRecursionDepth() : Void
+ {
+ if (recursionDepth < recursionLimit)
+ ++recursionDepth;
+ else
+ throw new TProtocolException(TProtocolException.DEPTH_LIMIT, "Depth limit exceeded");
+ }
+
+ public function DecrementRecursionDepth() : Void
+ {
+ --recursionDepth;
+ }
+
+
+ private function CheckReadBytesAvailableSet(set : TSet) : Void
+ {
+ Transport.CheckReadBytesAvailable(set.size * GetMinSerializedSize(set.elemType));
+ }
+
+ private function CheckReadBytesAvailableList(list : TList) : Void
+ {
+ Transport.CheckReadBytesAvailable(list.size * GetMinSerializedSize(list.elemType));
+ }
+
+ private function CheckReadBytesAvailableMap (map : TMap) : Void
+ {
+ var elmSize = GetMinSerializedSize(map.keyType) + GetMinSerializedSize(map.valueType);
+ Transport.CheckReadBytesAvailable(map.size * elmSize);
+ }
+
+ // Returns the minimum amount of bytes needed to store the smallest possible instance of TType.
+ public function GetMinSerializedSize(type : TType) : Int throw "abstract method called";
+
+}
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TRecursionTracker.hx b/lib/haxe/src/org/apache/thrift/protocol/TRecursionTracker.hx
deleted file mode 100644
index cf0211b39..000000000
--- a/lib/haxe/src/org/apache/thrift/protocol/TRecursionTracker.hx
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.protocol;
-
-import org.apache.thrift.*;
-
-
-class TRecursionTracker {
-
- // default
- private static inline var DEFAULT_RECURSION_DEPTH : Int = 64;
-
- // limit and actual value
- public var recursionLimit : Int = DEFAULT_RECURSION_DEPTH;
- private var recursionDepth : Int = 0;
-
- public function IncrementRecursionDepth() : Void
- {
- if (recursionDepth < recursionLimit)
- ++recursionDepth;
- else
- throw new TProtocolException(TProtocolException.DEPTH_LIMIT, "Depth limit exceeded");
- }
-
- public function DecrementRecursionDepth() : Void
- {
- --recursionDepth;
- }
-
-
-}
diff --git a/lib/haxe/src/org/apache/thrift/transport/TBufferedTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TBufferedTransport.hx
index 4b33fcf86..72ce9218c 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TBufferedTransport.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TBufferedTransport.hx
@@ -21,6 +21,7 @@ package org.apache.thrift.transport;
import org.apache.thrift.transport.*;
+import haxe.Int64;
import haxe.io.Eof;
import haxe.io.Bytes;
import haxe.io.BytesBuffer;
@@ -28,16 +29,13 @@ import haxe.io.BytesOutput;
import haxe.io.BytesInput;
-class TBufferedTransport extends TTransport
+class TBufferedTransport extends TLayeredTransport
{
// constants
public static inline var DEFAULT_BUFSIZE : Int = 0x1000; // 4096 Bytes
public static inline var MIN_BUFSIZE : Int = 0x100; // 256 Bytes
public static inline var MAX_BUFSIZE : Int = 0x100000; // 1 MB
- // Underlying transport
- public var transport(default,null) : TTransport = null;
-
// Buffer for input/output
private var readBuffer_ : BytesInput = null;
private var writeBuffer_ : BytesOutput = null;
@@ -45,6 +43,7 @@ class TBufferedTransport extends TTransport
// Constructor wraps around another transport
public function new( transport : TTransport, bufSize : Int = DEFAULT_BUFSIZE) {
+ super(transport);
// ensure buffer size is in the range
if ( bufSize < MIN_BUFSIZE)
@@ -52,22 +51,21 @@ class TBufferedTransport extends TTransport
else if( bufSize > MAX_BUFSIZE)
bufSize = MAX_BUFSIZE;
- this.transport = transport;
this.bufSize = bufSize;
this.writeBuffer_ = new BytesOutput();
this.writeBuffer_.bigEndian = true;
}
public override function open() : Void {
- transport.open();
+ InnerTransport.open();
}
public override function isOpen() : Bool {
- return transport.isOpen();
+ return InnerTransport.isOpen();
}
public override function close() : Void {
- transport.close();
+ InnerTransport.close();
}
public override function read(buf : BytesBuffer, off : Int, len : Int) : Int {
@@ -86,7 +84,7 @@ class TBufferedTransport extends TTransport
// there is no point in buffering whenever the
// remaining length exceeds the buffer size
if ( len >= bufSize) {
- var got = transport.read( buf, off, len);
+ var got = InnerTransport.read( buf, off, len);
if (got > 0) {
buf.addBytes(data, 0, got);
return got;
@@ -109,7 +107,7 @@ class TBufferedTransport extends TTransport
var size = bufSize;
try {
var buffer = new BytesBuffer();
- size = transport.read( buffer, 0, size);
+ size = InnerTransport.read( buffer, 0, size);
readBuffer_ = new BytesInput( buffer.getBytes(), 0, size);
readBuffer_.bigEndian = true;
return size;
@@ -125,7 +123,7 @@ class TBufferedTransport extends TTransport
var buf = writeBuffer_.getBytes();
writeBuffer_ = new BytesOutput();
writeBuffer_.bigEndian = true;
- transport.write(buf, 0, buf.length);
+ InnerTransport.write(buf, 0, buf.length);
}
}
}
@@ -141,7 +139,7 @@ class TBufferedTransport extends TTransport
var write_thru : Bool = exceeds_buf && (writeBuffer_.length >= halfSize);
if ( write_thru) {
writeChunk(true); // force send whatever we have in there
- transport.write(buf, off, len); // write thru
+ InnerTransport.write(buf, off, len); // write thru
} else {
writeBuffer_.writeBytes(buf, off, len);
writeChunk(false);
@@ -150,6 +148,18 @@ class TBufferedTransport extends TTransport
public override function flush( callback : Dynamic->Void =null) : Void {
writeChunk(true);
- transport.flush(callback);
+ InnerTransport.flush(callback);
}
+
+ public override function CheckReadBytesAvailable(numBytes : Int64) : Void
+ {
+ var buffered = readBuffer_.length - readBuffer_.position;
+ if (buffered < numBytes)
+ {
+ numBytes -= buffered;
+ InnerTransport.CheckReadBytesAvailable(numBytes);
+ }
+ }
+
+
}
diff --git a/lib/haxe/src/org/apache/thrift/transport/TBufferedTransportFactory.hx b/lib/haxe/src/org/apache/thrift/transport/TBufferedTransportFactory.hx
index 539e72033..11d1a72a9 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TBufferedTransportFactory.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TBufferedTransportFactory.hx
@@ -27,7 +27,7 @@ class TBufferedTransportFactory extends TTransportFactory {
private var bufSize : Int;
public function new(bufSize : Int = TBufferedTransport.DEFAULT_BUFSIZE) {
- super();
+ super();
this.bufSize = bufSize;
}
diff --git a/lib/haxe/src/org/apache/thrift/transport/TEndpointTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TEndpointTransport.hx
new file mode 100644
index 000000000..8c0d3effa
--- /dev/null
+++ b/lib/haxe/src/org/apache/thrift/transport/TEndpointTransport.hx
@@ -0,0 +1,95 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.thrift.transport;
+
+import haxe.Int64;
+import org.apache.thrift.TConfiguration;
+
+class TEndpointTransport extends TTransport
+{
+ private var MaxMessageSize(get, never) : Int64;
+ private var KnownMessageSize(default, null) : Int64 ;
+ private var RemainingMessageSize(default, null) : Int64 ;
+
+ private var _configuration(default,null) : TConfiguration;
+
+ public override function get_Configuration() : TConfiguration {
+ return _configuration;
+ }
+
+ private function get_MaxMessageSize() : Int64 {
+ return Configuration.MaxMessageSize;
+ }
+
+
+ // private CTOR to prevent direct instantiation
+ // in other words, this class MUST be extended
+ private function new( config : TConfiguration)
+ {
+ _configuration = (config != null) ? config : new TConfiguration();
+ ResetConsumedMessageSize();
+ }
+
+ // Resets RemainingMessageSize to the configured maximum
+ private function ResetConsumedMessageSize(?newSize : Int64) : Void
+ {
+ // full reset
+ if (newSize == null)
+ {
+ KnownMessageSize = MaxMessageSize;
+ RemainingMessageSize = MaxMessageSize;
+ return;
+ }
+
+ // update only: message size can shrink, but not grow
+ if (newSize > KnownMessageSize)
+ throw new TTransportException(TTransportException.END_OF_FILE, "ResetConsumedMessageSize: MaxMessageSize reached");
+
+ KnownMessageSize = newSize;
+ RemainingMessageSize = newSize;
+ }
+
+ // Updates RemainingMessageSize to reflect then known real message size (e.g. framed transport).
+ // Will throw if we already consumed too many bytes or if the new size is larger than allowed.
+ public override function UpdateKnownMessageSize(size : Int64) : Void
+ {
+ var consumed = KnownMessageSize - RemainingMessageSize;
+ ResetConsumedMessageSize(size);
+ CountConsumedMessageBytes(consumed);
+ }
+
+ // Throws if there are not enough bytes in the input stream to satisfy a read of numBytes bytes of data
+ public override function CheckReadBytesAvailable(numBytes : Int64) : Void
+ {
+ if (RemainingMessageSize < numBytes)
+ throw new TTransportException(TTransportException.END_OF_FILE, 'CheckReadBytesAvailable(${numBytes}): MaxMessageSize reached, only ${RemainingMessageSize} bytes available');
+ }
+
+ // Consumes numBytes from the RemainingMessageSize.
+ private function CountConsumedMessageBytes(numBytes : Int64) : Void
+ {
+ if (RemainingMessageSize >= numBytes)
+ {
+ RemainingMessageSize -= numBytes;
+ }
+ else
+ {
+ RemainingMessageSize = 0;
+ throw new TTransportException(TTransportException.END_OF_FILE, 'CountConsumedMessageBytes(${numBytes}): MaxMessageSize reached');
+ }
+ }
+}
diff --git a/lib/haxe/src/org/apache/thrift/transport/TFramedTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TFramedTransport.hx
index cef82ef61..37e495946 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TFramedTransport.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TFramedTransport.hx
@@ -21,6 +21,7 @@ package org.apache.thrift.transport;
import org.apache.thrift.transport.*;
+import haxe.Int64;
import haxe.io.Eof;
import haxe.io.Bytes;
import haxe.io.BytesBuffer;
@@ -32,16 +33,9 @@ import haxe.io.BytesInput;
* TFramedTransport is a buffered TTransport that ensures a fully read message
* every time by preceding messages with a 4-byte frame size.
*/
-class TFramedTransport extends TTransport
+class TFramedTransport extends TLayeredTransport
{
- public static inline var DEFAULT_MAX_LENGTH = 16384000;
-
- var maxLength_ : Int;
-
- /**
- * Underlying transport
- */
- var transport_ : TTransport = null;
+ private static inline var HEADER_SIZE = 4;
/**
* Buffer for output
@@ -56,21 +50,20 @@ class TFramedTransport extends TTransport
/**
* Constructor wraps around another transport
*/
- public function new( transport : TTransport, maxLength : Int = DEFAULT_MAX_LENGTH) {
- transport_ = transport;
- maxLength_ = maxLength;
+ public function new( transport : TTransport) {
+ super(transport);
}
public override function open() : Void {
- transport_.open();
+ InnerTransport.open();
}
public override function isOpen() : Bool {
- return transport_.isOpen();
+ return InnerTransport.isOpen();
}
public override function close() : Void {
- transport_.close();
+ InnerTransport.close();
}
public override function read(buf : BytesBuffer, off : Int, len : Int) : Int {
@@ -101,13 +94,13 @@ class TFramedTransport extends TTransport
function readFrameSize() : Int {
try {
var buffer = new BytesBuffer();
- var len = transport_.readAll( buffer, 0, 4);
- var inp = new BytesInput( buffer.getBytes(), 0, 4);
+ var len = InnerTransport.readAll( buffer, 0, HEADER_SIZE);
+ var inp = new BytesInput( buffer.getBytes(), 0, HEADER_SIZE);
inp.bigEndian = true;
return inp.readInt32();
}
catch(eof : Eof) {
- throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read 4 bytes!');
+ throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read ${HEADER_SIZE} bytes!');
}
}
@@ -118,13 +111,14 @@ class TFramedTransport extends TTransport
if (size < 0) {
throw new TTransportException(TTransportException.UNKNOWN, 'Read a negative frame size ($size)!');
};
- if (size > maxLength_) {
- throw new TTransportException(TTransportException.UNKNOWN, 'Frame size ($size) larger than max length ($maxLength_)!');
+ if (size > Configuration.MaxFrameSize) {
+ throw new TTransportException(TTransportException.UNKNOWN, 'Frame size ($size) larger than max length ($Configuration.MaxFrameSize)!');
};
+ UpdateKnownMessageSize(size + HEADER_SIZE);
try {
var buffer = new BytesBuffer();
- size = transport_.readAll( buffer, 0, size);
+ size = InnerTransport.readAll( buffer, 0, size);
readBuffer_ = new BytesInput( buffer.getBytes(), 0, size);
readBuffer_.bigEndian = true;
}
@@ -141,18 +135,31 @@ class TFramedTransport extends TTransport
var out = new BytesOutput();
out.bigEndian = true;
out.writeInt32(len);
- transport_.write(out.getBytes(), 0, 4);
+ InnerTransport.write(out.getBytes(), 0, HEADER_SIZE);
}
public override function flush( callback : Dynamic->Void =null) : Void {
var buf : Bytes = writeBuffer_.getBytes();
var len : Int = buf.length;
writeBuffer_ = new BytesOutput();
+ readBuffer_ = null;
writeFrameSize(len);
- transport_.write(buf, 0, len);
- transport_.flush(callback);
+ InnerTransport.write(buf, 0, len);
+ InnerTransport.flush(callback);
}
+
+
+ public override function CheckReadBytesAvailable(numBytes : Int64) : Void
+ {
+ var buffered = readBuffer_.length - readBuffer_.position;
+ if (buffered < numBytes)
+ {
+ numBytes -= buffered;
+ InnerTransport.CheckReadBytesAvailable(numBytes);
+ }
+ }
+
}
diff --git a/lib/haxe/src/org/apache/thrift/transport/TFramedTransportFactory.hx b/lib/haxe/src/org/apache/thrift/transport/TFramedTransportFactory.hx
index 8d45a641a..ca04e7fe4 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TFramedTransportFactory.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TFramedTransportFactory.hx
@@ -19,19 +19,17 @@
package org.apache.thrift.transport;
+import org.apache.thrift.TConfiguration;
import org.apache.thrift.transport.*;
class TFramedTransportFactory extends TTransportFactory {
- var maxLength_ : Int;
-
- public function new(maxLength : Int = TFramedTransport.DEFAULT_MAX_LENGTH) {
- super();
- maxLength_ = maxLength;
+ public function new() {
+ super();
}
public override function getTransport(base : TTransport) : TTransport {
- return new TFramedTransport(base, maxLength_);
+ return new TFramedTransport(base);
}
}
diff --git a/lib/haxe/src/org/apache/thrift/transport/TFullDuplexHttpClient.hx b/lib/haxe/src/org/apache/thrift/transport/TFullDuplexHttpClient.hx
index 1972853ef..cc34ec4fa 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TFullDuplexHttpClient.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TFullDuplexHttpClient.hx
@@ -41,213 +41,217 @@ import flash.events.EventDispatcher;
* Unlike Http Client, it uses a single POST, and chunk-encoding to transfer all messages.
*/
- public class TFullDuplexHttpClient extends TTransport
- {
- private var socket : Socket = null;
- private var host : String;
- private var port : Int;
- private var resource : String;
- private var stripped : Bool = false;
- private var obuffer : Bytes = new Bytes();
- private var input : IDataInput;
- private var output : IDataOutput;
- private var bytesInChunk : Int = 0;
- private var CRLF : Bytes = new Bytes();
- private var ioCallback : TException->Void = null;
- private var eventDispatcher : EventDispatcher = new EventDispatcher();
-
- public function new(host : String, port : Int, resource : String) : Void
- {
- CRLF.writeByte(13);
- CRLF.writeByte(10);
- this.host = host;
- this.port = port;
- this.resource = resource;
- }
-
- public override function close() : Void
- {
- this.input = null;
- this.output = null;
- this.stripped = false;
- socket.close()
- }
-
- public override function peek() : Bool
- {
- if(socket.connected)
- {
- trace("Bytes remained:" + socket.bytesAvailable);
- return socket.bytesAvailable>0;
- }
- return false;
- }
-
- public override function read(buf : Bytes, off : Int, len : Int) : Int
- {
- var n1 : Int = 0, n2 : Int = 0, n3 : Int = 0, n4 : Int = 0, cidx : Int = 2;
- var chunkSize : Bytes = new Bytes();
-
- try
- {
- while (!stripped)
- {
- n1 = n2;
- n2 = n3;
- n3 = n4;
- n4 = input.readByte();
- if ((n1 == 13) && (n2 == 10) && (n3 == 13) && (n4 == 10))
- {
- stripped = true;
- }
- }
-
- // read chunk size
- if (bytesInChunk == 0)
- {
- n1 = input.readByte();
- n2 = input.readByte();
-
- chunkSize.writeByte(n1);
- chunkSize.writeByte(n2);
-
- while (!((n1 == 13) && (n2 == 10)))
- {
- n1 = n2;
- n2 = input.readByte();
- chunkSize.writeByte(n2);
- }
-
- bytesInChunk = parseInt(chunkSize.toString(), 16);
- }
-
- input.readBytes(buf, off, len);
- debugBuffer(buf);
- bytesInChunk -= len;
-
- if (bytesInChunk == 0)
- {
- // advance the : "\r\n"
- input.readUTFBytes(2);
- }
- return len;
- }
- catch (e : EOFError)
- {
- trace(e);
- throw new TTransportException(TTransportException.UNKNOWN, "No more data available.");
- }
- catch (e : TException)
- {
- trace('TException $e');
- throw e;
- }
- catch (e : Error)
- {
- trace(e);
- throw new TTransportException(TTransportException.UNKNOWN, 'Bad IO error: $e');
- }
- catch (e : Dynamic)
- {
- trace(e);
- throw new TTransportException(TTransportException.UNKNOWN, 'Bad IO error: $e');
- }
- return 0;
- }
-
- public function debugBuffer(buf : Bytes) : Void
- {
- var debug : String = "BUFFER >>";
- var i : Int;
- for (i = 0; i < buf.length; i++)
- {
- debug += buf[i] as int;
- debug += " ";
- }
-
- trace(debug + "<<");
- }
-
- public override function write(buf : Bytes, off : Int, len : Int) : Void
- {
- obuffer.writeBytes(buf, off, len);
- }
-
- public function addEventListener(type : String, listener : Function, useCapture : Bool = false, priority : Int = 0, useWeakReference : Bool = false) : Void
- {
- this.eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
- }
-
- public override function open() : Void
- {
- this.socket = new Socket();
- this.socket.addEventListener(Event.CONNECT, socketConnected);
- this.socket.addEventListener(IOErrorEvent.IO_ERROR, socketError);
- this.socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, socketSecurityError);
- this.socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
- this.socket.connect(host, port);
- }
-
- public function socketConnected(event : Event) : Void
- {
- this.output = this.socket;
- this.input = this.socket;
- this.output.writeUTF( "CONNECT " + resource + " HTTP/1.1\n"
- + "Host : " + host + ":" + port + "\r\n"
- + "User-Agent : Thrift/Haxe\r\n"
- + "Transfer-Encoding : chunked\r\n"
- + "content-type : application/x-thrift\r\n"
- + "Accept : */*\r\n"
- + "\r\n");
- this.eventDispatcher.dispatchEvent(event);
- }
-
- public function socketError(event : IOErrorEvent) : Void
- {
- trace("Error Connecting:" + event);
- this.close();
- if (ioCallback == null)
- {
- return;
- }
- ioCallback(new TTransportException(TTransportException.UNKNOWN, "IOError : " + event.text));
- this.eventDispatcher.dispatchEvent(event);
- }
-
- public function socketSecurityError(event : SecurityErrorEvent) : Void
- {
- trace("Security Error Connecting:" + event);
- this.close();
- this.eventDispatcher.dispatchEvent(event);
- }
-
- public function socketDataHandler(event : ProgressEvent) : Void
- {
- trace("Got Data call:" +ioCallback);
- if (ioCallback != null)
- {
- ioCallback(null);
- };
- this.eventDispatcher.dispatchEvent(event);
- }
-
- public override function flush(callback : Error->Void = null) : Void
- {
- trace("set callback:" + callback);
- this.ioCallback = callback;
- this.output.writeUTF(this.obuffer.length.toString(16));
- this.output.writeBytes(CRLF);
- this.output.writeBytes(this.obuffer);
- this.output.writeBytes(CRLF);
- this.socket.flush();
- // waiting for new Flex sdk 3.5
- //this.obuffer.clear();
- this.obuffer = new Bytes();
- }
-
- public override function isOpen() : Bool
- {
- return (this.socket == null ? false : this.socket.connected);
- }
+public class TFullDuplexHttpClient extends TEndpointTransport
+{
+ private var socket : Socket = null;
+ private var host : String;
+ private var port : Int;
+ private var resource : String;
+ private var stripped : Bool = false;
+ private var obuffer : Bytes = new Bytes();
+ private var input : IDataInput;
+ private var output : IDataOutput;
+ private var bytesInChunk : Int = 0;
+ private var CRLF : Bytes = new Bytes();
+ private var ioCallback : TException->Void = null;
+ private var eventDispatcher : EventDispatcher = new EventDispatcher();
+
+ public function new(host : String, port : Int, resource : String, config : TConfiguration = null) : Void
+ {
+ super(config);
+ CRLF.writeByte(13);
+ CRLF.writeByte(10);
+ this.host = host;
+ this.port = port;
+ this.resource = resource;
+ }
+
+ public override function close() : Void
+ {
+ this.input = null;
+ this.output = null;
+ this.stripped = false;
+ socket.close();
+ ResetConsumedMessageSize();
+ }
+
+ public override function peek() : Bool
+ {
+ if(socket.connected)
+ {
+ trace("Bytes remaining:" + socket.bytesAvailable);
+ return socket.bytesAvailable>0;
+ }
+ return false;
+ }
+
+ public override function read(buf : Bytes, off : Int, len : Int) : Int
+ {
+ var n1 : Int = 0, n2 : Int = 0, n3 : Int = 0, n4 : Int = 0, cidx : Int = 2;
+ var chunkSize : Bytes = new Bytes();
+
+ try
+ {
+ while (!stripped)
+ {
+ n1 = n2;
+ n2 = n3;
+ n3 = n4;
+ n4 = input.readByte();
+ if ((n1 == 13) && (n2 == 10) && (n3 == 13) && (n4 == 10))
+ {
+ stripped = true;
+ }
+ }
+
+ // read chunk size
+ if (bytesInChunk == 0)
+ {
+ n1 = input.readByte();
+ n2 = input.readByte();
+
+ chunkSize.writeByte(n1);
+ chunkSize.writeByte(n2);
+
+ while (!((n1 == 13) && (n2 == 10)))
+ {
+ n1 = n2;
+ n2 = input.readByte();
+ chunkSize.writeByte(n2);
+ }
+
+ bytesInChunk = parseInt(chunkSize.toString(), 16);
+ }
+
+ input.readBytes(buf, off, len);
+ debugBuffer(buf);
+ bytesInChunk -= len;
+
+ if (bytesInChunk == 0)
+ {
+ // advance the : "\r\n"
+ input.readUTFBytes(2);
+ }
+
+ CountConsumedMessageBytes(len);
+ return len;
+ }
+ catch (e : EOFError)
+ {
+ trace(e);
+ throw new TTransportException(TTransportException.UNKNOWN, "No more data available.");
+ }
+ catch (e : TException)
+ {
+ trace('TException $e');
+ throw e;
+ }
+ catch (e : Error)
+ {
+ trace(e);
+ throw new TTransportException(TTransportException.UNKNOWN, 'Bad IO error: $e');
+ }
+ catch (e : Dynamic)
+ {
+ trace(e);
+ throw new TTransportException(TTransportException.UNKNOWN, 'Bad IO error: $e');
+ }
+ return 0;
+ }
+
+ public function debugBuffer(buf : Bytes) : Void
+ {
+ var debug : String = "BUFFER >>";
+ var i : Int;
+ for (i = 0; i < buf.length; i++)
+ {
+ debug += buf[i] as int;
+ debug += " ";
+ }
+
+ trace(debug + "<<");
+ }
+
+ public override function write(buf : Bytes, off : Int, len : Int) : Void
+ {
+ obuffer.writeBytes(buf, off, len);
+ }
+
+ public function addEventListener(type : String, listener : Function, useCapture : Bool = false, priority : Int = 0, useWeakReference : Bool = false) : Void
+ {
+ this.eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
+ }
+
+ public override function open() : Void
+ {
+ this.socket = new Socket();
+ this.socket.addEventListener(Event.CONNECT, socketConnected);
+ this.socket.addEventListener(IOErrorEvent.IO_ERROR, socketError);
+ this.socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, socketSecurityError);
+ this.socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
+ this.socket.connect(host, port);
+ ResetConsumedMessageSize();
+ }
+
+ public function socketConnected(event : Event) : Void
+ {
+ this.output = this.socket;
+ this.input = this.socket;
+ this.output.writeUTF( "CONNECT " + resource + " HTTP/1.1\n"
+ + "Host : " + host + ":" + port + "\r\n"
+ + "User-Agent : Thrift/Haxe\r\n"
+ + "Transfer-Encoding : chunked\r\n"
+ + "Content-Type : application/x-thrift\r\n"
+ + "Accept : */*\r\n"
+ + "\r\n");
+ this.eventDispatcher.dispatchEvent(event);
+ }
+
+ public function socketError(event : IOErrorEvent) : Void
+ {
+ trace("Error Connecting:" + event);
+ this.close();
+ if (ioCallback == null)
+ {
+ return;
+ }
+ ioCallback(new TTransportException(TTransportException.UNKNOWN, "IOError : " + event.text));
+ this.eventDispatcher.dispatchEvent(event);
+ }
+
+ public function socketSecurityError(event : SecurityErrorEvent) : Void
+ {
+ trace("Security Error Connecting:" + event);
+ this.close();
+ this.eventDispatcher.dispatchEvent(event);
+ }
+
+ public function socketDataHandler(event : ProgressEvent) : Void
+ {
+ trace("Got Data call:" +ioCallback);
+ if (ioCallback != null)
+ {
+ ioCallback(null);
+ };
+ this.eventDispatcher.dispatchEvent(event);
+ }
+
+ public override function flush(callback : Error->Void = null) : Void
+ {
+ trace("set callback:" + callback);
+ this.ioCallback = callback;
+ this.output.writeUTF(this.obuffer.length.toString(16));
+ this.output.writeBytes(CRLF);
+ this.output.writeBytes(this.obuffer);
+ this.output.writeBytes(CRLF);
+ this.socket.flush();
+ this.obuffer = new Bytes();
+ ResetConsumedMessageSize();
+ }
+
+ public override function isOpen() : Bool
+ {
+ return (this.socket != null) && this.socket.connected;
+ }
} \ No newline at end of file
diff --git a/lib/haxe/src/org/apache/thrift/transport/THttpClient.hx b/lib/haxe/src/org/apache/thrift/transport/THttpClient.hx
index 79f86610d..703dd81f6 100644
--- a/lib/haxe/src/org/apache/thrift/transport/THttpClient.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/THttpClient.hx
@@ -20,6 +20,7 @@
package org.apache.thrift.transport;
+import haxe.Timer;
import haxe.io.Bytes;
import haxe.io.BytesBuffer;
import haxe.io.BytesOutput;
@@ -27,6 +28,9 @@ import haxe.io.BytesInput;
import haxe.Http;
+#if js
+import js.lib.Promise;
+#end
/**
@@ -34,7 +38,7 @@ import haxe.Http;
* Thrift web services implementation.
*/
-class THttpClient extends TTransport {
+class THttpClient extends TEndpointTransport {
private var requestBuffer_ : BytesOutput = new BytesOutput();
private var responseBuffer_ : BytesInput = null;
@@ -42,20 +46,23 @@ class THttpClient extends TTransport {
private var request_ : Http = null;
- public function new( requestUrl : String) : Void {
- request_ = new Http(requestUrl);
- request_.addHeader( "contentType", "application/x-thrift");
+ public function new( requestUrl : String, config : TConfiguration = null) : Void {
+ super(config);
+
+ request_ = new Http(requestUrl);
+ request_.addHeader( "Content-Type", "application/x-thrift");
}
public override function open() : Void {
+ ResetConsumedMessageSize();
}
public override function close() : Void {
}
public override function isOpen() : Bool {
- return true;
+ return true;
}
public override function read(buf:BytesBuffer, off : Int, len : Int) : Int {
@@ -66,6 +73,7 @@ class THttpClient extends TTransport {
var data =Bytes.alloc(len);
len = responseBuffer_.readBytes(data, off, len);
buf.addBytes(data,0,len);
+ CountConsumedMessageBytes(len);
return len;
}
@@ -78,24 +86,36 @@ class THttpClient extends TTransport {
var buffer = requestBuffer_;
requestBuffer_ = new BytesOutput();
responseBuffer_ = null;
+ ResetConsumedMessageSize();
+ /*
request_.onData = function(data : String) {
- var tmp = new BytesBuffer();
- tmp.addString(data);
- responseBuffer_ = new BytesInput(tmp.getBytes());
- if( callback != null) {
- callback(null);
- }
+ var tmp = new BytesBuffer();
+ tmp.addString(data);
+ responseBuffer_ = new BytesInput(tmp.getBytes());
+ if( callback != null) {
+ callback(null);
};
-
- request_.onError = function(msg : String) {
- if( callback != null) {
- callback(new TTransportException(TTransportException.UNKNOWN, "IOError: " + msg));
- }
- };
-
- request_.setPostData(buffer.getBytes().toString());
- request_.request(true/*POST*/);
+ */
+
+ request_.onBytes = function(data : Bytes) {
+ responseBuffer_ = new BytesInput(data);
+ if( callback != null) {
+ callback(null);
+ }
+ };
+
+ request_.onError = function(msg : String) {
+ if( callback != null) {
+ callback(new TTransportException(TTransportException.UNKNOWN, "IOError: " + msg));
+ }
+ };
+
+
+ // the request
+ request_.setPostBytes(buffer.getBytes());
+ request_.request(true/*POST*/);
+
}
}
diff --git a/lib/haxe/src/org/apache/thrift/transport/TLayeredTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TLayeredTransport.hx
new file mode 100644
index 000000000..161d91edd
--- /dev/null
+++ b/lib/haxe/src/org/apache/thrift/transport/TLayeredTransport.hx
@@ -0,0 +1,50 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.thrift.transport;
+
+import haxe.Int64;
+import org.apache.thrift.TConfiguration;
+
+class TLayeredTransport extends TTransport
+{
+ private var InnerTransport : TTransport;
+
+ public override function get_Configuration() : TConfiguration {
+ return InnerTransport.Configuration;
+ }
+
+ // private CTOR to prevent direct instantiation
+ // in other words, this class MUST be extended
+ private function new(transport : TTransport)
+ {
+ if( transport != null)
+ InnerTransport = transport;
+ else
+ throw new TTransportException( TTransportException.UNKNOWN, "Inner transport must not be null");
+ }
+
+ public override function UpdateKnownMessageSize(size : Int64) : Void
+ {
+ InnerTransport.UpdateKnownMessageSize(size);
+ }
+
+ public override function CheckReadBytesAvailable(numBytes : Int64) : Void
+ {
+ InnerTransport.CheckReadBytesAvailable(numBytes);
+ }
+}
diff --git a/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx b/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx
index 4badb2a1f..e1ef5a18f 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx
@@ -19,7 +19,10 @@
package org.apache.thrift.transport;
-import haxe.remoting.SocketProtocol;
+#if (cs || neko || cpp || java || macro || lua || php || python || hl)
+import sys.net.Socket;
+#end
+
import haxe.io.Bytes;
import haxe.io.BytesBuffer;
import haxe.io.BytesInput;
@@ -27,9 +30,9 @@ import haxe.io.BytesOutput;
import haxe.io.Input;
import haxe.io.Output;
import haxe.io.Eof;
+import org.apache.thrift.TConfiguration;
-//import flash.net.ServerSocket; - not yet available on Haxe 3.1.3
-#if ! (flash || html5)
+#if ! (flash || html5 || js)
import sys.net.Host;
@@ -46,8 +49,10 @@ class TServerSocket extends TServerTransport {
private var _useBufferedSockets : Bool = false;
- public function new(?address : String = 'localhost', port : Int, clientTimeout : Float = 5, useBufferedSockets : Bool = false)
+ public function new(?address : String = 'localhost', port : Int, clientTimeout : Float = 5, useBufferedSockets : Bool = false, config : TConfiguration = null)
{
+ super(config);
+
_clientTimeout = clientTimeout;
_useBufferedSockets = useBufferedSockets;
diff --git a/lib/haxe/src/org/apache/thrift/transport/TServerTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TServerTransport.hx
index 21899819e..16fa564d5 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TServerTransport.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TServerTransport.hx
@@ -21,6 +21,15 @@ package org.apache.thrift.transport;
class TServerTransport {
+ private var Configuration(default,null) : TConfiguration;
+
+ // private CTOR to prevent direct instantiation
+ // in other words, this class MUST be extended
+ private function new( config : TConfiguration)
+ {
+ Configuration = (config != null) ? config : new TConfiguration();
+ }
+
public function Accept() : TTransport {
var transport = AcceptImpl();
if (transport == null) {
diff --git a/lib/haxe/src/org/apache/thrift/transport/TSocket.hx b/lib/haxe/src/org/apache/thrift/transport/TSocket.hx
index 7941ab9fe..a7435437f 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TSocket.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TSocket.hx
@@ -19,12 +19,12 @@
package org.apache.thrift.transport;
-#if flash
+#if (cs || neko || cpp || java || macro || lua || php || python || hl)
+import sys.net.Socket;
+#elseif flash
import flash.net.Socket;
#elseif js
import js.html.WebSocket;
-#else
-import haxe.remoting.SocketProtocol;
#end
import haxe.io.Bytes;
@@ -34,6 +34,7 @@ import haxe.io.BytesOutput;
import haxe.io.Input;
import haxe.io.Output;
import haxe.io.Eof;
+import org.apache.thrift.TConfiguration;
#if ! (flash || js)
@@ -46,7 +47,7 @@ import sys.net.Host;
* Thrift Socket Server based implementations.
*/
-class TSocket extends TTransport {
+class TSocket extends TEndpointTransport {
#if (flash || js)
private var host : String;
@@ -79,7 +80,9 @@ class TSocket extends TTransport {
private var ioCallback : TException->Void = null;
private var readCount : Int = 0;
- public function new(host : String, port : Int) : Void {
+ public function new(host : String, port : Int, config : TConfiguration = null) : Void {
+ super(config);
+
#if (flash || js)
this.host = host;
#else
@@ -132,6 +135,7 @@ class TSocket extends TTransport {
buf.addByte( input.readByte());
--remaining;
}
+ CountConsumedMessageBytes(len);
return len;
#elseif js
@@ -144,6 +148,7 @@ class TSocket extends TTransport {
buf.addByte( input.get(off+nr));
++nr;
}
+ CountConsumedMessageBytes(len);
return len;
#else
@@ -158,6 +163,7 @@ class TSocket extends TTransport {
var got = input.readBytes(data, 0, len);
buf.addBytes( data, 0, got);
readCount += got;
+ CountConsumedMessageBytes(got);
return got;
#end
@@ -223,6 +229,7 @@ class TSocket extends TTransport {
#end
obuffer = new BytesOutput();
+ ResetConsumedMessageSize();
ioCallback = callback;
@@ -262,7 +269,7 @@ class TSocket extends TTransport {
public override function open() : Void
{
#if js
- var socket = new WebSocket();
+ var socket = new WebSocket(host);
socket.onmessage = function( event : js.html.MessageEvent) {
this.input = event.data;
}
@@ -287,6 +294,7 @@ class TSocket extends TTransport {
#end
assignSocket( socket);
+ ResetConsumedMessageSize();
}
#if js
@@ -308,11 +316,26 @@ class TSocket extends TTransport {
#end
}
+ #if (flash)
+
+ public function setTimeout( timeout : UInt) : Void {
+ if(isOpen()) {
+ socket.timeout = timeout;
+ }
+ this.timeout = timeout;
+ }
+
+ #else
+
public function setTimeout( timeout : Float ) : Void {
if(isOpen()) {
- socket.setTimeout(timeout);
+ #if ! (js)
+ socket.setTimeout(timeout);
+ #end
}
this.timeout = timeout;
}
+ #end
+
}
diff --git a/lib/haxe/src/org/apache/thrift/transport/TStreamTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TStreamTransport.hx
index 31a7c141e..59bef15d3 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TStreamTransport.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TStreamTransport.hx
@@ -19,6 +19,7 @@
package org.apache.thrift.transport;
+import org.apache.thrift.TConfiguration;
import org.apache.thrift.transport.*;
import org.apache.thrift.helper.*;
@@ -28,13 +29,15 @@ import haxe.io.BytesOutput;
import haxe.io.BytesInput;
-class TStreamTransport extends TTransport {
+class TStreamTransport extends TEndpointTransport {
public var InputStream(default,null) : TStream;
public var OutputStream(default,null) : TStream;
- public function new( input : TStream, output : TStream) {
+ public function new( input : TStream, output : TStream, config : TConfiguration) {
+ super(config);
+
this.InputStream = input;
this.OutputStream = output;
}
@@ -48,7 +51,7 @@ class TStreamTransport extends TTransport {
}
public override function open() : Void {
- }
+ }
public override function close() : Void {
if (InputStream != null)
diff --git a/lib/haxe/src/org/apache/thrift/transport/TTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TTransport.hx
index e6b31791f..8d2b5b8b9 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TTransport.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TTransport.hx
@@ -19,12 +19,18 @@
package org.apache.thrift.transport;
+import haxe.Int64;
import haxe.io.Eof;
import haxe.io.Bytes;
import haxe.io.BytesBuffer;
import org.apache.thrift.AbstractMethodError;
class TTransport {
+
+ public var Configuration(get, never) : TConfiguration;
+ public function get_Configuration() : TConfiguration throw "abstract method called";
+ public function UpdateKnownMessageSize(size : Int64) : Void throw "abstract method called";
+ public function CheckReadBytesAvailable(numBytes : Int64) : Void throw "abstract method called";
/**
* Queries whether the transport is open.
diff --git a/lib/haxe/src/org/apache/thrift/transport/TWrappingServerTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TWrappingServerTransport.hx
index b2272f387..6da6e018b 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TWrappingServerTransport.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TWrappingServerTransport.hx
@@ -25,23 +25,25 @@ package org.apache.thrift.transport;
*/
class TWrappingServerTransport extends TServerTransport {
- private var transport(default,null) : TTransport;
+ private var transport(default,null) : TTransport;
- public function new(transport : TTransport) {
- this.transport = transport;
- }
+ public function new(transport : TTransport) {
+ super(transport.Configuration);
- public override function Listen() : Void
- {
- }
+ this.transport = transport;
+ }
- private override function AcceptImpl() : TTransport
- {
- return transport;
- }
+ public override function Listen() : Void
+ {
+ }
- public override function Close() : Void
- {
+ private override function AcceptImpl() : TTransport
+ {
+ return transport;
+ }
- }
+ public override function Close() : Void
+ {
+
+ }
}
diff --git a/test/haxe/Makefile.am b/test/haxe/Makefile.am
index 6c0483e9e..d37aaa77a 100644
--- a/test/haxe/Makefile.am
+++ b/test/haxe/Makefile.am
@@ -34,6 +34,13 @@ $(BIN_CPP): \
../../lib/haxe/src/org/apache/thrift/**/*.hx \
gen-haxe/thrift/test/ThriftTest.hx
$(HAXE) --cwd . cpp.hxml
+
+# $(HAXE) --cwd . csharp
+# $(HAXE) --cwd . flash
+# $(HAXE) --cwd . java
+# $(HAXE) --cwd . javascript
+# $(HAXE) --cwd . neko
+# $(HAXE) --cwd . python
$(BIN_PHP): \
src/*.hx \
@@ -49,15 +56,6 @@ $(BIN_PHP_WEB): \
-#TODO: other haxe targets
-# $(HAXE) --cwd . csharp
-# $(HAXE) --cwd . flash
-# $(HAXE) --cwd . java
-# $(HAXE) --cwd . javascript
-# $(HAXE) --cwd . neko
-# $(HAXE) --cwd . python # needs Haxe 3.2.0
-
-
clean-local:
$(RM) -r gen-haxe bin
diff --git a/test/haxe/TestClientServer.hxproj b/test/haxe/TestClientServer.hxproj
index 6696d80c2..44faa37ee 100644
--- a/test/haxe/TestClientServer.hxproj
+++ b/test/haxe/TestClientServer.hxproj
@@ -4,7 +4,7 @@
<output>
<movie outputType="Application" />
<movie input="" />
- <movie path="bin/TestClientServer" />
+ <movie path="bin\TestClientServer" />
<movie fps="30" />
<movie width="800" />
<movie height="600" />
@@ -17,7 +17,7 @@
<classpaths>
<class path="src" />
<class path="gen-haxe" />
- <class path="../../lib/haxe/src" />
+ <class path="..\..\lib\haxe\src" />
</classpaths>
<!-- Build options -->
<build>
diff --git a/test/haxe/make_all.bat b/test/haxe/make_all.bat
index eaeba890d..966bfa530 100644
--- a/test/haxe/make_all.bat
+++ b/test/haxe/make_all.bat
@@ -30,16 +30,19 @@ thrift -r -gen haxe ..\ThriftTest.thrift
if errorlevel 1 goto STOP
rem # invoke Haxe compiler for all targets
+rd .buildtemp /S /Q
for %%a in (*.hxml) do (
- rem * filter Python, as it is not supported by Haxe 3.1.3 (but will be in 3.1.4)
- if not "%%a"=="python.hxml" (
- echo --------------------------
- echo Building %%a ...
- echo --------------------------
- haxe --cwd . %%a
- )
+ echo --------------------------
+ echo Building %%a ...
+ echo --------------------------
+ haxe --cwd . %%a
+ if not exist ".buildtemp" mkdir ".buildtemp"
+ move bin ".buildtemp\%%a"
+ if errorlevel 1 pause
)
+rd bin /S /Q
+rename .buildtemp bin
echo.
echo done.
diff --git a/test/haxe/php-web-server.hxml b/test/haxe/php-web-server.hxml
index 395a8521e..f628c3a51 100644
--- a/test/haxe/php-web-server.hxml
+++ b/test/haxe/php-web-server.hxml
@@ -26,8 +26,8 @@
-main Main
#PHP target
--php bin/php-web-server/
---php-front Main-debug.php
+-php bin/php-web-server
+-D php-front=Main-debug.php
#defines
-D phpwebserver
diff --git a/test/haxe/php.hxml b/test/haxe/php.hxml
index 965189843..c3aa97fb3 100644
--- a/test/haxe/php.hxml
+++ b/test/haxe/php.hxml
@@ -26,8 +26,8 @@
-main Main
#PHP target
--php bin/php/
---php-front Main-debug.php
+-php bin/php
+-D php-front=Main-debug.php
#Add debug information
diff --git a/test/haxe/src/Arguments.hx b/test/haxe/src/Arguments.hx
index 56e525356..023f250fd 100644
--- a/test/haxe/src/Arguments.hx
+++ b/test/haxe/src/Arguments.hx
@@ -92,7 +92,7 @@ class Arguments
#if sys
private static function GetHelp() : String {
- var sProg = Path.withoutDirectory( Sys.executablePath());
+ var sProg = Path.withoutDirectory( Sys.programPath());
return "\n"
+sProg+" [client|server] [options]\n"
+"\n"
diff --git a/test/haxe/src/TestClient.hx b/test/haxe/src/TestClient.hx
index 853319e23..579dc00a1 100644
--- a/test/haxe/src/TestClient.hx
+++ b/test/haxe/src/TestClient.hx
@@ -35,7 +35,7 @@ import org.apache.thrift.server.*;
import org.apache.thrift.meta_data.*;
#if cpp
-import cpp.vm.Thread;
+import sys.thread.Thread;
#else
// no thread support (yet)
#end
diff --git a/test/haxe/src/TestServer.hx b/test/haxe/src/TestServer.hx
index 450c8f28c..d44c68cfa 100644
--- a/test/haxe/src/TestServer.hx
+++ b/test/haxe/src/TestServer.hx
@@ -39,20 +39,24 @@ class TestServer
switch( args.transport) {
case socket:
trace("- socket port "+args.port);
+ #if (flash || html5 || js)
+ throw "Transport not supported on this platform";
+ #else
transport = new TServerSocket( args.port);
+ #end
case http:
trace("- http");
- #if !phpwebserver
- throw "HTTP server not implemented yet";
- //transport = new THttpServer( targetHost);
+ #if phpwebserver
+ transport = new TWrappingServerTransport(
+ new TStreamTransport(
+ new TFileStream("php://input", Read),
+ new TFileStream("php://output", Append),
+ null
+ )
+ );
#else
- transport = new TWrappingServerTransport(
- new TStreamTransport(
- new TFileStream("php://input", Read),
- new TFileStream("php://output", Append)
- )
- );
-
+ throw "Transport not supported on this platform";
+ //transport = new THttpServer( targetHost);
#end
default:
throw "Unhandled transport";
@@ -86,7 +90,7 @@ class TestServer
// Processor
- var handler = new TestServerHandler();
+ var handler : ThriftTest_service = new TestServerHandler();
var processor = new ThriftTestProcessor(handler);
// Simple Server
diff --git a/test/haxe/src/TestServerHandler.hx b/test/haxe/src/TestServerHandler.hx
index b8a2590d5..0e1910560 100644
--- a/test/haxe/src/TestServerHandler.hx
+++ b/test/haxe/src/TestServerHandler.hx
@@ -36,7 +36,7 @@ import haxe.ds.ObjectMap;
import thrift.test.*; // generated code
-class TestServerHandler implements ThriftTest {
+class TestServerHandler implements ThriftTest_service {
public var server:TServer;
@@ -465,8 +465,10 @@ class TestServerHandler implements ThriftTest {
*/
public function testOneway(secondsToSleep:haxe.Int32):Void
{
+ #if sys
trace("testOneway(" + secondsToSleep + "), sleeping...");
Sys.sleep(secondsToSleep);
+ #end
trace("testOneway finished");
}
diff --git a/tutorial/haxe/Tutorial.hxproj b/tutorial/haxe/Tutorial.hxproj
index 796f648a5..44e0efdbb 100644
--- a/tutorial/haxe/Tutorial.hxproj
+++ b/tutorial/haxe/Tutorial.hxproj
@@ -4,7 +4,7 @@
<output>
<movie outputType="Application" />
<movie input="" />
- <movie path="bin/HaxeTutorial" />
+ <movie path="bin\HaxeTutorial" />
<movie fps="30" />
<movie width="800" />
<movie height="600" />
@@ -17,7 +17,7 @@
<classpaths>
<class path="src" />
<class path="gen-haxe" />
- <class path="../../lib/haxe/src" />
+ <class path="..\..\lib\haxe\src" />
</classpaths>
<!-- Build options -->
<build>
diff --git a/tutorial/haxe/php-web-server.hxml b/tutorial/haxe/php-web-server.hxml
index 395a8521e..88007c18f 100644
--- a/tutorial/haxe/php-web-server.hxml
+++ b/tutorial/haxe/php-web-server.hxml
@@ -27,7 +27,7 @@
#PHP target
-php bin/php-web-server/
---php-front Main-debug.php
+-D php-front=Main-debug.php
#defines
-D phpwebserver
diff --git a/tutorial/haxe/php.hxml b/tutorial/haxe/php.hxml
index c2f68878e..42bbf7424 100644
--- a/tutorial/haxe/php.hxml
+++ b/tutorial/haxe/php.hxml
@@ -27,7 +27,7 @@
#PHP target
-php bin/php/
---php-front Main-debug.php
+-D php-front=Main-debug.php
#Add debug information
-debug
diff --git a/tutorial/haxe/src/CalculatorHandler.hx b/tutorial/haxe/src/CalculatorHandler.hx
index e9752db9f..fcb06d196 100644
--- a/tutorial/haxe/src/CalculatorHandler.hx
+++ b/tutorial/haxe/src/CalculatorHandler.hx
@@ -31,7 +31,7 @@ import tutorial.*;
import shared.*;
-class CalculatorHandler implements Calculator {
+class CalculatorHandler implements Calculator_service {
private var log = new IntMap<SharedStruct>();
diff --git a/tutorial/haxe/src/Main.hx b/tutorial/haxe/src/Main.hx
index 6bebe7164..a56549f8c 100644
--- a/tutorial/haxe/src/Main.hx
+++ b/tutorial/haxe/src/Main.hx
@@ -32,6 +32,7 @@ import shared.*;
enum Prot {
binary;
json;
+ compact;
}
enum Trns {
@@ -112,12 +113,12 @@ class Main {
#if ! (flash || js)
private static function GetHelp() : String {
- return Sys.executablePath()+" modus trnsOption transport protocol\n"
+ return Sys.programPath+" modus layered transport protocol\n"
+"Options:\n"
- +" modus: client, server (default: client)\n"
- +" trnsOption: framed, buffered (default: none)\n"
- +" transport: socket, http (default: socket)\n"
- +" protocol: binary, json (default: binary)\n"
+ +" modus: client, server (default: client)\n"
+ +" layered: framed, buffered (default: none)\n"
+ +" transport: socket, http (default: socket)\n"
+ +" protocol: binary, json, compact (default: binary)\n"
+"\n"
+"All arguments are optional.\n";
}
@@ -160,6 +161,9 @@ class Main {
} else if ( arg == "json") {
prot = json;
++step;
+ } else if ( arg == "compact") {
+ prot = compact;
+ ++step;
} else {
throw "Unknown protocol "+arg;
}
@@ -217,6 +221,9 @@ class Main {
case json:
trace("- JSON protocol");
protocol = new TJSONProtocol( transport);
+ case compact:
+ trace("- compact protocol");
+ protocol = new TCompactProtocol( transport);
default:
throw "Unhandled protocol";
}
@@ -232,7 +239,7 @@ class Main {
var client = ClientSetup();
try {
- client.ping();
+ client.ping();
trace("ping() successful");
} catch(error : TException) {
trace('ping() failed: $error');
@@ -310,11 +317,12 @@ class Main {
#else
trace("- http transport");
transport = new TWrappingServerTransport(
- new TStreamTransport(
- new TFileStream("php://input", Read),
- new TFileStream("php://output", Append)
- )
- );
+ new TStreamTransport(
+ new TFileStream("php://input", Read),
+ new TFileStream("php://output", Append),
+ null
+ )
+ );
#end
default:
@@ -341,11 +349,14 @@ class Main {
case json:
trace("- JSON protocol");
protfactory = new TJSONProtocolFactory();
+ case compact:
+ trace("- compact protocol");
+ protfactory = new TCompactProtocolFactory();
default:
throw "Unhandled protocol";
}
- var handler = new CalculatorHandler();
+ var handler : Calculator_service = new CalculatorHandler();
var processor = new CalculatorProcessor(handler);
var server = new TSimpleServer( processor, transport, transfactory, protfactory);
#if phpwebserver