public static int WritePacketHeader(byte[] packetBuffer, byte channelID, ushort sequence, ushort ack, uint ackBits) { using (ByteArrayReaderWriter byteArrayReaderWriter = ByteArrayReaderWriter.Get(packetBuffer)) { byte b = 0; if ((ackBits & 0xFF) != 255) { b = (byte)(b | 2); } if ((ackBits & 0xFF00) != 65280) { b = (byte)(b | 4); } if ((ackBits & 0xFF0000) != 16711680) { b = (byte)(b | 8); } if (((int)ackBits & -16777216) != -16777216) { b = (byte)(b | 0x10); } int num = sequence - ack; if (num < 0) { num += 65536; } if (num <= 255) { b = (byte)(b | 0x20); } byteArrayReaderWriter.Write(b); byteArrayReaderWriter.Write(channelID); byteArrayReaderWriter.Write(sequence); if (num <= 255) { byteArrayReaderWriter.Write((byte)num); } else { byteArrayReaderWriter.Write(ack); } if ((ackBits & 0xFF) != 255) { byteArrayReaderWriter.Write((byte)(ackBits & 0xFF)); } if ((ackBits & 0xFF00) != 65280) { byteArrayReaderWriter.Write((byte)((ackBits & 0xFF00) >> 8)); } if ((ackBits & 0xFF0000) != 16711680) { byteArrayReaderWriter.Write((byte)((ackBits & 0xFF0000) >> 16)); } if (((int)ackBits & -16777216) != -16777216) { byteArrayReaderWriter.Write((byte)((uint)((int)ackBits & -16777216) >> 24)); } return((int)byteArrayReaderWriter.WritePosition); } }
public static void Release(ByteArrayReaderWriter reader) { lock (readerPool) { readerPool.Enqueue(reader); } }
public static int WriteAckPacket(byte[] packetBuffer, byte channelID, ushort ack, uint ackBits) { using (var writer = ByteArrayReaderWriter.Get(packetBuffer)) { byte prefixByte = 0x80; // top bit set, indicates ack packet if ((ackBits & 0x000000FF) != 0x000000FF) { prefixByte |= (1 << 1); } if ((ackBits & 0x0000FF00) != 0x0000FF00) { prefixByte |= (1 << 2); } if ((ackBits & 0x00FF0000) != 0x00FF0000) { prefixByte |= (1 << 3); } if ((ackBits & 0xFF000000) != 0xFF000000) { prefixByte |= (1 << 4); } writer.Write(prefixByte); writer.Write(channelID); writer.Write(ack); if ((ackBits & 0x000000FF) != 0x000000FF) { writer.Write((byte)((ackBits & 0x000000FF))); } if ((ackBits & 0x0000FF00) != 0x0000FF00) { writer.Write((byte)((ackBits & 0x0000FF00) >> 8)); } if ((ackBits & 0x00FF0000) != 0x00FF0000) { writer.Write((byte)((ackBits & 0x00FF0000) >> 16)); } if ((ackBits & 0xFF000000) != 0xFF000000) { writer.Write((byte)((ackBits & 0xFF000000) >> 24)); } return((int)writer.WritePosition); } }
public static ByteArrayReaderWriter Get(byte[] byteArray) { ByteArrayReaderWriter byteArrayReaderWriter = null; lock (readerPool) { byteArrayReaderWriter = ((readerPool.Count <= 0) ? new ByteArrayReaderWriter() : readerPool.Dequeue()); } byteArrayReaderWriter.SetStream(byteArray); return(byteArrayReaderWriter); }
public static int ReadFragmentHeader(byte[] packetBuffer, int offset, int bufferLength, int maxFragments, int fragmentSize, out int fragmentID, out int numFragments, out int fragmentBytes, out ushort sequence, out ushort ack, out uint ackBits, out byte channelID) { if (bufferLength < 6) { throw new FormatException("Buffer too small for packet header"); } using (ByteArrayReaderWriter byteArrayReaderWriter = ByteArrayReaderWriter.Get(packetBuffer)) { byte b = byteArrayReaderWriter.ReadByte(); if ((b & 1) != 1) { throw new FormatException("Packet header indicates non-fragment packet"); } channelID = byteArrayReaderWriter.ReadByte(); sequence = byteArrayReaderWriter.ReadUInt16(); fragmentID = byteArrayReaderWriter.ReadByte(); numFragments = byteArrayReaderWriter.ReadByte() + 1; if (numFragments > maxFragments) { throw new FormatException("Packet header indicates fragments outside of max range"); } if (fragmentID >= numFragments) { throw new FormatException("Packet header indicates fragment ID outside of fragment count"); } fragmentBytes = bufferLength - 6; ushort sequence2 = 0; ushort ack2 = 0; uint ackBits2 = 0u; byte channelID2 = 0; if (fragmentID == 0) { int num = ReadPacketHeader(packetBuffer, 6, bufferLength, out channelID2, out sequence2, out ack2, out ackBits2); if (sequence2 != sequence) { throw new FormatException("Bad packet sequence in fragment"); } fragmentBytes = bufferLength - num - 6; } ack = ack2; ackBits = ackBits2; if (fragmentBytes > fragmentSize) { throw new FormatException("Fragment bytes remaining > indicated fragment size"); } if (fragmentID != numFragments - 1 && fragmentBytes != fragmentSize) { throw new FormatException("Fragment size invalid"); } return((int)byteArrayReaderWriter.ReadPosition - offset); } }
/// <summary> /// Get a reader/writer for the given byte array /// </summary> public static ByteArrayReaderWriter Get(byte[] byteArray) { ByteArrayReaderWriter reader = null; if (readerPool.Count > 0) { reader = readerPool.Dequeue(); } else { reader = new ByteArrayReaderWriter(); } reader.SetStream(byteArray); return(reader); }
public static int WriteAckPacket(byte[] packetBuffer, byte channelID, ushort ack, uint ackBits) { using (ByteArrayReaderWriter byteArrayReaderWriter = ByteArrayReaderWriter.Get(packetBuffer)) { byte b = 128; if ((ackBits & 0xFF) != 255) { b = (byte)(b | 2); } if ((ackBits & 0xFF00) != 65280) { b = (byte)(b | 4); } if ((ackBits & 0xFF0000) != 16711680) { b = (byte)(b | 8); } if (((int)ackBits & -16777216) != -16777216) { b = (byte)(b | 0x10); } byteArrayReaderWriter.Write(b); byteArrayReaderWriter.Write(channelID); byteArrayReaderWriter.Write(ack); if ((ackBits & 0xFF) != 255) { byteArrayReaderWriter.Write((byte)(ackBits & 0xFF)); } if ((ackBits & 0xFF00) != 65280) { byteArrayReaderWriter.Write((byte)((ackBits & 0xFF00) >> 8)); } if ((ackBits & 0xFF0000) != 16711680) { byteArrayReaderWriter.Write((byte)((ackBits & 0xFF0000) >> 16)); } if (((int)ackBits & -16777216) != -16777216) { byteArrayReaderWriter.Write((byte)((uint)((int)ackBits & -16777216) >> 24)); } return((int)byteArrayReaderWriter.WritePosition); } }
public static int WritePacketHeader(byte[] packetBuffer, byte channelID, ushort sequence, ushort ack, uint ackBits) { using (var writer = ByteArrayReaderWriter.Get(packetBuffer)) { byte prefixByte = 0; if ((ackBits & 0x000000FF) != 0x000000FF) { prefixByte |= (1 << 1); } if ((ackBits & 0x0000FF00) != 0x0000FF00) { prefixByte |= (1 << 2); } if ((ackBits & 0x00FF0000) != 0x00FF0000) { prefixByte |= (1 << 3); } if ((ackBits & 0xFF000000) != 0xFF000000) { prefixByte |= (1 << 4); } int sequenceDiff = sequence - ack; if (sequenceDiff < 0) { sequenceDiff += 65536; } if (sequenceDiff <= 255) { prefixByte |= (1 << 5); } writer.Write(prefixByte); writer.Write(channelID); writer.Write(sequence); if (sequenceDiff <= 255) { writer.Write((byte)sequenceDiff); } else { writer.Write(ack); } if ((ackBits & 0x000000FF) != 0x000000FF) { writer.Write((byte)((ackBits & 0x000000FF))); } if ((ackBits & 0x0000FF00) != 0x0000FF00) { writer.Write((byte)((ackBits & 0x0000FF00) >> 8)); } if ((ackBits & 0x00FF0000) != 0x00FF0000) { writer.Write((byte)((ackBits & 0x00FF0000) >> 16)); } if ((ackBits & 0xFF000000) != 0xFF000000) { writer.Write((byte)((ackBits & 0xFF000000) >> 24)); } return((int)writer.WritePosition); } }
public static int ReadPacketHeader(byte[] packetBuffer, int offset, int bufferLength, out byte channelID, out ushort sequence, out ushort ack, out uint ackBits) { if (bufferLength < 4) { throw new FormatException("Buffer too small for packet header"); } using (var reader = ByteArrayReaderWriter.Get(packetBuffer)) { reader.SeekRead(offset); byte prefixByte = reader.ReadByte(); if ((prefixByte & 1) != 0) { throw new InvalidOperationException("Header does not indicate regular packet"); } channelID = reader.ReadByte(); // ack packets don't have sequence numbers if ((prefixByte & 0x80) == 0) { sequence = reader.ReadUInt16(); } else { sequence = 0; } if ((prefixByte & (1 << 5)) != 0) { if (bufferLength < 2 + 1) { throw new FormatException("Buffer too small for packet header"); } byte sequenceDiff = reader.ReadByte(); ack = (ushort)(sequence - sequenceDiff); } else { if (bufferLength < 2 + 2) { throw new FormatException("Buffer too small for packet header"); } ack = reader.ReadUInt16(); } int expectedBytes = 0; for (int i = 0; i <= 4; i++) { if ((prefixByte & (1 << i)) != 0) { expectedBytes++; } } if (bufferLength < (bufferLength - reader.ReadPosition) + expectedBytes) { throw new FormatException("Buffer too small for packet header"); } ackBits = 0xFFFFFFFF; if ((prefixByte & (1 << 1)) != 0) { ackBits &= 0xFFFFFF00; ackBits |= reader.ReadByte(); } if ((prefixByte & (1 << 2)) != 0) { ackBits &= 0xFFFF00FF; ackBits |= (uint)(reader.ReadByte() << 8); } if ((prefixByte & (1 << 3)) != 0) { ackBits &= 0xFF00FFFF; ackBits |= (uint)(reader.ReadByte() << 16); } if ((prefixByte & (1 << 4)) != 0) { ackBits &= 0x00FFFFFF; ackBits |= (uint)(reader.ReadByte() << 24); } return((int)reader.ReadPosition - offset); } }
public static int ReadFragmentHeader(byte[] packetBuffer, int offset, int bufferLength, int maxFragments, int fragmentSize, out int fragmentID, out int numFragments, out int fragmentBytes, out ushort sequence, out ushort ack, out uint ackBits, out byte channelID) { if (bufferLength < Defines.FRAGMENT_HEADER_BYTES) { throw new FormatException("Buffer too small for packet header"); } using (var reader = ByteArrayReaderWriter.Get(packetBuffer)) { byte prefixByte = reader.ReadByte(); if (prefixByte != 1) { throw new FormatException("Packet header indicates non-fragment packet"); } channelID = reader.ReadByte(); sequence = reader.ReadUInt16(); fragmentID = reader.ReadByte(); numFragments = reader.ReadByte() + 1; if (numFragments > maxFragments) { throw new FormatException("Packet header indicates fragments outside of max range"); } if (fragmentID >= numFragments) { throw new FormatException("Packet header indicates fragment ID outside of fragment count"); } fragmentBytes = bufferLength - Defines.FRAGMENT_HEADER_BYTES; ushort packetSequence = 0; ushort packetAck = 0; uint packetAckBits = 0; byte packetChannelID = 0; if (fragmentID == 0) { int packetHeaderBytes = ReadPacketHeader(packetBuffer, Defines.FRAGMENT_HEADER_BYTES, bufferLength, out packetChannelID, out packetSequence, out packetAck, out packetAckBits); if (packetSequence != sequence) { throw new FormatException("Bad packet sequence in fragment"); } fragmentBytes = bufferLength - packetHeaderBytes - Defines.FRAGMENT_HEADER_BYTES; } ack = packetAck; ackBits = packetAckBits; if (fragmentBytes > fragmentSize) { throw new FormatException("Fragment bytes remaining > indicated fragment size"); } if (fragmentID != numFragments - 1 && fragmentBytes != fragmentSize) { throw new FormatException("Fragment size invalid"); } return((int)reader.ReadPosition - offset); } }
public static int ReadPacketHeader(byte[] packetBuffer, int offset, int bufferLength, out byte channelID, out ushort sequence, out ushort ack, out uint ackBits) { if (bufferLength < 4) { throw new FormatException("Buffer too small for packet header"); } using (ByteArrayReaderWriter byteArrayReaderWriter = ByteArrayReaderWriter.Get(packetBuffer)) { byteArrayReaderWriter.SeekRead(offset); byte b = byteArrayReaderWriter.ReadByte(); if ((b & 1) != 0) { throw new InvalidOperationException("Header does not indicate regular packet"); } channelID = byteArrayReaderWriter.ReadByte(); if ((b & 0x80) == 0) { sequence = byteArrayReaderWriter.ReadUInt16(); } else { sequence = 0; } if ((b & 0x20) != 0) { if (bufferLength < 3) { throw new FormatException("Buffer too small for packet header"); } byte b2 = byteArrayReaderWriter.ReadByte(); ack = (ushort)(sequence - b2); } else { if (bufferLength < 4) { throw new FormatException("Buffer too small for packet header"); } ack = byteArrayReaderWriter.ReadUInt16(); } int num = 0; for (int i = 0; i <= 4; i++) { if ((b & (1 << i)) != 0) { num++; } } if (bufferLength < bufferLength - byteArrayReaderWriter.ReadPosition + num) { throw new FormatException("Buffer too small for packet header"); } ackBits = uint.MaxValue; if ((b & 2) != 0) { ackBits &= 4294967040u; ackBits |= byteArrayReaderWriter.ReadByte(); } if ((b & 4) != 0) { ackBits &= 4294902015u; ackBits |= (uint)(byteArrayReaderWriter.ReadByte() << 8); } if ((b & 8) != 0) { ackBits &= 4278255615u; ackBits |= (uint)(byteArrayReaderWriter.ReadByte() << 16); } if ((b & 0x10) != 0) { ackBits &= 16777215u; ackBits |= (uint)(byteArrayReaderWriter.ReadByte() << 24); } return((int)byteArrayReaderWriter.ReadPosition - offset); } }