private int WriteFrameToSendBuffer(MessageOpcode opcode, bool endOfMessage, ArraySegment<byte> payloadBuffer)
{
// Grow our send buffer as needed. We reuse the buffer for all messages, with it protected by the send frame lock.
EnsureBufferLength(ref _sendBuffer, payloadBuffer.Count + MaxMessageHeaderLength);
// Write the message header data to the buffer.
int headerLength;
int? maskOffset = null;
if (_isServer)
{
// The server doesn't send a mask, so the mask offset returned by WriteHeader
// is actually the end of the header.
headerLength = WriteHeader(opcode, _sendBuffer, payloadBuffer, endOfMessage, useMask: false);
}
else
{
// We need to know where the mask starts so that we can use the mask to manipulate the payload data,
// and we need to know the total length for sending it on the wire.
maskOffset = WriteHeader(opcode, _sendBuffer, payloadBuffer, endOfMessage, useMask: true);
headerLength = maskOffset.GetValueOrDefault() + MaskLength;
}
// Write the payload
if (payloadBuffer.Count > 0)
{
Buffer.BlockCopy(payloadBuffer.Array, payloadBuffer.Offset, _sendBuffer, headerLength, payloadBuffer.Count);
// If we added a mask to the header, XOR the payload with the mask. We do the manipulation in the send buffer so as to avoid
// changing the data in the caller-supplied payload buffer.
if (maskOffset.HasValue)
{
ApplyMask(_sendBuffer, headerLength, _sendBuffer, maskOffset.Value, 0, payloadBuffer.Count);
}
}
// Return the number of bytes in the send buffer
return headerLength + payloadBuffer.Count;
}