You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			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;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |