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.

1793 lines
91 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  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. #if HAVE_ASYNC
  26. using System;
  27. using System.Globalization;
  28. using System.Threading;
  29. #if HAVE_BIG_INTEGER
  30. using System.Numerics;
  31. #endif
  32. using System.Threading.Tasks;
  33. using Newtonsoft.Json.Utilities;
  34. namespace Newtonsoft.Json
  35. {
  36. internal abstract partial class JsonWriter
  37. {
  38. internal Task AutoCompleteAsync(JsonToken tokenBeingWritten, CancellationToken cancellationToken)
  39. {
  40. State oldState = _currentState;
  41. // gets new state based on the current state and what is being written
  42. State newState = StateArray[(int)tokenBeingWritten][(int)oldState];
  43. if (newState == State.Error)
  44. {
  45. throw JsonWriterException.Create(this, "Token {0} in state {1} would result in an invalid JSON object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), oldState.ToString()), null);
  46. }
  47. _currentState = newState;
  48. if (_formatting == Formatting.Indented)
  49. {
  50. switch (oldState)
  51. {
  52. case State.Start:
  53. break;
  54. case State.Property:
  55. return WriteIndentSpaceAsync(cancellationToken);
  56. case State.ArrayStart:
  57. case State.ConstructorStart:
  58. return WriteIndentAsync(cancellationToken);
  59. case State.Array:
  60. case State.Constructor:
  61. return tokenBeingWritten == JsonToken.Comment ? WriteIndentAsync(cancellationToken) : AutoCompleteAsync(cancellationToken);
  62. case State.Object:
  63. switch (tokenBeingWritten)
  64. {
  65. case JsonToken.Comment:
  66. break;
  67. case JsonToken.PropertyName:
  68. return AutoCompleteAsync(cancellationToken);
  69. default:
  70. return WriteValueDelimiterAsync(cancellationToken);
  71. }
  72. break;
  73. default:
  74. if (tokenBeingWritten == JsonToken.PropertyName)
  75. {
  76. return WriteIndentAsync(cancellationToken);
  77. }
  78. break;
  79. }
  80. }
  81. else if (tokenBeingWritten != JsonToken.Comment)
  82. {
  83. switch (oldState)
  84. {
  85. case State.Object:
  86. case State.Array:
  87. case State.Constructor:
  88. return WriteValueDelimiterAsync(cancellationToken);
  89. }
  90. }
  91. return AsyncUtils.CompletedTask;
  92. }
  93. private async Task AutoCompleteAsync(CancellationToken cancellationToken)
  94. {
  95. await WriteValueDelimiterAsync(cancellationToken).ConfigureAwait(false);
  96. await WriteIndentAsync(cancellationToken).ConfigureAwait(false);
  97. }
  98. /// <summary>
  99. /// Asynchronously closes this writer.
  100. /// If <see cref="JsonWriter.CloseOutput"/> is set to <c>true</c>, the destination is also closed.
  101. /// </summary>
  102. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  103. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  104. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  105. /// classes can override this behaviour for true asynchronicity.</remarks>
  106. public virtual Task CloseAsync(CancellationToken cancellationToken = default(CancellationToken))
  107. {
  108. if (cancellationToken.IsCancellationRequested)
  109. {
  110. return cancellationToken.FromCanceled();
  111. }
  112. Close();
  113. return AsyncUtils.CompletedTask;
  114. }
  115. /// <summary>
  116. /// Asynchronously flushes whatever is in the buffer to the destination and also flushes the destination.
  117. /// </summary>
  118. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  119. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  120. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  121. /// classes can override this behaviour for true asynchronicity.</remarks>
  122. public virtual Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
  123. {
  124. if (cancellationToken.IsCancellationRequested)
  125. {
  126. return cancellationToken.FromCanceled();
  127. }
  128. Flush();
  129. return AsyncUtils.CompletedTask;
  130. }
  131. /// <summary>
  132. /// Asynchronously writes the specified end token.
  133. /// </summary>
  134. /// <param name="token">The end token to write.</param>
  135. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  136. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  137. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  138. /// classes can override this behaviour for true asynchronicity.</remarks>
  139. protected virtual Task WriteEndAsync(JsonToken token, CancellationToken cancellationToken)
  140. {
  141. if (cancellationToken.IsCancellationRequested)
  142. {
  143. return cancellationToken.FromCanceled();
  144. }
  145. WriteEnd(token);
  146. return AsyncUtils.CompletedTask;
  147. }
  148. /// <summary>
  149. /// Asynchronously writes indent characters.
  150. /// </summary>
  151. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  152. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  153. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  154. /// classes can override this behaviour for true asynchronicity.</remarks>
  155. protected virtual Task WriteIndentAsync(CancellationToken cancellationToken)
  156. {
  157. if (cancellationToken.IsCancellationRequested)
  158. {
  159. return cancellationToken.FromCanceled();
  160. }
  161. WriteIndent();
  162. return AsyncUtils.CompletedTask;
  163. }
  164. /// <summary>
  165. /// Asynchronously writes the JSON value delimiter.
  166. /// </summary>
  167. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  168. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  169. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  170. /// classes can override this behaviour for true asynchronicity.</remarks>
  171. protected virtual Task WriteValueDelimiterAsync(CancellationToken cancellationToken)
  172. {
  173. if (cancellationToken.IsCancellationRequested)
  174. {
  175. return cancellationToken.FromCanceled();
  176. }
  177. WriteValueDelimiter();
  178. return AsyncUtils.CompletedTask;
  179. }
  180. /// <summary>
  181. /// Asynchronously writes an indent space.
  182. /// </summary>
  183. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  184. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  185. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  186. /// classes can override this behaviour for true asynchronicity.</remarks>
  187. protected virtual Task WriteIndentSpaceAsync(CancellationToken cancellationToken)
  188. {
  189. if (cancellationToken.IsCancellationRequested)
  190. {
  191. return cancellationToken.FromCanceled();
  192. }
  193. WriteIndentSpace();
  194. return AsyncUtils.CompletedTask;
  195. }
  196. /// <summary>
  197. /// Asynchronously writes raw JSON without changing the writer's state.
  198. /// </summary>
  199. /// <param name="json">The raw JSON to write.</param>
  200. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  201. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  202. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  203. /// classes can override this behaviour for true asynchronicity.</remarks>
  204. public virtual Task WriteRawAsync(string json, CancellationToken cancellationToken = default(CancellationToken))
  205. {
  206. if (cancellationToken.IsCancellationRequested)
  207. {
  208. return cancellationToken.FromCanceled();
  209. }
  210. WriteRaw(json);
  211. return AsyncUtils.CompletedTask;
  212. }
  213. /// <summary>
  214. /// Asynchronously writes the end of the current JSON object or array.
  215. /// </summary>
  216. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  217. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  218. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  219. /// classes can override this behaviour for true asynchronicity.</remarks>
  220. public virtual Task WriteEndAsync(CancellationToken cancellationToken = default(CancellationToken))
  221. {
  222. if (cancellationToken.IsCancellationRequested)
  223. {
  224. return cancellationToken.FromCanceled();
  225. }
  226. WriteEnd();
  227. return AsyncUtils.CompletedTask;
  228. }
  229. internal Task WriteEndInternalAsync(CancellationToken cancellationToken)
  230. {
  231. JsonContainerType type = Peek();
  232. switch (type)
  233. {
  234. case JsonContainerType.Object:
  235. return WriteEndObjectAsync(cancellationToken);
  236. case JsonContainerType.Array:
  237. return WriteEndArrayAsync(cancellationToken);
  238. case JsonContainerType.Constructor:
  239. return WriteEndConstructorAsync(cancellationToken);
  240. default:
  241. if (cancellationToken.IsCancellationRequested)
  242. {
  243. return cancellationToken.FromCanceled();
  244. }
  245. throw JsonWriterException.Create(this, "Unexpected type when writing end: " + type, null);
  246. }
  247. }
  248. internal Task InternalWriteEndAsync(JsonContainerType type, CancellationToken cancellationToken)
  249. {
  250. if (cancellationToken.IsCancellationRequested)
  251. {
  252. return cancellationToken.FromCanceled();
  253. }
  254. int levelsToComplete = CalculateLevelsToComplete(type);
  255. while (levelsToComplete-- > 0)
  256. {
  257. JsonToken token = GetCloseTokenForType(Pop());
  258. Task t;
  259. if (_currentState == State.Property)
  260. {
  261. t = WriteNullAsync(cancellationToken);
  262. if (!t.IsCompletedSucessfully())
  263. {
  264. return AwaitProperty(t, levelsToComplete, token, cancellationToken);
  265. }
  266. }
  267. if (_formatting == Formatting.Indented)
  268. {
  269. if (_currentState != State.ObjectStart && _currentState != State.ArrayStart)
  270. {
  271. t = WriteIndentAsync(cancellationToken);
  272. if (!t.IsCompletedSucessfully())
  273. {
  274. return AwaitIndent(t, levelsToComplete, token, cancellationToken);
  275. }
  276. }
  277. }
  278. t = WriteEndAsync(token, cancellationToken);
  279. if (!t.IsCompletedSucessfully())
  280. {
  281. return AwaitEnd(t, levelsToComplete, cancellationToken);
  282. }
  283. UpdateCurrentState();
  284. }
  285. return AsyncUtils.CompletedTask;
  286. // Local functions, params renamed (capitalized) so as not to capture and allocate when calling async
  287. async Task AwaitProperty(Task task, int LevelsToComplete, JsonToken token, CancellationToken CancellationToken)
  288. {
  289. await task.ConfigureAwait(false);
  290. // Finish current loop
  291. if (_formatting == Formatting.Indented)
  292. {
  293. if (_currentState != State.ObjectStart && _currentState != State.ArrayStart)
  294. {
  295. await WriteIndentAsync(CancellationToken).ConfigureAwait(false);
  296. }
  297. }
  298. await WriteEndAsync(token, CancellationToken).ConfigureAwait(false);
  299. UpdateCurrentState();
  300. await AwaitRemaining(LevelsToComplete, CancellationToken).ConfigureAwait(false);
  301. }
  302. async Task AwaitIndent(Task task, int LevelsToComplete, JsonToken token, CancellationToken CancellationToken)
  303. {
  304. await task.ConfigureAwait(false);
  305. // Finish current loop
  306. await WriteEndAsync(token, CancellationToken).ConfigureAwait(false);
  307. UpdateCurrentState();
  308. await AwaitRemaining(LevelsToComplete, CancellationToken).ConfigureAwait(false);
  309. }
  310. async Task AwaitEnd(Task task, int LevelsToComplete, CancellationToken CancellationToken)
  311. {
  312. await task.ConfigureAwait(false);
  313. // Finish current loop
  314. UpdateCurrentState();
  315. await AwaitRemaining(LevelsToComplete, CancellationToken).ConfigureAwait(false);
  316. }
  317. async Task AwaitRemaining(int LevelsToComplete, CancellationToken CancellationToken)
  318. {
  319. while (LevelsToComplete-- > 0)
  320. {
  321. JsonToken token = GetCloseTokenForType(Pop());
  322. if (_currentState == State.Property)
  323. {
  324. await WriteNullAsync(CancellationToken).ConfigureAwait(false);
  325. }
  326. if (_formatting == Formatting.Indented)
  327. {
  328. if (_currentState != State.ObjectStart && _currentState != State.ArrayStart)
  329. {
  330. await WriteIndentAsync(CancellationToken).ConfigureAwait(false);
  331. }
  332. }
  333. await WriteEndAsync(token, CancellationToken).ConfigureAwait(false);
  334. UpdateCurrentState();
  335. }
  336. }
  337. }
  338. /// <summary>
  339. /// Asynchronously writes the end of an array.
  340. /// </summary>
  341. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  342. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  343. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  344. /// classes can override this behaviour for true asynchronicity.</remarks>
  345. public virtual Task WriteEndArrayAsync(CancellationToken cancellationToken = default(CancellationToken))
  346. {
  347. if (cancellationToken.IsCancellationRequested)
  348. {
  349. return cancellationToken.FromCanceled();
  350. }
  351. WriteEndArray();
  352. return AsyncUtils.CompletedTask;
  353. }
  354. /// <summary>
  355. /// Asynchronously writes the end of a constructor.
  356. /// </summary>
  357. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  358. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  359. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  360. /// classes can override this behaviour for true asynchronicity.</remarks>
  361. public virtual Task WriteEndConstructorAsync(CancellationToken cancellationToken = default(CancellationToken))
  362. {
  363. if (cancellationToken.IsCancellationRequested)
  364. {
  365. return cancellationToken.FromCanceled();
  366. }
  367. WriteEndConstructor();
  368. return AsyncUtils.CompletedTask;
  369. }
  370. /// <summary>
  371. /// Asynchronously writes the end of a JSON object.
  372. /// </summary>
  373. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  374. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  375. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  376. /// classes can override this behaviour for true asynchronicity.</remarks>
  377. public virtual Task WriteEndObjectAsync(CancellationToken cancellationToken = default(CancellationToken))
  378. {
  379. if (cancellationToken.IsCancellationRequested)
  380. {
  381. return cancellationToken.FromCanceled();
  382. }
  383. WriteEndObject();
  384. return AsyncUtils.CompletedTask;
  385. }
  386. /// <summary>
  387. /// Asynchronously writes a null value.
  388. /// </summary>
  389. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  390. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  391. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  392. /// classes can override this behaviour for true asynchronicity.</remarks>
  393. public virtual Task WriteNullAsync(CancellationToken cancellationToken = default(CancellationToken))
  394. {
  395. if (cancellationToken.IsCancellationRequested)
  396. {
  397. return cancellationToken.FromCanceled();
  398. }
  399. WriteNull();
  400. return AsyncUtils.CompletedTask;
  401. }
  402. /// <summary>
  403. /// Asynchronously writes the property name of a name/value pair of a JSON object.
  404. /// </summary>
  405. /// <param name="name">The name of the property.</param>
  406. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  407. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  408. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  409. /// classes can override this behaviour for true asynchronicity.</remarks>
  410. public virtual Task WritePropertyNameAsync(string name, CancellationToken cancellationToken = default(CancellationToken))
  411. {
  412. if (cancellationToken.IsCancellationRequested)
  413. {
  414. return cancellationToken.FromCanceled();
  415. }
  416. WritePropertyName(name);
  417. return AsyncUtils.CompletedTask;
  418. }
  419. /// <summary>
  420. /// Asynchronously writes the property name of a name/value pair of a JSON object.
  421. /// </summary>
  422. /// <param name="name">The name of the property.</param>
  423. /// <param name="escape">A flag to indicate whether the text should be escaped when it is written as a JSON property name.</param>
  424. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  425. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  426. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  427. /// classes can override this behaviour for true asynchronicity.</remarks>
  428. public virtual Task WritePropertyNameAsync(string name, bool escape, CancellationToken cancellationToken = default(CancellationToken))
  429. {
  430. if (cancellationToken.IsCancellationRequested)
  431. {
  432. return cancellationToken.FromCanceled();
  433. }
  434. WritePropertyName(name, escape);
  435. return AsyncUtils.CompletedTask;
  436. }
  437. internal Task InternalWritePropertyNameAsync(string name, CancellationToken cancellationToken)
  438. {
  439. if (cancellationToken.IsCancellationRequested)
  440. {
  441. return cancellationToken.FromCanceled();
  442. }
  443. _currentPosition.PropertyName = name;
  444. return AutoCompleteAsync(JsonToken.PropertyName, cancellationToken);
  445. }
  446. /// <summary>
  447. /// Asynchronously writes the beginning of a JSON array.
  448. /// </summary>
  449. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  450. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  451. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  452. /// classes can override this behaviour for true asynchronicity.</remarks>
  453. public virtual Task WriteStartArrayAsync(CancellationToken cancellationToken = default(CancellationToken))
  454. {
  455. if (cancellationToken.IsCancellationRequested)
  456. {
  457. return cancellationToken.FromCanceled();
  458. }
  459. WriteStartArray();
  460. return AsyncUtils.CompletedTask;
  461. }
  462. internal async Task InternalWriteStartAsync(JsonToken token, JsonContainerType container, CancellationToken cancellationToken)
  463. {
  464. UpdateScopeWithFinishedValue();
  465. await AutoCompleteAsync(token, cancellationToken).ConfigureAwait(false);
  466. Push(container);
  467. }
  468. /// <summary>
  469. /// Asynchronously writes a comment <c>/*...*/</c> containing the specified text.
  470. /// </summary>
  471. /// <param name="text">Text to place inside the comment.</param>
  472. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  473. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  474. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  475. /// classes can override this behaviour for true asynchronicity.</remarks>
  476. public virtual Task WriteCommentAsync(string text, CancellationToken cancellationToken = default(CancellationToken))
  477. {
  478. if (cancellationToken.IsCancellationRequested)
  479. {
  480. return cancellationToken.FromCanceled();
  481. }
  482. WriteComment(text);
  483. return AsyncUtils.CompletedTask;
  484. }
  485. internal Task InternalWriteCommentAsync(CancellationToken cancellationToken)
  486. {
  487. return AutoCompleteAsync(JsonToken.Comment, cancellationToken);
  488. }
  489. /// <summary>
  490. /// Asynchronously writes raw JSON where a value is expected and updates the writer's state.
  491. /// </summary>
  492. /// <param name="json">The raw JSON to write.</param>
  493. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  494. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  495. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  496. /// classes can override this behaviour for true asynchronicity.</remarks>
  497. public virtual Task WriteRawValueAsync(string json, CancellationToken cancellationToken = default(CancellationToken))
  498. {
  499. if (cancellationToken.IsCancellationRequested)
  500. {
  501. return cancellationToken.FromCanceled();
  502. }
  503. WriteRawValue(json);
  504. return AsyncUtils.CompletedTask;
  505. }
  506. /// <summary>
  507. /// Asynchronously writes the start of a constructor with the given name.
  508. /// </summary>
  509. /// <param name="name">The name of the constructor.</param>
  510. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  511. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  512. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  513. /// classes can override this behaviour for true asynchronicity.</remarks>
  514. public virtual Task WriteStartConstructorAsync(string name, CancellationToken cancellationToken = default(CancellationToken))
  515. {
  516. if (cancellationToken.IsCancellationRequested)
  517. {
  518. return cancellationToken.FromCanceled();
  519. }
  520. WriteStartConstructor(name);
  521. return AsyncUtils.CompletedTask;
  522. }
  523. /// <summary>
  524. /// Asynchronously writes the beginning of a JSON object.
  525. /// </summary>
  526. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  527. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  528. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  529. /// classes can override this behaviour for true asynchronicity.</remarks>
  530. public virtual Task WriteStartObjectAsync(CancellationToken cancellationToken = default(CancellationToken))
  531. {
  532. if (cancellationToken.IsCancellationRequested)
  533. {
  534. return cancellationToken.FromCanceled();
  535. }
  536. WriteStartObject();
  537. return AsyncUtils.CompletedTask;
  538. }
  539. /// <summary>
  540. /// Asynchronously writes the current <see cref="JsonReader"/> token.
  541. /// </summary>
  542. /// <param name="reader">The <see cref="JsonReader"/> to read the token from.</param>
  543. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  544. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  545. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  546. /// classes can override this behaviour for true asynchronicity.</remarks>
  547. public Task WriteTokenAsync(JsonReader reader, CancellationToken cancellationToken = default(CancellationToken))
  548. {
  549. return WriteTokenAsync(reader, true, cancellationToken);
  550. }
  551. /// <summary>
  552. /// Asynchronously writes the current <see cref="JsonReader"/> token.
  553. /// </summary>
  554. /// <param name="reader">The <see cref="JsonReader"/> to read the token from.</param>
  555. /// <param name="writeChildren">A flag indicating whether the current token's children should be written.</param>
  556. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  557. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  558. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  559. /// classes can override this behaviour for true asynchronicity.</remarks>
  560. public Task WriteTokenAsync(JsonReader reader, bool writeChildren, CancellationToken cancellationToken = default(CancellationToken))
  561. {
  562. ValidationUtils.ArgumentNotNull(reader, nameof(reader));
  563. return WriteTokenAsync(reader, writeChildren, true, true, cancellationToken);
  564. }
  565. /// <summary>
  566. /// Asynchronously writes the <see cref="JsonToken"/> token and its value.
  567. /// </summary>
  568. /// <param name="token">The <see cref="JsonToken"/> to write.</param>
  569. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  570. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  571. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  572. /// classes can override this behaviour for true asynchronicity.</remarks>
  573. public Task WriteTokenAsync(JsonToken token, CancellationToken cancellationToken = default(CancellationToken))
  574. {
  575. return WriteTokenAsync(token, null, cancellationToken);
  576. }
  577. /// <summary>
  578. /// Asynchronously writes the <see cref="JsonToken"/> token and its value.
  579. /// </summary>
  580. /// <param name="token">The <see cref="JsonToken"/> to write.</param>
  581. /// <param name="value">
  582. /// The value to write.
  583. /// A value is only required for tokens that have an associated value, e.g. the <see cref="String"/> property name for <see cref="JsonToken.PropertyName"/>.
  584. /// <c>null</c> can be passed to the method for tokens that don't have a value, e.g. <see cref="JsonToken.StartObject"/>.
  585. /// </param>
  586. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  587. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  588. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  589. /// classes can override this behaviour for true asynchronicity.</remarks>
  590. public Task WriteTokenAsync(JsonToken token, object value, CancellationToken cancellationToken = default(CancellationToken))
  591. {
  592. if (cancellationToken.IsCancellationRequested)
  593. {
  594. return cancellationToken.FromCanceled();
  595. }
  596. switch (token)
  597. {
  598. case JsonToken.None:
  599. // read to next
  600. return AsyncUtils.CompletedTask;
  601. case JsonToken.StartObject:
  602. return WriteStartObjectAsync(cancellationToken);
  603. case JsonToken.StartArray:
  604. return WriteStartArrayAsync(cancellationToken);
  605. case JsonToken.StartConstructor:
  606. ValidationUtils.ArgumentNotNull(value, nameof(value));
  607. return WriteStartConstructorAsync(value.ToString(), cancellationToken);
  608. case JsonToken.PropertyName:
  609. ValidationUtils.ArgumentNotNull(value, nameof(value));
  610. return WritePropertyNameAsync(value.ToString(), cancellationToken);
  611. case JsonToken.Comment:
  612. return WriteCommentAsync(value?.ToString(), cancellationToken);
  613. case JsonToken.Integer:
  614. ValidationUtils.ArgumentNotNull(value, nameof(value));
  615. return
  616. #if HAVE_BIG_INTEGER
  617. value is BigInteger integer ? WriteValueAsync(integer, cancellationToken) :
  618. #endif
  619. WriteValueAsync(Convert.ToInt64(value, CultureInfo.InvariantCulture), cancellationToken);
  620. case JsonToken.Float:
  621. ValidationUtils.ArgumentNotNull(value, nameof(value));
  622. if (value is decimal dec)
  623. {
  624. return WriteValueAsync(dec, cancellationToken);
  625. }
  626. if (value is double doub)
  627. {
  628. return WriteValueAsync(doub, cancellationToken);
  629. }
  630. if (value is float f)
  631. {
  632. return WriteValueAsync(f, cancellationToken);
  633. }
  634. return WriteValueAsync(Convert.ToDouble(value, CultureInfo.InvariantCulture), cancellationToken);
  635. case JsonToken.String:
  636. ValidationUtils.ArgumentNotNull(value, nameof(value));
  637. return WriteValueAsync(value.ToString(), cancellationToken);
  638. case JsonToken.Boolean:
  639. ValidationUtils.ArgumentNotNull(value, nameof(value));
  640. return WriteValueAsync(Convert.ToBoolean(value, CultureInfo.InvariantCulture), cancellationToken);
  641. case JsonToken.Null:
  642. return WriteNullAsync(cancellationToken);
  643. case JsonToken.Undefined:
  644. return WriteUndefinedAsync(cancellationToken);
  645. case JsonToken.EndObject:
  646. return WriteEndObjectAsync(cancellationToken);
  647. case JsonToken.EndArray:
  648. return WriteEndArrayAsync(cancellationToken);
  649. case JsonToken.EndConstructor:
  650. return WriteEndConstructorAsync(cancellationToken);
  651. case JsonToken.Date:
  652. ValidationUtils.ArgumentNotNull(value, nameof(value));
  653. if (value is DateTimeOffset offset)
  654. {
  655. return WriteValueAsync(offset, cancellationToken);
  656. }
  657. return WriteValueAsync(Convert.ToDateTime(value, CultureInfo.InvariantCulture), cancellationToken);
  658. case JsonToken.Raw:
  659. return WriteRawValueAsync(value?.ToString(), cancellationToken);
  660. case JsonToken.Bytes:
  661. ValidationUtils.ArgumentNotNull(value, nameof(value));
  662. if (value is Guid guid)
  663. {
  664. return WriteValueAsync(guid, cancellationToken);
  665. }
  666. return WriteValueAsync((byte[])value, cancellationToken);
  667. default:
  668. throw MiscellaneousUtils.CreateArgumentOutOfRangeException(nameof(token), token, "Unexpected token type.");
  669. }
  670. }
  671. internal virtual async Task WriteTokenAsync(JsonReader reader, bool writeChildren, bool writeDateConstructorAsDate, bool writeComments, CancellationToken cancellationToken)
  672. {
  673. int initialDepth = CalculateWriteTokenInitialDepth(reader);
  674. do
  675. {
  676. // write a JValue date when the constructor is for a date
  677. if (writeDateConstructorAsDate && reader.TokenType == JsonToken.StartConstructor && string.Equals(reader.Value.ToString(), "Date", StringComparison.Ordinal))
  678. {
  679. await WriteConstructorDateAsync(reader, cancellationToken).ConfigureAwait(false);
  680. }
  681. else
  682. {
  683. if (writeComments || reader.TokenType != JsonToken.Comment)
  684. {
  685. await WriteTokenAsync(reader.TokenType, reader.Value, cancellationToken).ConfigureAwait(false);
  686. }
  687. }
  688. } while (
  689. // stop if we have reached the end of the token being read
  690. initialDepth - 1 < reader.Depth - (JsonTokenUtils.IsEndToken(reader.TokenType) ? 1 : 0)
  691. && writeChildren
  692. && await reader.ReadAsync(cancellationToken).ConfigureAwait(false));
  693. if (initialDepth < CalculateWriteTokenFinalDepth(reader))
  694. {
  695. throw JsonWriterException.Create(this, "Unexpected end when reading token.", null);
  696. }
  697. }
  698. // For internal use, when we know the writer does not offer true async support (e.g. when backed
  699. // by a StringWriter) and therefore async write methods are always in practice just a less efficient
  700. // path through the sync version.
  701. internal async Task WriteTokenSyncReadingAsync(JsonReader reader, CancellationToken cancellationToken)
  702. {
  703. int initialDepth = CalculateWriteTokenInitialDepth(reader);
  704. do
  705. {
  706. // write a JValue date when the constructor is for a date
  707. if (reader.TokenType == JsonToken.StartConstructor && string.Equals(reader.Value.ToString(), "Date", StringComparison.Ordinal))
  708. {
  709. WriteConstructorDate(reader);
  710. }
  711. else
  712. {
  713. WriteToken(reader.TokenType, reader.Value);
  714. }
  715. } while (
  716. // stop if we have reached the end of the token being read
  717. initialDepth - 1 < reader.Depth - (JsonTokenUtils.IsEndToken(reader.TokenType) ? 1 : 0)
  718. && await reader.ReadAsync(cancellationToken).ConfigureAwait(false));
  719. if (initialDepth < CalculateWriteTokenFinalDepth(reader))
  720. {
  721. throw JsonWriterException.Create(this, "Unexpected end when reading token.", null);
  722. }
  723. }
  724. private async Task WriteConstructorDateAsync(JsonReader reader, CancellationToken cancellationToken)
  725. {
  726. if (!await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
  727. {
  728. throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null);
  729. }
  730. if (reader.TokenType != JsonToken.Integer)
  731. {
  732. throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected Integer, got " + reader.TokenType, null);
  733. }
  734. DateTime date = DateTimeUtils.ConvertJavaScriptTicksToDateTime((long)reader.Value);
  735. if (!await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
  736. {
  737. throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null);
  738. }
  739. if (reader.TokenType != JsonToken.EndConstructor)
  740. {
  741. throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected EndConstructor, got " + reader.TokenType, null);
  742. }
  743. await WriteValueAsync(date, cancellationToken).ConfigureAwait(false);
  744. }
  745. /// <summary>
  746. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="bool"/> value.
  747. /// </summary>
  748. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="bool"/> value to write.</param>
  749. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  750. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  751. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  752. /// classes can override this behaviour for true asynchronicity.</remarks>
  753. public virtual Task WriteValueAsync(bool value, CancellationToken cancellationToken = default(CancellationToken))
  754. {
  755. if (cancellationToken.IsCancellationRequested)
  756. {
  757. return cancellationToken.FromCanceled();
  758. }
  759. WriteValue(value);
  760. return AsyncUtils.CompletedTask;
  761. }
  762. /// <summary>
  763. /// Asynchronously writes a <see cref="bool"/> value.
  764. /// </summary>
  765. /// <param name="value">The <see cref="bool"/> value to write.</param>
  766. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  767. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  768. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  769. /// classes can override this behaviour for true asynchronicity.</remarks>
  770. public virtual Task WriteValueAsync(bool? value, CancellationToken cancellationToken = default(CancellationToken))
  771. {
  772. if (cancellationToken.IsCancellationRequested)
  773. {
  774. return cancellationToken.FromCanceled();
  775. }
  776. WriteValue(value);
  777. return AsyncUtils.CompletedTask;
  778. }
  779. /// <summary>
  780. /// Asynchronously writes a <see cref="byte"/> value.
  781. /// </summary>
  782. /// <param name="value">The <see cref="byte"/> value to write.</param>
  783. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  784. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  785. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  786. /// classes can override this behaviour for true asynchronicity.</remarks>
  787. public virtual Task WriteValueAsync(byte value, CancellationToken cancellationToken = default(CancellationToken))
  788. {
  789. if (cancellationToken.IsCancellationRequested)
  790. {
  791. return cancellationToken.FromCanceled();
  792. }
  793. WriteValue(value);
  794. return AsyncUtils.CompletedTask;
  795. }
  796. /// <summary>
  797. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="byte"/> value.
  798. /// </summary>
  799. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="byte"/> value to write.</param>
  800. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  801. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  802. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  803. /// classes can override this behaviour for true asynchronicity.</remarks>
  804. public virtual Task WriteValueAsync(byte? value, CancellationToken cancellationToken = default(CancellationToken))
  805. {
  806. if (cancellationToken.IsCancellationRequested)
  807. {
  808. return cancellationToken.FromCanceled();
  809. }
  810. WriteValue(value);
  811. return AsyncUtils.CompletedTask;
  812. }
  813. /// <summary>
  814. /// Asynchronously writes a <see cref="byte"/>[] value.
  815. /// </summary>
  816. /// <param name="value">The <see cref="byte"/>[] value to write.</param>
  817. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  818. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  819. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  820. /// classes can override this behaviour for true asynchronicity.</remarks>
  821. public virtual Task WriteValueAsync(byte[] value, CancellationToken cancellationToken = default(CancellationToken))
  822. {
  823. if (cancellationToken.IsCancellationRequested)
  824. {
  825. return cancellationToken.FromCanceled();
  826. }
  827. WriteValue(value);
  828. return AsyncUtils.CompletedTask;
  829. }
  830. /// <summary>
  831. /// Asynchronously writes a <see cref="char"/> value.
  832. /// </summary>
  833. /// <param name="value">The <see cref="char"/> value to write.</param>
  834. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  835. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  836. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  837. /// classes can override this behaviour for true asynchronicity.</remarks>
  838. public virtual Task WriteValueAsync(char value, CancellationToken cancellationToken = default(CancellationToken))
  839. {
  840. if (cancellationToken.IsCancellationRequested)
  841. {
  842. return cancellationToken.FromCanceled();
  843. }
  844. WriteValue(value);
  845. return AsyncUtils.CompletedTask;
  846. }
  847. /// <summary>
  848. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="char"/> value.
  849. /// </summary>
  850. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="char"/> value to write.</param>
  851. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  852. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  853. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  854. /// classes can override this behaviour for true asynchronicity.</remarks>
  855. public virtual Task WriteValueAsync(char? value, CancellationToken cancellationToken = default(CancellationToken))
  856. {
  857. if (cancellationToken.IsCancellationRequested)
  858. {
  859. return cancellationToken.FromCanceled();
  860. }
  861. WriteValue(value);
  862. return AsyncUtils.CompletedTask;
  863. }
  864. /// <summary>
  865. /// Asynchronously writes a <see cref="DateTime"/> value.
  866. /// </summary>
  867. /// <param name="value">The <see cref="DateTime"/> value to write.</param>
  868. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  869. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  870. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  871. /// classes can override this behaviour for true asynchronicity.</remarks>
  872. public virtual Task WriteValueAsync(DateTime value, CancellationToken cancellationToken = default(CancellationToken))
  873. {
  874. if (cancellationToken.IsCancellationRequested)
  875. {
  876. return cancellationToken.FromCanceled();
  877. }
  878. WriteValue(value);
  879. return AsyncUtils.CompletedTask;
  880. }
  881. /// <summary>
  882. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="DateTime"/> value.
  883. /// </summary>
  884. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="DateTime"/> value to write.</param>
  885. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  886. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  887. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  888. /// classes can override this behaviour for true asynchronicity.</remarks>
  889. public virtual Task WriteValueAsync(DateTime? value, CancellationToken cancellationToken = default(CancellationToken))
  890. {
  891. if (cancellationToken.IsCancellationRequested)
  892. {
  893. return cancellationToken.FromCanceled();
  894. }
  895. WriteValue(value);
  896. return AsyncUtils.CompletedTask;
  897. }
  898. /// <summary>
  899. /// Asynchronously writes a <see cref="DateTimeOffset"/> value.
  900. /// </summary>
  901. /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
  902. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  903. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  904. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  905. /// classes can override this behaviour for true asynchronicity.</remarks>
  906. public virtual Task WriteValueAsync(DateTimeOffset value, CancellationToken cancellationToken = default(CancellationToken))
  907. {
  908. if (cancellationToken.IsCancellationRequested)
  909. {
  910. return cancellationToken.FromCanceled();
  911. }
  912. WriteValue(value);
  913. return AsyncUtils.CompletedTask;
  914. }
  915. /// <summary>
  916. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="DateTimeOffset"/> value.
  917. /// </summary>
  918. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="DateTimeOffset"/> value to write.</param>
  919. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  920. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  921. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  922. /// classes can override this behaviour for true asynchronicity.</remarks>
  923. public virtual Task WriteValueAsync(DateTimeOffset? value, CancellationToken cancellationToken = default(CancellationToken))
  924. {
  925. if (cancellationToken.IsCancellationRequested)
  926. {
  927. return cancellationToken.FromCanceled();
  928. }
  929. WriteValue(value);
  930. return AsyncUtils.CompletedTask;
  931. }
  932. /// <summary>
  933. /// Asynchronously writes a <see cref="decimal"/> value.
  934. /// </summary>
  935. /// <param name="value">The <see cref="decimal"/> value to write.</param>
  936. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  937. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  938. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  939. /// classes can override this behaviour for true asynchronicity.</remarks>
  940. public virtual Task WriteValueAsync(decimal value, CancellationToken cancellationToken = default(CancellationToken))
  941. {
  942. if (cancellationToken.IsCancellationRequested)
  943. {
  944. return cancellationToken.FromCanceled();
  945. }
  946. WriteValue(value);
  947. return AsyncUtils.CompletedTask;
  948. }
  949. /// <summary>
  950. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="decimal"/> value.
  951. /// </summary>
  952. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="decimal"/> value to write.</param>
  953. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  954. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  955. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  956. /// classes can override this behaviour for true asynchronicity.</remarks>
  957. public virtual Task WriteValueAsync(decimal? value, CancellationToken cancellationToken = default(CancellationToken))
  958. {
  959. if (cancellationToken.IsCancellationRequested)
  960. {
  961. return cancellationToken.FromCanceled();
  962. }
  963. WriteValue(value);
  964. return AsyncUtils.CompletedTask;
  965. }
  966. /// <summary>
  967. /// Asynchronously writes a <see cref="double"/> value.
  968. /// </summary>
  969. /// <param name="value">The <see cref="double"/> value to write.</param>
  970. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  971. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  972. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  973. /// classes can override this behaviour for true asynchronicity.</remarks>
  974. public virtual Task WriteValueAsync(double value, CancellationToken cancellationToken = default(CancellationToken))
  975. {
  976. if (cancellationToken.IsCancellationRequested)
  977. {
  978. return cancellationToken.FromCanceled();
  979. }
  980. WriteValue(value);
  981. return AsyncUtils.CompletedTask;
  982. }
  983. /// <summary>
  984. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="double"/> value.
  985. /// </summary>
  986. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="double"/> value to write.</param>
  987. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  988. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  989. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  990. /// classes can override this behaviour for true asynchronicity.</remarks>
  991. public virtual Task WriteValueAsync(double? value, CancellationToken cancellationToken = default(CancellationToken))
  992. {
  993. if (cancellationToken.IsCancellationRequested)
  994. {
  995. return cancellationToken.FromCanceled();
  996. }
  997. WriteValue(value);
  998. return AsyncUtils.CompletedTask;
  999. }
  1000. /// <summary>
  1001. /// Asynchronously writes a <see cref="float"/> value.
  1002. /// </summary>
  1003. /// <param name="value">The <see cref="float"/> value to write.</param>
  1004. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1005. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1006. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1007. /// classes can override this behaviour for true asynchronicity.</remarks>
  1008. public virtual Task WriteValueAsync(float value, CancellationToken cancellationToken = default(CancellationToken))
  1009. {
  1010. if (cancellationToken.IsCancellationRequested)
  1011. {
  1012. return cancellationToken.FromCanceled();
  1013. }
  1014. WriteValue(value);
  1015. return AsyncUtils.CompletedTask;
  1016. }
  1017. /// <summary>
  1018. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="float"/> value.
  1019. /// </summary>
  1020. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="float"/> value to write.</param>
  1021. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1022. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1023. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1024. /// classes can override this behaviour for true asynchronicity.</remarks>
  1025. public virtual Task WriteValueAsync(float? value, CancellationToken cancellationToken = default(CancellationToken))
  1026. {
  1027. if (cancellationToken.IsCancellationRequested)
  1028. {
  1029. return cancellationToken.FromCanceled();
  1030. }
  1031. WriteValue(value);
  1032. return AsyncUtils.CompletedTask;
  1033. }
  1034. /// <summary>
  1035. /// Asynchronously writes a <see cref="Guid"/> value.
  1036. /// </summary>
  1037. /// <param name="value">The <see cref="Guid"/> value to write.</param>
  1038. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1039. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1040. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1041. /// classes can override this behaviour for true asynchronicity.</remarks>
  1042. public virtual Task WriteValueAsync(Guid value, CancellationToken cancellationToken = default(CancellationToken))
  1043. {
  1044. if (cancellationToken.IsCancellationRequested)
  1045. {
  1046. return cancellationToken.FromCanceled();
  1047. }
  1048. WriteValue(value);
  1049. return AsyncUtils.CompletedTask;
  1050. }
  1051. /// <summary>
  1052. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="Guid"/> value.
  1053. /// </summary>
  1054. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="Guid"/> value to write.</param>
  1055. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1056. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1057. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1058. /// classes can override this behaviour for true asynchronicity.</remarks>
  1059. public virtual Task WriteValueAsync(Guid? value, CancellationToken cancellationToken = default(CancellationToken))
  1060. {
  1061. if (cancellationToken.IsCancellationRequested)
  1062. {
  1063. return cancellationToken.FromCanceled();
  1064. }
  1065. WriteValue(value);
  1066. return AsyncUtils.CompletedTask;
  1067. }
  1068. /// <summary>
  1069. /// Asynchronously writes a <see cref="int"/> value.
  1070. /// </summary>
  1071. /// <param name="value">The <see cref="int"/> value to write.</param>
  1072. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1073. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1074. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1075. /// classes can override this behaviour for true asynchronicity.</remarks>
  1076. public virtual Task WriteValueAsync(int value, CancellationToken cancellationToken = default(CancellationToken))
  1077. {
  1078. if (cancellationToken.IsCancellationRequested)
  1079. {
  1080. return cancellationToken.FromCanceled();
  1081. }
  1082. WriteValue(value);
  1083. return AsyncUtils.CompletedTask;
  1084. }
  1085. /// <summary>
  1086. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="int"/> value.
  1087. /// </summary>
  1088. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="int"/> value to write.</param>
  1089. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1090. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1091. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1092. /// classes can override this behaviour for true asynchronicity.</remarks>
  1093. public virtual Task WriteValueAsync(int? value, CancellationToken cancellationToken = default(CancellationToken))
  1094. {
  1095. if (cancellationToken.IsCancellationRequested)
  1096. {
  1097. return cancellationToken.FromCanceled();
  1098. }
  1099. WriteValue(value);
  1100. return AsyncUtils.CompletedTask;
  1101. }
  1102. /// <summary>
  1103. /// Asynchronously writes a <see cref="long"/> value.
  1104. /// </summary>
  1105. /// <param name="value">The <see cref="long"/> value to write.</param>
  1106. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1107. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1108. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1109. /// classes can override this behaviour for true asynchronicity.</remarks>
  1110. public virtual Task WriteValueAsync(long value, CancellationToken cancellationToken = default(CancellationToken))
  1111. {
  1112. if (cancellationToken.IsCancellationRequested)
  1113. {
  1114. return cancellationToken.FromCanceled();
  1115. }
  1116. WriteValue(value);
  1117. return AsyncUtils.CompletedTask;
  1118. }
  1119. /// <summary>
  1120. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="long"/> value.
  1121. /// </summary>
  1122. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="long"/> value to write.</param>
  1123. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1124. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1125. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1126. /// classes can override this behaviour for true asynchronicity.</remarks>
  1127. public virtual Task WriteValueAsync(long? value, CancellationToken cancellationToken = default(CancellationToken))
  1128. {
  1129. if (cancellationToken.IsCancellationRequested)
  1130. {
  1131. return cancellationToken.FromCanceled();
  1132. }
  1133. WriteValue(value);
  1134. return AsyncUtils.CompletedTask;
  1135. }
  1136. /// <summary>
  1137. /// Asynchronously writes a <see cref="object"/> value.
  1138. /// </summary>
  1139. /// <param name="value">The <see cref="object"/> value to write.</param>
  1140. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1141. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1142. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1143. /// classes can override this behaviour for true asynchronicity.</remarks>
  1144. public virtual Task WriteValueAsync(object value, CancellationToken cancellationToken = default(CancellationToken))
  1145. {
  1146. if (cancellationToken.IsCancellationRequested)
  1147. {
  1148. return cancellationToken.FromCanceled();
  1149. }
  1150. WriteValue(value);
  1151. return AsyncUtils.CompletedTask;
  1152. }
  1153. /// <summary>
  1154. /// Asynchronously writes a <see cref="sbyte"/> value.
  1155. /// </summary>
  1156. /// <param name="value">The <see cref="sbyte"/> value to write.</param>
  1157. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1158. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1159. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1160. /// classes can override this behaviour for true asynchronicity.</remarks>
  1161. public virtual Task WriteValueAsync(sbyte value, CancellationToken cancellationToken = default(CancellationToken))
  1162. {
  1163. if (cancellationToken.IsCancellationRequested)
  1164. {
  1165. return cancellationToken.FromCanceled();
  1166. }
  1167. WriteValue(value);
  1168. return AsyncUtils.CompletedTask;
  1169. }
  1170. /// <summary>
  1171. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="sbyte"/> value.
  1172. /// </summary>
  1173. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="sbyte"/> value to write.</param>
  1174. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1175. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1176. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1177. /// classes can override this behaviour for true asynchronicity.</remarks>
  1178. public virtual Task WriteValueAsync(sbyte? value, CancellationToken cancellationToken = default(CancellationToken))
  1179. {
  1180. if (cancellationToken.IsCancellationRequested)
  1181. {
  1182. return cancellationToken.FromCanceled();
  1183. }
  1184. WriteValue(value);
  1185. return AsyncUtils.CompletedTask;
  1186. }
  1187. /// <summary>
  1188. /// Asynchronously writes a <see cref="short"/> value.
  1189. /// </summary>
  1190. /// <param name="value">The <see cref="short"/> value to write.</param>
  1191. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1192. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1193. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1194. /// classes can override this behaviour for true asynchronicity.</remarks>
  1195. public virtual Task WriteValueAsync(short value, CancellationToken cancellationToken = default(CancellationToken))
  1196. {
  1197. if (cancellationToken.IsCancellationRequested)
  1198. {
  1199. return cancellationToken.FromCanceled();
  1200. }
  1201. WriteValue(value);
  1202. return AsyncUtils.CompletedTask;
  1203. }
  1204. /// <summary>
  1205. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="short"/> value.
  1206. /// </summary>
  1207. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="short"/> value to write.</param>
  1208. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1209. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1210. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1211. /// classes can override this behaviour for true asynchronicity.</remarks>
  1212. public virtual Task WriteValueAsync(short? value, CancellationToken cancellationToken = default(CancellationToken))
  1213. {
  1214. if (cancellationToken.IsCancellationRequested)
  1215. {
  1216. return cancellationToken.FromCanceled();
  1217. }
  1218. WriteValue(value);
  1219. return AsyncUtils.CompletedTask;
  1220. }
  1221. /// <summary>
  1222. /// Asynchronously writes a <see cref="string"/> value.
  1223. /// </summary>
  1224. /// <param name="value">The <see cref="string"/> value to write.</param>
  1225. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1226. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1227. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1228. /// classes can override this behaviour for true asynchronicity.</remarks>
  1229. public virtual Task WriteValueAsync(string value, CancellationToken cancellationToken = default(CancellationToken))
  1230. {
  1231. if (cancellationToken.IsCancellationRequested)
  1232. {
  1233. return cancellationToken.FromCanceled();
  1234. }
  1235. WriteValue(value);
  1236. return AsyncUtils.CompletedTask;
  1237. }
  1238. /// <summary>
  1239. /// Asynchronously writes a <see cref="TimeSpan"/> value.
  1240. /// </summary>
  1241. /// <param name="value">The <see cref="TimeSpan"/> value to write.</param>
  1242. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1243. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1244. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1245. /// classes can override this behaviour for true asynchronicity.</remarks>
  1246. public virtual Task WriteValueAsync(TimeSpan value, CancellationToken cancellationToken = default(CancellationToken))
  1247. {
  1248. if (cancellationToken.IsCancellationRequested)
  1249. {
  1250. return cancellationToken.FromCanceled();
  1251. }
  1252. WriteValue(value);
  1253. return AsyncUtils.CompletedTask;
  1254. }
  1255. /// <summary>
  1256. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="TimeSpan"/> value.
  1257. /// </summary>
  1258. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="TimeSpan"/> value to write.</param>
  1259. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1260. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1261. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1262. /// classes can override this behaviour for true asynchronicity.</remarks>
  1263. public virtual Task WriteValueAsync(TimeSpan? value, CancellationToken cancellationToken = default(CancellationToken))
  1264. {
  1265. if (cancellationToken.IsCancellationRequested)
  1266. {
  1267. return cancellationToken.FromCanceled();
  1268. }
  1269. WriteValue(value);
  1270. return AsyncUtils.CompletedTask;
  1271. }
  1272. /// <summary>
  1273. /// Asynchronously writes a <see cref="uint"/> value.
  1274. /// </summary>
  1275. /// <param name="value">The <see cref="uint"/> value to write.</param>
  1276. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1277. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1278. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1279. /// classes can override this behaviour for true asynchronicity.</remarks>
  1280. public virtual Task WriteValueAsync(uint value, CancellationToken cancellationToken = default(CancellationToken))
  1281. {
  1282. if (cancellationToken.IsCancellationRequested)
  1283. {
  1284. return cancellationToken.FromCanceled();
  1285. }
  1286. WriteValue(value);
  1287. return AsyncUtils.CompletedTask;
  1288. }
  1289. /// <summary>
  1290. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="uint"/> value.
  1291. /// </summary>
  1292. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="uint"/> value to write.</param>
  1293. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1294. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1295. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1296. /// classes can override this behaviour for true asynchronicity.</remarks>
  1297. public virtual Task WriteValueAsync(uint? value, CancellationToken cancellationToken = default(CancellationToken))
  1298. {
  1299. if (cancellationToken.IsCancellationRequested)
  1300. {
  1301. return cancellationToken.FromCanceled();
  1302. }
  1303. WriteValue(value);
  1304. return AsyncUtils.CompletedTask;
  1305. }
  1306. /// <summary>
  1307. /// Asynchronously writes a <see cref="ulong"/> value.
  1308. /// </summary>
  1309. /// <param name="value">The <see cref="ulong"/> value to write.</param>
  1310. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1311. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1312. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1313. /// classes can override this behaviour for true asynchronicity.</remarks>
  1314. public virtual Task WriteValueAsync(ulong value, CancellationToken cancellationToken = default(CancellationToken))
  1315. {
  1316. if (cancellationToken.IsCancellationRequested)
  1317. {
  1318. return cancellationToken.FromCanceled();
  1319. }
  1320. WriteValue(value);
  1321. return AsyncUtils.CompletedTask;
  1322. }
  1323. /// <summary>
  1324. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="ulong"/> value.
  1325. /// </summary>
  1326. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="ulong"/> value to write.</param>
  1327. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1328. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1329. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1330. /// classes can override this behaviour for true asynchronicity.</remarks>
  1331. public virtual Task WriteValueAsync(ulong? value, CancellationToken cancellationToken = default(CancellationToken))
  1332. {
  1333. if (cancellationToken.IsCancellationRequested)
  1334. {
  1335. return cancellationToken.FromCanceled();
  1336. }
  1337. WriteValue(value);
  1338. return AsyncUtils.CompletedTask;
  1339. }
  1340. /// <summary>
  1341. /// Asynchronously writes a <see cref="Uri"/> value.
  1342. /// </summary>
  1343. /// <param name="value">The <see cref="Uri"/> value to write.</param>
  1344. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1345. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1346. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1347. /// classes can override this behaviour for true asynchronicity.</remarks>
  1348. public virtual Task WriteValueAsync(Uri value, CancellationToken cancellationToken = default(CancellationToken))
  1349. {
  1350. if (cancellationToken.IsCancellationRequested)
  1351. {
  1352. return cancellationToken.FromCanceled();
  1353. }
  1354. WriteValue(value);
  1355. return AsyncUtils.CompletedTask;
  1356. }
  1357. /// <summary>
  1358. /// Asynchronously writes a <see cref="ushort"/> value.
  1359. /// </summary>
  1360. /// <param name="value">The <see cref="ushort"/> value to write.</param>
  1361. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1362. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1363. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1364. /// classes can override this behaviour for true asynchronicity.</remarks>
  1365. public virtual Task WriteValueAsync(ushort value, CancellationToken cancellationToken = default(CancellationToken))
  1366. {
  1367. if (cancellationToken.IsCancellationRequested)
  1368. {
  1369. return cancellationToken.FromCanceled();
  1370. }
  1371. WriteValue(value);
  1372. return AsyncUtils.CompletedTask;
  1373. }
  1374. /// <summary>
  1375. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="ushort"/> value.
  1376. /// </summary>
  1377. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="ushort"/> value to write.</param>
  1378. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1379. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1380. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1381. /// classes can override this behaviour for true asynchronicity.</remarks>
  1382. public virtual Task WriteValueAsync(ushort? value, CancellationToken cancellationToken = default(CancellationToken))
  1383. {
  1384. if (cancellationToken.IsCancellationRequested)
  1385. {
  1386. return cancellationToken.FromCanceled();
  1387. }
  1388. WriteValue(value);
  1389. return AsyncUtils.CompletedTask;
  1390. }
  1391. /// <summary>
  1392. /// Asynchronously writes an undefined value.
  1393. /// </summary>
  1394. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1395. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1396. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1397. /// classes can override this behaviour for true asynchronicity.</remarks>
  1398. public virtual Task WriteUndefinedAsync(CancellationToken cancellationToken = default(CancellationToken))
  1399. {
  1400. if (cancellationToken.IsCancellationRequested)
  1401. {
  1402. return cancellationToken.FromCanceled();
  1403. }
  1404. WriteUndefined();
  1405. return AsyncUtils.CompletedTask;
  1406. }
  1407. /// <summary>
  1408. /// Asynchronously writes the given white space.
  1409. /// </summary>
  1410. /// <param name="ws">The string of white space characters.</param>
  1411. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1412. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1413. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1414. /// classes can override this behaviour for true asynchronicity.</remarks>
  1415. public virtual Task WriteWhitespaceAsync(string ws, CancellationToken cancellationToken = default(CancellationToken))
  1416. {
  1417. if (cancellationToken.IsCancellationRequested)
  1418. {
  1419. return cancellationToken.FromCanceled();
  1420. }
  1421. WriteWhitespace(ws);
  1422. return AsyncUtils.CompletedTask;
  1423. }
  1424. internal Task InternalWriteValueAsync(JsonToken token, CancellationToken cancellationToken)
  1425. {
  1426. if (cancellationToken.IsCancellationRequested)
  1427. {
  1428. return cancellationToken.FromCanceled();
  1429. }
  1430. UpdateScopeWithFinishedValue();
  1431. return AutoCompleteAsync(token, cancellationToken);
  1432. }
  1433. /// <summary>
  1434. /// Asynchronously ets the state of the <see cref="JsonWriter"/>.
  1435. /// </summary>
  1436. /// <param name="token">The <see cref="JsonToken"/> being written.</param>
  1437. /// <param name="value">The value being written.</param>
  1438. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1439. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1440. /// <remarks>The default behaviour is to execute synchronously, returning an already-completed task. Derived
  1441. /// classes can override this behaviour for true asynchronicity.</remarks>
  1442. protected Task SetWriteStateAsync(JsonToken token, object value, CancellationToken cancellationToken)
  1443. {
  1444. if (cancellationToken.IsCancellationRequested)
  1445. {
  1446. return cancellationToken.FromCanceled();
  1447. }
  1448. switch (token)
  1449. {
  1450. case JsonToken.StartObject:
  1451. return InternalWriteStartAsync(token, JsonContainerType.Object, cancellationToken);
  1452. case JsonToken.StartArray:
  1453. return InternalWriteStartAsync(token, JsonContainerType.Array, cancellationToken);
  1454. case JsonToken.StartConstructor:
  1455. return InternalWriteStartAsync(token, JsonContainerType.Constructor, cancellationToken);
  1456. case JsonToken.PropertyName:
  1457. if (!(value is string))
  1458. {
  1459. throw new ArgumentException("A name is required when setting property name state.", nameof(value));
  1460. }
  1461. return InternalWritePropertyNameAsync((string)value, cancellationToken);
  1462. case JsonToken.Comment:
  1463. return InternalWriteCommentAsync(cancellationToken);
  1464. case JsonToken.Raw:
  1465. return AsyncUtils.CompletedTask;
  1466. case JsonToken.Integer:
  1467. case JsonToken.Float:
  1468. case JsonToken.String:
  1469. case JsonToken.Boolean:
  1470. case JsonToken.Date:
  1471. case JsonToken.Bytes:
  1472. case JsonToken.Null:
  1473. case JsonToken.Undefined:
  1474. return InternalWriteValueAsync(token, cancellationToken);
  1475. case JsonToken.EndObject:
  1476. return InternalWriteEndAsync(JsonContainerType.Object, cancellationToken);
  1477. case JsonToken.EndArray:
  1478. return InternalWriteEndAsync(JsonContainerType.Array, cancellationToken);
  1479. case JsonToken.EndConstructor:
  1480. return InternalWriteEndAsync(JsonContainerType.Constructor, cancellationToken);
  1481. default:
  1482. throw new ArgumentOutOfRangeException(nameof(token));
  1483. }
  1484. }
  1485. internal static Task WriteValueAsync(JsonWriter writer, PrimitiveTypeCode typeCode, object value, CancellationToken cancellationToken)
  1486. {
  1487. while (true)
  1488. {
  1489. switch (typeCode)
  1490. {
  1491. case PrimitiveTypeCode.Char:
  1492. return writer.WriteValueAsync((char)value, cancellationToken);
  1493. case PrimitiveTypeCode.CharNullable:
  1494. return writer.WriteValueAsync(value == null ? (char?)null : (char)value, cancellationToken);
  1495. case PrimitiveTypeCode.Boolean:
  1496. return writer.WriteValueAsync((bool)value, cancellationToken);
  1497. case PrimitiveTypeCode.BooleanNullable:
  1498. return writer.WriteValueAsync(value == null ? (bool?)null : (bool)value, cancellationToken);
  1499. case PrimitiveTypeCode.SByte:
  1500. return writer.WriteValueAsync((sbyte)value, cancellationToken);
  1501. case PrimitiveTypeCode.SByteNullable:
  1502. return writer.WriteValueAsync(value == null ? (sbyte?)null : (sbyte)value, cancellationToken);
  1503. case PrimitiveTypeCode.Int16:
  1504. return writer.WriteValueAsync((short)value, cancellationToken);
  1505. case PrimitiveTypeCode.Int16Nullable:
  1506. return writer.WriteValueAsync(value == null ? (short?)null : (short)value, cancellationToken);
  1507. case PrimitiveTypeCode.UInt16:
  1508. return writer.WriteValueAsync((ushort)value, cancellationToken);
  1509. case PrimitiveTypeCode.UInt16Nullable:
  1510. return writer.WriteValueAsync(value == null ? (ushort?)null : (ushort)value, cancellationToken);
  1511. case PrimitiveTypeCode.Int32:
  1512. return writer.WriteValueAsync((int)value, cancellationToken);
  1513. case PrimitiveTypeCode.Int32Nullable:
  1514. return writer.WriteValueAsync(value == null ? (int?)null : (int)value, cancellationToken);
  1515. case PrimitiveTypeCode.Byte:
  1516. return writer.WriteValueAsync((byte)value, cancellationToken);
  1517. case PrimitiveTypeCode.ByteNullable:
  1518. return writer.WriteValueAsync(value == null ? (byte?)null : (byte)value, cancellationToken);
  1519. case PrimitiveTypeCode.UInt32:
  1520. return writer.WriteValueAsync((uint)value, cancellationToken);
  1521. case PrimitiveTypeCode.UInt32Nullable:
  1522. return writer.WriteValueAsync(value == null ? (uint?)null : (uint)value, cancellationToken);
  1523. case PrimitiveTypeCode.Int64:
  1524. return writer.WriteValueAsync((long)value, cancellationToken);
  1525. case PrimitiveTypeCode.Int64Nullable:
  1526. return writer.WriteValueAsync(value == null ? (long?)null : (long)value, cancellationToken);
  1527. case PrimitiveTypeCode.UInt64:
  1528. return writer.WriteValueAsync((ulong)value, cancellationToken);
  1529. case PrimitiveTypeCode.UInt64Nullable:
  1530. return writer.WriteValueAsync(value == null ? (ulong?)null : (ulong)value, cancellationToken);
  1531. case PrimitiveTypeCode.Single:
  1532. return writer.WriteValueAsync((float)value, cancellationToken);
  1533. case PrimitiveTypeCode.SingleNullable:
  1534. return writer.WriteValueAsync(value == null ? (float?)null : (float)value, cancellationToken);
  1535. case PrimitiveTypeCode.Double:
  1536. return writer.WriteValueAsync((double)value, cancellationToken);
  1537. case PrimitiveTypeCode.DoubleNullable:
  1538. return writer.WriteValueAsync(value == null ? (double?)null : (double)value, cancellationToken);
  1539. case PrimitiveTypeCode.DateTime:
  1540. return writer.WriteValueAsync((DateTime)value, cancellationToken);
  1541. case PrimitiveTypeCode.DateTimeNullable:
  1542. return writer.WriteValueAsync(value == null ? (DateTime?)null : (DateTime)value, cancellationToken);
  1543. case PrimitiveTypeCode.DateTimeOffset:
  1544. return writer.WriteValueAsync((DateTimeOffset)value, cancellationToken);
  1545. case PrimitiveTypeCode.DateTimeOffsetNullable:
  1546. return writer.WriteValueAsync(value == null ? (DateTimeOffset?)null : (DateTimeOffset)value, cancellationToken);
  1547. case PrimitiveTypeCode.Decimal:
  1548. return writer.WriteValueAsync((decimal)value, cancellationToken);
  1549. case PrimitiveTypeCode.DecimalNullable:
  1550. return writer.WriteValueAsync(value == null ? (decimal?)null : (decimal)value, cancellationToken);
  1551. case PrimitiveTypeCode.Guid:
  1552. return writer.WriteValueAsync((Guid)value, cancellationToken);
  1553. case PrimitiveTypeCode.GuidNullable:
  1554. return writer.WriteValueAsync(value == null ? (Guid?)null : (Guid)value, cancellationToken);
  1555. case PrimitiveTypeCode.TimeSpan:
  1556. return writer.WriteValueAsync((TimeSpan)value, cancellationToken);
  1557. case PrimitiveTypeCode.TimeSpanNullable:
  1558. return writer.WriteValueAsync(value == null ? (TimeSpan?)null : (TimeSpan)value, cancellationToken);
  1559. #if HAVE_BIG_INTEGER
  1560. case PrimitiveTypeCode.BigInteger:
  1561. // this will call to WriteValueAsync(object)
  1562. return writer.WriteValueAsync((BigInteger)value, cancellationToken);
  1563. case PrimitiveTypeCode.BigIntegerNullable:
  1564. // this will call to WriteValueAsync(object)
  1565. return writer.WriteValueAsync(value == null ? (BigInteger?)null : (BigInteger)value, cancellationToken);
  1566. #endif
  1567. case PrimitiveTypeCode.Uri:
  1568. return writer.WriteValueAsync((Uri)value, cancellationToken);
  1569. case PrimitiveTypeCode.String:
  1570. return writer.WriteValueAsync((string)value, cancellationToken);
  1571. case PrimitiveTypeCode.Bytes:
  1572. return writer.WriteValueAsync((byte[])value, cancellationToken);
  1573. case PrimitiveTypeCode.DBNull:
  1574. return writer.WriteNullAsync(cancellationToken);
  1575. default:
  1576. if (value is IConvertible convertible)
  1577. {
  1578. ResolveConvertibleValue(convertible, out typeCode, out value);
  1579. continue;
  1580. }
  1581. // write an unknown null value, fix https://github.com/JamesNK/Newtonsoft.Json/issues/1460
  1582. if (value == null)
  1583. {
  1584. return writer.WriteNullAsync(cancellationToken);
  1585. }
  1586. throw CreateUnsupportedTypeException(writer, value);
  1587. }
  1588. }
  1589. }
  1590. }
  1591. }
  1592. #endif