You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by je...@apache.org on 2014/11/11 01:41:35 UTC

[1/3] thrift git commit: THRIFT-2813 multiple haxe library fixes/improvements Client: Haxe Patch: Jens Geyer

Repository: thrift
Updated Branches:
  refs/heads/master 6794c6248 -> e5ff9a860


THRIFT-2813 multiple haxe library fixes/improvements
Client: Haxe
Patch: Jens Geyer

This closes #260


Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/65e9bde0
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/65e9bde0
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/65e9bde0

Branch: refs/heads/master
Commit: 65e9bde0ede772c9148e33ccc9be7f92eeeb9638
Parents: 6794c62
Author: Jens Geyer <je...@apache.org>
Authored: Tue Nov 11 01:30:02 2014 +0100
Committer: Jens Geyer <je...@apache.org>
Committed: Tue Nov 11 01:35:21 2014 +0100

----------------------------------------------------------------------
 lib/Makefile.am                                 |  1 +
 lib/haxe/haxelib.json                           | 11 ++++
 .../src/org/apache/thrift/server/TServer.hx     |  7 +-
 .../org/apache/thrift/server/TSimpleServer.hx   | 14 ++--
 .../apache/thrift/transport/TFramedTransport.hx | 62 +++++++++++-------
 .../apache/thrift/transport/TServerSocket.hx    |  4 +-
 .../src/org/apache/thrift/transport/TSocket.hx  | 17 +++--
 lib/haxe/test/HaxeTests.hxproj                  | 67 ++++++++++++++++++++
 lib/haxe/test/Makefile.am                       | 14 ++++
 test/haxe/Makefile.am                           | 14 ++++
 test/haxe/TestClientServer.hxproj               | 67 ++++++++++++++++++++
 tutorial/haxe/Makefile.am                       | 16 ++++-
 tutorial/haxe/Tutorial.hxproj                   | 67 ++++++++++++++++++++
 13 files changed, 319 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/thrift/blob/65e9bde0/lib/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 5751a2c..7b235d0 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -85,6 +85,7 @@ EXTRA_DIST = \
 	cocoa \
 	d \
 	delphi \
+	haxe \
 	javame \
 	js \
 	ocaml \

http://git-wip-us.apache.org/repos/asf/thrift/blob/65e9bde0/lib/haxe/haxelib.json
----------------------------------------------------------------------
diff --git a/lib/haxe/haxelib.json b/lib/haxe/haxelib.json
new file mode 100644
index 0000000..a3bde74
--- /dev/null
+++ b/lib/haxe/haxelib.json
@@ -0,0 +1,11 @@
+{
+	"name": "thrift",
+	"url" : "http://thrift.apache.org",
+	"license": "Apache",
+	"tags": ["thrift", "rpc", "serialization", "cross", "framework"],
+	"description": "Haxe bindings for the Apache Thrift RPC and serialization framework",
+	"version": "0.9.2-beta.1",
+	"releasenote": "First release, based on Apache Thrift 0.9.2. For details see THRIFT-2644.",
+	"contributors": ["JensG"],
+	"dependencies": {}
+}

http://git-wip-us.apache.org/repos/asf/thrift/blob/65e9bde0/lib/haxe/src/org/apache/thrift/server/TServer.hx
----------------------------------------------------------------------
diff --git a/lib/haxe/src/org/apache/thrift/server/TServer.hx b/lib/haxe/src/org/apache/thrift/server/TServer.hx
index e689b32..56eee0a 100644
--- a/lib/haxe/src/org/apache/thrift/server/TServer.hx
+++ b/lib/haxe/src/org/apache/thrift/server/TServer.hx
@@ -38,7 +38,7 @@ class TServer
 
     // Log delegation
     private var _logDelegate : Dynamic->Void  = null;
-    public var logDelegate(default,set) : Dynamic->Void;
+    public var logDelegate(get,set) : Dynamic->Void;
 
     public function new( processor : TProcessor,
                          serverTransport : TServerTransport,
@@ -87,6 +87,11 @@ class TServer
     }
 
 
+    private function get_logDelegate() : Dynamic->Void {
+        return _logDelegate;
+    }
+
+
     private function DefaultLogDelegate(value : Dynamic) : Void  {
         trace( value);
     }

http://git-wip-us.apache.org/repos/asf/thrift/blob/65e9bde0/lib/haxe/src/org/apache/thrift/server/TSimpleServer.hx
----------------------------------------------------------------------
diff --git a/lib/haxe/src/org/apache/thrift/server/TSimpleServer.hx b/lib/haxe/src/org/apache/thrift/server/TSimpleServer.hx
index cb7cbd6..f3408e2 100644
--- a/lib/haxe/src/org/apache/thrift/server/TSimpleServer.hx
+++ b/lib/haxe/src/org/apache/thrift/server/TSimpleServer.hx
@@ -33,15 +33,14 @@ class TSimpleServer extends TServer  {
                          serverTransport : TServerTransport,
                          transportFactory : TTransportFactory = null,
                          protocolFactory : TProtocolFactory = null,
-                         logDelegate : Dynamic->Void = null) {
+                         logger : Dynamic->Void = null) {
       super( processor, serverTransport,
              transportFactory, transportFactory,
              protocolFactory, protocolFactory,
-             logDelegate);
+             logger);
     }
 
 
-
     public override function Serve() : Void
     {
         try
@@ -102,12 +101,15 @@ class TSimpleServer extends TServer  {
             }
             catch( ttx : TTransportException)
             {
-                  // Usually a client disconnect, expected
+                // Usually a client disconnect, expected
+            }
+            catch( pex : TProtocolException)
+            {
+                logDelegate(pex); // Unexpected
             }
             catch( e : Dynamic)
             {
-                // Unexpected
-                  logDelegate(e);
+                logDelegate(e); // Unexpected
             }
 
             // Fire deleteContext server event after client disconnects

http://git-wip-us.apache.org/repos/asf/thrift/blob/65e9bde0/lib/haxe/src/org/apache/thrift/transport/TFramedTransport.hx
----------------------------------------------------------------------
diff --git a/lib/haxe/src/org/apache/thrift/transport/TFramedTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TFramedTransport.hx
index 5f0168a..cef82ef 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.io.Eof;
 import haxe.io.Bytes;
 import haxe.io.BytesBuffer;
 import haxe.io.BytesOutput;
@@ -73,31 +74,41 @@ class TFramedTransport extends TTransport
     }
 
     public override function read(buf : BytesBuffer, off : Int, len : Int) : Int {
-        var data = Bytes.alloc(len);
-
-        if (readBuffer_ != null) {
-            var got : Int = readBuffer_.readBytes(data, off, len);
-            if (got > 0) {
-                buf.addBytes(data,0,got);
-                return got;
+        try {
+            var data = Bytes.alloc(len);
+
+            if ((readBuffer_ != null) && (readBuffer_.position < readBuffer_.length)) {
+                var got : Int = readBuffer_.readBytes(data, off, len);
+                if (got > 0) {
+                    buf.addBytes(data,0,got);
+                    return got;
+                };
             };
-        };
 
-        // Read another frame of data
-        readFrame();
+            // Read another frame of data
+            readFrame();
 
-        var got = readBuffer_.readBytes(data, off, len);
-        buf.addBytes(data,0,got);
-        return got;
+            var got = readBuffer_.readBytes(data, off, len);
+            buf.addBytes(data,0,got);
+            return got;
+        }
+        catch (eof : Eof) {
+            throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read $len bytes!');
+        }
     }
 
 
     function readFrameSize() : Int {
-        var buffer = new BytesBuffer();
-        var len = transport_.readAll( buffer, 0, 4);
-        var inp = new BytesInput( buffer.getBytes(), 0, 4);
-        inp.bigEndian = true;
-        return inp.readInt32();
+        try {
+            var buffer = new BytesBuffer();
+            var len = transport_.readAll( buffer, 0, 4);
+            var inp = new BytesInput( buffer.getBytes(), 0, 4);
+            inp.bigEndian = true;
+            return inp.readInt32();
+        }
+        catch(eof : Eof) {
+            throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read 4 bytes!');
+        }
     }
 
 
@@ -111,10 +122,15 @@ class TFramedTransport extends TTransport
             throw new TTransportException(TTransportException.UNKNOWN, 'Frame size ($size) larger than max length ($maxLength_)!');
         };
 
-        var buffer = new BytesBuffer();
-        size = transport_.readAll( buffer, 0, size);
-        readBuffer_ = new BytesInput( buffer.getBytes(), 0, size);
-        readBuffer_.bigEndian = true;
+        try {
+            var buffer = new BytesBuffer();
+            size = transport_.readAll( buffer, 0, size);
+            readBuffer_ = new BytesInput( buffer.getBytes(), 0, size);
+            readBuffer_.bigEndian = true;
+        }
+        catch(eof : Eof) {
+            throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read $size bytes!');
+        }
     }
 
     public override function write(buf : Bytes, off : Int, len : Int) : Void {
@@ -135,7 +151,7 @@ class TFramedTransport extends TTransport
 
         writeFrameSize(len);
         transport_.write(buf, 0, len);
-        transport_.flush();
+        transport_.flush(callback);
     }
 }
 

http://git-wip-us.apache.org/repos/asf/thrift/blob/65e9bde0/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx
----------------------------------------------------------------------
diff --git a/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx b/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx
index f38b584..586a8b6 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx
@@ -43,13 +43,13 @@ class TServerSocket extends TServerTransport {
     private var _port : Int = 0;
 
     // Timeout for client sockets from accept
-    private var _clientTimeout : Int = 0;
+    private var _clientTimeout : Float = 0;
 
     // Whether or not to wrap new TSocket connections in buffers
     private var _useBufferedSockets : Bool = false;
 
 
-    public function new( port : Int, clientTimeout : Int = 0, useBufferedSockets : Bool = false)
+    public function new( port : Int, clientTimeout : Float = 0, useBufferedSockets : Bool = false)
     {
         _port = port;
         _clientTimeout = clientTimeout;

http://git-wip-us.apache.org/repos/asf/thrift/blob/65e9bde0/lib/haxe/src/org/apache/thrift/transport/TSocket.hx
----------------------------------------------------------------------
diff --git a/lib/haxe/src/org/apache/thrift/transport/TSocket.hx b/lib/haxe/src/org/apache/thrift/transport/TSocket.hx
index 9d5e2dc..b6f2119 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TSocket.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TSocket.hx
@@ -83,6 +83,7 @@ class TSocket extends TTransport  {
         #else
         this.host = new Host(host);
         #end
+
         this.port = port;
     }
 
@@ -143,7 +144,7 @@ class TSocket extends TTransport  {
 
             #else
 
-            socket.waitForRead();
+            //socket.waitForRead();  -  no, this ignores timeout and blocks infinitely
             if(readCount < off) {
                 input.read(off-readCount);
                 readCount = off;
@@ -208,7 +209,6 @@ class TSocket extends TTransport  {
         }
         var bytes = outbuf.buffer;
 
-
         #else
 
         var bytes = obuffer.getBytes();
@@ -222,11 +222,13 @@ class TSocket extends TTransport  {
         ioCallback = callback;
         try {
             readCount = 0;
+
             #if js
             output.send( bytes);
             #else
             output.writeBytes( bytes, 0, bytes.length);
             #end
+
             if(ioCallback != null) {
                 ioCallback(null);  // success call
             }
@@ -260,15 +262,14 @@ class TSocket extends TTransport  {
         }
 
         #elseif flash
-
         var socket = new Socket();
         socket.connect(host, port);
 
         #else
-
         var socket = new Socket();
         socket.setBlocking(true);
         socket.setFastSend(true);
+        socket.setTimeout(5.0);
         socket.connect(host, port);
 
         #end
@@ -286,10 +287,12 @@ class TSocket extends TTransport  {
 
         #if (flash || js)
         output = socket;
-          input = socket;
+        input = socket;
+
         #else
-          output = socket.output;
-          input = socket.input;
+        output = socket.output;
+        input = socket.input;
+
         #end
     }
 

http://git-wip-us.apache.org/repos/asf/thrift/blob/65e9bde0/lib/haxe/test/HaxeTests.hxproj
----------------------------------------------------------------------
diff --git a/lib/haxe/test/HaxeTests.hxproj b/lib/haxe/test/HaxeTests.hxproj
new file mode 100644
index 0000000..4e8929b
--- /dev/null
+++ b/lib/haxe/test/HaxeTests.hxproj
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project version="2">
+  <!-- Output SWF options -->
+  <output>
+    <movie outputType="Application" />
+    <movie input="" />
+    <movie path="bin/HaxeTests" />
+    <movie fps="30" />
+    <movie width="800" />
+    <movie height="600" />
+    <movie version="1" />
+    <movie minorVersion="0" />
+    <movie platform="C++" />
+    <movie background="#FFFFFF" />
+  </output>
+  <!-- Other classes to be compiled into your SWF -->
+  <classpaths>
+    <class path="src" />
+    <class path="gen-haxe" />
+    <class path="../src" />
+  </classpaths>
+  <!-- Build options -->
+  <build>
+    <option directives="" />
+    <option flashStrict="False" />
+    <option noInlineOnDebug="False" />
+    <option mainClass="Main" />
+    <option enabledebug="False" />
+    <option additional="" />
+  </build>
+  <!-- haxelib libraries -->
+  <haxelib>
+    <!-- example: <library name="..." /> -->
+  </haxelib>
+  <!-- Class files to compile (other referenced classes will automatically be included) -->
+  <compileTargets>
+    <!-- example: <compile path="..." /> -->
+  </compileTargets>
+  <!-- Paths to exclude from the Project Explorer tree -->
+  <hiddenPaths>
+    <hidden path="obj" />
+    <hidden path="cpp.hxml" />
+    <hidden path="csharp.hxml" />
+    <hidden path="flash.hxml" />
+    <hidden path="java.hxml" />
+    <hidden path="javascript.hxml" />
+    <hidden path="make_all.bat" />
+    <hidden path="make_all.sh" />
+    <hidden path="Makefile.am" />
+    <hidden path="neko.hxml" />
+    <hidden path="php.hxml" />
+    <hidden path="project.hide" />
+    <hidden path="python.hxml" />
+  </hiddenPaths>
+  <!-- Executed before build -->
+  <preBuildCommand>thrift -r -gen haxe  ../../../test/ThriftTest.thrift</preBuildCommand>
+  <!-- Executed after build -->
+  <postBuildCommand alwaysRun="False" />
+  <!-- Other project options -->
+  <options>
+    <option showHiddenPaths="False" />
+    <option testMovie="Unknown" />
+    <option testMovieCommand="" />
+  </options>
+  <!-- Plugin storage -->
+  <storage />
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/65e9bde0/lib/haxe/test/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/haxe/test/Makefile.am b/lib/haxe/test/Makefile.am
index 5e92f98..357436c 100644
--- a/lib/haxe/test/Makefile.am
+++ b/lib/haxe/test/Makefile.am
@@ -48,3 +48,17 @@ clean-local:
 check: $(BIN_CPP)
 	$(BIN_CPP)
 
+EXTRA_DIST = \
+             src \
+             cpp.hxml \
+             csharp.hxml \
+             flash.hxml \
+             java.hxml \
+             javascript.hxml \
+             neko.hxml \
+             php.hxml \
+             python.hxml \
+             project.hide \
+             HaxeTests.hxproj \
+             make_all.bat \
+             make_all.sh

http://git-wip-us.apache.org/repos/asf/thrift/blob/65e9bde0/test/haxe/Makefile.am
----------------------------------------------------------------------
diff --git a/test/haxe/Makefile.am b/test/haxe/Makefile.am
index 127c45d..3d4894a 100644
--- a/test/haxe/Makefile.am
+++ b/test/haxe/Makefile.am
@@ -50,3 +50,17 @@ check: $(BIN_CPP)
 	sleep 1
 	$(BIN_CPP) client
 
+EXTRA_DIST = \
+             src \
+             cpp.hxml \
+             csharp.hxml \
+             flash.hxml \
+             java.hxml \
+             javascript.hxml \
+             neko.hxml \
+             php.hxml \
+             python.hxml \
+             project.hide \
+             TestClientServer.hxproj \
+             make_all.bat \
+             make_all.sh

http://git-wip-us.apache.org/repos/asf/thrift/blob/65e9bde0/test/haxe/TestClientServer.hxproj
----------------------------------------------------------------------
diff --git a/test/haxe/TestClientServer.hxproj b/test/haxe/TestClientServer.hxproj
new file mode 100644
index 0000000..6696d80
--- /dev/null
+++ b/test/haxe/TestClientServer.hxproj
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project version="2">
+  <!-- Output SWF options -->
+  <output>
+    <movie outputType="Application" />
+    <movie input="" />
+    <movie path="bin/TestClientServer" />
+    <movie fps="30" />
+    <movie width="800" />
+    <movie height="600" />
+    <movie version="1" />
+    <movie minorVersion="0" />
+    <movie platform="C++" />
+    <movie background="#FFFFFF" />
+  </output>
+  <!-- Other classes to be compiled into your SWF -->
+  <classpaths>
+    <class path="src" />
+    <class path="gen-haxe" />
+    <class path="../../lib/haxe/src" />
+  </classpaths>
+  <!-- Build options -->
+  <build>
+    <option directives="" />
+    <option flashStrict="False" />
+    <option noInlineOnDebug="False" />
+    <option mainClass="Main" />
+    <option enabledebug="False" />
+    <option additional="" />
+  </build>
+  <!-- haxelib libraries -->
+  <haxelib>
+    <!-- example: <library name="..." /> -->
+  </haxelib>
+  <!-- Class files to compile (other referenced classes will automatically be included) -->
+  <compileTargets>
+    <!-- example: <compile path="..." /> -->
+  </compileTargets>
+  <!-- Paths to exclude from the Project Explorer tree -->
+  <hiddenPaths>
+    <hidden path="obj" />
+    <hidden path="cpp.hxml" />
+    <hidden path="csharp.hxml" />
+    <hidden path="flash.hxml" />
+    <hidden path="java.hxml" />
+    <hidden path="javascript.hxml" />
+    <hidden path="make_all.bat" />
+    <hidden path="make_all.sh" />
+    <hidden path="Makefile.am" />
+    <hidden path="neko.hxml" />
+    <hidden path="php.hxml" />
+    <hidden path="project.hide" />
+    <hidden path="python.hxml" />
+  </hiddenPaths>
+  <!-- Executed before build -->
+  <preBuildCommand>thrift -r -gen haxe  ../ThriftTest.thrift</preBuildCommand>
+  <!-- Executed after build -->
+  <postBuildCommand alwaysRun="False" />
+  <!-- Other project options -->
+  <options>
+    <option showHiddenPaths="False" />
+    <option testMovie="Unknown" />
+    <option testMovieCommand="" />
+  </options>
+  <!-- Plugin storage -->
+  <storage />
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/65e9bde0/tutorial/haxe/Makefile.am
----------------------------------------------------------------------
diff --git a/tutorial/haxe/Makefile.am b/tutorial/haxe/Makefile.am
index 8212648..a781b5a 100644
--- a/tutorial/haxe/Makefile.am
+++ b/tutorial/haxe/Makefile.am
@@ -45,6 +45,16 @@ clean-local:
 	$(RM) -r gen-haxe bin
 
 EXTRA_DIST = \
-	src/Main.hx \
-	src/CalculatorHandler.hx
-
+             src \
+             cpp.hxml \
+             csharp.hxml \
+             flash.hxml \
+             java.hxml \
+             javascript.hxml \
+             neko.hxml \
+             php.hxml \
+             python.hxml \
+             project.hide \
+             Tutorial.hxproj \
+             make_all.bat \
+             make_all.sh

http://git-wip-us.apache.org/repos/asf/thrift/blob/65e9bde0/tutorial/haxe/Tutorial.hxproj
----------------------------------------------------------------------
diff --git a/tutorial/haxe/Tutorial.hxproj b/tutorial/haxe/Tutorial.hxproj
new file mode 100644
index 0000000..796f648
--- /dev/null
+++ b/tutorial/haxe/Tutorial.hxproj
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project version="2">
+  <!-- Output SWF options -->
+  <output>
+    <movie outputType="Application" />
+    <movie input="" />
+    <movie path="bin/HaxeTutorial" />
+    <movie fps="30" />
+    <movie width="800" />
+    <movie height="600" />
+    <movie version="1" />
+    <movie minorVersion="0" />
+    <movie platform="C++" />
+    <movie background="#FFFFFF" />
+  </output>
+  <!-- Other classes to be compiled into your SWF -->
+  <classpaths>
+    <class path="src" />
+    <class path="gen-haxe" />
+    <class path="../../lib/haxe/src" />
+  </classpaths>
+  <!-- Build options -->
+  <build>
+    <option directives="" />
+    <option flashStrict="False" />
+    <option noInlineOnDebug="False" />
+    <option mainClass="Main" />
+    <option enabledebug="False" />
+    <option additional="" />
+  </build>
+  <!-- haxelib libraries -->
+  <haxelib>
+    <!-- example: <library name="..." /> -->
+  </haxelib>
+  <!-- Class files to compile (other referenced classes will automatically be included) -->
+  <compileTargets>
+    <!-- example: <compile path="..." /> -->
+  </compileTargets>
+  <!-- Paths to exclude from the Project Explorer tree -->
+  <hiddenPaths>
+    <hidden path="obj" />
+    <hidden path="cpp.hxml" />
+    <hidden path="csharp.hxml" />
+    <hidden path="flash.hxml" />
+    <hidden path="java.hxml" />
+    <hidden path="javascript.hxml" />
+    <hidden path="make_all.bat" />
+    <hidden path="make_all.sh" />
+    <hidden path="Makefile.am" />
+    <hidden path="neko.hxml" />
+    <hidden path="php.hxml" />
+    <hidden path="project.hide" />
+    <hidden path="python.hxml" />
+  </hiddenPaths>
+  <!-- Executed before build -->
+  <preBuildCommand>thrift -r -gen haxe  ../tutorial.thrift</preBuildCommand>
+  <!-- Executed after build -->
+  <postBuildCommand alwaysRun="False" />
+  <!-- Other project options -->
+  <options>
+    <option showHiddenPaths="False" />
+    <option testMovie="Unknown" />
+    <option testMovieCommand="" />
+  </options>
+  <!-- Plugin storage -->
+  <storage />
+</project>
\ No newline at end of file


[2/3] thrift git commit: THRIFT-2814 args/result classes not found when no namespace is set Client: Haxe Patch: Jens Geyer

Posted by je...@apache.org.
THRIFT-2814 args/result classes not found when no namespace is set
Client: Haxe
Patch: Jens Geyer

This closes #261


Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/96dfcd5c
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/96dfcd5c
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/96dfcd5c

Branch: refs/heads/master
Commit: 96dfcd5c5d25df035c8e3ebd29cb160fb54fd822
Parents: 65e9bde
Author: Jens Geyer <je...@apache.org>
Authored: Tue Nov 11 01:32:19 2014 +0100
Committer: Jens Geyer <je...@apache.org>
Committed: Tue Nov 11 01:35:24 2014 +0100

----------------------------------------------------------------------
 compiler/cpp/src/generate/t_haxe_generator.cc | 180 +++++++++++----------
 1 file changed, 94 insertions(+), 86 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/thrift/blob/96dfcd5c/compiler/cpp/src/generate/t_haxe_generator.cc
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/generate/t_haxe_generator.cc b/compiler/cpp/src/generate/t_haxe_generator.cc
index 3c2207f..2a27518 100644
--- a/compiler/cpp/src/generate/t_haxe_generator.cc
+++ b/compiler/cpp/src/generate/t_haxe_generator.cc
@@ -86,9 +86,9 @@ class t_haxe_generator : public t_oop_generator {
    * Service-level generation functions
    */
 
-  void generate_haxe_struct(t_struct* tstruct, bool is_exception);
+  void generate_haxe_struct(t_struct* tstruct, bool is_exception, bool is_result = false);
 
-  void generate_haxe_struct_definition(std::ofstream& out, t_struct* tstruct, bool is_xception=false, bool in_class=false, bool is_result=false);
+  void generate_haxe_struct_definition(std::ofstream& out, t_struct* tstruct, bool is_xception=false, bool is_result=false);
   //removed -- equality,compare_to
   void generate_haxe_struct_reader(std::ofstream& out, t_struct* tstruct);
   void generate_haxe_validator(std::ofstream& out, t_struct* tstruct);
@@ -201,22 +201,22 @@ class t_haxe_generator : public t_oop_generator {
   bool type_can_be_null(t_type* ttype) {
     ttype = get_true_type(ttype);
 
-	if (ttype->is_container() || ttype->is_struct() || ttype->is_xception() || ttype->is_string()) {
-		return true;
-	}
+    if (ttype->is_container() || ttype->is_struct() || ttype->is_xception() || ttype->is_string()) {
+      return true;
+    }
 
-	if (ttype->is_base_type()) {
-		t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
-		switch (tbase) {
-		case t_base_type::TYPE_STRING:
-		case t_base_type::TYPE_I64:
-			return true;
-		default:
-			return false;
-		}
-	}
+    if (ttype->is_base_type()) {
+      t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
+      switch (tbase) {
+      case t_base_type::TYPE_STRING:
+      case t_base_type::TYPE_I64:
+        return true;
+      default:
+        return false;
+      }
+    }
 
-	return false;
+    return false;
   }
 
   std::string constant_name(std::string name);
@@ -388,14 +388,14 @@ void t_haxe_generator::generate_typedef(t_typedef* ttypedef) {
  */
 void t_haxe_generator::generate_enum(t_enum* tenum) {
   // Make output file
-  string f_enum_name = package_dir_+"/"+(tenum->get_name()) + ".hx";
+  string f_enum_name = package_dir_ + "/" + get_cap_name(tenum->get_name()) + ".hx";
   ofstream f_enum;
   f_enum.open(f_enum_name.c_str());
 
   // Comment and package it
   f_enum <<
     autogen_comment() <<
-    haxe_package() << ";" << endl;
+    haxe_package() << ";" << endl << endl;
   
   // Add haxe imports
   f_enum << string() +
@@ -403,7 +403,7 @@ void t_haxe_generator::generate_enum(t_enum* tenum) {
   endl;
   
   indent(f_enum) <<
-    "class " << tenum->get_name() << " ";
+    "class " << get_cap_name(tenum->get_name()) << " ";
   scope_up(f_enum);
 
   vector<t_enum_value*> constants = tenum->get_constants();
@@ -454,13 +454,13 @@ void t_haxe_generator::generate_consts(std::vector<t_const*> consts) {
     return;
   }
 
-  string f_consts_name = package_dir_+ "/" + program_name_ + "Constants.hx";
+  string f_consts_name = package_dir_ + "/" + get_cap_name(program_name_) + "Constants.hx";
   ofstream f_consts;
   f_consts.open(f_consts_name.c_str());
 
   // Print header
   f_consts <<
-    autogen_comment() << haxe_package() << ";" << endl;
+    autogen_comment() << haxe_package() << ";" << endl << endl;
   
   f_consts << endl;
   
@@ -469,7 +469,7 @@ void t_haxe_generator::generate_consts(std::vector<t_const*> consts) {
  
   
   indent(f_consts) <<
-    "class " << program_name_ << 
+    "class " << get_cap_name(program_name_) <<
     "Constants {" << endl << endl;
   indent_up();
   vector<t_const*>::iterator c_iter;
@@ -678,9 +678,10 @@ void t_haxe_generator::generate_xception(t_struct* txception) {
  * @param tstruct The struct definition
  */
 void t_haxe_generator::generate_haxe_struct(t_struct* tstruct,
-                                            bool is_exception) {
+                                            bool is_exception,
+                                            bool is_result) {
   // Make output file
-  string f_struct_name = package_dir_+"/"+(tstruct->get_name()) + ".hx";
+  string f_struct_name = package_dir_ + "/" + get_cap_name(tstruct->get_name()) + ".hx";
   ofstream f_struct;
   f_struct.open(f_struct_name.c_str());
 
@@ -697,9 +698,7 @@ void t_haxe_generator::generate_haxe_struct(t_struct* tstruct,
     haxe_thrift_imports() << 
     haxe_thrift_gen_imports(tstruct, imports) << endl;
   
-  generate_haxe_struct_definition(f_struct,
-                                  tstruct,
-                                  is_exception);
+  generate_haxe_struct_definition(f_struct, tstruct, is_exception, is_result);
   
   f_struct.close();
 }
@@ -717,9 +716,7 @@ void t_haxe_generator::generate_haxe_struct(t_struct* tstruct,
 void t_haxe_generator::generate_haxe_struct_definition(ofstream &out,
                                                        t_struct* tstruct,
                                                        bool is_exception,
-                                                       bool in_class,
                                                        bool is_result) {
-  (void) in_class;
   generate_haxe_doc(out, tstruct);
 
   string clsname = get_cap_name( tstruct->get_name());
@@ -754,7 +751,7 @@ void t_haxe_generator::generate_haxe_struct_definition(ofstream &out,
     generate_haxe_doc(out, *m_iter);
     //indent(out) << "private var _" << (*m_iter)->get_name() + " : " + type_name((*m_iter)->get_type()) << ";" << endl;
     indent(out) << "@:isVar" << endl;
-    indent(out) << "public var " << (*m_iter)->get_name() + "(get,set) : " + type_name((*m_iter)->get_type()) << ";" << endl;
+    indent(out) << "public var " << (*m_iter)->get_name() + "(get,set) : " + get_cap_name(type_name((*m_iter)->get_type())) << ";" << endl;
   }
   
   out << endl;
@@ -1205,8 +1202,8 @@ void t_haxe_generator::generate_property_getters_setters(ofstream& out,
         
     // Simple getter
     generate_haxe_doc(out, field);
-    indent(out) << "public function get_" << field_name << "():" <<
-      type_name(type) << " {" << endl;
+    indent(out) << "public function get_" << field_name << "() : " <<
+      get_cap_name(type_name(type)) << " {" << endl;
     indent_up();
     indent(out) << "return this." << field_name << ";" << endl;
     indent_down();
@@ -1216,8 +1213,8 @@ void t_haxe_generator::generate_property_getters_setters(ofstream& out,
     generate_haxe_doc(out, field);
     indent(out) << 
       "public function set_" << field_name << 
-      "(" << field_name << ":" << type_name(type) << ") : " << 
-      type_name(type) << " {" << endl;
+      "(" << field_name << ":" << get_cap_name(type_name(type)) << ") : " <<
+      get_cap_name(type_name(type)) << " {" << endl;
     indent_up();
     indent(out) << 
       "this." << field_name << " = " << field_name << ";" << endl;
@@ -1443,7 +1440,7 @@ void t_haxe_generator::generate_field_value_meta_data(std::ofstream& out, t_type
  */
 void t_haxe_generator::generate_service(t_service* tservice) {
   // Make interface file
-  string f_service_name = package_dir_+"/"+service_name_ + ".hx";
+  string f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + ".hx";
   f_service_.open(f_service_name.c_str());
 
   f_service_ <<
@@ -1469,7 +1466,7 @@ void t_haxe_generator::generate_service(t_service* tservice) {
   f_service_.close();
   
   // Now make the implementation/client file
-  f_service_name = package_dir_+"/"+service_name_+"Impl.hx";
+  f_service_name = package_dir_+"/"+get_cap_name(service_name_)+"Impl.hx";
   f_service_.open(f_service_name.c_str());
   
   f_service_ <<
@@ -1491,12 +1488,14 @@ void t_haxe_generator::generate_service(t_service* tservice) {
   f_service_ << endl;
 
   generate_service_client(tservice);
-  generate_service_helpers(tservice);
-  
+
   f_service_.close();
-  
+
+  // Now make the helper class files
+  generate_service_helpers(tservice);
+
   // Now make the processor/server file
-  f_service_name = package_dir_+"/"+service_name_+"Processor.hx";
+  f_service_name = package_dir_+"/"+get_cap_name(service_name_)+"Processor.hx";
   f_service_.open(f_service_name.c_str());
   
   f_service_ <<
@@ -1508,12 +1507,11 @@ void t_haxe_generator::generate_service(t_service* tservice) {
   
   if(!package_name_.empty()) {
     f_service_ << "import " << package_name_ << ".*;" << endl;
-    f_service_ << "import " << package_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);
-  //generate_service_helpers(tservice); - once is enough, see client file
   
   f_service_.close();
     
@@ -1612,7 +1610,7 @@ void t_haxe_generator::generate_service_interface(t_service* tservice) {
   }
 
   generate_haxe_doc(f_service_, tservice);
-  f_service_ << indent() << "interface " << service_name_ << extends_iface <<
+  f_service_ << indent() << "interface " << get_cap_name(service_name_) << extends_iface <<
     " {" << endl << endl;
   indent_up();
   vector<t_function*> functions = tservice->get_functions();
@@ -1638,7 +1636,7 @@ void t_haxe_generator::generate_service_helpers(t_service* tservice) {
   vector<t_function*>::iterator f_iter;
   for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
     t_struct* ts = (*f_iter)->get_arglist();
-    generate_haxe_struct_definition(f_service_, ts, false, true);
+    generate_haxe_struct(ts, false);
     generate_function_helpers(*f_iter);
   }
 }
@@ -1653,14 +1651,14 @@ void t_haxe_generator::generate_service_client(t_service* tservice) {
   string extends = "";
   string extends_client = "";
   if (tservice->get_extends() != NULL) {
-    extends = tservice->get_extends()->get_name();
+    extends = get_cap_name(tservice->get_extends()->get_name());
     extends_client = " extends " + extends + "Impl";
   }
 
   indent(f_service_) <<
-    "class " << service_name_ << 
-    "Impl" << extends_client << 
-    " implements " << service_name_ << 
+    "class " << get_cap_name(service_name_) <<
+    "Impl" << extends_client <<
+    " implements " << get_cap_name(service_name_) <<
     " {" << endl << endl;
   indent_up();
 
@@ -1731,7 +1729,7 @@ void t_haxe_generator::generate_service_client(t_service* tservice) {
     const vector<t_field*>& fields = arg_struct->get_members();
 
     // Serialize the request
-	string calltype = (*f_iter)->is_oneway() ? "ONEWAY" : "CALL";
+    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;
@@ -1879,20 +1877,20 @@ void t_haxe_generator::generate_service_server(t_service* tservice) {
   string extends = "";
   string extends_processor = "";
   if (tservice->get_extends() != NULL) {
-    extends = type_name(tservice->get_extends());
+    extends = get_cap_name(type_name(tservice->get_extends()));
     extends_processor = " extends " + extends + "Processor";
   }
 
   // Generate the header portion
   indent(f_service_) <<
-    "class " << service_name_ << 
-    "Processor" << extends_processor << 
+    "class " << get_cap_name(service_name_) <<
+    "Processor" << extends_processor <<
     " implements TProcessor {" << 
     endl << endl;
   indent_up();
 
   f_service_ <<
-    indent() << "private var " << service_name_ << "_iface_ : " << service_name_ << ";" << endl;
+    indent() << "private var " << get_cap_name(service_name_) << "_iface_ : " << get_cap_name(service_name_) << ";" << endl;
 
   if (extends.empty()) {
     f_service_ <<
@@ -1902,14 +1900,14 @@ void t_haxe_generator::generate_service_server(t_service* tservice) {
   f_service_ << endl;
 
   indent(f_service_) <<
-    "public function new( iface : " << service_name_ << ")" << endl;
+    "public function new( iface : " << get_cap_name(service_name_) << ")" << endl;
   scope_up(f_service_);
   if (!extends.empty()) {
     f_service_ <<
       indent() << "super(iface);" << endl;
   }
   f_service_ <<
-    indent() << service_name_ << "_iface_ = iface;" << endl;
+    indent() << get_cap_name(service_name_) << "_iface_ = iface;" << endl;
 
   for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
     f_service_ <<
@@ -1989,7 +1987,7 @@ void t_haxe_generator::generate_function_helpers(t_function* tfunction) {
     result.append(*f_iter);
   }
 
-  generate_haxe_struct_definition(f_service_, &result, false, true, true);
+  generate_haxe_struct(&result, false, true);
 }
 
 /**
@@ -2044,7 +2042,7 @@ void t_haxe_generator::generate_process_function(t_service* tservice,
   
     f_service_ << indent();
     f_service_ <<
-      service_name_ << "_iface_." << tfunction->get_name() << "(";
+      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) {
@@ -2094,7 +2092,7 @@ void t_haxe_generator::generate_process_function(t_service* tservice,
       f_service_ << "result.success = ";
     }
     f_service_ <<
-      service_name_ << "_iface_." << tfunction->get_name() << "(";
+      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) {
@@ -2113,7 +2111,7 @@ void t_haxe_generator::generate_process_function(t_service* tservice,
   if( ! tfunction->is_oneway()) {
     // catch exceptions defined in the IDL
     for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
-      f_service_ << " catch (" << (*x_iter)->get_name() << ":" << type_name((*x_iter)->get_type(), false, false) << ") {" << endl;
+      f_service_ << " catch (" << (*x_iter)->get_name() << ":" << get_cap_name(type_name((*x_iter)->get_type(), false, false)) << ") {" << endl;
       if (!tfunction->is_oneway()) {
         indent_up();
         f_service_ <<
@@ -2254,7 +2252,7 @@ void t_haxe_generator::generate_deserialize_struct(ofstream& out,
                                                    t_struct* tstruct,
                                                    string prefix) {
   out <<
-    indent() << prefix << " = new " << type_name(tstruct) << "();" << endl <<
+    indent() << prefix << " = new " << get_cap_name(type_name(tstruct)) << "();" << endl <<
     indent() << prefix << ".read(iprot);" << endl;
 }
 
@@ -2604,9 +2602,9 @@ string t_haxe_generator::type_name(t_type* ttype, bool in_container, bool in_ini
   
   if (ttype->is_map()) {
     t_type* tkey = get_true_type(((t_map*)ttype)->get_key_type());
-	t_type* tval = get_true_type(((t_map*)ttype)->get_val_type());
-	if (tkey->is_base_type()) {
-	  t_base_type::t_base tbase = ((t_base_type*)tkey)->get_base();
+    t_type* tval = get_true_type(((t_map*)ttype)->get_val_type());
+    if (tkey->is_base_type()) {
+      t_base_type::t_base tbase = ((t_base_type*)tkey)->get_base();
       switch (tbase) {
       case t_base_type::TYPE_STRING:
         if( ! (((t_base_type*)tkey)->is_binary())) {
@@ -2614,24 +2612,24 @@ string t_haxe_generator::type_name(t_type* ttype, bool in_container, bool in_ini
         }
       case t_base_type::TYPE_BYTE:
       case t_base_type::TYPE_I16:
-	  case t_base_type::TYPE_I32:
-		return "IntMap< " + type_name(tval) + ">";
-	  case t_base_type::TYPE_I64:
-		return "Int64Map< " + type_name(tval) + ">";
-	  default:
+      case t_base_type::TYPE_I32:
+        return "IntMap< " + type_name(tval) + ">";
+      case t_base_type::TYPE_I64:
+        return "Int64Map< " + type_name(tval) + ">";
+      default:
         break;  // default to ObjectMap<>
       }
-	}
-	if (tkey->is_enum()) {
-		return "IntMap< " + type_name(tval) + ">";
-	}
-	return "ObjectMap< " + type_name(tkey) + ", " + type_name(tval) + ">";
+    }
+    if (tkey->is_enum()) {
+        return "IntMap< " + type_name(tval) + ">";
+    }
+    return "ObjectMap< " + type_name(tkey) + ", " + type_name(tval) + ">";
   }
   
   if (ttype->is_set()) {
     t_type* tkey = get_true_type(((t_list*)ttype)->get_elem_type());
- 	if( tkey->is_base_type()) {
-	  t_base_type::t_base tbase = ((t_base_type*)tkey)->get_base();
+     if( tkey->is_base_type()) {
+      t_base_type::t_base tbase = ((t_base_type*)tkey)->get_base();
       switch (tbase) {
       case t_base_type::TYPE_STRING:
         if( ! (((t_base_type*)tkey)->is_binary())) {
@@ -2640,17 +2638,17 @@ string t_haxe_generator::type_name(t_type* ttype, bool in_container, bool in_ini
       case t_base_type::TYPE_BYTE:
       case t_base_type::TYPE_I16:
       case t_base_type::TYPE_I32:
-		  return "IntSet";
-	  case t_base_type::TYPE_I64:
-		  return "Int64Set";
-	  default:
+          return "IntSet";
+      case t_base_type::TYPE_I64:
+          return "Int64Set";
+      default:
         break;  // default to ObjectSet
       }
     }
-	if (tkey->is_enum()) {
-		return "IntSet";
-	}
-	return "ObjectSet< " + type_name(tkey) + ">";
+    if (tkey->is_enum()) {
+        return "IntSet";
+    }
+    return "ObjectSet< " + type_name(tkey) + ">";
   }
   
   if (ttype->is_list()) {
@@ -2745,7 +2743,7 @@ string t_haxe_generator::declare_field(t_field* tfield, bool init) {
     } else if (ttype->is_container()) {
       result += " = new " + type_name(ttype, false, true) + "()";
     } else {
-      result += " = new " + type_name(ttype, false, true) + "()";;
+      result += " = new " + type_name(ttype, false, true) + "()";
     }
   }
   return result + ";";
@@ -2855,10 +2853,20 @@ string t_haxe_generator::type_to_enum(t_type* type) {
 }
 
 /**
- * Applies the correct style to a string based on the value of nocamel_style_
+ * Haxe class names must start with uppercase letter, but Haxe namespaces must not.
  */
 std::string t_haxe_generator::get_cap_name(std::string name){
-  name[0] = toupper(name[0]);  // class name must start with uppercase letter
+  size_t index = name.rfind('.');
+  if (index != std::string::npos) {
+    ++index;
+  } else {
+    index = 0;
+  }
+
+  if (index < name.length()) {
+    name[index] = toupper(name[index]);
+  }
+
   return name;
 }
 


[3/3] thrift git commit: THRIFT-2815 Support for Multiplexing Services on any Transport, Protocol and Server Client: Haxe Patch: Jens Geyer

Posted by je...@apache.org.
THRIFT-2815 Support for Multiplexing Services on any Transport, Protocol and Server
Client: Haxe
Patch: Jens Geyer

This closes #262


Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/e5ff9a86
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/e5ff9a86
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/e5ff9a86

Branch: refs/heads/master
Commit: e5ff9a860d69fbd6cc6d6cb79833930e1148e4c0
Parents: 96dfcd5
Author: Jens Geyer <je...@apache.org>
Authored: Tue Nov 11 01:39:38 2014 +0100
Committer: Jens Geyer <je...@apache.org>
Committed: Tue Nov 11 01:39:38 2014 +0100

----------------------------------------------------------------------
 .../thrift/protocol/TMultiplexedProcessor.hx    | 174 ++++++++++++++
 .../thrift/protocol/TMultiplexedProtocol.hx     |  97 ++++++++
 .../thrift/protocol/TProtocolDecorator.hx       | 218 ++++++++++++++++++
 lib/haxe/test/HaxeTests.hxproj                  |   8 +-
 lib/haxe/test/Makefile.am                       |  12 +-
 lib/haxe/test/make_all.bat                      |   4 +-
 lib/haxe/test/make_all.sh                       |   2 +
 lib/haxe/test/src/Main.hx                       |  50 ++++-
 lib/haxe/test/src/MultiplexTest.hx              | 224 +++++++++++++++++++
 lib/haxe/test/src/StreamTest.hx                 |  32 +--
 lib/haxe/test/src/TestBase.hx                   |  10 +-
 11 files changed, 808 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/thrift/blob/e5ff9a86/lib/haxe/src/org/apache/thrift/protocol/TMultiplexedProcessor.hx
----------------------------------------------------------------------
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TMultiplexedProcessor.hx b/lib/haxe/src/org/apache/thrift/protocol/TMultiplexedProcessor.hx
new file mode 100644
index 0000000..7354ff4
--- /dev/null
+++ b/lib/haxe/src/org/apache/thrift/protocol/TMultiplexedProcessor.hx
@@ -0,0 +1,174 @@
+/**
+ * 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 haxe.ds.StringMap;
+import org.apache.thrift.TApplicationException;
+import org.apache.thrift.TProcessor;
+
+import org.apache.thrift.transport.TTransport;
+
+
+/**
+ * TMultiplexedProcessor is a TProcessor allowing a single TServer to provide multiple services.
+ * To do so, you instantiate the processor and then register additional processors with it,
+ * as shown in the following example:
+ *
+ *     TMultiplexedProcessor processor = new TMultiplexedProcessor();
+ *
+ *     processor.registerProcessor(
+ *         "Calculator",
+ *         new Calculator.Processor(new CalculatorHandler()));
+ *
+ *     processor.registerProcessor(
+ *         "WeatherReport",
+ *         new WeatherReport.Processor(new WeatherReportHandler()));
+ *
+ *     TServerTransport t = new TServerSocket(9090);
+ *     TSimpleServer server = new TSimpleServer(processor, t);
+ *
+ *     server.serve();
+ */
+class TMultiplexedProcessor implements TProcessor
+{
+    private var serviceProcessorMap : StringMap<TProcessor> = new StringMap<TProcessor>();
+    private var defaultProcessor : TProcessor = null;
+
+    /**
+     * 'Register' a service with this TMultiplexedProcessor. This allows us to broker
+     * requests to individual services by using the service name to select them at request time.
+     *
+     * Args:
+     * - serviceName    Name of a service, has to be identical to the name
+     *                  declared in the Thrift IDL, e.g. "WeatherReport".
+     * - processor      Implementation of a service, ususally referred to as "handlers",
+     *                  e.g. WeatherReportHandler implementing WeatherReport.Iface.
+     */
+    public function RegisterProcessor(serviceName : String, processor : TProcessor, asDefault : Bool = false) : Void {
+        serviceProcessorMap.set(serviceName, processor);
+        if ( asDefault) {
+            if( defaultProcessor != null) {
+                throw new TApplicationException( TApplicationException.UNKNOWN, "Can't have multiple default processors");
+            } else {
+                defaultProcessor = processor;
+            }
+        }
+    }
+
+
+    private function Fail( oprot : TProtocol, message : TMessage, extype : Int, etxt : String) : Void {
+        var appex = new TApplicationException( extype, etxt);
+
+        var newMessage = new TMessage(message.name, TMessageType.EXCEPTION, message.seqid);
+
+        oprot.writeMessageBegin(newMessage);
+        appex.write( oprot);
+        oprot.writeMessageEnd();
+        oprot.getTransport().flush();
+    }
+
+
+    /**
+     * This implementation of process performs the following steps:
+     *
+     * - Read the beginning of the message.
+     * - Extract the service name from the message.
+     * - Using the service name to locate the appropriate processor.
+     * - Dispatch to the processor, with a decorated instance of TProtocol
+     *    that allows readMessageBegin() to return the original TMessage.
+     *
+     * Throws an exception if
+     * - the message type is not CALL or ONEWAY,
+     * - the service name was not found in the message, or
+     * - the service name has not been RegisterProcessor()ed.
+     */
+    public function process( iprot : TProtocol, oprot : TProtocol) : Bool {
+        /*  Use the actual underlying protocol (e.g. TBinaryProtocol) to read the
+            message header.  This pulls the message "off the wire", which we'll
+            deal with at the end of this method. */
+
+        var message : TMessage = iprot.readMessageBegin();
+        var methodName : String = "";
+
+        if ((message.type != TMessageType.CALL) && (message.type != TMessageType.ONEWAY))
+        {
+            Fail(oprot, message,
+                  TApplicationException.INVALID_MESSAGE_TYPE,
+                  "Message type CALL or ONEWAY expected");
+            return false;
+        }
+
+        // Extract the service name
+        var actualProcessor : TProcessor = null;
+        var index = message.name.indexOf(TMultiplexedProtocol.SEPARATOR);
+        if (index < 0) {
+            // fallback to default processor
+            methodName = message.name;
+            actualProcessor = defaultProcessor;
+            if( actualProcessor == null) {
+                Fail(oprot, message,
+                      TApplicationException.INVALID_PROTOCOL,
+                      "Service name not found in message name: " + message.name + " and no default processor defined. " +
+                      "Did you forget to use a TMultiplexProtocol in your client?");
+                return false;
+            }
+
+        } else {
+            // service name given
+            var serviceName = message.name.substring(0, index);
+            methodName = message.name.substring( serviceName.length + TMultiplexedProtocol.SEPARATOR.length);
+            actualProcessor = serviceProcessorMap.get( serviceName);
+            if( actualProcessor == null) {
+                Fail(oprot, message,
+                      TApplicationException.INTERNAL_ERROR,
+                      "Service name not found: " + serviceName + ". " +
+                      "Did you forget to call RegisterProcessor()?");
+                return false;
+            }
+        }
+
+        // Create a new TMessage, removing the service name
+        // Dispatch processing to the stored processor
+        var newMessage = new TMessage( methodName, message.type, message.seqid);
+        var storedMsg = new StoredMessageProtocol( iprot, newMessage);
+        return actualProcessor.process( storedMsg, oprot);
+    }
+}
+
+
+/**
+ *  Our goal was to work with any protocol.  In order to do that, we needed
+ *  to allow them to call readMessageBegin() and get a TMessage in exactly
+ *  the standard format, without the service name prepended to TMessage.name.
+ */
+class StoredMessageProtocol extends TProtocolDecorator
+{
+    private var messageBegin : TMessage;
+
+    public function new( protocol : TProtocol, messageBegin : TMessage) {
+        super( protocol);
+        this.messageBegin = messageBegin;
+    }
+
+    public override function readMessageBegin() : TMessage {
+        return messageBegin;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/thrift/blob/e5ff9a86/lib/haxe/src/org/apache/thrift/protocol/TMultiplexedProtocol.hx
----------------------------------------------------------------------
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TMultiplexedProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TMultiplexedProtocol.hx
new file mode 100644
index 0000000..cacd1d7
--- /dev/null
+++ b/lib/haxe/src/org/apache/thrift/protocol/TMultiplexedProtocol.hx
@@ -0,0 +1,97 @@
+/**
+ * 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.transport.TTransport;
+
+
+/**
+ * TMultiplexedProtocol is a protocol-independent concrete decorator that allows a Thrift
+ * client to communicate with a multiplexing Thrift server, by prepending the service name
+ * to the function name during function calls.
+ *
+ * NOTE: THIS IS NOT TO BE USED BY SERVERS.
+ * On the server, use TMultiplexedProcessor to handle requests from a multiplexing client.
+ *
+ * This example uses a single socket transport to invoke two services:
+ *
+ *     TSocket transport = new TSocket("localhost", 9090);
+ *     transport.open();
+ *
+ *     TBinaryProtocol protocol = new TBinaryProtocol(transport);
+ *
+ *     TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator");
+ *     Calculator.Client service = new Calculator.Client(mp);
+ *
+ *     TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport");
+ *     WeatherReport.Client service2 = new WeatherReport.Client(mp2);
+ *
+ *     System.out.println(service.add(2,2));
+ *     System.out.println(service2.getTemperature());
+ *
+ */
+class TMultiplexedProtocol extends TProtocolDecorator {
+
+    /** Used to delimit the service name from the function name */
+    public static inline var SEPARATOR : String = ":";
+
+    private var service : String;
+
+    /**
+     * Wrap the specified protocol, allowing it to be used to communicate with a
+     * multiplexing server.  The <code>serviceName</code> is required as it is
+     * prepended to the message header so that the multiplexing server can broker
+     * the function call to the proper service.
+     *
+     * Args:
+     *  protocol        Your communication protocol of choice, e.g. TBinaryProtocol
+     *  serviceName     The service name of the service communicating via this protocol.
+     */
+    public function new( protocol : TProtocol, serviceName : String)    {
+        super( protocol);
+        service = serviceName;
+    }
+
+    /**
+     * Prepends the service name to the function name, separated by TMultiplexedProtocol.SEPARATOR.
+     * Args:
+     *   tMessage     The original message.
+     */
+    public override function writeMessageBegin( message : TMessage) : Void {
+        switch( message.type)
+        {
+            case TMessageType.CALL:
+                super.writeMessageBegin(new TMessage(
+                    service + SEPARATOR + message.name,
+                    message.type,
+                    message.seqid));
+
+            case TMessageType.ONEWAY:
+                super.writeMessageBegin(new TMessage(
+                    service + SEPARATOR + message.name,
+                    message.type,
+                    message.seqid));
+
+            default:
+                super.writeMessageBegin(message);
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/thrift/blob/e5ff9a86/lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx
----------------------------------------------------------------------
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx b/lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx
new file mode 100644
index 0000000..e43d2d9
--- /dev/null
+++ b/lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx
@@ -0,0 +1,218 @@
+/**
+ * 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 haxe.io.Bytes;
+import haxe.Int64;
+
+import org.apache.thrift.transport.TTransport;
+
+
+/**
+ * TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
+ * providing a way to author concise concrete decorator subclasses.  While it has
+ * no abstract methods, it is marked abstract as a reminder that by itself,
+ * it does not modify the behaviour of the enclosed TProtocol.
+ *
+ * See p.175 of Design Patterns (by Gamma et al.)
+ * See TMultiplexedProtocol
+ */
+class TProtocolDecorator implements TProtocol
+{
+    private var wrapped : TProtocol;
+
+    /**
+     * Encloses the specified protocol.
+     * @param protocol All operations will be forward to this protocol.  Must be non-null.
+     */
+    private function new( protocol : TProtocol)  // not to be instantiated, must derive a class
+    {
+        wrapped = protocol;
+    }
+
+    public function getTransport() : TTransport {
+      return wrapped.getTransport();
+    }
+
+    public function writeMessageBegin( value : TMessage) : Void    {
+        wrapped.writeMessageBegin( value);
+    }
+
+    public function writeMessageEnd() : Void {
+        wrapped.writeMessageEnd();
+    }
+
+    public function writeStructBegin(value : TStruct) : Void {
+        wrapped.writeStructBegin( value);
+    }
+
+    public function writeStructEnd() : Void {
+        wrapped.writeStructEnd();
+    }
+
+    public function writeFieldBegin(value : TField) : Void {
+        wrapped.writeFieldBegin( value);
+    }
+
+    public function writeFieldEnd() : Void {
+        wrapped.writeFieldEnd();
+    }
+
+    public function writeFieldStop() : Void {
+        wrapped.writeFieldStop();
+    }
+
+    public function writeMapBegin( value : TMap) : Void {
+        wrapped.writeMapBegin( value);
+    }
+
+    public function writeMapEnd() : Void {
+        wrapped.writeMapEnd();
+    }
+
+    public function writeListBegin( value : TList) : Void {
+        wrapped.writeListBegin( value);
+    }
+
+    public function writeListEnd() : Void {
+        wrapped.writeListEnd();
+    }
+
+    public function writeSetBegin( value : TSet) : Void {
+        wrapped.writeSetBegin( value);
+    }
+
+    public function writeSetEnd() : Void {
+        wrapped.writeSetEnd();
+    }
+
+    public function writeBool(value : Bool) : Void {
+        wrapped.writeBool( value);
+    }
+
+    public function writeByte(value : Int) : Void {
+        wrapped.writeByte( value);
+    }
+
+    public function writeI16(value : Int) : Void {
+        wrapped.writeI16( value);
+    }
+
+    public function writeI32(value : Int) : Void {
+        wrapped.writeI32( value);
+    }
+
+    public function writeI64(value : haxe.Int64) : Void {
+        wrapped.writeI64( value);
+    }
+
+    public function writeDouble(value : Float) : Void {
+        wrapped.writeDouble( value);
+    }
+
+    public function writeString(value : String) : Void {
+        wrapped.writeString( value);
+    }
+
+    public function writeBinary(value : Bytes ) : Void {
+        wrapped.writeBinary( value);
+    }
+
+    public function readMessageBegin() : TMessage {
+        return wrapped.readMessageBegin();
+    }
+
+    public function readMessageEnd() : Void {
+        wrapped.readMessageEnd();
+    }
+
+    public function readStructBegin() : TStruct {
+        return wrapped.readStructBegin();
+    }
+
+    public function readStructEnd() : Void {
+        wrapped.readStructEnd();
+    }
+
+    public function readFieldBegin() : TField {
+        return wrapped.readFieldBegin();
+    }
+
+    public function readFieldEnd() : Void {
+        wrapped.readFieldEnd();
+    }
+
+    public function readMapBegin() : TMap {
+        return wrapped.readMapBegin();
+    }
+
+    public function readMapEnd() : Void {
+        wrapped.readMapEnd();
+    }
+
+    public function readListBegin() : TList {
+        return wrapped.readListBegin();
+    }
+
+    public function readListEnd() : Void {
+        wrapped.readListEnd();
+    }
+
+    public function readSetBegin() : TSet {
+        return wrapped.readSetBegin();
+    }
+
+    public function readSetEnd() : Void {
+        wrapped.readSetEnd();
+    }
+
+    public function readBool() : Bool
+    {
+        return wrapped.readBool();
+    }
+
+    public function readByte() : Int {
+        return wrapped.readByte();
+    }
+
+    public function readI16() : Int {
+        return wrapped.readI16();
+    }
+
+    public function readI32() : Int {
+        return wrapped.readI32();
+    }
+
+    public function readI64() : haxe.Int64 {
+        return wrapped.readI64();
+    }
+
+    public function readDouble() : Float {
+        return wrapped.readDouble();
+    }
+
+    public function readString() : String {
+        return wrapped.readString();
+    }
+
+    public function readBinary() : Bytes {
+        return wrapped.readBinary();
+    }
+}

http://git-wip-us.apache.org/repos/asf/thrift/blob/e5ff9a86/lib/haxe/test/HaxeTests.hxproj
----------------------------------------------------------------------
diff --git a/lib/haxe/test/HaxeTests.hxproj b/lib/haxe/test/HaxeTests.hxproj
index 4e8929b..3beed82 100644
--- a/lib/haxe/test/HaxeTests.hxproj
+++ b/lib/haxe/test/HaxeTests.hxproj
@@ -53,14 +53,16 @@
     <hidden path="python.hxml" />
   </hiddenPaths>
   <!-- Executed before build -->
-  <preBuildCommand>thrift -r -gen haxe  ../../../test/ThriftTest.thrift</preBuildCommand>
+  <preBuildCommand>thrift -r -gen haxe  ../../../test/ThriftTest.thrift
+thrift -r -gen haxe  ../../../contrib/async-test/aggr.thrift
+thrift -r -gen haxe  ../../../lib/rb/benchmark/Benchmark.thrift</preBuildCommand>
   <!-- Executed after build -->
   <postBuildCommand alwaysRun="False" />
   <!-- Other project options -->
   <options>
     <option showHiddenPaths="False" />
-    <option testMovie="Unknown" />
-    <option testMovieCommand="" />
+    <option testMovie="Custom" />
+    <option testMovieCommand="bin/HaxeTests/Main.exe server multiplex" />
   </options>
   <!-- Plugin storage -->
   <storage />

http://git-wip-us.apache.org/repos/asf/thrift/blob/e5ff9a86/lib/haxe/test/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/haxe/test/Makefile.am b/lib/haxe/test/Makefile.am
index 357436c..13b4266 100644
--- a/lib/haxe/test/Makefile.am
+++ b/lib/haxe/test/Makefile.am
@@ -20,15 +20,25 @@
 THRIFT = $(top_srcdir)/compiler/cpp/thrift
 THRIFTCMD = $(THRIFT) --gen haxe -r
 THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift
+AGGR = $(top_srcdir)/contrib/async-test/aggr.thrift
+BENCHMARK = $(top_srcdir)/lib/rb/benchmark/Benchmark.thrift
 
 BIN_CPP = bin/Main-debug
 
 gen-haxe/thrift/test/ThriftTest.hx: $(THRIFTTEST)
 	$(THRIFTCMD) $(THRIFTTEST)
 
+gen-haxe/thrift/test/Aggr.hx: $(AGGR)
+	$(THRIFTCMD) $(AGGR)
+
+gen-haxe/thrift/test/BenchmarkService.hx: $(BENCHMARK)
+	$(THRIFTCMD) $(BENCHMARK)
+
 all-local: $(BIN_CPP)
 
-$(BIN_CPP):    gen-haxe/thrift/test/ThriftTest.hx
+$(BIN_CPP): gen-haxe/thrift/test/ThriftTest.hx \
+			gen-haxe/thrift/test/Aggr.hx \
+			gen-haxe/thrift/test/BenchmarkService.hx
 	$(HAXE) --cwd .  cpp.hxml
 
 

http://git-wip-us.apache.org/repos/asf/thrift/blob/e5ff9a86/lib/haxe/test/make_all.bat
----------------------------------------------------------------------
diff --git a/lib/haxe/test/make_all.bat b/lib/haxe/test/make_all.bat
index ee18f10..0314e18 100644
--- a/lib/haxe/test/make_all.bat
+++ b/lib/haxe/test/make_all.bat
@@ -26,7 +26,9 @@ if "%HAXEPATH%"=="" goto NOTINSTALLED
 set path=%HAXEPATH%;%HAXEPATH%\..\neko;%path%
 
 rem # invoke Thrift comnpiler
-thrift -r -gen haxe   ..\..\..\test\ThriftTest.thrift
+thrift -r -gen haxe  ..\..\..\test\ThriftTest.thrift
+thrift -r -gen haxe  ..\..\..\contrib\async-test\aggr.thrift
+thrift -r -gen haxe  ..\..\..\lib\rb\benchmark\Benchmark.thrift
 if errorlevel 1 goto STOP
 
 rem # invoke Haxe compiler for all targets

http://git-wip-us.apache.org/repos/asf/thrift/blob/e5ff9a86/lib/haxe/test/make_all.sh
----------------------------------------------------------------------
diff --git a/lib/haxe/test/make_all.sh b/lib/haxe/test/make_all.sh
index 13b5754..512f5ec 100644
--- a/lib/haxe/test/make_all.sh
+++ b/lib/haxe/test/make_all.sh
@@ -20,6 +20,8 @@
 
 # invoke Thrift comnpiler
 thrift -r -gen haxe  ../../../test/ThriftTest.thrift
+thrift -r -gen haxe  ../../../contrib/async-test/aggr.thrift
+thrift -r -gen haxe  ../../../lib/rb/benchmark/Benchmark.thrift
 
 # output folder
 if [ ! -d bin ]; then

http://git-wip-us.apache.org/repos/asf/thrift/blob/e5ff9a86/lib/haxe/test/src/Main.hx
----------------------------------------------------------------------
diff --git a/lib/haxe/test/src/Main.hx b/lib/haxe/test/src/Main.hx
index da0a7f5..6c262d7 100644
--- a/lib/haxe/test/src/Main.hx
+++ b/lib/haxe/test/src/Main.hx
@@ -27,19 +27,67 @@ import org.apache.thrift.meta_data.*;
 
 import thrift.test.*;  // generated code
 
+
+enum WhatTests {
+    Normal;
+    Multiplex;
+}
+
 class Main
 {
+    static private var tests : WhatTests = Normal;
+    static private var server : Bool = false;
+
+    static private inline var CMDLINEHELP : String
+        = "\nHaxeTests  [client|server]  [multiplex]\n"
+        + "  client|server  ... determines run mode for some tests, default is client\n"
+        + "  multiplex ........ run multiplex test server or client\n";
+
+    static private function ParseArgs() {
+        #if sys
+
+        var args = Sys.args();
+        if ( args != null) {
+            for ( arg in args) {
+                switch(arg.toLowerCase()) {
+                    case "client":
+                        server = false;
+                    case "server" :
+                        server = true;
+                    case "multiplex" :
+                        tests = Multiplex;
+                    default:
+                throw 'Invalid argument "$arg"\n'+CMDLINEHELP;
+                }
+            }
+        }
+
+        #end
+    }
+
     static public function main()
     {
         try
         {
-            StreamTest.Run();
+            ParseArgs();
+
+            switch( tests) {
+                case Normal:
+                    StreamTest.Run(server);
+                case Multiplex:
+                    MultiplexTest.Run(server);
+                default:
+                    throw "Unhandled test mode $tests";
+            }
 
             trace("All tests completed.");
         }
         catch( e: Dynamic)
         {
             trace('$e');
+            #if sys
+            Sys.exit(1);  // indicate error
+            #end
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/thrift/blob/e5ff9a86/lib/haxe/test/src/MultiplexTest.hx
----------------------------------------------------------------------
diff --git a/lib/haxe/test/src/MultiplexTest.hx b/lib/haxe/test/src/MultiplexTest.hx
new file mode 100644
index 0000000..3818b66
--- /dev/null
+++ b/lib/haxe/test/src/MultiplexTest.hx
@@ -0,0 +1,224 @@
+/*
+ * 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;
+
+import haxe.Int64;
+import haxe.Int32;
+
+import org.apache.thrift.*;
+import org.apache.thrift.protocol.*;
+import org.apache.thrift.transport.*;
+import org.apache.thrift.server.*;
+import org.apache.thrift.meta_data.*;
+
+// debug only
+import org.apache.thrift.protocol.TProtocolDecorator;
+import org.apache.thrift.protocol.TMultiplexedProtocol;
+import org.apache.thrift.protocol.TMultiplexedProcessor;
+
+// generated code imports
+import Aggr;
+import AggrImpl;
+import AggrProcessor;
+import BenchmarkService;
+import BenchmarkServiceImpl;
+import BenchmarkServiceProcessor;
+import Error;
+
+
+class BenchmarkServiceHandler implements BenchmarkService
+{
+    public function new() {
+    }
+
+    public function fibonacci(n : haxe.Int32) : haxe.Int32 {
+        trace('Benchmark.fibonacci($n)');
+        var next : Int;
+        var prev   = 0;
+        var result = 1;
+        while( n > 0)
+        {
+            next   = result + prev;
+            prev   = result;
+            result = next;
+            --n;
+        }
+        return result;
+    }
+}
+
+
+class AggrServiceHandler implements Aggr
+{
+    private var values : List<haxe.Int32> = new List<haxe.Int32>();
+
+    public function new() {
+    }
+
+    public function addValue(value : haxe.Int32) : Void    {
+        trace('Aggr.addValue($value)');
+        values.add( value);
+    }
+
+    public function getValues() : List< haxe.Int32> {
+        trace('Aggr.getValues()');
+        return values;
+    }
+}
+
+
+
+class MultiplexTest extends TestBase {
+
+    private inline static var NAME_BENCHMARKSERVICE : String = "BenchmarkService";
+    private inline static var NAME_AGGR             : String  = "Aggr";
+
+
+    public static override function Run(server : Bool) : Void {
+        if ( server) {
+            RunMultiplexServer();
+        } else {
+            RunMultiplexClient();
+            RunDefaultClient();
+        }
+    }
+
+
+    // run the multiplex server
+    public static override function RunMultiplexServer() : Void  {
+       try
+       {
+            var benchHandler : BenchmarkService = new BenchmarkServiceHandler();
+            var benchProcessor : TProcessor = new BenchmarkServiceProcessor( benchHandler);
+
+            var aggrHandler : Aggr = new AggrServiceHandler();
+            var aggrProcessor : TProcessor = new AggrProcessor( aggrHandler);
+
+            var multiplex : TMultiplexedProcessor = new TMultiplexedProcessor();
+            multiplex.RegisterProcessor( NAME_BENCHMARKSERVICE, benchProcessor, true);  // default
+            multiplex.RegisterProcessor( NAME_AGGR, aggrProcessor);
+
+            // protocol+transport stack
+            var protfact : TProtocolFactory = new TBinaryProtocolFactory(true,true);
+            var servertrans : TServerTransport = new TServerSocket( 9090, 5, false);
+            var transfact : TTransportFactory = new TFramedTransportFactory();
+
+            var server : TServer = new TSimpleServer( multiplex, servertrans, transfact, protfact);
+
+            trace("Starting the server ...");
+            server.Serve();
+       }
+        catch( e : TApplicationException)
+        {
+            TestBase.Expect(false,'${e.errorID} ${e.errorMsg}');
+        }
+        catch( e : TException)
+        {
+            TestBase.Expect(false,'$e');
+        }
+    }
+
+
+    // run multiplex client against multiplex server
+    public static override function RunMultiplexClient() : Void  {
+        try
+        {
+            var trans : TTransport;
+            trans = new TSocket("localhost", 9090);
+            trans = new TFramedTransport(trans);
+            trans.open();
+
+            var protocol : TProtocol = new TBinaryProtocol(trans,true,true);
+            var multiplex : TMultiplexedProtocol;
+
+            multiplex = new TMultiplexedProtocol( protocol, NAME_BENCHMARKSERVICE);
+            var bench = new BenchmarkServiceImpl( multiplex);
+
+            multiplex = new TMultiplexedProtocol( protocol, NAME_AGGR);
+            var aggr = new AggrImpl( multiplex);
+
+            trace('calling aggr.add( bench.fibo())...');
+            for( i in 1 ... 10)
+            {
+                trace('$i');
+                aggr.addValue( bench.fibonacci(i));
+            }
+
+            trace('calling aggr ...');
+            var i = 1;
+            var values = aggr.getValues();
+            TestBase.Expect(values != null,'aggr.getValues() == null');
+            for( k in values)
+            {
+                trace('fib($i) = $k');
+                ++i;
+            }
+
+            trans.close();
+            trace('done.');
+
+        }
+        catch( e : TApplicationException)
+        {
+            TestBase.Expect(false,'${e.errorID} ${e.errorMsg}');
+        }
+        catch( e : TException)
+        {
+            TestBase.Expect(false,'$e');
+        }
+    }
+
+
+    // run non-multiplex client against multiplex server to test default fallback
+    public static override function RunDefaultClient() : Void  {
+        try
+        {
+            var trans : TTransport;
+            trans = new TSocket("localhost", 9090);
+            trans = new TFramedTransport(trans);
+            trans.open();
+
+            var protocol : TProtocol = new TBinaryProtocol(trans,true,true);
+
+            var bench = new BenchmarkServiceImpl( protocol);
+
+            trace('calling bench (via default) ...');
+            for( i in 1 ... 10)
+            {
+                var k = bench.fibonacci(i);
+                trace('fib($i) = $k');
+            }
+
+            trans.close();
+            trace('done.');
+        }
+        catch( e : TApplicationException)
+        {
+            TestBase.Expect(false,'${e.errorID} ${e.errorMsg}');
+        }
+        catch( e : TException)
+        {
+            TestBase.Expect(false,'$e');
+        }
+    }
+
+}
+
+

http://git-wip-us.apache.org/repos/asf/thrift/blob/e5ff9a86/lib/haxe/test/src/StreamTest.hx
----------------------------------------------------------------------
diff --git a/lib/haxe/test/src/StreamTest.hx b/lib/haxe/test/src/StreamTest.hx
index 7500eee..244f1ea 100644
--- a/lib/haxe/test/src/StreamTest.hx
+++ b/lib/haxe/test/src/StreamTest.hx
@@ -20,6 +20,7 @@
 package;
 
 import haxe.Int64;
+import sys.FileSystem;
 
 import org.apache.thrift.*;
 import org.apache.thrift.protocol.*;
@@ -33,15 +34,9 @@ import thrift.test.*;  // generated code
 class StreamTest extends TestBase {
 
 
-    private inline static var tmpfile : String = "bin/data.tmp";
+    private inline static var tmpfile : String = "data.tmp";
 
 
-    private static function Expect( expr : Bool, info : String, ?pos : haxe.PosInfos) : Void {
-        if( ! expr) {
-            throw ('Test "$info" failed at '+pos.methodName+' in '+pos.fileName+':'+pos.lineNumber);
-        }
-    }
-
     private static function MakeTestData() : Xtruct {
         var data : Xtruct = new Xtruct();
         data.string_thing = "Streamtest";
@@ -77,15 +72,22 @@ class StreamTest extends TestBase {
         return data;
     }
 
-    public static override function Run() : Void
+    public static override function Run(server : Bool) : Void
     {
-        var written = WriteData();
-        var read = ReadData();
-
-        Expect( read.string_thing == written.string_thing, "string data");
-        Expect( read.byte_thing == written.byte_thing, "byte data");
-        Expect( read.i32_thing == written.i32_thing, "i32 data");
-        Expect( Int64.compare( read.i64_thing, written.i64_thing) == 0, "i64 data");
+        try {
+            var written = WriteData();
+            var read = ReadData();
+            FileSystem.deleteFile(tmpfile);
+
+            TestBase.Expect( read.string_thing == written.string_thing, "string data");
+            TestBase.Expect( read.byte_thing == written.byte_thing, "byte data");
+            TestBase.Expect( read.i32_thing == written.i32_thing, "i32 data");
+            TestBase.Expect( Int64.compare( read.i64_thing, written.i64_thing) == 0, "i64 data");
+
+        } catch(e:Dynamic) {
+            FileSystem.deleteFile(tmpfile);
+            throw e;
+        }
     }
 
 }

http://git-wip-us.apache.org/repos/asf/thrift/blob/e5ff9a86/lib/haxe/test/src/TestBase.hx
----------------------------------------------------------------------
diff --git a/lib/haxe/test/src/TestBase.hx b/lib/haxe/test/src/TestBase.hx
index 2a344d6..1232773 100644
--- a/lib/haxe/test/src/TestBase.hx
+++ b/lib/haxe/test/src/TestBase.hx
@@ -25,7 +25,6 @@ import org.apache.thrift.transport.*;
 import org.apache.thrift.server.*;
 import org.apache.thrift.meta_data.*;
 
-import thrift.test.*;  // generated code
 
 class TestBase {
 
@@ -33,8 +32,15 @@ class TestBase {
         // override, if necessary
     }
 
-    public static function Run() : Void {
+    public static function Run(server : Bool) : Void {
           throw new AbstractMethodError();
     }
+
+    public static function Expect( expr : Bool, info : String, ?pos : haxe.PosInfos) : Void {
+        if( ! expr) {
+            throw ('Test "$info" failed at '+pos.methodName+' in '+pos.fileName+':'+pos.lineNumber);
+        }
+    }
+
 }
  
\ No newline at end of file