456 lines
12 KiB
C#
456 lines
12 KiB
C#
using System;
|
|
using System.Text;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace FairyGUI.Utils
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class ByteBuffer
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public bool littleEndian;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public string[] stringTable;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int version;
|
|
|
|
int _pointer;
|
|
int _offset;
|
|
int _length;
|
|
byte[] _data;
|
|
|
|
static byte[] temp = new byte[8];
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
/// <param name="offset"></param>
|
|
/// <param name="length"></param>
|
|
public ByteBuffer(byte[] data, int offset = 0, int length = -1)
|
|
{
|
|
_data = data;
|
|
_pointer = 0;
|
|
_offset = offset;
|
|
if (length < 0)
|
|
_length = data.Length - offset;
|
|
else
|
|
_length = length;
|
|
littleEndian = false;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int position
|
|
{
|
|
get { return _pointer; }
|
|
set { _pointer = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int length
|
|
{
|
|
get { return _length; }
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public bool bytesAvailable
|
|
{
|
|
get { return _pointer < _length; }
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public byte[] buffer
|
|
{
|
|
get { return _data; }
|
|
set
|
|
{
|
|
_data = value;
|
|
_pointer = 0;
|
|
_offset = 0;
|
|
_length = _data.Length;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="count"></param>
|
|
/// <returns></returns>
|
|
public int Skip(int count)
|
|
{
|
|
_pointer += count;
|
|
return _pointer;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public byte ReadByte()
|
|
{
|
|
return _data[_offset + _pointer++];
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="output"></param>
|
|
/// <param name="destIndex"></param>
|
|
/// <param name="count"></param>
|
|
/// <returns></returns>
|
|
public byte[] ReadBytes(byte[] output, int destIndex, int count)
|
|
{
|
|
if (count > _length - _pointer)
|
|
throw new ArgumentOutOfRangeException();
|
|
|
|
Array.Copy(_data, _offset + _pointer, output, destIndex, count);
|
|
_pointer += count;
|
|
return output;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="count"></param>
|
|
/// <returns></returns>
|
|
public byte[] ReadBytes(int count)
|
|
{
|
|
if (count > _length - _pointer)
|
|
throw new ArgumentOutOfRangeException();
|
|
|
|
byte[] result = new byte[count];
|
|
Array.Copy(_data, _offset + _pointer, result, 0, count);
|
|
_pointer += count;
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public ByteBuffer ReadBuffer()
|
|
{
|
|
int count = ReadInt();
|
|
ByteBuffer ba = new ByteBuffer(_data, _pointer, count);
|
|
ba.stringTable = stringTable;
|
|
ba.version = version;
|
|
_pointer += count;
|
|
return ba;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public char ReadChar()
|
|
{
|
|
return (char)ReadShort();
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool ReadBool()
|
|
{
|
|
bool result = _data[_offset + _pointer] == 1;
|
|
_pointer++;
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public short ReadShort()
|
|
{
|
|
int startIndex = _offset + _pointer;
|
|
_pointer += 2;
|
|
if (littleEndian)
|
|
return (short)(_data[startIndex] | (_data[startIndex + 1] << 8));
|
|
else
|
|
return (short)((_data[startIndex] << 8) | _data[startIndex + 1]);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public ushort ReadUshort()
|
|
{
|
|
return (ushort)ReadShort();
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public int ReadInt()
|
|
{
|
|
int startIndex = _offset + _pointer;
|
|
_pointer += 4;
|
|
if (littleEndian)
|
|
return (_data[startIndex]) | (_data[startIndex + 1] << 8) | (_data[startIndex + 2] << 16) | (_data[startIndex + 3] << 24);
|
|
else
|
|
return (_data[startIndex] << 24) | (_data[startIndex + 1] << 16) | (_data[startIndex + 2] << 8) | (_data[startIndex + 3]);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public uint ReadUint()
|
|
{
|
|
return (uint)ReadInt();
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public float ReadFloat()
|
|
{
|
|
int startIndex = _offset + _pointer;
|
|
_pointer += 4;
|
|
if (littleEndian == BitConverter.IsLittleEndian)
|
|
return BitConverter.ToSingle(_data, startIndex);
|
|
else
|
|
{
|
|
temp[3] = _data[startIndex];
|
|
temp[2] = _data[startIndex + 1];
|
|
temp[1] = _data[startIndex + 2];
|
|
temp[0] = _data[startIndex + 3];
|
|
return BitConverter.ToSingle(temp, 0);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public long ReadLong()
|
|
{
|
|
int startIndex = _offset + _pointer;
|
|
_pointer += 8;
|
|
if (littleEndian)
|
|
{
|
|
int i1 = (_data[startIndex]) | (_data[startIndex + 1] << 8) | (_data[startIndex + 2] << 16) | (_data[startIndex + 3] << 24);
|
|
int i2 = (_data[startIndex + 4]) | (_data[startIndex + 5] << 8) | (_data[startIndex + 6] << 16) | (_data[startIndex + 7] << 24);
|
|
return (uint)i1 | ((long)i2 << 32);
|
|
}
|
|
else
|
|
{
|
|
int i1 = (_data[startIndex] << 24) | (_data[startIndex + 1] << 16) | (_data[startIndex + 2] << 8) | (_data[startIndex + 3]);
|
|
int i2 = (_data[startIndex + 4] << 24) | (_data[startIndex + 5] << 16) | (_data[startIndex + 6] << 8) | (_data[startIndex + 7]);
|
|
return (uint)i2 | ((long)i1 << 32);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public double ReadDouble()
|
|
{
|
|
int startIndex = _offset + _pointer;
|
|
_pointer += 8;
|
|
if (littleEndian == BitConverter.IsLittleEndian)
|
|
return BitConverter.ToDouble(_data, startIndex);
|
|
else
|
|
{
|
|
temp[7] = _data[startIndex];
|
|
temp[6] = _data[startIndex + 1];
|
|
temp[5] = _data[startIndex + 2];
|
|
temp[4] = _data[startIndex + 3];
|
|
temp[3] = _data[startIndex + 4];
|
|
temp[2] = _data[startIndex + 5];
|
|
temp[1] = _data[startIndex + 6];
|
|
temp[0] = _data[startIndex + 7];
|
|
return BitConverter.ToSingle(temp, 0);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string ReadString()
|
|
{
|
|
ushort len = ReadUshort();
|
|
string result = Encoding.UTF8.GetString(_data, _offset + _pointer, len);
|
|
_pointer += len;
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="len"></param>
|
|
/// <returns></returns>
|
|
public string ReadString(int len)
|
|
{
|
|
string result = Encoding.UTF8.GetString(_data, _offset + _pointer, len);
|
|
_pointer += len;
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string ReadS()
|
|
{
|
|
int index = ReadUshort();
|
|
if (index == 65534) //null
|
|
return null;
|
|
else if (index == 65533)
|
|
return string.Empty;
|
|
else
|
|
return stringTable[index];
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="cnt"></param>
|
|
/// <returns></returns>
|
|
public string[] ReadSArray(int cnt)
|
|
{
|
|
string[] ret = new string[cnt];
|
|
for (int i = 0; i < cnt; i++)
|
|
ret[i] = ReadS();
|
|
|
|
return ret;
|
|
}
|
|
|
|
private static List<GPathPoint> helperPoints = new List<GPathPoint>();
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="result"></param>
|
|
public List<GPathPoint> ReadPath()
|
|
{
|
|
helperPoints.Clear();
|
|
|
|
int len = ReadInt();
|
|
if (len == 0)
|
|
return helperPoints;
|
|
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
GPathPoint.CurveType curveType = (GPathPoint.CurveType)ReadByte();
|
|
switch (curveType)
|
|
{
|
|
case GPathPoint.CurveType.Bezier:
|
|
helperPoints.Add(new GPathPoint(new Vector3(ReadFloat(), ReadFloat(), 0),
|
|
new Vector3(ReadFloat(), ReadFloat(), 0)));
|
|
break;
|
|
|
|
case GPathPoint.CurveType.CubicBezier:
|
|
helperPoints.Add(new GPathPoint(new Vector3(ReadFloat(), ReadFloat(), 0),
|
|
new Vector3(ReadFloat(), ReadFloat(), 0),
|
|
new Vector3(ReadFloat(), ReadFloat(), 0)));
|
|
break;
|
|
|
|
default:
|
|
helperPoints.Add(new GPathPoint(new Vector3(ReadFloat(), ReadFloat(), 0), curveType));
|
|
break;
|
|
}
|
|
}
|
|
|
|
return helperPoints;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
public void WriteS(string value)
|
|
{
|
|
int index = ReadUshort();
|
|
if (index != 65534 && index != 65533)
|
|
stringTable[index] = value;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public Color ReadColor()
|
|
{
|
|
int startIndex = _offset + _pointer;
|
|
byte r = _data[startIndex];
|
|
byte g = _data[startIndex + 1];
|
|
byte b = _data[startIndex + 2];
|
|
byte a = _data[startIndex + 3];
|
|
_pointer += 4;
|
|
|
|
return new Color32(r, g, b, a);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="indexTablePos"></param>
|
|
/// <param name="blockIndex"></param>
|
|
/// <returns></returns>
|
|
public bool Seek(int indexTablePos, int blockIndex)
|
|
{
|
|
int tmp = _pointer;
|
|
_pointer = indexTablePos;
|
|
int segCount = _data[_offset + _pointer++];
|
|
if (blockIndex < segCount)
|
|
{
|
|
bool useShort = _data[_offset + _pointer++] == 1;
|
|
int newPos;
|
|
if (useShort)
|
|
{
|
|
_pointer += 2 * blockIndex;
|
|
newPos = ReadShort();
|
|
}
|
|
else
|
|
{
|
|
_pointer += 4 * blockIndex;
|
|
newPos = ReadInt();
|
|
}
|
|
|
|
if (newPos > 0)
|
|
{
|
|
_pointer = indexTablePos + newPos;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
_pointer = tmp;
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_pointer = tmp;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|