unit uROAsyncResponseStorage; {----------------------------------------------------------------------------} { RemObjects SDK Library - Core Library } { } { compiler: Delphi 5 and up, Kylix 2 and up } { platform: Win32, Linux } { } { (c)opyright RemObjects Software. all rights reserved. } { } { Using this code requires a valid license of the RemObjects SDK } { which can be obtained at http://www.remobjects.com. } {----------------------------------------------------------------------------} {$I RemObjects.inc} interface uses Classes, SysUtils, uROClasses, uROClient; type TROResponseItem = class; { IROAsyncResponseStorage } IROAsyncResponseStorage = interface ['{CD2C473C-F557-4B04-876A-4367D5959680}'] procedure AddResp(aResp: TROResponseItem); procedure RemoveResp(aResp: TROResponseItem); procedure RemoveRespByUID(aUID: String); procedure DeleteResp(Index: Integer); function GetResp(Index: Integer): TROResponseItem; function GetRespByUID(aUID: String): TROResponseItem; function IndexOfResp(aResp: TROResponseItem): Integer; function CountOfResp: Integer; procedure ClearStorage; property ResponseItem[Index: Integer]: TROResponseItem read GetResp; end; { TROAsyncResponseStorage } TROAsyncResponseStorage = class(TROComponent, IROAsyncResponseStorage) private protected function GetResp(Index: Integer): TROResponseItem;virtual;abstract; public procedure DeleteResp(Index: Integer);virtual;abstract; procedure AddResp(aResp: TROResponseItem);virtual;abstract; procedure RemoveResp(aResp: TROResponseItem);virtual;abstract; procedure RemoveRespByUID(aUID: String);virtual;abstract; function GetRespByUID(aUID: String): TROResponseItem;virtual; function IndexOfResp(aResp: TROResponseItem): Integer;virtual;abstract; function CountOfResp: Integer;virtual; procedure ClearStorage;virtual; property ResponseItem[Index: Integer]: TROResponseItem read GetResp; end; { TROSimpleAsyncResponseStorage } TROSimpleAsyncResponseStorage = class(TROAsyncResponseStorage, IROAsyncResponseStorage) private FStorage: TThreadList; protected function GetResp(Index: Integer): TROResponseItem;override; public procedure DeleteResp(Index: Integer);override; procedure AddResp(aResp: TROResponseItem);override; procedure RemoveResp(aResp: TROResponseItem);override; procedure RemoveRespByUID(aUID: String);override; function IndexOfResp(aResp: TROResponseItem): Integer;override; function CountOfResp: Integer;override; procedure ClearStorage;override; constructor Create(AOwner: TComponent);override; Destructor Destroy;override; end; EROResponseItem = class(EROException); { TROResponseItem } TROResponseItem = class private FUID: String; FResponse: TStream; FPort: Integer; FIP: String; procedure SetIP(const Value: String); procedure SetPort(const Value: Integer); public property UID: String read FUID; property IP: String read FIP write SetIP; property Port: Integer read FPort write SetPort; property Response: TStream read FResponse; constructor Create(aResponse: TStream;aUID: String); Destructor Destroy;override; end; implementation { TROResponseItem } constructor TROResponseItem.Create(aResponse: TStream; aUID: String); begin if (not(Assigned(aResponse))) or (aUID = '') then raise EROResponseItem.Create('Invalid constructor parameter value''s'); FResponse := aResponse; FUID := aUID; end; destructor TROResponseItem.Destroy; begin FResponse.Free; inherited; end; procedure TROResponseItem.SetIP(const Value: String); begin FIP := Value; end; procedure TROResponseItem.SetPort(const Value: Integer); begin FPort := Value; end; { TROAsyncResponseStorage } procedure TROAsyncResponseStorage.ClearStorage; var i: Integer; begin for i := 0 to CountOfResp-1 do DeleteResp(0); end; function TROAsyncResponseStorage.CountOfResp: Integer; begin result := 0; end; function TROAsyncResponseStorage.GetRespByUID(aUID: String): TROResponseItem; var i: Integer; begin result := nil; if aUID = '' then Exit; for i := 0 to CountOfResp-1 do begin if ResponseItem[i].UID = aUID then begin result := ResponseItem[i]; Break; end; end; end; { TROSimpleAsyncResponseStorage } constructor TROSimpleAsyncResponseStorage.Create(AOwner: TComponent); begin inherited; FStorage := TThreadList.Create; end; destructor TROSimpleAsyncResponseStorage.Destroy; begin ClearStorage; FStorage.Free; inherited; end; procedure TROSimpleAsyncResponseStorage.AddResp(aResp: TROResponseItem); begin if not(Assigned(aResp)) then Exit; FStorage.Add(aResp); end; procedure TROSimpleAsyncResponseStorage.ClearStorage; begin Inherited; try with FStorage.LockList do begin Clear; end; finally FStorage.UnlockList; end; end; function TROSimpleAsyncResponseStorage.CountOfResp: Integer; begin try with FStorage.LockList do begin result := Count; end; finally FStorage.UnlockList; end; end; function TROSimpleAsyncResponseStorage.GetResp(Index: Integer): TROResponseItem; begin try with FStorage.LockList do begin // TList will throw an exception when out of bounds result := TROResponseItem(Items[Index]); end; finally FStorage.UnlockList; end; end; function TROSimpleAsyncResponseStorage.IndexOfResp(aResp: TROResponseItem): Integer; var i: Integer; begin result := -1; if not(Assigned(aResp)) then Exit; try with FStorage.LockList do begin for i := 0 to Count-1 do begin if TROResponseItem(Items[i]) = aResp then begin result := i; Break; end; end; end; finally FStorage.UnlockList; end; end; procedure TROSimpleAsyncResponseStorage.RemoveResp(aResp: TROResponseItem); var lIdx: Integer; begin if not(Assigned(aResp)) then Exit; lIdx := IndexOfResp(aResp); if lIdx <> -1 then DeleteResp(lIdx); end; procedure TROSimpleAsyncResponseStorage.RemoveRespByUID(aUID: String); var i: Integer; begin if aUID = '' then Exit; try with FStorage.LockList do begin for i := 0 to Count-1 do begin if TROResponseItem(Items[i]).UID = aUID then begin DeleteResp(i); Break; end; end; end; finally FStorage.UnlockList; end; end; procedure TROSimpleAsyncResponseStorage.DeleteResp(Index: Integer); begin try with FStorage.LockList do begin // TList will throw an exception when out of bounds TROResponseItem(Items[Index]).Free; Delete(Index); end; finally FStorage.UnlockList; end; end; end.