THRIFT-5593 Implement uuid for Haxe
Client: hx
Patch: Jens Geyer

Relies on https://github.com/flashultra/uuid/issues/4 being fixed, thus may require using the most recent uuid package from Github instead of the Haxelib package.
diff --git a/lib/haxe/haxelib.json b/lib/haxe/haxelib.json
index da0c834..4775ac4 100644
--- a/lib/haxe/haxelib.json
+++ b/lib/haxe/haxelib.json
@@ -14,7 +14,8 @@
 	"releasenote": "Licensed under Apache License, Version 2.0. The Apache Thrift compiler needs to be installed separately.",
 	"contributors": ["ApacheThrift"],
 	"dependencies": { 
-		"crypto": ""
+		"crypto": "",
+		"uuid": ""
 	},
 	"classPath": "src"
 }
diff --git a/lib/haxe/src/org/apache/thrift/helper/Int64Map.hx b/lib/haxe/src/org/apache/thrift/helper/Int64Map.hx
index a8e735f..fc5cc0b 100644
--- a/lib/haxe/src/org/apache/thrift/helper/Int64Map.hx
+++ b/lib/haxe/src/org/apache/thrift/helper/Int64Map.hx
@@ -27,7 +27,7 @@
 // Int64Map allows mapping of Int64 keys to arbitrary values.
 // ObjectMap<> cannot be used, since we want to compare by value, not address
 
-class Int64Map<T> implements IMap< Int64, T> {
+class Int64Map<T> implements haxe.Constraints.IMap< Int64, T> {
 
     private var SubMaps : IntMap< IntMap< T>>;  // Hi -> Lo -> Value
 
@@ -141,7 +141,7 @@
 		SubMaps.clear();
     }
 
-    public function copy() : IMap< Int64, T> {
+    public function copy() : haxe.Constraints.IMap< Int64, T> {
 		var retval = new Int64Map<T>();
 		for( key in this.keys())
 			retval.set( key, this.get(key));
diff --git a/lib/haxe/src/org/apache/thrift/helper/UuidHelper.hx b/lib/haxe/src/org/apache/thrift/helper/UuidHelper.hx
new file mode 100644
index 0000000..082a9d3
--- /dev/null
+++ b/lib/haxe/src/org/apache/thrift/helper/UuidHelper.hx
@@ -0,0 +1,46 @@
+/*
+ * 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.helper;
+
+import haxe.io.Bytes;
+import uuid.Uuid;
+
+class UuidHelper {
+	
+	public static function CanonicalUuid( uuid : String) : String {
+		uuid = StringTools.replace( uuid, "{", "");
+		uuid = StringTools.replace( uuid, "}", "");
+		uuid = Uuid.stringify( Uuid.parse( uuid));
+		return uuid;
+	}
+	
+	#if debug
+	
+	public static function UnitTest() : Void 
+	{
+		var guid : String = CanonicalUuid("{00112233-4455-6677-8899-AABBCCDDEEFF}");
+		if ( guid.length != 36)
+			throw 'UuidHelper Test: CanonicalUuid() failed';
+	}
+
+	#end
+	
+}
+
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx
index 736a7dc..48b8d1e 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx
@@ -25,8 +25,11 @@
 import haxe.io.BytesBuffer;
 import haxe.Int64;
 
+import uuid.Uuid;
+
 import org.apache.thrift.TException;
 import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.helper.UuidHelper;
 
 /**
 * Binary protocol implementation for thrift.
@@ -164,6 +167,12 @@
         Transport.write(bin, 0, bin.length);
     }
 
+    public function writeUuid(uuid : String) : Void {		
+        var bytes : Bytes = Uuid.parse(UuidHelper.CanonicalUuid(uuid));
+        Transport.write(bytes, 0, bytes.length);
+    }
+
+
     /**
      * Reading methods.
      */
@@ -300,6 +309,13 @@
         return buffer.getBytes();
     }
 
+    public function readUuid() : String {
+        var buffer = new BytesBuffer();
+        Transport.readAll( buffer, 0, 16);
+        var bytes : Bytes = buffer.getBytes();
+        return Uuid.stringify( bytes);
+    }
+
 	// Return the minimum number of bytes a type will consume on the wire
 	public override function GetMinSerializedSize(type : TType) : Int
 	{
@@ -318,6 +334,7 @@
 			case TType.MAP: return 4;  // element count
 			case TType.SET: return 4;  // element count
 			case TType.LIST: return 4;  // element count
+			case TType.UUID: return 16;  // uuid bytes
 			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 bf7b886..d3577f1 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx
@@ -28,11 +28,13 @@
 import haxe.Int32;
 import haxe.Int64;
 
+import uuid.Uuid;
+
 import org.apache.thrift.TException;
 import org.apache.thrift.transport.TTransport;
 import org.apache.thrift.helper.ZigZag;
 import org.apache.thrift.helper.BitConverter;
-
+import org.apache.thrift.helper.UuidHelper;
 
 /**
 * Compact protocol implementation for thrift.
@@ -62,7 +64,8 @@
         TType.STRUCT  => TCompactTypes.STRUCT,
         TType.MAP     => TCompactTypes.MAP,
         TType.SET     => TCompactTypes.SET,
-        TType.LIST    => TCompactTypes.LIST
+        TType.LIST    => TCompactTypes.LIST,
+        TType.UUID    => TCompactTypes.UUID
     ];
 
     private static var tcompactTypeToType = [
@@ -78,7 +81,8 @@
         TCompactTypes.LIST          => TType.LIST,
         TCompactTypes.SET           => TType.SET,
         TCompactTypes.MAP           => TType.MAP,
-        TCompactTypes.STRUCT        => TType.STRUCT
+        TCompactTypes.STRUCT        => TType.STRUCT,
+        TCompactTypes.UUID          => TType.UUID
     ];
 
 
@@ -337,6 +341,10 @@
         Transport.write( bin, 0, bin.length);
     }
 
+    public function writeUuid(uuid : String) : Void {
+        var bytes : Bytes = Uuid.parse(UuidHelper.CanonicalUuid(uuid));
+        Transport.write(bytes, 0, bytes.length);
+    }
 
     // These methods are called by structs, but don't actually have any wire
     // output or purpose.
@@ -616,6 +624,13 @@
     }
 
 
+    public function readUuid() : String {
+        var buffer = new BytesBuffer();
+        Transport.readAll( buffer, 0, 16);
+        var bytes : Bytes = buffer.getBytes();
+        return Uuid.stringify( bytes);
+    }
+
     // These methods are here for the struct to call, but don't have any wire
     // encoding.
     public function readMessageEnd() : Void { }
@@ -723,6 +738,7 @@
 			case TType.MAP:     return 1;  // element count
 			case TType.SET:    return 1;  // element count
 			case TType.LIST:    return 1;  // element count
+			case TType.UUID: return 16;  // uuid bytes
 			default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
 		}
 	}
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TCompactTypes.hx b/lib/haxe/src/org/apache/thrift/protocol/TCompactTypes.hx
index cdd3d87..a3a7aac 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TCompactTypes.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TCompactTypes.hx
@@ -37,5 +37,6 @@
     public static inline var SET           = 0x0A;
     public static inline var MAP           = 0x0B;
     public static inline var STRUCT        = 0x0C;
+    public static inline var UUID          = 0x0D;
 }
 
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx
index 2385ca8..a47479d 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx
@@ -28,6 +28,8 @@
 import haxe.crypto.Base64;
 import haxe.Int64;
 
+import uuid.Uuid;
+
 import org.apache.thrift.TException;
 import org.apache.thrift.protocol.TMessage;
 import org.apache.thrift.protocol.TField;
@@ -35,6 +37,7 @@
 import org.apache.thrift.protocol.TSet;
 import org.apache.thrift.protocol.TList;
 import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.helper.UuidHelper;
 
 
 
@@ -164,6 +167,10 @@
         WriteJSONBase64(bin);
     }
 
+    public function writeUuid(uuid : String) : Void {
+		writeString( UuidHelper.CanonicalUuid(uuid)); 
+    }
+
     public function readMessageBegin():TMessage {
         var message : TMessage = new TMessage();
         ReadJSONArrayStart();
@@ -289,6 +296,10 @@
         return ReadJSONBase64();
     }
 
+    public function readUuid() : String {
+        return UuidHelper.CanonicalUuid( readString()); 
+    }
+
     // Push a new JSON context onto the stack.
     private function  PushContext(c : JSONBaseContext) : Void {
         contextStack.add(context);
@@ -794,6 +805,7 @@
 			case TType.MAP: return 2;  // empty map
 			case TType.SET: return 2;  // empty set
 			case TType.LIST: return 2;  // empty list
+			case TType.UUID: return 36;  // "E236974D-F0B0-4E05-8F29-0B455D41B1A1"
 			default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
 		}
 	}
@@ -892,6 +904,7 @@
     public static var NAME_MAP    = 'map';
     public static var NAME_LIST   = 'lst';
     public static var NAME_SET    = 'set';
+	public static var NAME_UUID   = 'uid';
 
     public static function GetTypeNameForTypeID(typeID : Int) : String {
         switch (typeID)
@@ -907,6 +920,7 @@
             case TType.MAP:         return NAME_MAP;
             case TType.SET:         return NAME_SET;
             case TType.LIST:     return NAME_LIST;
+            case TType.UUID:     return NAME_UUID;
         }
         throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized type");
     }
@@ -922,7 +936,8 @@
         NAME_STRUCT => TType.STRUCT,
         NAME_MAP    => TType.MAP,
         NAME_SET    => TType.SET,
-        NAME_LIST   => TType.LIST
+        NAME_LIST   => TType.LIST,
+		NAME_UUID   => TType.UUID
     ];
 
     public static function GetTypeIDForTypeName(name : String) : Int
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx
index 316067a..6ce5999 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx
@@ -20,7 +20,6 @@
 package org.apache.thrift.protocol;
 
 import haxe.io.Bytes;
-import org.apache.thrift.TException;
 import org.apache.thrift.transport.TTransport;
 
 /**
@@ -54,6 +53,7 @@
     function writeDouble(dub : Float) : Void;
     function writeString(str : String) : Void;
     function writeBinary(bin : Bytes) : Void;
+	function writeUuid(uuid : String) : Void;
 
     /**
      * Reading methods.
@@ -78,6 +78,7 @@
     function readDouble() : Float;
     function readString() : String;
     function readBinary() : Bytes;
+	function readUuid() : String;
 
     // recursion tracking
     function IncrementRecursionDepth() : Void;
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TType.hx b/lib/haxe/src/org/apache/thrift/protocol/TType.hx
index 964b26e..8e21ed7 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TType.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TType.hx
@@ -34,4 +34,5 @@
     public static inline var MAP : Int    = 13;
     public static inline var SET : Int    = 14;
     public static inline var LIST : Int   = 15;
+	public static inline var UUID : Int   = 16;
 }
diff --git a/lib/haxe/test/cpp.hxml b/lib/haxe/test/cpp.hxml
index 28e1a01..04a2543 100644
--- a/lib/haxe/test/cpp.hxml
+++ b/lib/haxe/test/cpp.hxml
@@ -36,11 +36,11 @@
 #To produce 64 bit binaries the file should define the HXCPP_M64 compile variable:
 #-D HXCPP_M64
 
+# libs
+-lib uuid
+
 #Add debug information
 -debug
 
 #dead code elimination : remove unused code
-#"-dce no" : do not remove unused code
-#"-dce std" : remove unused code in the std lib (default)
-#"-dce full" : remove all unused code
 -dce full
\ No newline at end of file
diff --git a/lib/haxe/test/csharp.hxml b/lib/haxe/test/csharp.hxml
index 6ddfd07..e406ce6 100644
--- a/lib/haxe/test/csharp.hxml
+++ b/lib/haxe/test/csharp.hxml
@@ -33,11 +33,11 @@
 #CSHARP target
 -cs bin/Test.exe
 
+# libs
+-lib uuid
+
 #Add debug information
 -debug
 
 #dead code elimination : remove unused code
-#"-dce no" : do not remove unused code
-#"-dce std" : remove unused code in the std lib (default)
-#"-dce full" : remove all unused code
 -dce full
\ No newline at end of file
diff --git a/lib/haxe/test/flash.hxml b/lib/haxe/test/flash.hxml
index 130ab78..6df1f61 100644
--- a/lib/haxe/test/flash.hxml
+++ b/lib/haxe/test/flash.hxml
@@ -33,11 +33,11 @@
 #Flash target
 -swf bin/Test.swf
 
+# libs
+-lib uuid
+
 #Add debug information
 -debug
 
 #dead code elimination : remove unused code
-#"-dce no" : do not remove unused code
-#"-dce std" : remove unused code in the std lib (default)
-#"-dce full" : remove all unused code
 -dce full
\ No newline at end of file
diff --git a/lib/haxe/test/java.hxml b/lib/haxe/test/java.hxml
index b72d99f..0b214d7 100644
--- a/lib/haxe/test/java.hxml
+++ b/lib/haxe/test/java.hxml
@@ -33,11 +33,11 @@
 #Java target
 -java bin/Test.jar
 
+# libs
+-lib uuid
+
 #Add debug information
 -debug
 
 #dead code elimination : remove unused code
-#"-dce no" : do not remove unused code
-#"-dce std" : remove unused code in the std lib (default)
-#"-dce full" : remove all unused code
 -dce full
\ No newline at end of file
diff --git a/lib/haxe/test/javascript.hxml b/lib/haxe/test/javascript.hxml
index 496e780..ad21d16 100644
--- a/lib/haxe/test/javascript.hxml
+++ b/lib/haxe/test/javascript.hxml
@@ -39,11 +39,11 @@
 #you modify your .hx files.
 -D source-map-content
 
+# libs
+-lib uuid
+
 #Generate source map and add debug information
 -debug
 
 #dead code elimination : remove unused code
-#"-dce no" : do not remove unused code
-#"-dce std" : remove unused code in the std lib (default)
-#"-dce full" : remove all unused code
 -dce full
\ No newline at end of file
diff --git a/lib/haxe/test/neko.hxml b/lib/haxe/test/neko.hxml
index eed22bd..51de778 100644
--- a/lib/haxe/test/neko.hxml
+++ b/lib/haxe/test/neko.hxml
@@ -33,11 +33,11 @@
 #neko target
 -neko bin/Test.n
 
+# libs
+-lib uuid
+
 #Add debug information
 -debug
 
 #dead code elimination : remove unused code
-#"-dce no" : do not remove unused code
-#"-dce std" : remove unused code in the std lib (default)
-#"-dce full" : remove all unused code
 -dce full
\ No newline at end of file
diff --git a/lib/haxe/test/php.hxml b/lib/haxe/test/php.hxml
index 3af54da..f94e641 100644
--- a/lib/haxe/test/php.hxml
+++ b/lib/haxe/test/php.hxml
@@ -34,11 +34,11 @@
 -php bin/php/
 #--php-front Main-debug.php
 
+# libs
+-lib uuid
+
 #Add debug information
 -debug
 
 #dead code elimination : remove unused code
-#"-dce no" : do not remove unused code
-#"-dce std" : remove unused code in the std lib (default)
-#"-dce full" : remove all unused code
 -dce full
diff --git a/lib/haxe/test/python.hxml b/lib/haxe/test/python.hxml
index 58eb3cb..dbb48e2 100644
--- a/lib/haxe/test/python.hxml
+++ b/lib/haxe/test/python.hxml
@@ -33,11 +33,11 @@
 #Python target
 -python bin/Test.py
 
+# libs
+-lib uuid
+
 #Add debug information
 -debug
 
 #dead code elimination : remove unused code
-#"-dce no" : do not remove unused code
-#"-dce std" : remove unused code in the std lib (default)
-#"-dce full" : remove all unused code
 -dce full
\ No newline at end of file
diff --git a/lib/haxe/test/src/Main.hx b/lib/haxe/test/src/Main.hx
index e04af78..5976bb0 100644
--- a/lib/haxe/test/src/Main.hx
+++ b/lib/haxe/test/src/Main.hx
@@ -76,9 +76,13 @@
 
             switch( tests) {
                 case Normal:
+                    #if sys
                     StreamTest.Run(server);
+                    #end
                 case Multiplex:
+                    #if ! (flash || html5 || js)
                     MultiplexTest.Run(server);
+                    #end
                 case Constants:
                     ConstantsTest.Run(server);
                 default:
diff --git a/lib/haxe/test/src/MultiplexTest.hx b/lib/haxe/test/src/MultiplexTest.hx
index 74fa357..a17bf15 100644
--- a/lib/haxe/test/src/MultiplexTest.hx
+++ b/lib/haxe/test/src/MultiplexTest.hx
@@ -19,6 +19,8 @@
 
 package;
 
+#if ! (flash || html5 || js)
+
 import haxe.Int64;
 import haxe.Int32;
 
@@ -42,7 +44,6 @@
 import BenchmarkServiceProcessor;
 import Error;
 
-
 class BenchmarkServiceHandler implements BenchmarkService_service
 {
     public function new() {
@@ -221,4 +222,5 @@
 
 }
 
+#end
 
diff --git a/lib/haxe/test/src/StreamTest.hx b/lib/haxe/test/src/StreamTest.hx
index 4744272..3e70ada 100644
--- a/lib/haxe/test/src/StreamTest.hx
+++ b/lib/haxe/test/src/StreamTest.hx
@@ -18,6 +18,7 @@
  */
 
 package;
+#if sys
 
 import haxe.Int64;
 import sys.FileSystem;
@@ -95,3 +96,4 @@
 }
 
 
+#end