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 2019/05/09 22:39:35 UTC

[thrift] branch master updated (acdd422 -> 8f7487e)

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

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


    from acdd422  Remove unused THREADMODEL from MSVC appveyor build
     new 14a9a12  THRIFT-4863 better indication of WinHTTP errors Client: Delphi Patch: Jens Geyer
     new 8f7487e  THRIFT-4862 better ToString() support for enums and container types Client: Delphi Patch: Jens Geyer

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../cpp/src/thrift/generate/t_delphi_generator.cc  |   8 +-
 lib/delphi/src/Thrift.Collections.pas              |  87 ++++++++++++--
 lib/delphi/src/Thrift.Protocol.pas                 |  25 +---
 lib/delphi/src/Thrift.Utils.pas                    |  75 +++++++++++-
 lib/delphi/src/Thrift.WinHTTP.pas                  |   3 +
 lib/delphi/test/TestServer.pas                     | 129 ++++++---------------
 6 files changed, 197 insertions(+), 130 deletions(-)


[thrift] 02/02: THRIFT-4862 better ToString() support for enums and container types Client: Delphi Patch: Jens Geyer

Posted by je...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 8f7487e1086d8da6baff3376679436e526dd8fd0
Author: Jens Geyer <je...@apache.org>
AuthorDate: Thu May 9 22:21:32 2019 +0200

    THRIFT-4862 better ToString() support for enums and container types
    Client: Delphi
    Patch: Jens Geyer
    
    This closes #1795
---
 .../cpp/src/thrift/generate/t_delphi_generator.cc  |   8 +-
 lib/delphi/src/Thrift.Collections.pas              |  87 ++++++++++++--
 lib/delphi/src/Thrift.Protocol.pas                 |  25 +---
 lib/delphi/src/Thrift.Utils.pas                    |  75 +++++++++++-
 lib/delphi/test/TestServer.pas                     | 129 ++++++---------------
 5 files changed, 194 insertions(+), 130 deletions(-)

diff --git a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
index 505120e..11501bf 100644
--- a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
@@ -1743,7 +1743,7 @@ void t_delphi_generator::generate_delphi_struct_definition(ostream& out,
   if (is_exception && (!is_x_factory)) {
     out << "TException";
   } else {
-    out << "TInterfacedObject, IBase, " << struct_intf_name;
+    out << "TInterfacedObject, IBase, ISupportsToString, " << struct_intf_name;
   }
   out << ")" << endl;
 
@@ -3949,8 +3949,10 @@ void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out,
                        << ".Append('<null>') else " << tmp_sb << ".Append( Self."
                        << prop_name((*f_iter), is_exception) << ".ToString());" << endl;
     } else if (ttype->is_enum()) {
-      indent_impl(out) << tmp_sb << ".Append(System.Integer( Self." << prop_name((*f_iter), is_exception)
-                       << "));" << endl;
+      indent_impl(out) << tmp_sb << ".Append(EnumUtils<" 
+                       << type_name(ttype, false, true, is_exception, true) 
+                       << ">.ToString( System.Ord( Self." 
+                       << prop_name((*f_iter), is_exception) << ")));" << endl;
     } else {
       indent_impl(out) << tmp_sb << ".Append( Self." << prop_name((*f_iter), is_exception) << ");"
                        << endl;
diff --git a/lib/delphi/src/Thrift.Collections.pas b/lib/delphi/src/Thrift.Collections.pas
index b2206cb..2e13724 100644
--- a/lib/delphi/src/Thrift.Collections.pas
+++ b/lib/delphi/src/Thrift.Collections.pas
@@ -22,7 +22,7 @@ unit Thrift.Collections;
 interface
 
 uses
-  Generics.Collections, Generics.Defaults, Thrift.Utils;
+  SysUtils, Generics.Collections, Generics.Defaults, Thrift.Utils;
 
 type
 
@@ -30,11 +30,11 @@ type
   TArray<T> = array of T;
 {$IFEND}
 
-  IThriftContainer = interface
-    ['{93DEF5A0-D162-461A-AB22-5B4EE0734050}']
-    function ToString: string;
+  IThriftContainer = interface( ISupportsToString)
+    ['{E05C0F9D-A4F5-491D-AADA-C926B4BDB6E4}']
   end;
 
+
   IThriftDictionary<TKey,TValue> = interface(IThriftContainer)
     ['{25EDD506-F9D1-4008-A40F-5940364B7E46}']
     function GetEnumerator: TEnumerator<TPair<TKey,TValue>>;
@@ -64,7 +64,7 @@ type
     property Values: TDictionary<TKey,TValue>.TValueCollection read GetValues;
   end;
 
-  TThriftDictionaryImpl<TKey,TValue> = class( TInterfacedObject, IThriftDictionary<TKey,TValue>)
+  TThriftDictionaryImpl<TKey,TValue> = class( TInterfacedObject, IThriftDictionary<TKey,TValue>, IThriftContainer, ISupportsToString)
   private
     FDictionaly : TDictionary<TKey,TValue>;
   protected
@@ -95,6 +95,7 @@ type
   public
     constructor Create(ACapacity: Integer = 0);
     destructor Destroy; override;
+    function ToString : string;  override;
   end;
 
   IThriftList<T> = interface(IThriftContainer)
@@ -140,7 +141,7 @@ type
     property Items[Index: Integer]: T read GetItem write SetItem; default;
   end;
 
-  TThriftListImpl<T> = class( TInterfacedObject, IThriftList<T>)
+  TThriftListImpl<T> = class( TInterfacedObject, IThriftList<T>, IThriftContainer, ISupportsToString)
   private
     FList : TList<T>;
   protected
@@ -186,6 +187,7 @@ type
   public
     constructor Create;
     destructor Destroy; override;
+    function ToString : string;  override;
   end;
 
   IHashSet<TValue> = interface(IThriftContainer)
@@ -202,7 +204,7 @@ type
     function Remove( const item: TValue ): Boolean;
   end;
 
-  THashSetImpl<TValue> = class( TInterfacedObject, IHashSet<TValue>)
+  THashSetImpl<TValue> = class( TInterfacedObject, IHashSet<TValue>, IThriftContainer, ISupportsToString)
   private
     FDictionary : IThriftDictionary<TValue,Integer>;
     FIsReadOnly: Boolean;
@@ -219,6 +221,7 @@ type
     function Remove( const item: TValue ): Boolean;
   public
     constructor Create;
+    function ToString : string;  override;
   end;
 
 implementation
@@ -287,6 +290,28 @@ begin
   end;
 end;
 
+function THashSetImpl<TValue>.ToString : string;
+var elm : TValue;
+    sb : TThriftStringBuilder;
+    first : Boolean;
+begin
+  sb := TThriftStringBuilder.Create('{');
+  try
+    first := TRUE;
+    for elm in FDictionary.Keys do begin
+      if first
+      then first := FALSE
+      else sb.Append(', ');
+
+      sb.Append( StringUtils<TValue>.ToString(elm));
+    end;
+    sb.Append('}');
+    Result := sb.ToString;
+  finally
+    sb.Free;
+  end;
+end;
+
 { TThriftDictionaryImpl<TKey, TValue> }
 
 procedure TThriftDictionaryImpl<TKey, TValue>.Add(const Key: TKey;
@@ -393,6 +418,32 @@ begin
 {$IFEND}
 end;
 
+function TThriftDictionaryImpl<TKey, TValue>.ToString : string;
+var pair : TPair<TKey, TValue>;
+    sb : TThriftStringBuilder;
+    first : Boolean;
+begin
+  sb := TThriftStringBuilder.Create('{');
+  try
+    first := TRUE;
+    for pair in FDictionaly do begin
+      if first
+      then first := FALSE
+      else sb.Append(', ');
+
+      sb.Append( '(');
+      sb.Append( StringUtils<TKey>.ToString(pair.Key));
+      sb.Append(' => ');
+      sb.Append( StringUtils<TValue>.ToString(pair.Value));
+      sb.Append(')');
+    end;
+    sb.Append('}');
+    Result := sb.ToString;
+  finally
+    sb.Free;
+  end;
+end;
+
 procedure TThriftDictionaryImpl<TKey, TValue>.TrimExcess;
 begin
   FDictionaly.TrimExcess;
@@ -611,6 +662,28 @@ begin
 {$IFEND}
 end;
 
+function TThriftListImpl<T>.ToString : string;
+var elm : T;
+    sb : TThriftStringBuilder;
+    first : Boolean;
+begin
+  sb := TThriftStringBuilder.Create('{');
+  try
+    first := TRUE;
+    for elm in FList do begin
+      if first
+      then first := FALSE
+      else sb.Append(', ');
+
+      sb.Append( StringUtils<T>.ToString(elm));
+    end;
+    sb.Append('}');
+    Result := sb.ToString;
+  finally
+    sb.Free;
+  end;
+end;
+
 procedure TThriftListImpl<T>.TrimExcess;
 begin
   FList.TrimExcess;
diff --git a/lib/delphi/src/Thrift.Protocol.pas b/lib/delphi/src/Thrift.Protocol.pas
index 36509ca..609dfc6 100644
--- a/lib/delphi/src/Thrift.Protocol.pas
+++ b/lib/delphi/src/Thrift.Protocol.pas
@@ -29,6 +29,7 @@ uses
   Contnrs,
   Thrift.Exception,
   Thrift.Stream,
+  Thrift.Utils,
   Thrift.Collections,
   Thrift.Transport;
 
@@ -111,12 +112,6 @@ type
     function GetProtocol( const trans: ITransport): IProtocol;
   end;
 
-  TThriftStringBuilder = class( TStringBuilder)
-  public
-    function Append(const Value: TBytes): TStringBuilder; overload;
-    function Append(const Value: IThriftContainer): TStringBuilder; overload;
-  end;
-
   TProtocolException = class( TException)
   public
     const // TODO(jensg): change into enum
@@ -292,9 +287,8 @@ type
     constructor Create( trans: ITransport );
   end;
 
-  IBase = interface
-    ['{08D9BAA8-5EAA-410F-B50B-AC2E6E5E4155}']
-    function ToString: string;
+  IBase = interface( ISupportsToString)
+    ['{AFF6CECA-5200-4540-950E-9B89E0C1C00C}']
     procedure Read( const iprot: IProtocol);
     procedure Write( const iprot: IProtocol);
   end;
@@ -1034,19 +1028,6 @@ begin
   inherited HiddenCreate(Msg);
 end;
 
-{ TThriftStringBuilder }
-
-function TThriftStringBuilder.Append(const Value: TBytes): TStringBuilder;
-begin
-  Result := Append( string( RawByteString(Value)) );
-end;
-
-function TThriftStringBuilder.Append(
-  const Value: IThriftContainer): TStringBuilder;
-begin
-  Result := Append( Value.ToString );
-end;
-
 { TBinaryProtocolImpl.TFactory }
 
 constructor TBinaryProtocolImpl.TFactory.Create(AStrictRead, AStrictWrite: Boolean);
diff --git a/lib/delphi/src/Thrift.Utils.pas b/lib/delphi/src/Thrift.Utils.pas
index 7e57863..46e238c 100644
--- a/lib/delphi/src/Thrift.Utils.pas
+++ b/lib/delphi/src/Thrift.Utils.pas
@@ -25,12 +25,19 @@ interface
 
 uses
   {$IFDEF OLD_UNIT_NAMES}
-  Classes, Windows, SysUtils, Character, SyncObjs;
+  Classes, Windows, SysUtils, Character, SyncObjs, TypInfo, Rtti;
   {$ELSE}
-  System.Classes, Winapi.Windows, System.SysUtils, System.Character, System.SyncObjs;
+  System.Classes, Winapi.Windows, System.SysUtils, System.Character,
+  System.SyncObjs, System.TypInfo, System.Rtti;
   {$ENDIF}
 
 type
+  ISupportsToString = interface
+    ['{AF71C350-E0CD-4E94-B77C-0310DC8227FF}']
+    function ToString : string;
+  end;
+
+
   IOverlappedHelper = interface
     ['{A1832EFA-2E02-4884-8F09-F0A0277157FA}']
     function Overlapped : TOverlapped;
@@ -55,6 +62,13 @@ type
   end;
 
 
+  TThriftStringBuilder = class( TStringBuilder)
+  public
+    function Append(const Value: TBytes): TStringBuilder; overload;
+    function Append(const Value: ISupportsToString): TStringBuilder; overload;
+  end;
+
+
   Base64Utils = class sealed
   public
     class function Encode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; static;
@@ -68,6 +82,16 @@ type
     class function IsLowSurrogate( const c : Char) : Boolean; static; inline;
   end;
 
+  EnumUtils<T> = class sealed
+  public
+    class function ToString(const value : Integer) : string;  reintroduce; static; inline;
+  end;
+
+  StringUtils<T> = class sealed
+  public
+    class function ToString(const value : T) : string;  reintroduce; static; inline;
+  end;
+
 
 {$IFDEF Win64}
 function InterlockedExchangeAdd64( var Addend : Int64; Value : Int64) : Int64;  
@@ -256,4 +280,51 @@ end;
 {$ENDIF}
 
 
+{ EnumUtils<T> }
+
+class function EnumUtils<T>.ToString(const value : Integer) : string;
+var pType : PTypeInfo;
+begin
+  pType := PTypeInfo(TypeInfo(T));
+  if Assigned(pType) and (pType^.Kind = tkEnumeration)
+  then result := GetEnumName(pType,value)
+  else result := IntToStr(Ord(value));
+end;
+
+
+{ StringUtils<T> }
+
+class function StringUtils<T>.ToString(const value : T) : string;
+var pType : PTypeInfo;
+    base  : ISupportsToString;
+begin
+  pType := PTypeInfo(TypeInfo(T));
+  if Assigned(pType) then begin
+    case pType^.Kind of
+      tkInterface : begin
+        if Supports(IInterface(value), ISupportsToString, base) then begin
+          result := base.toString;
+          Exit;
+        end;
+      end;
+    end;
+  end;
+
+  result := TValue.From<T>(value).ToString;
+end;
+
+
+{ TThriftStringBuilder }
+
+function TThriftStringBuilder.Append(const Value: TBytes): TStringBuilder;
+begin
+  Result := Append( string( RawByteString(Value)) );
+end;
+
+function TThriftStringBuilder.Append( const Value: ISupportsToString): TStringBuilder;
+begin
+  Result := Append( Value.ToString );
+end;
+
+
 end.
diff --git a/lib/delphi/test/TestServer.pas b/lib/delphi/test/TestServer.pas
index 374472c..4cb0090 100644
--- a/lib/delphi/test/TestServer.pas
+++ b/lib/delphi/test/TestServer.pas
@@ -150,7 +150,7 @@ end;
 
 function TTestServer.TTestHandlerImpl.testEnum(thing: TNumberz): TNumberz;
 begin
-  Console.WriteLine('testEnum(' + IntToStr( Integer( thing)) + ')');
+  Console.WriteLine('testEnum(' + EnumUtils<TNumberz>.ToString(Ord(thing)) + ')');
   Result := thing;
 end;
 
@@ -191,7 +191,10 @@ var
   insane : IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
 
 begin
-  Console.WriteLine('testInsanity()');
+  Console.Write('testInsanity(');
+  if argument <> nil then Console.Write(argument.ToString);
+  Console.WriteLine(')');
+
 
   (**
    * So you think you've got this all worked, out eh?
@@ -222,49 +225,20 @@ begin
   Result := insane;
 end;
 
-function TTestServer.TTestHandlerImpl.testList(
-  const thing: IThriftList<Integer>): IThriftList<Integer>;
-var
-  first : Boolean;
-  elem : Integer;
+function TTestServer.TTestHandlerImpl.testList( const thing: IThriftList<Integer>): IThriftList<Integer>;
 begin
-  Console.Write('testList({');
-  first := True;
-  for elem in thing do
-  begin
-    if first then
-    begin
-      first := False;
-    end else
-    begin
-      Console.Write(', ');
-    end;
-    Console.Write( IntToStr( elem));
-  end;
-  Console.WriteLine('})');
+  Console.Write('testList(');
+  if thing <> nil then Console.Write(thing.ToString);
+  Console.WriteLine(')');
   Result := thing;
 end;
 
 function TTestServer.TTestHandlerImpl.testMap(
   const thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
-var
-  first : Boolean;
-  key : Integer;
 begin
-  Console.Write('testMap({');
-  first := True;
-  for key in thing.Keys do
-  begin
-    if (first) then
-    begin
-      first := false;
-    end else
-    begin
-      Console.Write(', ');
-    end;
-    Console.Write(IntToStr(key) + ' => ' + IntToStr( thing[key]));
-  end;
-  Console.WriteLine('})');
+  Console.Write('testMap(');
+  if thing <> nil then Console.Write(thing.ToString);
+  Console.WriteLine(')');
   Result := thing;
 end;
 
@@ -313,12 +287,11 @@ var
   x2 : TXception2;
 begin
   Console.WriteLine('testMultiException(' + arg0 + ', ' + arg1 + ')');
-  if ( arg0 = 'Xception') then
-  begin
+  if ( arg0 = 'Xception') then begin
     raise TXception.Create( 1001, 'This is an Xception');  // test the new rich CTOR
-  end else
-  if ( arg0 = 'Xception2') then
-  begin
+  end;
+
+  if ( arg0 = 'Xception2') then begin
     x2 := TXception2.Create;  // the old way still works too?
     x2.ErrorCode := 2002;
     x2.Struct_thing := TXtructImpl.Create;
@@ -332,17 +305,11 @@ begin
 end;
 
 function TTestServer.TTestHandlerImpl.testNest( const thing: IXtruct2): IXtruct2;
-var
-  temp : IXtruct;
 begin
-  temp := thing.Struct_thing;
-  Console.WriteLine('testNest({' +
-         IntToStr( thing.Byte_thing) + ', {' +
-         '"' + temp.String_thing + '", ' +
-         IntToStr( temp.Byte_thing) + ', ' +
-         IntToStr( temp.I32_thing) + ', ' +
-         IntToStr( temp.I64_thing) + '}, ' +
-         IntToStr( temp.I32_thing) + '})');
+  Console.Write('testNest(');
+  if thing <> nil then Console.Write(thing.ToString);
+  Console.WriteLine(')');
+
   Result := thing;
 end;
 
@@ -353,34 +320,18 @@ begin
   Console.WriteLine('testOneway finished');
 end;
 
-function TTestServer.TTestHandlerImpl.testSet(
-  const thing: IHashSet<Integer>):IHashSet<Integer>;
-var
-  first : Boolean;
-  elem : Integer;
+function TTestServer.TTestHandlerImpl.testSet( const thing: IHashSet<Integer>):IHashSet<Integer>;
 begin
-  Console.Write('testSet({');
-  first := True;
+  Console.Write('testSet(');
+  if thing <> nil then Console.Write(thing.ToString);
+  Console.WriteLine(')');;
 
-  for elem in thing do
-  begin
-    if first then
-    begin
-      first := False;
-    end else
-    begin
-      Console.Write( ', ');
-    end;
-    Console.Write( IntToStr( elem));
-  end;
-  Console.WriteLine('})');
   Result := thing;
 end;
 
 procedure TTestServer.TTestHandlerImpl.testStop;
 begin
-  if FServer <> nil then
-  begin
+  if FServer <> nil then begin
     FServer.Stop;
   end;
 end;
@@ -399,24 +350,11 @@ end;
 
 function TTestServer.TTestHandlerImpl.testStringMap(
   const thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
-var
-  first : Boolean;
-  key : string;
 begin
-  Console.Write('testStringMap({');
-  first := True;
-  for key in thing.Keys do
-  begin
-    if (first) then
-    begin
-      first := false;
-    end else
-    begin
-      Console.Write(', ');
-    end;
-    Console.Write(key + ' => ' + thing[key]);
-  end;
-  Console.WriteLine('})');
+  Console.Write('testStringMap(');
+  if thing <> nil then Console.Write(thing.ToString);
+  Console.WriteLine(')');
+
   Result := thing;
 end;
 
@@ -433,11 +371,10 @@ end;
 
 function TTestServer.TTestHandlerImpl.testStruct( const thing: IXtruct): IXtruct;
 begin
-  Console.WriteLine('testStruct({' +
-    '"' + thing.String_thing + '", ' +
-      IntToStr( thing.Byte_thing) + ', ' +
-      IntToStr( thing.I32_thing) + ', ' +
-      IntToStr( thing.I64_thing));
+  Console.Write('testStruct(');
+  if thing <> nil then Console.Write(thing.ToString);
+  Console.WriteLine(')');
+
   Result := thing;
 end;
 


[thrift] 01/02: THRIFT-4863 better indication of WinHTTP errors Client: Delphi Patch: Jens Geyer

Posted by je...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 14a9a120a859c2e101bcd5f529693139bf9aef7a
Author: Jens Geyer <je...@apache.org>
AuthorDate: Thu May 9 23:29:24 2019 +0200

    THRIFT-4863 better indication of WinHTTP errors
    Client: Delphi
    Patch: Jens Geyer
---
 lib/delphi/src/Thrift.WinHTTP.pas | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib/delphi/src/Thrift.WinHTTP.pas b/lib/delphi/src/Thrift.WinHTTP.pas
index 0d824b6..6ad8400 100644
--- a/lib/delphi/src/Thrift.WinHTTP.pas
+++ b/lib/delphi/src/Thrift.WinHTTP.pas
@@ -497,6 +497,7 @@ begin
                          PWideChar(Pointer(aProxy)),        // may be nil
                          PWideChar(Pointer(aProxyBypass)),  // may be nil
                          aFlags);
+  if handle = nil then RaiseLastOSError;
   inherited Create( handle);
 end;
 
@@ -527,6 +528,7 @@ var handle : HINTERNET;
 begin
   FSession := aSession;
   handle   := WinHttpConnect( FSession.Handle, PWideChar(aHostName), aPort, 0);
+  if handle = nil then RaiseLastOSError;
   inherited Create( handle);
 end;
 
@@ -572,6 +574,7 @@ begin
                                      PWideChar(aReferrer),
                                      @accept,
                                      aFlags);
+  if handle = nil then RaiseLastOSError;
   inherited Create( handle);
 end;