123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- using System;
- using System.Runtime.CompilerServices;
- using System.Text;
- using Unity.Collections.LowLevel.Unsafe;
- using UnityEngine;
- namespace Mirror
- {
-
- public class NetworkWriter
- {
-
-
- public const ushort MaxStringLength = ushort.MaxValue - 1;
-
-
-
- public const int DefaultCapacity = 1500;
- internal byte[] buffer = new byte[DefaultCapacity];
-
- public int Position;
-
- public int Capacity => buffer.Length;
-
-
-
-
-
-
-
-
- internal readonly UTF8Encoding encoding = new UTF8Encoding(false, true);
-
-
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Reset()
- {
- Position = 0;
- }
-
-
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal void EnsureCapacity(int value)
- {
- if (buffer.Length < value)
- {
- int capacity = Math.Max(value, buffer.Length * 2);
- Array.Resize(ref buffer, capacity);
- }
- }
-
-
- public byte[] ToArray()
- {
- byte[] data = new byte[Position];
- Array.ConstrainedCopy(buffer, 0, data, 0, Position);
- return data;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public ArraySegment<byte> ToArraySegment() =>
- new ArraySegment<byte>(buffer, 0, Position);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static implicit operator ArraySegment<byte>(NetworkWriter w) =>
- w.ToArraySegment();
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- internal unsafe void WriteBlittable<T>(T value)
- where T : unmanaged
- {
-
- #if UNITY_EDITOR
- if (!UnsafeUtility.IsBlittable(typeof(T)))
- {
- Debug.LogError($"{typeof(T)} is not blittable!");
- return;
- }
- #endif
-
-
-
-
-
-
- int size = sizeof(T);
-
-
-
-
- EnsureCapacity(Position + size);
-
- fixed (byte* ptr = &buffer[Position])
- {
- #if UNITY_ANDROID
-
-
-
-
-
-
-
-
-
-
-
-
-
- T* valueBuffer = stackalloc T[1]{value};
- UnsafeUtility.MemCpy(ptr, valueBuffer, size);
- #else
-
- *(T*)ptr = value;
- #endif
- }
- Position += size;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal void WriteBlittableNullable<T>(T? value)
- where T : unmanaged
- {
-
- WriteByte((byte)(value.HasValue ? 0x01 : 0x00));
-
- if (value.HasValue)
- WriteBlittable(value.Value);
- }
- public void WriteByte(byte value) => WriteBlittable(value);
-
-
- public void WriteBytes(byte[] array, int offset, int count)
- {
- EnsureCapacity(Position + count);
- Array.ConstrainedCopy(array, offset, this.buffer, Position, count);
- Position += count;
- }
-
-
- public unsafe bool WriteBytes(byte* ptr, int offset, int size)
- {
- EnsureCapacity(Position + size);
- fixed (byte* destination = &buffer[Position])
- {
-
-
-
-
-
-
- UnsafeUtility.MemCpy(destination, ptr + offset, size);
- }
- Position += size;
- return true;
- }
-
- public void Write<T>(T value)
- {
- Action<NetworkWriter, T> writeDelegate = Writer<T>.write;
- if (writeDelegate == null)
- {
- Debug.LogError($"No writer found for {typeof(T)}. This happens either if you are missing a NetworkWriter extension for your custom type, or if weaving failed. Try to reimport a script to weave again.");
- }
- else
- {
- writeDelegate(this, value);
- }
- }
-
-
-
- public override string ToString() =>
- $"[{ToArraySegment().ToHexString()} @ {Position}/{Capacity}]";
- }
-
-
-
- public static class Writer<T>
- {
- public static Action<NetworkWriter, T> write;
- }
- }
|