| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 | 
							- using System;
 
- using MECF.Framework.Common.Communications.Tcp.Socket.Framing.Base;
 
- namespace MECF.Framework.Common.Communications.Tcp.Socket.Framing
 
- {
 
-     // A high-level overview of the framing is given in the following figure. 
 
-     //  0                   1                   2                   3
 
-     //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 
-     // +-+-------------+-----------------------------------------------+
 
-     // |M| Payload len |    Extended payload length                    |
 
-     // |A|     (7)     |             (16/64)                           |
 
-     // |S|             |   (if payload len==126/127)                   |
 
-     // |K|             |                                               |
 
-     // +-+-------------+- - - - - - - - - - - - - - - - - - - - - - - -+
 
-     // |     Extended payload length continued, if payload len == 127  |
 
-     // + - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - +
 
-     // |               |    Masking-key, if MASK set to 1              |
 
-     // +---------------+- - - - - - - - - - - - - - - - - - - - - - - -+
 
-     // |               |          Payload Data                         :
 
-     // +----------------- - - - - - - - - - - - - - - - - - - - - - - -+
 
-     // :                     Payload Data continued ...                :
 
-     // + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
 
-     // |                     Payload Data continued ...                |
 
-     // +---------------------------------------------------------------+
 
-     public sealed class LengthPrefixedFrameBuilder : FrameBuilder
 
-     {
 
-         public LengthPrefixedFrameBuilder(bool isMasked = false)
 
-             : this(new LengthPrefixedFrameEncoder(isMasked), new LengthPrefixedFrameDecoder(isMasked))
 
-         {
 
-         }
 
-         public LengthPrefixedFrameBuilder(LengthPrefixedFrameEncoder encoder, LengthPrefixedFrameDecoder decoder)
 
-             : base(encoder, decoder)
 
-         {
 
-         }
 
-     }
 
-     public sealed class LengthPrefixedFrameEncoder : IFrameEncoder
 
-     {
 
-         private static readonly Random _rng = new Random(DateTime.UtcNow.Millisecond);
 
-         private static readonly int MaskingKeyLength = 4;
 
-         public LengthPrefixedFrameEncoder(bool isMasked = false)
 
-         {
 
-             IsMasked = isMasked;
 
-         }
 
-         public bool IsMasked { get; private set; }
 
-         public void EncodeFrame(byte[] payload, int offset, int count, out byte[] frameBuffer, out int frameBufferOffset, out int frameBufferLength)
 
-         {
 
-             var buffer = Encode(payload, offset, count, IsMasked);
 
-             frameBuffer = buffer;
 
-             frameBufferOffset = 0;
 
-             frameBufferLength = buffer.Length;
 
-         }
 
-         private static byte[] Encode(byte[] payload, int offset, int count, bool isMasked = false)
 
-         {
 
-             byte[] fragment;
 
-             // Payload length:  7 bits, 7+16 bits, or 7+64 bits.
 
-             // The length of the "Payload data", in bytes: 
 
-             // if 0-125, that is the payload length.  
 
-             // If 126, the following 2 bytes interpreted as a 16-bit unsigned integer are the payload length.  
 
-             // If 127, the following 8 bytes interpreted as a 64-bit unsigned integer are the payload length.
 
-             if (count < 126)
 
-             {
 
-                 fragment = new byte[1 + (isMasked ? MaskingKeyLength : 0) + count];
 
-                 fragment[0] = (byte)count;
 
-             }
 
-             else if (count < 65536)
 
-             {
 
-                 fragment = new byte[1 + 2 + (isMasked ? MaskingKeyLength : 0) + count];
 
-                 fragment[0] = (byte)126;
 
-                 fragment[1] = (byte)(count / 256);
 
-                 fragment[2] = (byte)(count % 256);
 
-             }
 
-             else
 
-             {
 
-                 fragment = new byte[1 + 8 + (isMasked ? MaskingKeyLength : 0) + count];
 
-                 fragment[0] = (byte)127;
 
-                 int left = count;
 
-                 for (int i = 8; i > 0; i--)
 
-                 {
 
-                     fragment[i] = (byte)(left % 256);
 
-                     left = left / 256;
 
-                     if (left == 0)
 
-                         break;
 
-                 }
 
-             }
 
-             // Mask:  1 bit
 
-             // Defines whether the "Payload data" is masked.
 
-             if (isMasked)
 
-                 fragment[0] = (byte)(fragment[0] | 0x80);
 
-             // Masking-key:  0 or 4 bytes
 
-             // The masking key is a 32-bit value chosen at random by the client.
 
-             if (isMasked)
 
-             {
 
-                 int maskingKeyIndex = fragment.Length - (MaskingKeyLength + count);
 
-                 for (var i = maskingKeyIndex; i < maskingKeyIndex + MaskingKeyLength; i++)
 
-                 {
 
-                     fragment[i] = (byte)_rng.Next(0, 255);
 
-                 }
 
-                 if (count > 0)
 
-                 {
 
-                     int payloadIndex = fragment.Length - count;
 
-                     for (var i = 0; i < count; i++)
 
-                     {
 
-                         fragment[payloadIndex + i] = (byte)(payload[offset + i] ^ fragment[maskingKeyIndex + i % MaskingKeyLength]);
 
-                     }
 
-                 }
 
-             }
 
-             else
 
-             {
 
-                 if (count > 0)
 
-                 {
 
-                     int payloadIndex = fragment.Length - count;
 
-                     Array.Copy(payload, offset, fragment, payloadIndex, count);
 
-                 }
 
-             }
 
-             return fragment;
 
-         }
 
-     }
 
-     public sealed class LengthPrefixedFrameDecoder : IFrameDecoder
 
-     {
 
-         private static readonly int MaskingKeyLength = 4;
 
-         public LengthPrefixedFrameDecoder(bool isMasked = false)
 
-         {
 
-             IsMasked = isMasked;
 
-         }
 
-         public bool IsMasked { get; private set; }
 
-         public bool TryDecodeFrame(byte[] buffer, int offset, int count, out int frameLength, out byte[] payload, out int payloadOffset, out int payloadCount)
 
-         {
 
-             frameLength = 0;
 
-             payload = null;
 
-             payloadOffset = 0;
 
-             payloadCount = 0;
 
-             var frameHeader = DecodeHeader(buffer, offset, count);
 
-             if (frameHeader != null && frameHeader.Length + frameHeader.PayloadLength <= count)
 
-             {
 
-                 if (IsMasked)
 
-                 {
 
-                     payload = DecodeMaskedPayload(buffer, offset, frameHeader.MaskingKeyOffset, frameHeader.Length, frameHeader.PayloadLength);
 
-                     payloadOffset = 0;
 
-                     payloadCount = payload.Length;
 
-                 }
 
-                 else
 
-                 {
 
-                     payload = buffer;
 
-                     payloadOffset = offset + frameHeader.Length;
 
-                     payloadCount = frameHeader.PayloadLength;
 
-                 }
 
-                 frameLength = frameHeader.Length + frameHeader.PayloadLength;
 
-                 return true;
 
-             }
 
-             return false;
 
-         }
 
-         internal sealed class Header
 
-         {
 
-             public bool IsMasked { get; set; }
 
-             public int PayloadLength { get; set; }
 
-             public int MaskingKeyOffset { get; set; }
 
-             public int Length { get; set; }
 
-             public override string ToString()
 
-             {
 
-                 return string.Format("IsMasked[{0}], PayloadLength[{1}], MaskingKeyOffset[{2}], Length[{3}]",
 
-                     IsMasked, PayloadLength, MaskingKeyOffset, Length);
 
-             }
 
-         }
 
-         private static Header DecodeHeader(byte[] buffer, int offset, int count)
 
-         {
 
-             if (count < 1)
 
-                 return null;
 
-             // parse fixed header
 
-             var header = new Header()
 
-             {
 
-                 IsMasked = ((buffer[offset + 0] & 0x80) == 0x80),
 
-                 PayloadLength = (buffer[offset + 0] & 0x7f),
 
-                 Length = 1,
 
-             };
 
-             // parse extended payload length
 
-             if (header.PayloadLength >= 126)
 
-             {
 
-                 if (header.PayloadLength == 126)
 
-                     header.Length += 2;
 
-                 else
 
-                     header.Length += 8;
 
-                 if (count < header.Length)
 
-                     return null;
 
-                 if (header.PayloadLength == 126)
 
-                 {
 
-                     header.PayloadLength = buffer[offset + 1] * 256 + buffer[offset + 2];
 
-                 }
 
-                 else
 
-                 {
 
-                     int totalLength = 0;
 
-                     int level = 1;
 
-                     for (int i = 7; i >= 0; i--)
 
-                     {
 
-                         totalLength += buffer[offset + i + 1] * level;
 
-                         level *= 256;
 
-                     }
 
-                     header.PayloadLength = totalLength;
 
-                 }
 
-             }
 
-             // parse masking key
 
-             if (header.IsMasked)
 
-             {
 
-                 if (count < header.Length + MaskingKeyLength)
 
-                     return null;
 
-                 header.MaskingKeyOffset = header.Length;
 
-                 header.Length += MaskingKeyLength;
 
-             }
 
-             return header;
 
-         }
 
-         private static byte[] DecodeMaskedPayload(byte[] buffer, int offset, int maskingKeyOffset, int payloadOffset, int payloadCount)
 
-         {
 
-             var payload = new byte[payloadCount];
 
-             for (var i = 0; i < payloadCount; i++)
 
-             {
 
-                 payload[i] = (byte)(buffer[offset + payloadOffset + i] ^ buffer[offset + maskingKeyOffset + i % MaskingKeyLength]);
 
-             }
 
-             return payload;
 
-         }
 
-     }
 
- }
 
 
  |