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;
- }
- }
- }
|