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;