| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- {
- $Project$
- $Workfile$
- $Revision$
- $DateUTC$
- $Id$
- This file is part of the Indy (Internet Direct) project, and is offered
- under the dual-licensing agreement described on the Indy website.
- (http://www.indyproject.org/)
- Copyright:
- (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
- }
- {
- $Log$
- }
- {
- Rev 1.10 3/10/2005 12:00:46 AM JPMugaas
- Minor problem Craig Peterson had noted in an E-Mail to me.
- Rev 1.9 11/30/04 6:19:12 PM RLebeau
- Promoted the TIdConnectionIntercept.Intercept property from protected to
- published
- Rev 1.8 2004.02.03 4:16:44 PM czhower
- For unit name changes.
- Rev 1.7 2004.01.20 10:03:24 PM czhower
- InitComponent
- Rev 1.6 5/12/2003 12:33:32 AM GGrieve
- add Data from BlockCipher descendent
- Rev 1.5 2003.10.14 1:26:48 PM czhower
- Uupdates + Intercept support
- Rev 1.4 2003.10.11 5:48:16 PM czhower
- -VCL fixes for servers
- -Chain suport for servers (Super core)
- -Scheduler upgrades
- -Full yarn support
- Rev 1.3 10/5/2003 3:20:46 PM BGooijen
- .net
- Rev 1.2 2003.10.01 1:12:34 AM czhower
- .Net
- Rev 1.1 3/5/2003 10:59:48 PM BGooijen
- Fixed (i know, the SendBuffer looks bad)
- Rev 1.0 11/13/2002 08:44:42 AM JPMugaas
- 2002-03-01 - Andrew P.Rybin
- - Nested Intercept support (ex: ->logging->compression->encryption)
- 2002-04-09 - Chuck Smith
- - set ABuffer.Position := 0; in OnSend/OnReceive for Nested Stream send/receive
- }
- unit IdIntercept;
- interface
- {$I IdCompilerDefines.inc}
- //here only to put FPC in Delphi mode
- uses
- Classes,
- IdGlobal, IdBaseComponent, IdException;
- type
- EIdInterceptCircularLink = class(EIdException);
- TIdConnectionIntercept = class;
- TIdInterceptNotifyEvent = procedure(ASender: TIdConnectionIntercept) of object;
- TIdInterceptStreamEvent = procedure(ASender: TIdConnectionIntercept; var ABuffer: TIdBytes) of object;
- TIdConnectionIntercept = class(TIdBaseComponent)
- protected
- FConnection: TComponent;
- {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FIntercept: TIdConnectionIntercept;
- FIsClient: Boolean;
- {$IFDEF USE_OBJECT_ARC}
- // When ARC is enabled, object references MUST be valid objects.
- // It is common for users to store non-object values, though, so
- // we will provide separate properties for those purposes
- //
- // TODO; use TValue instead of separating them
- //
- FDataObject: TObject;
- FDataValue: PtrInt;
- {$ELSE}
- FData: TObject;
- {$ENDIF}
- FOnConnect: TIdInterceptNotifyEvent;
- FOnDisconnect: TIdInterceptNotifyEvent;
- FOnReceive: TIdInterceptStreamEvent;
- FOnSend: TIdInterceptStreamEvent;
- //
- procedure InitComponent; override;
- {$IFNDEF USE_OBJECT_ARC}
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- {$ENDIF}
- procedure SetIntercept(AValue: TIdConnectionIntercept);
- //
- public
- procedure Connect(AConnection: TComponent); virtual;
- procedure Disconnect; virtual;
- procedure Receive(var VBuffer: TIdBytes); virtual;
- procedure Send(var VBuffer: TIdBytes); virtual;
- //
- property Connection: TComponent read FConnection;
- property IsClient: Boolean read FIsClient;
- // user can use this to keep context
- {$IFDEF USE_OBJECT_ARC}
- property DataObject: TObject read FDataObject write FDataObject;
- property DataValue: PtrInt read FDataValue write FDataValue;
- {$ELSE}
- property Data: TObject read FData write FData;
- {$ENDIF}
- published
- property Intercept: TIdConnectionIntercept read FIntercept write SetIntercept;
- property OnConnect: TIdInterceptNotifyEvent read FOnConnect write FOnConnect;
- property OnDisconnect: TIdInterceptNotifyEvent read FOnDisconnect write FOnDisconnect;
- property OnReceive: TIdInterceptStreamEvent read FOnReceive write FOnReceive;
- property OnSend: TIdInterceptStreamEvent read FOnSend write FOnSend;
- end;
- TIdServerIntercept = class(TIdBaseComponent)
- public
- procedure Init; virtual; abstract;
- function Accept(AConnection: TComponent): TIdConnectionIntercept; virtual; abstract;
- end;
- implementation
- uses
- IdResourceStringsCore;
- { TIdIntercept }
- procedure TIdConnectionIntercept.Disconnect;
- var
- // under ARC, convert a weak reference to a strong reference before working with it
- LIntercept: TIdConnectionIntercept;
- begin
- LIntercept := Intercept;
- if LIntercept <> nil then begin
- LIntercept.Disconnect;
- end;
- if Assigned(OnDisconnect) then begin
- OnDisconnect(Self);
- end;
- FConnection := nil;
- end;
- procedure TIdConnectionIntercept.Connect(AConnection: TComponent);
- var
- // under ARC, convert a weak reference to a strong reference before working with it
- LIntercept: TIdConnectionIntercept;
- begin
- FConnection := AConnection;
- if Assigned(OnConnect) then begin
- OnConnect(Self);
- end;
- LIntercept := Intercept;
- if LIntercept <> nil then begin
- LIntercept.Connect(AConnection);
- end;
- end;
- procedure TIdConnectionIntercept.Receive(var VBuffer: TIdBytes);
- var
- // under ARC, convert a weak reference to a strong reference before working with it
- LIntercept: TIdConnectionIntercept;
- begin
- LIntercept := Intercept;
- if LIntercept <> nil then begin
- LIntercept.Receive(VBuffer);
- end;
- if Assigned(OnReceive) then begin
- OnReceive(Self, VBuffer);
- end;
- end;
- procedure TIdConnectionIntercept.Send(var VBuffer: TIdBytes);
- var
- // under ARC, convert a weak reference to a strong reference before working with it
- LIntercept: TIdConnectionIntercept;
- begin
- if Assigned(OnSend) then begin
- OnSend(Self, VBuffer);
- end;
- LIntercept := Intercept;
- if LIntercept <> nil then begin
- LIntercept.Send(VBuffer);
- end;
- end;
- procedure TIdConnectionIntercept.SetIntercept(AValue: TIdConnectionIntercept);
- var
- // under ARC, convert a weak reference to a strong reference before working with it
- LIntercept: TIdConnectionIntercept;
- LNextValue: TIdConnectionIntercept;
- begin
- LIntercept := FIntercept;
- if LIntercept <> AValue then
- begin
- LNextValue := AValue;
- while Assigned(LNextValue) do begin
- if LNextValue = Self then begin //recursion
- raise EIdInterceptCircularLink.CreateFmt(RSInterceptCircularLink, [ClassName]);
- end;
- LNextValue := LNextValue.Intercept;
- end;
- // under ARC, all weak references to a freed object get nil'ed automatically
- {$IFNDEF USE_OBJECT_ARC}
- // remove self from the Intercept's free notification list {Do not Localize}
- if Assigned(LIntercept) then begin
- LIntercept.RemoveFreeNotification(Self);
- end;
- {$ENDIF}
- FIntercept := AValue;
- {$IFNDEF USE_OBJECT_ARC}
- // add self to the Intercept's free notification list {Do not Localize}
- if Assigned(AValue) then begin
- AValue.FreeNotification(Self);
- end;
- {$ENDIF}
- end;
- end;
- // under ARC, all weak references to a freed object get nil'ed automatically
- {$IFNDEF USE_OBJECT_ARC}
- procedure TIdConnectionIntercept.Notification(AComponent: TComponent; Operation: TOperation);
- begin
- if (Operation = opRemove) and (AComponent = Intercept) then begin
- FIntercept := nil;
- end;
- inherited Notification(AComponent, OPeration);
- end;
- {$ENDIF}
- procedure TIdConnectionIntercept.InitComponent;
- begin
- inherited InitComponent;
- FIsClient := True;
- end;
- end.
|