Code Coverage Statistics for Source File
Newtonsoft.Json\JsonTextWriter.cs
Symbol Coverage: 98.00% (147 of 150)
Branch Coverage: 93.22% (55 of 59)
Cyclomatic Complexity Avg: 1.26 Max:3
Code Lines: 142
Symbol Coverage Trend
View:
L | V | Source |
---|---|---|
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 |
||
26 |
using System; |
|
27 |
using System.Collections.Generic; |
|
28 |
using System.Text; |
|
29 |
using System.IO; |
|
30 |
using System.Xml; |
|
31 |
using Newtonsoft.Json.Utilities; |
|
32 |
||
33 |
namespace Newtonsoft.Json |
|
34 |
{ |
|
35 |
/// <summary> |
|
36 |
/// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. |
|
37 |
/// </summary> |
|
38 |
public class JsonTextWriter : JsonWriter |
|
39 |
{ |
|
40 |
private readonly TextWriter _writer; |
|
41 |
private Base64Encoder _base64Encoder; |
|
42 |
private char _indentChar; |
|
43 |
private int _indentation; |
|
44 |
private char _quoteChar; |
|
45 |
private bool _quoteName; |
|
46 |
||
47 |
private Base64Encoder Base64Encoder |
|
48 |
{ |
|
49 |
get |
|
50 |
{ |
|
51 |
420 |
if (_base64Encoder == null)
|
52 |
207 |
_base64Encoder = new Base64Encoder(_writer);
|
53 |
||
54 |
420 |
return _base64Encoder;
|
55 |
420 |
}
|
56 |
} |
|
57 |
||
58 |
/// <summary> |
|
59 |
/// Gets or sets how many IndentChars to write for each level in the hierarchy when <paramref name="Formatting"/> is set to <c>Formatting.Indented</c>. |
|
60 |
/// </summary> |
|
61 |
public int Indentation |
|
62 |
{ |
|
63 |
1 |
get { return _indentation; }
|
64 |
set |
|
65 |
{ |
|
66 |
1 |
if (value < 0)
|
67 |
0 |
throw new ArgumentException("Indentation value must be greater than 0.");
|
68 |
||
69 |
1 |
_indentation = value;
|
70 |
1 |
}
|
71 |
} |
|
72 |
||
73 |
/// <summary> |
|
74 |
/// Gets or sets which character to use to quote attribute values. |
|
75 |
/// </summary> |
|
76 |
public char QuoteChar |
|
77 |
{ |
|
78 |
1 |
get { return _quoteChar; }
|
79 |
set |
|
80 |
{ |
|
81 |
2 |
if (value != '"' && value != '\'')
|
82 |
1 |
throw new ArgumentException(@"Invalid JavaScript string quote character. Valid quote characters are ' and "".");
|
83 |
||
84 |
1 |
_quoteChar = value;
|
85 |
1 |
}
|
86 |
} |
|
87 |
||
88 |
/// <summary> |
|
89 |
/// Gets or sets which character to use for indenting when <paramref name="Formatting"/> is set to <c>Formatting.Indented</c>. |
|
90 |
/// </summary> |
|
91 |
public char IndentChar |
|
92 |
{ |
|
93 |
1 |
get { return _indentChar; }
|
94 |
1 |
set { _indentChar = value; }
|
95 |
} |
|
96 |
||
97 |
/// <summary> |
|
98 |
/// Gets or sets a value indicating whether object names will be surrounded with quotes. |
|
99 |
/// </summary> |
|
100 |
public bool QuoteName |
|
101 |
{ |
|
102 |
1 |
get { return _quoteName; }
|
103 |
1 |
set { _quoteName = value; }
|
104 |
} |
|
105 |
||
106 |
/// <summary> |
|
107 |
/// Creates an instance of the <c>JsonWriter</c> class using the specified <see cref="TextWriter"/>. |
|
108 |
/// </summary> |
|
109 |
/// <param name="textWriter">The <c>TextWriter</c> to write to.</param> |
|
110 |
5747 |
public JsonTextWriter(TextWriter textWriter)
|
111 |
{ |
|
112 |
5747 |
if (textWriter == null)
|
113 |
0 |
throw new ArgumentNullException("textWriter");
|
114 |
||
115 |
5747 |
_writer = textWriter;
|
116 |
5747 |
_quoteChar = '"';
|
117 |
5747 |
_quoteName = true;
|
118 |
5747 |
_indentChar = ' ';
|
119 |
5747 |
_indentation = 2;
|
120 |
5747 |
}
|
121 |
||
122 |
/// <summary> |
|
123 |
/// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. |
|
124 |
/// </summary> |
|
125 |
public override void Flush() |
|
126 |
{ |
|
127 |
1 |
_writer.Flush();
|
128 |
1 |
}
|
129 |
||
130 |
/// <summary> |
|
131 |
/// Closes this stream and the underlying stream. |
|
132 |
/// </summary> |
|
133 |
public override void Close() |
|
134 |
{ |
|
135 |
5656 |
base.Close();
|
136 |
||
137 |
5656 |
_writer.Close();
|
138 |
5656 |
}
|
139 |
||
140 |
/// <summary> |
|
141 |
/// Writes the beginning of a Json object. |
|
142 |
/// </summary> |
|
143 |
public override void WriteStartObject() |
|
144 |
{ |
|
145 |
26844 |
base.WriteStartObject();
|
146 |
||
147 |
26844 |
_writer.Write("{");
|
148 |
26844 |
}
|
149 |
||
150 |
/// <summary> |
|
151 |
/// Writes the beginning of a Json array. |
|
152 |
/// </summary> |
|
153 |
public override void WriteStartArray() |
|
154 |
{ |
|
155 |
10634 |
base.WriteStartArray();
|
156 |
||
157 |
10634 |
_writer.Write("[");
|
158 |
10634 |
}
|
159 |
||
160 |
/// <summary> |
|
161 |
/// Writes the start of a constructor with the given name. |
|
162 |
/// </summary> |
|
163 |
/// <param name="name">The name of the constructor.</param> |
|
164 |
public override void WriteStartConstructor(string name) |
|
165 |
{ |
|
166 |
13 |
base.WriteStartConstructor(name);
|
167 |
||
168 |
13 |
_writer.Write("new ");
|
169 |
13 |
_writer.Write(name);
|
170 |
13 |
_writer.Write("(");
|
171 |
13 |
}
|
172 |
||
173 |
/// <summary> |
|
174 |
/// Writes the specified end token. |
|
175 |
/// </summary> |
|
176 |
/// <param name="token">The end token to write.</param> |
|
177 |
protected override void WriteEnd(JsonToken token) |
|
178 |
{ |
|
179 |
37491 |
switch (token)
|
180 |
{ |
|
181 |
case JsonToken.EndObject: |
|
182 |
26844 |
_writer.Write("}");
|
183 |
26844 |
break;
|
184 |
case JsonToken.EndArray: |
|
185 |
10634 |
_writer.Write("]");
|
186 |
10634 |
break;
|
187 |
case JsonToken.EndConstructor: |
|
188 |
13 |
_writer.Write(")");
|
189 |
13 |
break;
|
190 |
default: |
|
191 |
0 |
throw new JsonWriterException("Invalid JsonToken: " + token);
|
192 |
} |
|
193 |
37491 |
}
|
194 |
||
195 |
/// <summary> |
|
196 |
/// Writes the property name of a name/value pair on a Json object. |
|
197 |
/// </summary> |
|
198 |
/// <param name="name">The name of the property.</param> |
|
199 |
public override void WritePropertyName(string name) |
|
200 |
{ |
|
201 |
101223 |
base.WritePropertyName(name);
|
202 |
||
203 |
101223 |
JavaScriptUtils.WriteEscapedJavaScriptString(_writer, name, _quoteChar, _quoteName);
|
204 |
||
205 |
101223 |
_writer.Write(':');
|
206 |
101223 |
}
|
207 |
||
208 |
/// <summary> |
|
209 |
/// Writes indent characters. |
|
210 |
/// </summary> |
|
211 |
protected override void WriteIndent() |
|
212 |
{ |
|
213 |
165315 |
if (Formatting == Formatting.Indented)
|
214 |
{ |
|
215 |
2437 |
_writer.Write(Environment.NewLine);
|
216 |
||
217 |
// levels of indentation multiplied by the indent count |
|
218 |
2437 |
int currentIndentCount = Top * _indentation;
|
219 |
||
220 |
2437 |
for (int i = 0; i < currentIndentCount; i++) |
221 |
{ |
|
222 |
10707 |
_writer.Write(_indentChar);
|
223 |
} |
|
224 |
} |
|
225 |
165315 |
}
|
226 |
||
227 |
/// <summary> |
|
228 |
/// Writes the JSON value delimiter. |
|
229 |
/// </summary> |
|
230 |
protected override void WriteValueDelimiter() |
|
231 |
{ |
|
232 |
90371 |
_writer.Write(',');
|
233 |
90371 |
}
|
234 |
||
235 |
/// <summary> |
|
236 |
/// Writes an indent space. |
|
237 |
/// </summary> |
|
238 |
protected override void WriteIndentSpace() |
|
239 |
{ |
|
240 |
1343 |
_writer.Write(' ');
|
241 |
1343 |
}
|
242 |
||
243 |
private void WriteValueInternal(string value, JsonToken token) |
|
244 |
{ |
|
245 |
31763 |
_writer.Write(value);
|
246 |
31763 |
}
|
247 |
||
248 |
#region WriteValue methods |
|
249 |
/// <summary> |
|
250 |
/// Writes a null value. |
|
251 |
/// </summary> |
|
252 |
public override void WriteNull() |
|
253 |
{ |
|
254 |
10556 |
base.WriteNull();
|
255 |
10556 |
WriteValueInternal(JsonConvert.Null, JsonToken.Null);
|
256 |
10556 |
}
|
257 |
||
258 |
/// <summary> |
|
259 |
/// Writes an undefined value. |
|
260 |
/// </summary> |
|
261 |
public override void WriteUndefined() |
|
262 |
{ |
|
263 |
3 |
base.WriteUndefined();
|
264 |
3 |
WriteValueInternal(JsonConvert.Undefined, JsonToken.Undefined);
|
265 |
3 |
}
|
266 |
||
267 |
/// <summary> |
|
268 |
/// Writes raw JSON. |
|
269 |
/// </summary> |
|
270 |
/// <param name="json">The raw JSON to write.</param> |
|
271 |
public override void WriteRaw(string json) |
|
272 |
{ |
|
273 |
20 |
base.WriteRaw(json);
|
274 |
||
275 |
20 |
_writer.Write(json);
|
276 |
20 |
}
|
277 |
||
278 |
/// <summary> |
|
279 |
/// Writes a <see cref="String"/> value. |
|
280 |
/// </summary> |
|
281 |
/// <param name="value">The <see cref="String"/> value to write.</param> |
|
282 |
public override void WriteValue(string value) |
|
283 |
{ |
|
284 |
43234 |
base.WriteValue(value);
|
285 |
43234 |
if (value == null)
|
286 |
2 |
WriteValueInternal(JsonConvert.Null, JsonToken.Null);
|
287 |
else |
|
288 |
43232 |
JavaScriptUtils.WriteEscapedJavaScriptString(_writer, value, _quoteChar, true);
|
289 |
43234 |
}
|
290 |
||
291 |
/// <summary> |
|
292 |
/// Writes a <see cref="Int32"/> value. |
|
293 |
/// </summary> |
|
294 |
/// <param name="value">The <see cref="Int32"/> value to write.</param> |
|
295 |
public override void WriteValue(int value) |
|
296 |
{ |
|
297 |
15778 |
base.WriteValue(value);
|
298 |
15778 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
|
299 |
15778 |
}
|
300 |
||
301 |
/// <summary> |
|
302 |
/// Writes a <see cref="UInt32"/> value. |
|
303 |
/// </summary> |
|
304 |
/// <param name="value">The <see cref="UInt32"/> value to write.</param> |
|
305 |
public override void WriteValue(uint value) |
|
306 |
{ |
|
307 |
3 |
base.WriteValue(value);
|
308 |
3 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
|
309 |
3 |
}
|
310 |
||
311 |
/// <summary> |
|
312 |
/// Writes a <see cref="Int64"/> value. |
|
313 |
/// </summary> |
|
314 |
/// <param name="value">The <see cref="Int64"/> value to write.</param> |
|
315 |
public override void WriteValue(long value) |
|
316 |
{ |
|
317 |
60 |
base.WriteValue(value);
|
318 |
60 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
|
319 |
60 |
}
|
320 |
||
321 |
/// <summary> |
|
322 |
/// Writes a <see cref="UInt64"/> value. |
|
323 |
/// </summary> |
|
324 |
/// <param name="value">The <see cref="UInt64"/> value to write.</param> |
|
325 |
public override void WriteValue(ulong value) |
|
326 |
{ |
|
327 |
3 |
base.WriteValue(value);
|
328 |
3 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
|
329 |
3 |
}
|
330 |
||
331 |
/// <summary> |
|
332 |
/// Writes a <see cref="Single"/> value. |
|
333 |
/// </summary> |
|
334 |
/// <param name="value">The <see cref="Single"/> value to write.</param> |
|
335 |
public override void WriteValue(float value) |
|
336 |
{ |
|
337 |
11 |
base.WriteValue(value);
|
338 |
11 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float);
|
339 |
11 |
}
|
340 |
||
341 |
/// <summary> |
|
342 |
/// Writes a <see cref="Double"/> value. |
|
343 |
/// </summary> |
|
344 |
/// <param name="value">The <see cref="Double"/> value to write.</param> |
|
345 |
public override void WriteValue(double value) |
|
346 |
{ |
|
347 |
35 |
base.WriteValue(value);
|
348 |
35 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float);
|
349 |
35 |
}
|
350 |
||
351 |
/// <summary> |
|
352 |
/// Writes a <see cref="Boolean"/> value. |
|
353 |
/// </summary> |
|
354 |
/// <param name="value">The <see cref="Boolean"/> value to write.</param> |
|
355 |
public override void WriteValue(bool value) |
|
356 |
{ |
|
357 |
37 |
base.WriteValue(value);
|
358 |
37 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Boolean);
|
359 |
37 |
}
|
360 |
||
361 |
/// <summary> |
|
362 |
/// Writes a <see cref="Int16"/> value. |
|
363 |
/// </summary> |
|
364 |
/// <param name="value">The <see cref="Int16"/> value to write.</param> |
|
365 |
public override void WriteValue(short value) |
|
366 |
{ |
|
367 |
5 |
base.WriteValue(value);
|
368 |
5 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
|
369 |
5 |
}
|
370 |
||
371 |
/// <summary> |
|
372 |
/// Writes a <see cref="UInt16"/> value. |
|
373 |
/// </summary> |
|
374 |
/// <param name="value">The <see cref="UInt16"/> value to write.</param> |
|
375 |
public override void WriteValue(ushort value) |
|
376 |
{ |
|
377 |
3 |
base.WriteValue(value);
|
378 |
3 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
|
379 |
3 |
}
|
380 |
||
381 |
/// <summary> |
|
382 |
/// Writes a <see cref="Char"/> value. |
|
383 |
/// </summary> |
|
384 |
/// <param name="value">The <see cref="Char"/> value to write.</param> |
|
385 |
public override void WriteValue(char value) |
|
386 |
{ |
|
387 |
9 |
base.WriteValue(value);
|
388 |
9 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
|
389 |
9 |
}
|
390 |
||
391 |
/// <summary> |
|
392 |
/// Writes a <see cref="Byte"/> value. |
|
393 |
/// </summary> |
|
394 |
/// <param name="value">The <see cref="Byte"/> value to write.</param> |
|
395 |
public override void WriteValue(byte value) |
|
396 |
{ |
|
397 |
4 |
base.WriteValue(value);
|
398 |
4 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
|
399 |
4 |
}
|
400 |
||
401 |
/// <summary> |
|
402 |
/// Writes a <see cref="SByte"/> value. |
|
403 |
/// </summary> |
|
404 |
/// <param name="value">The <see cref="SByte"/> value to write.</param> |
|
405 |
public override void WriteValue(sbyte value) |
|
406 |
{ |
|
407 |
3 |
base.WriteValue(value);
|
408 |
3 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
|
409 |
3 |
}
|
410 |
||
411 |
/// <summary> |
|
412 |
/// Writes a <see cref="Decimal"/> value. |
|
413 |
/// </summary> |
|
414 |
/// <param name="value">The <see cref="Decimal"/> value to write.</param> |
|
415 |
public override void WriteValue(decimal value) |
|
416 |
{ |
|
417 |
5245 |
base.WriteValue(value);
|
418 |
5245 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float);
|
419 |
5245 |
}
|
420 |
||
421 |
/// <summary> |
|
422 |
/// Writes a <see cref="DateTime"/> value. |
|
423 |
/// </summary> |
|
424 |
/// <param name="value">The <see cref="DateTime"/> value to write.</param> |
|
425 |
public override void WriteValue(DateTime value) |
|
426 |
{ |
|
427 |
20873 |
base.WriteValue(value);
|
428 |
20873 |
JsonConvert.WriteDateTimeString(_writer, value);
|
429 |
20873 |
}
|
430 |
||
431 |
/// <summary> |
|
432 |
/// Writes a <see cref="T:Byte[]"/> value. |
|
433 |
/// </summary> |
|
434 |
/// <param name="value">The <see cref="T:Byte[]"/> value to write.</param> |
|
435 |
public override void WriteValue(byte[] value) |
|
436 |
{ |
|
437 |
211 |
base.WriteValue(value);
|
438 |
||
439 |
211 |
if (value != null)
|
440 |
{ |
|
441 |
210 |
_writer.Write(_quoteChar);
|
442 |
210 |
Base64Encoder.Encode(value, 0, value.Length);
|
443 |
210 |
Base64Encoder.Flush();
|
444 |
210 |
_writer.Write(_quoteChar);
|
445 |
} |
|
446 |
211 |
}
|
447 |
||
448 |
#if !PocketPC && !NET20 |
|
449 |
/// <summary> |
|
450 |
/// Writes a <see cref="DateTimeOffset"/> value. |
|
451 |
/// </summary> |
|
452 |
/// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param> |
|
453 |
public override void WriteValue(DateTimeOffset value) |
|
454 |
{ |
|
455 |
6 |
base.WriteValue(value);
|
456 |
6 |
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Date);
|
457 |
6 |
}
|
458 |
#endif |
|
459 |
#endregion |
|
460 |
||
461 |
/// <summary> |
|
462 |
/// Writes out a comment <code>/*...*/</code> containing the specified text. |
|
463 |
/// </summary> |
|
464 |
/// <param name="text">Text to place inside the comment.</param> |
|
465 |
public override void WriteComment(string text) |
|
466 |
{ |
|
467 |
4 |
base.WriteComment(text);
|
468 |
||
469 |
4 |
_writer.Write("/*");
|
470 |
4 |
_writer.Write(text);
|
471 |
4 |
_writer.Write("*/");
|
472 |
4 |
}
|
473 |
||
474 |
/// <summary> |
|
475 |
/// Writes out the given white space. |
|
476 |
/// </summary> |
|
477 |
/// <param name="ws">The string of white space characters.</param> |
|
478 |
public override void WriteWhitespace(string ws) |
|
479 |
{ |
|
480 |
1 |
base.WriteWhitespace(ws);
|
481 |
||
482 |
1 |
_writer.Write(ws);
|
483 |
1 |
}
|
484 |
} |
|
485 |
} |