/// <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(); }
public void Write(ByteDataFragment data) { lock (_sync) { if (!_closed) { _strm.Write(data.Buffer, data.Offset, data.Length); Wrote(); } } }
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); }
public void Write(ByteDataFragment data) { if (this.IsEmpty) { return; } foreach (IBinaryLogger logger in this) { logger.Write(data); } }
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++]); } }
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); }
/// <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); } }
/// <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); } } }
// サーバからの受信データを解析する // 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(); } } } } }
public abstract void OnReception(ByteDataFragment data);
/* * //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); } }
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); } }
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); } } } } }
/// <summary> /// Implements IPoderosaSocket. /// </summary> public void Transmit(ByteDataFragment data) { // do nothing }
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; } }
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); } }
// サーバからの受信データを解析する // 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); }
public void Transmit(ByteDataFragment data) { Transmit(data.Buffer, data.Offset, data.Length); }
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); } }
/// <summary> /// OnReception /// </summary> public void OnReception(ByteDataFragment data) { }
public void Write(ByteDataFragment data) { _strm.Write(data.Buffer, data.Offset, data.Length); }