Refactored PayloadData.cs

This commit is contained in:
sta 2014-09-15 14:39:14 +09:00
parent 1b920993b7
commit dd25d1d0a4
2 changed files with 96 additions and 70 deletions

View File

@ -1341,37 +1341,74 @@ namespace WebSocketSharp
/// <summary> /// <summary>
/// Retrieves a sub-array from the specified <paramref name="array"/>. /// Retrieves a sub-array from the specified <paramref name="array"/>.
/// A sub-array starts at the specified element position. /// A sub-array starts at the specified element position in <paramref name="array"/>.
/// </summary> /// </summary>
/// <returns> /// <returns>
/// An array of T that receives a sub-array, or an empty array of T if any problems /// An array of T that receives a sub-array, or an empty array of T
/// with the parameters. /// if any problems with the parameters.
/// </returns> /// </returns>
/// <param name="array"> /// <param name="array">
/// An array of T that contains the data to retrieve a sub-array. /// An array of T from which to retrieve a sub-array.
/// </param> /// </param>
/// <param name="startIndex"> /// <param name="startIndex">
/// An <see cref="int"/> that contains the zero-based starting position of a sub-array /// An <see cref="int"/> that represents the zero-based starting position of
/// in <paramref name="array"/>. /// a sub-array in <paramref name="array"/>.
/// </param> /// </param>
/// <param name="length"> /// <param name="length">
/// An <see cref="int"/> that contains the number of elements to retrieve a sub-array. /// An <see cref="int"/> that represents the number of elements to retrieve.
/// </param> /// </param>
/// <typeparam name="T"> /// <typeparam name="T">
/// The type of elements in the <paramref name="array"/>. /// The type of elements in <paramref name="array"/>.
/// </typeparam> /// </typeparam>
public static T[] SubArray<T> (this T[] array, int startIndex, int length) public static T[] SubArray<T> (this T[] array, int startIndex, int length)
{ {
if (array == null || array.Length == 0) int len;
if (array == null || (len = array.Length) == 0)
return new T[0]; return new T[0];
if (startIndex < 0 || length <= 0) if (startIndex < 0 || length <= 0 || startIndex + length > len)
return new T[0]; return new T[0];
if (startIndex + length > array.Length) if (startIndex == 0 && length == len)
return array;
var subArray = new T[length];
Array.Copy (array, startIndex, subArray, 0, length);
return subArray;
}
/// <summary>
/// Retrieves a sub-array from the specified <paramref name="array"/>.
/// A sub-array starts at the specified element position in <paramref name="array"/>.
/// </summary>
/// <returns>
/// An array of T that receives a sub-array, or an empty array of T
/// if any problems with the parameters.
/// </returns>
/// <param name="array">
/// An array of T from which to retrieve a sub-array.
/// </param>
/// <param name="startIndex">
/// A <see cref="long"/> that represents the zero-based starting position of
/// a sub-array in <paramref name="array"/>.
/// </param>
/// <param name="length">
/// A <see cref="long"/> that represents the number of elements to retrieve.
/// </param>
/// <typeparam name="T">
/// The type of elements in <paramref name="array"/>.
/// </typeparam>
public static T[] SubArray<T> (this T[] array, long startIndex, long length)
{
long len;
if (array == null || (len = array.LongLength) == 0)
return new T[0]; return new T[0];
if (startIndex == 0 && array.Length == length) if (startIndex < 0 || length <= 0 || startIndex + length > len)
return new T[0];
if (startIndex == 0 && length == len)
return array; return array;
var subArray = new T[length]; var subArray = new T[length];

View File

@ -37,11 +37,11 @@ namespace WebSocketSharp
{ {
#region Private Fields #region Private Fields
private byte[] _appData; private byte[] _data;
private ulong _appDataLength; private static readonly byte[] _empty;
private byte[] _extData; private long _extDataLength;
private ulong _extDataLength; private long _length;
private bool _masked; private bool _masked;
#endregion #endregion
@ -51,49 +51,52 @@ namespace WebSocketSharp
#endregion #endregion
#region Static Constructor
static PayloadData ()
{
_empty = new byte[0];
}
#endregion
#region Internal Constructors #region Internal Constructors
internal PayloadData () internal PayloadData ()
: this (new byte[0], new byte[0], false) {
_data = _empty;
}
internal PayloadData (byte[] data)
: this (data, false)
{ {
} }
internal PayloadData (byte[] applicationData) internal PayloadData (byte[] data, bool masked)
: this (new byte[0], applicationData, false)
{ {
} _data = data;
internal PayloadData (string applicationData)
: this (new byte[0], Encoding.UTF8.GetBytes (applicationData), false)
{
}
internal PayloadData (byte[] applicationData, bool masked)
: this (new byte[0], applicationData, masked)
{
}
internal PayloadData (byte[] extensionData, byte[] applicationData, bool masked)
{
_extDataLength = (ulong) extensionData.LongLength;
_appDataLength = (ulong) applicationData.LongLength;
if (_appDataLength > MaxLength - _extDataLength)
throw new ArgumentOutOfRangeException (
"The total length of 'extensionData' and 'applicationData' is greater than the allowable length.");
_extData = extensionData;
_appData = applicationData;
_masked = masked; _masked = masked;
_length = data.LongLength;
} }
#endregion #endregion
#region Internal Properties #region Internal Properties
internal long ExtensionDataLength {
get {
return _extDataLength;
}
set {
_extDataLength = value;
}
}
internal bool IncludesReservedCloseStatusCode { internal bool IncludesReservedCloseStatusCode {
get { get {
return _appDataLength > 1 && return _length > 1 &&
_appData.SubArray (0, 2).ToUInt16 (ByteOrder.Big).IsReserved (); _data.SubArray (0, 2).ToUInt16 (ByteOrder.Big).IsReserved ();
} }
} }
@ -103,13 +106,17 @@ namespace WebSocketSharp
public byte[] ApplicationData { public byte[] ApplicationData {
get { get {
return _appData; return _extDataLength > 0
? _data.SubArray (_extDataLength, _length - _extDataLength)
: _data;
} }
} }
public byte[] ExtensionData { public byte[] ExtensionData {
get { get {
return _extData; return _extDataLength > 0
? _data.SubArray (0, _extDataLength)
: _empty;
} }
} }
@ -121,31 +128,18 @@ namespace WebSocketSharp
public ulong Length { public ulong Length {
get { get {
return _extDataLength + _appDataLength; return (ulong) _length;
} }
} }
#endregion #endregion
#region Private Methods
private static void mask (byte[] source, byte[] key)
{
for (long i = 0; i < source.LongLength; i++)
source[i] = (byte) (source[i] ^ key[i % 4]);
}
#endregion
#region Internal Methods #region Internal Methods
internal void Mask (byte[] key) internal void Mask (byte[] key)
{ {
if (_extDataLength > 0) for (long i = 0; i < _length; i++)
mask (_extData, key); _data[i] = (byte) (_data[i] ^ key[i % 4]);
if (_appDataLength > 0)
mask (_appData, key);
_masked = !_masked; _masked = !_masked;
} }
@ -156,23 +150,18 @@ namespace WebSocketSharp
public IEnumerator<byte> GetEnumerator () public IEnumerator<byte> GetEnumerator ()
{ {
foreach (var b in _extData) foreach (var b in _data)
yield return b;
foreach (var b in _appData)
yield return b; yield return b;
} }
public byte[] ToByteArray () public byte[] ToByteArray ()
{ {
return _extDataLength > 0 return _data;
? new List<byte> (this).ToArray ()
: _appData;
} }
public override string ToString () public override string ToString ()
{ {
return BitConverter.ToString (ToByteArray ()); return BitConverter.ToString (_data);
} }
#endregion #endregion