PageRenderTime 28ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/client/clrcore/MsgPackDeserializer.cs

https://gitlab.com/Zeus_Fox/multifive-core
C# | 352 lines | 270 code | 79 blank | 3 comment | 16 complexity | 38ca28a12244de3982dd3bd1431fc925 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Dynamic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace CitizenFX.Core
  9. {
  10. public delegate object CallbackDelegate(params object[] args);
  11. internal static class MsgPackDeserializer
  12. {
  13. public static object Deserialize(byte[] data)
  14. {
  15. var memoryStream = new MemoryStream(data);
  16. var reader = new BinaryReader(memoryStream);
  17. return UnpackAny(reader);
  18. }
  19. static object UnpackAny(BinaryReader reader)
  20. {
  21. var type = reader.ReadByte();
  22. var unpacker = GetUnpacker(type);
  23. return unpacker(type, reader);
  24. }
  25. static object UnpackMap(BinaryReader reader, int length)
  26. {
  27. var retObject = new ExpandoObject() as IDictionary<string, object>;
  28. for (int i = 0; i < length; i++)
  29. {
  30. var key = UnpackAny(reader).ToString();
  31. var value = UnpackAny(reader);
  32. retObject[key] = value;
  33. }
  34. return retObject;
  35. }
  36. static object UnpackArray(BinaryReader reader, int length)
  37. {
  38. List<object> retObject = new List<object>();
  39. for (int i = 0; i < length; i++)
  40. {
  41. var value = UnpackAny(reader);
  42. retObject.Add(value);
  43. }
  44. return retObject;
  45. }
  46. static object UnpackNil(byte a, BinaryReader reader)
  47. {
  48. return null;
  49. }
  50. static object UnpackTrue(byte a, BinaryReader reader)
  51. {
  52. return true;
  53. }
  54. static object UnpackFalse(byte a, BinaryReader reader)
  55. {
  56. return false;
  57. }
  58. static object UnpackSingle(byte a, BinaryReader reader)
  59. {
  60. var bytes = reader.ReadBytes(4);
  61. return BitConverter.ToSingle(new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] }, 0);
  62. }
  63. static object UnpackDouble(byte a, BinaryReader reader)
  64. {
  65. var bytes = reader.ReadBytes(8);
  66. return BitConverter.ToDouble(new byte[] { bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0] }, 0);
  67. }
  68. static object UnpackFixNumPos(byte a, BinaryReader reader)
  69. {
  70. return (int)a;
  71. }
  72. static object UnpackUInt8(byte a, BinaryReader reader)
  73. {
  74. return reader.ReadByte();
  75. }
  76. static object UnpackUInt16(byte a, BinaryReader reader)
  77. {
  78. var bytes = reader.ReadBytes(2);
  79. return BitConverter.ToUInt16(new byte[] { bytes[1], bytes[0] }, 0);
  80. }
  81. static object UnpackUInt32(byte a, BinaryReader reader)
  82. {
  83. var bytes = reader.ReadBytes(4);
  84. return BitConverter.ToUInt32(new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] }, 0);
  85. }
  86. static object UnpackUInt64(byte a, BinaryReader reader)
  87. {
  88. var bytes = reader.ReadBytes(8);
  89. return BitConverter.ToUInt64(new byte[] { bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0] }, 0);
  90. }
  91. static object UnpackInt8(byte a, BinaryReader reader)
  92. {
  93. return reader.ReadSByte();
  94. }
  95. static object UnpackInt16(byte a, BinaryReader reader)
  96. {
  97. var bytes = reader.ReadBytes(2);
  98. return BitConverter.ToInt16(new byte[] { bytes[1], bytes[0] }, 0);
  99. }
  100. static object UnpackInt32(byte a, BinaryReader reader)
  101. {
  102. var bytes = reader.ReadBytes(4);
  103. return BitConverter.ToInt32(new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] }, 0);
  104. }
  105. static object UnpackInt64(byte a, BinaryReader reader)
  106. {
  107. var bytes = reader.ReadBytes(8);
  108. return BitConverter.ToInt64(new byte[] { bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0] }, 0);
  109. }
  110. static object UnpackFixNumNeg(byte a, BinaryReader reader)
  111. {
  112. return (int)a - 256;
  113. }
  114. static object UnpackFixStr(byte a, BinaryReader reader)
  115. {
  116. var len = a % 32;
  117. var bytes = reader.ReadBytes(len);
  118. return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
  119. }
  120. static object UnpackString8(byte a, BinaryReader reader)
  121. {
  122. var len = reader.ReadByte();
  123. var bytes = reader.ReadBytes(len);
  124. return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
  125. }
  126. static object UnpackString16(byte a, BinaryReader reader)
  127. {
  128. var lenBytes = reader.ReadBytes(2);
  129. var len = BitConverter.ToUInt16(new byte[] { lenBytes[1], lenBytes[0] }, 0);
  130. var bytes = reader.ReadBytes(len);
  131. return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
  132. }
  133. static object UnpackString32(byte a, BinaryReader reader)
  134. {
  135. var lenBytes = reader.ReadBytes(4);
  136. var len = BitConverter.ToInt32(new byte[] { lenBytes[3], lenBytes[2], lenBytes[1], lenBytes[0] }, 0);
  137. var bytes = reader.ReadBytes(len);
  138. return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
  139. }
  140. static object UnpackBin8(byte a, BinaryReader reader)
  141. {
  142. var len = reader.ReadByte();
  143. return reader.ReadBytes(len);
  144. }
  145. static object UnpackBin16(byte a, BinaryReader reader)
  146. {
  147. var lenBytes = reader.ReadBytes(2);
  148. var len = BitConverter.ToUInt16(new byte[] { lenBytes[1], lenBytes[0] }, 0);
  149. return reader.ReadBytes(len);
  150. }
  151. static object UnpackBin32(byte a, BinaryReader reader)
  152. {
  153. var lenBytes = reader.ReadBytes(4);
  154. var len = BitConverter.ToInt32(new byte[] { lenBytes[3], lenBytes[2], lenBytes[1], lenBytes[0] }, 0);
  155. return reader.ReadBytes(len);
  156. }
  157. static object UnpackFixArray(byte a, BinaryReader reader)
  158. {
  159. var len = a % 16;
  160. return UnpackArray(reader, len);
  161. }
  162. static object UnpackArray16(byte a, BinaryReader reader)
  163. {
  164. var lenBytes = reader.ReadBytes(2);
  165. var len = BitConverter.ToUInt16(new byte[] { lenBytes[1], lenBytes[0] }, 0);
  166. return UnpackArray(reader, len);
  167. }
  168. static object UnpackArray32(byte a, BinaryReader reader)
  169. {
  170. var lenBytes = reader.ReadBytes(4);
  171. var len = BitConverter.ToInt32(new byte[] { lenBytes[3], lenBytes[2], lenBytes[1], lenBytes[0] }, 0);
  172. return UnpackArray(reader, len);
  173. }
  174. static object UnpackFixMap(byte a, BinaryReader reader)
  175. {
  176. var len = a % 16;
  177. return UnpackMap(reader, len);
  178. }
  179. static object UnpackMap16(byte a, BinaryReader reader)
  180. {
  181. var lenBytes = reader.ReadBytes(2);
  182. var len = BitConverter.ToUInt16(new byte[] { lenBytes[1], lenBytes[0] }, 0);
  183. return UnpackMap(reader, len);
  184. }
  185. static object UnpackMap32(byte a, BinaryReader reader)
  186. {
  187. var lenBytes = reader.ReadBytes(4);
  188. var len = BitConverter.ToInt32(new byte[] { lenBytes[3], lenBytes[2], lenBytes[1], lenBytes[0] }, 0);
  189. return UnpackMap(reader, len);
  190. }
  191. static object UnpackExt8(byte a, BinaryReader reader)
  192. {
  193. var length = reader.ReadByte();
  194. var extType = reader.ReadByte();
  195. if (extType != 1)
  196. {
  197. throw new InvalidOperationException("Only extension type 1 (Citizen callback) is handled by this class.");
  198. }
  199. // read the local reference ID
  200. var tmpBytes = reader.ReadBytes(4);
  201. var reference = BitConverter.ToUInt32(new byte[] { tmpBytes[3], tmpBytes[2], tmpBytes[1], tmpBytes[0] }, 0);
  202. // read the environment instance ID
  203. tmpBytes = reader.ReadBytes(4);
  204. var instance = BitConverter.ToUInt32(new byte[] { tmpBytes[3], tmpBytes[2], tmpBytes[1], tmpBytes[0] }, 0);
  205. // read the resource name
  206. tmpBytes = reader.ReadBytes(length - 8);
  207. var resource = Encoding.UTF8.GetString(tmpBytes, 0, tmpBytes.Length);
  208. var remoteFunctionReference = new RemoteFunctionReference(resource, instance, reference);
  209. return new CallbackDelegate(delegate(object[] args)
  210. {
  211. var byteData = MsgPackSerializer.Serialize(args);
  212. var returnByteData = remoteFunctionReference.InvokeNative(byteData);
  213. var returnData = Deserialize(returnByteData) as List<object>;
  214. if (returnData == null || returnData.Count == 0)
  215. {
  216. return null;
  217. }
  218. return (returnData)[0];
  219. });
  220. }
  221. private static Dictionary<byte, Func<byte, BinaryReader, object>> ms_unpackMap = new Dictionary<byte, Func<byte, BinaryReader, object>>()
  222. {
  223. { 0xC0, UnpackNil },
  224. { 0xC2, UnpackFalse },
  225. { 0xC3, UnpackTrue },
  226. { 0xC4, UnpackBin8 },
  227. { 0xC5, UnpackBin16 },
  228. { 0xC6, UnpackBin32 },
  229. { 0xC7, UnpackExt8 },
  230. { 0xCA, UnpackSingle },
  231. { 0xCB, UnpackDouble },
  232. { 0xCC, UnpackUInt8 },
  233. { 0xCD, UnpackUInt16 },
  234. { 0xCE, UnpackUInt32 },
  235. { 0xCF, UnpackUInt64 },
  236. { 0xD0, UnpackInt8 },
  237. { 0xD1, UnpackInt16 },
  238. { 0xD2, UnpackInt32 },
  239. { 0xD3, UnpackInt64 },
  240. { 0xD9, UnpackString8 },
  241. { 0xDA, UnpackString16 },
  242. { 0xDB, UnpackString32 },
  243. { 0xDC, UnpackArray16 },
  244. { 0xDD, UnpackArray32 },
  245. { 0xDE, UnpackMap16 },
  246. { 0xDF, UnpackMap32 },
  247. };
  248. private static Func<byte, BinaryReader, object> GetUnpacker(byte type)
  249. {
  250. if (type < 0xC0)
  251. {
  252. if (type < 0x80)
  253. {
  254. return UnpackFixNumPos;
  255. }
  256. else if (type < 0x90)
  257. {
  258. return UnpackFixMap;
  259. }
  260. else if (type < 0xA0)
  261. {
  262. return UnpackFixArray;
  263. }
  264. return UnpackFixStr;
  265. }
  266. else if (type > 0xDF)
  267. {
  268. return UnpackFixNumNeg;
  269. }
  270. return ms_unpackMap[type];
  271. }
  272. }
  273. }