|
| 1 | +using System; |
| 2 | +using System.Collections.Generic; |
| 3 | +using System.IO; |
| 4 | + |
| 5 | +namespace MLAPI.NetworkingManagerComponents |
| 6 | +{ |
| 7 | + public static class MessageChunker |
| 8 | + { |
| 9 | + public static List<byte[]> GetChunkedMessage(ref byte[] message, int chunkSize) |
| 10 | + { |
| 11 | + List<byte[]> chunks = new List<byte[]>((int)Math.Ceiling((double)message.Length / chunkSize)); |
| 12 | + //The extra 4 bytes is the chunkIndex |
| 13 | + byte[] chunk = new byte[chunkSize + 4]; |
| 14 | + |
| 15 | + for (int i = 0; i < message.Length; i++) |
| 16 | + { |
| 17 | + uint currentChunkIndex = (uint)Math.Floor((double)i / (double)chunkSize); |
| 18 | + int currentByteIndex = i % chunkSize; |
| 19 | + |
| 20 | + if (currentByteIndex == 0) |
| 21 | + { |
| 22 | + byte[] chunkIndexBytes = BitConverter.GetBytes(currentChunkIndex); |
| 23 | + if (BitConverter.IsLittleEndian) |
| 24 | + Array.Reverse(chunkIndexBytes); |
| 25 | + chunk[0] = chunkIndexBytes[0]; |
| 26 | + chunk[1] = chunkIndexBytes[1]; |
| 27 | + chunk[2] = chunkIndexBytes[2]; |
| 28 | + chunk[3] = chunkIndexBytes[3]; |
| 29 | + } |
| 30 | + chunk[4 + currentByteIndex] = message[i]; |
| 31 | + if(currentByteIndex == (chunkSize -1) || i == (message.Length -1)) |
| 32 | + { |
| 33 | + //This is the last byte in the chunk |
| 34 | + chunks.Add(chunk); |
| 35 | + } |
| 36 | + } |
| 37 | + return chunks; |
| 38 | + } |
| 39 | + |
| 40 | + public static byte[] GetMessageOrdered(ref List<byte[]> chunks, int chunkSize = -1) |
| 41 | + { |
| 42 | + if (chunks.Count == 0) |
| 43 | + return new byte[0]; |
| 44 | + if (chunkSize == -1) |
| 45 | + chunkSize = chunks[0].Length - 4; |
| 46 | + |
| 47 | + uint lastIndex = 0; |
| 48 | + uint messageSize = 0; |
| 49 | + for (int i = 0; i < chunks.Count; i++) |
| 50 | + { |
| 51 | + uint chunkIndex = BitConverter.ToUInt32(chunks[i], 0); |
| 52 | + if (chunkIndex <= lastIndex) |
| 53 | + throw new ArgumentException("Chunks not in order"); |
| 54 | + lastIndex = chunkIndex; |
| 55 | + messageSize += Convert.ToUInt32(chunks[i].Length - 4); |
| 56 | + } |
| 57 | + byte[] message = new byte[messageSize]; |
| 58 | + for (int i = 0; i < chunks.Count; i++) |
| 59 | + { |
| 60 | + Array.Copy(chunks[i], 3, message, i * chunkSize, chunkSize); |
| 61 | + } |
| 62 | + return message; |
| 63 | + } |
| 64 | + } |
| 65 | +} |
0 commit comments