This is an automated email from the ASF dual-hosted git repository.

jensg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/thrift.git


The following commit(s) were added to refs/heads/master by this push:
     new 2dcefad  THRIFT-5370 Haxe 4 compatibility incl TConfiguration & 
MAX_MESSAGE_SIZE Client: haxe Patch: Jens Geyer
2dcefad is described below

commit 2dcefadba853c9ad0ab5e908894213826ec3b43a
Author: Jens Geyer <[email protected]>
AuthorDate: Thu Feb 25 09:42:52 2021 +0100

    THRIFT-5370 Haxe 4 compatibility incl TConfiguration & MAX_MESSAGE_SIZE
    Client: haxe
    Patch: Jens Geyer
    
    This closes #2349
---
 .gitignore                                         |   1 +
 .../cpp/src/thrift/generate/t_haxe_generator.cc    | 409 ++++++++++----------
 configure.ac                                       |   2 +-
 lib/haxe/README.md                                 |  51 +--
 lib/haxe/haxelib.json                              |  12 +-
 lib/haxe/src/org/apache/thrift/Limits.hx           |   4 +-
 lib/haxe/src/org/apache/thrift/TConfiguration.hx   |  36 ++
 lib/haxe/src/org/apache/thrift/TException.hx       |   5 +
 lib/haxe/src/org/apache/thrift/helper/Int64Map.hx  |  47 ++-
 .../org/apache/thrift/protocol/TBinaryProtocol.hx  |  81 ++--
 .../org/apache/thrift/protocol/TCompactProtocol.hx |  88 +++--
 .../org/apache/thrift/protocol/TJSONProtocol.hx    |  94 ++---
 .../src/org/apache/thrift/protocol/TProtocol.hx    |   3 +
 .../apache/thrift/protocol/TProtocolDecorator.hx   |   6 +
 .../apache/thrift/protocol/TProtocolImplBase.hx    |  86 +++++
 .../apache/thrift/protocol/TRecursionTracker.hx    |  48 ---
 .../apache/thrift/transport/TBufferedTransport.hx  |  36 +-
 .../thrift/transport/TBufferedTransportFactory.hx  |   2 +-
 .../apache/thrift/transport/TEndpointTransport.hx  |  95 +++++
 .../apache/thrift/transport/TFramedTransport.hx    |  55 +--
 .../thrift/transport/TFramedTransportFactory.hx    |  10 +-
 .../thrift/transport/TFullDuplexHttpClient.hx      | 420 +++++++++++----------
 .../src/org/apache/thrift/transport/THttpClient.hx |  60 ++-
 .../apache/thrift/transport/TLayeredTransport.hx   |  50 +++
 .../org/apache/thrift/transport/TServerSocket.hx   |  13 +-
 .../apache/thrift/transport/TServerTransport.hx    |   9 +
 .../src/org/apache/thrift/transport/TSocket.hx     |  37 +-
 .../apache/thrift/transport/TStreamTransport.hx    |   9 +-
 .../src/org/apache/thrift/transport/TTransport.hx  |   6 +
 .../thrift/transport/TWrappingServerTransport.hx   |  30 +-
 test/haxe/Makefile.am                              |  16 +-
 test/haxe/TestClientServer.hxproj                  |   4 +-
 test/haxe/make_all.bat                             |  17 +-
 test/haxe/php-web-server.hxml                      |   4 +-
 test/haxe/php.hxml                                 |   4 +-
 test/haxe/src/Arguments.hx                         |   2 +-
 test/haxe/src/TestClient.hx                        |   2 +-
 test/haxe/src/TestServer.hx                        |  26 +-
 test/haxe/src/TestServerHandler.hx                 |   4 +-
 tutorial/haxe/Tutorial.hxproj                      |   4 +-
 tutorial/haxe/php-web-server.hxml                  |   2 +-
 tutorial/haxe/php.hxml                             |   2 +-
 tutorial/haxe/src/CalculatorHandler.hx             |   2 +-
 tutorial/haxe/src/Main.hx                          |  35 +-
 44 files changed, 1172 insertions(+), 757 deletions(-)

diff --git a/.gitignore b/.gitignore
index 603838f..c34d9f6 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 725a534..9f8e946 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 98327f4..2d6d62b 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 c9f74b5..1f09c2c 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 14d0dcb..61448da 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 44eec3a..3a7807d 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 0000000..c5ec4e5
--- /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 54fa1ff..8bd9fcc 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 8845fd0..a8e735f 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 7ef291c..2cc254b 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 03b13e2..ae626b5 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 e20ff33..145eab9 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 b7f3842..316067a 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 769e93c..011f42b 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 0000000..60e4a1f
--- /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 cf0211b..0000000
--- 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 4b33fcf..72ce921 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 539e720..11d1a72 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 0000000..8c0d3ef
--- /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 cef82ef..37e4959 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 8d45a64..ca04e7f 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 1972853..cc34ec4 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 79f8661..703dd81 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 0000000..161d91e
--- /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 4badb2a..e1ef5a1 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 2189981..16fa564 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 7941ab9..a743543 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 31a7c14..59bef15 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 e6b3179..8d2b5b8 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 b2272f3..6da6e01 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 6c0483e..d37aaa7 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 6696d80..44faa37 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 eaeba89..966bfa5 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 395a852..f628c3a 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 9651898..c3aa97f 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 56e5253..023f250 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 853319e..579dc00 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 450c8f2..d44c68c 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 b8a2590..0e19105 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 796f648..44e0efd 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 395a852..88007c1 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 c2f6887..42bbf74 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 e9752db..fcb06d1 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 6bebe71..a56549f 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

Reply via email to