unit Outside.Impl.FooService;
interface
uses
Inside.Foo,
Outside.IFooWebService,
Outside.IFooService,
System.Threading,
System.ZLib;
type
TFooDTO =
class
private
FData:
string;
public
/// <summary>
/// Compressed UTF16-String as BASE64
/// </summary>
property Data:
string read FData
write FData;
end;
TFooAssembler =
class
private
FCompressionLevel: TZCompressionLevel;
public
property CompressionLevel: TZCompressionLevel
read FCompressionLevel
write FCompressionLevel;
function Convert( AFoo: TFooDTO ): TFoo;
overload;
function Convert( AFoo: TFoo ): TFooDTO;
overload;
end;
TFooService =
class( TInterfacedObject, IFooService )
private
FFooWebService: IFooWebService;
FFooAssembler: TFooAssembler;
procedure PostFoo( AFoo: TFoo );
overload;
function PostFoo( AFoo: TFoo; callback: TResultAction ): ITask;
overload;
procedure GetFoo(
out AFoo: TFoo );
overload;
function GetFoo( callback: TObjectResultAction<TFoo> ): ITask;
overload;
public
constructor Create( AFooWebService: IFooWebService );
destructor Destroy;
override;
end;
implementation
uses
REST.Json, REST.JsonReflect,
System.NetEncoding,
System.SysUtils;
{ TFooAssembler }
function TFooAssembler.Convert( AFoo: TFoo ): TFooDTO;
var
LFooDTO: TFooDTO;
LInBuffer, LOutBuffer: TBytes;
begin
LFooDTO := TFooDTO.Create;
try
// String mit der entsprechenden Kodierung in eine Byte-Folge umwandeln
LInBuffer := TEncoding.Unicode.GetBytes( AFoo.Data );
// Die Byte-Folge komprimieren
ZCompress(
{inBuffer} LInBuffer,
{outBuffer} LOutBuffer,
{level} CompressionLevel );
// Die komprimierte Byte-Folge in einen BASE64-String kodieren
LFooDTO.Data := TNetEncoding.Base64.EncodeBytesToString( LOutBuffer );
Result := LFooDTO;
LFooDTO :=
nil;
finally
LFooDTO.Free;
end;
end;
function TFooAssembler.Convert( AFoo: TFooDTO ): TFoo;
var
LFoo: TFoo;
LInBuffer, LOutBuffer: TBytes;
begin
LFoo := TFoo.Create;
try
// BASE64 String decodieren in eine Byte-Folge
LInBuffer := TNetEncoding.Base64.DecodeStringToBytes( AFoo.Data );
// Byte-Folge entkomprimieren
ZDecompress(
{inBuffer} LInBuffer,
{outBuffer} LOutBuffer );
// UTF16-String aus der entkomprimierten Byte-Folge lesen
LFoo.Data := TEncoding.Unicode.GetString( LOutBuffer );
Result := LFoo;
LFoo :=
nil;
finally
LFoo.Free;
end;
end;
{ TFooService }
constructor TFooService.Create( AFooWebService: IFooWebService );
begin
inherited Create;
FFooWebService := AFooWebService;
FFooAssembler := TFooAssembler.Create;
FFooAssembler.CompressionLevel := TZCompressionLevel.zcMax;
end;
destructor TFooService.Destroy;
begin
FFooAssembler.Free;
inherited;
end;
function TFooService.GetFoo( callback: TObjectResultAction<TFoo> ): ITask;
begin
Result := TTask.Run(
procedure
var
LFoo: TFoo;
LDispose: Boolean;
begin
LDispose := True;
try
try
GetFoo( LFoo );
callback( LFoo,
nil, LDispose );
except
on E:
Exception do
callback(
nil, E, LDispose );
end;
finally
if LDispose
then
LFoo.Free;
end;
end );
end;
procedure TFooService.GetFoo(
out AFoo: TFoo );
var
LFooDTO: TFooDTO;
LFooStr:
string;
begin
FFooWebService.GetFoo( LFooStr );
LFooDTO := TJson.JsonToObject<TFooDTO>( LFooStr );
try
AFoo := FFooAssembler.Convert( LFooDTO );
finally
LFooDTO.Free;
end;
end;
procedure TFooService.PostFoo( AFoo: TFoo );
var
LFooDTO: TFooDTO;
LFooStr:
string;
begin
LFooDTO := FFooAssembler.Convert( AFoo );
try
LFooStr := TJson.ObjectToJsonString( LFooDTO );
FFooWebService.PostFoo( LFooStr );
finally
LFooDTO.Free;
end;
end;
function TFooService.PostFoo( AFoo: TFoo; callback: TResultAction ): ITask;
begin
Result := TTask.Run(
procedure
begin
try
PostFoo( AFoo );
callback(
nil );
except
on E:
Exception do
callback( E );
end;
end );
end;
end.