using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SuperSocket.SocketBase.Command;
using SuperWebSocket.Protocol;
namespace SuperWebSocket.Command
{
///
/// FragmentCommand
///
/// The type of the web socket session.
abstract class FragmentCommand : CommandBase
where TWebSocketSession : WebSocketSession, new()
{
///
/// Gets the UTF8 encoding which has been set ExceptionFallback.
///
protected Encoding Utf8Encoding { get; private set; }
///
/// Initializes a new instance of the class.
///
public FragmentCommand()
{
Utf8Encoding = Encoding.GetEncoding(65001, EncoderFallback.ExceptionFallback, DecoderFallback.ExceptionFallback);
}
///
/// Checks the frame.
///
/// The frame.
///
protected bool CheckFrame(WebSocketDataFrame frame)
{
//Check RSV
return (frame.InnerData[0] & 0x70) == 0x00;
}
///
/// Checks the control frame.
///
/// The frame.
///
protected bool CheckControlFrame(WebSocketDataFrame frame)
{
if (!CheckFrame(frame))
return false;
//http://tools.ietf.org/html/rfc6455#section-5.5
//All control frames MUST have a payload length of 125 bytes or less and MUST NOT be fragmented
if (!frame.FIN || frame.ActualPayloadLength > 125)
{
return false;
}
return true;
}
///
/// Gets data from websocket frames.
///
/// The frames.
///
protected byte[] GetWebSocketData(IList frames)
{
int offset, length;
var resultBuffer = new byte[frames.Sum(f => (int)f.ActualPayloadLength)];
int copied = 0;
for (var i = 0; i < frames.Count; i++)
{
var frame = frames[i];
offset = frame.InnerData.Count - (int)frame.ActualPayloadLength;
length = (int)frame.ActualPayloadLength;
if (length > 0)
{
if (frame.HasMask)
{
frame.InnerData.DecodeMask(frame.MaskKey, offset, length);
}
frame.InnerData.CopyTo(resultBuffer, offset, copied, length);
copied += length;
}
}
return resultBuffer;
}
///
/// Gets text string from websocket frames.
///
/// The frames.
///
protected string GetWebSocketText(IList frames)
{
var data = GetWebSocketData(frames);
return Utf8Encoding.GetString(data);
}
///
/// Gets data from a websocket frame.
///
/// The frame.
///
protected byte[] GetWebSocketData(WebSocketDataFrame frame)
{
int offset = frame.InnerData.Count - (int)frame.ActualPayloadLength;
int length = (int)frame.ActualPayloadLength;
if (frame.HasMask && length > 0)
{
frame.InnerData.DecodeMask(frame.MaskKey, offset, length);
}
byte[] data;
if (length > 0)
data = frame.InnerData.ToArrayData(offset, length);
else
data = new byte[0];
return data;
}
///
/// Gets text string from a websocket frame.
///
/// The frame.
///
protected string GetWebSocketText(WebSocketDataFrame frame)
{
int offset = frame.InnerData.Count - (int)frame.ActualPayloadLength;
int length = (int)frame.ActualPayloadLength;
if (frame.HasMask && length > 0)
{
frame.InnerData.DecodeMask(frame.MaskKey, offset, length);
}
string text;
if (length > 0)
{
text = frame.InnerData.Decode(Utf8Encoding, offset, length);
}
else
{
text = string.Empty;
}
return text;
}
}
}