/sources/core/Stride.Core/Serialization/Serializers/PrimitiveTypeSerializers.cs

https://github.com/xenko3d/xenko · C# · 372 lines · 251 code · 32 blank · 89 comment · 26 complexity · 75ed2c2f016c7b72a98db6b7c16861a9 MD5 · raw file

  1. // Copyright (c) Stride contributors (https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
  2. // Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
  3. #pragma warning disable SA1402 // File may only contain a single class
  4. #pragma warning disable SA1649 // File name must match first type name
  5. using System;
  6. using System.Runtime.InteropServices;
  7. using Stride.Core.Reflection;
  8. namespace Stride.Core.Serialization.Serializers
  9. {
  10. /// <summary>
  11. /// Data serializer for string.
  12. /// </summary>
  13. [DataSerializerGlobal(typeof(UriSerializer))]
  14. public class UriSerializer : DataSerializer<Uri>
  15. {
  16. /// <inheritdoc/>
  17. public override void Serialize(ref Uri obj, ArchiveMode mode, SerializationStream stream)
  18. {
  19. if (mode == ArchiveMode.Serialize)
  20. {
  21. var text = obj.ToString();
  22. stream.Serialize(ref text);
  23. }
  24. else
  25. {
  26. string text = null;
  27. stream.Serialize(ref text);
  28. obj = new Uri(text);
  29. }
  30. }
  31. }
  32. /// <summary>
  33. /// Data serializer for string.
  34. /// </summary>
  35. [DataSerializerGlobal(typeof(StringSerializer))]
  36. public class StringSerializer : DataSerializer<string>
  37. {
  38. /// <inheritdoc/>
  39. public override void Serialize(ref string obj, ArchiveMode mode, SerializationStream stream)
  40. {
  41. stream.Serialize(ref obj);
  42. }
  43. }
  44. /// <summary>
  45. /// Data serializer for bool.
  46. /// </summary>
  47. [DataSerializerGlobal(typeof(BoolSerializer))]
  48. public class BoolSerializer : DataSerializer<bool>
  49. {
  50. /// <inheritdoc/>
  51. public override void Serialize(ref bool obj, ArchiveMode mode, SerializationStream stream)
  52. {
  53. stream.Serialize(ref obj);
  54. }
  55. }
  56. /// <summary>
  57. /// Data serializer for float.
  58. /// </summary>
  59. [DataSerializerGlobal(typeof(SingleSerializer))]
  60. public class SingleSerializer : DataSerializer<float>
  61. {
  62. /// <inheritdoc/>
  63. public override bool IsBlittable => true;
  64. /// <inheritdoc/>
  65. public override void Serialize(ref float obj, ArchiveMode mode, SerializationStream stream)
  66. {
  67. stream.Serialize(ref obj);
  68. }
  69. }
  70. /// <summary>
  71. /// Data serializer for double.
  72. /// </summary>
  73. [DataSerializerGlobal(typeof(DoubleSerializer))]
  74. public class DoubleSerializer : DataSerializer<double>
  75. {
  76. /// <inheritdoc/>
  77. public override bool IsBlittable => true;
  78. /// <inheritdoc/>
  79. public override void Serialize(ref double obj, ArchiveMode mode, SerializationStream stream)
  80. {
  81. stream.Serialize(ref obj);
  82. }
  83. }
  84. /// <summary>
  85. /// Data serializer for char.
  86. /// </summary>
  87. [DataSerializerGlobal(typeof(CharSerializer))]
  88. public class CharSerializer : DataSerializer<char>
  89. {
  90. /// <inheritdoc/>
  91. public override void Serialize(ref char obj, ArchiveMode mode, SerializationStream stream)
  92. {
  93. stream.Serialize(ref obj);
  94. }
  95. }
  96. /// <summary>
  97. /// Data serializer for byte.
  98. /// </summary>
  99. [DataSerializerGlobal(typeof(ByteSerializer))]
  100. public class ByteSerializer : DataSerializer<byte>
  101. {
  102. /// <inheritdoc/>
  103. public override bool IsBlittable => true;
  104. /// <inheritdoc/>
  105. public override void Serialize(ref byte obj, ArchiveMode mode, SerializationStream stream)
  106. {
  107. stream.Serialize(ref obj);
  108. }
  109. }
  110. /// <summary>
  111. /// Data serializer for sbyte.
  112. /// </summary>
  113. [DataSerializerGlobal(typeof(SByteSerializer))]
  114. public class SByteSerializer : DataSerializer<sbyte>
  115. {
  116. /// <inheritdoc/>
  117. public override bool IsBlittable => true;
  118. /// <inheritdoc/>
  119. public override void Serialize(ref sbyte obj, ArchiveMode mode, SerializationStream stream)
  120. {
  121. stream.Serialize(ref obj);
  122. }
  123. }
  124. /// <summary>
  125. /// Data serializer for short.
  126. /// </summary>
  127. [DataSerializerGlobal(typeof(Int16Serializer))]
  128. public class Int16Serializer : DataSerializer<short>
  129. {
  130. /// <inheritdoc/>
  131. public override bool IsBlittable => true;
  132. /// <inheritdoc/>
  133. public override void Serialize(ref short obj, ArchiveMode mode, SerializationStream stream)
  134. {
  135. stream.Serialize(ref obj);
  136. }
  137. }
  138. /// <summary>
  139. /// Data serializer for ushort.
  140. /// </summary>
  141. [DataSerializerGlobal(typeof(UInt16Serializer))]
  142. public class UInt16Serializer : DataSerializer<ushort>
  143. {
  144. /// <inheritdoc/>
  145. public override bool IsBlittable => true;
  146. /// <inheritdoc/>
  147. public override void Serialize(ref ushort obj, ArchiveMode mode, SerializationStream stream)
  148. {
  149. stream.Serialize(ref obj);
  150. }
  151. }
  152. /// <summary>
  153. /// Data serializer for int.
  154. /// </summary>
  155. [DataSerializerGlobal(typeof(Int32Serializer))]
  156. public class Int32Serializer : DataSerializer<int>
  157. {
  158. /// <inheritdoc/>
  159. public override bool IsBlittable => true;
  160. /// <inheritdoc/>
  161. public override void Serialize(ref int obj, ArchiveMode mode, SerializationStream stream)
  162. {
  163. stream.Serialize(ref obj);
  164. }
  165. }
  166. /// <summary>
  167. /// Data serializer for uint.
  168. /// </summary>
  169. [DataSerializerGlobal(typeof(UInt32Serializer))]
  170. public class UInt32Serializer : DataSerializer<uint>
  171. {
  172. /// <inheritdoc/>
  173. public override bool IsBlittable => true;
  174. /// <inheritdoc/>
  175. public override void Serialize(ref uint obj, ArchiveMode mode, SerializationStream stream)
  176. {
  177. stream.Serialize(ref obj);
  178. }
  179. }
  180. /// <summary>
  181. /// Data serializer for long.
  182. /// </summary>
  183. [DataSerializerGlobal(typeof(Int64Serializer))]
  184. public class Int64Serializer : DataSerializer<long>
  185. {
  186. /// <inheritdoc/>
  187. public override bool IsBlittable => true;
  188. /// <inheritdoc/>
  189. public override void Serialize(ref long obj, ArchiveMode mode, SerializationStream stream)
  190. {
  191. stream.Serialize(ref obj);
  192. }
  193. }
  194. /// <summary>
  195. /// Data serializer for ulong.
  196. /// </summary>
  197. [DataSerializerGlobal(typeof(UInt64Serializer))]
  198. public class UInt64Serializer : DataSerializer<ulong>
  199. {
  200. /// <inheritdoc/>
  201. public override bool IsBlittable => true;
  202. /// <inheritdoc/>
  203. public override void Serialize(ref ulong obj, ArchiveMode mode, SerializationStream stream)
  204. {
  205. stream.Serialize(ref obj);
  206. }
  207. }
  208. /// <summary>
  209. /// Data serializer for Enum.
  210. /// </summary>
  211. public class EnumSerializer : DataSerializer<Enum>
  212. {
  213. /// <inheritdoc/>
  214. public override void Serialize(ref Enum obj, ArchiveMode mode, SerializationStream stream)
  215. {
  216. if (mode == ArchiveMode.Serialize)
  217. {
  218. stream.Write(obj != null ? obj.GetType().AssemblyQualifiedName : string.Empty);
  219. stream.Write(Convert.ToInt32(obj));
  220. }
  221. else if (mode == ArchiveMode.Deserialize)
  222. {
  223. var type = AssemblyRegistry.GetType(stream.ReadString());
  224. var value = stream.ReadInt32();
  225. if (type != null)
  226. obj = (Enum)Enum.ToObject(type, value);
  227. }
  228. }
  229. }
  230. /// <summary>
  231. /// Data serializer for typed enum.
  232. /// </summary>
  233. public unsafe class EnumSerializer<T> : DataSerializer<T> where T : struct
  234. {
  235. private int enumSize;
  236. public override void Initialize(SerializerSelector serializerSelector)
  237. {
  238. // Use Marshal SizeOf to avoid AOT issues on iOS
  239. enumSize = Marshal.SizeOf(Enum.GetUnderlyingType(typeof(T)));
  240. }
  241. /// <inheritdoc/>
  242. public override void Serialize(ref T obj, ArchiveMode mode, SerializationStream stream)
  243. {
  244. // For now, 1 and 2 bytes enum are stored as 4 bytes for previous binary compatibility.
  245. // Future, 2 choices if we decide to drop it and have more compact formats for small enum:
  246. // - Dump as-is from/to memory (not so resistant to structure size changes)
  247. // - Use 7bit encoded integer
  248. switch (enumSize)
  249. {
  250. case 1:
  251. {
  252. var objPtr = (byte*)Interop.Cast(ref obj);
  253. uint value = *objPtr;
  254. stream.Serialize(ref value);
  255. *objPtr = (byte)value;
  256. break;
  257. }
  258. case 2:
  259. {
  260. var objPtr = (ushort*)Interop.Cast(ref obj);
  261. uint value = *objPtr;
  262. stream.Serialize(ref value);
  263. *objPtr = (ushort)value;
  264. break;
  265. }
  266. case 4:
  267. {
  268. var objPtr = (uint*)Interop.Cast(ref obj);
  269. stream.Serialize(ref *objPtr);
  270. break;
  271. }
  272. case 8:
  273. {
  274. var objPtr = (ulong*)Interop.Cast(ref obj);
  275. stream.Serialize(ref *objPtr);
  276. break;
  277. }
  278. default:
  279. throw new InvalidOperationException();
  280. }
  281. }
  282. }
  283. /// <summary>
  284. /// Data serializer for Guid.
  285. /// </summary>
  286. [DataSerializerGlobal(typeof(GuidSerializer))]
  287. public class GuidSerializer : DataSerializer<Guid>
  288. {
  289. /// <inheritdoc/>
  290. public override bool IsBlittable => true;
  291. /// <inheritdoc/>
  292. public override void Serialize(ref Guid obj, ArchiveMode mode, SerializationStream stream)
  293. {
  294. if (mode == ArchiveMode.Serialize)
  295. {
  296. var guidData = obj.ToByteArray();
  297. stream.Serialize(guidData, 0, guidData.Length);
  298. }
  299. else if (mode == ArchiveMode.Deserialize)
  300. {
  301. var guidData = new byte[16];
  302. stream.Serialize(guidData, 0, guidData.Length);
  303. obj = new Guid(guidData);
  304. }
  305. }
  306. }
  307. /// <summary>
  308. /// Data serializer for TimeSpan.
  309. /// </summary>
  310. [DataSerializerGlobal(typeof(TimeSpanSerializer))]
  311. public class TimeSpanSerializer : DataSerializer<TimeSpan>
  312. {
  313. public override void Serialize(ref TimeSpan timeSpan, ArchiveMode mode, SerializationStream stream)
  314. {
  315. if (mode == ArchiveMode.Serialize)
  316. {
  317. stream.Write(timeSpan.Ticks);
  318. }
  319. else if (mode == ArchiveMode.Deserialize)
  320. {
  321. timeSpan = new TimeSpan(stream.ReadInt64());
  322. }
  323. }
  324. }
  325. [DataSerializerGlobal(typeof(DateTimeSerializer))]
  326. public class DateTimeSerializer : DataSerializer<DateTime>
  327. {
  328. public override void Serialize(ref DateTime dateTime, ArchiveMode mode, SerializationStream stream)
  329. {
  330. if (mode == ArchiveMode.Serialize)
  331. {
  332. stream.Write(dateTime.Ticks);
  333. }
  334. else if (mode == ArchiveMode.Deserialize)
  335. {
  336. dateTime = new DateTime(stream.ReadInt64());
  337. }
  338. }
  339. }
  340. }