コード例 #1
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="host"></param>
 /// <param name="settings"></param>
 /// <param name="connection"></param>
 /// <exclude/>
 public TerminalTransmission(AbstractTerminal host, ITerminalSettings settings, ITerminalConnection connection)
 {
     _host             = host;
     _settings         = settings;
     _connection       = connection;
     _dataForLocalEcho = new ByteDataFragment();
 }
コード例 #2
0
ファイル: Logger.cs プロジェクト: hanamiche/poderosa
 public void Write(ByteDataFragment data)
 {
     lock (_sync) {
         if (!_closed)
         {
             _strm.Write(data.Buffer, data.Offset, data.Length);
             Wrote();
         }
     }
 }
コード例 #3
0
        public void RepeatAsyncRead(IByteAsyncInputStream cb)
        {
            if (_callback != null)
            {
                throw new InvalidOperationException("duplicated AsyncRead() is attempted");
            }

            _callback     = cb;
            _dataFragment = new ByteDataFragment();
            new Thread(new ThreadStart(AsyncEntry)).Start();
            //_stream.BeginRead(_buf, 0, _buf.Length, new AsyncCallback(RepeatCallback), null);
        }
コード例 #4
0
ファイル: Logger.cs プロジェクト: hanamiche/poderosa
        public void Write(ByteDataFragment data)
        {
            if (this.IsEmpty)
            {
                return;
            }

            foreach (IBinaryLogger logger in this)
            {
                logger.Write(data);
            }
        }
コード例 #5
0
        public void OnReception(ByteDataFragment data)
        {
            //処理本体
            byte[] t      = data.Buffer;
            int    last   = data.Offset + data.Length;
            int    offset = data.Offset;

            while (offset < last)
            {
                ProcessByte(t[offset++]);
            }
        }
コード例 #6
0
        private void AdjustBuffer(ref ByteDataFragment fragment)
        {
            if (_buffer == null || _buffer.Position == 0)
            {
                return;
            }

            _buffer.Write(fragment.Buffer, fragment.Offset, fragment.Length);
            int count = (int)_buffer.Position;

            _buffer.Close();
            fragment.Set(_buffer.ToArray(), 0, count);
        }
コード例 #7
0
ファイル: PipeSocket.cs プロジェクト: yoshikixxxx/poderosa
        /// <summary>
        /// Thread input from stream
        /// </summary>
        /// <param name="asyncInput"></param>
        private void InputThread(IByteAsyncInputStream asyncInput)
        {
            byte[] buff = new byte[4096];

            ByteDataFragment _dataFragment = new ByteDataFragment();

            try {
                bool endOfStream = false;

                while (!_terminateInputThread && !_processExited)
                {
                    IAsyncResult asyncResult = _inputStream.BeginRead(buff, 0, buff.Length, null, null);

                    while (!_terminateInputThread && !_processExited)
                    {
                        bool signaled = asyncResult.AsyncWaitHandle.WaitOne(500);
                        if (signaled)
                        {
                            int len = _inputStream.EndRead(asyncResult);
                            if (len == 0)
                            {
                                endOfStream = true;
                                goto EndThread;
                            }

                            _dataFragment.Set(buff, 0, len);
                            asyncInput.OnReception(_dataFragment);

                            break;
                        }
                    }
                }

EndThread:
                if (endOfStream || _processExited)
                {
                    _skipInputThreadJoin = true; // avoids deadlock
                    Close();
                    asyncInput.OnNormalTermination();
                }
            }
            catch (Exception e) {
                RuntimeUtil.SilentReportException(e);
                _skipInputThreadJoin = true; // avoids deadlock
                Close();
                asyncInput.OnAbnormalTermination("Input thread error: " + e.Message);
            }
        }
コード例 #8
0
        /// <summary>
        /// Pump thread
        /// </summary>
        /// <param name="receiver"></param>
        private void PumpThread(IByteAsyncInputStream receiver)
        {
            lock (_pumpThreadSync) {
                while (true)
                {
                    if (_isClosed)
                    {
                        break;
                    }

                    if (_generator != null)
                    {
                        IEnumerable <byte[]> generator = _generator;
                        _generator = null;

                        _isProcessing = true;

                        foreach (byte[] data in generator)
                        {
                            if (_isClosed)
                            {
                                break;
                            }
                            ByteDataFragment fragment = new ByteDataFragment(data, 0, data.Length);
                            receiver.OnReception(fragment);
                        }

                        _isProcessing = false;

                        Monitor.PulseAll(_pumpThreadSync);
                    }

                    if (_isClosed)
                    {
                        break;
                    }

                    Monitor.Wait(_pumpThreadSync);
                }
            }
        }
コード例 #9
0
        // サーバからの受信データを解析する
        // Readerクラスから呼ばれる
        public override void OnReception(ByteDataFragment fragment)
        {
            byte[] data   = fragment.Buffer;
            int    offset = fragment.Offset;
            int    length = fragment.Length;
            int    i;
            byte   c;

            Debug.WriteLine(String.Format("OnReception len={0} state={1} pos={2}", length, _state.ToString(), _CurrentPos));

            if (_state == State.GetFileInfo)
            {
                // ファイル情報を取得する
                _state = State.WaitingZPAD;
                ParseFileInfo(data, offset, length);
                return;
            }
            else if (_state == State.GetFileData)
            {
                // ファイルの内容を読み取り、書き込む。
                int p = ParseFileData(data, offset, length);
                offset += p;
                length -= p;
            }

            for (i = 0; i < length; i++)
            {
                c = data[offset + i];

                // 0x11, 0x13, 0x81, 0x83は無視する
                if ((c & 0x7f) == XON || (c & 0x7f) == XOFF)
                {
                    continue;
                }

                if (_state == State.WaitingZPAD)
                {
                    switch (c)
                    {
                    case ZPAD:
                        _state = State.WaitingZDLE;
                        break;

                    default:
                        break;
                    }
                }
                else if (_state == State.WaitingZDLE)
                {
                    switch (c)
                    {
                    case ZPAD:
                        break;

                    case ZDLE:
                        _state = State.GetHeaderFormat;
                        break;

                    default:
                        _state = State.WaitingZPAD;
                        break;
                    }
                }
                else if (_state == State.GetHeaderFormat)
                {
                    switch (c)
                    {
                    case ZBIN:
                        _PktInCount = 7;
                        _state      = State.GetBinaryData;
                        break;

                    case ZHEX:
                        _PktInCount = 7;
                        _state      = State.GetHexData;
                        break;

                    case ZBIN32:
                        _PktInCount = 9;
                        _state      = State.GetBinaryData;
                        break;

                    default:
                        _state = State.WaitingZPAD;
                        break;
                    }
                    // initialize variables
                    _PktInIndex = 0;
                    _HexLo      = false;
                }
                else if (_state == State.GetBinaryData)  // binary('A') data
                {
                    _PktIn[_PktInIndex++] = c;
                    _PktInCount--;
                    if (_PktInCount <= 0)
                    {
                        _state = State.WaitingZPAD;

                        if (CheckHeader(_PktIn, _PktInCount))
                        {
                            ParseHeader();

                            if (_RxType == ZDATA)
                            {
                                i += ParseFileData(data, offset + 10, length - 10);
                            }
                            else if (_RxType == ZFILE)
                            {
                                ParseFileInfo(data, offset + 10, length - 10);
                            }
                        }
                    }
                }
                else if (_state == State.GetHexData)  // HEX('B') data
                {
                    if (c <= '9')
                    {
                        c -= 0x30;
                    }
                    else if ((c >= 'a') && (c <= 'f'))
                    {
                        c -= 0x57;
                    }
                    else
                    {
                        _state = State.WaitingZPAD;
                        break;  // for loop
                    }

                    if (_HexLo)
                    {  // lower
                        _PktIn[_PktInIndex] |= c;
                        _PktInIndex++;
                        _HexLo = false;
                        _PktInCount--;

                        if (_PktInCount <= 0)
                        {
                            _state      = State.GetHexEOL;
                            _PktInCount = 2;  // CRとLFの分をスキップする
                        }
                    }
                    else
                    {  // upper
                        _PktIn[_PktInIndex] = (byte)(c << 4);
                        _HexLo = true;
                    }
                }
                else if (_state == State.GetHexEOL)
                {
                    _PktInCount--;
                    if (_PktInCount <= 0)
                    {
                        _state = State.WaitingZPAD;

                        if (CheckHeader(_PktIn, _PktInCount))
                        {
                            ParseHeader();
                        }
                    }
                }
            }
        }
コード例 #10
0
 public abstract void OnReception(ByteDataFragment data);
コード例 #11
0
/*
 *      //ModalTerminalTaskŽü•Ó
 *      public virtual void StartModalTerminalTask(IModalTerminalTask task) {
 *          _modalTerminalTask = task;
 *          new ModalTerminalTaskSite(this).Start(task);
 *      }
 *      public virtual void EndModalTerminalTask() {
 *          _modalTerminalTask = null;
 *      }
 *      public IModalTerminalTask CurrentModalTerminalTask {
 *          get {
 *              return _modalTerminalTask;
 *          }
 *      }
 */
        #region IByteAsyncInputStream
        public void OnReception(ByteDataFragment data)
        {
            try {
                bool pass_to_terminal = true;
                //if(_modalTerminalTask!=null) {
                //    bool show_input = _modalTerminalTask.ShowInputInTerminal;
                //    _modalTerminalTask.OnReception(data);
                //    if(!show_input) pass_to_terminal = false; //“ü—Í‚ðŒ©‚¹‚È‚¢(XMODEM‚Æ‚©)‚Ì‚Æ‚«‚̓^[ƒ~ƒiƒ‹‚É—^‚¦‚È‚¢
                //}

                //ƒoƒCƒiƒŠƒƒO‚̏o—Í
                _logService.BinaryLogger.Write(data);

                if (pass_to_terminal)
                {
                    TerminalDocument document = _document;
                    if (document != null)
                    {
                        lock (document)
                        {
                            //_invalidateParam.Reset();
                            //‚±‚±‚©‚ç‹ŒInput()
                            //_manipulator.Load(GetDocument().CurrentLine, 0);
                            //_manipulator.CaretColumn = GetDocument().CaretColumn;

                            //ˆ—–{‘Ì
                            _decoder.OnReception(data);

                            //GetDocument().ReplaceCurrentLine(_manipulator.Export());
                            //GetDocument().CaretColumn = _manipulator.CaretColumn;
                            //‚±‚±‚Ü‚Å

                            //‰E’[‚ɃLƒƒƒŒƒbƒg‚ª—ˆ‚½‚Æ‚«‚Í•Ö‹X“I‚ÉŽŸs‚Ì“ª‚É‚à‚Á‚Ä‚¢‚­
                            //if(document.CaretColumn==document.TerminalWidth) {
                            //    document.CurrentLineNumber++; //‚±‚ê‚É‚æ‚Á‚ÄŽŸs‚Ì‘¶Ý‚ð•ÛØ
                            //    document.CaretColumn = 0;
                            //}

                            CheckDiscardDocument();
                            //AdjustTransientScrollBar();

                            //Œ»Ýs‚ª‰º’[‚ÉŒ©‚¦‚é‚悤‚ÈScrollBarValue‚ðŒvŽZ
                            //int n = document.CurrentLineNumber-document.TerminalHeight+1-document.FirstLineNumber;
                            //if(n < 0) n = 0;

                            //Debug.WriteLine(String.Format("E={0} C={1} T={2} H={3} LC={4} MAX={5} n={6}", _transientScrollBarEnabled, _tag.Document.CurrentLineNumber, _tag.Document.TopLineNumber, _tag.Connection.TerminalHeight, _transientScrollBarLargeChange, _transientScrollBarMaximum, n));

                            /* if(IsAutoScrollMode(n)) {
                             *  _scrollBarValues.Value = n;
                             *  document.TopLineNumber = n + document.FirstLineNumber;
                             * }
                             * else
                             *  _scrollBarValues.Value = document.TopLineNumber - document.FirstLineNumber;
                             */
                            //Invalidate‚ðlock‚ÌŠO‚ɏo‚·B‚±‚Ì‚Ù‚¤‚ªˆÀ‘S‚ÆŽv‚í‚ꂽ

                            //ŽóMƒXƒŒƒbƒh“à‚ł̓}[ƒN‚ð‚‚¯‚é‚̂݁Bƒ^ƒCƒ}[‚ōs‚¤‚Ì‚ÍIntelliSense‚É•›ì—p‚ ‚é‚̂ňꎞ’âŽ~
                            //_promptRecognizer.SetContentUpdateMark();
                            //_promptRecognizer.Recognize();
                        }
                    }

                    if (_afterExitLockActions.Count > 0)
                    {
                        //Control main = _session.OwnerWindow.AsControl();
                        //foreach(AfterExitLockDelegate action in _afterExitLockActions) {
                        //    main.Invoke(action);
                        //}
                        _afterExitLockActions.Clear();
                    }
                }

                //if(_modalTerminalTask!=null) _modalTerminalTask.NotifyEndOfPacket();
                _session.NotifyViewsDataArrived();
            }
            catch (Exception ex) {
                RuntimeUtil.ReportException(ex);
            }
        }
コード例 #12
0
        public override void OnReception(ByteDataFragment fragment)
        {
            if (_timer != null)
            {
                _timer.Dispose();
                _timer = null;
            }

            byte[] data   = fragment.Buffer;
            int    offset = fragment.Offset;
            int    count  = fragment.Length;

            if (_negotiating)
            {
                for (int i = 0; i < count; i++)
                {
                    byte t = data[offset + i];
                    if (t == NAK || t == (byte)'C')
                    {
                        _crcEnabled     = t == (byte)'C';
                        _negotiating    = false;
                        _sequenceNumber = 1;
                        _offset         = _nextOffset = 0;
                        break;
                    }
                }
                if (_negotiating)
                {
                    return; //あたまがきていない
                }
            }
            else
            {
                byte t = data[offset];
                if (t == ACK)
                {
                    _sequenceNumber++;
                    _retryCount = 0;
                    if (_offset == _body.Length)   //successfully exit
                    {
                        _site.MainWindow.Information(XZModemPlugin.Instance.Strings.GetString("Message.XModem.SendComplete"));
                        Complete();
                        return;
                    }
                    _offset = _nextOffset;
                }
                else if (t != NAK || (++_retryCount == 3))
                {
                    Fail(XZModemPlugin.Instance.Strings.GetString("Message.XModem.BlockStartError"));
                    return;
                }
            }

            if (_nextOffset >= _body.Length)   //last
            {
                SendByte(EOT);
                _offset = _body.Length;
            }
            else
            {
                int len = 128;
                if (_crcEnabled && _offset + 1024 <= _body.Length)
                {
                    len = 1024;
                }
                byte[] buf = new byte[3 + len + (_crcEnabled ? 2 : 1)];
                buf[0] = len == 128 ? SOH : STX;
                buf[1] = (byte)_sequenceNumber;
                buf[2] = (byte)(255 - buf[1]);
                int body_len = Math.Min(len, _body.Length - _offset);
                Array.Copy(_body, _offset, buf, 3, body_len);
                for (int i = body_len; i < len; i++)
                {
                    buf[3 + i] = 26; //padding
                }
                if (_crcEnabled)
                {
                    ushort sum = CalcCRC(buf, 3, len);
                    buf[3 + len]     = (byte)(sum >> 8);
                    buf[3 + len + 1] = (byte)(sum & 0xFF);
                }
                else
                {
                    byte sum = 0;
                    for (int i = 0; i < len; i++)
                    {
                        sum += buf[3 + i];
                    }
                    buf[3 + len] = sum;
                }

                _nextOffset = _offset + len;
                _connection.Socket.Transmit(buf, 0, buf.Length);
                _parent.AsyncSetProgressValue(_nextOffset);
                //Debug.WriteLine("Transmitted "+_sequenceNumber+" " +_offset);
            }
        }
コード例 #13
0
        public override void OnReception(ByteDataFragment fragment)
        {
            if (_timer != null)
            {
                _timer.Dispose();
                _timer = null;
            }

            //Debug.WriteLine(String.Format("Received {0}", count));
            //_debugStream.Write(data, offset, count);
            //_debugStream.Flush();
            AdjustBuffer(ref fragment);
            byte[] data   = fragment.Buffer;
            int    offset = fragment.Offset;
            int    count  = fragment.Length;

            byte head = data[offset];

            if (head == EOT)   //successfully exit
            {
                SendByte(ACK);
                _site.MainWindow.Information(XZModemPlugin.Instance.Strings.GetString("Message.XModem.ReceiveComplete"));
                Complete();
                //_debugStream.Close();
            }
            else
            {
                int required = 3 + (head == STX ? 1024 : 128) + (_crcEnabled ? 2 : 1);
                if (required > count)
                {
                    ReserveBuffer(data, offset, count); //途中で切れていた場合
                    //Debug.WriteLine(String.Format("Reserving #{0} last={1} offset={2} count={3}", seq, last, offset, count));
                    return;
                }

                byte seq = data[offset + 1];
                byte neg = data[offset + 2];
                if (seq != _sequenceNumber || seq + neg != 255)
                {
                    Fail(XZModemPlugin.Instance.Strings.GetString("Message.XModem.SequenceError"));
                }
                else
                {
                    //Debug.WriteLine(String.Format("Processing #{0}", seq));
                    bool success;
                    int  body_offset     = offset + 3;
                    int  body_len        = head == STX ? 1024 : 128;
                    int  checksum_offset = offset + 3 + body_len;
                    if (_crcEnabled)
                    {
                        ushort sent = (ushort)((((ushort)data[checksum_offset]) << 8) + (ushort)data[checksum_offset + 1]);
                        ushort sum  = CalcCRC(data, body_offset, body_len);
                        success = (sent == sum);
                    }
                    else
                    {
                        byte sent = data[checksum_offset];
                        byte sum  = 0;
                        for (int i = body_offset; i < checksum_offset; i++)
                        {
                            sum += data[i];
                        }
                        success = (sent == sum);
                    }

                    _buffer = null; //ブロックごとにACKを待つ仕様なので、もらってきたデータが複数ブロックにまたがることはない。したがってここで破棄して構わない。
                    if (success)
                    {
                        SendByte(ACK);
                        _sequenceNumber++;

                        int t = checksum_offset - 1;
                        while (t >= body_offset && data[t] == 26)
                        {
                            t--; //Ctrl+Zで埋まっているところは無視
                        }
                        int len = t + 1 - body_offset;
                        _outputStream.Write(data, body_offset, len);
                        _processedLength += len;
                        _parent.AsyncSetProgressValue((int)_processedLength);
                        _retryCount = 0;
                    }
                    else
                    {
                        //_debugStream.Close();
                        if (++_retryCount == 3)   //もうあきらめる
                        {
                            Fail(XZModemPlugin.Instance.Strings.GetString("Message.XModem.CheckSumError"));
                        }
                        else
                        {
                            SendByte(NAK);
                        }
                    }
                }
            }
        }
コード例 #14
0
 /// <summary>
 /// Implements IPoderosaSocket.
 /// </summary>
 public void Transmit(ByteDataFragment data)
 {
     // do nothing
 }
コード例 #15
0
ファイル: xmodem.cs プロジェクト: youkebing/poderosa
        public override void OnReception(ByteDataFragment fragment)
        {
            if (_state == State.Stopped)
            {
                return;
            }

            if (_state == State.Aborting)
            {
                Send(CAN);
                Send(CAN);
                _state = State.Stopped;
                return;
            }

            byte[] data   = fragment.Buffer;
            int    offset = fragment.Offset;
            int    length = fragment.Length;

            byte response;

            for (int i = 0; i < length; ++i)
            {
                byte c = data[offset + i];
                if (c == LETTER_C || c == ACK || c == NAK || c == CAN)
                {
                    response = c;
                    goto GotResponse;
                }
            }

            return;

GotResponse:
            Interlocked.Exchange(ref _lastResponseTimeUtcTicks, DateTime.UtcNow.Ticks);

            switch (response)
            {
            case NAK:
                Trace("--> NAK");
Resend:
                if (_state == State.AfterEOT)
                {
                    Trace("<-- EOT(resend)");
                    Send(EOT);
                }
                else
                {
                    SendBlock(_crcMode, true);
                }
                break;

            case LETTER_C:
                Trace("--> C");
                _crcMode = true;
                goto Resend;

            case ACK:
                Trace("--> ACK");
                if (_state == State.AfterEOT)
                {
                    _state = State.Stopped;
                    //Completed(false, true, XZModemPlugin.Instance.Strings.GetString("Message.XModem.SendComplete"));
                    Completed(false, true, null);
                }
                else
                {
                    SendBlock(_crcMode, false);
                }
                break;

            case CAN:
                Trace("--> CAN");
                _state = State.Stopped;
                Abort(XZModemPlugin.Instance.Strings.GetString("Message.ZModem.Aborted"), false);
                break;
            }
        }
コード例 #16
0
ファイル: xmodem.cs プロジェクト: youkebing/poderosa
        public override void OnReception(ByteDataFragment fragment)
        {
            Interlocked.Exchange(ref _lastReceptionTimeUtcTicks, DateTime.UtcNow.Ticks);

            if (_aborting)
            {
                return;
            }

            byte[] data   = fragment.Buffer;
            int    offset = fragment.Offset;
            int    length = fragment.Length;

            BlockTypeInfo blockInfo;

            if (_recvLen > 0)
            {
                blockInfo = GetBlockTypeInfo(_recvBuff[0], Volatile.Read(ref _mode));
            }
            else
            {
                blockInfo = new BlockTypeInfo();    // update later
            }

            for (int i = 0; i < length; i++)
            {
                byte c = data[offset + i];

                if (_recvLen == 0)
                {
                    if (c == EOT)
                    {
                        Trace("--> EOT");
                        FlushPendingBuffer(true);
                        Trace("<-- ACK");
                        Send(ACK);
                        Completed(false, true, XZModemPlugin.Instance.Strings.GetString("Message.XModem.ReceiveComplete"));
                        return;
                    }

                    if (c != SOH && c != STX)
                    {
                        continue;   // skip
                    }

                    // determine expected block type
                    blockInfo = GetBlockTypeInfo(c, Volatile.Read(ref _mode));
                }

                _recvBuff[_recvLen++] = c;

                if (_recvLen >= blockInfo.BlockSize)
                {
                    goto BlockReceived;
                }
            }

            return;

BlockReceived:
            // a block has been received
            Interlocked.Exchange(ref _lastBlockTimeUtcTicks, DateTime.UtcNow.Ticks);

            Trace("--> {0:X2} {1:X2} ...({2})", _recvBuff[0], _recvBuff[1], _recvLen);

            // check sequence number
            if (_recvBuff[1] != _nextSequenceNumber || _recvBuff[2] != (255 - _nextSequenceNumber))
            {
                Trace("<-- NAK (bad seq)");
                goto Error;
            }

            // check CRC or checksum
            if (blockInfo.HasCRC)
            {
                ushort crc      = Crc16.Update(Crc16.InitialValue, _recvBuff, blockInfo.DataOffset, blockInfo.DataLength);
                int    crcIndex = blockInfo.DataOffset + blockInfo.DataLength;
                if (_recvBuff[crcIndex] != (byte)(crc >> 8) || _recvBuff[crcIndex + 1] != (byte)crc)
                {
                    // CRC error
                    Trace("<-- NAK (CRC error)");
                    goto Error;
                }
            }
            else
            {
                byte checksum = 0;
                int  index    = blockInfo.DataOffset;
                for (int n = 0; n < blockInfo.DataLength; ++n)
                {
                    checksum += _recvBuff[index++];
                }
                if (_recvBuff[index] != checksum)
                {
                    // checksum error
                    Trace("<-- NAK (checksum error)");
                    goto Error;
                }
            }

            // ok
            _nextSequenceNumber++;

            FlushPendingBuffer(false);
            SaveToPendingBuffer(_recvBuff, blockInfo.DataOffset, blockInfo.DataLength);

            _errorCount = 0;
            _recvLen    = 0;
            Send(ACK);
            return;

Error:
            _recvLen = 0;
            _errorCount++;
            if (_errorCount > MAX_ERROR)
            {
                Abort(XZModemPlugin.Instance.Strings.GetString("Message.XModem.CouldNotReceiveCorrectData"), false);
            }
            else
            {
                Send(NAK);
            }
        }
コード例 #17
0
ファイル: zmodem.cs プロジェクト: stone89son/poderosa
        // サーバからの受信データを解析する
        // Readerクラスから呼ばれる
        public override void OnReception(ByteDataFragment fragment)
        {
            Interlocked.Exchange(ref _lastReceptionTimeUtcTicks, DateTime.UtcNow.Ticks);

            byte[] data   = fragment.Buffer;
            int    offset = fragment.Offset;
            int    length = fragment.Length;

            //Debug.WriteLine(String.Format("OnReception len={0} state={1}", length, _state.ToString()));

            if (_state == State.None || _state == State.Error || Volatile.Read(ref _aborting))
            {
                return;
            }

            string errorMessage = null;

            for (int i = 0; i < length; i++)
            {
                if (Volatile.Read(ref _aborting))
                {
                    return;
                }

                byte c = data[offset + i];

                // abort sequence detection
                if (c == CAN)
                {
                    _canCount++;
                    if (_canCount > 5)
                    {
                        _state = State.None;    // don't accept any more
                        ProcessAbortByPeer();
                        return;
                    }
                }
                else
                {
                    _canCount = 0;
                }

                // 0x11, 0x13, 0x81, 0x83は無視する
                if ((c & 0x7f) == XON || (c & 0x7f) == XOFF)
                {
                    continue;
                }

CheckByte:
                switch (_state)
                {
                case State.WaitingZPAD: {
                    switch (c)
                    {
                    case ZPAD:
                        _state = State.WaitingZDLE;
                        break;

                    default:
                        break;
                    }
                }
                break;

                case State.WaitingZDLE: {
                    switch (c)
                    {
                    case ZPAD:
                        break;

                    case ZDLE:
                        _state = State.GetHeaderFormat;
                        break;

                    default:
                        _state = State.WaitingZPAD;
                        break;
                    }
                }
                break;

                case State.GetHeaderFormat: {
                    switch (c)
                    {
                    case ZBIN:
                        //Debug.WriteLine("ZBIN");
                        _crcType     = CRCType.CRC16;
                        _bytesNeeded = 7;
                        _state       = State.GetBinaryData;
                        break;

                    case ZHEX:
                        //Debug.WriteLine("ZHEX");
                        _crcType     = CRCType.CRC16;
                        _bytesNeeded = 7;
                        _state       = State.GetHexData;
                        break;

                    case ZBIN32:
                        //Debug.WriteLine("ZBIN32");
                        _crcType     = CRCType.CRC32;
                        _bytesNeeded = 9;
                        _state       = State.GetBinaryData;
                        break;

                    default:
                        _state = State.WaitingZPAD;
                        break;
                    }
                    // initialize variables
                    _rcvPacketLen = 0;
                    _hexLo        = false;
                    _gotZDLE      = false;
                }
                break;

                case State.GetBinaryData: {     // binary('A') or binary('C') data
                    if (_gotZDLE)
                    {
                        // unescape
                        _rcvPacket[_rcvPacketLen++] = (byte)(c ^ 0x40);
                        _bytesNeeded--;
                        _gotZDLE = false;
                    }
                    else if (c == ZDLE)
                    {
                        _gotZDLE = true;
                    }
                    else
                    {
                        _rcvPacket[_rcvPacketLen++] = c;
                        _bytesNeeded--;
                        _gotZDLE = false;
                    }

                    if (_bytesNeeded <= 0)
                    {
                        _state = State.WaitingZPAD;
                        Header hdr;
                        if (CheckHeader(_crcType, _rcvPacket, _rcvPacketLen, out hdr))
                        {
                            ProcessHeader(hdr);
                            if (hdr.Type == ZDATA)
                            {
                                _state        = State.GetFileData;
                                _rcvPacketLen = 0;
                                _gotZDLE      = false;
                            }
                            else if (hdr.Type == ZFILE)
                            {
                                _state        = State.GetFileInfo;
                                _rcvPacketLen = 0;
                                _gotZDLE      = false;
                            }
                        }
                    }
                }
                break;

                case State.GetHexData: {      // HEX('B') data
                    if ((c >= '0') && (c <= '9'))
                    {
                        c -= 0x30;
                    }
                    else if ((c >= 'a') && (c <= 'f'))
                    {
                        c -= 0x57;
                    }
                    else
                    {
                        Debug.WriteLine("Unexpected character in {0}", _state);
                        errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.InvalidHeader");
                        goto Error;
                    }

                    if (_hexLo)            // lower
                    {
                        _rcvPacket[_rcvPacketLen++] |= c;
                        _hexLo = false;
                        _bytesNeeded--;

                        if (_bytesNeeded <= 0)
                        {
                            Header hdr;
                            if (CheckHeader(_crcType, _rcvPacket, _rcvPacketLen, out hdr))
                            {
                                ProcessHeader(hdr);
                                _state       = State.GetHexEOL;
                                _bytesNeeded = 2;            // CR LF
                            }
                            else
                            {
                                _state = State.WaitingZPAD;
                            }
                        }
                    }
                    else            // upper
                    {
                        _rcvPacket[_rcvPacketLen] = (byte)(c << 4);
                        _hexLo = true;
                    }
                }
                break;

                case State.GetHexEOL: {
                    byte cc = (byte)(c & 0x7f);         // sz sends { 0x0d, 0x8a } as CR/LF
                    if (cc == 0x0a || cc == 0x0d)
                    {
                        _bytesNeeded--;
                        if (_bytesNeeded <= 0)
                        {
                            _state = State.WaitingZPAD;
                        }
                    }
                    else
                    {
                        _state = State.WaitingZPAD;
                        goto CheckByte;
                    }
                }
                break;

                case State.GetFileInfo:
                case State.GetFileData: {
                    if (_rcvPacketLen >= _rcvPacket.Length)
                    {
                        Debug.WriteLine("Buffer full in {0}", _state);
                        errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.BufferFull");
                        goto Error;
                    }
                    if (_gotZDLE)
                    {
                        if (c == ZCRCE || c == ZCRCG || c == ZCRCQ || c == ZCRCW)
                        {
                            // end of frame. need CRC bytes.
                            _rcvPacket[_rcvPacketLen++] = c;
                            _gotZDLE     = false;
                            _bytesNeeded = (_crcType == CRCType.CRC32) ? 4 : 2;            // CRC bytes
                            _state       = (_state == State.GetFileInfo) ? State.GetFileInfoCRC :
                                           (_state == State.GetFileData) ? State.GetFileDataCRC : State.Error;
                        }
                        else
                        {
                            // unescape
                            _rcvPacket[_rcvPacketLen++] = (byte)(c ^ 0x40);
                            _gotZDLE = false;
                        }
                    }
                    else if (c == ZDLE)
                    {
                        _gotZDLE = true;
                    }
                    else
                    {
                        _rcvPacket[_rcvPacketLen++] = c;
                        _gotZDLE = false;
                    }
                }
                break;

                case State.GetFileInfoCRC:
                case State.GetFileDataCRC: {
                    if (_rcvPacketLen >= _rcvPacket.Length)
                    {
                        Debug.WriteLine("Buffer full in {0}", _state);
                        errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.BufferFull");
                        goto Error;
                    }
                    if (_gotZDLE)
                    {
                        // unescape
                        _rcvPacket[_rcvPacketLen++] = (byte)(c ^ 0x40);
                        _bytesNeeded--;
                        _gotZDLE = false;
                    }
                    else if (c == ZDLE)
                    {
                        _gotZDLE = true;
                    }
                    else
                    {
                        _rcvPacket[_rcvPacketLen++] = c;
                        _bytesNeeded--;
                        _gotZDLE = false;
                    }

                    if (_bytesNeeded <= 0)
                    {
                        int dataLen = _rcvPacketLen - (_crcType == CRCType.CRC32 ? 5 : 3);
                        if (_state == State.GetFileInfoCRC)
                        {
                            if (CheckCRC(_crcType, _rcvPacket, _rcvPacketLen))
                            {
                                ParseFileInfo(_rcvPacket, 0, dataLen);
                                _rcvPacketLen = 0;
                                _gotZDLE      = false;
                                _state        = State.WaitingZPAD;
                            }
                            else
                            {
                                Debug.WriteLine("CRC Error in {0}", _state);
                                errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.CRCError");
                                goto Error;
                            }
                        }
                        else if (_state == State.GetFileDataCRC)
                        {
                            byte frameType = _rcvPacket[dataLen];
                            //Debug.WriteLine("frameType = 0x{0:x2}", frameType);

                            if (CheckCRC(_crcType, _rcvPacket, _rcvPacketLen))
                            {
                                ProcessFileData(_rcvPacket, 0, dataLen);
                                _rcvPacketLen = 0;
                                _gotZDLE      = false;
                                if (frameType == ZCRCE)
                                {
                                    // finished
                                    _state = State.WaitingZPAD;
                                }
                                else if (frameType == ZCRCW)
                                {
                                    SendACK();
                                    // read next subpacket
                                    _state = State.WaitingZPAD;
                                }
                                else
                                {
                                    // read next subpacket
                                    _state = State.GetFileData;
                                }
                            }
                            else
                            {
                                Debug.WriteLine("CRC Error in {0}", _state);
                                errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.CRCError");
                                goto Error;
                            }
                        }
                    }
                }
                break;
                }
            }

            return;

Error:
            _state = State.Error;
            Abort(errorMessage, false);
        }
コード例 #18
0
ファイル: PipeSocket.cs プロジェクト: yoshikixxxx/poderosa
 public void Transmit(ByteDataFragment data)
 {
     Transmit(data.Buffer, data.Offset, data.Length);
 }
コード例 #19
0
ファイル: TerminalBase.cs プロジェクト: lstratman/poderosa
        public void OnReception(ByteDataFragment data)
        {
            try {
                bool pass_to_terminal = true;
                if (_modalTerminalTask != null)
                {
                    bool show_input = _modalTerminalTask.ShowInputInTerminal;
                    _modalTerminalTask.OnReception(data);
                    if (!show_input)
                    {
                        pass_to_terminal = false; //入力を見せない(XMODEMとか)のときはターミナルに与えない
                    }
                }

                //バイナリログの出力
                _logService.BinaryLogger.Write(data);

                if (pass_to_terminal)
                {
                    TerminalDocument document = _document;
                    lock (document) {
                        //_invalidateParam.Reset();
                        //ここから旧Input()
                        _manipulator.Load(GetDocument().CurrentLine, 0);
                        _manipulator.CaretColumn       = GetDocument().CaretColumn;
                        _manipulator.DefaultDecoration = _currentdecoration;

                        //処理本体
                        _decoder.OnReception(data);

                        GetDocument().ReplaceCurrentLine(_manipulator.Export());
                        GetDocument().CaretColumn = _manipulator.CaretColumn;
                        //ここまで

                        //右端にキャレットが来たときは便宜的に次行の頭にもっていく
                        if (document.CaretColumn == document.TerminalWidth)
                        {
                            document.CurrentLineNumber++; //これによって次行の存在を保証
                            document.CaretColumn = 0;
                        }

                        CheckDiscardDocument();
                        AdjustTransientScrollBar();

                        //現在行が下端に見えるようなScrollBarValueを計算
                        int n = document.CurrentLineNumber - document.TerminalHeight + 1 - document.FirstLineNumber;
                        if (n < 0)
                        {
                            n = 0;
                        }

                        //Debug.WriteLine(String.Format("E={0} C={1} T={2} H={3} LC={4} MAX={5} n={6}", _transientScrollBarEnabled, _tag.Document.CurrentLineNumber, _tag.Document.TopLineNumber, _tag.Connection.TerminalHeight, _transientScrollBarLargeChange, _transientScrollBarMaximum, n));
                        if (IsAutoScrollMode(n))
                        {
                            _scrollBarValues.Value = n;
                            document.TopLineNumber = n + document.FirstLineNumber;
                        }
                        else
                        {
                            _scrollBarValues.Value = document.TopLineNumber - document.FirstLineNumber;
                        }

                        //Invalidateをlockの外に出す。このほうが安全と思われた

                        //受信スレッド内ではマークをつけるのみ。タイマーで行うのはIntelliSenseに副作用あるので一時停止
                        //_promptRecognizer.SetContentUpdateMark();
                        _promptRecognizer.Recognize();
                    }

                    if (_afterExitLockActions.Count > 0)
                    {
                        Control main = _session.OwnerWindow.AsControl();
                        foreach (AfterExitLockDelegate action in _afterExitLockActions)
                        {
                            main.Invoke(action);
                        }
                        _afterExitLockActions.Clear();
                    }
                }

                if (_modalTerminalTask != null)
                {
                    _modalTerminalTask.NotifyEndOfPacket();
                }
                _session.NotifyViewsDataArrived();
            }
            catch (Exception ex) {
                RuntimeUtil.ReportException(ex);
            }
        }
コード例 #20
0
 /// <summary>
 /// OnReception
 /// </summary>
 public void OnReception(ByteDataFragment data)
 {
 }
コード例 #21
0
 public void Write(ByteDataFragment data)
 {
     _strm.Write(data.Buffer, data.Offset, data.Length);
 }