THRIFT-5591 Add uuid type to IDL and implement reference code (+ improved self-tests)
Client: compiler general, netstd, Delphi
Patch: Jens Geyer
diff --git a/lib/delphi/src/Thrift.Protocol.pas b/lib/delphi/src/Thrift.Protocol.pas
index 9f2cac8..636f201 100644
--- a/lib/delphi/src/Thrift.Protocol.pas
+++ b/lib/delphi/src/Thrift.Protocol.pas
@@ -49,7 +49,8 @@
     Struct = 12,
     Map = 13,
     Set_ = 14,
-    List = 15
+    List = 15,
+    Uuid = 16
   );
 
   TMessageType = (
@@ -62,7 +63,7 @@
 const
   VALID_TTYPES = [
     TType.Stop, TType.Void,
-    TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_,
+    TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_, TType.Uuid,
     TType.Struct, TType.Map, TType.Set_, TType.List
   ];
 
@@ -221,6 +222,7 @@
     procedure WriteAnsiString( const s: AnsiString);
     procedure WriteBinary( const b: TBytes); overload;
     procedure WriteBinary( const b: IThriftBytes); overload;
+    procedure WriteUuid( const uuid: TGuid);
 
     function ReadMessageBegin: TThriftMessage;
     procedure ReadMessageEnd();
@@ -242,6 +244,7 @@
     function ReadDouble:Double;
     function ReadBinary: TBytes;  // IMPORTANT: this is NOT safe across module boundaries
     function ReadBinaryCOM : IThriftBytes;
+    function ReadUuid: TGuid;
     function ReadString: string;
     function ReadAnsiString: AnsiString;
 
@@ -297,6 +300,7 @@
     procedure WriteString( const s: string ); virtual;
     procedure WriteAnsiString( const s: AnsiString); virtual;
     procedure WriteBinary( const b: TBytes); overload; virtual; abstract;
+    procedure WriteUuid( const b: TGuid); virtual; abstract;
 
     function ReadMessageBegin: TThriftMessage; virtual; abstract;
     procedure ReadMessageEnd(); virtual; abstract;
@@ -317,6 +321,7 @@
     function ReadI64: Int64; virtual; abstract;
     function ReadDouble:Double; virtual; abstract;
     function ReadBinary: TBytes; virtual; abstract;
+    function ReadUuid: TGuid; virtual; abstract;
     function ReadString: string; virtual;
     function ReadAnsiString: AnsiString; virtual;
 
@@ -415,6 +420,7 @@
     procedure WriteI64( const i64: Int64); override;
     procedure WriteDouble( const d: Double); override;
     procedure WriteBinary( const b: TBytes); override;
+    procedure WriteUuid( const uuid: TGuid); override;
 
     function ReadMessageBegin: TThriftMessage; override;
     procedure ReadMessageEnd(); override;
@@ -435,6 +441,7 @@
     function ReadI64: Int64; override;
     function ReadDouble:Double; override;
     function ReadBinary: TBytes; override;
+    function ReadUuid: TGuid; override;
 
   end;
 
@@ -479,6 +486,7 @@
     procedure WriteString( const s: string ); override;
     procedure WriteAnsiString( const s: AnsiString); override;
     procedure WriteBinary( const b: TBytes); override;
+    procedure WriteUuid( const uuid: TGuid); override;
 
     function ReadMessageBegin: TThriftMessage; override;
     procedure ReadMessageEnd(); override;
@@ -499,6 +507,7 @@
     function ReadI64: Int64; override;
     function ReadDouble:Double; override;
     function ReadBinary: TBytes; override;
+    function ReadUuid: TGuid; override;
     function ReadString: string; override;
     function ReadAnsiString: AnsiString; override;
   end;
@@ -800,6 +809,7 @@
     TType.I64     :  prot.ReadI64();
     TType.Double_ :  prot.ReadDouble();
     TType.String_ :  prot.ReadBinary();// Don't try to decode the string, just skip it.
+    TType.Uuid    :  prot.ReadUuid();
 
     // structured types
     TType.Struct :  begin
@@ -874,6 +884,14 @@
   Result := buf;
 end;
 
+function TBinaryProtocolImpl.ReadUuid : TGuid;
+var network : TGuid;  // in network order (Big Endian)
+begin
+  ASSERT( SizeOf(result) = 16);
+  FTrans.ReadAll( @network, SizeOf(network), 0, SizeOf(network));
+  result := network.SwapByteOrder;
+end;
+
 function TBinaryProtocolImpl.ReadBool: Boolean;
 begin
   Result := (ReadByte = 1);
@@ -1042,6 +1060,14 @@
   if iLen > 0 then FTrans.Write(b, 0, iLen);
 end;
 
+procedure TBinaryProtocolImpl.WriteUuid( const uuid: TGuid);
+var network : TGuid;  // in network order (Big Endian)
+begin
+  ASSERT( SizeOf(uuid) = 16);
+  network := uuid.SwapByteOrder;
+  Transport.Write( @network, 0, SizeOf(network));
+end;
+
 procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
 begin
   if b then begin
@@ -1191,6 +1217,7 @@
     TType.Map:     result := SizeOf(Int32);  // element count
     TType.Set_:    result := SizeOf(Int32);  // element count
     TType.List:    result := SizeOf(Int32);  // element count
+    TType.Uuid:    result := SizeOf(TGuid);
   else
     raise TTransportExceptionBadArgs.Create('Unhandled type code');
   end;
@@ -1437,6 +1464,12 @@
 end;
 
 
+procedure TProtocolDecorator.WriteUuid( const uuid: TGuid);
+begin
+  FWrappedProtocol.WriteUuid( uuid);
+end;
+
+
 function TProtocolDecorator.ReadMessageBegin: TThriftMessage;
 begin
   result := FWrappedProtocol.ReadMessageBegin;
@@ -1551,6 +1584,12 @@
 end;
 
 
+function TProtocolDecorator.ReadUuid: TGuid;
+begin
+  result := FWrappedProtocol.ReadUuid;
+end;
+
+
 function TProtocolDecorator.ReadString: string;
 begin
   result := FWrappedProtocol.ReadString;