mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
Utity
Utity
This commit is contained in:
102
Assets/TEngine/Runtime/Utility/Utility.Assembly.cs
Normal file
102
Assets/TEngine/Runtime/Utility/Utility.Assembly.cs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 程序集相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static class Assembly
|
||||||
|
{
|
||||||
|
private static readonly System.Reflection.Assembly[] s_Assemblies = null;
|
||||||
|
private static readonly Dictionary<string, Type> s_CachedTypes = new Dictionary<string, Type>(StringComparer.Ordinal);
|
||||||
|
|
||||||
|
static Assembly()
|
||||||
|
{
|
||||||
|
s_Assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取已加载的程序集。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>已加载的程序集。</returns>
|
||||||
|
public static System.Reflection.Assembly[] GetAssemblies()
|
||||||
|
{
|
||||||
|
return s_Assemblies;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取已加载的程序集中的所有类型。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>已加载的程序集中的所有类型。</returns>
|
||||||
|
public static Type[] GetTypes()
|
||||||
|
{
|
||||||
|
List<Type> results = new List<Type>();
|
||||||
|
foreach (System.Reflection.Assembly assembly in s_Assemblies)
|
||||||
|
{
|
||||||
|
results.AddRange(assembly.GetTypes());
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取已加载的程序集中的所有类型。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="results">已加载的程序集中的所有类型。</param>
|
||||||
|
public static void GetTypes(List<Type> results)
|
||||||
|
{
|
||||||
|
if (results == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Results is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
results.Clear();
|
||||||
|
foreach (System.Reflection.Assembly assembly in s_Assemblies)
|
||||||
|
{
|
||||||
|
results.AddRange(assembly.GetTypes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取已加载的程序集中的指定类型。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="typeName">要获取的类型名。</param>
|
||||||
|
/// <returns>已加载的程序集中的指定类型。</returns>
|
||||||
|
public static Type GetType(string typeName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(typeName))
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Type name is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Type type = null;
|
||||||
|
if (s_CachedTypes.TryGetValue(typeName, out type))
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = Type.GetType(typeName);
|
||||||
|
if (type != null)
|
||||||
|
{
|
||||||
|
s_CachedTypes.Add(typeName, type);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (System.Reflection.Assembly assembly in s_Assemblies)
|
||||||
|
{
|
||||||
|
type = Type.GetType(Text.Format("{0}, {1}", typeName, assembly.FullName));
|
||||||
|
if (type != null)
|
||||||
|
{
|
||||||
|
s_CachedTypes.Add(typeName, type);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Utility/Utility.Assembly.cs.meta
Normal file
11
Assets/TEngine/Runtime/Utility/Utility.Assembly.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7609018db739fe545ba5be5d32f7eb3c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -0,0 +1,52 @@
|
|||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
public static partial class Compression
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩解压缩辅助器接口。
|
||||||
|
/// </summary>
|
||||||
|
public interface ICompressionHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">要压缩的数据的二进制流。</param>
|
||||||
|
/// <param name="offset">要压缩的数据的二进制流的偏移。</param>
|
||||||
|
/// <param name="length">要压缩的数据的二进制流的长度。</param>
|
||||||
|
/// <param name="compressedStream">压缩后的数据的二进制流。</param>
|
||||||
|
/// <returns>是否压缩数据成功。</returns>
|
||||||
|
bool Compress(byte[] bytes, int offset, int length, Stream compressedStream);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">要压缩的数据的二进制流。</param>
|
||||||
|
/// <param name="compressedStream">压缩后的数据的二进制流。</param>
|
||||||
|
/// <returns>是否压缩数据成功。</returns>
|
||||||
|
bool Compress(Stream stream, Stream compressedStream);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">要解压缩的数据的二进制流。</param>
|
||||||
|
/// <param name="offset">要解压缩的数据的二进制流的偏移。</param>
|
||||||
|
/// <param name="length">要解压缩的数据的二进制流的长度。</param>
|
||||||
|
/// <param name="decompressedStream">解压缩后的数据的二进制流。</param>
|
||||||
|
/// <returns>是否解压缩数据成功。</returns>
|
||||||
|
bool Decompress(byte[] bytes, int offset, int length, Stream decompressedStream);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">要解压缩的数据的二进制流。</param>
|
||||||
|
/// <param name="decompressedStream">解压缩后的数据的二进制流。</param>
|
||||||
|
/// <returns>是否解压缩数据成功。</returns>
|
||||||
|
bool Decompress(Stream stream, Stream decompressedStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3d82356f5e654704daa0769074b9e5a7
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
337
Assets/TEngine/Runtime/Utility/Utility.Compression.cs
Normal file
337
Assets/TEngine/Runtime/Utility/Utility.Compression.cs
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩解压缩相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static partial class Compression
|
||||||
|
{
|
||||||
|
private static ICompressionHelper s_CompressionHelper = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置压缩解压缩辅助器。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="compressionHelper">要设置的压缩解压缩辅助器。</param>
|
||||||
|
public static void SetCompressionHelper(ICompressionHelper compressionHelper)
|
||||||
|
{
|
||||||
|
s_CompressionHelper = compressionHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">要压缩的数据的二进制流。</param>
|
||||||
|
/// <returns>压缩后的数据的二进制流。</returns>
|
||||||
|
public static byte[] Compress(byte[] bytes)
|
||||||
|
{
|
||||||
|
if (bytes == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Bytes is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Compress(bytes, 0, bytes.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">要压缩的数据的二进制流。</param>
|
||||||
|
/// <param name="compressedStream">压缩后的数据的二进制流。</param>
|
||||||
|
/// <returns>是否压缩数据成功。</returns>
|
||||||
|
public static bool Compress(byte[] bytes, Stream compressedStream)
|
||||||
|
{
|
||||||
|
if (bytes == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Bytes is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Compress(bytes, 0, bytes.Length, compressedStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">要压缩的数据的二进制流。</param>
|
||||||
|
/// <param name="offset">要压缩的数据的二进制流的偏移。</param>
|
||||||
|
/// <param name="length">要压缩的数据的二进制流的长度。</param>
|
||||||
|
/// <returns>压缩后的数据的二进制流。</returns>
|
||||||
|
public static byte[] Compress(byte[] bytes, int offset, int length)
|
||||||
|
{
|
||||||
|
using (MemoryStream compressedStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
if (Compress(bytes, offset, length, compressedStream))
|
||||||
|
{
|
||||||
|
return compressedStream.ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">要压缩的数据的二进制流。</param>
|
||||||
|
/// <param name="offset">要压缩的数据的二进制流的偏移。</param>
|
||||||
|
/// <param name="length">要压缩的数据的二进制流的长度。</param>
|
||||||
|
/// <param name="compressedStream">压缩后的数据的二进制流。</param>
|
||||||
|
/// <returns>是否压缩数据成功。</returns>
|
||||||
|
public static bool Compress(byte[] bytes, int offset, int length, Stream compressedStream)
|
||||||
|
{
|
||||||
|
if (s_CompressionHelper == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Compressed helper is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Bytes is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset < 0 || length < 0 || offset + length > bytes.Length)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Offset or length is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compressedStream == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Compressed stream is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return s_CompressionHelper.Compress(bytes, offset, length, compressedStream);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
if (exception is GameFrameworkException)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new GameFrameworkException(Text.Format("Can not compress with exception '{0}'.", exception), exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">要压缩的数据的二进制流。</param>
|
||||||
|
/// <returns>压缩后的数据的二进制流。</returns>
|
||||||
|
public static byte[] Compress(Stream stream)
|
||||||
|
{
|
||||||
|
using (MemoryStream compressedStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
if (Compress(stream, compressedStream))
|
||||||
|
{
|
||||||
|
return compressedStream.ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">要压缩的数据的二进制流。</param>
|
||||||
|
/// <param name="compressedStream">压缩后的数据的二进制流。</param>
|
||||||
|
/// <returns>是否压缩数据成功。</returns>
|
||||||
|
public static bool Compress(Stream stream, Stream compressedStream)
|
||||||
|
{
|
||||||
|
if (s_CompressionHelper == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Compressed helper is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Stream is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compressedStream == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Compressed stream is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return s_CompressionHelper.Compress(stream, compressedStream);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
if (exception is GameFrameworkException)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new GameFrameworkException(Text.Format("Can not compress with exception '{0}'.", exception), exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">要解压缩的数据的二进制流。</param>
|
||||||
|
/// <returns>解压缩后的数据的二进制流。</returns>
|
||||||
|
public static byte[] Decompress(byte[] bytes)
|
||||||
|
{
|
||||||
|
if (bytes == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Bytes is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Decompress(bytes, 0, bytes.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">要解压缩的数据的二进制流。</param>
|
||||||
|
/// <param name="decompressedStream">解压缩后的数据的二进制流。</param>
|
||||||
|
/// <returns>是否解压缩数据成功。</returns>
|
||||||
|
public static bool Decompress(byte[] bytes, Stream decompressedStream)
|
||||||
|
{
|
||||||
|
if (bytes == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Bytes is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Decompress(bytes, 0, bytes.Length, decompressedStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">要解压缩的数据的二进制流。</param>
|
||||||
|
/// <param name="offset">要解压缩的数据的二进制流的偏移。</param>
|
||||||
|
/// <param name="length">要解压缩的数据的二进制流的长度。</param>
|
||||||
|
/// <returns>解压缩后的数据的二进制流。</returns>
|
||||||
|
public static byte[] Decompress(byte[] bytes, int offset, int length)
|
||||||
|
{
|
||||||
|
using (MemoryStream decompressedStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
if (Decompress(bytes, offset, length, decompressedStream))
|
||||||
|
{
|
||||||
|
return decompressedStream.ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">要解压缩的数据的二进制流。</param>
|
||||||
|
/// <param name="offset">要解压缩的数据的二进制流的偏移。</param>
|
||||||
|
/// <param name="length">要解压缩的数据的二进制流的长度。</param>
|
||||||
|
/// <param name="decompressedStream">解压缩后的数据的二进制流。</param>
|
||||||
|
/// <returns>是否解压缩数据成功。</returns>
|
||||||
|
public static bool Decompress(byte[] bytes, int offset, int length, Stream decompressedStream)
|
||||||
|
{
|
||||||
|
if (s_CompressionHelper == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Compressed helper is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Bytes is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset < 0 || length < 0 || offset + length > bytes.Length)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Offset or length is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decompressedStream == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Decompressed stream is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return s_CompressionHelper.Decompress(bytes, offset, length, decompressedStream);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
if (exception is GameFrameworkException)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new GameFrameworkException(Text.Format("Can not decompress with exception '{0}'.", exception), exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">要解压缩的数据的二进制流。</param>
|
||||||
|
/// <returns>是否解压缩数据成功。</returns>
|
||||||
|
public static byte[] Decompress(Stream stream)
|
||||||
|
{
|
||||||
|
using (MemoryStream decompressedStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
if (Decompress(stream, decompressedStream))
|
||||||
|
{
|
||||||
|
return decompressedStream.ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解压缩数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">要解压缩的数据的二进制流。</param>
|
||||||
|
/// <param name="decompressedStream">解压缩后的数据的二进制流。</param>
|
||||||
|
/// <returns>是否解压缩数据成功。</returns>
|
||||||
|
public static bool Decompress(Stream stream, Stream decompressedStream)
|
||||||
|
{
|
||||||
|
if (s_CompressionHelper == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Compressed helper is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Stream is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decompressedStream == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Decompressed stream is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return s_CompressionHelper.Decompress(stream, decompressedStream);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
if (exception is GameFrameworkException)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new GameFrameworkException(Text.Format("Can not decompress with exception '{0}'.", exception), exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Utility/Utility.Compression.cs.meta
Normal file
11
Assets/TEngine/Runtime/Utility/Utility.Compression.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f1ec2480f190a1e419297e6efd755541
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
841
Assets/TEngine/Runtime/Utility/Utility.Converter.cs
Normal file
841
Assets/TEngine/Runtime/Utility/Utility.Converter.cs
Normal file
@@ -0,0 +1,841 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 类型转换相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static class Converter
|
||||||
|
{
|
||||||
|
private const float InchesToCentimeters = 2.54f; // 1 inch = 2.54 cm
|
||||||
|
private const float CentimetersToInches = 1f / InchesToCentimeters; // 1 cm = 0.3937 inches
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取数据在此计算机结构中存储时的字节顺序。
|
||||||
|
/// </summary>
|
||||||
|
public static bool IsLittleEndian
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return BitConverter.IsLittleEndian;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置屏幕每英寸点数。
|
||||||
|
/// </summary>
|
||||||
|
public static float ScreenDpi
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将像素转换为厘米。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pixels">像素。</param>
|
||||||
|
/// <returns>厘米。</returns>
|
||||||
|
public static float GetCentimetersFromPixels(float pixels)
|
||||||
|
{
|
||||||
|
if (ScreenDpi <= 0)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("You must set screen DPI first.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return InchesToCentimeters * pixels / ScreenDpi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将厘米转换为像素。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="centimeters">厘米。</param>
|
||||||
|
/// <returns>像素。</returns>
|
||||||
|
public static float GetPixelsFromCentimeters(float centimeters)
|
||||||
|
{
|
||||||
|
if (ScreenDpi <= 0)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("You must set screen DPI first.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return CentimetersToInches * centimeters * ScreenDpi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将像素转换为英寸。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pixels">像素。</param>
|
||||||
|
/// <returns>英寸。</returns>
|
||||||
|
public static float GetInchesFromPixels(float pixels)
|
||||||
|
{
|
||||||
|
if (ScreenDpi <= 0)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("You must set screen DPI first.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return pixels / ScreenDpi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将英寸转换为像素。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inches">英寸。</param>
|
||||||
|
/// <returns>像素。</returns>
|
||||||
|
public static float GetPixelsFromInches(float inches)
|
||||||
|
{
|
||||||
|
if (ScreenDpi <= 0)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("You must set screen DPI first.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return inches * ScreenDpi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的布尔值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的布尔值。</param>
|
||||||
|
/// <returns>用于存放结果的字节数组。</returns>
|
||||||
|
public static byte[] GetBytes(bool value)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[1];
|
||||||
|
GetBytes(value, buffer, 0);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的布尔值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的布尔值。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
public static void GetBytes(bool value, byte[] buffer)
|
||||||
|
{
|
||||||
|
GetBytes(value, buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的布尔值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的布尔值。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <param name="startIndex">buffer 内的起始位置。</param>
|
||||||
|
public static void GetBytes(bool value, byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
if (buffer == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Buffer is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startIndex < 0 || startIndex + 1 > buffer.Length)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Start index is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[startIndex] = value ? (byte)1 : (byte)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中首字节转换来的布尔值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <returns>如果 value 中的首字节非零,则为 true,否则为 false。</returns>
|
||||||
|
public static bool GetBoolean(byte[] value)
|
||||||
|
{
|
||||||
|
return BitConverter.ToBoolean(value, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中指定位置的一个字节转换来的布尔值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <param name="startIndex">value 内的起始位置。</param>
|
||||||
|
/// <returns>如果 value 中指定位置的字节非零,则为 true,否则为 false。</returns>
|
||||||
|
public static bool GetBoolean(byte[] value, int startIndex)
|
||||||
|
{
|
||||||
|
return BitConverter.ToBoolean(value, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 Unicode 字符值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的字符。</param>
|
||||||
|
/// <returns>用于存放结果的字节数组。</returns>
|
||||||
|
public static byte[] GetBytes(char value)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[2];
|
||||||
|
GetBytes((short)value, buffer, 0);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 Unicode 字符值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的字符。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
public static void GetBytes(char value, byte[] buffer)
|
||||||
|
{
|
||||||
|
GetBytes((short)value, buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 Unicode 字符值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的字符。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <param name="startIndex">buffer 内的起始位置。</param>
|
||||||
|
public static void GetBytes(char value, byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
GetBytes((short)value, buffer, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中前两个字节转换来的 Unicode 字符。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <returns>由两个字节构成的字符。</returns>
|
||||||
|
public static char GetChar(byte[] value)
|
||||||
|
{
|
||||||
|
return BitConverter.ToChar(value, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中指定位置的两个字节转换来的 Unicode 字符。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <param name="startIndex">value 内的起始位置。</param>
|
||||||
|
/// <returns>由两个字节构成的字符。</returns>
|
||||||
|
public static char GetChar(byte[] value, int startIndex)
|
||||||
|
{
|
||||||
|
return BitConverter.ToChar(value, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 16 位有符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <returns>用于存放结果的字节数组。</returns>
|
||||||
|
public static byte[] GetBytes(short value)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[2];
|
||||||
|
GetBytes(value, buffer, 0);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 16 位有符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
public static void GetBytes(short value, byte[] buffer)
|
||||||
|
{
|
||||||
|
GetBytes(value, buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 16 位有符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <param name="startIndex">buffer 内的起始位置。</param>
|
||||||
|
public static unsafe void GetBytes(short value, byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
if (buffer == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Buffer is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startIndex < 0 || startIndex + 2 > buffer.Length)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Start index is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed (byte* valueRef = buffer)
|
||||||
|
{
|
||||||
|
*(short*)(valueRef + startIndex) = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中前两个字节转换来的 16 位有符号整数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <returns>由两个字节构成的 16 位有符号整数。</returns>
|
||||||
|
public static short GetInt16(byte[] value)
|
||||||
|
{
|
||||||
|
return BitConverter.ToInt16(value, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中指定位置的两个字节转换来的 16 位有符号整数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <param name="startIndex">value 内的起始位置。</param>
|
||||||
|
/// <returns>由两个字节构成的 16 位有符号整数。</returns>
|
||||||
|
public static short GetInt16(byte[] value, int startIndex)
|
||||||
|
{
|
||||||
|
return BitConverter.ToInt16(value, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 16 位无符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <returns>用于存放结果的字节数组。</returns>
|
||||||
|
public static byte[] GetBytes(ushort value)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[2];
|
||||||
|
GetBytes((short)value, buffer, 0);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 16 位无符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
public static void GetBytes(ushort value, byte[] buffer)
|
||||||
|
{
|
||||||
|
GetBytes((short)value, buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 16 位无符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <param name="startIndex">buffer 内的起始位置。</param>
|
||||||
|
public static void GetBytes(ushort value, byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
GetBytes((short)value, buffer, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中前两个字节转换来的 16 位无符号整数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <returns>由两个字节构成的 16 位无符号整数。</returns>
|
||||||
|
public static ushort GetUInt16(byte[] value)
|
||||||
|
{
|
||||||
|
return BitConverter.ToUInt16(value, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中指定位置的两个字节转换来的 16 位无符号整数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <param name="startIndex">value 内的起始位置。</param>
|
||||||
|
/// <returns>由两个字节构成的 16 位无符号整数。</returns>
|
||||||
|
public static ushort GetUInt16(byte[] value, int startIndex)
|
||||||
|
{
|
||||||
|
return BitConverter.ToUInt16(value, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 32 位有符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <returns>用于存放结果的字节数组。</returns>
|
||||||
|
public static byte[] GetBytes(int value)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[4];
|
||||||
|
GetBytes(value, buffer, 0);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 32 位有符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
public static void GetBytes(int value, byte[] buffer)
|
||||||
|
{
|
||||||
|
GetBytes(value, buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 32 位有符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <param name="startIndex">buffer 内的起始位置。</param>
|
||||||
|
public static unsafe void GetBytes(int value, byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
if (buffer == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Buffer is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startIndex < 0 || startIndex + 4 > buffer.Length)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Start index is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed (byte* valueRef = buffer)
|
||||||
|
{
|
||||||
|
*(int*)(valueRef + startIndex) = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中前四个字节转换来的 32 位有符号整数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <returns>由四个字节构成的 32 位有符号整数。</returns>
|
||||||
|
public static int GetInt32(byte[] value)
|
||||||
|
{
|
||||||
|
return BitConverter.ToInt32(value, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中指定位置的四个字节转换来的 32 位有符号整数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <param name="startIndex">value 内的起始位置。</param>
|
||||||
|
/// <returns>由四个字节构成的 32 位有符号整数。</returns>
|
||||||
|
public static int GetInt32(byte[] value, int startIndex)
|
||||||
|
{
|
||||||
|
return BitConverter.ToInt32(value, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 32 位无符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <returns>用于存放结果的字节数组。</returns>
|
||||||
|
public static byte[] GetBytes(uint value)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[4];
|
||||||
|
GetBytes((int)value, buffer, 0);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 32 位无符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
public static void GetBytes(uint value, byte[] buffer)
|
||||||
|
{
|
||||||
|
GetBytes((int)value, buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 32 位无符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <param name="startIndex">buffer 内的起始位置。</param>
|
||||||
|
public static void GetBytes(uint value, byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
GetBytes((int)value, buffer, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中前四个字节转换来的 32 位无符号整数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <returns>由四个字节构成的 32 位无符号整数。</returns>
|
||||||
|
public static uint GetUInt32(byte[] value)
|
||||||
|
{
|
||||||
|
return BitConverter.ToUInt32(value, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中指定位置的四个字节转换来的 32 位无符号整数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <param name="startIndex">value 内的起始位置。</param>
|
||||||
|
/// <returns>由四个字节构成的 32 位无符号整数。</returns>
|
||||||
|
public static uint GetUInt32(byte[] value, int startIndex)
|
||||||
|
{
|
||||||
|
return BitConverter.ToUInt32(value, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 64 位有符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <returns>用于存放结果的字节数组。</returns>
|
||||||
|
public static byte[] GetBytes(long value)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[8];
|
||||||
|
GetBytes(value, buffer, 0);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 64 位有符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
public static void GetBytes(long value, byte[] buffer)
|
||||||
|
{
|
||||||
|
GetBytes(value, buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 64 位有符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <param name="startIndex">buffer 内的起始位置。</param>
|
||||||
|
public static unsafe void GetBytes(long value, byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
if (buffer == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Buffer is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startIndex < 0 || startIndex + 8 > buffer.Length)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Start index is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed (byte* valueRef = buffer)
|
||||||
|
{
|
||||||
|
*(long*)(valueRef + startIndex) = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中前八个字节转换来的 64 位有符号整数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <returns>由八个字节构成的 64 位有符号整数。</returns>
|
||||||
|
public static long GetInt64(byte[] value)
|
||||||
|
{
|
||||||
|
return BitConverter.ToInt64(value, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中指定位置的八个字节转换来的 64 位有符号整数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <param name="startIndex">value 内的起始位置。</param>
|
||||||
|
/// <returns>由八个字节构成的 64 位有符号整数。</returns>
|
||||||
|
public static long GetInt64(byte[] value, int startIndex)
|
||||||
|
{
|
||||||
|
return BitConverter.ToInt64(value, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 64 位无符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <returns>用于存放结果的字节数组。</returns>
|
||||||
|
public static byte[] GetBytes(ulong value)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[8];
|
||||||
|
GetBytes((long)value, buffer, 0);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 64 位无符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
public static void GetBytes(ulong value, byte[] buffer)
|
||||||
|
{
|
||||||
|
GetBytes((long)value, buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的 64 位无符号整数值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <param name="startIndex">buffer 内的起始位置。</param>
|
||||||
|
public static void GetBytes(ulong value, byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
GetBytes((long)value, buffer, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中前八个字节转换来的 64 位无符号整数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <returns>由八个字节构成的 64 位无符号整数。</returns>
|
||||||
|
public static ulong GetUInt64(byte[] value)
|
||||||
|
{
|
||||||
|
return BitConverter.ToUInt64(value, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中指定位置的八个字节转换来的 64 位无符号整数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <param name="startIndex">value 内的起始位置。</param>
|
||||||
|
/// <returns>由八个字节构成的 64 位无符号整数。</returns>
|
||||||
|
public static ulong GetUInt64(byte[] value, int startIndex)
|
||||||
|
{
|
||||||
|
return BitConverter.ToUInt64(value, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的单精度浮点值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <returns>用于存放结果的字节数组。</returns>
|
||||||
|
public static unsafe byte[] GetBytes(float value)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[4];
|
||||||
|
GetBytes(*(int*)&value, buffer, 0);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的单精度浮点值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
public static unsafe void GetBytes(float value, byte[] buffer)
|
||||||
|
{
|
||||||
|
GetBytes(*(int*)&value, buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的单精度浮点值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <param name="startIndex">buffer 内的起始位置。</param>
|
||||||
|
public static unsafe void GetBytes(float value, byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
GetBytes(*(int*)&value, buffer, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中前四个字节转换来的单精度浮点数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <returns>由四个字节构成的单精度浮点数。</returns>
|
||||||
|
public static float GetSingle(byte[] value)
|
||||||
|
{
|
||||||
|
return BitConverter.ToSingle(value, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中指定位置的四个字节转换来的单精度浮点数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <param name="startIndex">value 内的起始位置。</param>
|
||||||
|
/// <returns>由四个字节构成的单精度浮点数。</returns>
|
||||||
|
public static float GetSingle(byte[] value, int startIndex)
|
||||||
|
{
|
||||||
|
return BitConverter.ToSingle(value, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的双精度浮点值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <returns>用于存放结果的字节数组。</returns>
|
||||||
|
public static unsafe byte[] GetBytes(double value)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[8];
|
||||||
|
GetBytes(*(long*)&value, buffer, 0);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的双精度浮点值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
public static unsafe void GetBytes(double value, byte[] buffer)
|
||||||
|
{
|
||||||
|
GetBytes(*(long*)&value, buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定的双精度浮点值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的数字。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <param name="startIndex">buffer 内的起始位置。</param>
|
||||||
|
public static unsafe void GetBytes(double value, byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
GetBytes(*(long*)&value, buffer, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中前八个字节转换来的双精度浮点数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <returns>由八个字节构成的双精度浮点数。</returns>
|
||||||
|
public static double GetDouble(byte[] value)
|
||||||
|
{
|
||||||
|
return BitConverter.ToDouble(value, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组中指定位置的八个字节转换来的双精度浮点数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <param name="startIndex">value 内的起始位置。</param>
|
||||||
|
/// <returns>由八个字节构成的双精度浮点数。</returns>
|
||||||
|
public static double GetDouble(byte[] value, int startIndex)
|
||||||
|
{
|
||||||
|
return BitConverter.ToDouble(value, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取 UTF-8 编码的字符串。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的字符串。</param>
|
||||||
|
/// <returns>用于存放结果的字节数组。</returns>
|
||||||
|
public static byte[] GetBytes(string value)
|
||||||
|
{
|
||||||
|
return GetBytes(value, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取 UTF-8 编码的字符串。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的字符串。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <returns>buffer 内实际填充了多少字节。</returns>
|
||||||
|
public static int GetBytes(string value, byte[] buffer)
|
||||||
|
{
|
||||||
|
return GetBytes(value, Encoding.UTF8, buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取 UTF-8 编码的字符串。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的字符串。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <param name="startIndex">buffer 内的起始位置。</param>
|
||||||
|
/// <returns>buffer 内实际填充了多少字节。</returns>
|
||||||
|
public static int GetBytes(string value, byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
return GetBytes(value, Encoding.UTF8, buffer, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定编码的字符串。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的字符串。</param>
|
||||||
|
/// <param name="encoding">要使用的编码。</param>
|
||||||
|
/// <returns>用于存放结果的字节数组。</returns>
|
||||||
|
public static byte[] GetBytes(string value, Encoding encoding)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Value is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encoding == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Encoding is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return encoding.GetBytes(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定编码的字符串。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的字符串。</param>
|
||||||
|
/// <param name="encoding">要使用的编码。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <returns>buffer 内实际填充了多少字节。</returns>
|
||||||
|
public static int GetBytes(string value, Encoding encoding, byte[] buffer)
|
||||||
|
{
|
||||||
|
return GetBytes(value, encoding, buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以字节数组的形式获取指定编码的字符串。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要转换的字符串。</param>
|
||||||
|
/// <param name="encoding">要使用的编码。</param>
|
||||||
|
/// <param name="buffer">用于存放结果的字节数组。</param>
|
||||||
|
/// <param name="startIndex">buffer 内的起始位置。</param>
|
||||||
|
/// <returns>buffer 内实际填充了多少字节。</returns>
|
||||||
|
public static int GetBytes(string value, Encoding encoding, byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Value is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encoding == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Encoding is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return encoding.GetBytes(value, 0, value.Length, buffer, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组使用 UTF-8 编码转换成的字符串。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <returns>转换后的字符串。</returns>
|
||||||
|
public static string GetString(byte[] value)
|
||||||
|
{
|
||||||
|
return GetString(value, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组使用指定编码转换成的字符串。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <param name="encoding">要使用的编码。</param>
|
||||||
|
/// <returns>转换后的字符串。</returns>
|
||||||
|
public static string GetString(byte[] value, Encoding encoding)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Value is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encoding == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Encoding is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return encoding.GetString(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组使用 UTF-8 编码转换成的字符串。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <param name="startIndex">value 内的起始位置。</param>
|
||||||
|
/// <param name="length">长度。</param>
|
||||||
|
/// <returns>转换后的字符串。</returns>
|
||||||
|
public static string GetString(byte[] value, int startIndex, int length)
|
||||||
|
{
|
||||||
|
return GetString(value, startIndex, length, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回由字节数组使用指定编码转换成的字符串。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">字节数组。</param>
|
||||||
|
/// <param name="startIndex">value 内的起始位置。</param>
|
||||||
|
/// <param name="length">长度。</param>
|
||||||
|
/// <param name="encoding">要使用的编码。</param>
|
||||||
|
/// <returns>转换后的字符串。</returns>
|
||||||
|
public static string GetString(byte[] value, int startIndex, int length, Encoding encoding)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Value is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encoding == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Encoding is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return encoding.GetString(value, startIndex, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Utility/Utility.Converter.cs.meta
Normal file
11
Assets/TEngine/Runtime/Utility/Utility.Converter.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7362a66e3741e8440bcc831815b4426c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
127
Assets/TEngine/Runtime/Utility/Utility.Encryption.cs
Normal file
127
Assets/TEngine/Runtime/Utility/Utility.Encryption.cs
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 加密解密相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static class Encryption
|
||||||
|
{
|
||||||
|
internal const int QuickEncryptLength = 220;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 bytes 使用 code 做异或运算的快速版本。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">原始二进制流。</param>
|
||||||
|
/// <param name="code">异或二进制流。</param>
|
||||||
|
/// <returns>异或后的二进制流。</returns>
|
||||||
|
public static byte[] GetQuickXorBytes(byte[] bytes, byte[] code)
|
||||||
|
{
|
||||||
|
return GetXorBytes(bytes, 0, QuickEncryptLength, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 bytes 使用 code 做异或运算的快速版本。此方法将复用并改写传入的 bytes 作为返回值,而不额外分配内存空间。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">原始及异或后的二进制流。</param>
|
||||||
|
/// <param name="code">异或二进制流。</param>
|
||||||
|
public static void GetQuickSelfXorBytes(byte[] bytes, byte[] code)
|
||||||
|
{
|
||||||
|
GetSelfXorBytes(bytes, 0, QuickEncryptLength, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 bytes 使用 code 做异或运算。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">原始二进制流。</param>
|
||||||
|
/// <param name="code">异或二进制流。</param>
|
||||||
|
/// <returns>异或后的二进制流。</returns>
|
||||||
|
public static byte[] GetXorBytes(byte[] bytes, byte[] code)
|
||||||
|
{
|
||||||
|
if (bytes == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetXorBytes(bytes, 0, bytes.Length, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 bytes 使用 code 做异或运算。此方法将复用并改写传入的 bytes 作为返回值,而不额外分配内存空间。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">原始及异或后的二进制流。</param>
|
||||||
|
/// <param name="code">异或二进制流。</param>
|
||||||
|
public static void GetSelfXorBytes(byte[] bytes, byte[] code)
|
||||||
|
{
|
||||||
|
if (bytes == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetSelfXorBytes(bytes, 0, bytes.Length, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 bytes 使用 code 做异或运算。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">原始二进制流。</param>
|
||||||
|
/// <param name="startIndex">异或计算的开始位置。</param>
|
||||||
|
/// <param name="length">异或计算长度,若小于 0,则计算整个二进制流。</param>
|
||||||
|
/// <param name="code">异或二进制流。</param>
|
||||||
|
/// <returns>异或后的二进制流。</returns>
|
||||||
|
public static byte[] GetXorBytes(byte[] bytes, int startIndex, int length, byte[] code)
|
||||||
|
{
|
||||||
|
if (bytes == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bytesLength = bytes.Length;
|
||||||
|
byte[] results = new byte[bytesLength];
|
||||||
|
Array.Copy(bytes, 0, results, 0, bytesLength);
|
||||||
|
GetSelfXorBytes(results, startIndex, length, code);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 bytes 使用 code 做异或运算。此方法将复用并改写传入的 bytes 作为返回值,而不额外分配内存空间。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">原始及异或后的二进制流。</param>
|
||||||
|
/// <param name="startIndex">异或计算的开始位置。</param>
|
||||||
|
/// <param name="length">异或计算长度。</param>
|
||||||
|
/// <param name="code">异或二进制流。</param>
|
||||||
|
public static void GetSelfXorBytes(byte[] bytes, int startIndex, int length, byte[] code)
|
||||||
|
{
|
||||||
|
if (bytes == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Code is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int codeLength = code.Length;
|
||||||
|
if (codeLength <= 0)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Code length is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startIndex < 0 || length < 0 || startIndex + length > bytes.Length)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Start index or length is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int codeIndex = startIndex % codeLength;
|
||||||
|
for (int i = startIndex; i < length; i++)
|
||||||
|
{
|
||||||
|
bytes[i] ^= code[codeIndex++];
|
||||||
|
codeIndex %= codeLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Utility/Utility.Encryption.cs.meta
Normal file
11
Assets/TEngine/Runtime/Utility/Utility.Encryption.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a279fdc81b03f4847a1b1a209af2a68e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
232
Assets/TEngine/Runtime/Utility/Utility.File.cs
Normal file
232
Assets/TEngine/Runtime/Utility/Utility.File.cs
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unity平台路径类型。
|
||||||
|
/// </summary>
|
||||||
|
public enum UnityPlatformPathType : int
|
||||||
|
{
|
||||||
|
dataPath = 0,
|
||||||
|
streamingAssetsPath,
|
||||||
|
persistentDataPath,
|
||||||
|
temporaryCachePath,
|
||||||
|
}
|
||||||
|
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 文件相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static class File
|
||||||
|
{
|
||||||
|
public static bool CreateFile(string filePath, bool isCreateDir = true)
|
||||||
|
{
|
||||||
|
if (!System.IO.File.Exists(filePath))
|
||||||
|
{
|
||||||
|
string dir = System.IO.Path.GetDirectoryName(filePath);
|
||||||
|
if (!Directory.Exists(dir))
|
||||||
|
{
|
||||||
|
if (isCreateDir)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(dir);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error("文件夹不存在 Path=" + dir);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.IO.File.Create(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool CreateFile(string filePath, string info, bool isCreateDir = true)
|
||||||
|
{
|
||||||
|
StreamWriter sw;
|
||||||
|
FileInfo t = new FileInfo(filePath);
|
||||||
|
if (!t.Exists)
|
||||||
|
{
|
||||||
|
string dir = System.IO.Path.GetDirectoryName(filePath);
|
||||||
|
if (!Directory.Exists(dir))
|
||||||
|
{
|
||||||
|
if (isCreateDir)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(dir);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
EditorUtility.DisplayDialog("Tips", "文件夹不存在", "CANCEL");
|
||||||
|
#endif
|
||||||
|
Log.Error("文件夹不存在 Path=" + dir);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sw = t.CreateText();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sw = t.AppendText();
|
||||||
|
}
|
||||||
|
|
||||||
|
sw.WriteLine(info);
|
||||||
|
sw.Close();
|
||||||
|
sw.Dispose();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetPersistentDataPlatformPath(string filePath)
|
||||||
|
{
|
||||||
|
filePath =
|
||||||
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||||
|
Application.dataPath + "!assets" + "/" + filePath;
|
||||||
|
#else
|
||||||
|
Application.streamingAssetsPath + "/" + filePath;
|
||||||
|
#endif
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetPath(string path)
|
||||||
|
{
|
||||||
|
return path.Replace("\\", "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Md5ByPathName(string pathName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileStream file = new FileStream(pathName, FileMode.Open);
|
||||||
|
System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
|
||||||
|
byte[] retVal = md5.ComputeHash(file);
|
||||||
|
file.Close();
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < retVal.Length; i++)
|
||||||
|
{
|
||||||
|
sb.Append(retVal[i].ToString("x2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error("to md5 fail,error:" + ex.Message);
|
||||||
|
return "Error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetLengthString(long length)
|
||||||
|
{
|
||||||
|
if (length < 1024)
|
||||||
|
{
|
||||||
|
return $"{length.ToString()} Bytes";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length < 1024 * 1024)
|
||||||
|
{
|
||||||
|
return $"{(length / 1024f):F2} KB";
|
||||||
|
}
|
||||||
|
|
||||||
|
return length < 1024 * 1024 * 1024 ? $"{(length / 1024f / 1024f):F2} MB" : $"{(length / 1024f / 1024f / 1024f):F2} GB";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetByteLengthString(long byteLength)
|
||||||
|
{
|
||||||
|
if (byteLength < 1024L) // 2 ^ 10
|
||||||
|
{
|
||||||
|
return Utility.Text.Format("{0} Bytes", byteLength.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (byteLength < 1048576L) // 2 ^ 20
|
||||||
|
{
|
||||||
|
return Utility.Text.Format("{0} KB", (byteLength / 1024f).ToString("F2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (byteLength < 1073741824L) // 2 ^ 30
|
||||||
|
{
|
||||||
|
return Utility.Text.Format("{0} MB", (byteLength / 1048576f).ToString("F2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (byteLength < 1099511627776L) // 2 ^ 40
|
||||||
|
{
|
||||||
|
return Utility.Text.Format("{0} GB", (byteLength / 1073741824f).ToString("F2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (byteLength < 1125899906842624L) // 2 ^ 50
|
||||||
|
{
|
||||||
|
return Utility.Text.Format("{0} TB", (byteLength / 1099511627776f).ToString("F2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (byteLength < 1152921504606846976L) // 2 ^ 60
|
||||||
|
{
|
||||||
|
return Utility.Text.Format("{0} PB", (byteLength / 1125899906842624f).ToString("F2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Utility.Text.Format("{0} EB", (byteLength / 1152921504606846976f).ToString("F2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string BinToUtf8(byte[] total)
|
||||||
|
{
|
||||||
|
byte[] result = total;
|
||||||
|
if (total[0] == 0xef && total[1] == 0xbb && total[2] == 0xbf)
|
||||||
|
{
|
||||||
|
// utf8文件的前三个字节为特殊占位符,要跳过
|
||||||
|
result = new byte[total.Length - 3];
|
||||||
|
System.Array.Copy(total, 3, result, 0, total.Length - 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
string utf8string = System.Text.Encoding.UTF8.GetString(result);
|
||||||
|
return utf8string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 数据格式转换
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">数据</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string FormatData(long data)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
if (data < 0)
|
||||||
|
data = 0;
|
||||||
|
|
||||||
|
if (data > 1024 * 1024)
|
||||||
|
{
|
||||||
|
result = ((int)(data / (1024 * 1024))).ToString() + "MB";
|
||||||
|
}
|
||||||
|
else if (data > 1024)
|
||||||
|
{
|
||||||
|
result = ((int)(data / 1024)).ToString() + "KB";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = data + "B";
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取文件大小
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">文件路径</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static long GetFileSize(string path)
|
||||||
|
{
|
||||||
|
using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||||
|
{
|
||||||
|
return file.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Utility/Utility.File.cs.meta
Normal file
11
Assets/TEngine/Runtime/Utility/Utility.File.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6d1483cbdd562774a95cb697ed574e43
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
134
Assets/TEngine/Runtime/Utility/Utility.Folder.cs
Normal file
134
Assets/TEngine/Runtime/Utility/Utility.Folder.cs
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Folder 相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static partial class Folder
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 清理文件夹。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">文件夹路径。</param>
|
||||||
|
/// <returns>操作成功。</returns>
|
||||||
|
public static bool ClearFolder(string path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var di = new DirectoryInfo(path);
|
||||||
|
if (!di.Exists)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var file in di.GetFiles())
|
||||||
|
{
|
||||||
|
file.Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var dir in di.GetDirectories())
|
||||||
|
{
|
||||||
|
dir.Delete(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException($"ClearFolder invalid:{e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝文件到根目录。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceRootPath">源文件目录。</param>
|
||||||
|
/// <param name="destRootPath">目标文件目录。</param>
|
||||||
|
/// <param name="searchOption">查找选项。</param>
|
||||||
|
/// <returns>操作成功。</returns>
|
||||||
|
public static bool CopyFilesToRootPath(string sourceRootPath, string destRootPath, SearchOption searchOption = SearchOption.AllDirectories)
|
||||||
|
{
|
||||||
|
string[] fileNames = Directory.GetFiles(sourceRootPath, "*", searchOption);
|
||||||
|
foreach (string fileName in fileNames)
|
||||||
|
{
|
||||||
|
string destFileName = System.IO.Path.Combine(destRootPath, fileName.Substring(sourceRootPath.Length));
|
||||||
|
FileInfo destFileInfo = new FileInfo(destFileName);
|
||||||
|
if (destFileInfo.Directory != null && !destFileInfo.Directory.Exists)
|
||||||
|
{
|
||||||
|
destFileInfo.Directory.Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.IO.File.Copy(fileName, destFileName, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝文件夹。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="srcPath">需要被拷贝的文件夹路径。</param>
|
||||||
|
/// <param name="tarPath">拷贝目标路径。</param>
|
||||||
|
public static bool CopyFolder(string srcPath, string tarPath)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(srcPath))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(tarPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(tarPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
//获得源文件下所有文件
|
||||||
|
List<string> files = new List<string>(Directory.GetFiles(srcPath));
|
||||||
|
files.ForEach(f =>
|
||||||
|
{
|
||||||
|
string destFile = System.IO.Path.Combine(tarPath, System.IO.Path.GetFileName(f));
|
||||||
|
System.IO.File.Copy(f, destFile, true); //覆盖模式
|
||||||
|
});
|
||||||
|
|
||||||
|
//获得源文件下所有目录文件
|
||||||
|
List<string> folders = new List<string>(Directory.GetDirectories(srcPath));
|
||||||
|
folders.ForEach(f =>
|
||||||
|
{
|
||||||
|
string destDir = System.IO.Path.Combine(tarPath, System.IO.Path.GetFileName(f));
|
||||||
|
CopyFolder(f, destDir); //递归实现子文件夹拷贝
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝文件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceRootPath">源文件目录。</param>
|
||||||
|
/// <param name="destRootPath">目标文件目录。</param>
|
||||||
|
/// <param name="searchOption">搜索选项。</param>
|
||||||
|
/// <returns>操作成功。</returns>
|
||||||
|
public static bool CopyFiles(string sourceRootPath, string destRootPath, SearchOption searchOption = SearchOption.AllDirectories)
|
||||||
|
{
|
||||||
|
string[] fileNames = Directory.GetFiles(sourceRootPath, "*", searchOption);
|
||||||
|
foreach (string fileName in fileNames)
|
||||||
|
{
|
||||||
|
FileInfo sourceFileInfo = new FileInfo(fileName);
|
||||||
|
string destFileName = System.IO.Path.Combine(destRootPath, sourceFileInfo.Name);
|
||||||
|
FileInfo destFileInfo = new FileInfo(destFileName);
|
||||||
|
if (destFileInfo.Directory != null && !destFileInfo.Directory.Exists)
|
||||||
|
{
|
||||||
|
destFileInfo.Directory.Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.IO.File.Copy(fileName, destFileName, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Utility/Utility.Folder.cs.meta
Normal file
11
Assets/TEngine/Runtime/Utility/Utility.Folder.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 30d9951d450df9647a77c814ea8f68f6
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
39
Assets/TEngine/Runtime/Utility/Utility.Json.IJsonHelper.cs
Normal file
39
Assets/TEngine/Runtime/Utility/Utility.Json.IJsonHelper.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
public static partial class Json
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// JSON 辅助器接口。
|
||||||
|
/// </summary>
|
||||||
|
public interface IJsonHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 将对象序列化为 JSON 字符串。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">要序列化的对象。</param>
|
||||||
|
/// <returns>序列化后的 JSON 字符串。</returns>
|
||||||
|
string ToJson(object obj);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 JSON 字符串反序列化为对象。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">对象类型。</typeparam>
|
||||||
|
/// <param name="json">要反序列化的 JSON 字符串。</param>
|
||||||
|
/// <returns>反序列化后的对象。</returns>
|
||||||
|
T ToObject<T>(string json);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 JSON 字符串反序列化为对象。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objectType">对象类型。</param>
|
||||||
|
/// <param name="json">要反序列化的 JSON 字符串。</param>
|
||||||
|
/// <returns>反序列化后的对象。</returns>
|
||||||
|
object ToObject(Type objectType, string json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 54fba14fdfb53ab4f9edcd7eb3a9bc4c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
112
Assets/TEngine/Runtime/Utility/Utility.Json.cs
Normal file
112
Assets/TEngine/Runtime/Utility/Utility.Json.cs
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// JSON 相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static partial class Json
|
||||||
|
{
|
||||||
|
private static IJsonHelper s_JsonHelper = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置 JSON 辅助器。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="jsonHelper">要设置的 JSON 辅助器。</param>
|
||||||
|
public static void SetJsonHelper(IJsonHelper jsonHelper)
|
||||||
|
{
|
||||||
|
s_JsonHelper = jsonHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将对象序列化为 JSON 字符串。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">要序列化的对象。</param>
|
||||||
|
/// <returns>序列化后的 JSON 字符串。</returns>
|
||||||
|
public static string ToJson(object obj)
|
||||||
|
{
|
||||||
|
if (s_JsonHelper == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("JSON helper is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return s_JsonHelper.ToJson(obj);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
if (exception is GameFrameworkException)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new GameFrameworkException(Text.Format("Can not convert to JSON with exception '{0}'.", exception), exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 JSON 字符串反序列化为对象。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">对象类型。</typeparam>
|
||||||
|
/// <param name="json">要反序列化的 JSON 字符串。</param>
|
||||||
|
/// <returns>反序列化后的对象。</returns>
|
||||||
|
public static T ToObject<T>(string json)
|
||||||
|
{
|
||||||
|
if (s_JsonHelper == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("JSON helper is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return s_JsonHelper.ToObject<T>(json);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
if (exception is GameFrameworkException)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new GameFrameworkException(Text.Format("Can not convert to object with exception '{0}'.", exception), exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 JSON 字符串反序列化为对象。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objectType">对象类型。</param>
|
||||||
|
/// <param name="json">要反序列化的 JSON 字符串。</param>
|
||||||
|
/// <returns>反序列化后的对象。</returns>
|
||||||
|
public static object ToObject(Type objectType, string json)
|
||||||
|
{
|
||||||
|
if (s_JsonHelper == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("JSON helper is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objectType == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Object type is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return s_JsonHelper.ToObject(objectType, json);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
if (exception is GameFrameworkException)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new GameFrameworkException(Text.Format("Can not convert to object with exception '{0}'.", exception), exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Utility/Utility.Json.cs.meta
Normal file
11
Assets/TEngine/Runtime/Utility/Utility.Json.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4ee7fcac5a1ebab449eba2456434d3e6
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
233
Assets/TEngine/Runtime/Utility/Utility.Marshal.cs
Normal file
233
Assets/TEngine/Runtime/Utility/Utility.Marshal.cs
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Marshal 相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static class Marshal
|
||||||
|
{
|
||||||
|
private const int BlockSize = 1024 * 4;
|
||||||
|
private static IntPtr s_CachedHGlobalPtr = IntPtr.Zero;
|
||||||
|
private static int s_CachedHGlobalSize = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取缓存的从进程的非托管内存中分配的内存的大小。
|
||||||
|
/// </summary>
|
||||||
|
public static int CachedHGlobalSize
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return s_CachedHGlobalSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 确保从进程的非托管内存中分配足够大小的内存并缓存。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ensureSize">要确保从进程的非托管内存中分配内存的大小。</param>
|
||||||
|
public static void EnsureCachedHGlobalSize(int ensureSize)
|
||||||
|
{
|
||||||
|
if (ensureSize < 0)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Ensure size is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_CachedHGlobalPtr == IntPtr.Zero || s_CachedHGlobalSize < ensureSize)
|
||||||
|
{
|
||||||
|
FreeCachedHGlobal();
|
||||||
|
int size = (ensureSize - 1 + BlockSize) / BlockSize * BlockSize;
|
||||||
|
s_CachedHGlobalPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(size);
|
||||||
|
s_CachedHGlobalSize = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放缓存的从进程的非托管内存中分配的内存。
|
||||||
|
/// </summary>
|
||||||
|
public static void FreeCachedHGlobal()
|
||||||
|
{
|
||||||
|
if (s_CachedHGlobalPtr != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
System.Runtime.InteropServices.Marshal.FreeHGlobal(s_CachedHGlobalPtr);
|
||||||
|
s_CachedHGlobalPtr = IntPtr.Zero;
|
||||||
|
s_CachedHGlobalSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将数据从对象转换为二进制流。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要转换的对象的类型。</typeparam>
|
||||||
|
/// <param name="structure">要转换的对象。</param>
|
||||||
|
/// <returns>存储转换结果的二进制流。</returns>
|
||||||
|
public static byte[] StructureToBytes<T>(T structure)
|
||||||
|
{
|
||||||
|
return StructureToBytes(structure, System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将数据从对象转换为二进制流。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要转换的对象的类型。</typeparam>
|
||||||
|
/// <param name="structure">要转换的对象。</param>
|
||||||
|
/// <param name="structureSize">要转换的对象的大小。</param>
|
||||||
|
/// <returns>存储转换结果的二进制流。</returns>
|
||||||
|
internal static byte[] StructureToBytes<T>(T structure, int structureSize)
|
||||||
|
{
|
||||||
|
if (structureSize < 0)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Structure size is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureCachedHGlobalSize(structureSize);
|
||||||
|
System.Runtime.InteropServices.Marshal.StructureToPtr(structure, s_CachedHGlobalPtr, true);
|
||||||
|
byte[] result = new byte[structureSize];
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(s_CachedHGlobalPtr, result, 0, structureSize);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将数据从对象转换为二进制流。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要转换的对象的类型。</typeparam>
|
||||||
|
/// <param name="structure">要转换的对象。</param>
|
||||||
|
/// <param name="result">存储转换结果的二进制流。</param>
|
||||||
|
public static void StructureToBytes<T>(T structure, byte[] result)
|
||||||
|
{
|
||||||
|
StructureToBytes(structure, System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), result, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将数据从对象转换为二进制流。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要转换的对象的类型。</typeparam>
|
||||||
|
/// <param name="structure">要转换的对象。</param>
|
||||||
|
/// <param name="structureSize">要转换的对象的大小。</param>
|
||||||
|
/// <param name="result">存储转换结果的二进制流。</param>
|
||||||
|
internal static void StructureToBytes<T>(T structure, int structureSize, byte[] result)
|
||||||
|
{
|
||||||
|
StructureToBytes(structure, structureSize, result, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将数据从对象转换为二进制流。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要转换的对象的类型。</typeparam>
|
||||||
|
/// <param name="structure">要转换的对象。</param>
|
||||||
|
/// <param name="result">存储转换结果的二进制流。</param>
|
||||||
|
/// <param name="startIndex">写入存储转换结果的二进制流的起始位置。</param>
|
||||||
|
public static void StructureToBytes<T>(T structure, byte[] result, int startIndex)
|
||||||
|
{
|
||||||
|
StructureToBytes(structure, System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), result, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将数据从对象转换为二进制流。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要转换的对象的类型。</typeparam>
|
||||||
|
/// <param name="structure">要转换的对象。</param>
|
||||||
|
/// <param name="structureSize">要转换的对象的大小。</param>
|
||||||
|
/// <param name="result">存储转换结果的二进制流。</param>
|
||||||
|
/// <param name="startIndex">写入存储转换结果的二进制流的起始位置。</param>
|
||||||
|
internal static void StructureToBytes<T>(T structure, int structureSize, byte[] result, int startIndex)
|
||||||
|
{
|
||||||
|
if (structureSize < 0)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Structure size is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Result is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startIndex < 0)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Start index is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startIndex + structureSize > result.Length)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Result length is not enough.");
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureCachedHGlobalSize(structureSize);
|
||||||
|
System.Runtime.InteropServices.Marshal.StructureToPtr(structure, s_CachedHGlobalPtr, true);
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(s_CachedHGlobalPtr, result, startIndex, structureSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将数据从二进制流转换为对象。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要转换的对象的类型。</typeparam>
|
||||||
|
/// <param name="buffer">要转换的二进制流。</param>
|
||||||
|
/// <returns>存储转换结果的对象。</returns>
|
||||||
|
public static T BytesToStructure<T>(byte[] buffer)
|
||||||
|
{
|
||||||
|
return BytesToStructure<T>(System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将数据从二进制流转换为对象。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要转换的对象的类型。</typeparam>
|
||||||
|
/// <param name="buffer">要转换的二进制流。</param>
|
||||||
|
/// <param name="startIndex">读取要转换的二进制流的起始位置。</param>
|
||||||
|
/// <returns>存储转换结果的对象。</returns>
|
||||||
|
public static T BytesToStructure<T>(byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
return BytesToStructure<T>(System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), buffer, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将数据从二进制流转换为对象。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要转换的对象的类型。</typeparam>
|
||||||
|
/// <param name="structureSize">要转换的对象的大小。</param>
|
||||||
|
/// <param name="buffer">要转换的二进制流。</param>
|
||||||
|
/// <returns>存储转换结果的对象。</returns>
|
||||||
|
internal static T BytesToStructure<T>(int structureSize, byte[] buffer)
|
||||||
|
{
|
||||||
|
return BytesToStructure<T>(structureSize, buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将数据从二进制流转换为对象。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要转换的对象的类型。</typeparam>
|
||||||
|
/// <param name="structureSize">要转换的对象的大小。</param>
|
||||||
|
/// <param name="buffer">要转换的二进制流。</param>
|
||||||
|
/// <param name="startIndex">读取要转换的二进制流的起始位置。</param>
|
||||||
|
/// <returns>存储转换结果的对象。</returns>
|
||||||
|
internal static T BytesToStructure<T>(int structureSize, byte[] buffer, int startIndex)
|
||||||
|
{
|
||||||
|
if (structureSize < 0)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Structure size is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Buffer is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startIndex < 0)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Start index is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startIndex + structureSize > buffer.Length)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Buffer length is not enough.");
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureCachedHGlobalSize(structureSize);
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(buffer, startIndex, s_CachedHGlobalPtr, structureSize);
|
||||||
|
return (T)System.Runtime.InteropServices.Marshal.PtrToStructure(s_CachedHGlobalPtr, typeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Utility/Utility.Marshal.cs.meta
Normal file
11
Assets/TEngine/Runtime/Utility/Utility.Marshal.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e4eaf023a908b6847bc7c1b16e025fcd
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
93
Assets/TEngine/Runtime/Utility/Utility.Path.cs
Normal file
93
Assets/TEngine/Runtime/Utility/Utility.Path.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 路径相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static class Path
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取规范的路径。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">要规范的路径。</param>
|
||||||
|
/// <returns>规范的路径。</returns>
|
||||||
|
public static string GetRegularPath(string path)
|
||||||
|
{
|
||||||
|
if (path == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.Replace('\\', '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取远程格式的路径(带有file:// 或 http:// 前缀)。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">原始路径。</param>
|
||||||
|
/// <returns>远程格式路径。</returns>
|
||||||
|
public static string GetRemotePath(string path)
|
||||||
|
{
|
||||||
|
string regularPath = GetRegularPath(path);
|
||||||
|
if (regularPath == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return regularPath.Contains("://") ? regularPath : ("file:///" + regularPath).Replace("file:////", "file:///");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除空文件夹。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="directoryName">要处理的文件夹名称。</param>
|
||||||
|
/// <returns>是否移除空文件夹成功。</returns>
|
||||||
|
public static bool RemoveEmptyDirectory(string directoryName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(directoryName))
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Directory name is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(directoryName))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不使用 SearchOption.AllDirectories,以便于在可能产生异常的环境下删除尽可能多的目录
|
||||||
|
string[] subDirectoryNames = Directory.GetDirectories(directoryName, "*");
|
||||||
|
int subDirectoryCount = subDirectoryNames.Length;
|
||||||
|
foreach (string subDirectoryName in subDirectoryNames)
|
||||||
|
{
|
||||||
|
if (RemoveEmptyDirectory(subDirectoryName))
|
||||||
|
{
|
||||||
|
subDirectoryCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subDirectoryCount > 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Directory.GetFiles(directoryName, "*").Length > 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory.Delete(directoryName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Utility/Utility.Path.cs.meta
Normal file
11
Assets/TEngine/Runtime/Utility/Utility.Path.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ffffdb31a0e4d6e49a95d47aa1976e94
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
72
Assets/TEngine/Runtime/Utility/Utility.Random.cs
Normal file
72
Assets/TEngine/Runtime/Utility/Utility.Random.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 随机相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static class Random
|
||||||
|
{
|
||||||
|
private static System.Random s_Random = new System.Random((int)DateTime.UtcNow.Ticks);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置随机数种子。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="seed">随机数种子。</param>
|
||||||
|
public static void SetSeed(int seed)
|
||||||
|
{
|
||||||
|
s_Random = new System.Random(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回非负随机数。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>大于等于零且小于 System.Int32.MaxValue 的 32 位带符号整数。</returns>
|
||||||
|
public static int GetRandom()
|
||||||
|
{
|
||||||
|
return s_Random.Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回一个小于所指定最大值的非负随机数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="maxValue">要生成的随机数的上界(随机数不能取该上界值)。maxValue 必须大于等于零。</param>
|
||||||
|
/// <returns>大于等于零且小于 maxValue 的 32 位带符号整数,即:返回值的范围通常包括零但不包括 maxValue。不过,如果 maxValue 等于零,则返回 maxValue。</returns>
|
||||||
|
public static int GetRandom(int maxValue)
|
||||||
|
{
|
||||||
|
return s_Random.Next(maxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回一个指定范围内的随机数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="minValue">返回的随机数的下界(随机数可取该下界值)。</param>
|
||||||
|
/// <param name="maxValue">返回的随机数的上界(随机数不能取该上界值)。maxValue 必须大于等于 minValue。</param>
|
||||||
|
/// <returns>一个大于等于 minValue 且小于 maxValue 的 32 位带符号整数,即:返回的值范围包括 minValue 但不包括 maxValue。如果 minValue 等于 maxValue,则返回 minValue。</returns>
|
||||||
|
public static int GetRandom(int minValue, int maxValue)
|
||||||
|
{
|
||||||
|
return s_Random.Next(minValue, maxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回一个介于 0.0 和 1.0 之间的随机数。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>大于等于 0.0 并且小于 1.0 的双精度浮点数。</returns>
|
||||||
|
public static double GetRandomDouble()
|
||||||
|
{
|
||||||
|
return s_Random.NextDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用随机数填充指定字节数组的元素。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">包含随机数的字节数组。</param>
|
||||||
|
public static void GetRandomBytes(byte[] buffer)
|
||||||
|
{
|
||||||
|
s_Random.NextBytes(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Utility/Utility.Random.cs.meta
Normal file
11
Assets/TEngine/Runtime/Utility/Utility.Random.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d141c00a7ebf38141b1661ed1acb48f1
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
391
Assets/TEngine/Runtime/Utility/Utility.Unity.cs
Normal file
391
Assets/TEngine/Runtime/Utility/Utility.Unity.cs
Normal file
@@ -0,0 +1,391 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Events;
|
||||||
|
using UnityEngine.Internal;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unity相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static partial class Unity
|
||||||
|
{
|
||||||
|
private static GameObject _entity;
|
||||||
|
private static MainBehaviour _behaviour;
|
||||||
|
|
||||||
|
#region 控制协程Coroutine
|
||||||
|
|
||||||
|
public static Coroutine StartCoroutine(string methodName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(methodName))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_MakeEntity();
|
||||||
|
return _behaviour.StartCoroutine(methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Coroutine StartCoroutine(IEnumerator routine)
|
||||||
|
{
|
||||||
|
if (routine == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_MakeEntity();
|
||||||
|
return _behaviour.StartCoroutine(routine);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Coroutine StartCoroutine(string methodName, [DefaultValue("null")] object value)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(methodName))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_MakeEntity();
|
||||||
|
return _behaviour.StartCoroutine(methodName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StopCoroutine(string methodName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(methodName))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_entity != null)
|
||||||
|
{
|
||||||
|
_behaviour.StopCoroutine(methodName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StopCoroutine(IEnumerator routine)
|
||||||
|
{
|
||||||
|
if (routine == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_entity != null)
|
||||||
|
{
|
||||||
|
_behaviour.StopCoroutine(routine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StopCoroutine(Coroutine routine)
|
||||||
|
{
|
||||||
|
if (routine == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_entity != null)
|
||||||
|
{
|
||||||
|
_behaviour.StopCoroutine(routine);
|
||||||
|
routine = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StopAllCoroutines()
|
||||||
|
{
|
||||||
|
if (_entity != null)
|
||||||
|
{
|
||||||
|
_behaviour.StopAllCoroutines();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 注入UnityUpdate/FixedUpdate/LateUpdate
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 为给外部提供的 添加帧更新事件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fun"></param>
|
||||||
|
public static void AddUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
_MakeEntity();
|
||||||
|
_behaviour.AddUpdateListener(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 为给外部提供的 添加物理帧更新事件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fun"></param>
|
||||||
|
public static void AddFixedUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
_MakeEntity();
|
||||||
|
_behaviour.AddFixedUpdateListener(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 为给外部提供的 添加Late帧更新事件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fun"></param>
|
||||||
|
public static void AddLateUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
_MakeEntity();
|
||||||
|
_behaviour.AddLateUpdateListener(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除帧更新事件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fun"></param>
|
||||||
|
public static void RemoveUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
_MakeEntity();
|
||||||
|
_behaviour.RemoveUpdateListener(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除物理帧更新事件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fun"></param>
|
||||||
|
public static void RemoveFixedUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
_MakeEntity();
|
||||||
|
_behaviour.RemoveFixedUpdateListener(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除Late帧更新事件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fun"></param>
|
||||||
|
public static void RemoveLateUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
_MakeEntity();
|
||||||
|
_behaviour.RemoveLateUpdateListener(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Unity Events 注入
|
||||||
|
/// <summary>
|
||||||
|
/// 为给外部提供的Destroy注册事件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fun"></param>
|
||||||
|
public static void AddDestroyListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
_MakeEntity();
|
||||||
|
_behaviour.AddDestroyListener(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 为给外部提供的Destroy反注册事件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fun"></param>
|
||||||
|
public static void RemoveDestroyListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
_MakeEntity();
|
||||||
|
_behaviour.RemoveDestroyListener(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 为给外部提供的OnDrawGizmos注册事件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fun"></param>
|
||||||
|
public static void AddOnDrawGizmosListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
_MakeEntity();
|
||||||
|
_behaviour.RemoveDestroyListener(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 为给外部提供的OnDrawGizmos反注册事件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fun"></param>
|
||||||
|
public static void RemoveOnDrawGizmosListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
_MakeEntity();
|
||||||
|
_behaviour.RemoveDestroyListener(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 为给外部提供的OnApplicationPause注册事件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fun"></param>
|
||||||
|
public static void AddOnApplicationPauseListener(UnityAction<bool> fun)
|
||||||
|
{
|
||||||
|
_MakeEntity();
|
||||||
|
_behaviour.AddOnApplicationPauseListener(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 为给外部提供的OnApplicationPause反注册事件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fun"></param>
|
||||||
|
public static void RemoveOnApplicationPauseListener(UnityAction<bool> fun)
|
||||||
|
{
|
||||||
|
_MakeEntity();
|
||||||
|
_behaviour.AddOnApplicationPauseListener(fun);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放Behaviour生命周期。
|
||||||
|
/// </summary>
|
||||||
|
public static void Release()
|
||||||
|
{
|
||||||
|
_MakeEntity();
|
||||||
|
_behaviour.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void _MakeEntity()
|
||||||
|
{
|
||||||
|
if (_entity != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_entity = new GameObject("__MonoUtility__")
|
||||||
|
{
|
||||||
|
hideFlags = HideFlags.HideAndDontSave
|
||||||
|
};
|
||||||
|
_entity.SetActive(true);
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
if (Application.isPlaying)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
Object.DontDestroyOnLoad(_entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnityEngine.Assertions.Assert.IsFalse(_behaviour);
|
||||||
|
_behaviour = _entity.AddComponent<MainBehaviour>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MainBehaviour : MonoBehaviour
|
||||||
|
{
|
||||||
|
private event UnityAction updateEvent;
|
||||||
|
private event UnityAction fixedUpdateEvent;
|
||||||
|
private event UnityAction lateUpdateEvent;
|
||||||
|
private event UnityAction destroyEvent;
|
||||||
|
private event UnityAction onDrawGizmosEvent;
|
||||||
|
private event UnityAction<bool> onApplicationPause;
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
if (updateEvent != null)
|
||||||
|
{
|
||||||
|
updateEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixedUpdate()
|
||||||
|
{
|
||||||
|
if (fixedUpdateEvent != null)
|
||||||
|
{
|
||||||
|
fixedUpdateEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LateUpdate()
|
||||||
|
{
|
||||||
|
if (lateUpdateEvent != null)
|
||||||
|
{
|
||||||
|
lateUpdateEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
if (destroyEvent != null)
|
||||||
|
{
|
||||||
|
destroyEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDrawGizmos()
|
||||||
|
{
|
||||||
|
if (onDrawGizmosEvent != null)
|
||||||
|
{
|
||||||
|
onDrawGizmosEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnApplicationPause(bool pauseStatus)
|
||||||
|
{
|
||||||
|
if (onApplicationPause != null)
|
||||||
|
{
|
||||||
|
onApplicationPause(pauseStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddLateUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
lateUpdateEvent += fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveLateUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
lateUpdateEvent -= fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddFixedUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
fixedUpdateEvent += fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveFixedUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
fixedUpdateEvent -= fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
updateEvent += fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveUpdateListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
updateEvent -= fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddDestroyListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
destroyEvent += fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveDestroyListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
destroyEvent -= fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddOnDrawGizmosListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
onDrawGizmosEvent += fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveOnDrawGizmosListener(UnityAction fun)
|
||||||
|
{
|
||||||
|
onDrawGizmosEvent -= fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddOnApplicationPauseListener(UnityAction<bool> fun)
|
||||||
|
{
|
||||||
|
onApplicationPause += fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveOnApplicationPauseListener(UnityAction<bool> fun)
|
||||||
|
{
|
||||||
|
onApplicationPause -= fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Release()
|
||||||
|
{
|
||||||
|
updateEvent = null;
|
||||||
|
fixedUpdateEvent = null;
|
||||||
|
lateUpdateEvent = null;
|
||||||
|
onDrawGizmosEvent = null;
|
||||||
|
destroyEvent = null;
|
||||||
|
onApplicationPause = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Utility/Utility.Unity.cs.meta
Normal file
11
Assets/TEngine/Runtime/Utility/Utility.Unity.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1b5e063f21f5cba4d85471c343c33271
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
87
Assets/TEngine/Runtime/Utility/Utility.Verifier.Crc32.cs
Normal file
87
Assets/TEngine/Runtime/Utility/Utility.Verifier.Crc32.cs
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
public static partial class Verifier
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// CRC32 算法。
|
||||||
|
/// </summary>
|
||||||
|
private sealed class Crc32
|
||||||
|
{
|
||||||
|
private const int TableLength = 256;
|
||||||
|
private const uint DefaultPolynomial = 0xedb88320;
|
||||||
|
private const uint DefaultSeed = 0xffffffff;
|
||||||
|
|
||||||
|
private readonly uint m_Seed;
|
||||||
|
private readonly uint[] m_Table;
|
||||||
|
private uint m_Hash;
|
||||||
|
|
||||||
|
public Crc32()
|
||||||
|
: this(DefaultPolynomial, DefaultSeed)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Crc32(uint polynomial, uint seed)
|
||||||
|
{
|
||||||
|
m_Seed = seed;
|
||||||
|
m_Table = InitializeTable(polynomial);
|
||||||
|
m_Hash = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
m_Hash = m_Seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HashCore(byte[] bytes, int offset, int length)
|
||||||
|
{
|
||||||
|
m_Hash = CalculateHash(m_Table, m_Hash, bytes, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint HashFinal()
|
||||||
|
{
|
||||||
|
return ~m_Hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint CalculateHash(uint[] table, uint value, byte[] bytes, int offset, int length)
|
||||||
|
{
|
||||||
|
int last = offset + length;
|
||||||
|
for (int i = offset; i < last; i++)
|
||||||
|
{
|
||||||
|
unchecked
|
||||||
|
{
|
||||||
|
value = (value >> 8) ^ table[bytes[i] ^ value & 0xff];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint[] InitializeTable(uint polynomial)
|
||||||
|
{
|
||||||
|
uint[] table = new uint[TableLength];
|
||||||
|
for (int i = 0; i < TableLength; i++)
|
||||||
|
{
|
||||||
|
uint entry = (uint)i;
|
||||||
|
for (int j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
if ((entry & 1) == 1)
|
||||||
|
{
|
||||||
|
entry = (entry >> 1) ^ polynomial;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table[i] = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9a7d0ce566dde9749b214b5ae065ac3d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
188
Assets/TEngine/Runtime/Utility/Utility.Verifier.cs
Normal file
188
Assets/TEngine/Runtime/Utility/Utility.Verifier.cs
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 校验相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static partial class Verifier
|
||||||
|
{
|
||||||
|
private const int CachedBytesLength = 0x1000;
|
||||||
|
private static readonly byte[] s_CachedBytes = new byte[CachedBytesLength];
|
||||||
|
private static readonly Crc32 s_Algorithm = new Crc32();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算二进制流的 CRC32。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">指定的二进制流。</param>
|
||||||
|
/// <returns>计算后的 CRC32。</returns>
|
||||||
|
public static int GetCrc32(byte[] bytes)
|
||||||
|
{
|
||||||
|
if (bytes == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Bytes is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetCrc32(bytes, 0, bytes.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算二进制流的 CRC32。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">指定的二进制流。</param>
|
||||||
|
/// <param name="offset">二进制流的偏移。</param>
|
||||||
|
/// <param name="length">二进制流的长度。</param>
|
||||||
|
/// <returns>计算后的 CRC32。</returns>
|
||||||
|
public static int GetCrc32(byte[] bytes, int offset, int length)
|
||||||
|
{
|
||||||
|
if (bytes == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Bytes is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset < 0 || length < 0 || offset + length > bytes.Length)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Offset or length is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
s_Algorithm.HashCore(bytes, offset, length);
|
||||||
|
int result = (int)s_Algorithm.HashFinal();
|
||||||
|
s_Algorithm.Initialize();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算二进制流的 CRC32。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">指定的二进制流。</param>
|
||||||
|
/// <returns>计算后的 CRC32。</returns>
|
||||||
|
public static int GetCrc32(Stream stream)
|
||||||
|
{
|
||||||
|
if (stream == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Stream is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int bytesRead = stream.Read(s_CachedBytes, 0, CachedBytesLength);
|
||||||
|
if (bytesRead > 0)
|
||||||
|
{
|
||||||
|
s_Algorithm.HashCore(s_CachedBytes, 0, bytesRead);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = (int)s_Algorithm.HashFinal();
|
||||||
|
s_Algorithm.Initialize();
|
||||||
|
Array.Clear(s_CachedBytes, 0, CachedBytesLength);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取 CRC32 数值的二进制数组。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="crc32">CRC32 数值。</param>
|
||||||
|
/// <returns>CRC32 数值的二进制数组。</returns>
|
||||||
|
public static byte[] GetCrc32Bytes(int crc32)
|
||||||
|
{
|
||||||
|
return new byte[] { (byte)((crc32 >> 24) & 0xff), (byte)((crc32 >> 16) & 0xff), (byte)((crc32 >> 8) & 0xff), (byte)(crc32 & 0xff) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取 CRC32 数值的二进制数组。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="crc32">CRC32 数值。</param>
|
||||||
|
/// <param name="bytes">要存放结果的数组。</param>
|
||||||
|
public static void GetCrc32Bytes(int crc32, byte[] bytes)
|
||||||
|
{
|
||||||
|
GetCrc32Bytes(crc32, bytes, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取 CRC32 数值的二进制数组。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="crc32">CRC32 数值。</param>
|
||||||
|
/// <param name="bytes">要存放结果的数组。</param>
|
||||||
|
/// <param name="offset">CRC32 数值的二进制数组在结果数组内的起始位置。</param>
|
||||||
|
public static void GetCrc32Bytes(int crc32, byte[] bytes, int offset)
|
||||||
|
{
|
||||||
|
if (bytes == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Result is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset < 0 || offset + 4 > bytes.Length)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Offset or length is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes[offset] = (byte)((crc32 >> 24) & 0xff);
|
||||||
|
bytes[offset + 1] = (byte)((crc32 >> 16) & 0xff);
|
||||||
|
bytes[offset + 2] = (byte)((crc32 >> 8) & 0xff);
|
||||||
|
bytes[offset + 3] = (byte)(crc32 & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int GetCrc32(Stream stream, byte[] code, int length)
|
||||||
|
{
|
||||||
|
if (stream == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Stream is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code == null)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Code is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int codeLength = code.Length;
|
||||||
|
if (codeLength <= 0)
|
||||||
|
{
|
||||||
|
throw new GameFrameworkException("Code length is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int bytesLength = (int)stream.Length;
|
||||||
|
if (length < 0 || length > bytesLength)
|
||||||
|
{
|
||||||
|
length = bytesLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
int codeIndex = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int bytesRead = stream.Read(s_CachedBytes, 0, CachedBytesLength);
|
||||||
|
if (bytesRead > 0)
|
||||||
|
{
|
||||||
|
if (length > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < bytesRead && i < length; i++)
|
||||||
|
{
|
||||||
|
s_CachedBytes[i] ^= code[codeIndex++];
|
||||||
|
codeIndex %= codeLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
length -= bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_Algorithm.HashCore(s_CachedBytes, 0, bytesRead);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = (int)s_Algorithm.HashFinal();
|
||||||
|
s_Algorithm.Initialize();
|
||||||
|
Array.Clear(s_CachedBytes, 0, CachedBytesLength);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Utility/Utility.Verifier.cs.meta
Normal file
11
Assets/TEngine/Runtime/Utility/Utility.Verifier.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 968c23f2e5a22ec4f884c9932c8fa90b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Reference in New Issue
Block a user