Serialization.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Numerics;
  4. using System.Text;
  5. using System.Text.Json;
  6. namespace SharpGLTF.IO
  7. {
  8. static class _JSonSerializationExtensions
  9. {
  10. public static Boolean AsBoolean(this in Utf8JsonReader reader)
  11. {
  12. switch (reader.TokenType)
  13. {
  14. case JsonTokenType.Null: return false;
  15. case JsonTokenType.True: return true;
  16. case JsonTokenType.False: return false;
  17. case JsonTokenType.Number: return reader.GetInt32() != 0;
  18. default: throw new NotImplementedException();
  19. }
  20. }
  21. public static String AsString(this in Utf8JsonReader reader)
  22. {
  23. switch (reader.TokenType)
  24. {
  25. case JsonTokenType.Null: return null;
  26. case JsonTokenType.String: return reader.GetString();
  27. case JsonTokenType.PropertyName: return reader.GetString();
  28. case JsonTokenType.True: return "true";
  29. case JsonTokenType.False: return "false";
  30. case JsonTokenType.Number: return reader.GetDecimal().ToString(System.Globalization.CultureInfo.InvariantCulture);
  31. default: throw new NotImplementedException();
  32. }
  33. }
  34. public static Object AsEnum(this in Utf8JsonReader reader, Type enumType)
  35. {
  36. if (reader.TokenType == JsonTokenType.String)
  37. {
  38. var jsonVal = reader.GetString();
  39. try { return Enum.Parse(enumType, jsonVal, true); }
  40. catch (System.ArgumentException ex)
  41. {
  42. throw new System.Text.Json.JsonException($"Value {jsonVal} not found int {enumType}", ex);
  43. }
  44. }
  45. if (reader.TokenType == JsonTokenType.Number)
  46. {
  47. if (reader.TryGetInt32(out Int32 int32Val)) return Enum.ToObject(enumType, int32Val);
  48. if (reader.TryGetInt64(out Int64 int64Val)) return Enum.ToObject(enumType, int64Val);
  49. }
  50. throw new NotImplementedException();
  51. }
  52. public static Object GetAnyValue(this in Utf8JsonReader reader)
  53. {
  54. switch (reader.TokenType)
  55. {
  56. case JsonTokenType.Null: return null;
  57. case JsonTokenType.True: return true;
  58. case JsonTokenType.False: return false;
  59. case JsonTokenType.String: return reader.GetString();
  60. case JsonTokenType.Number: return reader.GetDecimal();
  61. case JsonTokenType.PropertyName: return reader.GetString();
  62. default: throw new NotImplementedException();
  63. }
  64. }
  65. public static Object GetValueAs(this in Utf8JsonReader reader, Type vtype)
  66. {
  67. System.Diagnostics.Debug.Assert(reader.TokenType != JsonTokenType.StartArray);
  68. System.Diagnostics.Debug.Assert(reader.TokenType != JsonTokenType.EndArray);
  69. System.Diagnostics.Debug.Assert(reader.TokenType != JsonTokenType.StartObject);
  70. System.Diagnostics.Debug.Assert(reader.TokenType != JsonTokenType.EndObject);
  71. if (reader.TokenType == JsonTokenType.Null) return null;
  72. if (vtype == typeof(String)) { return reader.AsString(); }
  73. if (vtype == typeof(Boolean)) { return reader.AsBoolean(); }
  74. if (vtype == typeof(Int16)) { return reader.GetInt16(); }
  75. if (vtype == typeof(Int32)) { return reader.GetInt32(); }
  76. if (vtype == typeof(Int64)) { return reader.GetInt64(); }
  77. if (vtype == typeof(UInt16)) { return reader.GetUInt16(); }
  78. if (vtype == typeof(UInt32)) { return reader.GetUInt32(); }
  79. if (vtype == typeof(UInt64)) { return reader.GetUInt64(); }
  80. if (vtype == typeof(Single)) { return reader.GetSingle(); }
  81. if (vtype == typeof(Double)) { return reader.GetDouble(); }
  82. if (vtype == typeof(Decimal)) { return reader.GetDecimal(); }
  83. return Convert.ChangeType(reader.GetString(), vtype, System.Globalization.CultureInfo.InvariantCulture);
  84. }
  85. public static T GetValueAs<T>(this in Utf8JsonReader reader)
  86. where T : struct
  87. {
  88. return (T)reader.GetValueAs(typeof(T));
  89. }
  90. public static bool TryWriteProperty(this Utf8JsonWriter writer, string property, Object value)
  91. {
  92. if (value is String vstr) { writer.WriteString(property, vstr); return true; }
  93. if (value is Boolean vbol) { writer.WriteBoolean(property, vbol); return true; }
  94. if (value is Byte vu8) { writer.WriteNumber(property, vu8); return true; }
  95. if (value is UInt16 vu16) { writer.WriteNumber(property, vu16); return true; }
  96. if (value is UInt32 vu32) { writer.WriteNumber(property, vu32); return true; }
  97. if (value is UInt64 vu64) { writer.WriteNumber(property, vu64); return true; }
  98. if (value is SByte vs8) { writer.WriteNumber(property, vs8); return true; }
  99. if (value is Int16 vs16) { writer.WriteNumber(property, vs16); return true; }
  100. if (value is Int32 vs32) { writer.WriteNumber(property, vs32); return true; }
  101. if (value is Int64 vs64) { writer.WriteNumber(property, vs64); return true; }
  102. if (value is Single vf32) { writer.WriteNumber(property, vf32); return true; }
  103. if (value is Double vf64) { writer.WriteNumber(property, vf64); return true; }
  104. if (value is Decimal vfxx) { writer.WriteNumber(property, vfxx); return true; }
  105. if (value is Vector2 vvv2) { writer.WritePropertyName(property); writer.WriteVector2(vvv2); return true; }
  106. if (value is Vector3 vvv3) { writer.WritePropertyName(property); writer.WriteVector3(vvv3); return true; }
  107. if (value is Vector4 vvv4) { writer.WritePropertyName(property); writer.WriteVector4(vvv4); return true; }
  108. if (value is Quaternion qqq4) { writer.WritePropertyName(property); writer.WriteQuaternion(qqq4); return true; }
  109. if (value is Matrix4x4 mm44) { writer.WritePropertyName(property); writer.WriteMatrix4x4(mm44); return true; }
  110. return false;
  111. }
  112. public static bool TryWriteValue(this Utf8JsonWriter writer, Object value)
  113. {
  114. if (value is String vstr) { writer.WriteStringValue(vstr); return true; }
  115. if (value is Boolean vbol) { writer.WriteBooleanValue(vbol); return true; }
  116. if (value is Byte vu8) { writer.WriteNumberValue(vu8); return true; }
  117. if (value is UInt16 vu16) { writer.WriteNumberValue(vu16); return true; }
  118. if (value is UInt32 vu32) { writer.WriteNumberValue(vu32); return true; }
  119. if (value is UInt64 vu64) { writer.WriteNumberValue(vu64); return true; }
  120. if (value is SByte vs8) { writer.WriteNumberValue(vs8); return true; }
  121. if (value is Int16 vs16) { writer.WriteNumberValue(vs16); return true; }
  122. if (value is Int32 vs32) { writer.WriteNumberValue(vs32); return true; }
  123. if (value is Int64 vs64) { writer.WriteNumberValue(vs64); return true; }
  124. if (value is Single vf32) { writer.WriteNumberValue(vf32); return true; }
  125. if (value is Double vf64) { writer.WriteNumberValue(vf64); return true; }
  126. if (value is Decimal vfxx) { writer.WriteNumberValue(vfxx); return true; }
  127. if (value is Vector2 vvv2) { writer.WriteVector2(vvv2); return true; }
  128. if (value is Vector3 vvv3) { writer.WriteVector3(vvv3); return true; }
  129. if (value is Vector4 vvv4) { writer.WriteVector4(vvv4); return true; }
  130. if (value is Quaternion qqq4) { writer.WriteQuaternion(qqq4); return true; }
  131. if (value is Matrix4x4 mm44) { writer.WriteMatrix4x4(mm44); return true; }
  132. return false;
  133. }
  134. public static void WriteVector2(this Utf8JsonWriter writer, Vector2 v)
  135. {
  136. writer.WriteStartArray();
  137. writer.WriteNumberValue(v.X);
  138. writer.WriteNumberValue(v.Y);
  139. writer.WriteEndArray();
  140. }
  141. public static void WriteVector3(this Utf8JsonWriter writer, Vector3 v)
  142. {
  143. writer.WriteStartArray();
  144. writer.WriteNumberValue(v.X);
  145. writer.WriteNumberValue(v.Y);
  146. writer.WriteNumberValue(v.Z);
  147. writer.WriteEndArray();
  148. }
  149. public static void WriteVector4(this Utf8JsonWriter writer, Vector4 v)
  150. {
  151. writer.WriteStartArray();
  152. writer.WriteNumberValue(v.X);
  153. writer.WriteNumberValue(v.Y);
  154. writer.WriteNumberValue(v.Z);
  155. writer.WriteNumberValue(v.W);
  156. writer.WriteEndArray();
  157. }
  158. public static void WriteQuaternion(this Utf8JsonWriter writer, Quaternion q)
  159. {
  160. writer.WriteStartArray();
  161. writer.WriteNumberValue(q.X);
  162. writer.WriteNumberValue(q.Y);
  163. writer.WriteNumberValue(q.Z);
  164. writer.WriteNumberValue(q.W);
  165. writer.WriteEndArray();
  166. }
  167. public static void WriteMatrix4x4(this Utf8JsonWriter writer, Matrix4x4 m)
  168. {
  169. writer.WriteStartArray();
  170. writer.WriteNumberValue(m.M11);
  171. writer.WriteNumberValue(m.M12);
  172. writer.WriteNumberValue(m.M13);
  173. writer.WriteNumberValue(m.M14);
  174. writer.WriteNumberValue(m.M21);
  175. writer.WriteNumberValue(m.M22);
  176. writer.WriteNumberValue(m.M23);
  177. writer.WriteNumberValue(m.M24);
  178. writer.WriteNumberValue(m.M31);
  179. writer.WriteNumberValue(m.M32);
  180. writer.WriteNumberValue(m.M33);
  181. writer.WriteNumberValue(m.M34);
  182. writer.WriteNumberValue(m.M41);
  183. writer.WriteNumberValue(m.M42);
  184. writer.WriteNumberValue(m.M43);
  185. writer.WriteNumberValue(m.M44);
  186. writer.WriteEndArray();
  187. }
  188. }
  189. }