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

📄 awascii.pas

📁 测试用例
💻 PAS
📖 第 1 页 / 共 3 页
字号:
                    sAsciiState := taFinishDrain;
                    Dispatcher.SetTimerTrigger(aTimeoutTrigger, aTransTimeout, True);
                    Dispatcher.SetStatusTrigger(aOutBuffUsedTrigger, 0, True);
                  end else
                    sAsciiState := taGetBlock;

                  {Update timer and force status}
                  aElapsedTicks := ElapsedTime(aTimer);
                  aForceStatus := True;
                end;

              taSendDelay :
                if Integer(TriggerID) = aTimeoutTrigger then
                  sAsciiState := taSendBlock;

              taFinishDrain :
                if Integer(TriggerID) = aOutBuffUsedTrigger then begin
                  sAsciiState := taFinished;
                  aProtocolStatus := psEndFile;
                end else if Integer(TriggerID) = aTimeoutTrigger then begin
                  apProtocolError(P, ecTimeout);
                  sAsciiState := taFinished;
                end;

              taFinished :
                begin
                  if aProtocolError <> ecOK then
                    Dispatcher.FlushInBuffer;

                  {Close the file}
                  apFinishReading(P);

                  {Show status, user logging, and clean up}
                  if aProtocolError = ecOK then
                    apLogFile(P, lfTransmitOk)
                  else
                    apLogFile(P, lfTransmitFail);
                  apShowLastStatus(P);

                  {Tell parent we're finished}
                  apSignalFinish(P);
                  sAsciiState := taDone;
                end;
            end;

            {Should we exit or not}                   
            case sAsciiState of
              {Stay in state machine}
              taGetBlock,
              taSendBlock,
              taFinished : Finished := False;

              {Exit state machine to wait for trigger}
              taFinishDrain,
              taWaitFreeSpace,
              taSendDelay,
              taDone : Finished := True;
              else     Finished := False;
            end;
          except                                                       {!!.01}
            on EAccessViolation do begin                               {!!.01}
              Finished := True;                                        {!!.01}
              aProtocolError := ecAbortNoCarrier;                      {!!.01}
              apSignalFinish(P);                                       {!!.01}
            end;                                                       {!!.01}
          end;                                                         {!!.01}
        until Finished;
      {$IFDEF Win32}                                                 {!!.01}
      LeaveCriticalSection(P^.aProtSection);                         {!!.01}
      {$ENDIF}                                                       {!!.01}
    end;

  end;

  procedure spPrepareReceive(P : PProtocolData);
    {-Prepare to receive by Ascii protocol}
  begin
    with P^ do begin
      {Prepare to enter state machine}
      sAsciiState := raInitial;
      sCtrlZEncountered := False;
      apResetStatus(P);
      apShowFirstStatus(P);
      aProtocolError := ecOK;
      aForceStatus := False;
    end;
  end;

  procedure spReceive(Msg, wParam : Cardinal;
                     lParam : LongInt);
    {-Performs one increment of an Ascii receive}
  label
    ExitPoint;
  var
    TriggerID   : Cardinal absolute wParam;
    P           : PProtocolData;
    BlockSize   : Cardinal;
    Finished    : Boolean;
    Handshake   : Char;
    StatusTicks : LongInt;
    Dispatcher  : TApdBaseDispatcher;

    procedure Cleanup(DisposeBuffers : Boolean);
      {-Handle error reporting and other cleanup}
    begin
      with P^ do begin
        {if DisposeBuffers then}
        {  FreeMemCheck(aDataBlock, SizeOf(TDataBlock));}
        apShowLastStatus(P);

        {Tell parent we're finished}
        apSignalFinish(P);
        sAsciiState := raDone;
      end;
    end;

  begin
    Finished := False;                                                 {!!.01}                                                     
    {Get the protocol pointer from data pointer 1}
    try                                                                {!!.01}
      Dispatcher := TApdBaseDispatcher(PortList[LH(lParam).H]);
      with Dispatcher do
        GetDataPointer(Pointer(P), 1);
    except                                                             {!!.01}
      on EAccessViolation do begin                                     {!!.01}
        { There is no access to P^ here, so the only thing to do is }  {!!.01}
        { exit }                                                       {!!.01}
        Exit;                                                          {!!.01}
      end;                                                             {!!.01}
    end;                                                               {!!.01}

    with P^ do begin
      {$IFDEF Win32}
      EnterCriticalSection(aProtSection);

      {Exit if protocol was cancelled while waiting for crit section}
      if sAsciiState = raDone then begin
        LeaveCriticalSection(aProtSection);
        Exit;
      end;
      {$ENDIF}
        {Force TriggerID for TriggerAvail messages}
        if Msg = apw_TriggerAvail then
          TriggerID := aDataTrigger;

        repeat
          try                                                          {!!.01}
            if Dispatcher.Logging then
              Dispatcher.AddDispatchEntry(
                dtAscii,LogAsciiState[sAsciiState],0,nil,0);

            {Check for use abort}
            if (Integer(TriggerID) = aNoCarrierTrigger) or
               (Msg = apw_ProtocolCancel) then begin
              if Integer(TriggerID) = aNoCarrierTrigger then           
                aProtocolStatus := psAbortNoCarrier
              else
                aProtocolStatus := psCancelRequested;
              spCancel(P);
              sAsciiState := raFinished;
              aForceStatus := False;
            end;

            {Show status periodically}
            if (Integer(TriggerID) = aStatusTrigger) or aForceStatus then begin
              if Dispatcher.TimerTicksRemaining(aStatusTrigger,
                                      StatusTicks) <> 0 then
                StatusTicks := 0;
              if StatusTicks <= 0 then begin
                apShowStatus(P, 0);
                Dispatcher.SetTimerTrigger(aStatusTrigger, aStatusInterval, True);
                aForceStatus := False;
              end;                                                          
            end;

            {Process current state}
            case sAsciiState of
              raInitial :
                begin
                  {Pathname should already have name of file to receive}
                  if aPathname[0] = #0 then begin
                    apProtocolError(P, ecNoFilename);
                    Cleanup(True);
                    goto ExitPoint;
                  end else if aUpcaseFileNames then
                    AnsiUpper(aPathname);

                  {Send file name to user's LogFile procedure}
                  apLogFile(P, lfReceiveStart);

                  {Accept this file}
                  if not apAcceptFile(P, aPathname) then begin
                    spCancel(P);
                    aProtocolStatus := psFileRejected;
                    goto ExitPoint;
                  end;

                  {Prepare file for writing protocol blocks}
                  apPrepareWriting(P);
                  if (aProtocolError <> ecOK) or
                     (aProtocolStatus = psCantWriteFile) then begin
                    if aProtocolStatus = psCantWriteFile then
                      aProtocolError := ecCantWriteFile;
                    spCancel(P);
                    sAsciiState := raFinished;
                    goto ExitPoint;
                  end;

                  {Prepare to collect first block}
                  sAsciiState := raCollectBlock;
                  aFileOfs := 0;
                  aBlockNum := 1;
                  aBlkIndex := 0;
                  aForceStatus := True;

                  Dispatcher.SetTimerTrigger(aTimeoutTrigger, aRcvTimeout, True);
                  aTimerPending := True;
                end;

              raCollectBlock :
                if TriggerID = aDataTrigger then begin
                  if apCollectBlock(P, aDataBlock^) then
                    sAsciiState := raProcessBlock;
                end else if Integer(TriggerID) = aTimeoutTrigger then begin
                  {Timeout out waiting for complete block, assume EOF}
                  sCtrlZEncountered := True;
                  sAsciiState := raProcessBlock;
                end;

              raProcessBlock :
                begin
                  {Go process what's in aDataBlock}
                  BlockSize := aBlkIndex;
                  apReceiveBlock(P, aDataBlock^, BlockSize, Handshake);
                  apWriteProtocolBlock(P, aDataBlock^, BlockSize);
                  if aProtocolError = ecOK then begin
                    {Normal received block}
                    Inc(aFileOfs, BlockSize);
                    Dispatcher.SetTimerTrigger(aTimeoutTrigger, aRcvTimeout, True);
                    aForceStatus := True;
                    aBlkIndex := 0;
                    if sCtrlZEncountered then
                      sAsciiState := raFinished
                    else
                      sAsciiState := raCollectBlock;
                  end else
                    {Error during write, clean up and exit}
                    sAsciiState := raFinished;
                end;

              raFinished :
                begin
                  apFinishWriting(P);
                  apLogFile(P, lfReceiveOk);
                  Cleanup(True);
                end;
            end;

ExitPoint:
            {Should we exit or not}
            case sAsciiState of
              {Stay in state machine or exit?}
              raProcessBlock,
              raFinished : Finished := False;

              raCollectBlock : begin
                                 Finished := not Dispatcher.CharReady;
                                 TriggerID := aDataTrigger;
                               end;
              raDone : Finished := True;
              else     Finished := True;
            end;
          except                                                       {!!.01}
            on EAccessViolation do begin                               {!!.01}
              Finished := True;                                        {!!.01}
              aProtocolError := ecAbortNoCarrier;                      {!!.01}
              apSignalFinish(P);                                       {!!.01}
            end;                                                       {!!.01}
          end;                                                         {!!.01}
        until Finished;                                                {!!.01}
      {$IFDEF Win32}                                                 {!!.01}
      LeaveCriticalSection(P^.aProtSection);                         {!!.01}
      {$ENDIF}                                                       {!!.01}
    end;                                                               {!!.01}
  end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -