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: