📄 adpacket.pas
字号:
or (IgnoreCase
and (UpCase(Manager.DataBuffer[EndMatchStart + EndMatchPos])
= InternalEndString[EndMatchPos])) then
inc(EndMatchPos)
else
Match := False;
if Match and (EndMatchPos > length(InternalEndString)) then begin
fDataSize := (EndMatchStart + EndMatchPos) - BeginMatch {+1};{!!.02}
Packet(ecString);
exit;
end;
until not Match
or (EndMatchPos > length(InternalEndString))
or ((EndMatchStart + EndMatchPos) > Manager.BufferPtr - 1);
if Match then begin
inc(EndMatchPos);
break;
end
end;
if not Match then begin
EndMatchPos := 1;
EndMatchStart := -1;
end;
end else begin
EndMatchPos := 1;
EndMatchStart := -1;
end;
end;
end;
end;
if Manager.DataBuffer = nil then
break;
inc(I);
end;
end;
end;
procedure TApdDataPacket.Loaded;
begin
inherited Loaded;
if assigned(fManager) then
Manager.EnableIfPending;
if EnablePending then begin
Enable;
EnablePending := False;
end;
end;
procedure SetupWildMask(var MatchString,Mask : string);
var
i,j : Integer;
Esc : boolean;
Ch : char;
begin
Esc := False;
j := 0;
{$IFDEF HugeStr}
SetLength(Mask,length(MatchString));
{$ELSE}
Mask[0] := Chr(Length(MatchString));
{$ENDIF}
for i := 1 to length(MatchString) do
if Esc then begin
inc(j);
MatchString[j] := MatchString[i];
Mask[j] := '0';
Esc := False;
end else if MatchString[i] = EscapeCharacter then
Esc := True
else begin
Ch := MatchString[i];
inc(j);
MatchString[j] := Ch;
if Ch = WildCardCharacter then
Mask[j] := '1'
else
Mask[j] := '0';
end;
{$IFDEF HugeStr}
SetLength(MatchString,j);
SetLength(Mask,j);
{$ELSE}
MatchString[0] := Chr(j);
Mask[0] := Chr(j);
{$ENDIF}
end;
procedure TApdDataPacket.LogPacketEvent(Event : TDispatchSubType; Data :
Pointer; DataSize : Integer);
var
NameStr : string;
begin
NameStr := 'Packet:'+Name;
if Assigned(fManager.ComPort.Dispatcher) then {!!.02}
if fManager.ComPort.Dispatcher.Logging then begin
if (Data <> nil) and (DataSize <> 0) then
fManager.ComPort.Dispatcher.AddDispatchEntry(
dtPacket,Event,0,Data,DataSize)
else
fManager.ComPort.Dispatcher.AddDispatchEntry(
dtPacket,Event,0,@NameStr[1],length(NameStr));
end;
end;
procedure TApdDataPacket.Enable;
begin
if (csDesigning in ComponentState) then
exit;
if csLoading in ComponentState then begin
EnablePending := True;
exit;
end;
if assigned(fManager) and Manager.Enabled then begin
if fManager.InEvent then begin
EnablePending := True;
exit;
end;
LogPacketEvent(dstEnable,nil,0);
if (FEnableTimer = 0) and (FEnableTimeout > 0) then begin {!!.04}
{ add the enable timer }
fComPort.Dispatcher.RegisterEventTriggerHandler(TriggerHandler); {!!.04}
FEnableTimer := fComPort.AddTimerTrigger; {!!.04}
fComPort.SetTimerTrigger(FEnableTimer,FEnableTimeout,True); {!!.04}
end; {!!.04}
if (StartCond = scString) then begin
LogPacketEvent(dstStartStr,@FStartString[1],length(StartString));
if (StartString = '') then
raise EInvalidProperty.Create(ecStartStringEmpty, False);
if (ecPacketSize in EndCond) and (PacketSize < length(StartString)) then
raise EInvalidProperty.Create(ecPacketTooSmall, False);
if not IncludeStrings then
inc(LocalPacketSize,length(StartString));
Mode := dpWaitStart;
if IgnoreCase then
InternalStartString := UpperCase(StartString)
else
InternalStartString := StartString;
SetupWildMask(InternalStartString,WildStartString);
end else
if (EndCond = []) then
raise EInvalidProperty.Create(ecNoEndCharCount, False)
else
if Manager.fCapture = nil then
Mode := dpCollecting
else
WillCollect := True;
if (ecString in EndCond) then begin
if (EndString = '') then
raise EInvalidProperty.Create(ecEmptyEndString, False);
LogPacketEvent(dstEndStr,@FEndString[1],length(EndString));
if not IncludeStrings then
inc(LocalPacketSize,length(EndString));
if IgnoreCase then
InternalEndString := UpperCase(EndString)
else
InternalEndString := EndString;
SetupWildMask(InternalEndString,WildEndString);
end;
if (ecPacketSize in EndCond) and (PacketSize = 0) then
raise EInvalidProperty.Create(ecZeroSizePacket, False);
end;
LocalPacketSize := PacketSize;
StartMatchPos := 1;
fBeginMatch := -1;
EndMatchPos := 1;
end;
procedure TApdDataPacket.Disable;
begin
if not EnablePending and not WillCollect and (Mode = dpIdle) then
exit;
EnablePending := False;
WillCollect := False;
if FEnableTimer > 0 then begin {!!.04}
{ remove our enable timer and callback }
if Assigned(fComPort) and Assigned(fComPort.Dispatcher) then begin {!!.04}
fComPort.Dispatcher.RemoveTrigger(FEnableTimer); {!!.04}
fComPort.Dispatcher.DeregisterEventTriggerHandler(TriggerHandler); {!!.04}
end;
FEnableTimer := 0; {!!.04}
end; {!!.04}
if assigned(fManager) then begin
Mode := dpIdle;
LogPacketEvent(dstDisable, nil, 0);
end;
end;
procedure TApdDataPacket.NotifyRemove(Data : Integer);
begin
if Enabled and (BeginMatch <> -1) then
if BeginMatch < Data then
Enable
else
if BeginMatch <> -1 then
Resync;
end;
procedure TApdDataPacket.CancelMatch;
begin
if Enabled and assigned(fComPort) then begin
Disable;
Enable;
end;
end;
procedure TApdDataPacket.DoPacket;
var
S : string;
begin
try
if Assigned(fOnPacket) then
fOnPacket(Self,Packetbuffer,fDataSize);
if Assigned(fOnStringPacket) then begin
{$IFOPT H-}
if fDataSize > 255 then
raise EStringSizeError.Create(ecPacketTooLong, False);
{$ENDIF}
SetLength(S, fDataSize);
Move(PacketBuffer^, S[1], fDataSize);
fOnStringPacket(Self,S);
end;
except
Application.HandleException(Self);
end;
end;
procedure TApdDataPacket.Packet(Reason : TPacketEndCond);
var
LocalSize : Integer;
begin
fManager.InEvent := True;
try
Enabled := False;
LocalSize := fDataSize;
if (StartCond = scString) and not IncludeStrings then begin
PacketBuffer := pChar(@Manager.DataBuffer[BeginMatch+length(InternalStartString)]);
dec(fDataSize,length(InternalStartString));
end else
PacketBuffer := pChar(@Manager.DataBuffer[BeginMatch]);
if not IncludeStrings and (Reason = ecString) then
dec(fDataSize,length(InternalEndString));
LogPacketEvent(dstStringPacket,nil,0);
case Reason of
ecString :
LogPacketEvent(dstStringPacket,PacketBuffer,fDataSize);
else
LogPacketEvent(dstSizePacket,PacketBuffer,fDataSize);
end;
FDataMatch := True; {!!.02}
if SyncEvents and assigned(ComPort.Dispatcher.DispThread) then
ComPort.Dispatcher.DispThread.Sync(DoPacket)
else
DoPacket;
Manager.RemoveData(BeginMatch,LocalSize);
if AutoEnable then
Enabled := True;
finally
fManager.InEvent := False;
end;
end;
procedure TApdDataPacket.DoTimeout;
begin
try
if Assigned(fOnTimeout) then
fOnTimeout(Self);
except
Application.HandleException(Self);
end;
end;
procedure TApdDataPacket.TimedOut;
begin
fManager.InEvent := True;
try
LogPacketEvent(dstPacketTimeout,nil,0);
Enabled := False;
FTimedOut := True; {!!.02}
PacketBuffer := PChar (@Manager.DataBuffer[BeginMatch + {!!.04}
Length (InternalStartString)]); {!!.04}
fDataSize := Manager.BufferPtr - BeginMatch; {!!.04}
if SyncEvents and assigned(ComPort.Dispatcher.DispThread) then
ComPort.Dispatcher.DispThread.Sync(DoTimeout)
else
DoTimeout;
if FFlushOnTimeout then {!!.04}
Manager.RemoveData (BeginMatch, Manager.BufferPtr - BeginMatch);
finally
fManager.InEvent := False;
end;
end;
procedure Finalize;
begin
PacketManagerList.Free;
end;
procedure TApdDataPacket.SetEndString(Value: String);
var
OldEnabled : Boolean;
begin
OldEnabled := Enabled;
Enabled := False;
FEndString := Value;
Enabled := OldEnabled;
end;
procedure TApdDataPacket.SetEndCond(const Value: TPacketEndSet);
var
OldEnabled : Boolean;
begin
OldEnabled := Enabled;
Enabled := False;
fEndCond := Value;
Enabled := OldEnabled;
end;
procedure TApdDataPacket.SetFlushOnTimeout (const v : Boolean); {!!.04}
begin {!!.04}
if v <> FFlushOnTimeout then {!!.04}
FFlushOnTimeout := v; {!!.04}
end; {!!.04}
procedure TApdDataPacket.GetCollectedString(var Data: String);
{- Returns data collected in OnStringPacket format}
var
SLength : Integer;
begin
SLength := fDataSize;
{$IFOPT H-}
if SLength > 255 then
SLength := 255;
{$ENDIF}
SetLength(Data, SLength);
Move(PacketBuffer^, Data[1], SLength);
end;
procedure TApdDataPacket.GetCollectedData(var Data: Pointer;
var Size: Integer);
{- Returns data collected in OnPacket format}
begin
Data := PacketBuffer;
Size := fDataSize;
end;
function TApdDataPacket.WaitForString(var Data : string) : Boolean; {!!.01}
{ waits for the data match or timeout }
var
Res : LongInt;
begin
AutoEnable := False;
Enabled := True;
repeat
Res := SafeYield;
until (Res = WM_QUIT) or FTimedOut or FDataMatch;
Result := FDataMatch;
if Result then begin
Res := fDataSize;
{$IFOPT H-}
if Res > 255 then
Res := 255;
{$ENDIF}
SetLength(Data, Res);
Move(PacketBuffer^, Data[1], Res);
end;
end;
function TApdDataPacket.WaitForPacket(var Data: Pointer; {!!.01}
var Size: Integer): Boolean;
{ Data and Size are returned and valid if Result is True }
var
Res : LongInt;
begin
AutoEnable := False;
Enabled := True;
repeat
Res := SafeYield;
until (Res = WM_QUIT) or FTimedOut or FDataMatch;
Result := FDataMatch;
if Result then begin
Size := fDataSize;
Data := PacketBuffer;
end;
end;
procedure TApdDataPacket.TriggerHandler(Msg, wParam: Cardinal; {!!.04}
lParam: Integer); {!!.04}
{- process messages from dispatcher, only used for the EnableTimeout} {!!.04}
begin {!!.04}
if (Msg = apw_TriggerTimer) and (Integer(wParam) = FEnableTimer) {!!.04}
and (Mode <> dpIdle) then begin {!!.04}
TimedOut; {!!.04}
end; {!!.04}
end; {!!.04}
initialization
PacketManagerList := TApdDataPacketManagerList.Create;
finalization
Finalize;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -