- Recompilación en Delphi10 de todos los paquetes de RO para generar las DCU's en Lib\D10 git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.RemObjects@7 b6239004-a887-0f4b-9937-50029ccdca16
337 lines
10 KiB
ObjectPascal
337 lines
10 KiB
ObjectPascal
unit uROServerMultiMessage;
|
|
|
|
{$I RemObjects.inc}
|
|
interface
|
|
uses
|
|
{$IFDEF REMOBJECTS_TRIAL}uROTrial, {$ENDIF}
|
|
SysUtils, Classes, TypInfo,
|
|
uROClientIntf, uROSerializer, uROClient;
|
|
|
|
type
|
|
TROServerMultiMessage = class;
|
|
TROServerMultiMessageCollectionItem = class(TCollectionItem)
|
|
private
|
|
FMessage: TROMessage;
|
|
procedure SetMessage(const Value: TROMessage);
|
|
protected
|
|
function GetDisplayName: string; override;
|
|
public
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property Message: TROMessage read FMessage write SetMessage;
|
|
end;
|
|
|
|
TROServerMultiMessageCollection = class(TCollection)
|
|
private
|
|
FOwner: TROServerMultiMessage;
|
|
function GetItems(Index: integer): TROServerMultiMessageCollectionItem;
|
|
public
|
|
constructor Create(aOwner: TROServerMultiMessage);
|
|
function FindItemByMessage(AMessage: TROMessage): TROServerMultiMessageCollectionItem;
|
|
property Items[Index: integer]: TROServerMultiMessageCollectionItem read GetItems; default;
|
|
end;
|
|
|
|
TROServerMultiMessage = class(TROMessage)
|
|
private
|
|
FSupportedMessages: TROServerMultiMessageCollection;
|
|
FDefaultMessage: TROMessage;
|
|
procedure DetectMessageFromStream(aStream: TStream);
|
|
procedure SetSupportedMessages(const Value: TROServerMultiMessageCollection);
|
|
function InternalIsValidMessage(aData: PChar; aLength: Integer): integer;
|
|
protected
|
|
function DefaultMessage: IROMessage;
|
|
function QueryInterface(const IID: TGUID; out Obj): HResult; override; stdcall;
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
{ Internals }
|
|
function ReadException: Exception; override;
|
|
procedure InitObject; override;
|
|
|
|
function CreateSerializer: TROSerializer; override;
|
|
|
|
{ IROMessage }
|
|
procedure Initialize(const aTransport: IROTransport; const anInterfaceName, aMessageName: string; aType: TMessageType); override;
|
|
procedure Initialize(const aTransport: IROTransport; const aLibraryName, anInterfaceName, aMessageName: string; aType: TMessageType); override;
|
|
procedure Finalize; override;
|
|
|
|
{$IFDEF DOTNET}
|
|
{$ELSE}
|
|
procedure Write(const aName: string; aTypeInfo: PTypeInfo; const Ptr; Attributes: TParamAttributes); override;
|
|
procedure Read(const aName: string; aTypeInfo: PTypeInfo; var Ptr; Attributes: TParamAttributes); override;
|
|
{$ENDIF}
|
|
|
|
procedure WriteToStream(aStream: TStream); override;
|
|
procedure ReadFromStream(aStream: TStream); override;
|
|
procedure ReadFromStream(aStream: TStream; var aFreeStream: Boolean); override;
|
|
function GetMessageType: TMessageType; override;
|
|
procedure WriteException(aStream: TStream; anException: Exception); override;
|
|
procedure FreeStream; override;
|
|
public
|
|
destructor Destroy; override;
|
|
procedure Assign(iSource: TPersistent); override;
|
|
procedure CheckProperties; override;
|
|
function IsValidMessage(aData: PChar; aLength: Integer): boolean; override;
|
|
published
|
|
property SupportedMessages: TROServerMultiMessageCollection read FSupportedMessages write SetSupportedMessages;
|
|
end;
|
|
|
|
implementation
|
|
uses
|
|
uROClasses, uRORes;
|
|
|
|
{ TROServerMultiMessage }
|
|
|
|
procedure TROServerMultiMessage.Assign(iSource: TPersistent);
|
|
begin
|
|
inherited;
|
|
if Assigned(iSource) then begin
|
|
if not (iSource is TROServerMultiMessage) then RaiseError('Cannot Assign a %s t a %s', [ClassName, iSource.ClassName]);
|
|
self.SupportedMessages := (iSource as TROServerMultiMessage).SupportedMessages;
|
|
end;
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.CheckProperties;
|
|
begin
|
|
Check(FDefaultMessage = nil, Name + '. Can not detect default message'); //???
|
|
FDefaultMessage.CheckProperties;
|
|
inherited;
|
|
end;
|
|
|
|
function TROServerMultiMessage.CreateSerializer: TROSerializer;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TROServerMultiMessage.DefaultMessage: IROMessage;
|
|
begin
|
|
CheckProperties;
|
|
Result := FDefaultMessage;
|
|
end;
|
|
|
|
destructor TROServerMultiMessage.Destroy;
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.DetectMessageFromStream(aStream: TStream);
|
|
const
|
|
BufSize = 100;
|
|
var
|
|
i: integer;
|
|
buf: Pchar;
|
|
currentBufSize: int64;
|
|
begin
|
|
FDefaultMessage := nil;
|
|
aStream.Position := 0;
|
|
|
|
if aStream.Size > bufsize then
|
|
currentBufSize := BufSize
|
|
else
|
|
currentBufSize := aStream.Size;
|
|
|
|
GetMem(buf, currentBufSize);
|
|
try
|
|
aStream.Read(buf^, currentBufSize);
|
|
if copy(Buf,1,6) = 'rorock' then RaiseInvalidStreamError(err_InvalidHeaderEncrypted, [], aStream);
|
|
i := InternalIsValidMessage(buf, currentBufSize);
|
|
if i <> -1 then FDefaultMessage := FSupportedMessages[i].Message;
|
|
Check(FDefaultMessage = nil, Name + '. Can not find the valid Message for stream.' + sLineBreak + string(buf));
|
|
finally
|
|
aStream.Position := 0;
|
|
FreeMem(buf);
|
|
end;
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.Finalize;
|
|
begin
|
|
DefaultMessage.Finalize;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.FreeStream;
|
|
begin
|
|
DefaultMessage.FreeStream;
|
|
inherited;
|
|
end;
|
|
|
|
function TROServerMultiMessage.GetMessageType: TMessageType;
|
|
begin
|
|
Result := DefaultMessage.MessageType;
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.Initialize(const aTransport: IROTransport;
|
|
const anInterfaceName, aMessageName: string; aType: TMessageType);
|
|
begin
|
|
inherited Initialize(aTransport, anInterfaceName, aMessageName, aType);
|
|
DefaultMessage.Initialize(aTransport, anInterfaceName, aMessageName, aType);
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.Initialize(const aTransport: IROTransport;
|
|
const aLibraryName, anInterfaceName, aMessageName: string;
|
|
aType: TMessageType);
|
|
begin
|
|
inherited Initialize(aTransport, anInterfaceName, aMessageName, aType);
|
|
DefaultMessage.Initialize(aTransport, aLibraryName, anInterfaceName, aMessageName, aType);
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.InitObject;
|
|
begin
|
|
inherited;
|
|
FSupportedMessages := TROServerMultiMessageCollection.Create(Self);
|
|
end;
|
|
|
|
function TROServerMultiMessage.InternalIsValidMessage(aData: PChar;
|
|
aLength: Integer): integer;
|
|
begin
|
|
for Result := 0 to FSupportedMessages.Count - 1 do
|
|
with FSupportedMessages[Result] do
|
|
if (Message <> nil) and Message.IsValidMessage(aData, aLength) then Exit;
|
|
Result := -1;
|
|
end;
|
|
|
|
function TROServerMultiMessage.IsValidMessage(aData: PChar;
|
|
aLength: Integer): boolean;
|
|
begin
|
|
Result := InternalisValidMessage(aData, aLength) <> -1;
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.Notification(AComponent: TComponent;
|
|
Operation: TOperation);
|
|
var
|
|
item: TROServerMultiMessageCollectionItem;
|
|
begin
|
|
inherited;
|
|
if (Operation = opRemove) then begin
|
|
if (AComponent is TROMessage) and (FSupportedMessages.Count > 0) then begin
|
|
Item := FSupportedMessages.FindItemByMessage(AComponent as TROMessage);
|
|
if Item <> nil then Item.Message := nil;
|
|
end;
|
|
end
|
|
end;
|
|
|
|
function TROServerMultiMessage.QueryInterface(const IID: TGUID;
|
|
out Obj): HResult;
|
|
begin
|
|
Result := inherited QueryInterface(IID, Obj);
|
|
if Result = E_NOINTERFACE then
|
|
if FDefaultMessage <> nil then
|
|
Result := DefaultMessage.QueryInterface(IID, Obj);
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.Read(const aName: string;
|
|
aTypeInfo: PTypeInfo; var Ptr; Attributes: TParamAttributes);
|
|
begin
|
|
DefaultMessage.Read(aName, aTypeInfo, Ptr, Attributes);
|
|
if Assigned(OnReadMessageParameter) then OnReadMessageParameter(Self, aName, aTypeInfo, pointer(Ptr), Attributes);
|
|
end;
|
|
|
|
function TROServerMultiMessage.ReadException: Exception;
|
|
begin
|
|
// not called from ROServerMultiMessage
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.ReadFromStream(aStream: TStream);
|
|
begin
|
|
inherited;
|
|
DetectMessageFromStream(aStream);
|
|
DefaultMessage.ReadFromStream(aStream);
|
|
InterfaceName := DefaultMessage.InterfaceName;
|
|
MessageName := DefaultMessage.MessageName;
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.ReadFromStream(aStream: TStream;
|
|
var aFreeStream: Boolean);
|
|
begin
|
|
inherited;
|
|
DetectMessageFromStream(aStream);
|
|
DefaultMessage.ReadFromStream(aStream, aFreeStream);
|
|
InterfaceName := DefaultMessage.InterfaceName;
|
|
MessageName := DefaultMessage.MessageName;
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.SetSupportedMessages(
|
|
const Value: TROServerMultiMessageCollection);
|
|
begin
|
|
FSupportedMessages.Assign(Value);
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.Write(const aName: string;
|
|
aTypeInfo: PTypeInfo; const Ptr; Attributes: TParamAttributes);
|
|
begin
|
|
if Assigned(OnWriteMessageParameter) then OnWriteMessageParameter(Self, aName, aTypeInfo, pointer(Ptr), Attributes);
|
|
DefaultMessage.Write(aName, aTypeInfo, Ptr, Attributes);
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.WriteException(aStream: TStream;
|
|
anException: Exception);
|
|
begin
|
|
DefaultMessage.WriteException(aStream, anException);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TROServerMultiMessage.WriteToStream(aStream: TStream);
|
|
begin
|
|
DefaultMessage.WriteToStream(aStream);
|
|
inherited;
|
|
end;
|
|
|
|
{ TROServerMultiMessageCollectionItem }
|
|
|
|
procedure TROServerMultiMessageCollectionItem.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TROServerMultiMessageCollectionItem then begin
|
|
Message := TROServerMultiMessageCollectionItem(Source).Message;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TROServerMultiMessageCollectionItem.GetDisplayName: string;
|
|
begin
|
|
if FMessage <> nil then
|
|
Result := FMessage.Name + ' (' + FMessage.ClassName + ')'
|
|
else
|
|
Result := '[Unassigned]';
|
|
end;
|
|
|
|
procedure TROServerMultiMessageCollectionItem.SetMessage(
|
|
const Value: TROMessage);
|
|
begin
|
|
if (FMessage <> Value) then begin
|
|
if Value <> nil then Check(Value is TROServerMultiMessage, Value.Name + ' can not be used here.');
|
|
FMessage := Value;
|
|
if (FMessage <> nil) then FMessage.FreeNotification(TROServerMultiMessageCollection(inherited Collection).FOwner);
|
|
end;
|
|
end;
|
|
|
|
{ TROServerMultiMessageCollection }
|
|
|
|
constructor TROServerMultiMessageCollection.Create(
|
|
aOwner: TROServerMultiMessage);
|
|
begin
|
|
inherited Create(TROServerMultiMessageCollectionItem);
|
|
FOwner := aOwner;
|
|
end;
|
|
|
|
function TROServerMultiMessageCollection.FindItemByMessage(
|
|
AMessage: TROMessage): TROServerMultiMessageCollectionItem;
|
|
var
|
|
i: integer;
|
|
begin
|
|
Result := nil;
|
|
for i := 0 to Count - 1 do
|
|
if Items[i].Message = AMessage then begin
|
|
Result := Items[i];
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
function TROServerMultiMessageCollection.GetItems(
|
|
Index: integer): TROServerMultiMessageCollectionItem;
|
|
begin
|
|
Result := TROServerMultiMessageCollectionItem(inherited Items[Index]);
|
|
end;
|
|
|
|
end.
|
|
|