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.

1356 lines
77 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 partial class JsonTextWriter
  37. {
  38. // It's not safe to perform the async methods here in a derived class as if the synchronous equivalent
  39. // has been overriden then the asychronous method will no longer be doing the same operation.
  40. #if HAVE_ASYNC // Double-check this isn't included inappropriately.
  41. private readonly bool _safeAsync;
  42. #endif
  43. /// <summary>
  44. /// Asynchronously flushes whatever is in the buffer to the destination and also flushes the destination.
  45. /// </summary>
  46. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  47. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  48. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  49. /// execute synchronously, returning an already-completed task.</remarks>
  50. public override Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
  51. {
  52. return _safeAsync ? DoFlushAsync(cancellationToken) : base.FlushAsync(cancellationToken);
  53. }
  54. internal Task DoFlushAsync(CancellationToken cancellationToken)
  55. {
  56. return cancellationToken.CancelIfRequestedAsync() ?? _writer.FlushAsync();
  57. }
  58. /// <summary>
  59. /// Asynchronously writes the JSON value delimiter.
  60. /// </summary>
  61. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  62. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  63. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  64. /// execute synchronously, returning an already-completed task.</remarks>
  65. protected override Task WriteValueDelimiterAsync(CancellationToken cancellationToken)
  66. {
  67. return _safeAsync ? DoWriteValueDelimiterAsync(cancellationToken) : base.WriteValueDelimiterAsync(cancellationToken);
  68. }
  69. internal Task DoWriteValueDelimiterAsync(CancellationToken cancellationToken)
  70. {
  71. return _writer.WriteAsync(',', cancellationToken);
  72. }
  73. /// <summary>
  74. /// Asynchronously writes the specified end token.
  75. /// </summary>
  76. /// <param name="token">The end token to write.</param>
  77. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  78. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  79. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  80. /// execute synchronously, returning an already-completed task.</remarks>
  81. protected override Task WriteEndAsync(JsonToken token, CancellationToken cancellationToken)
  82. {
  83. return _safeAsync ? DoWriteEndAsync(token, cancellationToken) : base.WriteEndAsync(token, cancellationToken);
  84. }
  85. internal Task DoWriteEndAsync(JsonToken token, CancellationToken cancellationToken)
  86. {
  87. switch (token)
  88. {
  89. case JsonToken.EndObject:
  90. return _writer.WriteAsync('}', cancellationToken);
  91. case JsonToken.EndArray:
  92. return _writer.WriteAsync(']', cancellationToken);
  93. case JsonToken.EndConstructor:
  94. return _writer.WriteAsync(')', cancellationToken);
  95. default:
  96. throw JsonWriterException.Create(this, "Invalid JsonToken: " + token, null);
  97. }
  98. }
  99. /// <summary>
  100. /// Asynchronously closes this writer.
  101. /// If <see cref="JsonWriter.CloseOutput"/> is set to <c>true</c>, the destination is also closed.
  102. /// </summary>
  103. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  104. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  105. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  106. /// execute synchronously, returning an already-completed task.</remarks>
  107. public override Task CloseAsync(CancellationToken cancellationToken = default(CancellationToken))
  108. {
  109. return _safeAsync ? DoCloseAsync(cancellationToken) : base.CloseAsync(cancellationToken);
  110. }
  111. internal async Task DoCloseAsync(CancellationToken cancellationToken)
  112. {
  113. if (Top == 0) // otherwise will happen in calls to WriteEndAsync
  114. {
  115. cancellationToken.ThrowIfCancellationRequested();
  116. }
  117. while (Top > 0)
  118. {
  119. await WriteEndAsync(cancellationToken).ConfigureAwait(false);
  120. }
  121. CloseBufferAndWriter();
  122. }
  123. /// <summary>
  124. /// Asynchronously writes the end of the current JSON object or array.
  125. /// </summary>
  126. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  127. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  128. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  129. /// execute synchronously, returning an already-completed task.</remarks>
  130. public override Task WriteEndAsync(CancellationToken cancellationToken = default(CancellationToken))
  131. {
  132. return _safeAsync ? WriteEndInternalAsync(cancellationToken) : base.WriteEndAsync(cancellationToken);
  133. }
  134. /// <summary>
  135. /// Asynchronously writes indent characters.
  136. /// </summary>
  137. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  138. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  139. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  140. /// execute synchronously, returning an already-completed task.</remarks>
  141. protected override Task WriteIndentAsync(CancellationToken cancellationToken)
  142. {
  143. return _safeAsync ? DoWriteIndentAsync(cancellationToken) : base.WriteIndentAsync(cancellationToken);
  144. }
  145. internal Task DoWriteIndentAsync(CancellationToken cancellationToken)
  146. {
  147. // levels of indentation multiplied by the indent count
  148. int currentIndentCount = Top * _indentation;
  149. int newLineLen = SetIndentChars();
  150. if (currentIndentCount <= IndentCharBufferSize)
  151. {
  152. return _writer.WriteAsync(_indentChars, 0, newLineLen + currentIndentCount, cancellationToken);
  153. }
  154. return WriteIndentAsync(currentIndentCount, newLineLen, cancellationToken);
  155. }
  156. private async Task WriteIndentAsync(int currentIndentCount, int newLineLen, CancellationToken cancellationToken)
  157. {
  158. await _writer.WriteAsync(_indentChars, 0, newLineLen + Math.Min(currentIndentCount, IndentCharBufferSize), cancellationToken).ConfigureAwait(false);
  159. while ((currentIndentCount -= IndentCharBufferSize) > 0)
  160. {
  161. await _writer.WriteAsync(_indentChars, newLineLen, Math.Min(currentIndentCount, IndentCharBufferSize), cancellationToken).ConfigureAwait(false);
  162. }
  163. }
  164. private Task WriteValueInternalAsync(JsonToken token, string value, CancellationToken cancellationToken)
  165. {
  166. Task task = InternalWriteValueAsync(token, cancellationToken);
  167. if (task.IsCompletedSucessfully())
  168. {
  169. return _writer.WriteAsync(value, cancellationToken);
  170. }
  171. return WriteValueInternalAsync(task, value, cancellationToken);
  172. }
  173. private async Task WriteValueInternalAsync(Task task, string value, CancellationToken cancellationToken)
  174. {
  175. await task.ConfigureAwait(false);
  176. await _writer.WriteAsync(value, cancellationToken).ConfigureAwait(false);
  177. }
  178. /// <summary>
  179. /// Asynchronously writes an indent space.
  180. /// </summary>
  181. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  182. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  183. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  184. /// execute synchronously, returning an already-completed task.</remarks>
  185. protected override Task WriteIndentSpaceAsync(CancellationToken cancellationToken)
  186. {
  187. return _safeAsync ? DoWriteIndentSpaceAsync(cancellationToken) : base.WriteIndentSpaceAsync(cancellationToken);
  188. }
  189. internal Task DoWriteIndentSpaceAsync(CancellationToken cancellationToken)
  190. {
  191. return _writer.WriteAsync(' ', cancellationToken);
  192. }
  193. /// <summary>
  194. /// Asynchronously writes raw JSON without changing the writer's state.
  195. /// </summary>
  196. /// <param name="json">The raw JSON to write.</param>
  197. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  198. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  199. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  200. /// execute synchronously, returning an already-completed task.</remarks>
  201. public override Task WriteRawAsync(string json, CancellationToken cancellationToken = default(CancellationToken))
  202. {
  203. return _safeAsync ? DoWriteRawAsync(json, cancellationToken) : base.WriteRawAsync(json, cancellationToken);
  204. }
  205. internal Task DoWriteRawAsync(string json, CancellationToken cancellationToken)
  206. {
  207. return _writer.WriteAsync(json, cancellationToken);
  208. }
  209. /// <summary>
  210. /// Asynchronously writes a null value.
  211. /// </summary>
  212. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  213. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  214. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  215. /// execute synchronously, returning an already-completed task.</remarks>
  216. public override Task WriteNullAsync(CancellationToken cancellationToken = default(CancellationToken))
  217. {
  218. return _safeAsync ? DoWriteNullAsync(cancellationToken) : base.WriteNullAsync(cancellationToken);
  219. }
  220. internal Task DoWriteNullAsync(CancellationToken cancellationToken)
  221. {
  222. return WriteValueInternalAsync(JsonToken.Null, JsonConvert.Null, cancellationToken);
  223. }
  224. private Task WriteDigitsAsync(ulong uvalue, bool negative, CancellationToken cancellationToken)
  225. {
  226. if (uvalue <= 9 & !negative)
  227. {
  228. return _writer.WriteAsync((char)('0' + uvalue), cancellationToken);
  229. }
  230. int length = WriteNumberToBuffer(uvalue, negative);
  231. return _writer.WriteAsync(_writeBuffer, 0, length, cancellationToken);
  232. }
  233. private Task WriteIntegerValueAsync(ulong uvalue, bool negative, CancellationToken cancellationToken)
  234. {
  235. Task task = InternalWriteValueAsync(JsonToken.Integer, cancellationToken);
  236. if (task.IsCompletedSucessfully())
  237. {
  238. return WriteDigitsAsync(uvalue, negative, cancellationToken);
  239. }
  240. return WriteIntegerValueAsync(task, uvalue, negative, cancellationToken);
  241. }
  242. private async Task WriteIntegerValueAsync(Task task, ulong uvalue, bool negative, CancellationToken cancellationToken)
  243. {
  244. await task.ConfigureAwait(false);
  245. await WriteDigitsAsync(uvalue, negative, cancellationToken).ConfigureAwait(false);
  246. }
  247. internal Task WriteIntegerValueAsync(long value, CancellationToken cancellationToken)
  248. {
  249. bool negative = value < 0;
  250. if (negative)
  251. {
  252. value = -value;
  253. }
  254. return WriteIntegerValueAsync((ulong)value, negative, cancellationToken);
  255. }
  256. internal Task WriteIntegerValueAsync(ulong uvalue, CancellationToken cancellationToken)
  257. {
  258. return WriteIntegerValueAsync(uvalue, false, cancellationToken);
  259. }
  260. private Task WriteEscapedStringAsync(string value, bool quote, CancellationToken cancellationToken)
  261. {
  262. return JavaScriptUtils.WriteEscapedJavaScriptStringAsync(_writer, value, _quoteChar, quote, _charEscapeFlags, StringEscapeHandling, this, _writeBuffer, cancellationToken);
  263. }
  264. /// <summary>
  265. /// Asynchronously writes the property name of a name/value pair of a JSON object.
  266. /// </summary>
  267. /// <param name="name">The name of the property.</param>
  268. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  269. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  270. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  271. /// execute synchronously, returning an already-completed task.</remarks>
  272. public override Task WritePropertyNameAsync(string name, CancellationToken cancellationToken = default(CancellationToken))
  273. {
  274. return _safeAsync ? DoWritePropertyNameAsync(name, cancellationToken) : base.WritePropertyNameAsync(name, cancellationToken);
  275. }
  276. internal Task DoWritePropertyNameAsync(string name, CancellationToken cancellationToken)
  277. {
  278. Task task = InternalWritePropertyNameAsync(name, cancellationToken);
  279. if (!task.IsCompletedSucessfully())
  280. {
  281. return DoWritePropertyNameAsync(task, name, cancellationToken);
  282. }
  283. task = WriteEscapedStringAsync(name, _quoteName, cancellationToken);
  284. if (task.IsCompletedSucessfully())
  285. {
  286. return _writer.WriteAsync(':', cancellationToken);
  287. }
  288. return JavaScriptUtils.WriteCharAsync(task, _writer, ':', cancellationToken);
  289. }
  290. private async Task DoWritePropertyNameAsync(Task task, string name, CancellationToken cancellationToken)
  291. {
  292. await task.ConfigureAwait(false);
  293. await WriteEscapedStringAsync(name, _quoteName, cancellationToken).ConfigureAwait(false);
  294. await _writer.WriteAsync(':').ConfigureAwait(false);
  295. }
  296. /// <summary>
  297. /// Asynchronously writes the property name of a name/value pair of a JSON object.
  298. /// </summary>
  299. /// <param name="name">The name of the property.</param>
  300. /// <param name="escape">A flag to indicate whether the text should be escaped when it is written as a JSON property name.</param>
  301. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  302. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  303. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  304. /// execute synchronously, returning an already-completed task.</remarks>
  305. public override Task WritePropertyNameAsync(string name, bool escape, CancellationToken cancellationToken = default(CancellationToken))
  306. {
  307. return _safeAsync ? DoWritePropertyNameAsync(name, escape, cancellationToken) : base.WritePropertyNameAsync(name, escape, cancellationToken);
  308. }
  309. internal async Task DoWritePropertyNameAsync(string name, bool escape, CancellationToken cancellationToken)
  310. {
  311. await InternalWritePropertyNameAsync(name, cancellationToken).ConfigureAwait(false);
  312. if (escape)
  313. {
  314. await WriteEscapedStringAsync(name, _quoteName, cancellationToken).ConfigureAwait(false);
  315. }
  316. else
  317. {
  318. if (_quoteName)
  319. {
  320. await _writer.WriteAsync(_quoteChar).ConfigureAwait(false);
  321. }
  322. await _writer.WriteAsync(name, cancellationToken).ConfigureAwait(false);
  323. if (_quoteName)
  324. {
  325. await _writer.WriteAsync(_quoteChar).ConfigureAwait(false);
  326. }
  327. }
  328. await _writer.WriteAsync(':').ConfigureAwait(false);
  329. }
  330. /// <summary>
  331. /// Asynchronously writes the beginning of a JSON array.
  332. /// </summary>
  333. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  334. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  335. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  336. /// execute synchronously, returning an already-completed task.</remarks>
  337. public override Task WriteStartArrayAsync(CancellationToken cancellationToken = default(CancellationToken))
  338. {
  339. return _safeAsync ? DoWriteStartArrayAsync(cancellationToken) : base.WriteStartArrayAsync(cancellationToken);
  340. }
  341. internal Task DoWriteStartArrayAsync(CancellationToken cancellationToken)
  342. {
  343. Task task = InternalWriteStartAsync(JsonToken.StartArray, JsonContainerType.Array, cancellationToken);
  344. if (task.IsCompletedSucessfully())
  345. {
  346. return _writer.WriteAsync('[', cancellationToken);
  347. }
  348. return DoWriteStartArrayAsync(task, cancellationToken);
  349. }
  350. internal async Task DoWriteStartArrayAsync(Task task, CancellationToken cancellationToken)
  351. {
  352. await task.ConfigureAwait(false);
  353. await _writer.WriteAsync('[', cancellationToken).ConfigureAwait(false);
  354. }
  355. /// <summary>
  356. /// Asynchronously writes the beginning of a JSON object.
  357. /// </summary>
  358. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  359. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  360. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  361. /// execute synchronously, returning an already-completed task.</remarks>
  362. public override Task WriteStartObjectAsync(CancellationToken cancellationToken = default(CancellationToken))
  363. {
  364. return _safeAsync ? DoWriteStartObjectAsync(cancellationToken) : base.WriteStartObjectAsync(cancellationToken);
  365. }
  366. internal Task DoWriteStartObjectAsync(CancellationToken cancellationToken)
  367. {
  368. Task task = InternalWriteStartAsync(JsonToken.StartObject, JsonContainerType.Object, cancellationToken);
  369. if (task.IsCompletedSucessfully())
  370. {
  371. return _writer.WriteAsync('{', cancellationToken);
  372. }
  373. return DoWriteStartObjectAsync(task, cancellationToken);
  374. }
  375. internal async Task DoWriteStartObjectAsync(Task task, CancellationToken cancellationToken)
  376. {
  377. await task.ConfigureAwait(false);
  378. await _writer.WriteAsync('{', cancellationToken).ConfigureAwait(false);
  379. }
  380. /// <summary>
  381. /// Asynchronously writes the start of a constructor with the given name.
  382. /// </summary>
  383. /// <param name="name">The name of the constructor.</param>
  384. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  385. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  386. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  387. /// execute synchronously, returning an already-completed task.</remarks>
  388. public override Task WriteStartConstructorAsync(string name, CancellationToken cancellationToken = default(CancellationToken))
  389. {
  390. return _safeAsync ? DoWriteStartConstructorAsync(name, cancellationToken) : base.WriteStartConstructorAsync(name, cancellationToken);
  391. }
  392. internal async Task DoWriteStartConstructorAsync(string name, CancellationToken cancellationToken)
  393. {
  394. await InternalWriteStartAsync(JsonToken.StartConstructor, JsonContainerType.Constructor, cancellationToken).ConfigureAwait(false);
  395. await _writer.WriteAsync("new ", cancellationToken).ConfigureAwait(false);
  396. await _writer.WriteAsync(name, cancellationToken).ConfigureAwait(false);
  397. await _writer.WriteAsync('(').ConfigureAwait(false);
  398. }
  399. /// <summary>
  400. /// Asynchronously writes an undefined value.
  401. /// </summary>
  402. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  403. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  404. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  405. /// execute synchronously, returning an already-completed task.</remarks>
  406. public override Task WriteUndefinedAsync(CancellationToken cancellationToken = default(CancellationToken))
  407. {
  408. return _safeAsync ? DoWriteUndefinedAsync(cancellationToken) : base.WriteUndefinedAsync(cancellationToken);
  409. }
  410. internal Task DoWriteUndefinedAsync(CancellationToken cancellationToken)
  411. {
  412. Task task = InternalWriteValueAsync(JsonToken.Undefined, cancellationToken);
  413. if (task.IsCompletedSucessfully())
  414. {
  415. return _writer.WriteAsync(JsonConvert.Undefined, cancellationToken);
  416. }
  417. return DoWriteUndefinedAsync(task, cancellationToken);
  418. }
  419. private async Task DoWriteUndefinedAsync(Task task, CancellationToken cancellationToken)
  420. {
  421. await task.ConfigureAwait(false);
  422. await _writer.WriteAsync(JsonConvert.Undefined, cancellationToken).ConfigureAwait(false);
  423. }
  424. /// <summary>
  425. /// Asynchronously writes the given white space.
  426. /// </summary>
  427. /// <param name="ws">The string of white space characters.</param>
  428. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  429. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  430. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  431. /// execute synchronously, returning an already-completed task.</remarks>
  432. public override Task WriteWhitespaceAsync(string ws, CancellationToken cancellationToken = default(CancellationToken))
  433. {
  434. return _safeAsync ? DoWriteWhitespaceAsync(ws, cancellationToken) : base.WriteWhitespaceAsync(ws, cancellationToken);
  435. }
  436. internal Task DoWriteWhitespaceAsync(string ws, CancellationToken cancellationToken)
  437. {
  438. InternalWriteWhitespace(ws);
  439. return _writer.WriteAsync(ws, cancellationToken);
  440. }
  441. /// <summary>
  442. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="bool"/> value.
  443. /// </summary>
  444. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="bool"/> value to write.</param>
  445. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  446. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  447. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  448. /// execute synchronously, returning an already-completed task.</remarks>
  449. public override Task WriteValueAsync(bool value, CancellationToken cancellationToken = default(CancellationToken))
  450. {
  451. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  452. }
  453. internal Task DoWriteValueAsync(bool value, CancellationToken cancellationToken)
  454. {
  455. return WriteValueInternalAsync(JsonToken.Boolean, JsonConvert.ToString(value), cancellationToken);
  456. }
  457. /// <summary>
  458. /// Asynchronously writes a <see cref="bool"/> value.
  459. /// </summary>
  460. /// <param name="value">The <see cref="bool"/> value to write.</param>
  461. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  462. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  463. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  464. /// execute synchronously, returning an already-completed task.</remarks>
  465. public override Task WriteValueAsync(bool? value, CancellationToken cancellationToken = default(CancellationToken))
  466. {
  467. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  468. }
  469. internal Task DoWriteValueAsync(bool? value, CancellationToken cancellationToken)
  470. {
  471. return value == null ? DoWriteNullAsync(cancellationToken) : DoWriteValueAsync(value.GetValueOrDefault(), cancellationToken);
  472. }
  473. /// <summary>
  474. /// Asynchronously writes a <see cref="byte"/> value.
  475. /// </summary>
  476. /// <param name="value">The <see cref="byte"/> value to write.</param>
  477. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  478. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  479. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  480. /// execute synchronously, returning an already-completed task.</remarks>
  481. public override Task WriteValueAsync(byte value, CancellationToken cancellationToken = default(CancellationToken))
  482. {
  483. return _safeAsync ? WriteIntegerValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  484. }
  485. /// <summary>
  486. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="byte"/> value.
  487. /// </summary>
  488. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="byte"/> value to write.</param>
  489. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  490. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  491. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  492. /// execute synchronously, returning an already-completed task.</remarks>
  493. public override Task WriteValueAsync(byte? value, CancellationToken cancellationToken = default(CancellationToken))
  494. {
  495. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  496. }
  497. internal Task DoWriteValueAsync(byte? value, CancellationToken cancellationToken)
  498. {
  499. return value == null ? DoWriteNullAsync(cancellationToken) : WriteIntegerValueAsync(value.GetValueOrDefault(), cancellationToken);
  500. }
  501. /// <summary>
  502. /// Asynchronously writes a <see cref="byte"/>[] value.
  503. /// </summary>
  504. /// <param name="value">The <see cref="byte"/>[] value to write.</param>
  505. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  506. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  507. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  508. /// execute synchronously, returning an already-completed task.</remarks>
  509. public override Task WriteValueAsync(byte[] value, CancellationToken cancellationToken = default(CancellationToken))
  510. {
  511. return _safeAsync ? (value == null ? WriteNullAsync(cancellationToken) : WriteValueNonNullAsync(value, cancellationToken)) : base.WriteValueAsync(value, cancellationToken);
  512. }
  513. internal async Task WriteValueNonNullAsync(byte[] value, CancellationToken cancellationToken)
  514. {
  515. await InternalWriteValueAsync(JsonToken.Bytes, cancellationToken).ConfigureAwait(false);
  516. await _writer.WriteAsync(_quoteChar).ConfigureAwait(false);
  517. await Base64Encoder.EncodeAsync(value, 0, value.Length, cancellationToken).ConfigureAwait(false);
  518. await Base64Encoder.FlushAsync(cancellationToken).ConfigureAwait(false);
  519. await _writer.WriteAsync(_quoteChar).ConfigureAwait(false);
  520. }
  521. /// <summary>
  522. /// Asynchronously writes a <see cref="char"/> value.
  523. /// </summary>
  524. /// <param name="value">The <see cref="char"/> value to write.</param>
  525. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  526. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  527. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  528. /// execute synchronously, returning an already-completed task.</remarks>
  529. public override Task WriteValueAsync(char value, CancellationToken cancellationToken = default(CancellationToken))
  530. {
  531. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  532. }
  533. internal Task DoWriteValueAsync(char value, CancellationToken cancellationToken)
  534. {
  535. return WriteValueInternalAsync(JsonToken.String, JsonConvert.ToString(value), cancellationToken);
  536. }
  537. /// <summary>
  538. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="char"/> value.
  539. /// </summary>
  540. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="char"/> value to write.</param>
  541. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  542. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  543. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  544. /// execute synchronously, returning an already-completed task.</remarks>
  545. public override Task WriteValueAsync(char? value, CancellationToken cancellationToken = default(CancellationToken))
  546. {
  547. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  548. }
  549. internal Task DoWriteValueAsync(char? value, CancellationToken cancellationToken)
  550. {
  551. return value == null ? DoWriteNullAsync(cancellationToken) : DoWriteValueAsync(value.GetValueOrDefault(), cancellationToken);
  552. }
  553. /// <summary>
  554. /// Asynchronously writes a <see cref="DateTime"/> value.
  555. /// </summary>
  556. /// <param name="value">The <see cref="DateTime"/> value to write.</param>
  557. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  558. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  559. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  560. /// execute synchronously, returning an already-completed task.</remarks>
  561. public override Task WriteValueAsync(DateTime value, CancellationToken cancellationToken = default(CancellationToken))
  562. {
  563. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  564. }
  565. internal async Task DoWriteValueAsync(DateTime value, CancellationToken cancellationToken)
  566. {
  567. await InternalWriteValueAsync(JsonToken.Date, cancellationToken).ConfigureAwait(false);
  568. value = DateTimeUtils.EnsureDateTime(value, DateTimeZoneHandling);
  569. if (string.IsNullOrEmpty(DateFormatString))
  570. {
  571. int length = WriteValueToBuffer(value);
  572. await _writer.WriteAsync(_writeBuffer, 0, length, cancellationToken).ConfigureAwait(false);
  573. }
  574. else
  575. {
  576. await _writer.WriteAsync(_quoteChar).ConfigureAwait(false);
  577. await _writer.WriteAsync(value.ToString(DateFormatString, Culture), cancellationToken).ConfigureAwait(false);
  578. await _writer.WriteAsync(_quoteChar).ConfigureAwait(false);
  579. }
  580. }
  581. /// <summary>
  582. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="DateTime"/> value.
  583. /// </summary>
  584. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="DateTime"/> value to write.</param>
  585. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  586. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  587. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  588. /// execute synchronously, returning an already-completed task.</remarks>
  589. public override Task WriteValueAsync(DateTime? value, CancellationToken cancellationToken = default(CancellationToken))
  590. {
  591. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  592. }
  593. internal Task DoWriteValueAsync(DateTime? value, CancellationToken cancellationToken)
  594. {
  595. return value == null ? DoWriteNullAsync(cancellationToken) : DoWriteValueAsync(value.GetValueOrDefault(), cancellationToken);
  596. }
  597. /// <summary>
  598. /// Asynchronously writes a <see cref="DateTimeOffset"/> value.
  599. /// </summary>
  600. /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
  601. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  602. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  603. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  604. /// execute synchronously, returning an already-completed task.</remarks>
  605. public override Task WriteValueAsync(DateTimeOffset value, CancellationToken cancellationToken = default(CancellationToken))
  606. {
  607. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  608. }
  609. internal async Task DoWriteValueAsync(DateTimeOffset value, CancellationToken cancellationToken)
  610. {
  611. await InternalWriteValueAsync(JsonToken.Date, cancellationToken).ConfigureAwait(false);
  612. if (string.IsNullOrEmpty(DateFormatString))
  613. {
  614. int length = WriteValueToBuffer(value);
  615. await _writer.WriteAsync(_writeBuffer, 0, length, cancellationToken).ConfigureAwait(false);
  616. }
  617. else
  618. {
  619. await _writer.WriteAsync(_quoteChar).ConfigureAwait(false);
  620. await _writer.WriteAsync(value.ToString(DateFormatString, Culture), cancellationToken).ConfigureAwait(false);
  621. await _writer.WriteAsync(_quoteChar).ConfigureAwait(false);
  622. }
  623. }
  624. /// <summary>
  625. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="DateTimeOffset"/> value.
  626. /// </summary>
  627. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="DateTimeOffset"/> value to write.</param>
  628. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  629. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  630. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  631. /// execute synchronously, returning an already-completed task.</remarks>
  632. public override Task WriteValueAsync(DateTimeOffset? value, CancellationToken cancellationToken = default(CancellationToken))
  633. {
  634. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  635. }
  636. internal Task DoWriteValueAsync(DateTimeOffset? value, CancellationToken cancellationToken)
  637. {
  638. return value == null ? DoWriteNullAsync(cancellationToken) : DoWriteValueAsync(value.GetValueOrDefault(), cancellationToken);
  639. }
  640. /// <summary>
  641. /// Asynchronously writes a <see cref="decimal"/> value.
  642. /// </summary>
  643. /// <param name="value">The <see cref="decimal"/> value to write.</param>
  644. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  645. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  646. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  647. /// execute synchronously, returning an already-completed task.</remarks>
  648. public override Task WriteValueAsync(decimal value, CancellationToken cancellationToken = default(CancellationToken))
  649. {
  650. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  651. }
  652. internal Task DoWriteValueAsync(decimal value, CancellationToken cancellationToken)
  653. {
  654. return WriteValueInternalAsync(JsonToken.Float, JsonConvert.ToString(value), cancellationToken);
  655. }
  656. /// <summary>
  657. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="decimal"/> value.
  658. /// </summary>
  659. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="decimal"/> value to write.</param>
  660. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  661. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  662. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  663. /// execute synchronously, returning an already-completed task.</remarks>
  664. public override Task WriteValueAsync(decimal? value, CancellationToken cancellationToken = default(CancellationToken))
  665. {
  666. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  667. }
  668. internal Task DoWriteValueAsync(decimal? value, CancellationToken cancellationToken)
  669. {
  670. return value == null ? DoWriteNullAsync(cancellationToken) : DoWriteValueAsync(value.GetValueOrDefault(), cancellationToken);
  671. }
  672. /// <summary>
  673. /// Asynchronously writes a <see cref="double"/> value.
  674. /// </summary>
  675. /// <param name="value">The <see cref="double"/> value to write.</param>
  676. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  677. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  678. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  679. /// execute synchronously, returning an already-completed task.</remarks>
  680. public override Task WriteValueAsync(double value, CancellationToken cancellationToken = default(CancellationToken))
  681. {
  682. return _safeAsync ? WriteValueAsync(value, false, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  683. }
  684. internal Task WriteValueAsync(double value, bool nullable, CancellationToken cancellationToken)
  685. {
  686. return WriteValueInternalAsync(JsonToken.Float, JsonConvert.ToString(value, FloatFormatHandling, QuoteChar, nullable), cancellationToken);
  687. }
  688. /// <summary>
  689. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="double"/> value.
  690. /// </summary>
  691. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="double"/> value to write.</param>
  692. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  693. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  694. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  695. /// execute synchronously, returning an already-completed task.</remarks>
  696. public override Task WriteValueAsync(double? value, CancellationToken cancellationToken = default(CancellationToken))
  697. {
  698. return _safeAsync ? (value.HasValue ? WriteValueAsync(value.GetValueOrDefault(), true, cancellationToken) : WriteNullAsync(cancellationToken)) : base.WriteValueAsync(value, cancellationToken);
  699. }
  700. /// <summary>
  701. /// Asynchronously writes a <see cref="float"/> value.
  702. /// </summary>
  703. /// <param name="value">The <see cref="float"/> value to write.</param>
  704. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  705. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  706. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  707. /// execute synchronously, returning an already-completed task.</remarks>
  708. public override Task WriteValueAsync(float value, CancellationToken cancellationToken = default(CancellationToken))
  709. {
  710. return _safeAsync ? WriteValueAsync(value, false, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  711. }
  712. internal Task WriteValueAsync(float value, bool nullable, CancellationToken cancellationToken)
  713. {
  714. return WriteValueInternalAsync(JsonToken.Float, JsonConvert.ToString(value, FloatFormatHandling, QuoteChar, nullable), cancellationToken);
  715. }
  716. /// <summary>
  717. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="float"/> value.
  718. /// </summary>
  719. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="float"/> value to write.</param>
  720. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  721. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  722. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  723. /// execute synchronously, returning an already-completed task.</remarks>
  724. public override Task WriteValueAsync(float? value, CancellationToken cancellationToken = default(CancellationToken))
  725. {
  726. return _safeAsync ? (value.HasValue ? WriteValueAsync(value.GetValueOrDefault(), true, cancellationToken) : WriteNullAsync(cancellationToken)) : base.WriteValueAsync(value, cancellationToken);
  727. }
  728. /// <summary>
  729. /// Asynchronously writes a <see cref="Guid"/> value.
  730. /// </summary>
  731. /// <param name="value">The <see cref="Guid"/> value to write.</param>
  732. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  733. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  734. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  735. /// execute synchronously, returning an already-completed task.</remarks>
  736. public override Task WriteValueAsync(Guid value, CancellationToken cancellationToken = default(CancellationToken))
  737. {
  738. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  739. }
  740. internal async Task DoWriteValueAsync(Guid value, CancellationToken cancellationToken)
  741. {
  742. await InternalWriteValueAsync(JsonToken.String, cancellationToken).ConfigureAwait(false);
  743. await _writer.WriteAsync(_quoteChar).ConfigureAwait(false);
  744. #if HAVE_CHAR_TO_STRING_WITH_CULTURE
  745. await _writer.WriteAsync(value.ToString("D", CultureInfo.InvariantCulture), cancellationToken).ConfigureAwait(false);
  746. #else
  747. await _writer.WriteAsync(value.ToString("D"), cancellationToken).ConfigureAwait(false);
  748. #endif
  749. await _writer.WriteAsync(_quoteChar).ConfigureAwait(false);
  750. }
  751. /// <summary>
  752. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="Guid"/> value.
  753. /// </summary>
  754. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="Guid"/> value to write.</param>
  755. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  756. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  757. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  758. /// execute synchronously, returning an already-completed task.</remarks>
  759. public override Task WriteValueAsync(Guid? value, CancellationToken cancellationToken = default(CancellationToken))
  760. {
  761. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  762. }
  763. internal Task DoWriteValueAsync(Guid? value, CancellationToken cancellationToken)
  764. {
  765. return value == null ? DoWriteNullAsync(cancellationToken) : DoWriteValueAsync(value.GetValueOrDefault(), cancellationToken);
  766. }
  767. /// <summary>
  768. /// Asynchronously writes a <see cref="int"/> value.
  769. /// </summary>
  770. /// <param name="value">The <see cref="int"/> value to write.</param>
  771. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  772. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  773. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  774. /// execute synchronously, returning an already-completed task.</remarks>
  775. public override Task WriteValueAsync(int value, CancellationToken cancellationToken = default(CancellationToken))
  776. {
  777. return _safeAsync ? WriteIntegerValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  778. }
  779. /// <summary>
  780. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="int"/> value.
  781. /// </summary>
  782. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="int"/> 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>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  786. /// execute synchronously, returning an already-completed task.</remarks>
  787. public override Task WriteValueAsync(int? value, CancellationToken cancellationToken = default(CancellationToken))
  788. {
  789. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  790. }
  791. internal Task DoWriteValueAsync(int? value, CancellationToken cancellationToken)
  792. {
  793. return value == null ? DoWriteNullAsync(cancellationToken) : WriteIntegerValueAsync(value.GetValueOrDefault(), cancellationToken);
  794. }
  795. /// <summary>
  796. /// Asynchronously writes a <see cref="long"/> value.
  797. /// </summary>
  798. /// <param name="value">The <see cref="long"/> value to write.</param>
  799. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  800. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  801. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  802. /// execute synchronously, returning an already-completed task.</remarks>
  803. public override Task WriteValueAsync(long value, CancellationToken cancellationToken = default(CancellationToken))
  804. {
  805. return _safeAsync ? WriteIntegerValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  806. }
  807. /// <summary>
  808. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="long"/> value.
  809. /// </summary>
  810. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="long"/> value to write.</param>
  811. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  812. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  813. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  814. /// execute synchronously, returning an already-completed task.</remarks>
  815. public override Task WriteValueAsync(long? value, CancellationToken cancellationToken = default(CancellationToken))
  816. {
  817. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  818. }
  819. internal Task DoWriteValueAsync(long? value, CancellationToken cancellationToken)
  820. {
  821. return value == null ? DoWriteNullAsync(cancellationToken) : WriteIntegerValueAsync(value.GetValueOrDefault(), cancellationToken);
  822. }
  823. #if HAVE_BIG_INTEGER
  824. internal Task WriteValueAsync(BigInteger value, CancellationToken cancellationToken)
  825. {
  826. return WriteValueInternalAsync(JsonToken.Integer, value.ToString(CultureInfo.InvariantCulture), cancellationToken);
  827. }
  828. #endif
  829. /// <summary>
  830. /// Asynchronously writes a <see cref="object"/> value.
  831. /// </summary>
  832. /// <param name="value">The <see cref="object"/> value to write.</param>
  833. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  834. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  835. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  836. /// execute synchronously, returning an already-completed task.</remarks>
  837. public override Task WriteValueAsync(object value, CancellationToken cancellationToken = default(CancellationToken))
  838. {
  839. if (_safeAsync)
  840. {
  841. if (value == null)
  842. {
  843. return WriteNullAsync(cancellationToken);
  844. }
  845. #if HAVE_BIG_INTEGER
  846. if (value is BigInteger i)
  847. {
  848. return WriteValueAsync(i, cancellationToken);
  849. }
  850. #endif
  851. return WriteValueAsync(this, ConvertUtils.GetTypeCode(value.GetType()), value, cancellationToken);
  852. }
  853. return base.WriteValueAsync(value, cancellationToken);
  854. }
  855. /// <summary>
  856. /// Asynchronously writes a <see cref="sbyte"/> value.
  857. /// </summary>
  858. /// <param name="value">The <see cref="sbyte"/> value to write.</param>
  859. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  860. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  861. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  862. /// execute synchronously, returning an already-completed task.</remarks>
  863. public override Task WriteValueAsync(sbyte value, CancellationToken cancellationToken = default(CancellationToken))
  864. {
  865. return _safeAsync ? WriteIntegerValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  866. }
  867. /// <summary>
  868. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="sbyte"/> value.
  869. /// </summary>
  870. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="sbyte"/> value to write.</param>
  871. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  872. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  873. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  874. /// execute synchronously, returning an already-completed task.</remarks>
  875. public override Task WriteValueAsync(sbyte? value, CancellationToken cancellationToken = default(CancellationToken))
  876. {
  877. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  878. }
  879. internal Task DoWriteValueAsync(sbyte? value, CancellationToken cancellationToken)
  880. {
  881. return value == null ? DoWriteNullAsync(cancellationToken) : WriteIntegerValueAsync(value.GetValueOrDefault(), cancellationToken);
  882. }
  883. /// <summary>
  884. /// Asynchronously writes a <see cref="short"/> value.
  885. /// </summary>
  886. /// <param name="value">The <see cref="short"/> value to write.</param>
  887. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  888. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  889. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  890. /// execute synchronously, returning an already-completed task.</remarks>
  891. public override Task WriteValueAsync(short value, CancellationToken cancellationToken = default(CancellationToken))
  892. {
  893. return _safeAsync ? WriteIntegerValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  894. }
  895. /// <summary>
  896. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="short"/> value.
  897. /// </summary>
  898. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="short"/> value to write.</param>
  899. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  900. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  901. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  902. /// execute synchronously, returning an already-completed task.</remarks>
  903. public override Task WriteValueAsync(short? value, CancellationToken cancellationToken = default(CancellationToken))
  904. {
  905. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  906. }
  907. internal Task DoWriteValueAsync(short? value, CancellationToken cancellationToken)
  908. {
  909. return value == null ? DoWriteNullAsync(cancellationToken) : WriteIntegerValueAsync(value.GetValueOrDefault(), cancellationToken);
  910. }
  911. /// <summary>
  912. /// Asynchronously writes a <see cref="string"/> value.
  913. /// </summary>
  914. /// <param name="value">The <see cref="string"/> value to write.</param>
  915. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  916. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  917. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  918. /// execute synchronously, returning an already-completed task.</remarks>
  919. public override Task WriteValueAsync(string value, CancellationToken cancellationToken = default(CancellationToken))
  920. {
  921. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  922. }
  923. internal Task DoWriteValueAsync(string value, CancellationToken cancellationToken)
  924. {
  925. Task task = InternalWriteValueAsync(JsonToken.String, cancellationToken);
  926. if (task.IsCompletedSucessfully())
  927. {
  928. return value == null ? _writer.WriteAsync(JsonConvert.Null, cancellationToken) : WriteEscapedStringAsync(value, true, cancellationToken);
  929. }
  930. return DoWriteValueAsync(task, value, cancellationToken);
  931. }
  932. private async Task DoWriteValueAsync(Task task, string value, CancellationToken cancellationToken)
  933. {
  934. await task.ConfigureAwait(false);
  935. await (value == null ? _writer.WriteAsync(JsonConvert.Null, cancellationToken) : WriteEscapedStringAsync(value, true, cancellationToken)).ConfigureAwait(false);
  936. }
  937. /// <summary>
  938. /// Asynchronously writes a <see cref="TimeSpan"/> value.
  939. /// </summary>
  940. /// <param name="value">The <see cref="TimeSpan"/> value to write.</param>
  941. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  942. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  943. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  944. /// execute synchronously, returning an already-completed task.</remarks>
  945. public override Task WriteValueAsync(TimeSpan value, CancellationToken cancellationToken = default(CancellationToken))
  946. {
  947. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  948. }
  949. internal async Task DoWriteValueAsync(TimeSpan value, CancellationToken cancellationToken)
  950. {
  951. await InternalWriteValueAsync(JsonToken.String, cancellationToken).ConfigureAwait(false);
  952. await _writer.WriteAsync(_quoteChar, cancellationToken).ConfigureAwait(false);
  953. await _writer.WriteAsync(value.ToString(null, CultureInfo.InvariantCulture), cancellationToken).ConfigureAwait(false);
  954. await _writer.WriteAsync(_quoteChar, cancellationToken).ConfigureAwait(false);
  955. }
  956. /// <summary>
  957. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="TimeSpan"/> value.
  958. /// </summary>
  959. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="TimeSpan"/> value to write.</param>
  960. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  961. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  962. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  963. /// execute synchronously, returning an already-completed task.</remarks>
  964. public override Task WriteValueAsync(TimeSpan? value, CancellationToken cancellationToken = default(CancellationToken))
  965. {
  966. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  967. }
  968. internal Task DoWriteValueAsync(TimeSpan? value, CancellationToken cancellationToken)
  969. {
  970. return value == null ? DoWriteNullAsync(cancellationToken) : DoWriteValueAsync(value.GetValueOrDefault(), cancellationToken);
  971. }
  972. /// <summary>
  973. /// Asynchronously writes a <see cref="uint"/> value.
  974. /// </summary>
  975. /// <param name="value">The <see cref="uint"/> value to write.</param>
  976. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  977. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  978. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  979. /// execute synchronously, returning an already-completed task.</remarks>
  980. public override Task WriteValueAsync(uint value, CancellationToken cancellationToken = default(CancellationToken))
  981. {
  982. return _safeAsync ? WriteIntegerValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  983. }
  984. /// <summary>
  985. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="uint"/> value.
  986. /// </summary>
  987. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="uint"/> value to write.</param>
  988. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  989. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  990. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  991. /// execute synchronously, returning an already-completed task.</remarks>
  992. public override Task WriteValueAsync(uint? value, CancellationToken cancellationToken = default(CancellationToken))
  993. {
  994. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  995. }
  996. internal Task DoWriteValueAsync(uint? value, CancellationToken cancellationToken)
  997. {
  998. return value == null ? DoWriteNullAsync(cancellationToken) : WriteIntegerValueAsync(value.GetValueOrDefault(), cancellationToken);
  999. }
  1000. /// <summary>
  1001. /// Asynchronously writes a <see cref="ulong"/> value.
  1002. /// </summary>
  1003. /// <param name="value">The <see cref="ulong"/> 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>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  1007. /// execute synchronously, returning an already-completed task.</remarks>
  1008. public override Task WriteValueAsync(ulong value, CancellationToken cancellationToken = default(CancellationToken))
  1009. {
  1010. return _safeAsync ? WriteIntegerValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  1011. }
  1012. /// <summary>
  1013. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="ulong"/> value.
  1014. /// </summary>
  1015. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="ulong"/> value to write.</param>
  1016. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1017. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1018. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  1019. /// execute synchronously, returning an already-completed task.</remarks>
  1020. public override Task WriteValueAsync(ulong? value, CancellationToken cancellationToken = default(CancellationToken))
  1021. {
  1022. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  1023. }
  1024. internal Task DoWriteValueAsync(ulong? value, CancellationToken cancellationToken)
  1025. {
  1026. return value == null ? DoWriteNullAsync(cancellationToken) : WriteIntegerValueAsync(value.GetValueOrDefault(), cancellationToken);
  1027. }
  1028. /// <summary>
  1029. /// Asynchronously writes a <see cref="Uri"/> value.
  1030. /// </summary>
  1031. /// <param name="value">The <see cref="Uri"/> value to write.</param>
  1032. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1033. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1034. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  1035. /// execute synchronously, returning an already-completed task.</remarks>
  1036. public override Task WriteValueAsync(Uri value, CancellationToken cancellationToken = default(CancellationToken))
  1037. {
  1038. return _safeAsync ? (value == null ? WriteNullAsync(cancellationToken) : WriteValueNotNullAsync(value, cancellationToken)) : base.WriteValueAsync(value, cancellationToken);
  1039. }
  1040. internal Task WriteValueNotNullAsync(Uri value, CancellationToken cancellationToken)
  1041. {
  1042. Task task = InternalWriteValueAsync(JsonToken.String, cancellationToken);
  1043. if (task.IsCompletedSucessfully())
  1044. {
  1045. return WriteEscapedStringAsync(value.OriginalString, true, cancellationToken);
  1046. }
  1047. return WriteValueNotNullAsync(task, value, cancellationToken);
  1048. }
  1049. internal async Task WriteValueNotNullAsync(Task task, Uri value, CancellationToken cancellationToken)
  1050. {
  1051. await task.ConfigureAwait(false);
  1052. await WriteEscapedStringAsync(value.OriginalString, true, cancellationToken).ConfigureAwait(false);
  1053. }
  1054. /// <summary>
  1055. /// Asynchronously writes a <see cref="ushort"/> value.
  1056. /// </summary>
  1057. /// <param name="value">The <see cref="ushort"/> value to write.</param>
  1058. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1059. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1060. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  1061. /// execute synchronously, returning an already-completed task.</remarks>
  1062. public override Task WriteValueAsync(ushort value, CancellationToken cancellationToken = default(CancellationToken))
  1063. {
  1064. return _safeAsync ? WriteIntegerValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  1065. }
  1066. /// <summary>
  1067. /// Asynchronously writes a <see cref="Nullable{T}"/> of <see cref="ushort"/> value.
  1068. /// </summary>
  1069. /// <param name="value">The <see cref="Nullable{T}"/> of <see cref="ushort"/> value to write.</param>
  1070. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1071. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1072. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  1073. /// execute synchronously, returning an already-completed task.</remarks>
  1074. public override Task WriteValueAsync(ushort? value, CancellationToken cancellationToken = default(CancellationToken))
  1075. {
  1076. return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
  1077. }
  1078. internal Task DoWriteValueAsync(ushort? value, CancellationToken cancellationToken)
  1079. {
  1080. return value == null ? DoWriteNullAsync(cancellationToken) : WriteIntegerValueAsync(value.GetValueOrDefault(), cancellationToken);
  1081. }
  1082. /// <summary>
  1083. /// Asynchronously writes a comment <c>/*...*/</c> containing the specified text.
  1084. /// </summary>
  1085. /// <param name="text">Text to place inside the comment.</param>
  1086. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1087. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1088. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  1089. /// execute synchronously, returning an already-completed task.</remarks>
  1090. public override Task WriteCommentAsync(string text, CancellationToken cancellationToken = default(CancellationToken))
  1091. {
  1092. return _safeAsync ? DoWriteCommentAsync(text, cancellationToken) : base.WriteCommentAsync(text, cancellationToken);
  1093. }
  1094. internal async Task DoWriteCommentAsync(string text, CancellationToken cancellationToken)
  1095. {
  1096. await InternalWriteCommentAsync(cancellationToken).ConfigureAwait(false);
  1097. await _writer.WriteAsync("/*", cancellationToken).ConfigureAwait(false);
  1098. await _writer.WriteAsync(text, cancellationToken).ConfigureAwait(false);
  1099. await _writer.WriteAsync("*/", cancellationToken).ConfigureAwait(false);
  1100. }
  1101. /// <summary>
  1102. /// Asynchronously writes the end of an array.
  1103. /// </summary>
  1104. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1105. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1106. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  1107. /// execute synchronously, returning an already-completed task.</remarks>
  1108. public override Task WriteEndArrayAsync(CancellationToken cancellationToken = default(CancellationToken))
  1109. {
  1110. return _safeAsync ? InternalWriteEndAsync(JsonContainerType.Array, cancellationToken) : base.WriteEndArrayAsync(cancellationToken);
  1111. }
  1112. /// <summary>
  1113. /// Asynchronously writes the end of a constructor.
  1114. /// </summary>
  1115. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1116. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1117. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  1118. /// execute synchronously, returning an already-completed task.</remarks>
  1119. public override Task WriteEndConstructorAsync(CancellationToken cancellationToken = default(CancellationToken))
  1120. {
  1121. return _safeAsync ? InternalWriteEndAsync(JsonContainerType.Constructor, cancellationToken) : base.WriteEndConstructorAsync(cancellationToken);
  1122. }
  1123. /// <summary>
  1124. /// Asynchronously writes the end of a JSON object.
  1125. /// </summary>
  1126. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1127. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1128. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  1129. /// execute synchronously, returning an already-completed task.</remarks>
  1130. public override Task WriteEndObjectAsync(CancellationToken cancellationToken = default(CancellationToken))
  1131. {
  1132. return _safeAsync ? InternalWriteEndAsync(JsonContainerType.Object, cancellationToken) : base.WriteEndObjectAsync(cancellationToken);
  1133. }
  1134. /// <summary>
  1135. /// Asynchronously writes raw JSON where a value is expected and updates the writer's state.
  1136. /// </summary>
  1137. /// <param name="json">The raw JSON to write.</param>
  1138. /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
  1139. /// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
  1140. /// <remarks>Derived classes must override this method to get asynchronous behaviour. Otherwise it will
  1141. /// execute synchronously, returning an already-completed task.</remarks>
  1142. public override Task WriteRawValueAsync(string json, CancellationToken cancellationToken = default(CancellationToken))
  1143. {
  1144. return _safeAsync ? DoWriteRawValueAsync(json, cancellationToken) : base.WriteRawValueAsync(json, cancellationToken);
  1145. }
  1146. internal Task DoWriteRawValueAsync(string json, CancellationToken cancellationToken)
  1147. {
  1148. UpdateScopeWithFinishedValue();
  1149. Task task = AutoCompleteAsync(JsonToken.Undefined, cancellationToken);
  1150. if (task.IsCompletedSucessfully())
  1151. {
  1152. return WriteRawAsync(json, cancellationToken);
  1153. }
  1154. return DoWriteRawValueAsync(task, json, cancellationToken);
  1155. }
  1156. private async Task DoWriteRawValueAsync(Task task, string json, CancellationToken cancellationToken)
  1157. {
  1158. await task.ConfigureAwait(false);
  1159. await WriteRawAsync(json, cancellationToken).ConfigureAwait(false);
  1160. }
  1161. internal char[] EnsureWriteBuffer(int length, int copyTo)
  1162. {
  1163. if (length < 35)
  1164. {
  1165. length = 35;
  1166. }
  1167. char[] buffer = _writeBuffer;
  1168. if (buffer == null)
  1169. {
  1170. return _writeBuffer = BufferUtils.RentBuffer(_arrayPool, length);
  1171. }
  1172. if (buffer.Length >= length)
  1173. {
  1174. return buffer;
  1175. }
  1176. char[] newBuffer = BufferUtils.RentBuffer(_arrayPool, length);
  1177. if (copyTo != 0)
  1178. {
  1179. Array.Copy(buffer, newBuffer, copyTo);
  1180. }
  1181. BufferUtils.ReturnBuffer(_arrayPool, buffer);
  1182. _writeBuffer = newBuffer;
  1183. return newBuffer;
  1184. }
  1185. }
  1186. }
  1187. #endif