From d2b7b541c865f8f86c967e0c02111b351b76d797 Mon Sep 17 00:00:00 2001 From: ALEXTANG <574809918@qq.com> Date: Thu, 4 Aug 2022 15:03:38 +0800 Subject: [PATCH] Update LoopBuffer.cs Update LoopBuffer.cs --- Assets/TEngine/Runtime/Net/LoopBuffer.meta | 8 + .../TEngine/Runtime/Net/LoopBuffer/Buffer.cs | 111 +++++++++ .../Runtime/Net/LoopBuffer/Buffer.cs.meta | 11 + .../Runtime/Net/LoopBuffer/LoopBuffer.cs | 223 ++++++++++++++++++ .../Runtime/Net/LoopBuffer/LoopBuffer.cs.meta | 11 + 5 files changed, 364 insertions(+) create mode 100644 Assets/TEngine/Runtime/Net/LoopBuffer.meta create mode 100644 Assets/TEngine/Runtime/Net/LoopBuffer/Buffer.cs create mode 100644 Assets/TEngine/Runtime/Net/LoopBuffer/Buffer.cs.meta create mode 100644 Assets/TEngine/Runtime/Net/LoopBuffer/LoopBuffer.cs create mode 100644 Assets/TEngine/Runtime/Net/LoopBuffer/LoopBuffer.cs.meta diff --git a/Assets/TEngine/Runtime/Net/LoopBuffer.meta b/Assets/TEngine/Runtime/Net/LoopBuffer.meta new file mode 100644 index 00000000..ee3ded3a --- /dev/null +++ b/Assets/TEngine/Runtime/Net/LoopBuffer.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: db9ced8ef8f2e9545a2a749dcb909f3f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/Net/LoopBuffer/Buffer.cs b/Assets/TEngine/Runtime/Net/LoopBuffer/Buffer.cs new file mode 100644 index 00000000..b2a6114c --- /dev/null +++ b/Assets/TEngine/Runtime/Net/LoopBuffer/Buffer.cs @@ -0,0 +1,111 @@ +namespace TEngine.Net +{ + public class Buffer + { + private int _size; + private int _offset; + private byte[] _data; + + public bool IsEmpty => _size == 0; + + public byte[] Data => _data; + + public int Capacity => _data.Length; + + public int Size => _size; + + public int Offset => _offset; + + public byte this[int index] => _data[index]; + + public Buffer() : this(0) + { + + } + + public Buffer(long capacity) + { + _size = 0; + _offset = 0; + _data = new byte[capacity]; + } + + public void Reserve(int capacity) + { + if (capacity < 0) + { + throw new System.ArgumentException("Invalid reserve capacity!", nameof(capacity)); + } + + if (capacity > Capacity) + { + byte[] data = new byte[System.Math.Max(capacity, 2 * Capacity)]; + System.Buffer.BlockCopy(_data, 0, data, 0, _size); + _data = data; + } + } + + public void Clear() + { + _size = 0; + _offset = 0; + } + + public void Rewind() { _offset = 0; } + + public void Shift(int offset) { _offset += offset; } + + public void Unshift(int offset) { _offset -= offset; } + + public void AddSize(int size) + { + _size += size; + _data[_size] = 0; + } + + public int Append(byte[] src) + { + Reserve(_size + src.Length); + System.Buffer.BlockCopy(src, 0, _data, _size, src.Length); + _size += src.Length; + return src.Length; + } + + public int Append(byte src) + { + Reserve(_size + 1); + _data[_size++] = src; + + return 1; + } + + public int Append(byte[] src, int offset, int count) + { + Reserve(_size + count); + System.Buffer.BlockCopy(src, offset, _data, _size, count); + _size += count; + return count; + } + + public int Append(string text) + { + Reserve(_size + System.Text.Encoding.UTF8.GetMaxByteCount(text.Length)); + int result = System.Text.Encoding.UTF8.GetBytes(text, 0, text.Length, _data, (int)_size); + _size += result; + return result; + } + + public string ExtractString(long offset, long size) + { + if ((offset + size) > Size) + throw new System.ArgumentException("Invalid offset & size!", nameof(offset)); + + return System.Text.Encoding.UTF8.GetString(_data, (int)offset, (int)size); + } + + public override string ToString() + { + return ExtractString(0, _size); + } + } +} diff --git a/Assets/TEngine/Runtime/Net/LoopBuffer/Buffer.cs.meta b/Assets/TEngine/Runtime/Net/LoopBuffer/Buffer.cs.meta new file mode 100644 index 00000000..2e376143 --- /dev/null +++ b/Assets/TEngine/Runtime/Net/LoopBuffer/Buffer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 302145da5b949d148965c386a09371c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/Net/LoopBuffer/LoopBuffer.cs b/Assets/TEngine/Runtime/Net/LoopBuffer/LoopBuffer.cs new file mode 100644 index 00000000..d2c579bb --- /dev/null +++ b/Assets/TEngine/Runtime/Net/LoopBuffer/LoopBuffer.cs @@ -0,0 +1,223 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace TEngine.Net +{ + public class LoopBuffer + { + private int _size; + private int _head; + private int _tail; + private byte[] _data; + + public bool IsEmpty => (_data == null) || (_size == 0); + + public int Size => _size; + + public int Capacity => _data != null ? _data.Length : 0; + + public int Remain => Capacity - _size; + + public LoopBuffer() : this(0) + { + + } + + public LoopBuffer(int capacity) + { + if (capacity < 0) + { + throw new System.ArgumentException("The buffer capacity must be greater than or equal to zero."); + } + + _size = 0; + _head = 0; + _tail = 0; + _data = new byte[capacity]; + } + + public void Reserve(long capacity) + { + if (capacity < 0) + { + throw new System.ArgumentException("Invalid reserve capacity!", nameof(capacity)); + } + if (capacity > Capacity) + { + byte[] data = new byte[System.Math.Max(capacity, 2 * Capacity)]; + if (_size > 0) + { + if (_head < _tail) + { + System.Buffer.BlockCopy(_data, _head, data, 0, _size); + } + else + { + System.Buffer.BlockCopy(_data, _head, data, 0, Capacity - _head); + System.Buffer.BlockCopy(_data, 0, data, Capacity - _head, _tail); + } + + } + + _head = 0; + _tail = _size; + _data = data; + } + } + + public void Clear() + { + _size = 0; + _head = 0; + _tail = 0; + } + + public int Put(byte[] src) + { + return Put(src, 0, src.Length); + } + + public int Put(byte[] src, int offset, int count) + { + if (count > Remain) + { + Reserve(_size + count); + } + + if (count > 0) + { + lock (this) + { + if (_head < _tail) + { + int right = Capacity - _tail; + + if (right >= count) + { + System.Buffer.BlockCopy(src, offset, _data, _tail, count); + } + else + { + System.Buffer.BlockCopy(src, offset, _data, _tail, right); + System.Buffer.BlockCopy(src, offset + right, _data, 0, count - right); + } + } + else + { + System.Buffer.BlockCopy(src, offset, _data, _tail, count); + } + + _tail = (_tail + count) % Capacity; + _size += count; + } + } + + return count; + } + + public void Skip(int count) + { + _head += count; + if (_head >= Capacity) + { + _head -= Capacity; + } + } + + public byte[] Get(int count) + { + var dst = new byte[count]; + Get(dst); + return dst; + } + + public int Get(byte[] dst) + { + return Get(dst, 0, dst.Length); + } + + public int Get(Buffer buffer, int count) + { + int rc = Get(buffer.Data, buffer.Offset, count); + buffer.AddSize(rc); + + return rc; + } + + public int Get(byte[] dst, int offset, int count) + { + count = System.Math.Min(count, _size); + + if (count > 0) + { + lock (this) + { + if (_head < _tail) + { + System.Buffer.BlockCopy(_data, _head, dst, offset, count); + } + else + { + int right = Capacity - _head; + + if (right >= count) + { + System.Buffer.BlockCopy(_data, _head, dst, offset, count); + } + else + { + System.Buffer.BlockCopy(_data, _head, dst, offset, right); + System.Buffer.BlockCopy(_data, 0, dst, offset + right, count - right); + } + } + + _head = (_head + count) % Capacity; + _size -= count; + + if (_size == 0) + { + _head = 0; + _tail = 0; + } + } + } + + return count; + } + + public bool Peek(byte[] dst, int offset, int count) + { + lock (this) + { + if (offset + count < _size) + { + if (_head < _tail) + { + System.Buffer.BlockCopy(_data, _head, dst, offset, count); + } + else + { + int right = Capacity - _head; + + if (right >= count) + { + System.Buffer.BlockCopy(_data, _head, dst, offset, count); + } + else + { + System.Buffer.BlockCopy(_data, _head, dst, offset, right); + System.Buffer.BlockCopy(_data, 0, dst, offset + right, count - right); + } + } + + return true; + } + else + { + return false; + } + } + } + } +} diff --git a/Assets/TEngine/Runtime/Net/LoopBuffer/LoopBuffer.cs.meta b/Assets/TEngine/Runtime/Net/LoopBuffer/LoopBuffer.cs.meta new file mode 100644 index 00000000..0437832d --- /dev/null +++ b/Assets/TEngine/Runtime/Net/LoopBuffer/LoopBuffer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4506f7a0cebc42043b734e5824a21f76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: