THRIFT-3788 Compatibility improvements and Win64 support
Client: Delphi
Patch: Nick Homolibere

Tested on XE, XE5, XE8, XE10

This closes #987
diff --git a/lib/delphi/src/Thrift.Serializer.pas b/lib/delphi/src/Thrift.Serializer.pas
index cf646c8..b4d6e6d 100644
--- a/lib/delphi/src/Thrift.Serializer.pas
+++ b/lib/delphi/src/Thrift.Serializer.pas
@@ -18,10 +18,18 @@
  *)
 unit Thrift.Serializer;
 
+{$IF CompilerVersion >= 23.0}
+  {$LEGACYIFEND ON}
+{$IFEND}
+
 interface
 
 uses
-  Classes, Windows, SysUtils,
+  {$IF CompilerVersion < 23.0}
+    Classes, Windows, SysUtils,
+  {$ELSE}
+    System.Classes, Winapi.Windows, System.SysUtils,
+  {$IFEND}
   Thrift.Protocol,
   Thrift.Transport,
   Thrift.Stream;
diff --git a/lib/delphi/src/Thrift.Server.pas b/lib/delphi/src/Thrift.Server.pas
index 2935747..8d95ed2 100644
--- a/lib/delphi/src/Thrift.Server.pas
+++ b/lib/delphi/src/Thrift.Server.pas
@@ -20,11 +20,18 @@
  unit Thrift.Server;
 
 {$I-}  // prevent annoying errors with default log delegate and no console
+{$IF CompilerVersion >= 23.0}
+  {$LEGACYIFEND ON}
+{$IFEND}
 
 interface
 
 uses
-  Windows, SysUtils,
+  {$IF CompilerVersion < 23.0}
+    Windows, SysUtils,
+  {$ELSE}
+    Winapi.Windows, System.SysUtils,
+  {$IFEND}
   Thrift,
   Thrift.Protocol,
   Thrift.Transport;
diff --git a/lib/delphi/src/Thrift.Stream.pas b/lib/delphi/src/Thrift.Stream.pas
index 74c1782..d78afe6 100644
--- a/lib/delphi/src/Thrift.Stream.pas
+++ b/lib/delphi/src/Thrift.Stream.pas
@@ -19,6 +19,10 @@
 
 unit Thrift.Stream;
 
+{$IF CompilerVersion >= 23.0}
+  {$LEGACYIFEND ON}
+{$IFEND}
+
 interface
 
 uses
@@ -26,8 +30,12 @@
   SysUtils,
   SysConst,
   RTLConsts,
-  Thrift.Utils,
-  ActiveX;
+  {$IF CompilerVersion < 23.0}
+    ActiveX,
+  {$ELSE}
+    Winapi.ActiveX,
+  {$IFEND}
+  Thrift.Utils;
 
 type
 
@@ -140,7 +148,7 @@
 var
   statstg: TStatStg;
   len : Integer;
-  NewPos : {$IF CompilerVersion >= 30.0} UInt64 {$ELSE} Int64  {$IFEND};
+  NewPos : {$IF CompilerVersion >= 29.0} UInt64 {$ELSE} Int64  {$IFEND};
   cbRead : Integer;
 begin
   FillChar( statstg, SizeOf( statstg), 0);
diff --git a/lib/delphi/src/Thrift.Transport.Pipes.pas b/lib/delphi/src/Thrift.Transport.Pipes.pas
index 47f3b4d..9e62341 100644
--- a/lib/delphi/src/Thrift.Transport.Pipes.pas
+++ b/lib/delphi/src/Thrift.Transport.Pipes.pas
@@ -19,11 +19,18 @@
 unit Thrift.Transport.Pipes;
 
 {$WARN SYMBOL_PLATFORM OFF}
+{$IF CompilerVersion >= 23.0}
+  {$LEGACYIFEND ON}
+{$IFEND}
 
 interface
 
 uses
+{$IF CompilerVersion < 23.0}
   Windows, SysUtils, Math, AccCtrl, AclAPI, SyncObjs,
+{$ELSE}
+  Winapi.Windows, System.SysUtils, System.Math, Winapi.AccCtrl, Winapi.AclAPI, System.SyncObjs,
+{$IFEND}
   Thrift.Transport,
   Thrift.Utils,
   Thrift.Stream;
@@ -896,9 +903,14 @@
 
 
 function TNamedPipeServerTransportImpl.Handle : THandle;
+{$IFDEF WIN64}
+var
+  Hndl: Integer;
+{$ENDIF}
 begin
   {$IFDEF WIN64}
-  result := THandle( InterlockedExchangeAdd64( Integer(FHandle), 0));
+  Hndl := Integer(FHandle);
+  result := THandle( InterlockedExchangeAdd( Hndl, 0));
   {$ELSE}
   result := THandle( InterlockedExchangeAdd( Integer(FHandle), 0));
   {$ENDIF}
@@ -946,6 +958,7 @@
     sa.bInheritHandle       := FALSE;
 
     // Create an instance of the named pipe
+{$IF CompilerVersion < 23.0}
     result := Windows.CreateNamedPipe( PChar( FPipeName),        // pipe name
                                        PIPE_ACCESS_DUPLEX or     // read/write access
                                        FILE_FLAG_OVERLAPPED,     // async mode
@@ -956,6 +969,18 @@
                                        FBufSize,                 // input buffer size
                                        FTimeout,                 // time-out, see MSDN
                                        @sa);                     // default security attribute
+{$ELSE}
+    result := Winapi.Windows.CreateNamedPipe( PChar( FPipeName),        // pipe name
+                                       PIPE_ACCESS_DUPLEX or     // read/write access
+                                       FILE_FLAG_OVERLAPPED,     // async mode
+                                       PIPE_TYPE_BYTE or         // byte type pipe
+                                       PIPE_READMODE_BYTE,       // byte read mode
+                                       FMaxConns,                // max. instances
+                                       FBufSize,                 // output buffer size
+                                       FBufSize,                 // input buffer size
+                                       FTimeout,                 // time-out, see MSDN
+                                       @sa);                     // default security attribute
+{$IFEND}
 
     if( result <> INVALID_HANDLE_VALUE)
     then InterlockedExchangePointer( Pointer(FHandle), Pointer(result))
diff --git a/lib/delphi/src/Thrift.Transport.pas b/lib/delphi/src/Thrift.Transport.pas
index c0d6712..c0f3111 100644
--- a/lib/delphi/src/Thrift.Transport.pas
+++ b/lib/delphi/src/Thrift.Transport.pas
@@ -17,7 +17,10 @@
  * under the License.
  *)
 
- {$SCOPEDENUMS ON}
+{$SCOPEDENUMS ON}
+{$IF CompilerVersion >= 23.0}
+  {$LEGACYIFEND ON}
+{$IFEND}
 
 {$IF CompilerVersion < 28.0}
   {$DEFINE OLD_SOCKETS}   // TODO: add socket support for CompilerVersion >= 28.0
@@ -32,16 +35,20 @@
   Classes,
   SysUtils,
   Math,
-  WinSock,
-  {$IFDEF OLD_SOCKETS}
-  Sockets,
-  {$ENDIF}
   Generics.Collections,
+{$IF CompilerVersion < 23.0}
+  ActiveX, msxml, WinSock, Sockets,
+{$ELSE}
+  Winapi.ActiveX, Winapi.msxml, Winapi.WinSock,
+  {$IF CompilerVersion < 28.0}
+    Web.Win.Sockets,
+  {$ELSE}
+    System.Win.ScktComp,
+  {$IFEND}
+{$IFEND}
   Thrift.Collections,
   Thrift.Utils,
-  Thrift.Stream,
-  ActiveX,
-  msxml;
+  Thrift.Stream;
 
 type
   ITransport = interface
@@ -1253,7 +1260,11 @@
   wsaError := 0;
   try
 {$IFDEF MSWINDOWS}
+  {$IF CompilerVersion < 23.0}
     result := WinSock.select(socket + 1, ReadFdsptr, WriteFdsptr, ExceptFdsptr, Timeptr);
+  {$ELSE}
+    result := Winapi.WinSock.select(socket + 1, ReadFdsptr, WriteFdsptr, ExceptFdsptr, Timeptr);
+  {$IFEND}
 {$ENDIF}
 {$IFDEF LINUX}
     result := Libc.select(socket + 1, ReadFdsptr, WriteFdsptr, ExceptFdsptr, Timeptr);
@@ -1293,7 +1304,11 @@
 
   // recv() returns the number of bytes received, or -1 if an error occurred.
   // The return value will be 0 when the peer has performed an orderly shutdown.
+{$IF CompilerVersion < 23.0}
   retval := recv( FTcpClient.Handle, pBuf^, DesiredBytes, WinSock.MSG_PEEK);
+{$ELSE}
+  retval := recv( FTcpClient.Handle, pBuf^, DesiredBytes, Winapi.WinSock.MSG_PEEK);
+{$IFEND}
   if retval <= 0
   then Exit( TWaitForData.wfd_Error);
 
diff --git a/lib/delphi/src/Thrift.Utils.pas b/lib/delphi/src/Thrift.Utils.pas
index 17131ef..962ef54 100644
--- a/lib/delphi/src/Thrift.Utils.pas
+++ b/lib/delphi/src/Thrift.Utils.pas
@@ -21,8 +21,16 @@
 
 interface
 
+{$IF CompilerVersion >= 23.0}
+  {$LEGACYIFEND ON}
+{$IFEND}
+
 uses
+{$IF CompilerVersion < 23.0}
   Classes, Windows, SysUtils, Character, SyncObjs;
+{$ELSE}
+  System.Classes, Winapi.Windows, System.SysUtils, System.Character, System.SyncObjs;
+{$IFEND}
 
 type
   IOverlappedHelper = interface
@@ -199,7 +207,11 @@
   {$IF RTLVersion  >= 28.0}  // XE7+
   result := c.IsHighSurrogate();
   {$ELSE}
-  result := Character.IsHighSurrogate( c);
+    {$IF CompilerVersion < 23.0}
+      result := Character.IsHighSurrogate( c);
+    {$ELSE}
+      result := c.IsHighSurrogate;
+    {$IFEND}
   {$IFEND}
 end;
 
@@ -209,7 +221,11 @@
   {$IF RTLVersion  >= 28.0}  // XE7+
   result := c.IsLowSurrogate();
   {$ELSE}
-  result := Character.IsLowSurrogate( c);
+    {$IF CompilerVersion < 23.0}
+      result := Character.IsLowSurrogate( c);
+    {$ELSE}
+      result := c.IsLowSurrogate;
+    {$IFEND}
   {$IFEND}
 end;