Json.NET
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


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
}