ByteBuffer.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. using System;
  2. using System.Text;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. namespace FairyGUI.Utils
  6. {
  7. /// <summary>
  8. ///
  9. /// </summary>
  10. public class ByteBuffer
  11. {
  12. /// <summary>
  13. ///
  14. /// </summary>
  15. public bool littleEndian;
  16. /// <summary>
  17. ///
  18. /// </summary>
  19. public string[] stringTable;
  20. /// <summary>
  21. ///
  22. /// </summary>
  23. public int version;
  24. int _pointer;
  25. int _offset;
  26. int _length;
  27. byte[] _data;
  28. static byte[] temp = new byte[8];
  29. /// <summary>
  30. ///
  31. /// </summary>
  32. /// <param name="data"></param>
  33. /// <param name="offset"></param>
  34. /// <param name="length"></param>
  35. public ByteBuffer(byte[] data, int offset = 0, int length = -1)
  36. {
  37. _data = data;
  38. _pointer = 0;
  39. _offset = offset;
  40. if (length < 0)
  41. _length = data.Length - offset;
  42. else
  43. _length = length;
  44. littleEndian = false;
  45. }
  46. /// <summary>
  47. ///
  48. /// </summary>
  49. public int position
  50. {
  51. get { return _pointer; }
  52. set { _pointer = value; }
  53. }
  54. /// <summary>
  55. ///
  56. /// </summary>
  57. public int length
  58. {
  59. get { return _length; }
  60. }
  61. /// <summary>
  62. ///
  63. /// </summary>
  64. public bool bytesAvailable
  65. {
  66. get { return _pointer < _length; }
  67. }
  68. /// <summary>
  69. ///
  70. /// </summary>
  71. public byte[] buffer
  72. {
  73. get { return _data; }
  74. set
  75. {
  76. _data = value;
  77. _pointer = 0;
  78. _offset = 0;
  79. _length = _data.Length;
  80. }
  81. }
  82. /// <summary>
  83. ///
  84. /// </summary>
  85. /// <param name="count"></param>
  86. /// <returns></returns>
  87. public int Skip(int count)
  88. {
  89. _pointer += count;
  90. return _pointer;
  91. }
  92. /// <summary>
  93. ///
  94. /// </summary>
  95. /// <returns></returns>
  96. public byte ReadByte()
  97. {
  98. return _data[_offset + _pointer++];
  99. }
  100. /// <summary>
  101. ///
  102. /// </summary>
  103. /// <param name="output"></param>
  104. /// <param name="destIndex"></param>
  105. /// <param name="count"></param>
  106. /// <returns></returns>
  107. public byte[] ReadBytes(byte[] output, int destIndex, int count)
  108. {
  109. if (count > _length - _pointer)
  110. throw new ArgumentOutOfRangeException();
  111. Array.Copy(_data, _offset + _pointer, output, destIndex, count);
  112. _pointer += count;
  113. return output;
  114. }
  115. /// <summary>
  116. ///
  117. /// </summary>
  118. /// <param name="count"></param>
  119. /// <returns></returns>
  120. public byte[] ReadBytes(int count)
  121. {
  122. if (count > _length - _pointer)
  123. throw new ArgumentOutOfRangeException();
  124. byte[] result = new byte[count];
  125. Array.Copy(_data, _offset + _pointer, result, 0, count);
  126. _pointer += count;
  127. return result;
  128. }
  129. /// <summary>
  130. ///
  131. /// </summary>
  132. /// <returns></returns>
  133. public ByteBuffer ReadBuffer()
  134. {
  135. int count = ReadInt();
  136. ByteBuffer ba = new ByteBuffer(_data, _pointer, count);
  137. ba.stringTable = stringTable;
  138. ba.version = version;
  139. _pointer += count;
  140. return ba;
  141. }
  142. /// <summary>
  143. ///
  144. /// </summary>
  145. /// <returns></returns>
  146. public char ReadChar()
  147. {
  148. return (char)ReadShort();
  149. }
  150. /// <summary>
  151. ///
  152. /// </summary>
  153. /// <returns></returns>
  154. public bool ReadBool()
  155. {
  156. bool result = _data[_offset + _pointer] == 1;
  157. _pointer++;
  158. return result;
  159. }
  160. /// <summary>
  161. ///
  162. /// </summary>
  163. /// <returns></returns>
  164. public short ReadShort()
  165. {
  166. int startIndex = _offset + _pointer;
  167. _pointer += 2;
  168. if (littleEndian)
  169. return (short)(_data[startIndex] | (_data[startIndex + 1] << 8));
  170. else
  171. return (short)((_data[startIndex] << 8) | _data[startIndex + 1]);
  172. }
  173. /// <summary>
  174. ///
  175. /// </summary>
  176. /// <returns></returns>
  177. public ushort ReadUshort()
  178. {
  179. return (ushort)ReadShort();
  180. }
  181. /// <summary>
  182. ///
  183. /// </summary>
  184. /// <returns></returns>
  185. public int ReadInt()
  186. {
  187. int startIndex = _offset + _pointer;
  188. _pointer += 4;
  189. if (littleEndian)
  190. return (_data[startIndex]) | (_data[startIndex + 1] << 8) | (_data[startIndex + 2] << 16) | (_data[startIndex + 3] << 24);
  191. else
  192. return (_data[startIndex] << 24) | (_data[startIndex + 1] << 16) | (_data[startIndex + 2] << 8) | (_data[startIndex + 3]);
  193. }
  194. /// <summary>
  195. ///
  196. /// </summary>
  197. /// <returns></returns>
  198. public uint ReadUint()
  199. {
  200. return (uint)ReadInt();
  201. }
  202. /// <summary>
  203. ///
  204. /// </summary>
  205. /// <returns></returns>
  206. public float ReadFloat()
  207. {
  208. int startIndex = _offset + _pointer;
  209. _pointer += 4;
  210. if (littleEndian == BitConverter.IsLittleEndian)
  211. return BitConverter.ToSingle(_data, startIndex);
  212. else
  213. {
  214. temp[3] = _data[startIndex];
  215. temp[2] = _data[startIndex + 1];
  216. temp[1] = _data[startIndex + 2];
  217. temp[0] = _data[startIndex + 3];
  218. return BitConverter.ToSingle(temp, 0);
  219. }
  220. }
  221. /// <summary>
  222. ///
  223. /// </summary>
  224. /// <returns></returns>
  225. public long ReadLong()
  226. {
  227. int startIndex = _offset + _pointer;
  228. _pointer += 8;
  229. if (littleEndian)
  230. {
  231. int i1 = (_data[startIndex]) | (_data[startIndex + 1] << 8) | (_data[startIndex + 2] << 16) | (_data[startIndex + 3] << 24);
  232. int i2 = (_data[startIndex + 4]) | (_data[startIndex + 5] << 8) | (_data[startIndex + 6] << 16) | (_data[startIndex + 7] << 24);
  233. return (uint)i1 | ((long)i2 << 32);
  234. }
  235. else
  236. {
  237. int i1 = (_data[startIndex] << 24) | (_data[startIndex + 1] << 16) | (_data[startIndex + 2] << 8) | (_data[startIndex + 3]);
  238. int i2 = (_data[startIndex + 4] << 24) | (_data[startIndex + 5] << 16) | (_data[startIndex + 6] << 8) | (_data[startIndex + 7]);
  239. return (uint)i2 | ((long)i1 << 32);
  240. }
  241. }
  242. /// <summary>
  243. ///
  244. /// </summary>
  245. /// <returns></returns>
  246. public double ReadDouble()
  247. {
  248. int startIndex = _offset + _pointer;
  249. _pointer += 8;
  250. if (littleEndian == BitConverter.IsLittleEndian)
  251. return BitConverter.ToDouble(_data, startIndex);
  252. else
  253. {
  254. temp[7] = _data[startIndex];
  255. temp[6] = _data[startIndex + 1];
  256. temp[5] = _data[startIndex + 2];
  257. temp[4] = _data[startIndex + 3];
  258. temp[3] = _data[startIndex + 4];
  259. temp[2] = _data[startIndex + 5];
  260. temp[1] = _data[startIndex + 6];
  261. temp[0] = _data[startIndex + 7];
  262. return BitConverter.ToSingle(temp, 0);
  263. }
  264. }
  265. /// <summary>
  266. ///
  267. /// </summary>
  268. /// <returns></returns>
  269. public string ReadString()
  270. {
  271. ushort len = ReadUshort();
  272. string result = Encoding.UTF8.GetString(_data, _offset + _pointer, len);
  273. _pointer += len;
  274. return result;
  275. }
  276. /// <summary>
  277. ///
  278. /// </summary>
  279. /// <param name="len"></param>
  280. /// <returns></returns>
  281. public string ReadString(int len)
  282. {
  283. string result = Encoding.UTF8.GetString(_data, _offset + _pointer, len);
  284. _pointer += len;
  285. return result;
  286. }
  287. /// <summary>
  288. ///
  289. /// </summary>
  290. /// <returns></returns>
  291. public string ReadS()
  292. {
  293. int index = ReadUshort();
  294. if (index == 65534) //null
  295. return null;
  296. else if (index == 65533)
  297. return string.Empty;
  298. else
  299. return stringTable[index];
  300. }
  301. /// <summary>
  302. ///
  303. /// </summary>
  304. /// <param name="cnt"></param>
  305. /// <returns></returns>
  306. public string[] ReadSArray(int cnt)
  307. {
  308. string[] ret = new string[cnt];
  309. for (int i = 0; i < cnt; i++)
  310. ret[i] = ReadS();
  311. return ret;
  312. }
  313. private static List<GPathPoint> helperPoints = new List<GPathPoint>();
  314. /// <summary>
  315. ///
  316. /// </summary>
  317. /// <param name="result"></param>
  318. public List<GPathPoint> ReadPath()
  319. {
  320. helperPoints.Clear();
  321. int len = ReadInt();
  322. if (len == 0)
  323. return helperPoints;
  324. for (int i = 0; i < len; i++)
  325. {
  326. GPathPoint.CurveType curveType = (GPathPoint.CurveType)ReadByte();
  327. switch (curveType)
  328. {
  329. case GPathPoint.CurveType.Bezier:
  330. helperPoints.Add(new GPathPoint(new Vector3(ReadFloat(), ReadFloat(), 0),
  331. new Vector3(ReadFloat(), ReadFloat(), 0)));
  332. break;
  333. case GPathPoint.CurveType.CubicBezier:
  334. helperPoints.Add(new GPathPoint(new Vector3(ReadFloat(), ReadFloat(), 0),
  335. new Vector3(ReadFloat(), ReadFloat(), 0),
  336. new Vector3(ReadFloat(), ReadFloat(), 0)));
  337. break;
  338. default:
  339. helperPoints.Add(new GPathPoint(new Vector3(ReadFloat(), ReadFloat(), 0), curveType));
  340. break;
  341. }
  342. }
  343. return helperPoints;
  344. }
  345. /// <summary>
  346. ///
  347. /// </summary>
  348. /// <param name="value"></param>
  349. public void WriteS(string value)
  350. {
  351. int index = ReadUshort();
  352. if (index != 65534 && index != 65533)
  353. stringTable[index] = value;
  354. }
  355. /// <summary>
  356. ///
  357. /// </summary>
  358. /// <returns></returns>
  359. public Color ReadColor()
  360. {
  361. int startIndex = _offset + _pointer;
  362. byte r = _data[startIndex];
  363. byte g = _data[startIndex + 1];
  364. byte b = _data[startIndex + 2];
  365. byte a = _data[startIndex + 3];
  366. _pointer += 4;
  367. return new Color32(r, g, b, a);
  368. }
  369. /// <summary>
  370. ///
  371. /// </summary>
  372. /// <param name="indexTablePos"></param>
  373. /// <param name="blockIndex"></param>
  374. /// <returns></returns>
  375. public bool Seek(int indexTablePos, int blockIndex)
  376. {
  377. int tmp = _pointer;
  378. _pointer = indexTablePos;
  379. int segCount = _data[_offset + _pointer++];
  380. if (blockIndex < segCount)
  381. {
  382. bool useShort = _data[_offset + _pointer++] == 1;
  383. int newPos;
  384. if (useShort)
  385. {
  386. _pointer += 2 * blockIndex;
  387. newPos = ReadShort();
  388. }
  389. else
  390. {
  391. _pointer += 4 * blockIndex;
  392. newPos = ReadInt();
  393. }
  394. if (newPos > 0)
  395. {
  396. _pointer = indexTablePos + newPos;
  397. return true;
  398. }
  399. else
  400. {
  401. _pointer = tmp;
  402. return false;
  403. }
  404. }
  405. else
  406. {
  407. _pointer = tmp;
  408. return false;
  409. }
  410. }
  411. }
  412. }