mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-09-27 10:46:17 +00:00
临时提交
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec2ef3dfb9b0443980685c7b6d1d0946
|
||||
timeCreated: 1729498592
|
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using JNGame.Runtime.Util;
|
||||
|
||||
namespace JNGame.Serialization
|
||||
{
|
||||
[Serializable]
|
||||
public partial class BaseFormater : ISerializable, ISerializablePacket
|
||||
{
|
||||
public virtual void Serialize(Serializer writer) { }
|
||||
|
||||
public virtual void Deserialize(Deserializer reader) { }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return JsonUtil.ToJson(this);
|
||||
}
|
||||
|
||||
public byte[] ToBytes()
|
||||
{
|
||||
var writer = new Serializer();
|
||||
Serialize(writer);
|
||||
var bytes = writer.CopyData(); // Compressor.Compress(writer.CopyData());
|
||||
return bytes;
|
||||
}
|
||||
public void FromBytes(byte[] data)
|
||||
{
|
||||
var bytes = data; //Compressor.Decompress(data);
|
||||
var reader = new Deserializer(bytes);
|
||||
Deserialize(reader);
|
||||
}
|
||||
public void FromBytes(byte[] data, int offset, int size)
|
||||
{
|
||||
var bytes = data; //Compressor.Decompress(data);
|
||||
var reader = new Deserializer(bytes, offset, size);
|
||||
Deserialize(reader);
|
||||
}
|
||||
|
||||
public static T FromBytes<T>(byte[] data) where T : BaseFormater, new()
|
||||
{
|
||||
var ret = new T();
|
||||
ret.FromBytes(data, 0, data.Length);
|
||||
return ret;
|
||||
}
|
||||
public static T FromBytes<T>(byte[] data, int offset, int size) where T : BaseFormater, new()
|
||||
{
|
||||
var ret = new T();
|
||||
ret.FromBytes(data, offset, size);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b344f7ec7d504003ab7053500714c7ee
|
||||
timeCreated: 1729498742
|
@@ -0,0 +1,832 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using JNGame.Math;
|
||||
|
||||
namespace JNGame.Serialization
|
||||
{
|
||||
public delegate uint FuncReadSlot(uint vTblOffset, int idx);
|
||||
|
||||
public class Deserializer
|
||||
{
|
||||
protected byte[] _data;
|
||||
protected int _position;
|
||||
protected int _dataSize;
|
||||
private int _offset;
|
||||
|
||||
public byte[] RawData
|
||||
{
|
||||
get { return _data; }
|
||||
}
|
||||
|
||||
public int RawDataSize
|
||||
{
|
||||
get { return _dataSize; }
|
||||
}
|
||||
|
||||
public int UserDataOffset
|
||||
{
|
||||
get { return _offset; }
|
||||
}
|
||||
|
||||
public int UserDataSize
|
||||
{
|
||||
get { return _dataSize - _offset; }
|
||||
}
|
||||
|
||||
public bool IsNull
|
||||
{
|
||||
get { return _data == null; }
|
||||
}
|
||||
|
||||
public int Position
|
||||
{
|
||||
get { return _position; }
|
||||
}
|
||||
|
||||
public void SetPosition(int pos)
|
||||
{
|
||||
_position = pos;
|
||||
}
|
||||
|
||||
public bool SkipLen(long len)
|
||||
{
|
||||
var dst = _position + len;
|
||||
if (dst > _dataSize)
|
||||
{
|
||||
throw new Exception(
|
||||
$"Skip len is out of range _dataSize:{_dataSize} _position:{_position} skipLen:{len}");
|
||||
}
|
||||
|
||||
_position += (int)len;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool EndOfData
|
||||
{
|
||||
get { return _position == _dataSize; }
|
||||
}
|
||||
|
||||
public int AvailableBytes
|
||||
{
|
||||
get { return _dataSize - _position; }
|
||||
}
|
||||
|
||||
public bool IsEnd
|
||||
{
|
||||
get { return _dataSize == _position; }
|
||||
}
|
||||
|
||||
public void SetSource(Serializer dataWriter)
|
||||
{
|
||||
_data = dataWriter.Data;
|
||||
_position = 0;
|
||||
_offset = 0;
|
||||
_dataSize = dataWriter.Length;
|
||||
}
|
||||
|
||||
public void SetSource(byte[] source)
|
||||
{
|
||||
_data = source;
|
||||
_position = 0;
|
||||
_offset = 0;
|
||||
_dataSize = source.Length;
|
||||
}
|
||||
|
||||
public void SetSource(byte[] source, int offset)
|
||||
{
|
||||
_data = source;
|
||||
_position = offset;
|
||||
_offset = offset;
|
||||
_dataSize = source.Length;
|
||||
}
|
||||
|
||||
public void SetSource(byte[] source, int offset, int maxSize)
|
||||
{
|
||||
_data = source;
|
||||
_position = offset;
|
||||
_offset = offset;
|
||||
_dataSize = maxSize;
|
||||
}
|
||||
|
||||
public Deserializer() { }
|
||||
|
||||
public Deserializer(byte[] source)
|
||||
{
|
||||
SetSource(source);
|
||||
}
|
||||
|
||||
public Deserializer(byte[] source, int offset)
|
||||
{
|
||||
SetSource(source, offset);
|
||||
}
|
||||
|
||||
public Deserializer(byte[] source, int offset, int maxSize)
|
||||
{
|
||||
SetSource(source, offset, maxSize);
|
||||
}
|
||||
|
||||
#region GetMethods
|
||||
|
||||
public bool SetSlotOffset(int vTblOffset, int slotSize, int idx)
|
||||
{
|
||||
int offset = (int)(vTblOffset + idx * slotSize);
|
||||
int dataOffset = _data[offset];
|
||||
if (slotSize == 4)
|
||||
{
|
||||
dataOffset = (int)FastBitConverter.ToUInt32(_data, offset);
|
||||
}
|
||||
else if (slotSize == 2)
|
||||
{
|
||||
dataOffset = FastBitConverter.ToUInt16(_data, offset);
|
||||
}
|
||||
_position = dataOffset;
|
||||
return dataOffset != 0;
|
||||
}
|
||||
|
||||
public uint ReadSlotInt16(uint offset, int idx)
|
||||
{
|
||||
return FastBitConverter.ToUInt16(_data, (int)(offset + idx * 2));
|
||||
}
|
||||
|
||||
public uint ReadSlotInt32(uint offset, int idx)
|
||||
{
|
||||
return FastBitConverter.ToUInt32(_data, (int)(offset + idx * 2));
|
||||
}
|
||||
|
||||
public byte ReadByte()
|
||||
{
|
||||
byte res = _data[_position];
|
||||
_position += 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
public sbyte ReadSByte()
|
||||
{
|
||||
var b = (sbyte)_data[_position];
|
||||
_position++;
|
||||
return b;
|
||||
}
|
||||
|
||||
public bool ReadBoolean()
|
||||
{
|
||||
bool res = _data[_position] > 0;
|
||||
_position += 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
public char ReadChar()
|
||||
{
|
||||
char result = (char)FastBitConverter.ToInt16(_data, _position);
|
||||
_position += 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
public ushort ReadUInt16()
|
||||
{
|
||||
ushort result = FastBitConverter.ToUInt16(_data, _position);
|
||||
_position += 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
public short ReadInt16()
|
||||
{
|
||||
short result = FastBitConverter.ToInt16(_data, _position);
|
||||
_position += 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
public long ReadInt64()
|
||||
{
|
||||
long result = FastBitConverter.ToInt64(_data, _position);
|
||||
_position += 8;
|
||||
return result;
|
||||
}
|
||||
|
||||
public ulong ReadUInt64()
|
||||
{
|
||||
ulong result = FastBitConverter.ToUInt64(_data, _position);
|
||||
_position += 8;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int ReadInt32()
|
||||
{
|
||||
int result = FastBitConverter.ToInt32(_data, _position);
|
||||
_position += 4;
|
||||
return result;
|
||||
}
|
||||
|
||||
public uint ReadUInt32()
|
||||
{
|
||||
uint result = FastBitConverter.ToUInt32(_data, _position);
|
||||
_position += 4;
|
||||
return result;
|
||||
}
|
||||
|
||||
public float ReadSingle()
|
||||
{
|
||||
float result = FastBitConverter.ToSingle(_data, _position);
|
||||
_position += 4;
|
||||
return result;
|
||||
}
|
||||
|
||||
public double ReadDouble()
|
||||
{
|
||||
double result = FastBitConverter.ToDouble(_data, _position);
|
||||
_position += 8;
|
||||
return result;
|
||||
}
|
||||
|
||||
public LFloat ReadLFloat()
|
||||
{
|
||||
var x = ReadInt64();
|
||||
return new LFloat(true, x);
|
||||
}
|
||||
|
||||
public LVector2 ReadLVector2()
|
||||
{
|
||||
var x = ReadInt64();
|
||||
var y = ReadInt64();
|
||||
return new LVector2(true, x, y);
|
||||
}
|
||||
|
||||
public LVector3 ReadLVector3()
|
||||
{
|
||||
var x = ReadInt64();
|
||||
var y = ReadInt64();
|
||||
var z = ReadInt64();
|
||||
return new LVector3(true, x, y, z);
|
||||
}
|
||||
|
||||
public T ReadRef<T>(ref T _) where T : BaseFormater, new()
|
||||
{
|
||||
if (ReadBoolean())
|
||||
return null;
|
||||
var val = new T();
|
||||
val.Deserialize(this);
|
||||
return val;
|
||||
}
|
||||
|
||||
public string ReadString(int maxLength)
|
||||
{
|
||||
int bytesCount = ReadInt32();
|
||||
if (bytesCount <= 0 || bytesCount > maxLength * 2)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
int charCount = Encoding.UTF8.GetCharCount(_data, _position, bytesCount);
|
||||
if (charCount > maxLength)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
string result = Encoding.UTF8.GetString(_data, _position, bytesCount);
|
||||
_position += bytesCount;
|
||||
return result;
|
||||
}
|
||||
|
||||
public string ReadString()
|
||||
{
|
||||
int bytesCount = ReadInt32();
|
||||
if (bytesCount <= 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
string result = Encoding.UTF8.GetString(_data, _position, bytesCount);
|
||||
_position += bytesCount;
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] ReadToEnd()
|
||||
{
|
||||
int size = _data.Length - _position;
|
||||
var outgoingData = new byte[size];
|
||||
Buffer.BlockCopy(_data, _position, outgoingData, 0, size);
|
||||
_position += size;
|
||||
return outgoingData;
|
||||
}
|
||||
|
||||
public byte[] ReadArray(byte[] _)
|
||||
{
|
||||
return ReadBytes();
|
||||
}
|
||||
|
||||
public short[] ReadArray(short[] _)
|
||||
{
|
||||
return _ReadArray(ReadInt16);
|
||||
}
|
||||
public List<short> ReadList(IList<short> _)
|
||||
{
|
||||
return _ReadList(ReadInt16);
|
||||
}
|
||||
|
||||
public ushort[] ReadArray(ushort[] _)
|
||||
{
|
||||
return _ReadArray(ReadUInt16);
|
||||
}
|
||||
public List<ushort> ReadList(IList<ushort> _)
|
||||
{
|
||||
return _ReadList(ReadUInt16);
|
||||
}
|
||||
|
||||
public int[] ReadArray(int[] _)
|
||||
{
|
||||
return _ReadArray(ReadInt32);
|
||||
}
|
||||
public List<int> ReadList(IList<int> _)
|
||||
{
|
||||
return _ReadList(ReadInt32);
|
||||
}
|
||||
|
||||
public uint[] ReadArray(uint[] _)
|
||||
{
|
||||
return _ReadArray(ReadUInt32);
|
||||
}
|
||||
public List<uint> ReadList(IList<uint> _)
|
||||
{
|
||||
return _ReadList(ReadUInt32);
|
||||
}
|
||||
|
||||
public long[] ReadArray(long[] _)
|
||||
{
|
||||
return _ReadArray(ReadInt64);
|
||||
}
|
||||
public List<long> ReadList(IList<long> _)
|
||||
{
|
||||
return _ReadList(ReadInt64);
|
||||
}
|
||||
|
||||
public ulong[] ReadArray(ulong[] _)
|
||||
{
|
||||
return _ReadArray(ReadUInt64);
|
||||
}
|
||||
public List<ulong> ReadList(IList<ulong> _)
|
||||
{
|
||||
return _ReadList(ReadUInt64);
|
||||
}
|
||||
|
||||
public float[] ReadArray(float[] _)
|
||||
{
|
||||
return _ReadArray(ReadSingle);
|
||||
}
|
||||
public List<float> ReadList(IList<float> _)
|
||||
{
|
||||
return _ReadList(ReadSingle);
|
||||
}
|
||||
|
||||
public double[] ReadArray(double[] _)
|
||||
{
|
||||
return _ReadArray(ReadDouble);
|
||||
}
|
||||
public List<double> ReadList(IList<double> _)
|
||||
{
|
||||
return _ReadList(ReadDouble);
|
||||
}
|
||||
|
||||
public bool[] ReadArray(bool[] _)
|
||||
{
|
||||
return _ReadArray(ReadBoolean);
|
||||
}
|
||||
public List<bool> ReadList(IList<bool> _)
|
||||
{
|
||||
return _ReadList(ReadBoolean);
|
||||
}
|
||||
|
||||
public string[] ReadArray(string[] _)
|
||||
{
|
||||
return _ReadArray(ReadString);
|
||||
}
|
||||
public List<string> ReadList(IList<string> _)
|
||||
{
|
||||
return _ReadList(ReadString);
|
||||
}
|
||||
|
||||
public LFloat[] ReadArray(LFloat[] _)
|
||||
{
|
||||
return _ReadArray(ReadLFloat);
|
||||
}
|
||||
public List<LFloat> ReadList(IList<LFloat> _)
|
||||
{
|
||||
return _ReadList(ReadLFloat);
|
||||
}
|
||||
|
||||
public LVector2[] ReadArray(LVector2[] _)
|
||||
{
|
||||
return _ReadArray(ReadLVector2);
|
||||
}
|
||||
public List<LVector2> ReadList(IList<LVector2> _)
|
||||
{
|
||||
return _ReadList(ReadLVector2);
|
||||
}
|
||||
|
||||
public LVector3[] ReadArray(LVector3[] _)
|
||||
{
|
||||
return _ReadArray(ReadLVector3);
|
||||
}
|
||||
public List<LVector3> ReadList(IList<LVector3> _)
|
||||
{
|
||||
return _ReadList(ReadLVector3);
|
||||
}
|
||||
|
||||
private T[] _ReadArray<T>(Func<T> _func)
|
||||
{
|
||||
ushort size = FastBitConverter.ToUInt16(_data, _position);
|
||||
_position += 2;
|
||||
var arr = new T[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
arr[i] = _func();
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
private List<T> _ReadList<T>(Func<T> _func)
|
||||
{
|
||||
ushort size = FastBitConverter.ToUInt16(_data, _position);
|
||||
_position += 2;
|
||||
var arr = new List<T>(size);
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
arr.Add(_func());
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
public T[] ReadArray<T>(T[] _) where T : BaseFormater, new()
|
||||
{
|
||||
ushort len = ReadUInt16();
|
||||
if (len == 0)
|
||||
return null;
|
||||
var formatters = new T[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
if (ReadBoolean())
|
||||
formatters[i] = null;
|
||||
else
|
||||
{
|
||||
var val = new T();
|
||||
val.Deserialize(this);
|
||||
formatters[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
return formatters;
|
||||
}
|
||||
|
||||
public List<T> ReadList<T>(List<T> _) where T : BaseFormater, new()
|
||||
{
|
||||
ushort len = ReadUInt16();
|
||||
if (len == 0)
|
||||
return null;
|
||||
var formatters = new List<T>(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
if (ReadBoolean())
|
||||
formatters[i] = null;
|
||||
else
|
||||
{
|
||||
var val = new T();
|
||||
val.Deserialize(this);
|
||||
formatters.Add(val);
|
||||
}
|
||||
}
|
||||
|
||||
return formatters;
|
||||
}
|
||||
|
||||
public byte[] GetRemainingBytes()
|
||||
{
|
||||
byte[] outgoingData = new byte[AvailableBytes];
|
||||
Buffer.BlockCopy(_data, _position, outgoingData, 0, AvailableBytes);
|
||||
_position = _data.Length;
|
||||
return outgoingData;
|
||||
}
|
||||
|
||||
public void GetBytes(byte[] destination, int start, int count)
|
||||
{
|
||||
Buffer.BlockCopy(_data, _position, destination, start, count);
|
||||
_position += count;
|
||||
}
|
||||
|
||||
public void GetBytes(byte[] destination, int count)
|
||||
{
|
||||
Buffer.BlockCopy(_data, _position, destination, 0, count);
|
||||
_position += count;
|
||||
}
|
||||
|
||||
public byte[] ReadBytes()
|
||||
{
|
||||
ushort size = ReadUInt16();
|
||||
if (size == 0) return null;
|
||||
var outgoingData = new byte[size];
|
||||
Buffer.BlockCopy(_data, _position, outgoingData, 0, size);
|
||||
_position += size;
|
||||
return outgoingData;
|
||||
}
|
||||
|
||||
public byte[] ReadBytes_255()
|
||||
{
|
||||
ushort size = ReadByte();
|
||||
if (size == 0) return null;
|
||||
var outgoingData = new byte[size];
|
||||
Buffer.BlockCopy(_data, _position, outgoingData, 0, size);
|
||||
_position += size;
|
||||
return outgoingData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PeekMethods
|
||||
|
||||
public byte PeekByte()
|
||||
{
|
||||
return _data[_position];
|
||||
}
|
||||
|
||||
public sbyte PeekSByte()
|
||||
{
|
||||
return (sbyte)_data[_position];
|
||||
}
|
||||
|
||||
public bool PeekBool()
|
||||
{
|
||||
return _data[_position] > 0;
|
||||
}
|
||||
|
||||
public char PeekChar()
|
||||
{
|
||||
return (char)FastBitConverter.ToInt16(_data, _position);
|
||||
}
|
||||
|
||||
public ushort PeekUShort()
|
||||
{
|
||||
return FastBitConverter.ToUInt16(_data, _position);
|
||||
}
|
||||
|
||||
public short PeekShort()
|
||||
{
|
||||
return FastBitConverter.ToInt16(_data, _position);
|
||||
}
|
||||
|
||||
public long PeekLong()
|
||||
{
|
||||
return FastBitConverter.ToInt64(_data, _position);
|
||||
}
|
||||
|
||||
public ulong PeekULong()
|
||||
{
|
||||
return FastBitConverter.ToUInt64(_data, _position);
|
||||
}
|
||||
|
||||
public int PeekInt()
|
||||
{
|
||||
return FastBitConverter.ToInt32(_data, _position);
|
||||
}
|
||||
|
||||
public uint PeekUInt()
|
||||
{
|
||||
return FastBitConverter.ToUInt32(_data, _position);
|
||||
}
|
||||
|
||||
public float PeekFloat()
|
||||
{
|
||||
return FastBitConverter.ToSingle(_data, _position);
|
||||
}
|
||||
|
||||
public double PeekDouble()
|
||||
{
|
||||
return FastBitConverter.ToDouble(_data, _position);
|
||||
}
|
||||
|
||||
public string PeekString(int maxLength)
|
||||
{
|
||||
int bytesCount = BitConverter.ToInt32(_data, _position);
|
||||
if (bytesCount <= 0 || bytesCount > maxLength * 2)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
int charCount = Encoding.UTF8.GetCharCount(_data, _position + 4, bytesCount);
|
||||
if (charCount > maxLength)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
string result = Encoding.UTF8.GetString(_data, _position + 4, bytesCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
public string PeekString()
|
||||
{
|
||||
int bytesCount = BitConverter.ToInt32(_data, _position);
|
||||
if (bytesCount <= 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
string result = Encoding.UTF8.GetString(_data, _position + 4, bytesCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region TryReadMethods
|
||||
|
||||
public bool TryReadByte(out byte result)
|
||||
{
|
||||
if (AvailableBytes >= 1)
|
||||
{
|
||||
result = ReadByte();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryReadSByte(out sbyte result)
|
||||
{
|
||||
if (AvailableBytes >= 1)
|
||||
{
|
||||
result = ReadSByte();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryReadBool(out bool result)
|
||||
{
|
||||
if (AvailableBytes >= 1)
|
||||
{
|
||||
result = ReadBoolean();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryReadChar(out char result)
|
||||
{
|
||||
if (AvailableBytes >= 2)
|
||||
{
|
||||
result = ReadChar();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = '\0';
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryReadShort(out short result)
|
||||
{
|
||||
if (AvailableBytes >= 2)
|
||||
{
|
||||
result = ReadInt16();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryReadUShort(out ushort result)
|
||||
{
|
||||
if (AvailableBytes >= 2)
|
||||
{
|
||||
result = ReadUInt16();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryReadInt(out int result)
|
||||
{
|
||||
if (AvailableBytes >= 4)
|
||||
{
|
||||
result = ReadInt32();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryReadUInt(out uint result)
|
||||
{
|
||||
if (AvailableBytes >= 4)
|
||||
{
|
||||
result = ReadUInt32();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryReadLong(out long result)
|
||||
{
|
||||
if (AvailableBytes >= 8)
|
||||
{
|
||||
result = ReadInt64();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryReadULong(out ulong result)
|
||||
{
|
||||
if (AvailableBytes >= 8)
|
||||
{
|
||||
result = ReadUInt64();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryReadFloat(out float result)
|
||||
{
|
||||
if (AvailableBytes >= 4)
|
||||
{
|
||||
result = ReadSingle();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryReadDouble(out double result)
|
||||
{
|
||||
if (AvailableBytes >= 8)
|
||||
{
|
||||
result = ReadDouble();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryReadString(out string result)
|
||||
{
|
||||
if (AvailableBytes >= 4)
|
||||
{
|
||||
var bytesCount = PeekInt();
|
||||
if (AvailableBytes >= bytesCount + 4)
|
||||
{
|
||||
result = ReadString();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryReadStringArray(out string[] result)
|
||||
{
|
||||
ushort size;
|
||||
if (!TryReadUShort(out size))
|
||||
{
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
result = new string[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (!TryReadString(out result[i]))
|
||||
{
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_position = 0;
|
||||
_dataSize = 0;
|
||||
_data = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce29f84641ff4ab2ada0a7f3a64a9e70
|
||||
timeCreated: 1729498630
|
@@ -0,0 +1,189 @@
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace JNGame.Serialization
|
||||
{
|
||||
public static class FastBitConverter
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
private struct ConverterHelperDouble
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public ulong Along;
|
||||
|
||||
[FieldOffset(0)]
|
||||
public double Adouble;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
private struct ConverterHelperFloat
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public int Aint;
|
||||
|
||||
[FieldOffset(0)]
|
||||
public float Afloat;
|
||||
}
|
||||
|
||||
private static void WriteLittleEndian(byte[] buffer, int offset, ulong data)
|
||||
{
|
||||
#if BIGENDIAN
|
||||
buffer[offset + 7] = (byte)(data);
|
||||
buffer[offset + 6] = (byte)(data >> 8);
|
||||
buffer[offset + 5] = (byte)(data >> 16);
|
||||
buffer[offset + 4] = (byte)(data >> 24);
|
||||
buffer[offset + 3] = (byte)(data >> 32);
|
||||
buffer[offset + 2] = (byte)(data >> 40);
|
||||
buffer[offset + 1] = (byte)(data >> 48);
|
||||
buffer[offset ] = (byte)(data >> 56);
|
||||
#else
|
||||
buffer[offset] = (byte)(data);
|
||||
buffer[offset + 1] = (byte)(data >> 8);
|
||||
buffer[offset + 2] = (byte)(data >> 16);
|
||||
buffer[offset + 3] = (byte)(data >> 24);
|
||||
buffer[offset + 4] = (byte)(data >> 32);
|
||||
buffer[offset + 5] = (byte)(data >> 40);
|
||||
buffer[offset + 6] = (byte)(data >> 48);
|
||||
buffer[offset + 7] = (byte)(data >> 56);
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void WriteLittleEndian(byte[] buffer, int offset, int data)
|
||||
{
|
||||
#if BIGENDIAN
|
||||
buffer[offset + 3] = (byte)(data);
|
||||
buffer[offset + 2] = (byte)(data >> 8);
|
||||
buffer[offset + 1] = (byte)(data >> 16);
|
||||
buffer[offset ] = (byte)(data >> 24);
|
||||
#else
|
||||
buffer[offset] = (byte)(data);
|
||||
buffer[offset + 1] = (byte)(data >> 8);
|
||||
buffer[offset + 2] = (byte)(data >> 16);
|
||||
buffer[offset + 3] = (byte)(data >> 24);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void WriteLittleEndian(byte[] buffer, int offset, short data)
|
||||
{
|
||||
#if BIGENDIAN
|
||||
buffer[offset + 1] = (byte)(data);
|
||||
buffer[offset ] = (byte)(data >> 8);
|
||||
#else
|
||||
buffer[offset] = (byte)(data);
|
||||
buffer[offset + 1] = (byte)(data >> 8);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void GetBytes(byte[] bytes, int startIndex, double value)
|
||||
{
|
||||
ConverterHelperDouble ch = new ConverterHelperDouble { Adouble = value };
|
||||
WriteLittleEndian(bytes, startIndex, ch.Along);
|
||||
}
|
||||
|
||||
public static void GetBytes(byte[] bytes, int startIndex, float value)
|
||||
{
|
||||
ConverterHelperFloat ch = new ConverterHelperFloat { Afloat = value };
|
||||
WriteLittleEndian(bytes, startIndex, ch.Aint);
|
||||
}
|
||||
|
||||
public static void GetBytes(byte[] bytes, int startIndex, bool value)
|
||||
{
|
||||
bytes[startIndex] = (byte)(value ? 1 : 0);
|
||||
}
|
||||
public static void GetBytes(byte[] bytes, int startIndex, short value)
|
||||
{
|
||||
WriteLittleEndian(bytes, startIndex, value);
|
||||
}
|
||||
public static void GetBytes(byte[] bytes, int startIndex, ushort value)
|
||||
{
|
||||
WriteLittleEndian(bytes, startIndex, (short)value);
|
||||
}
|
||||
|
||||
public static void GetBytes(byte[] bytes, int startIndex, int value)
|
||||
{
|
||||
WriteLittleEndian(bytes, startIndex, value);
|
||||
}
|
||||
|
||||
public static void GetBytes(byte[] bytes, int startIndex, uint value)
|
||||
{
|
||||
WriteLittleEndian(bytes, startIndex, (int)value);
|
||||
}
|
||||
|
||||
public static void GetBytes(byte[] bytes, int startIndex, long value)
|
||||
{
|
||||
WriteLittleEndian(bytes, startIndex, (ulong)value);
|
||||
}
|
||||
|
||||
public static void GetBytes(byte[] bytes, int startIndex, ulong value)
|
||||
{
|
||||
WriteLittleEndian(bytes, startIndex, value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static ulong ReadLittleEndian(byte[] buffer, int offset, int count)
|
||||
{
|
||||
ulong r = 0;
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
r |= (ulong)buffer[offset + i] << i * 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
r |= (ulong)buffer[offset + count - 1 - i] << i * 8;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public static short ToInt16(byte[] buffer, int index)
|
||||
{
|
||||
return (short)ReadLittleEndian(buffer, index, sizeof(short));
|
||||
}
|
||||
|
||||
public static ushort ToUInt16(byte[] buffer, int index)
|
||||
{
|
||||
return (ushort)ReadLittleEndian(buffer, index, sizeof(ushort));
|
||||
}
|
||||
|
||||
public static int ToInt32(byte[] buffer, int index)
|
||||
{
|
||||
return (int)ReadLittleEndian(buffer, index, sizeof(int));
|
||||
}
|
||||
|
||||
public static uint ToUInt32(byte[] buffer, int index)
|
||||
{
|
||||
return (uint)ReadLittleEndian(buffer, index, sizeof(uint));
|
||||
}
|
||||
|
||||
public static long ToInt64(byte[] buffer, int index)
|
||||
{
|
||||
return (long)ReadLittleEndian(buffer, index, sizeof(long));
|
||||
}
|
||||
|
||||
public static ulong ToUInt64(byte[] buffer, int index)
|
||||
{
|
||||
return ReadLittleEndian(buffer, index, sizeof(ulong));
|
||||
}
|
||||
|
||||
public static float ToSingle(byte[] buffer, int index)
|
||||
{
|
||||
int i = (int)ReadLittleEndian(buffer, index, sizeof(float));
|
||||
ConverterHelperFloat ch = new ConverterHelperFloat { Aint = i };
|
||||
return ch.Afloat;
|
||||
}
|
||||
|
||||
public static double ToDouble(byte[] buffer, int index)
|
||||
{
|
||||
ulong i = ReadLittleEndian(buffer, index, sizeof(double));
|
||||
ConverterHelperDouble ch = new ConverterHelperDouble { Along = i };
|
||||
return ch.Adouble;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e15925d63e644be9b2eff8a3ef1a0a21
|
||||
timeCreated: 1729498672
|
@@ -0,0 +1,534 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using JNGame.Math;
|
||||
|
||||
namespace JNGame.Serialization
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class Limited : Attribute
|
||||
{
|
||||
public bool le255;
|
||||
public bool le65535;
|
||||
|
||||
public Limited()
|
||||
{
|
||||
le255 = false;
|
||||
le65535 = true;
|
||||
}
|
||||
|
||||
public Limited(bool isLess255)
|
||||
{
|
||||
le255 = isLess255;
|
||||
le65535 = !isLess255;
|
||||
}
|
||||
}
|
||||
|
||||
public interface ISerializablePacket
|
||||
{
|
||||
byte[] ToBytes();
|
||||
void FromBytes(byte[] bytes);
|
||||
}
|
||||
|
||||
public interface ISerializable
|
||||
{
|
||||
void Serialize(Serializer writer);
|
||||
|
||||
void Deserialize(Deserializer reader);
|
||||
}
|
||||
|
||||
public partial class Serializer
|
||||
{
|
||||
//for ext
|
||||
protected int[] offsets;
|
||||
|
||||
public void SetPosition(int pos)
|
||||
{
|
||||
_position = pos;
|
||||
}
|
||||
|
||||
public int[] GetOffsetTable(int len)
|
||||
{
|
||||
if (offsets == null)
|
||||
{
|
||||
offsets = new int[len];
|
||||
return offsets;
|
||||
}
|
||||
else
|
||||
{
|
||||
var rawLen = offsets.Length;
|
||||
if (rawLen >= len)
|
||||
{
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
offsets[i] = 0;
|
||||
}
|
||||
return offsets;
|
||||
}
|
||||
|
||||
while (rawLen < len)
|
||||
{
|
||||
rawLen *= 2;
|
||||
}
|
||||
offsets = new int[rawLen];
|
||||
return offsets;
|
||||
}
|
||||
}
|
||||
|
||||
protected byte[] _data;
|
||||
protected int _position;
|
||||
private const int InitialSize = 64;
|
||||
private int _capacity;
|
||||
|
||||
public int Position => _position;
|
||||
public int Capacity
|
||||
{
|
||||
get { return _capacity; }
|
||||
}
|
||||
|
||||
public Serializer() : this(true, InitialSize) { }
|
||||
|
||||
public Serializer(int initialSize) : this(true, initialSize) { }
|
||||
|
||||
private Serializer(bool autoResize, int initialSize)
|
||||
{
|
||||
_data = new byte[initialSize];
|
||||
_capacity = initialSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates NetDataWriter from existing ByteArray
|
||||
/// </summary>
|
||||
/// <param name="bytes">Source byte array</param>
|
||||
/// <param name="copy">Copy array to new location or use existing</param>
|
||||
public static Serializer FromBytes(byte[] bytes, bool copy)
|
||||
{
|
||||
if (copy)
|
||||
{
|
||||
var netDataWriter = new Serializer(true, bytes.Length);
|
||||
netDataWriter._Put(bytes);
|
||||
return netDataWriter;
|
||||
}
|
||||
|
||||
return new Serializer(true, 0) { _data = bytes, _capacity = bytes.Length };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates NetDataWriter from existing ByteArray (always copied data)
|
||||
/// </summary>
|
||||
/// <param name="bytes">Source byte array</param>
|
||||
/// <param name="offset">Offset of array</param>
|
||||
/// <param name="length">Length of array</param>
|
||||
public static Serializer FromBytes(byte[] bytes, int offset, int length)
|
||||
{
|
||||
var netDataWriter = new Serializer(true, bytes.Length);
|
||||
netDataWriter._Put(bytes, offset, length);
|
||||
return netDataWriter;
|
||||
}
|
||||
|
||||
public static Serializer FromString(string value)
|
||||
{
|
||||
var netDataWriter = new Serializer();
|
||||
netDataWriter.Write(value);
|
||||
return netDataWriter;
|
||||
}
|
||||
|
||||
public void ResizeIfNeed(int newSize)
|
||||
{
|
||||
int len = _data.Length;
|
||||
if (len < newSize)
|
||||
{
|
||||
while (len < newSize)
|
||||
len *= 2;
|
||||
Array.Resize(ref _data, len);
|
||||
_capacity = _data.Length;
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset(int size)
|
||||
{
|
||||
ResizeIfNeed(size);
|
||||
_position = 0;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_position = 0;
|
||||
}
|
||||
|
||||
public byte[] CopyData()
|
||||
{
|
||||
byte[] resultData = new byte[_position];
|
||||
Buffer.BlockCopy(_data, 0, resultData, 0, _position);
|
||||
return resultData;
|
||||
}
|
||||
|
||||
public byte[] Data
|
||||
{
|
||||
get { return _data; }
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get { return _position; }
|
||||
}
|
||||
|
||||
public void Write(float value)
|
||||
{
|
||||
ResizeIfNeed(_position + 4);
|
||||
FastBitConverter.GetBytes(_data, _position, value);
|
||||
_position += 4;
|
||||
}
|
||||
|
||||
public void Write(double value)
|
||||
{
|
||||
ResizeIfNeed(_position + 8);
|
||||
FastBitConverter.GetBytes(_data, _position, value);
|
||||
_position += 8;
|
||||
}
|
||||
|
||||
public void Write(long value)
|
||||
{
|
||||
ResizeIfNeed(_position + 8);
|
||||
FastBitConverter.GetBytes(_data, _position, value);
|
||||
_position += 8;
|
||||
}
|
||||
|
||||
public void Write(ulong value)
|
||||
{
|
||||
ResizeIfNeed(_position + 8);
|
||||
FastBitConverter.GetBytes(_data, _position, value);
|
||||
_position += 8;
|
||||
}
|
||||
|
||||
public void Write(int value)
|
||||
{
|
||||
ResizeIfNeed(_position + 4);
|
||||
FastBitConverter.GetBytes(_data, _position, value);
|
||||
_position += 4;
|
||||
}
|
||||
|
||||
public void Write(uint value)
|
||||
{
|
||||
ResizeIfNeed(_position + 4);
|
||||
FastBitConverter.GetBytes(_data, _position, value);
|
||||
_position += 4;
|
||||
}
|
||||
|
||||
|
||||
public void Write(ushort value)
|
||||
{
|
||||
ResizeIfNeed(_position + 2);
|
||||
FastBitConverter.GetBytes(_data, _position, value);
|
||||
_position += 2;
|
||||
}
|
||||
|
||||
public void Write(short value)
|
||||
{
|
||||
ResizeIfNeed(_position + 2);
|
||||
FastBitConverter.GetBytes(_data, _position, value);
|
||||
_position += 2;
|
||||
}
|
||||
|
||||
public void Write(sbyte value)
|
||||
{
|
||||
ResizeIfNeed(_position + 1);
|
||||
_data[_position] = (byte)value;
|
||||
_position++;
|
||||
}
|
||||
|
||||
public void Write(byte value)
|
||||
{
|
||||
ResizeIfNeed(_position + 1);
|
||||
_data[_position] = value;
|
||||
_position++;
|
||||
}
|
||||
|
||||
public void Write(bool value)
|
||||
{
|
||||
ResizeIfNeed(_position + 1);
|
||||
_data[_position] = (byte)(value ? 1 : 0);
|
||||
_position++;
|
||||
}
|
||||
|
||||
public void Write(char value)
|
||||
{
|
||||
ResizeIfNeed(_position + 2);
|
||||
FastBitConverter.GetBytes(_data, _position, value);
|
||||
_position += 2;
|
||||
}
|
||||
|
||||
public void Write(IPEndPoint endPoint)
|
||||
{
|
||||
Write(endPoint.Address.ToString());
|
||||
Write(endPoint.Port);
|
||||
}
|
||||
|
||||
public void Write(string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
Write(0);
|
||||
return;
|
||||
}
|
||||
|
||||
//put bytes count
|
||||
int bytesCount = Encoding.UTF8.GetByteCount(value);
|
||||
ResizeIfNeed(_position + bytesCount + 4);
|
||||
Write(bytesCount);
|
||||
|
||||
//put string
|
||||
Encoding.UTF8.GetBytes(value, 0, value.Length, _data, _position);
|
||||
_position += bytesCount;
|
||||
}
|
||||
|
||||
|
||||
public void Write(BaseFormater value)
|
||||
{
|
||||
Write(value == null);
|
||||
value?.Serialize(this);
|
||||
}
|
||||
|
||||
|
||||
public void Write(string[] value)
|
||||
{
|
||||
ushort len = value == null ? (ushort)0 : (ushort)value.Length;
|
||||
Write(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
Write(value[i]);
|
||||
}
|
||||
|
||||
public void Append(byte[] value)
|
||||
{
|
||||
ushort len = value == null ? (ushort)0 : (ushort)value.Length;
|
||||
if (len > 0)
|
||||
{
|
||||
_Put(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// len should less then ushort.MaxValue
|
||||
public void Write(byte[] value)
|
||||
{
|
||||
ushort len = value == null ? (ushort)0 : (ushort)value.Length;
|
||||
Write(len);
|
||||
if (len > 0)
|
||||
{
|
||||
_Put(value);
|
||||
}
|
||||
}
|
||||
public void WriteBytes_255(byte[] value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
Write((byte)0);
|
||||
return;
|
||||
}
|
||||
if (value.Length > byte.MaxValue)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException($"Input Cmd len should less then {byte.MaxValue}");
|
||||
}
|
||||
Write((byte)value.Length);
|
||||
_Put(value);
|
||||
}
|
||||
|
||||
public void Write(float[] value) { _PutArray(value, sizeof(float), FastBitConverter.GetBytes); }
|
||||
public void Write(IList<float> value) { _PutArray(value, sizeof(float), FastBitConverter.GetBytes); }
|
||||
|
||||
public void Write(double[] value) { _PutArray(value, sizeof(double), FastBitConverter.GetBytes); }
|
||||
public void Write(IList<double> value) { _PutArray(value, sizeof(double), FastBitConverter.GetBytes); }
|
||||
|
||||
public void Write(long[] value) { _PutArray(value, sizeof(long), FastBitConverter.GetBytes); }
|
||||
public void Write(IList<long> value) { _PutArray(value, sizeof(long), FastBitConverter.GetBytes); }
|
||||
|
||||
public void Write(ulong[] value) { _PutArray(value, sizeof(ulong), FastBitConverter.GetBytes); }
|
||||
public void Write(IList<ulong> value) { _PutArray(value, sizeof(ulong), FastBitConverter.GetBytes); }
|
||||
|
||||
public void Write(int[] value) { _PutArray(value, sizeof(int), FastBitConverter.GetBytes); }
|
||||
public void Write(IList<int> value) { _PutArray(value, sizeof(int), FastBitConverter.GetBytes); }
|
||||
|
||||
public void Write(uint[] value) { _PutArray(value, sizeof(uint), FastBitConverter.GetBytes); }
|
||||
public void Write(IList<uint> value) { _PutArray(value, sizeof(uint), FastBitConverter.GetBytes); }
|
||||
|
||||
public void Write(ushort[] value) { _PutArray(value, sizeof(ushort), FastBitConverter.GetBytes); }
|
||||
public void Write(IList<ushort> value) { _PutArray(value, sizeof(ushort), FastBitConverter.GetBytes); }
|
||||
|
||||
public void Write(short[] value) { _PutArray(value, sizeof(short), FastBitConverter.GetBytes); }
|
||||
public void Write(IList<short> value) { _PutArray(value, sizeof(short), FastBitConverter.GetBytes); }
|
||||
|
||||
public void Write(bool[] value) { _PutArray(value, sizeof(bool), FastBitConverter.GetBytes); }
|
||||
public void Write(IList<bool> value) { _PutArray(value, sizeof(bool), FastBitConverter.GetBytes); }
|
||||
|
||||
public void Write(LFloat val) { Write(val.rawValue); }
|
||||
public void Write(LFloat[] value)
|
||||
{
|
||||
ushort len = (ushort)(value?.Length ?? 0);
|
||||
Write(len);
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
Write(value[i]);
|
||||
}
|
||||
}
|
||||
public void Write(IList<LFloat> value)
|
||||
{
|
||||
ushort len = (ushort)(value?.Count ?? 0);
|
||||
Write(len);
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
Write(value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(LVector2 val) { Write(val.RawX); Write(val.RawY); }
|
||||
public void Write(LVector2[] value)
|
||||
{
|
||||
ushort len = (ushort)(value?.Length ?? 0);
|
||||
Write(len);
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
Write(value[i]);
|
||||
}
|
||||
}
|
||||
public void Write(IList<LVector2> value)
|
||||
{
|
||||
ushort len = (ushort)(value?.Count ?? 0);
|
||||
Write(len);
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
Write(value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(LVector3 val) { Write(val.RawX); Write(val.RawY); Write(val.RawZ); }
|
||||
public void Write(LVector3[] value)
|
||||
{
|
||||
ushort len = (ushort)(value?.Length ?? 0);
|
||||
Write(len);
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
Write(value[i]);
|
||||
}
|
||||
}
|
||||
public void Write(IList<LVector3> value)
|
||||
{
|
||||
ushort len = (ushort)(value?.Count ?? 0);
|
||||
Write(len);
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
Write(value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Write<T>(T[] value) where T : BaseFormater
|
||||
{
|
||||
ushort len = (ushort)(value?.Length ?? 0);
|
||||
Write(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
var val = value[i];
|
||||
Write(val == null);
|
||||
val?.Serialize(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void Write<T>(List<T> value) where T : BaseFormater
|
||||
{
|
||||
ushort len = (ushort)(value?.Count ?? 0);
|
||||
Write(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
var val = value[i];
|
||||
Write(val == null);
|
||||
val?.Serialize(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void _Put(byte[] data, int offset, int length)
|
||||
{
|
||||
ResizeIfNeed(_position + length);
|
||||
Buffer.BlockCopy(data, offset, _data, _position, length);
|
||||
_position += length;
|
||||
}
|
||||
|
||||
private void _Put(byte[] data)
|
||||
{
|
||||
ResizeIfNeed(_position + data.Length);
|
||||
Buffer.BlockCopy(data, 0, _data, _position, data.Length);
|
||||
_position += data.Length;
|
||||
}
|
||||
|
||||
|
||||
private void _PutArray<T>(T[] value, int typeSize, Action<byte[], int, T> _func) where T : struct
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
__PutArrayFastLE(value, typeSize);
|
||||
return;
|
||||
}
|
||||
ushort len = value == null ? (ushort)0 : (ushort)value.Length;
|
||||
ResizeIfNeed(_position + 2 + typeSize * len);
|
||||
Write(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
_func(_data, _position, value[i]);
|
||||
_position += typeSize;
|
||||
}
|
||||
}
|
||||
|
||||
private void _PutArray<T>(IList<T> value, int typeSize, Action<byte[], int, T> _func) where T : struct
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
__PutArrayFastLE(value, typeSize);
|
||||
return;
|
||||
}
|
||||
ushort len = value == null ? (ushort)0 : (ushort)value.Count;
|
||||
ResizeIfNeed(_position + 2 + typeSize * len);
|
||||
Write(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
_func(_data, _position, value[i]);
|
||||
_position += typeSize;
|
||||
}
|
||||
}
|
||||
|
||||
private void __PutArrayFastLE<T>(T[] x, int elemSize) where T : struct
|
||||
{
|
||||
ushort len = x == null ? (ushort)0 : (ushort)x.Length;
|
||||
int bytesCount = elemSize * len;
|
||||
ResizeIfNeed(_position + 2 + bytesCount);
|
||||
FastBitConverter.GetBytes(_data, _position, len);
|
||||
_position += 2;
|
||||
if (len == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if we are LE, just do a block copy
|
||||
Buffer.BlockCopy(x, 0, _data, _position, bytesCount);
|
||||
_position += bytesCount;
|
||||
}
|
||||
|
||||
private void __PutArrayFastLE<T>(IList<T> x, int elemSize) where T : struct
|
||||
{
|
||||
ushort len = x == null ? (ushort)0 : (ushort)x.Count;
|
||||
int bytesCount = elemSize * len;
|
||||
ResizeIfNeed(_position + 2 + bytesCount);
|
||||
FastBitConverter.GetBytes(_data, _position, len);
|
||||
_position += 2;
|
||||
if (len == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if we are LE, just do a block copy
|
||||
Buffer.BlockCopy(x.ToArray(), 0, _data, _position, bytesCount);
|
||||
_position += bytesCount;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 062bd73f2ffb4142bb933b9e0fede7bd
|
||||
timeCreated: 1729498596
|
Reference in New Issue
Block a user