private void Deflate() { Debug.Assert(m_current.Position > 0); if (m_completedLast == null) { m_completedLast = new BufferSequenceSegment(WebSocketBase.Memory.Rent(WebSocketBase.DefaultSegmentSize), WebSocketBase.MaxHeaderSize); m_completedFirst = m_completedLast; } var compressableBytes = m_current.WrittenMemory.Span; while (compressableBytes.Length > 0) { if (m_completedLast.Available == 0) { m_completedLast = m_completedLast.Append(WebSocketBase.Memory.Rent(WebSocketBase.DefaultSegmentSize), 0); } m_deflater.Deflate(compressableBytes, m_completedLast.AvailableMemory.Span, out var consumed, out var written); m_completedLast.Advance(written); compressableBytes = compressableBytes.Slice(consumed); } // Move the current buffer to the start position m_current.Advance(-m_current.Position); }
private void Inflate() { if (m_inflater == null) { throw new WebSocketException("Message compression is not enabled."); } Debug.Assert(m_current.Position > 0); if (m_completed == null) { m_completed = new BufferSequenceSegment(WebSocketBase.Memory.Rent(WebSocketBase.DefaultSegmentSize), 0); } var inflatableBytes = m_current.WrittenMemory.Span; while (inflatableBytes.Length > 0) { if (m_completed.Available == 0) { m_completed = m_completed.Append(WebSocketBase.Memory.Rent(WebSocketBase.DefaultSegmentSize), 0); } m_inflater.Inflate(inflatableBytes, m_completed.AvailableMemory.Span, out var consumed, out var written); Length += written; m_completed.Advance(written); inflatableBytes = inflatableBytes.Slice(consumed); } // Reset the current buffer to the beginning. All bytes have been consumed (inflated). m_current.Advance(-m_current.Position); }
internal WebSocketMessage ToMessage(WebSocketMessageType messageType, WebSocketBase socket) { if (m_current.Position > 0) { if (m_deflater != null) { Deflate(); m_current.Reset(); } else { // No compression, just append the block for sending m_current.AppendTo(ref m_completedLast); if (m_completedFirst == null) { m_completedFirst = m_completedLast; } } } if (m_deflater != null && m_completedLast != null) { FinishDeflater(); } var offset = 0; var compressed = m_completedLast != null && m_deflater != null; if (socket.Native) { if (m_completedLast == null) { // The send procedure requires at least the message header m_completedLast = new BufferSequenceSegment(WebSocketBase.Memory.Rent(WebSocketBase.MaxHeaderSize), WebSocketBase.MaxHeaderSize); m_completedFirst = m_completedLast; } offset = WriteHeader(messageType, compressed, socket.IsServer()); if (!socket.IsServer()) { ApplyMask(); } } var message = m_completedFirst == null ? (WebSocketMessage) new WebSocketControlMessage(messageType, Array.Empty <Byte>()) : new WebSocketDataMessage(messageType, m_completedFirst, offset, compressed); m_completedFirst = null; m_completedLast = null; return(message); }
public WebSocketDataMessage(WebSocketMessageType type, BufferSequenceSegment start, Int32 startIndex, Boolean compressed) { Debug.Assert(start != null); m_next = start; m_nextStartIndex = startIndex; Type = type; Length = (Int32)Buffer.Length; Compressed = compressed; }
public Segment Add(BufferSequenceSegment buffer) { var segment = new Segment(buffer, 0) { RunningIndex = RunningIndex + Memory.Length }; Next = segment; if (buffer.Next == null) { return(segment); } return(segment.Add(buffer.Next)); }
public Segment(BufferSequenceSegment start, Int32 startIndex) { Memory = start.WrittenMemory.Slice(startIndex); }