Renci.SshNet.Sftp.SftpSession.OnDataReceived C# (CSharp) Méthode

OnDataReceived() protected méthode

protected OnDataReceived ( byte data ) : void
data byte
Résultat void
        protected override void OnDataReceived(byte[] data)
        {
            const int packetLengthByteCount = 4;
            const int sftpMessageTypeByteCount = 1;
            const int minimumChannelDataLength = packetLengthByteCount + sftpMessageTypeByteCount;

            var offset = 0;
            var count = data.Length;

            // improve performance and reduce GC pressure by not buffering channel data if the received
            // chunk contains the complete packet data.
            //
            // for this, the buffer should be empty and the chunk should contain at least the packet length
            // and the type of the SFTP message
            if (_data.Count == 0)
            {
                while (count >= minimumChannelDataLength)
                {
                    // extract packet length
                    var packetDataLength = data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 |
                                           data[offset + 3];

                    var packetTotalLength = packetDataLength + packetLengthByteCount;

                    // check if complete packet data (or more) is available
                    if (count >= packetTotalLength)
                    {
                        // load and process SFTP message
                        if (!TryLoadSftpMessage(data, offset + packetLengthByteCount, packetDataLength))
                        {
                            return;
                        }

                        // remove processed bytes from the number of bytes to process as the channel
                        // data we received may contain (part of) another message
                        count -= packetTotalLength;

                        // move offset beyond bytes we just processed
                        offset += packetTotalLength;
                    }
                    else
                    {
                        // we don't have a complete message
                        break;
                    }
                }

                // check if there is channel data left to process or buffer
                if (count == 0)
                {
                    return;
                }

                // check if we processed part of the channel data we received
                if (offset > 0)
                {
                    // add (remaining) channel data to internal data holder
                    var remainingChannelData = new byte[count];
                    Buffer.BlockCopy(data, offset, remainingChannelData, 0, count);
                    _data.AddRange(remainingChannelData);
                }
                else
                {
                    // add (remaining) channel data to internal data holder
                    _data.AddRange(data);
                }

                // skip further processing as we'll need a new chunk to complete the message
                return;
            }

            // add (remaining) channel data to internal data holder
            _data.AddRange(data);

            while (_data.Count >= minimumChannelDataLength)
            {
                // extract packet length
                var packetDataLength = _data[0] << 24 | _data[1] << 16 | _data[2] << 8 | _data[3];

                var packetTotalLength = packetDataLength + packetLengthByteCount;

                // check if complete packet data is available
                if (_data.Count < packetTotalLength)
                {
                    // wait for complete message to arrive first
                    break;
                }

                // create buffer to hold packet data
                var packetData = new byte[packetDataLength];

                // copy packet data and bytes for length to array
                _data.CopyTo(packetLengthByteCount, packetData, 0, packetDataLength);

                // remove loaded data and bytes for length from _data holder
                if (_data.Count == packetTotalLength)
                {
                    // the only buffered data is the data we're processing 
                    _data.Clear();
                }
                else
                {
                    // remove only the data we're processing
                    _data.RemoveRange(0, packetTotalLength);
                }

                // load and process SFTP message
                if (!TryLoadSftpMessage(packetData, 0, packetDataLength))
                {
                    break;
                }
            }
        }