99 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using FishNet.Serializing;
 | |
| using System;
 | |
| using UnityEngine;
 | |
| 
 | |
| namespace FishNet.Managing.Transporting
 | |
| {
 | |
| 
 | |
|     internal class SplitReader
 | |
|     {
 | |
|         #region Private.
 | |
|         /// <summary>
 | |
|         /// Tick split is for.
 | |
|         /// Tick must be a negative value so that it's impossible for the first tick to align.
 | |
|         /// </summary>
 | |
|         private long _tick = -1;
 | |
|         /// <summary>
 | |
|         /// Expected number of splits.
 | |
|         /// </summary>
 | |
|         private int _expectedMessages;
 | |
|         /// <summary>
 | |
|         /// Number of splits received so far.
 | |
|         /// </summary>
 | |
|         private ushort _receivedMessages;
 | |
|         /// <summary>
 | |
|         /// Writer containing split packet combined.
 | |
|         /// </summary>
 | |
|         private PooledWriter _writer = WriterPool.GetWriter();
 | |
|         #endregion
 | |
| 
 | |
|         internal SplitReader()
 | |
|         {
 | |
|             //Increase capacity to reduce the chance of resizing.
 | |
|             _writer.EnsureBufferCapacity(20000);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets split header values.
 | |
|         /// </summary>
 | |
|         internal void GetHeader(PooledReader reader, out int expectedMessages)
 | |
|         {
 | |
|             expectedMessages = reader.ReadInt32();
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Combines split data.
 | |
|         /// </summary>
 | |
|         internal void Write(uint tick, PooledReader reader, int expectedMessages)
 | |
|         {
 | |
|             //New tick which means new split.
 | |
|             if (tick != _tick)
 | |
|                 Reset(tick, expectedMessages);
 | |
| 
 | |
|             /* This is just a guess as to how large the end
 | |
|              * message could be. If the writer is not the minimum
 | |
|              * of this length then resize it. */
 | |
|             int estimatedBufferSize = (expectedMessages * 1500);
 | |
|             if (_writer.Capacity < estimatedBufferSize)
 | |
|                 _writer.EnsureBufferCapacity(estimatedBufferSize);
 | |
|             /* Empty remainder of reader into the writer.
 | |
|              * It does not matter if parts of the reader
 | |
|              * contain data added after the split because
 | |
|              * once the split is fully combined the data
 | |
|              * is parsed as though it came in as one message,
 | |
|              * which is how data is normally read. */
 | |
|             ArraySegment<byte> data = reader.ReadArraySegment(reader.Remaining);
 | |
|             _writer.WriteArraySegment(data);
 | |
|             _receivedMessages++;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Returns if all split messages have been received.
 | |
|         /// </summary>
 | |
|         /// <returns></returns>
 | |
|         internal ArraySegment<byte> GetFullMessage()
 | |
|         {
 | |
|             if (_receivedMessages < _expectedMessages)
 | |
|             {
 | |
|                 return default(ArraySegment<byte>);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 ArraySegment<byte> segment = _writer.GetArraySegment();
 | |
|                 Reset();
 | |
|                 return segment;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void Reset(uint tick = 0, int expectedMessages = 0)
 | |
|         {
 | |
|             _tick = tick;
 | |
|             _receivedMessages = 0;
 | |
|             _expectedMessages = expectedMessages;
 | |
|             _writer.Reset();
 | |
|         }
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
| } |