| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 | using System;using MECF.Framework.Common.Communications.Tcp.Socket.Framing.Base;namespace MECF.Framework.Common.Communications.Tcp.Socket.Framing{    public enum LengthField    {        OneByte = 1,        TwoBytes = 2,        FourBytes = 4,        EigthBytes = 8,    }    public sealed class LengthFieldBasedFrameBuilder : FrameBuilder    {        public LengthFieldBasedFrameBuilder()            : this(LengthField.FourBytes)        {        }        public LengthFieldBasedFrameBuilder(LengthField lengthField)            : this(new LengthFieldBasedFrameEncoder(lengthField), new LengthFieldBasedFrameDecoder(lengthField))        {        }        public LengthFieldBasedFrameBuilder(LengthFieldBasedFrameEncoder encoder, LengthFieldBasedFrameDecoder decoder)            : base(encoder, decoder)        {        }    }    public sealed class LengthFieldBasedFrameEncoder : IFrameEncoder    {        public LengthFieldBasedFrameEncoder(LengthField lengthField)        {            LengthField = lengthField;        }        public LengthField LengthField { get; private set; }        public void EncodeFrame(byte[] payload, int offset, int count, out byte[] frameBuffer, out int frameBufferOffset, out int frameBufferLength)        {            byte[] buffer = null;            switch (this.LengthField)            {                case LengthField.OneByte:                    {                        if (count > byte.MaxValue)                        {                            throw new ArgumentOutOfRangeException("count");                        }                        buffer = new byte[1 + count];                        buffer[0] = (byte)count;                        Array.Copy(payload, offset, buffer, 1, count);                    }                    break;                case LengthField.TwoBytes:                    {                        if (count > short.MaxValue)                        {                            throw new ArgumentOutOfRangeException("count");                        }                        buffer = new byte[2 + count];                        buffer[0] = (byte)((ushort)count >> 8);                        buffer[1] = (byte)count;                        Array.Copy(payload, offset, buffer, 2, count);                    }                    break;                case LengthField.FourBytes:                    {                        buffer = new byte[4 + count];                        uint unsignedValue = (uint)count;                        buffer[0] = (byte)(unsignedValue >> 24);                        buffer[1] = (byte)(unsignedValue >> 16);                        buffer[2] = (byte)(unsignedValue >> 8);                        buffer[3] = (byte)unsignedValue;                        Array.Copy(payload, offset, buffer, 4, count);                    }                    break;                case LengthField.EigthBytes:                    {                        buffer = new byte[8 + count];                        ulong unsignedValue = (ulong)count;                        buffer[0] = (byte)(unsignedValue >> 56);                        buffer[1] = (byte)(unsignedValue >> 48);                        buffer[2] = (byte)(unsignedValue >> 40);                        buffer[3] = (byte)(unsignedValue >> 32);                        buffer[4] = (byte)(unsignedValue >> 24);                        buffer[5] = (byte)(unsignedValue >> 16);                        buffer[6] = (byte)(unsignedValue >> 8);                        buffer[7] = (byte)unsignedValue;                        Array.Copy(payload, offset, buffer, 8, count);                    }                    break;                default:                    throw new NotSupportedException("Specified length field is not supported.");            }            frameBuffer = buffer;            frameBufferOffset = 0;            frameBufferLength = buffer.Length;        }    }    public sealed class LengthFieldBasedFrameDecoder : IFrameDecoder    {        public LengthFieldBasedFrameDecoder(LengthField lengthField)        {            LengthField = lengthField;        }        public LengthField LengthField { 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;            byte[] output = null;            long length = 0;            switch (this.LengthField)            {                case LengthField.OneByte:                    {                        if (count < 1)                            return false;                        length = buffer[offset];                        if (count - 1 < length)                            return false;                        output = new byte[length];                        Array.Copy(buffer, offset + 1, output, 0, length);                    }                    break;                case LengthField.TwoBytes:                    {                        if (count < 2)                            return false;                        length = (short)(buffer[offset] << 8 | buffer[offset + 1]);                        if (count - 2 < length)                            return false;                        output = new byte[length];                        Array.Copy(buffer, offset + 2, output, 0, length);                    }                    break;                case LengthField.FourBytes:                    {                        if (count < 4)                            return false;                        length = buffer[offset] << 24 |                            buffer[offset + 1] << 16 |                            buffer[offset + 2] << 8 |                            buffer[offset + 3];                        if (count - 4 < length)                            return false;                        output = new byte[length];                        Array.Copy(buffer, offset + 4, output, 0, length);                    }                    break;                case LengthField.EigthBytes:                    {                        if (count < 8)                            return false;                        int i1 = buffer[offset] << 24 |                            buffer[offset + 1] << 16 |                            buffer[offset + 2] << 8 |                            buffer[offset + 3];                        int i2 = buffer[offset + 4] << 24 |                            buffer[offset + 5] << 16 |                            buffer[offset + 6] << 8 |                            buffer[offset + 7];                        length = (uint)i2 | ((long)i1 << 32);                        if (count - 8 < length)                            return false;                        output = new byte[length];                        Array.Copy(buffer, offset + 8, output, 0, length);                    }                    break;                default:                    throw new NotSupportedException("Specified length field is not supported.");            }            payload = output;            payloadOffset = 0;            payloadCount = output.Length;            frameLength = (int)this.LengthField + output.Length;            return true;        }    }}
 |