You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

316 lines
11 KiB

  1. #region License
  2. // Copyright (c) 2007 James Newton-King
  3. //
  4. // Permission is hereby granted, free of charge, to any person
  5. // obtaining a copy of this software and associated documentation
  6. // files (the "Software"), to deal in the Software without
  7. // restriction, including without limitation the rights to use,
  8. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following
  11. // conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. // OTHER DEALINGS IN THE SOFTWARE.
  24. #endregion
  25. using System;
  26. using System.Collections;
  27. using System.Collections.Generic;
  28. using System.Reflection;
  29. using System.Runtime.Serialization;
  30. using Newtonsoft.Json.Linq;
  31. using Newtonsoft.Json.Utilities;
  32. namespace Newtonsoft.Json.Serialization
  33. {
  34. internal enum JsonContractType
  35. {
  36. None = 0,
  37. Object = 1,
  38. Array = 2,
  39. Primitive = 3,
  40. String = 4,
  41. Dictionary = 5,
  42. Dynamic = 6,
  43. Serializable = 7,
  44. Linq = 8
  45. }
  46. /// <summary>
  47. /// Handles <see cref="JsonSerializer"/> serialization callback events.
  48. /// </summary>
  49. /// <param name="o">The object that raised the callback event.</param>
  50. /// <param name="context">The streaming context.</param>
  51. internal delegate void SerializationCallback(object o, StreamingContext context);
  52. /// <summary>
  53. /// Handles <see cref="JsonSerializer"/> serialization error callback events.
  54. /// </summary>
  55. /// <param name="o">The object that raised the callback event.</param>
  56. /// <param name="context">The streaming context.</param>
  57. /// <param name="errorContext">The error context.</param>
  58. internal delegate void SerializationErrorCallback(object o, StreamingContext context, ErrorContext errorContext);
  59. /// <summary>
  60. /// Sets extension data for an object during deserialization.
  61. /// </summary>
  62. /// <param name="o">The object to set extension data on.</param>
  63. /// <param name="key">The extension data key.</param>
  64. /// <param name="value">The extension data value.</param>
  65. internal delegate void ExtensionDataSetter(object o, string key, object value);
  66. /// <summary>
  67. /// Gets extension data for an object during serialization.
  68. /// </summary>
  69. /// <param name="o">The object to set extension data on.</param>
  70. internal delegate IEnumerable<KeyValuePair<object, object>> ExtensionDataGetter(object o);
  71. /// <summary>
  72. /// Contract details for a <see cref="System.Type"/> used by the <see cref="JsonSerializer"/>.
  73. /// </summary>
  74. internal abstract class JsonContract
  75. {
  76. internal bool IsNullable;
  77. internal bool IsConvertable;
  78. internal bool IsEnum;
  79. internal Type NonNullableUnderlyingType;
  80. internal ReadType InternalReadType;
  81. internal JsonContractType ContractType;
  82. internal bool IsReadOnlyOrFixedSize;
  83. internal bool IsSealed;
  84. internal bool IsInstantiable;
  85. private List<SerializationCallback> _onDeserializedCallbacks;
  86. private IList<SerializationCallback> _onDeserializingCallbacks;
  87. private IList<SerializationCallback> _onSerializedCallbacks;
  88. private IList<SerializationCallback> _onSerializingCallbacks;
  89. private IList<SerializationErrorCallback> _onErrorCallbacks;
  90. private Type _createdType;
  91. /// <summary>
  92. /// Gets the underlying type for the contract.
  93. /// </summary>
  94. /// <value>The underlying type for the contract.</value>
  95. public Type UnderlyingType { get; }
  96. /// <summary>
  97. /// Gets or sets the type created during deserialization.
  98. /// </summary>
  99. /// <value>The type created during deserialization.</value>
  100. public Type CreatedType
  101. {
  102. get => _createdType;
  103. set
  104. {
  105. _createdType = value;
  106. IsSealed = _createdType.IsSealed();
  107. IsInstantiable = !(_createdType.IsInterface() || _createdType.IsAbstract());
  108. }
  109. }
  110. /// <summary>
  111. /// Gets or sets whether this type contract is serialized as a reference.
  112. /// </summary>
  113. /// <value>Whether this type contract is serialized as a reference.</value>
  114. public bool? IsReference { get; set; }
  115. /// <summary>
  116. /// Gets or sets the default <see cref="JsonConverter" /> for this contract.
  117. /// </summary>
  118. /// <value>The converter.</value>
  119. public JsonConverter Converter { get; set; }
  120. // internally specified JsonConverter's to override default behavour
  121. // checked for after passed in converters and attribute specified converters
  122. internal JsonConverter InternalConverter { get; set; }
  123. /// <summary>
  124. /// Gets or sets all methods called immediately after deserialization of the object.
  125. /// </summary>
  126. /// <value>The methods called immediately after deserialization of the object.</value>
  127. public IList<SerializationCallback> OnDeserializedCallbacks
  128. {
  129. get
  130. {
  131. if (_onDeserializedCallbacks == null)
  132. {
  133. _onDeserializedCallbacks = new List<SerializationCallback>();
  134. }
  135. return _onDeserializedCallbacks;
  136. }
  137. }
  138. /// <summary>
  139. /// Gets or sets all methods called during deserialization of the object.
  140. /// </summary>
  141. /// <value>The methods called during deserialization of the object.</value>
  142. public IList<SerializationCallback> OnDeserializingCallbacks
  143. {
  144. get
  145. {
  146. if (_onDeserializingCallbacks == null)
  147. {
  148. _onDeserializingCallbacks = new List<SerializationCallback>();
  149. }
  150. return _onDeserializingCallbacks;
  151. }
  152. }
  153. /// <summary>
  154. /// Gets or sets all methods called after serialization of the object graph.
  155. /// </summary>
  156. /// <value>The methods called after serialization of the object graph.</value>
  157. public IList<SerializationCallback> OnSerializedCallbacks
  158. {
  159. get
  160. {
  161. if (_onSerializedCallbacks == null)
  162. {
  163. _onSerializedCallbacks = new List<SerializationCallback>();
  164. }
  165. return _onSerializedCallbacks;
  166. }
  167. }
  168. /// <summary>
  169. /// Gets or sets all methods called before serialization of the object.
  170. /// </summary>
  171. /// <value>The methods called before serialization of the object.</value>
  172. public IList<SerializationCallback> OnSerializingCallbacks
  173. {
  174. get
  175. {
  176. if (_onSerializingCallbacks == null)
  177. {
  178. _onSerializingCallbacks = new List<SerializationCallback>();
  179. }
  180. return _onSerializingCallbacks;
  181. }
  182. }
  183. /// <summary>
  184. /// Gets or sets all method called when an error is thrown during the serialization of the object.
  185. /// </summary>
  186. /// <value>The methods called when an error is thrown during the serialization of the object.</value>
  187. public IList<SerializationErrorCallback> OnErrorCallbacks
  188. {
  189. get
  190. {
  191. if (_onErrorCallbacks == null)
  192. {
  193. _onErrorCallbacks = new List<SerializationErrorCallback>();
  194. }
  195. return _onErrorCallbacks;
  196. }
  197. }
  198. /// <summary>
  199. /// Gets or sets the default creator method used to create the object.
  200. /// </summary>
  201. /// <value>The default creator method used to create the object.</value>
  202. public Func<object> DefaultCreator { get; set; }
  203. /// <summary>
  204. /// Gets or sets a value indicating whether the default creator is non-public.
  205. /// </summary>
  206. /// <value><c>true</c> if the default object creator is non-public; otherwise, <c>false</c>.</value>
  207. public bool DefaultCreatorNonPublic { get; set; }
  208. internal JsonContract(Type underlyingType)
  209. {
  210. ValidationUtils.ArgumentNotNull(underlyingType, nameof(underlyingType));
  211. UnderlyingType = underlyingType;
  212. IsNullable = ReflectionUtils.IsNullable(underlyingType);
  213. NonNullableUnderlyingType = (IsNullable && ReflectionUtils.IsNullableType(underlyingType)) ? Nullable.GetUnderlyingType(underlyingType) : underlyingType;
  214. CreatedType = NonNullableUnderlyingType;
  215. IsConvertable = ConvertUtils.IsConvertible(NonNullableUnderlyingType);
  216. IsEnum = NonNullableUnderlyingType.IsEnum();
  217. InternalReadType = ReadType.Read;
  218. }
  219. internal void InvokeOnSerializing(object o, StreamingContext context)
  220. {
  221. if (_onSerializingCallbacks != null)
  222. {
  223. foreach (SerializationCallback callback in _onSerializingCallbacks)
  224. {
  225. callback(o, context);
  226. }
  227. }
  228. }
  229. internal void InvokeOnSerialized(object o, StreamingContext context)
  230. {
  231. if (_onSerializedCallbacks != null)
  232. {
  233. foreach (SerializationCallback callback in _onSerializedCallbacks)
  234. {
  235. callback(o, context);
  236. }
  237. }
  238. }
  239. internal void InvokeOnDeserializing(object o, StreamingContext context)
  240. {
  241. if (_onDeserializingCallbacks != null)
  242. {
  243. foreach (SerializationCallback callback in _onDeserializingCallbacks)
  244. {
  245. callback(o, context);
  246. }
  247. }
  248. }
  249. internal void InvokeOnDeserialized(object o, StreamingContext context)
  250. {
  251. if (_onDeserializedCallbacks != null)
  252. {
  253. foreach (SerializationCallback callback in _onDeserializedCallbacks)
  254. {
  255. callback(o, context);
  256. }
  257. }
  258. }
  259. internal void InvokeOnError(object o, StreamingContext context, ErrorContext errorContext)
  260. {
  261. if (_onErrorCallbacks != null)
  262. {
  263. foreach (SerializationErrorCallback callback in _onErrorCallbacks)
  264. {
  265. callback(o, context, errorContext);
  266. }
  267. }
  268. }
  269. internal static SerializationCallback CreateSerializationCallback(MethodInfo callbackMethodInfo)
  270. {
  271. return (o, context) => callbackMethodInfo.Invoke(o, new object[] { context });
  272. }
  273. internal static SerializationErrorCallback CreateSerializationErrorCallback(MethodInfo callbackMethodInfo)
  274. {
  275. return (o, context, econtext) => callbackMethodInfo.Invoke(o, new object[] { context, econtext });
  276. }
  277. }
  278. }