예제 #1
0
        /// <summary>
        /// </summary>
        /// <param name="e"></param>
        /// <param name="context">Used to enqueue bytes for delivery.</param>
        /// <returns><c>true</c> if more buffers can be appened.</returns>
        public bool Write(WriterContext context)
        {
            _writeBuffer = context.DequeueBuffer();
            var len = CopyTo(_writeBuffer.Array, _writeBuffer.Offset);

            context.Enqueue(new SendPacketsElement(_writeBuffer.Array, _writeBuffer.Offset, len));
            return(true);
        }
예제 #2
0
        /// <summary>
        /// </summary>
        /// <param name="e"></param>
        /// <param name="context">Used to enqueue bytes for delivery.</param>
        /// <returns><c>true</c> if more buffers can be appened.</returns>
        public bool Write(WriterContext context)
        {
            //_sendCompleted = true when previous send is done. Init everything for this send.
            if (_sendBuffer == WriterContext.EmptySegment)
            {
                _sendBuffer = context.DequeueBuffer();
            }
            var offset = _sendBuffer.Offset;

            if (_sendCompleted)
            {
                var buffer = _sendBuffer.Array;
                var len    = GetContentLength();
                if (len > 512)
                {
                    _flags = _flags | FrameFlags.LargeFrame;
                }

                buffer[offset++] = (byte)_flags;
                buffer[offset++] = _extensionId;
                if (len > 512)
                {
                    var lenBuffer = BitConverter.GetBytes(len);
                    if (BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(lenBuffer);
                    }
                    buffer[offset++] = lenBuffer[0];
                    buffer[offset++] = lenBuffer[1];
                    buffer[offset++] = lenBuffer[2];
                    buffer[offset++] = lenBuffer[3];
                }
                else
                {
                    buffer[offset++] = (byte)len;
                }

                var bytesLeft = _sendBuffer.Count - (offset - _sendBuffer.Offset);
                _sendCompleted = WritePayload(buffer, ref offset, bytesLeft);
            }
            else
            {
                var buffer = _sendBuffer.Array;
                _sendCompleted = WritePayload(buffer, ref offset, _sendBuffer.Count);
            }


            var bytesWritten = offset - _sendBuffer.Offset;

            context.Enqueue(_sendBuffer.Array, _sendBuffer.Offset, bytesWritten);
            return(_sendCompleted);
        }
예제 #3
0
        /// <summary>
        /// </summary>
        /// <param name="e"></param>
        /// <param name="context">Used to enqueue bytes for delivery.</param>
        /// <returns><c>true</c> if more buffers can be appened.</returns>
        public bool Write(WriterContext context)
        {
            if (_writeBytesLeftCorCurrentState != -1)
            {
                var bytesToCopy = Math.Min(_writeBuffer.Count, _writeBytesLeftCorCurrentState);
                bytesToCopy = Math.Min(bytesToCopy, context.BytesLeftToEnqueue);
                if (bytesToCopy < 10)
                {
                    return(false);
                }

                if (_payloadStream != null)
                {
                    _payloadStream.Write(_writeBuffer.Array, 0, bytesToCopy);
                }
                else
                {
                    Buffer.BlockCopy(_payloadBuffer.Array, _writePayloadBufferOffset, _writeBuffer.Array,
                                     _writeBuffer.Offset, bytesToCopy);
                }
                _writeBytesLeftCorCurrentState -= bytesToCopy;
                _writePayloadBufferOffset      += bytesToCopy;
                context.Enqueue(new ArraySegment <byte>(_writeBuffer.Array, _writeBuffer.Offset, bytesToCopy));
                if (_writeBytesLeftCorCurrentState == 0)
                {
                    return(true);
                }

                return(false);
            }

            _writeBuffer = context.DequeueBuffer();
            _writePayloadBufferOffset = 0;
            var offset        = _writeBuffer.Offset;
            var payloadLength = 0;

            if (_payloadStream != null)
            {
                _writeBuffer.Array[offset++] = _payloadStream.Length > byte.MaxValue
                    ? (byte)FrameFlags.LargeFrame
                    : (byte)0;
                payloadLength = (int)_payloadStream.Length;
            }
            else
            {
                _writeBuffer.Array[offset++] = PayloadBuffer.Count > byte.MaxValue
                    ? (byte)FrameFlags.LargeFrame
                    : (byte)0;
                payloadLength = PayloadBuffer.Count;
            }

            var buf = BitConverter.GetBytes(SequenceNumber);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(buf);
            }
            _writeBuffer.Array[offset++] = buf[0];
            _writeBuffer.Array[offset++] = buf[1];
            _writeBuffer.Array[offset++] = (byte)Destination.Length;
            if (Destination.Length > 0)
            {
                Encoding.ASCII.GetBytes(Destination, 0, Destination.Length, _writeBuffer.Array, offset);
                offset += Destination.Length;
            }

            if (_properties != null && _properties.Count > 0)
            {
                var filters   = EncodeFilters();
                var filterLen = BitConverter.GetBytes((short)filters.Length);
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(filterLen);
                }
                _writeBuffer.Array[offset++] = filterLen[0];
                _writeBuffer.Array[offset++] = filterLen[1];
                Encoding.ASCII.GetBytes(filters, 0, filters.Length, _writeBuffer.Array, offset);
                offset += filters.Length;
            }
            else
            {
                _writeBuffer.Array[offset++] = 0;
                _writeBuffer.Array[offset++] = 0;
            }

            //length
            if (payloadLength > byte.MaxValue)
            {
                buf = BitConverter.GetBytes(payloadLength);
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(buf);
                }
                _writeBuffer.Array[offset++] = buf[0];
                _writeBuffer.Array[offset++] = buf[1];
                _writeBuffer.Array[offset++] = buf[2];
                _writeBuffer.Array[offset++] = buf[3];
            }
            else
            {
                _writeBuffer.Array[offset++] = (byte)payloadLength;
            }


            _writeBytesLeftCorCurrentState = payloadLength;
            var payloadBytesToCopy = Math.Min(_writeBuffer.Count - (offset - _writeBuffer.Offset),
                                              _writeBytesLeftCorCurrentState);

            if (_payloadStream != null)
            {
                _payloadStream.Write(_writeBuffer.Array, offset, payloadBytesToCopy);
            }
            else
            {
                Buffer.BlockCopy(_payloadBuffer.Array, _writePayloadBufferOffset, _writeBuffer.Array, offset,
                                 payloadBytesToCopy);
            }
            payloadBytesToCopy              = Math.Min(payloadBytesToCopy, context.BytesLeftToEnqueue);
            _writeBytesLeftCorCurrentState -= payloadBytesToCopy;
            _writePayloadBufferOffset      += payloadBytesToCopy;
            var size = (offset - _writeBuffer.Offset) + payloadBytesToCopy;

            context.Enqueue(_writeBuffer.Array, _writeBuffer.Offset, size);

            if (_writeBytesLeftCorCurrentState == 0)
            {
                return(true);
            }
            return(false);
        }