⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adpacket.pas

📁 Async Professional 4.04
💻 PAS
📖 第 1 页 / 共 3 页
字号:
                      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 + -