mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
Init TEngine4.0.0
Init TEngine4.0.0
This commit is contained in:
174
UnityProject/Packages/YooAsset/Runtime/Utility/BufferReader.cs
Normal file
174
UnityProject/Packages/YooAsset/Runtime/Utility/BufferReader.cs
Normal file
@@ -0,0 +1,174 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class BufferReader
|
||||
{
|
||||
private readonly byte[] _buffer;
|
||||
private int _index = 0;
|
||||
|
||||
public BufferReader(byte[] data)
|
||||
{
|
||||
_buffer = data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否有效
|
||||
/// </summary>
|
||||
public bool IsValid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_buffer == null || _buffer.Length == 0)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缓冲区容量
|
||||
/// </summary>
|
||||
public int Capacity
|
||||
{
|
||||
get { return _buffer.Length; }
|
||||
}
|
||||
|
||||
public byte[] ReadBytes(int count)
|
||||
{
|
||||
CheckReaderIndex(count);
|
||||
var data = new byte[count];
|
||||
Buffer.BlockCopy(_buffer, _index, data, 0, count);
|
||||
_index += count;
|
||||
return data;
|
||||
}
|
||||
public byte ReadByte()
|
||||
{
|
||||
CheckReaderIndex(1);
|
||||
return _buffer[_index++];
|
||||
}
|
||||
|
||||
public bool ReadBool()
|
||||
{
|
||||
CheckReaderIndex(1);
|
||||
return _buffer[_index++] == 1;
|
||||
}
|
||||
public short ReadInt16()
|
||||
{
|
||||
CheckReaderIndex(2);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
short value = (short)((_buffer[_index]) | (_buffer[_index + 1] << 8));
|
||||
_index += 2;
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
short value = (short)((_buffer[_index] << 8) | (_buffer[_index + 1]));
|
||||
_index += 2;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
public ushort ReadUInt16()
|
||||
{
|
||||
return (ushort)ReadInt16();
|
||||
}
|
||||
public int ReadInt32()
|
||||
{
|
||||
CheckReaderIndex(4);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
int value = (_buffer[_index]) | (_buffer[_index + 1] << 8) | (_buffer[_index + 2] << 16) | (_buffer[_index + 3] << 24);
|
||||
_index += 4;
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
int value = (_buffer[_index] << 24) | (_buffer[_index + 1] << 16) | (_buffer[_index + 2] << 8) | (_buffer[_index + 3]);
|
||||
_index += 4;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
public uint ReadUInt32()
|
||||
{
|
||||
return (uint)ReadInt32();
|
||||
}
|
||||
public long ReadInt64()
|
||||
{
|
||||
CheckReaderIndex(8);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
int i1 = (_buffer[_index]) | (_buffer[_index + 1] << 8) | (_buffer[_index + 2] << 16) | (_buffer[_index + 3] << 24);
|
||||
int i2 = (_buffer[_index + 4]) | (_buffer[_index + 5] << 8) | (_buffer[_index + 6] << 16) | (_buffer[_index + 7] << 24);
|
||||
_index += 8;
|
||||
return (uint)i1 | ((long)i2 << 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i1 = (_buffer[_index] << 24) | (_buffer[_index + 1] << 16) | (_buffer[_index + 2] << 8) | (_buffer[_index + 3]);
|
||||
int i2 = (_buffer[_index + 4] << 24) | (_buffer[_index + 5] << 16) | (_buffer[_index + 6] << 8) | (_buffer[_index + 7]);
|
||||
_index += 8;
|
||||
return (uint)i2 | ((long)i1 << 32);
|
||||
}
|
||||
}
|
||||
public ulong ReadUInt64()
|
||||
{
|
||||
return (ulong)ReadInt64();
|
||||
}
|
||||
|
||||
public string ReadUTF8()
|
||||
{
|
||||
ushort count = ReadUInt16();
|
||||
if (count == 0)
|
||||
return string.Empty;
|
||||
|
||||
CheckReaderIndex(count);
|
||||
string value = Encoding.UTF8.GetString(_buffer, _index, count);
|
||||
_index += count;
|
||||
return value;
|
||||
}
|
||||
public int[] ReadInt32Array()
|
||||
{
|
||||
ushort count = ReadUInt16();
|
||||
int[] values = new int[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
values[i] = ReadInt32();
|
||||
}
|
||||
return values;
|
||||
}
|
||||
public long[] ReadInt64Array()
|
||||
{
|
||||
ushort count = ReadUInt16();
|
||||
long[] values = new long[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
values[i] = ReadInt64();
|
||||
}
|
||||
return values;
|
||||
}
|
||||
public string[] ReadUTF8Array()
|
||||
{
|
||||
ushort count = ReadUInt16();
|
||||
string[] values = new string[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
values[i] = ReadUTF8();
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void CheckReaderIndex(int length)
|
||||
{
|
||||
if (_index + length > Capacity)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76257995ca887ad48ac02bd5d2174d9b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
187
UnityProject/Packages/YooAsset/Runtime/Utility/BufferWriter.cs
Normal file
187
UnityProject/Packages/YooAsset/Runtime/Utility/BufferWriter.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据存储以小端字节序为标准
|
||||
/// </summary>
|
||||
internal class BufferWriter
|
||||
{
|
||||
private readonly byte[] _buffer;
|
||||
private int _index = 0;
|
||||
|
||||
public BufferWriter(int capacity)
|
||||
{
|
||||
_buffer = new byte[capacity];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缓冲区容量
|
||||
/// </summary>
|
||||
public int Capacity
|
||||
{
|
||||
get { return _buffer.Length; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空缓冲区
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
_index = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将有效数据写入文件流
|
||||
/// </summary>
|
||||
public void WriteToStream(FileStream fileStream)
|
||||
{
|
||||
fileStream.Write(_buffer, 0, _index);
|
||||
}
|
||||
|
||||
public void WriteBytes(byte[] data)
|
||||
{
|
||||
int count = data.Length;
|
||||
CheckWriterIndex(count);
|
||||
Buffer.BlockCopy(data, 0, _buffer, _index, count);
|
||||
_index += count;
|
||||
}
|
||||
public void WriteByte(byte value)
|
||||
{
|
||||
CheckWriterIndex(1);
|
||||
_buffer[_index++] = value;
|
||||
}
|
||||
|
||||
public void WriteBool(bool value)
|
||||
{
|
||||
WriteByte((byte)(value ? 1 : 0));
|
||||
}
|
||||
public void WriteInt16(short value)
|
||||
{
|
||||
WriteUInt16((ushort)value);
|
||||
}
|
||||
public void WriteUInt16(ushort value)
|
||||
{
|
||||
CheckWriterIndex(2);
|
||||
_buffer[_index++] = (byte)value;
|
||||
_buffer[_index++] = (byte)(value >> 8);
|
||||
}
|
||||
public void WriteInt32(int value)
|
||||
{
|
||||
WriteUInt32((uint)value);
|
||||
}
|
||||
public void WriteUInt32(uint value)
|
||||
{
|
||||
CheckWriterIndex(4);
|
||||
_buffer[_index++] = (byte)value;
|
||||
_buffer[_index++] = (byte)(value >> 8);
|
||||
_buffer[_index++] = (byte)(value >> 16);
|
||||
_buffer[_index++] = (byte)(value >> 24);
|
||||
}
|
||||
public void WriteInt64(long value)
|
||||
{
|
||||
WriteUInt64((ulong)value);
|
||||
}
|
||||
public void WriteUInt64(ulong value)
|
||||
{
|
||||
CheckWriterIndex(8);
|
||||
_buffer[_index++] = (byte)value;
|
||||
_buffer[_index++] = (byte)(value >> 8);
|
||||
_buffer[_index++] = (byte)(value >> 16);
|
||||
_buffer[_index++] = (byte)(value >> 24);
|
||||
_buffer[_index++] = (byte)(value >> 32);
|
||||
_buffer[_index++] = (byte)(value >> 40);
|
||||
_buffer[_index++] = (byte)(value >> 48);
|
||||
_buffer[_index++] = (byte)(value >> 56);
|
||||
}
|
||||
|
||||
public void WriteUTF8(string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
WriteUInt16(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(value);
|
||||
int count = bytes.Length;
|
||||
if (count > ushort.MaxValue)
|
||||
throw new FormatException($"Write string length cannot be greater than {ushort.MaxValue} !");
|
||||
|
||||
WriteUInt16(Convert.ToUInt16(count));
|
||||
WriteBytes(bytes);
|
||||
}
|
||||
}
|
||||
public void WriteInt32Array(int[] values)
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
WriteUInt16(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = values.Length;
|
||||
if (count > ushort.MaxValue)
|
||||
throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue} !");
|
||||
|
||||
WriteUInt16(Convert.ToUInt16(count));
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
WriteInt32(values[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void WriteInt64Array(long[] values)
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
WriteUInt16(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = values.Length;
|
||||
if (count > ushort.MaxValue)
|
||||
throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue} !");
|
||||
|
||||
WriteUInt16(Convert.ToUInt16(count));
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
WriteInt64(values[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void WriteUTF8Array(string[] values)
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
WriteUInt16(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = values.Length;
|
||||
if (count > ushort.MaxValue)
|
||||
throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue} !");
|
||||
|
||||
WriteUInt16(Convert.ToUInt16(count));
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
WriteUTF8(values[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void CheckWriterIndex(int length)
|
||||
{
|
||||
if (_index + length > Capacity)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a270f91ca07a38445949cb5e8195f0a2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
242
UnityProject/Packages/YooAsset/Runtime/Utility/CRC32Algorithm.cs
Normal file
242
UnityProject/Packages/YooAsset/Runtime/Utility/CRC32Algorithm.cs
Normal file
@@ -0,0 +1,242 @@
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class SafeProxy
|
||||
{
|
||||
private const uint Poly = 0xedb88320u;
|
||||
private readonly uint[] _table = new uint[16 * 256];
|
||||
|
||||
internal SafeProxy()
|
||||
{
|
||||
Init(Poly);
|
||||
}
|
||||
public void Init(uint poly)
|
||||
{
|
||||
var table = _table;
|
||||
for (uint i = 0; i < 256; i++)
|
||||
{
|
||||
uint res = i;
|
||||
for (int t = 0; t < 16; t++)
|
||||
{
|
||||
for (int k = 0; k < 8; k++) res = (res & 1) == 1 ? poly ^ (res >> 1) : (res >> 1);
|
||||
table[(t * 256) + i] = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
public uint Append(uint crc, byte[] input, int offset, int length)
|
||||
{
|
||||
uint crcLocal = uint.MaxValue ^ crc;
|
||||
|
||||
uint[] table = _table;
|
||||
while (length >= 16)
|
||||
{
|
||||
var a = table[(3 * 256) + input[offset + 12]]
|
||||
^ table[(2 * 256) + input[offset + 13]]
|
||||
^ table[(1 * 256) + input[offset + 14]]
|
||||
^ table[(0 * 256) + input[offset + 15]];
|
||||
|
||||
var b = table[(7 * 256) + input[offset + 8]]
|
||||
^ table[(6 * 256) + input[offset + 9]]
|
||||
^ table[(5 * 256) + input[offset + 10]]
|
||||
^ table[(4 * 256) + input[offset + 11]];
|
||||
|
||||
var c = table[(11 * 256) + input[offset + 4]]
|
||||
^ table[(10 * 256) + input[offset + 5]]
|
||||
^ table[(9 * 256) + input[offset + 6]]
|
||||
^ table[(8 * 256) + input[offset + 7]];
|
||||
|
||||
var d = table[(15 * 256) + ((byte)crcLocal ^ input[offset])]
|
||||
^ table[(14 * 256) + ((byte)(crcLocal >> 8) ^ input[offset + 1])]
|
||||
^ table[(13 * 256) + ((byte)(crcLocal >> 16) ^ input[offset + 2])]
|
||||
^ table[(12 * 256) + ((crcLocal >> 24) ^ input[offset + 3])];
|
||||
|
||||
crcLocal = d ^ c ^ b ^ a;
|
||||
offset += 16;
|
||||
length -= 16;
|
||||
}
|
||||
|
||||
while (--length >= 0)
|
||||
crcLocal = table[(byte)(crcLocal ^ input[offset++])] ^ crcLocal >> 8;
|
||||
|
||||
return crcLocal ^ uint.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is .NET safe implementation of Crc32 algorithm.
|
||||
/// Implementation of CRC-32.
|
||||
/// This class supports several convenient static methods returning the CRC as UInt32.
|
||||
/// </summary>
|
||||
internal class CRC32Algorithm : HashAlgorithm
|
||||
{
|
||||
private uint _currentCrc;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CRC32Algorithm"/> class.
|
||||
/// </summary>
|
||||
public CRC32Algorithm()
|
||||
{
|
||||
#if !NETCORE13
|
||||
HashSizeValue = 32;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets internal state of the algorithm. Used internally.
|
||||
/// </summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
_currentCrc = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends CRC-32 from given buffer
|
||||
/// </summary>
|
||||
protected override void HashCore(byte[] input, int offset, int length)
|
||||
{
|
||||
_currentCrc = AppendInternal(_currentCrc, input, offset, length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes CRC-32 from <see cref="HashCore"/>
|
||||
/// </summary>
|
||||
protected override byte[] HashFinal()
|
||||
{
|
||||
if(BitConverter.IsLittleEndian)
|
||||
return new[] { (byte)_currentCrc, (byte)(_currentCrc >> 8), (byte)(_currentCrc >> 16), (byte)(_currentCrc >> 24) };
|
||||
else
|
||||
return new[] { (byte)(_currentCrc >> 24), (byte)(_currentCrc >> 16), (byte)(_currentCrc >> 8), (byte)_currentCrc };
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Computes CRC-32 from multiple buffers.
|
||||
/// Call this method multiple times to chain multiple buffers.
|
||||
/// </summary>
|
||||
/// <param name="initial">
|
||||
/// Initial CRC value for the algorithm. It is zero for the first buffer.
|
||||
/// Subsequent buffers should have their initial value set to CRC value returned by previous call to this method.
|
||||
/// </param>
|
||||
/// <param name="input">Input buffer with data to be checksummed.</param>
|
||||
/// <param name="offset">Offset of the input data within the buffer.</param>
|
||||
/// <param name="length">Length of the input data in the buffer.</param>
|
||||
/// <returns>Accumulated CRC-32 of all buffers processed so far.</returns>
|
||||
public static uint Append(uint initial, byte[] input, int offset, int length)
|
||||
{
|
||||
if (input == null)
|
||||
throw new ArgumentNullException("input");
|
||||
if (offset < 0 || length < 0 || offset + length > input.Length)
|
||||
throw new ArgumentOutOfRangeException("length");
|
||||
return AppendInternal(initial, input, offset, length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes CRC-32 from multiple buffers.
|
||||
/// Call this method multiple times to chain multiple buffers.
|
||||
/// </summary>
|
||||
/// <param name="initial">
|
||||
/// Initial CRC value for the algorithm. It is zero for the first buffer.
|
||||
/// Subsequent buffers should have their initial value set to CRC value returned by previous call to this method.
|
||||
/// </param>
|
||||
/// <param name="input">Input buffer containing data to be checksummed.</param>
|
||||
/// <returns>Accumulated CRC-32 of all buffers processed so far.</returns>
|
||||
public static uint Append(uint initial, byte[] input)
|
||||
{
|
||||
if (input == null)
|
||||
throw new ArgumentNullException();
|
||||
return AppendInternal(initial, input, 0, input.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes CRC-32 from input buffer.
|
||||
/// </summary>
|
||||
/// <param name="input">Input buffer with data to be checksummed.</param>
|
||||
/// <param name="offset">Offset of the input data within the buffer.</param>
|
||||
/// <param name="length">Length of the input data in the buffer.</param>
|
||||
/// <returns>CRC-32 of the data in the buffer.</returns>
|
||||
public static uint Compute(byte[] input, int offset, int length)
|
||||
{
|
||||
return Append(0, input, offset, length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes CRC-32 from input buffer.
|
||||
/// </summary>
|
||||
/// <param name="input">Input buffer containing data to be checksummed.</param>
|
||||
/// <returns>CRC-32 of the buffer.</returns>
|
||||
public static uint Compute(byte[] input)
|
||||
{
|
||||
return Append(0, input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes CRC-32 from input buffer and writes it after end of data (buffer should have 4 bytes reserved space for it). Can be used in conjunction with <see cref="IsValidWithCrcAtEnd(byte[],int,int)"/>
|
||||
/// </summary>
|
||||
/// <param name="input">Input buffer with data to be checksummed.</param>
|
||||
/// <param name="offset">Offset of the input data within the buffer.</param>
|
||||
/// <param name="length">Length of the input data in the buffer.</param>
|
||||
/// <returns>CRC-32 of the data in the buffer.</returns>
|
||||
public static uint ComputeAndWriteToEnd(byte[] input, int offset, int length)
|
||||
{
|
||||
if (length + 4 > input.Length)
|
||||
throw new ArgumentOutOfRangeException("length", "Length of data should be less than array length - 4 bytes of CRC data");
|
||||
var crc = Append(0, input, offset, length);
|
||||
var r = offset + length;
|
||||
input[r] = (byte)crc;
|
||||
input[r + 1] = (byte)(crc >> 8);
|
||||
input[r + 2] = (byte)(crc >> 16);
|
||||
input[r + 3] = (byte)(crc >> 24);
|
||||
return crc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes CRC-32 from input buffer - 4 bytes and writes it as last 4 bytes of buffer. Can be used in conjunction with <see cref="IsValidWithCrcAtEnd(byte[])"/>
|
||||
/// </summary>
|
||||
/// <param name="input">Input buffer with data to be checksummed.</param>
|
||||
/// <returns>CRC-32 of the data in the buffer.</returns>
|
||||
public static uint ComputeAndWriteToEnd(byte[] input)
|
||||
{
|
||||
if (input.Length < 4)
|
||||
throw new ArgumentOutOfRangeException("input", "Input array should be 4 bytes at least");
|
||||
return ComputeAndWriteToEnd(input, 0, input.Length - 4);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates correctness of CRC-32 data in source buffer with assumption that CRC-32 data located at end of buffer in reverse bytes order. Can be used in conjunction with <see cref="ComputeAndWriteToEnd(byte[],int,int)"/>
|
||||
/// </summary>
|
||||
/// <param name="input">Input buffer with data to be checksummed.</param>
|
||||
/// <param name="offset">Offset of the input data within the buffer.</param>
|
||||
/// <param name="lengthWithCrc">Length of the input data in the buffer with CRC-32 bytes.</param>
|
||||
/// <returns>Is checksum valid.</returns>
|
||||
public static bool IsValidWithCrcAtEnd(byte[] input, int offset, int lengthWithCrc)
|
||||
{
|
||||
return Append(0, input, offset, lengthWithCrc) == 0x2144DF1C;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates correctness of CRC-32 data in source buffer with assumption that CRC-32 data located at end of buffer in reverse bytes order. Can be used in conjunction with <see cref="ComputeAndWriteToEnd(byte[],int,int)"/>
|
||||
/// </summary>
|
||||
/// <param name="input">Input buffer with data to be checksummed.</param>
|
||||
/// <returns>Is checksum valid.</returns>
|
||||
public static bool IsValidWithCrcAtEnd(byte[] input)
|
||||
{
|
||||
if (input.Length < 4)
|
||||
throw new ArgumentOutOfRangeException("input", "Input array should be 4 bytes at least");
|
||||
return Append(0, input, 0, input.Length) == 0x2144DF1C;
|
||||
}
|
||||
|
||||
|
||||
private static readonly SafeProxy _proxy = new SafeProxy();
|
||||
private static uint AppendInternal(uint initial, byte[] input, int offset, int length)
|
||||
{
|
||||
if (length > 0)
|
||||
{
|
||||
return _proxy.Append(initial, input, offset, length);
|
||||
}
|
||||
else
|
||||
return initial;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5eb0b1129d88a744973666a66a1902c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
81
UnityProject/Packages/YooAsset/Runtime/Utility/YooLogger.cs
Normal file
81
UnityProject/Packages/YooAsset/Runtime/Utility/YooLogger.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义日志处理
|
||||
/// </summary>
|
||||
public interface ILogger
|
||||
{
|
||||
void Log(string message);
|
||||
void Warning(string message);
|
||||
void Error(string message);
|
||||
void Exception(System.Exception exception);
|
||||
}
|
||||
|
||||
internal static class YooLogger
|
||||
{
|
||||
public static ILogger Logger = null;
|
||||
|
||||
/// <summary>
|
||||
/// 日志
|
||||
/// </summary>
|
||||
[Conditional("DEBUG")]
|
||||
public static void Log(string info)
|
||||
{
|
||||
if (Logger != null)
|
||||
{
|
||||
Logger.Log(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.Log(info);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 警告
|
||||
/// </summary>
|
||||
public static void Warning(string info)
|
||||
{
|
||||
if (Logger != null)
|
||||
{
|
||||
Logger.Warning(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.LogWarning(info);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 错误
|
||||
/// </summary>
|
||||
public static void Error(string info)
|
||||
{
|
||||
if (Logger != null)
|
||||
{
|
||||
Logger.Error(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.LogError(info);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异常
|
||||
/// </summary>
|
||||
public static void Exception(System.Exception exception)
|
||||
{
|
||||
if (Logger != null)
|
||||
{
|
||||
Logger.Exception(exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.LogException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ffcef42f3747ab43908595778accc29
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
355
UnityProject/Packages/YooAsset/Runtime/Utility/YooUtility.cs
Normal file
355
UnityProject/Packages/YooAsset/Runtime/Utility/YooUtility.cs
Normal file
@@ -0,0 +1,355 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 路径工具类
|
||||
/// </summary>
|
||||
internal static class PathUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// 路径归一化
|
||||
/// 注意:替换为Linux路径格式
|
||||
/// </summary>
|
||||
public static string RegularPath(string path)
|
||||
{
|
||||
return path.Replace('\\', '/').Replace("\\", "/");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除路径里的后缀名
|
||||
/// </summary>
|
||||
public static string RemoveExtension(string str)
|
||||
{
|
||||
if (string.IsNullOrEmpty(str))
|
||||
return str;
|
||||
|
||||
int index = str.LastIndexOf(".");
|
||||
if (index == -1)
|
||||
return str;
|
||||
else
|
||||
return str.Remove(index); //"assets/config/test.unity3d" --> "assets/config/test"
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 合并路径
|
||||
/// </summary>
|
||||
public static string Combine(string path1, string path2)
|
||||
{
|
||||
return StringUtility.Format("{0}/{1}", path1, path2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 合并路径
|
||||
/// </summary>
|
||||
public static string Combine(string path1, string path2, string path3)
|
||||
{
|
||||
return StringUtility.Format("{0}/{1}/{2}", path1, path2, path3);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 合并路径
|
||||
/// </summary>
|
||||
public static string Combine(string path1, string path2, string path3, string path4)
|
||||
{
|
||||
return StringUtility.Format("{0}/{1}/{2}/{3}", path1, path2, path3, path4);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字符串工具类
|
||||
/// </summary>
|
||||
internal static class StringUtility
|
||||
{
|
||||
[ThreadStatic]
|
||||
private static StringBuilder _cacheBuilder = new StringBuilder(2048);
|
||||
|
||||
public static string Format(string format, object arg0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(format))
|
||||
throw new ArgumentNullException();
|
||||
|
||||
_cacheBuilder.Length = 0;
|
||||
_cacheBuilder.AppendFormat(format, arg0);
|
||||
return _cacheBuilder.ToString();
|
||||
}
|
||||
public static string Format(string format, object arg0, object arg1)
|
||||
{
|
||||
if (string.IsNullOrEmpty(format))
|
||||
throw new ArgumentNullException();
|
||||
|
||||
_cacheBuilder.Length = 0;
|
||||
_cacheBuilder.AppendFormat(format, arg0, arg1);
|
||||
return _cacheBuilder.ToString();
|
||||
}
|
||||
public static string Format(string format, object arg0, object arg1, object arg2)
|
||||
{
|
||||
if (string.IsNullOrEmpty(format))
|
||||
throw new ArgumentNullException();
|
||||
|
||||
_cacheBuilder.Length = 0;
|
||||
_cacheBuilder.AppendFormat(format, arg0, arg1, arg2);
|
||||
return _cacheBuilder.ToString();
|
||||
}
|
||||
public static string Format(string format, params object[] args)
|
||||
{
|
||||
if (string.IsNullOrEmpty(format))
|
||||
throw new ArgumentNullException();
|
||||
|
||||
if (args == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
_cacheBuilder.Length = 0;
|
||||
_cacheBuilder.AppendFormat(format, args);
|
||||
return _cacheBuilder.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 文件工具类
|
||||
/// </summary>
|
||||
internal static class FileUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// 读取文件的文本数据
|
||||
/// </summary>
|
||||
public static string ReadAllText(string filePath)
|
||||
{
|
||||
if (File.Exists(filePath) == false)
|
||||
return string.Empty;
|
||||
return File.ReadAllText(filePath, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取文件的字节数据
|
||||
/// </summary>
|
||||
public static byte[] ReadAllBytes(string filePath)
|
||||
{
|
||||
if (File.Exists(filePath) == false)
|
||||
return null;
|
||||
return File.ReadAllBytes(filePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入文本数据(会覆盖指定路径的文件)
|
||||
/// </summary>
|
||||
public static void WriteAllText(string filePath, string content)
|
||||
{
|
||||
// 创建文件夹路径
|
||||
CreateFileDirectory(filePath);
|
||||
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(content);
|
||||
File.WriteAllBytes(filePath, bytes); //避免写入BOM标记
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入字节数据(会覆盖指定路径的文件)
|
||||
/// </summary>
|
||||
public static void WriteAllBytes(string filePath, byte[] data)
|
||||
{
|
||||
// 创建文件夹路径
|
||||
CreateFileDirectory(filePath);
|
||||
|
||||
File.WriteAllBytes(filePath, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建文件的文件夹路径
|
||||
/// </summary>
|
||||
public static void CreateFileDirectory(string filePath)
|
||||
{
|
||||
// 获取文件的文件夹路径
|
||||
string directory = Path.GetDirectoryName(filePath);
|
||||
CreateDirectory(directory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建文件夹路径
|
||||
/// </summary>
|
||||
public static void CreateDirectory(string directory)
|
||||
{
|
||||
// If the directory doesn't exist, create it.
|
||||
if (Directory.Exists(directory) == false)
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件大小(字节数)
|
||||
/// </summary>
|
||||
public static long GetFileSize(string filePath)
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(filePath);
|
||||
return fileInfo.Length;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 哈希工具类
|
||||
/// </summary>
|
||||
internal static class HashUtility
|
||||
{
|
||||
private static string ToString(byte[] hashBytes)
|
||||
{
|
||||
string result = BitConverter.ToString(hashBytes);
|
||||
result = result.Replace("-", "");
|
||||
return result.ToLower();
|
||||
}
|
||||
|
||||
#region SHA1
|
||||
/// <summary>
|
||||
/// 获取字符串的Hash值
|
||||
/// </summary>
|
||||
public static string StringSHA1(string str)
|
||||
{
|
||||
byte[] buffer = Encoding.UTF8.GetBytes(str);
|
||||
return BytesSHA1(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件的Hash值
|
||||
/// </summary>
|
||||
public static string FileSHA1(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return StreamSHA1(fs);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
YooLogger.Exception(e);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据流的Hash值
|
||||
/// </summary>
|
||||
public static string StreamSHA1(Stream stream)
|
||||
{
|
||||
// 说明:创建的是SHA1类的实例,生成的是160位的散列码
|
||||
HashAlgorithm hash = HashAlgorithm.Create();
|
||||
byte[] hashBytes = hash.ComputeHash(stream);
|
||||
return ToString(hashBytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取字节数组的Hash值
|
||||
/// </summary>
|
||||
public static string BytesSHA1(byte[] buffer)
|
||||
{
|
||||
// 说明:创建的是SHA1类的实例,生成的是160位的散列码
|
||||
HashAlgorithm hash = HashAlgorithm.Create();
|
||||
byte[] hashBytes = hash.ComputeHash(buffer);
|
||||
return ToString(hashBytes);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region MD5
|
||||
/// <summary>
|
||||
/// 获取字符串的MD5
|
||||
/// </summary>
|
||||
public static string StringMD5(string str)
|
||||
{
|
||||
byte[] buffer = Encoding.UTF8.GetBytes(str);
|
||||
return BytesMD5(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件的MD5
|
||||
/// </summary>
|
||||
public static string FileMD5(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return StreamMD5(fs);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
YooLogger.Exception(e);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据流的MD5
|
||||
/// </summary>
|
||||
public static string StreamMD5(Stream stream)
|
||||
{
|
||||
MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
|
||||
byte[] hashBytes = provider.ComputeHash(stream);
|
||||
return ToString(hashBytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取字节数组的MD5
|
||||
/// </summary>
|
||||
public static string BytesMD5(byte[] buffer)
|
||||
{
|
||||
MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
|
||||
byte[] hashBytes = provider.ComputeHash(buffer);
|
||||
return ToString(hashBytes);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CRC32
|
||||
/// <summary>
|
||||
/// 获取字符串的CRC32
|
||||
/// </summary>
|
||||
public static string StringCRC32(string str)
|
||||
{
|
||||
byte[] buffer = Encoding.UTF8.GetBytes(str);
|
||||
return BytesCRC32(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件的CRC32
|
||||
/// </summary>
|
||||
public static string FileCRC32(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return StreamCRC32(fs);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
YooLogger.Exception(e);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据流的CRC32
|
||||
/// </summary>
|
||||
public static string StreamCRC32(Stream stream)
|
||||
{
|
||||
CRC32Algorithm hash = new CRC32Algorithm();
|
||||
byte[] hashBytes = hash.ComputeHash(stream);
|
||||
return ToString(hashBytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取字节数组的CRC32
|
||||
/// </summary>
|
||||
public static string BytesCRC32(byte[] buffer)
|
||||
{
|
||||
CRC32Algorithm hash = new CRC32Algorithm();
|
||||
byte[] hashBytes = hash.ComputeHash(buffer);
|
||||
return ToString(hashBytes);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b559b6cd6f58a04497ef21b68d5dde8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user