![]() |
Overload einer Funktion der TIdTrivialFTP Komponente
Hi,
ich habe eine Frage zu Overload/Override. Ich habe die Funktion in der unit IdTrivialFTP:
Delphi-Quellcode:
Nun habe ich eine Hardware hier, die aber einen anderen Offset hat.
procedure TIdTrivialFTP.CheckOptionAck(const OptionPacket: TIdBytes; Reading: Boolean);
var LOptName, LOptValue: String; LOffset, Idx, OptionIdx: Integer; LRequestedBlkSize: Integer; begin LOffset := 2; // skip packet opcode try while LOffset < Length(OptionPacket) do begin Idx := ByteIndex(0, OptionPacket, LOffset); if Idx = -1 then begin raise EIdTFTPOptionNegotiationFailed.Create(''); end; LOptName := BytesToString(OptionPacket, LOffset, Idx-LOffset, IndyASCIIEncoding); LOffset := Idx+1; OptionIdx := PosInStrArray(LOptName, [sBlockSize, sTransferSize], False); if OptionIdx = -1 then begin raise EIdTFTPOptionNegotiationFailed.CreateFmt(RSTFTPUnsupportedOption, [LOptName]); end; Idx := ByteIndex(0, OptionPacket, LOffset); if Idx = -1 then begin raise EIdTFTPOptionNegotiationFailed.Create(''); end; LOptValue := BytesToString(OptionPacket, LOffset, Idx-LOffset, IndyASCIIEncoding); LOffset := Idx+1; case OptionIdx of 0: begin LRequestedBlkSize := IndyStrToInt(LOptValue); if (LRequestedBlkSize < 8) or (LRequestedBlkSize > 65464) then begin raise EIdTFTPOptionNegotiationFailed.CreateFmt(RSTFTPUnsupportedOptionValue, [LOptValue, LOptName]); end; BufferSize := 4 + LRequestedBlkSize; end; 1: begin if Reading then begin // TODO { if (IndyStrToInt(LOptValue) is not available) then begin raise raise EIdTFTPAllocationExceeded.Create(''); end; } end; end; end; end; except on E: Exception do begin SendError(Self, FPeerIP, FPeerPort, E); raise; end; end; end; So funktioniert es mit LOffset = 4:
Delphi-Quellcode:
Keine Ahnung warum da ein anderer Offset ist, aber mit 2 geht es nicht. Die Optionen starten erst ab Offset 4.
procedure TIdTrivialFTP.CheckOptionAck(const OptionPacket: TIdBytes; Reading: Boolean);
var LOptName, LOptValue: String; LOffset, Idx, OptionIdx: Integer; LRequestedBlkSize: Integer; begin LOffset := 2; // skip packet opcode LOffset := LOffset + 2; // skip packet opcode PicoMOD3 try while LOffset < Length(OptionPacket) do begin Idx := ByteIndex(0, OptionPacket, LOffset); if Idx = -1 then begin raise EIdTFTPOptionNegotiationFailed.Create(''); end; LOptName := BytesToString(OptionPacket, LOffset, Idx-LOffset, IndyASCIIEncoding); LOffset := Idx+1; OptionIdx := PosInStrArray(LOptName, [sBlockSize, sTransferSize], False); if OptionIdx = -1 then begin raise EIdTFTPOptionNegotiationFailed.CreateFmt(RSTFTPUnsupportedOption, [LOptName]); end; Idx := ByteIndex(0, OptionPacket, LOffset); if Idx = -1 then begin raise EIdTFTPOptionNegotiationFailed.Create(''); end; LOptValue := BytesToString(OptionPacket, LOffset, Idx-LOffset, IndyASCIIEncoding); LOffset := Idx+1; case OptionIdx of 0: begin LRequestedBlkSize := IndyStrToInt(LOptValue); if (LRequestedBlkSize < 8) or (LRequestedBlkSize > 65464) then begin raise EIdTFTPOptionNegotiationFailed.CreateFmt(RSTFTPUnsupportedOptionValue, [LOptValue, LOptName]); end; BufferSize := 4 + LRequestedBlkSize; end; 1: begin if Reading then begin // TODO { if (IndyStrToInt(LOptValue) is not available) then begin raise raise EIdTFTPAllocationExceeded.Create(''); end; } end; end; end; end; except on E: Exception do begin SendError(Self, FPeerIP, FPeerPort, E); raise; end; end; end; Kann ich das irgendwie in meine eigene Unit einbauen damit die IdTrivalFTP Unit unangetastet bleibt? |
AW: Overload einer Funktion der TIdTrivialFTP Komponente
Welche Sichtbarkeit hat denn die Methode? Wenn es mindestens protected ist, kannst Du Dir ja eine Ableitung schreiben und die Methode überladen.
|
AW: Overload einer Funktion der TIdTrivialFTP Komponente
Delphi-Quellcode:
Also Protected.
type
TIdTrivialFTP = class(TIdUDPClient) protected FMode: TIdTFTPMode; FRequestedBlockSize: Integer; FPeerPort: TIdPort; FPeerIP: String; function ModeToStr: string; procedure CheckOptionAck(const OptionPacket: TIdBytes; Reading: Boolean); protected procedure SendAck(const BlockNumber: Word); procedure RaiseError(const ErrorPacket: TIdBytes); procedure InitComponent; override; public procedure Get(const ServerFile: String; DestinationStream: TStream); overload; procedure Get(const ServerFile, LocalFile: String); overload; procedure Put(SourceStream: TStream; const ServerFile: String); overload; procedure Put(const LocalFile, ServerFile: String); overload; published property TransferMode: TIdTFTPMode read FMode write FMode Default GTransferMode; property RequestedBlockSize: Integer read FRequestedBlockSize write FRequestedBlockSize default 1500; property OnWork; property OnWorkBegin; property OnWorkEnd; end; Ich rufe die Put Prozedur auf. In dieser wird die CheckOptionAck aufgerufen. Wie müsste das Overload aussehen? So vielleicht
Delphi-Quellcode:
Und dann die Prozedur kopieren? Dann meldet er aber Fehler beim kompilieren. Mit dem einbinden weiterer Units bekomme ich die weg. Beim Kompilieren wird TMyIdTrivialFTP aber wegoptimiert...
type
TMyIdTrivialFTP = class(TIdTrivialFTP) protected procedure CheckOptionAck(const OptionPacket: TIdBytes; Reading: Boolean); overload; end; |
AW: Overload einer Funktion der TIdTrivialFTP Komponente
Versuch einmal:
Delphi-Quellcode:
TMyIdTrivialFTP = class(IdTrivialFTP.TIdTrivialFTP)
protected procedure CheckOptionAck(const OptionPacket: TIdBytes; Reading: Boolean); overload; procedure CheckOptionAck(const OptionPacket: TIdBytes; Reading: Boolean; AdditionalOffset: integer = 2); overload; end; ... procedure TMyIdTrivialFTP.CheckOptionAck(const OptionPacket: TIdBytes; Reading: Boolean); begin inherited; end; procedure TMyIdTrivialFTP.CheckOptionAck(const OptionPacket: TIdBytes; Reading: Boolean; AdditionalOffset: integer); var LOptName, LOptValue: String; LOffset, Idx, OptionIdx: Integer; LRequestedBlkSize: Integer; begin LOffset := 2; // skip packet opcode LOffset := LOffset + AdditionalOffset; // skip packet opcode PicoMOD3 //usw. |
AW: Overload einer Funktion der TIdTrivialFTP Komponente
Nicht ganz...
Ich rufe ja die Put(File :String,...) Prozedur auf, diese ruft die Put(Stream,...) auf und diese wieder die CheckOptionAck. Die orignalen Put von TIdTrivialFTP ruft mir natürlich auch die TIdTrivialFTP.CheckOptionAck auf und nicht meine. Ich habe nun die Put Prozeduren auch mit Overload in meine TMyIdTrivialFTP übernommen und nun wird meine CheckOptionAck Version aufgerufen. Mein IndyTFTP Client muss natürlich dann selber über TMyIdTrivialFTP erzeugt werden und nicht mehr über TIdTrivialFTP selber. |
AW: Overload einer Funktion der TIdTrivialFTP Komponente
Sicher, das hätte ich vielleicht dazu schreiben sollen. Ganz glücklich bin ich selbst mit dieser Lösung nicht, aber mir fällt kein anderer Weg ein, wie man das Problem lösen könnte, es sei denn, die Indy-Entwickler nehmen sich der Sache an. Du kannst ja einmal ganz lieb bei Assertor anfragen, ob es evtl. möglich ist, das Offset als Property zu deklarieren oder so etwas.
|
AW: Overload einer Funktion der TIdTrivialFTP Komponente
Ich bin auch nicht ganz Glücklich mit dieser Lösung. Aber zumindest kann ich jetzt Indy unangetastet lassen und bei einer Neuinstallation von Indy brauche ich nicht darauf dann keine Rücksicht mehr nehmen. Ausser natürlich die Funktionen von Indy ändern sich...
Warum der WinCE TFTP Server einen Offset von 4 statt 2 in den Optionen hat weis ich nicht. Vielleicht ist das irgendwie erkennbar und somit Automatisierbar!? |
AW: Overload einer Funktion der TIdTrivialFTP Komponente
Da es hier etwas durcheinander geht:
Overload: Es gibt zwei/mehrere Methoden, mit dem selben Namen und unterschiedlichen Parametern (Signaturen) und alle sind nutzbar. An den alten Methoden wird aber nichts verändert. Override: Eine Methode (mindestens Protected und Virtual/Dynamic) wird überschrieben/geändert. Der alte Aufruf wird also "ersetzt", mit einer Methode mit der selben Signatur (Parameter). |
AW: Overload einer Funktion der TIdTrivialFTP Komponente
Wo geht hier was durcheinander?
|
AW: Overload einer Funktion der TIdTrivialFTP Komponente
Komisch, ich dachte ich hätte "überschreiben" und overload in einem Satz gelesen. :gruebel:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:59 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz