diff --git a/Assets/YooAsset/Runtime/Utility/BufferDefine.cs b/Assets/YooAsset/Runtime/Utility/BufferDefine.cs new file mode 100644 index 0000000..3d4f24f --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/BufferDefine.cs @@ -0,0 +1,22 @@ +using System.Runtime.InteropServices; + +namespace YooAsset +{ + [StructLayout(LayoutKind.Explicit)] + internal struct DoubleContent + { + [FieldOffset(0)] + public double doubleValue; + [FieldOffset(0)] + public ulong ulongValue; + } + + [StructLayout(LayoutKind.Explicit)] + internal struct FloatContent + { + [FieldOffset(0)] + public float floatValue; + [FieldOffset(0)] + public uint uintValue; + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Utility/BufferDefine.cs.meta b/Assets/YooAsset/Runtime/Utility/BufferDefine.cs.meta new file mode 100644 index 0000000..6e67548 --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/BufferDefine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d89dfb0a9c98df548aa15f76dc8c2ac0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/Utility/BufferReader.cs b/Assets/YooAsset/Runtime/Utility/BufferReader.cs new file mode 100644 index 0000000..350e253 --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/BufferReader.cs @@ -0,0 +1,210 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; +using UnityEngine; + +namespace YooAsset +{ + internal class BufferReader + { + private readonly byte[] _buffer; + private int _index = 0; + + public BufferReader(byte[] data) + { + _buffer = data; + } + + /// + /// 缓冲区容量 + /// + public int Capacity + { + get { return _buffer.Length; } + } + + public byte[] ReadBytes(int count) + { + CheckReaderIndex(count); + var data = new byte[count]; + Buffer.BlockCopy(_buffer, _index, data, 0, count); + _index += count; + return data; + } + public byte ReadByte() + { + CheckReaderIndex(1); + return _buffer[_index++]; + } + public sbyte ReadSbyte() + { + return (sbyte)ReadByte(); + } + + public bool ReadBool() + { + CheckReaderIndex(1); + return _buffer[_index++] == 1; + } + public short ReadInt16() + { + return (short)ReadUInt16(); + } + public ushort ReadUInt16() + { + CheckReaderIndex(2); + ushort value = 0; + for (int i = 0; i < 2; i++) + { + value += (ushort)(_buffer[_index++] << (i * 8)); + } + return value; + } + public int ReadInt32() + { + return (int)ReadUInt32(); + } + public uint ReadUInt32() + { + CheckReaderIndex(4); + uint value = 0; + for (int i = 0; i < 4; i++) + { + value += (uint)(_buffer[_index++] << (i * 8)); + } + return value; + } + public long ReadInt64() + { + return (long)ReadUInt64(); + } + public ulong ReadUInt64() + { + CheckReaderIndex(8); + ulong value = 0; + for (int i = 0; i < 8; i++) + { + value += (ulong)(_buffer[_index++] << (i * 8)); + } + return value; + } + + public float ReadSingle() + { + CheckReaderIndex(4); + FloatContent content = new FloatContent(); + content.uintValue = ReadUInt32(); + return content.floatValue; + } + public double ReadDouble() + { + CheckReaderIndex(8); + DoubleContent content = new DoubleContent(); + content.ulongValue = ReadUInt64(); + return content.doubleValue; + } + + public string ReadUTF8() + { + ushort count = ReadUInt16(); + if (count == 0) + return string.Empty; + + CheckReaderIndex(count); + string value = Encoding.UTF8.GetString(_buffer, _index, count); + _index += count; + return value; + } + public int[] ReadInt32Array() + { + ushort count = ReadUInt16(); + int[] values = new int[count]; + for (int i = 0; i < count; i++) + { + values[i] = ReadInt32(); + } + return values; + } + public long[] ReadInt64Array() + { + ushort count = ReadUInt16(); + long[] values = new long[count]; + for (int i = 0; i < count; i++) + { + values[i] = ReadInt64(); + } + return values; + } + public float[] ReadFloatArray() + { + ushort count = ReadUInt16(); + float[] values = new float[count]; + for (int i = 0; i < count; i++) + { + values[i] = ReadSingle(); + } + return values; + } + public double[] ReadDoubleArray() + { + ushort count = ReadUInt16(); + double[] values = new double[count]; + for (int i = 0; i < count; i++) + { + values[i] = ReadDouble(); + } + return values; + } + public string[] ReadUTF8Array() + { + ushort count = ReadUInt16(); + string[] values = new string[count]; + for (int i = 0; i < count; i++) + { + values[i] = ReadUTF8(); + } + return values; + } + + public Vector2 ReadVector2() + { + float x = ReadSingle(); + float y = ReadSingle(); + return new Vector2(x, y); + } + public Vector3 ReadVector3() + { + float x = ReadSingle(); + float y = ReadSingle(); + float z = ReadSingle(); + return new Vector3(x, y, z); + } + public Vector4 ReadVector4() + { + float x = ReadSingle(); + float y = ReadSingle(); + float z = ReadSingle(); + float w = ReadSingle(); + return new Vector4(x, y, z, w); + } + public Quaternion ReadQuaternion() + { + float x = ReadSingle(); + float y = ReadSingle(); + float z = ReadSingle(); + float w = ReadSingle(); + return new Quaternion(x, y, z, w); + } + + [Conditional("DEBUG")] + private void CheckReaderIndex(int length) + { + if (_index + length > Capacity) + { + throw new IndexOutOfRangeException(); + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Utility/BufferReader.cs.meta b/Assets/YooAsset/Runtime/Utility/BufferReader.cs.meta new file mode 100644 index 0000000..2f4005a --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/BufferReader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 76257995ca887ad48ac02bd5d2174d9b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/Utility/BufferWriter.cs b/Assets/YooAsset/Runtime/Utility/BufferWriter.cs new file mode 100644 index 0000000..f2c9b39 --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/BufferWriter.cs @@ -0,0 +1,259 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; +using System.IO; +using UnityEngine; + +namespace YooAsset +{ + internal class BufferWriter + { + private readonly byte[] _buffer; + private int _index = 0; + + public BufferWriter(int capacity) + { + _buffer = new byte[capacity]; + } + + /// + /// 缓冲区容量 + /// + public int Capacity + { + get { return _buffer.Length; } + } + + /// + /// 将有效数据写入文件流 + /// + public void WriteToStream(FileStream fileStream) + { + fileStream.Write(_buffer, 0, _index); + } + + public void WriteBytes(byte[] data) + { + WriteBytes(data, 0, data.Length); + } + public void WriteBytes(byte[] data, int offset, int count) + { + CheckWriterIndex(count); + Buffer.BlockCopy(data, offset, _buffer, _index, count); + _index += count; + } + public void WriteByte(byte value) + { + CheckWriterIndex(1); + _buffer[_index++] = value; + } + public void WriteSbyte(sbyte value) + { + WriteByte((byte)value); + } + + public void WriteBool(bool value) + { + WriteByte((byte)(value ? 1 : 0)); + } + public void WriteInt16(short value) + { + WriteUInt16((ushort)value); + } + public void WriteUInt16(ushort value) + { + CheckWriterIndex(2); + for (int i = 0; i < 2; i++) + { + _buffer[_index++] = (byte)(value >> (i * 8)); + } + } + public void WriteInt32(int value) + { + WriteUInt32((uint)value); + } + public void WriteUInt32(uint value) + { + CheckWriterIndex(4); + for (int i = 0; i < 4; i++) + { + _buffer[_index++] = (byte)(value >> (i * 8)); + } + } + public void WriteInt64(long value) + { + WriteUInt64((ulong)value); + } + public void WriteUInt64(ulong value) + { + CheckWriterIndex(8); + for (int i = 0; i < 8; i++) + { + _buffer[_index++] = (byte)(value >> (i * 8)); + } + } + + public void WriteSingle(float value) + { + FloatContent content = new FloatContent(); + content.floatValue = value; + WriteUInt32(content.uintValue); + } + public void WriteDouble(double value) + { + DoubleContent content = new DoubleContent(); + content.doubleValue = value; + WriteUInt64(content.ulongValue); + } + + public void WriteUTF8(string value) + { + if (string.IsNullOrEmpty(value)) + { + WriteUInt16(0); + } + else + { + byte[] bytes = Encoding.UTF8.GetBytes(value); + int count = bytes.Length; + if (count > ushort.MaxValue) + throw new FormatException($"Write string length cannot be greater than {ushort.MaxValue} !"); + + WriteUInt16(Convert.ToUInt16(count)); + WriteBytes(bytes); + } + } + public void WriteInt32Array(int[] values) + { + if (values == null) + { + WriteUInt16(0); + } + else + { + int count = values.Length; + if (count > ushort.MaxValue) + throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue} !"); + + WriteUInt16(Convert.ToUInt16(count)); + for (int i = 0; i < count; i++) + { + WriteInt32(values[i]); + } + } + } + public void WriteInt64Array(long[] values) + { + if (values == null) + { + WriteUInt16(0); + } + else + { + int count = values.Length; + if (count > ushort.MaxValue) + throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue} !"); + + WriteUInt16(Convert.ToUInt16(count)); + for (int i = 0; i < count; i++) + { + WriteInt64(values[i]); + } + } + } + public void WriteSingleArray(float[] values) + { + if (values == null) + { + WriteUInt16(0); + } + else + { + int count = values.Length; + if (count > ushort.MaxValue) + throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue} !"); + + WriteUInt16(Convert.ToUInt16(count)); + for (int i = 0; i < count; i++) + { + WriteSingle(values[i]); + } + } + } + public void WriteDoubleArray(double[] values) + { + if (values == null) + { + WriteUInt16(0); + } + else + { + int count = values.Length; + if (count > ushort.MaxValue) + throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue} !"); + + WriteUInt16(Convert.ToUInt16(count)); + for (int i = 0; i < count; i++) + { + WriteDouble(values[i]); + } + } + } + public void WriteUTF8Array(string[] values) + { + if (values == null) + { + WriteUInt16(0); + } + else + { + int count = values.Length; + if (count > ushort.MaxValue) + throw new FormatException($"Write array length cannot be greater than {ushort.MaxValue} !"); + + WriteUInt16(Convert.ToUInt16(count)); + for (int i = 0; i < count; i++) + { + WriteUTF8(values[i]); + } + } + } + + public void WriteVector2(Vector2 value) + { + WriteSingle(value.x); + WriteSingle(value.y); + } + public void WriteVector3(Vector3 value) + { + WriteSingle(value.x); + WriteSingle(value.y); + WriteSingle(value.z); + } + public void WriteVector4(Vector4 value) + { + WriteSingle(value.x); + WriteSingle(value.y); + WriteSingle(value.z); + WriteSingle(value.w); + } + public void WriteQuaternion(Quaternion value) + { + WriteSingle(value.x); + WriteSingle(value.y); + WriteSingle(value.z); + WriteSingle(value.w); + } + + [Conditional("DEBUG")] + private void CheckWriterIndex(int length) + { + if (_index + length > Capacity) + { + throw new IndexOutOfRangeException(); + } + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/Utility/BufferWriter.cs.meta b/Assets/YooAsset/Runtime/Utility/BufferWriter.cs.meta new file mode 100644 index 0000000..ee20afe --- /dev/null +++ b/Assets/YooAsset/Runtime/Utility/BufferWriter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a270f91ca07a38445949cb5e8195f0a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: