using System;
using System.Text;
using System.Collections.Generic;
using UnityEngine;
namespace FairyGUI.Utils
{
///
///
///
public class ByteBuffer
{
///
///
///
public bool littleEndian;
///
///
///
public string[] stringTable;
///
///
///
public int version;
int _pointer;
int _offset;
int _length;
byte[] _data;
static byte[] temp = new byte[8];
///
///
///
///
///
///
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;
}
///
///
///
public int position
{
get { return _pointer; }
set { _pointer = value; }
}
///
///
///
public int length
{
get { return _length; }
}
///
///
///
public bool bytesAvailable
{
get { return _pointer < _length; }
}
///
///
///
public byte[] buffer
{
get { return _data; }
set
{
_data = value;
_pointer = 0;
_offset = 0;
_length = _data.Length;
}
}
///
///
///
///
///
public int Skip(int count)
{
_pointer += count;
return _pointer;
}
///
///
///
///
public byte ReadByte()
{
return _data[_offset + _pointer++];
}
///
///
///
///
///
///
///
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;
}
///
///
///
///
///
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;
}
///
///
///
///
public ByteBuffer ReadBuffer()
{
int count = ReadInt();
ByteBuffer ba = new ByteBuffer(_data, _pointer, count);
ba.stringTable = stringTable;
ba.version = version;
_pointer += count;
return ba;
}
///
///
///
///
public char ReadChar()
{
return (char)ReadShort();
}
///
///
///
///
public bool ReadBool()
{
bool result = _data[_offset + _pointer] == 1;
_pointer++;
return result;
}
///
///
///
///
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]);
}
///
///
///
///
public ushort ReadUshort()
{
return (ushort)ReadShort();
}
///
///
///
///
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]);
}
///
///
///
///
public uint ReadUint()
{
return (uint)ReadInt();
}
///
///
///
///
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);
}
}
///
///
///
///
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);
}
}
///
///
///
///
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);
}
}
///
///
///
///
public string ReadString()
{
ushort len = ReadUshort();
string result = Encoding.UTF8.GetString(_data, _offset + _pointer, len);
_pointer += len;
return result;
}
///
///
///
///
///
public string ReadString(int len)
{
string result = Encoding.UTF8.GetString(_data, _offset + _pointer, len);
_pointer += len;
return result;
}
///
///
///
///
public string ReadS()
{
int index = ReadUshort();
if (index == 65534) //null
return null;
else if (index == 65533)
return string.Empty;
else
return stringTable[index];
}
///
///
///
///
///
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 helperPoints = new List();
///
///
///
///
public List 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;
}
///
///
///
///
public void WriteS(string value)
{
int index = ReadUshort();
if (index != 65534 && index != 65533)
stringTable[index] = value;
}
///
///
///
///
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);
}
///
///
///
///
///
///
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;
}
}
}
}