~ubuntu-branches/ubuntu/trusty/smuxi/trusty-proposed

« back to all changes in this revision

Viewing changes to lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriter.cs

  • Committer: Package Import Robot
  • Author(s): Mirco Bauer
  • Date: 2013-05-25 22:11:31 UTC
  • mfrom: (1.2.12)
  • Revision ID: package-import@ubuntu.com-20130525221131-nd2mc0kzubuwyx20
Tags: 0.8.11-1
* [22d13d5] Imported Upstream version 0.8.11
* [6d2b95a] Refreshed patches
* [89eb66e] Added ServiceStack libraries to smuxi-engine package
* [848ab10] Enable Campfire engine
* [c6dbdc7] Always build db4o for predictable build result
* [13ec489] Exclude OS X specific libraries from dh_clideps

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
using Newtonsoft.Json.Linq;
33
 
using System.Globalization;
34
 
 
35
 
namespace Newtonsoft.Json
36
 
{
37
 
  /// <summary>
38
 
  /// Specifies the state of the <see cref="JsonWriter"/>.
39
 
  /// </summary>
40
 
  public enum WriteState
41
 
  {
42
 
    /// <summary>
43
 
    /// An exception has been thrown, which has left the <see cref="JsonWriter"/> in an invalid state.
44
 
    /// You may call the <see cref="JsonWriter.Close"/> method to put the <see cref="JsonWriter"/> in the <c>Closed</c> state.
45
 
    /// Any other <see cref="JsonWriter"/> method calls results in an <see cref="InvalidOperationException"/> being thrown. 
46
 
    /// </summary>
47
 
    Error,
48
 
    /// <summary>
49
 
    /// The <see cref="JsonWriter.Close"/> method has been called. 
50
 
    /// </summary>
51
 
    Closed,
52
 
    /// <summary>
53
 
    /// An object is being written. 
54
 
    /// </summary>
55
 
    Object,
56
 
    /// <summary>
57
 
    /// A array is being written.
58
 
    /// </summary>
59
 
    Array,
60
 
    /// <summary>
61
 
    /// A constructor is being written.
62
 
    /// </summary>
63
 
    Constructor,
64
 
    /// <summary>
65
 
    /// A property is being written.
66
 
    /// </summary>
67
 
    Property,
68
 
    /// <summary>
69
 
    /// A write method has not been called.
70
 
    /// </summary>
71
 
    Start
72
 
  }
73
 
 
74
 
  /// <summary>
75
 
  /// Specifies formatting options for the <see cref="JsonTextWriter"/>.
76
 
  /// </summary>
77
 
  public enum Formatting
78
 
  {
79
 
    /// <summary>
80
 
    /// No special formatting is applied. This is the default.
81
 
    /// </summary>
82
 
    None,
83
 
    /// <summary>
84
 
    /// Causes child objects to be indented according to the <see cref="JsonTextWriter.Indentation"/> and <see cref="JsonTextWriter.IndentChar"/> settings.
85
 
    /// </summary>
86
 
    Indented
87
 
  }
88
 
 
89
 
  /// <summary>
90
 
  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
91
 
  /// </summary>
92
 
  public abstract class JsonWriter : IDisposable
93
 
  {
94
 
    private enum State
95
 
    {
96
 
      Start,
97
 
      Property,
98
 
      ObjectStart,
99
 
      Object,
100
 
      ArrayStart,
101
 
      Array,
102
 
      ConstructorStart,
103
 
      Constructor,
104
 
      Bytes,
105
 
      Closed,
106
 
      Error
107
 
    }
108
 
 
109
 
    // array that gives a new state based on the current state an the token being written
110
 
    private static readonly State[][] stateArray = new[] {
111
 
//                      Start                   PropertyName            ObjectStart         Object            ArrayStart              Array                   ConstructorStart        Constructor             Closed          Error
112
 
//                        
113
 
/* None             */new[]{ State.Error,            State.Error,            State.Error,        State.Error,      State.Error,            State.Error,            State.Error,            State.Error,            State.Error,    State.Error },
114
 
/* StartObject      */new[]{ State.ObjectStart,      State.ObjectStart,      State.Error,        State.Error,      State.ObjectStart,      State.ObjectStart,      State.ObjectStart,      State.ObjectStart,      State.Error,    State.Error },
115
 
/* StartArray       */new[]{ State.ArrayStart,       State.ArrayStart,       State.Error,        State.Error,      State.ArrayStart,       State.ArrayStart,       State.ArrayStart,       State.ArrayStart,       State.Error,    State.Error },
116
 
/* StartConstructor */new[]{ State.ConstructorStart, State.ConstructorStart, State.Error,        State.Error,      State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.Error,    State.Error },
117
 
/* StartProperty    */new[]{ State.Property,         State.Error,            State.Property,     State.Property,   State.Error,            State.Error,            State.Error,            State.Error,            State.Error,    State.Error },
118
 
/* Comment          */new[]{ State.Start,            State.Property,         State.ObjectStart,  State.Object,     State.ArrayStart,       State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error },
119
 
/* Raw              */new[]{ State.Start,            State.Property,         State.ObjectStart,  State.Object,     State.ArrayStart,       State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error },
120
 
/* Value            */new[]{ State.Start,            State.Object,           State.Error,        State.Error,      State.Array,            State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error },
121
 
                };
122
 
 
123
 
    private int _top;
124
 
 
125
 
    private readonly List<JTokenType> _stack;
126
 
    private State _currentState;
127
 
    private Formatting _formatting;
128
 
 
129
 
    /// <summary>
130
 
    /// Gets the top.
131
 
    /// </summary>
132
 
    /// <value>The top.</value>
133
 
    protected internal int Top
134
 
    {
135
 
      get { return _top; }
136
 
    }
137
 
 
138
 
    /// <summary>
139
 
    /// Gets the state of the writer.
140
 
    /// </summary>
141
 
    public WriteState WriteState
142
 
    {
143
 
      get
144
 
      {
145
 
        switch (_currentState)
146
 
        {
147
 
          case State.Error:
148
 
            return WriteState.Error;
149
 
          case State.Closed:
150
 
            return WriteState.Closed;
151
 
          case State.Object:
152
 
          case State.ObjectStart:
153
 
            return WriteState.Object;
154
 
          case State.Array:
155
 
          case State.ArrayStart:
156
 
            return WriteState.Array;
157
 
          case State.Constructor:
158
 
          case State.ConstructorStart:
159
 
            return WriteState.Constructor;
160
 
          case State.Property:
161
 
            return WriteState.Property;
162
 
          case State.Start:
163
 
            return WriteState.Start;
164
 
          default:
165
 
            throw new JsonWriterException("Invalid state: " + _currentState);
166
 
        }
167
 
      }
168
 
    }
169
 
 
170
 
    /// <summary>
171
 
    /// Indicates how the output is formatted.
172
 
    /// </summary>
173
 
    public Formatting Formatting
174
 
    {
175
 
      get { return _formatting; }
176
 
      set { _formatting = value; }
177
 
    }
178
 
 
179
 
    /// <summary>
180
 
    /// Creates an instance of the <c>JsonWriter</c> class. 
181
 
    /// </summary>
182
 
    public JsonWriter()
183
 
    {
184
 
      _stack = new List<JTokenType>(8);
185
 
      _stack.Add(JTokenType.None);
186
 
      _currentState = State.Start;
187
 
      _formatting = Formatting.None;
188
 
    }
189
 
 
190
 
    private void Push(JTokenType value)
191
 
    {
192
 
      _top++;
193
 
      if (_stack.Count <= _top)
194
 
        _stack.Add(value);
195
 
      else
196
 
        _stack[_top] = value;
197
 
    }
198
 
 
199
 
    private JTokenType Pop()
200
 
    {
201
 
      JTokenType value = Peek();
202
 
      _top--;
203
 
 
204
 
      return value;
205
 
    }
206
 
 
207
 
    private JTokenType Peek()
208
 
    {
209
 
      return _stack[_top];
210
 
    }
211
 
 
212
 
    /// <summary>
213
 
    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
214
 
    /// </summary>
215
 
    public abstract void Flush();
216
 
 
217
 
    /// <summary>
218
 
    /// Closes this stream and the underlying stream.
219
 
    /// </summary>
220
 
    public virtual void Close()
221
 
    {
222
 
      AutoCompleteAll();
223
 
    }
224
 
 
225
 
    /// <summary>
226
 
    /// Writes the beginning of a Json object.
227
 
    /// </summary>
228
 
    public virtual void WriteStartObject()
229
 
    {
230
 
      AutoComplete(JsonToken.StartObject);
231
 
      Push(JTokenType.Object);
232
 
    }
233
 
 
234
 
    /// <summary>
235
 
    /// Writes the end of a Json object.
236
 
    /// </summary>
237
 
    public void WriteEndObject()
238
 
    {
239
 
      AutoCompleteClose(JsonToken.EndObject);
240
 
    }
241
 
 
242
 
    /// <summary>
243
 
    /// Writes the beginning of a Json array.
244
 
    /// </summary>
245
 
    public virtual void WriteStartArray()
246
 
    {
247
 
      AutoComplete(JsonToken.StartArray);
248
 
      Push(JTokenType.Array);
249
 
    }
250
 
 
251
 
    /// <summary>
252
 
    /// Writes the end of an array.
253
 
    /// </summary>
254
 
    public void WriteEndArray()
255
 
    {
256
 
      AutoCompleteClose(JsonToken.EndArray);
257
 
    }
258
 
 
259
 
    /// <summary>
260
 
    /// Writes the start of a constructor with the given name.
261
 
    /// </summary>
262
 
    /// <param name="name">The name of the constructor.</param>
263
 
    public virtual void WriteStartConstructor(string name)
264
 
    {
265
 
      AutoComplete(JsonToken.StartConstructor);
266
 
      Push(JTokenType.Constructor);
267
 
    }
268
 
 
269
 
    /// <summary>
270
 
    /// Writes the end constructor.
271
 
    /// </summary>
272
 
    public void WriteEndConstructor()
273
 
    {
274
 
      AutoCompleteClose(JsonToken.EndConstructor);
275
 
    }
276
 
 
277
 
    /// <summary>
278
 
    /// Writes the property name of a name/value pair on a Json object.
279
 
    /// </summary>
280
 
    /// <param name="name">The name of the property.</param>
281
 
    public virtual void WritePropertyName(string name)
282
 
    {
283
 
      AutoComplete(JsonToken.PropertyName);
284
 
    }
285
 
 
286
 
    /// <summary>
287
 
    /// Writes the end of the current Json object or array.
288
 
    /// </summary>
289
 
    public void WriteEnd()
290
 
    {
291
 
      WriteEnd(Peek());
292
 
    }
293
 
 
294
 
    /// <summary>
295
 
    /// Writes the current <see cref="JsonReader"/> token.
296
 
    /// </summary>
297
 
    /// <param name="reader">The <see cref="JsonReader"/> to read the token from.</param>
298
 
    public void WriteToken(JsonReader reader)
299
 
    {
300
 
      ValidationUtils.ArgumentNotNull(reader, "reader");
301
 
 
302
 
      int initialDepth;
303
 
 
304
 
      if (reader.TokenType == JsonToken.None)
305
 
        initialDepth = -1;
306
 
      else if (!IsStartToken(reader.TokenType))
307
 
        initialDepth = reader.Depth + 1;
308
 
      else
309
 
        initialDepth = reader.Depth;
310
 
 
311
 
      WriteToken(reader, initialDepth);
312
 
    }
313
 
 
314
 
    internal void WriteToken(JsonReader reader, int initialDepth)
315
 
    {
316
 
      do
317
 
      {
318
 
        switch (reader.TokenType)
319
 
        {
320
 
          case JsonToken.None:
321
 
            // read to next
322
 
            break;
323
 
          case JsonToken.StartObject:
324
 
            WriteStartObject();
325
 
            break;
326
 
          case JsonToken.StartArray:
327
 
            WriteStartArray();
328
 
            break;
329
 
          case JsonToken.StartConstructor:
330
 
            string constructorName = reader.Value.ToString();
331
 
            // write a JValue date when the constructor is for a date
332
 
            if (string.Compare(constructorName, "Date", StringComparison.Ordinal) == 0)
333
 
              WriteConstructorDate(reader);
334
 
            else
335
 
              WriteStartConstructor(reader.Value.ToString());
336
 
            break;
337
 
          case JsonToken.PropertyName:
338
 
            WritePropertyName(reader.Value.ToString());
339
 
            break;
340
 
          case JsonToken.Comment:
341
 
            WriteComment(reader.Value.ToString());
342
 
            break;
343
 
          case JsonToken.Integer:
344
 
            WriteValue((long)reader.Value);
345
 
            break;
346
 
          case JsonToken.Float:
347
 
            WriteValue((double)reader.Value);
348
 
            break;
349
 
          case JsonToken.String:
350
 
            WriteValue(reader.Value.ToString());
351
 
            break;
352
 
          case JsonToken.Boolean:
353
 
            WriteValue((bool)reader.Value);
354
 
            break;
355
 
          case JsonToken.Null:
356
 
            WriteNull();
357
 
            break;
358
 
          case JsonToken.Undefined:
359
 
            WriteUndefined();
360
 
            break;
361
 
          case JsonToken.EndObject:
362
 
            WriteEndObject();
363
 
            break;
364
 
          case JsonToken.EndArray:
365
 
            WriteEndArray();
366
 
            break;
367
 
          case JsonToken.EndConstructor:
368
 
            WriteEndConstructor();
369
 
            break;
370
 
          case JsonToken.Date:
371
 
            WriteValue((DateTime)reader.Value);
372
 
            break;
373
 
          case JsonToken.Raw:
374
 
            WriteRawValue((string)reader.Value);
375
 
            break;
376
 
          case JsonToken.Bytes:
377
 
            WriteValue((byte[])reader.Value);
378
 
            break;
379
 
          default:
380
 
            throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", reader.TokenType, "Unexpected token type.");
381
 
        }
382
 
      }
383
 
      while (
384
 
        // stop if we have reached the end of the token being read
385
 
        initialDepth - 1 < reader.Depth - (IsEndToken(reader.TokenType) ? 1 : 0)
386
 
        && reader.Read());
387
 
    }
388
 
 
389
 
    private void WriteConstructorDate(JsonReader reader)
390
 
    {
391
 
      if (!reader.Read())
392
 
        throw new Exception("Unexpected end while reading date constructor.");
393
 
      if (reader.TokenType != JsonToken.Integer)
394
 
        throw new Exception("Unexpected token while reading date constructor. Expected Integer, got " + reader.TokenType);
395
 
 
396
 
      long ticks = (long)reader.Value;
397
 
      DateTime date = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks);
398
 
 
399
 
      if (!reader.Read())
400
 
        throw new Exception("Unexpected end while reading date constructor.");
401
 
      if (reader.TokenType != JsonToken.EndConstructor)
402
 
        throw new Exception("Unexpected token while reading date constructor. Expected EndConstructor, got " + reader.TokenType);
403
 
 
404
 
      WriteValue(date);
405
 
    }
406
 
 
407
 
    private bool IsEndToken(JsonToken token)
408
 
    {
409
 
      switch (token)
410
 
      {
411
 
        case JsonToken.EndObject:
412
 
        case JsonToken.EndArray:
413
 
        case JsonToken.EndConstructor:
414
 
          return true;
415
 
        default:
416
 
          return false;
417
 
      }
418
 
    }
419
 
 
420
 
    private bool IsStartToken(JsonToken token)
421
 
    {
422
 
      switch (token)
423
 
      {
424
 
        case JsonToken.StartObject:
425
 
        case JsonToken.StartArray:
426
 
        case JsonToken.StartConstructor:
427
 
          return true;
428
 
        default:
429
 
          return false;
430
 
      }
431
 
    }
432
 
 
433
 
    private void WriteEnd(JTokenType type)
434
 
    {
435
 
      switch (type)
436
 
      {
437
 
        case JTokenType.Object:
438
 
          WriteEndObject();
439
 
          break;
440
 
        case JTokenType.Array:
441
 
          WriteEndArray();
442
 
          break;
443
 
        case JTokenType.Constructor:
444
 
          WriteEndConstructor();
445
 
          break;
446
 
        default:
447
 
          throw new JsonWriterException("Unexpected type when writing end: " + type);
448
 
      }
449
 
    }
450
 
 
451
 
    private void AutoCompleteAll()
452
 
    {
453
 
      while (_top > 0)
454
 
      {
455
 
        WriteEnd();
456
 
      }
457
 
    }
458
 
 
459
 
    private JTokenType GetTypeForCloseToken(JsonToken token)
460
 
    {
461
 
      switch (token)
462
 
      {
463
 
        case JsonToken.EndObject:
464
 
          return JTokenType.Object;
465
 
        case JsonToken.EndArray:
466
 
          return JTokenType.Array;
467
 
        case JsonToken.EndConstructor:
468
 
          return JTokenType.Constructor;
469
 
        default:
470
 
          throw new JsonWriterException("No type for token: " + token);
471
 
      }
472
 
    }
473
 
 
474
 
    private JsonToken GetCloseTokenForType(JTokenType type)
475
 
    {
476
 
      switch (type)
477
 
      {
478
 
        case JTokenType.Object:
479
 
          return JsonToken.EndObject;
480
 
        case JTokenType.Array:
481
 
          return JsonToken.EndArray;
482
 
        case JTokenType.Constructor:
483
 
          return JsonToken.EndConstructor;
484
 
        default:
485
 
          throw new JsonWriterException("No close token for type: " + type);
486
 
      }
487
 
    }
488
 
 
489
 
    private void AutoCompleteClose(JsonToken tokenBeingClosed)
490
 
    {
491
 
      // write closing symbol and calculate new state
492
 
 
493
 
      int levelsToComplete = 0;
494
 
 
495
 
      for (int i = 0; i < _top; i++)
496
 
      {
497
 
        int currentLevel = _top - i;
498
 
 
499
 
        if (_stack[currentLevel] == GetTypeForCloseToken(tokenBeingClosed))
500
 
        {
501
 
          levelsToComplete = i + 1;
502
 
          break;
503
 
        }
504
 
      }
505
 
 
506
 
      if (levelsToComplete == 0)
507
 
        throw new JsonWriterException("No token to close.");
508
 
 
509
 
      for (int i = 0; i < levelsToComplete; i++)
510
 
      {
511
 
        JsonToken token = GetCloseTokenForType(Pop());
512
 
 
513
 
        if (_currentState != State.ObjectStart && _currentState != State.ArrayStart)
514
 
          WriteIndent();
515
 
 
516
 
        WriteEnd(token);
517
 
      }
518
 
 
519
 
      JTokenType currentLevelType = Peek();
520
 
 
521
 
      switch (currentLevelType)
522
 
      {
523
 
        case JTokenType.Object:
524
 
          _currentState = State.Object;
525
 
          break;
526
 
        case JTokenType.Array:
527
 
          _currentState = State.Array;
528
 
          break;
529
 
        case JTokenType.Constructor:
530
 
          _currentState = State.Array;
531
 
          break;
532
 
        case JTokenType.None:
533
 
          _currentState = State.Start;
534
 
          break;
535
 
        default:
536
 
          throw new JsonWriterException("Unknown JsonType: " + currentLevelType);
537
 
      }
538
 
    }
539
 
 
540
 
    /// <summary>
541
 
    /// Writes the specified end token.
542
 
    /// </summary>
543
 
    /// <param name="token">The end token to write.</param>
544
 
    protected virtual void WriteEnd(JsonToken token)
545
 
    {
546
 
    }
547
 
 
548
 
    /// <summary>
549
 
    /// Writes indent characters.
550
 
    /// </summary>
551
 
    protected virtual void WriteIndent()
552
 
    {
553
 
    }
554
 
 
555
 
    /// <summary>
556
 
    /// Writes the JSON value delimiter.
557
 
    /// </summary>
558
 
    protected virtual void WriteValueDelimiter()
559
 
    {
560
 
    }
561
 
 
562
 
    /// <summary>
563
 
    /// Writes an indent space.
564
 
    /// </summary>
565
 
    protected virtual void WriteIndentSpace()
566
 
    {
567
 
    }
568
 
 
569
 
    internal void AutoComplete(JsonToken tokenBeingWritten)
570
 
    {
571
 
      int token;
572
 
 
573
 
      switch (tokenBeingWritten)
574
 
      {
575
 
        default:
576
 
          token = (int)tokenBeingWritten;
577
 
          break;
578
 
        case JsonToken.Integer:
579
 
        case JsonToken.Float:
580
 
        case JsonToken.String:
581
 
        case JsonToken.Boolean:
582
 
        case JsonToken.Null:
583
 
        case JsonToken.Undefined:
584
 
        case JsonToken.Date:
585
 
        case JsonToken.Bytes:
586
 
          // a value is being written
587
 
          token = 7;
588
 
          break;
589
 
      }
590
 
 
591
 
      // gets new state based on the current state and what is being written
592
 
      State newState = stateArray[token][(int)_currentState];
593
 
 
594
 
      if (newState == State.Error)
595
 
        throw new JsonWriterException("Token {0} in state {1} would result in an invalid JavaScript object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), _currentState.ToString()));
596
 
 
597
 
      if ((_currentState == State.Object || _currentState == State.Array || _currentState == State.Constructor) && tokenBeingWritten != JsonToken.Comment)
598
 
      {
599
 
        WriteValueDelimiter();
600
 
      }
601
 
      else if (_currentState == State.Property)
602
 
      {
603
 
        if (_formatting == Formatting.Indented)
604
 
          WriteIndentSpace();
605
 
      }
606
 
 
607
 
      WriteState writeState = WriteState;
608
 
 
609
 
      // don't indent a property when it is the first token to be written (i.e. at the start)
610
 
      if ((tokenBeingWritten == JsonToken.PropertyName && writeState != WriteState.Start) ||
611
 
        writeState == WriteState.Array || writeState == WriteState.Constructor)
612
 
      {
613
 
        WriteIndent();
614
 
      }
615
 
 
616
 
      _currentState = newState;
617
 
    }
618
 
 
619
 
    #region WriteValue methods
620
 
    /// <summary>
621
 
    /// Writes a null value.
622
 
    /// </summary>
623
 
    public virtual void WriteNull()
624
 
    {
625
 
      AutoComplete(JsonToken.Null);
626
 
    }
627
 
 
628
 
    /// <summary>
629
 
    /// Writes an undefined value.
630
 
    /// </summary>
631
 
    public virtual void WriteUndefined()
632
 
    {
633
 
      AutoComplete(JsonToken.Undefined);
634
 
    }
635
 
 
636
 
    /// <summary>
637
 
    /// Writes raw JSON without changing the writer's state.
638
 
    /// </summary>
639
 
    /// <param name="json">The raw JSON to write.</param>
640
 
    public virtual void WriteRaw(string json)
641
 
    {
642
 
    }
643
 
 
644
 
    /// <summary>
645
 
    /// Writes raw JSON where a value is expected and updates the writer's state.
646
 
    /// </summary>
647
 
    /// <param name="json">The raw JSON to write.</param>
648
 
    public virtual void WriteRawValue(string json)
649
 
    {
650
 
      // hack. want writer to change state as if a value had been written
651
 
      AutoComplete(JsonToken.Undefined);
652
 
      WriteRaw(json);
653
 
    }
654
 
 
655
 
    /// <summary>
656
 
    /// Writes a <see cref="String"/> value.
657
 
    /// </summary>
658
 
    /// <param name="value">The <see cref="String"/> value to write.</param>
659
 
    public virtual void WriteValue(string value)
660
 
    {
661
 
      AutoComplete(JsonToken.String);
662
 
    }
663
 
 
664
 
    /// <summary>
665
 
    /// Writes a <see cref="Int32"/> value.
666
 
    /// </summary>
667
 
    /// <param name="value">The <see cref="Int32"/> value to write.</param>
668
 
    public virtual void WriteValue(int value)
669
 
    {
670
 
      AutoComplete(JsonToken.Integer);
671
 
    }
672
 
 
673
 
    /// <summary>
674
 
    /// Writes a <see cref="UInt32"/> value.
675
 
    /// </summary>
676
 
    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
677
 
    [CLSCompliant(false)]
678
 
    public virtual void WriteValue(uint value)
679
 
    {
680
 
      AutoComplete(JsonToken.Integer);
681
 
    }
682
 
 
683
 
    /// <summary>
684
 
    /// Writes a <see cref="Int64"/> value.
685
 
    /// </summary>
686
 
    /// <param name="value">The <see cref="Int64"/> value to write.</param>
687
 
    public virtual void WriteValue(long value)
688
 
    {
689
 
      AutoComplete(JsonToken.Integer);
690
 
    }
691
 
 
692
 
    /// <summary>
693
 
    /// Writes a <see cref="UInt64"/> value.
694
 
    /// </summary>
695
 
    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
696
 
    [CLSCompliant(false)]
697
 
    public virtual void WriteValue(ulong value)
698
 
    {
699
 
      AutoComplete(JsonToken.Integer);
700
 
    }
701
 
 
702
 
    /// <summary>
703
 
    /// Writes a <see cref="Single"/> value.
704
 
    /// </summary>
705
 
    /// <param name="value">The <see cref="Single"/> value to write.</param>
706
 
    public virtual void WriteValue(float value)
707
 
    {
708
 
      AutoComplete(JsonToken.Float);
709
 
    }
710
 
 
711
 
    /// <summary>
712
 
    /// Writes a <see cref="Double"/> value.
713
 
    /// </summary>
714
 
    /// <param name="value">The <see cref="Double"/> value to write.</param>
715
 
    public virtual void WriteValue(double value)
716
 
    {
717
 
      AutoComplete(JsonToken.Float);
718
 
    }
719
 
 
720
 
    /// <summary>
721
 
    /// Writes a <see cref="Boolean"/> value.
722
 
    /// </summary>
723
 
    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
724
 
    public virtual void WriteValue(bool value)
725
 
    {
726
 
      AutoComplete(JsonToken.Boolean);
727
 
    }
728
 
 
729
 
    /// <summary>
730
 
    /// Writes a <see cref="Int16"/> value.
731
 
    /// </summary>
732
 
    /// <param name="value">The <see cref="Int16"/> value to write.</param>
733
 
    public virtual void WriteValue(short value)
734
 
    {
735
 
      AutoComplete(JsonToken.Integer);
736
 
    }
737
 
 
738
 
    /// <summary>
739
 
    /// Writes a <see cref="UInt16"/> value.
740
 
    /// </summary>
741
 
    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
742
 
    [CLSCompliant(false)]
743
 
    public virtual void WriteValue(ushort value)
744
 
    {
745
 
      AutoComplete(JsonToken.Integer);
746
 
    }
747
 
 
748
 
    /// <summary>
749
 
    /// Writes a <see cref="Char"/> value.
750
 
    /// </summary>
751
 
    /// <param name="value">The <see cref="Char"/> value to write.</param>
752
 
    public virtual void WriteValue(char value)
753
 
    {
754
 
      AutoComplete(JsonToken.String);
755
 
    }
756
 
 
757
 
    /// <summary>
758
 
    /// Writes a <see cref="Byte"/> value.
759
 
    /// </summary>
760
 
    /// <param name="value">The <see cref="Byte"/> value to write.</param>
761
 
    public virtual void WriteValue(byte value)
762
 
    {
763
 
      AutoComplete(JsonToken.Integer);
764
 
    }
765
 
 
766
 
    /// <summary>
767
 
    /// Writes a <see cref="SByte"/> value.
768
 
    /// </summary>
769
 
    /// <param name="value">The <see cref="SByte"/> value to write.</param>
770
 
    [CLSCompliant(false)]
771
 
    public virtual void WriteValue(sbyte value)
772
 
    {
773
 
      AutoComplete(JsonToken.Integer);
774
 
    }
775
 
 
776
 
    /// <summary>
777
 
    /// Writes a <see cref="Decimal"/> value.
778
 
    /// </summary>
779
 
    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
780
 
    public virtual void WriteValue(decimal value)
781
 
    {
782
 
      AutoComplete(JsonToken.Float);
783
 
    }
784
 
 
785
 
    /// <summary>
786
 
    /// Writes a <see cref="DateTime"/> value.
787
 
    /// </summary>
788
 
    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
789
 
    public virtual void WriteValue(DateTime value)
790
 
    {
791
 
      AutoComplete(JsonToken.Date);
792
 
    }
793
 
 
794
 
#if !PocketPC && !NET20
795
 
    /// <summary>
796
 
    /// Writes a <see cref="DateTimeOffset"/> value.
797
 
    /// </summary>
798
 
    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
799
 
    public virtual void WriteValue(DateTimeOffset value)
800
 
    {
801
 
      AutoComplete(JsonToken.Date);
802
 
    }
803
 
#endif
804
 
 
805
 
    /// <summary>
806
 
    /// Writes a <see cref="Nullable{Int32}"/> value.
807
 
    /// </summary>
808
 
    /// <param name="value">The <see cref="Nullable{Int32}"/> value to write.</param>
809
 
    public virtual void WriteValue(int? value)
810
 
    {
811
 
      if (value == null)
812
 
        WriteNull();
813
 
      else
814
 
        WriteValue(value.Value);
815
 
    }
816
 
 
817
 
    /// <summary>
818
 
    /// Writes a <see cref="Nullable{UInt32}"/> value.
819
 
    /// </summary>
820
 
    /// <param name="value">The <see cref="Nullable{UInt32}"/> value to write.</param>
821
 
    [CLSCompliant(false)]
822
 
    public virtual void WriteValue(uint? value)
823
 
    {
824
 
      if (value == null)
825
 
        WriteNull();
826
 
      else
827
 
        WriteValue(value.Value);
828
 
    }
829
 
 
830
 
    /// <summary>
831
 
    /// Writes a <see cref="Nullable{Int64}"/> value.
832
 
    /// </summary>
833
 
    /// <param name="value">The <see cref="Nullable{Int64}"/> value to write.</param>
834
 
    public virtual void WriteValue(long? value)
835
 
    {
836
 
      if (value == null)
837
 
        WriteNull();
838
 
      else
839
 
        WriteValue(value.Value);
840
 
    }
841
 
 
842
 
    /// <summary>
843
 
    /// Writes a <see cref="Nullable{UInt64}"/> value.
844
 
    /// </summary>
845
 
    /// <param name="value">The <see cref="Nullable{UInt64}"/> value to write.</param>
846
 
    [CLSCompliant(false)]
847
 
    public virtual void WriteValue(ulong? value)
848
 
    {
849
 
      if (value == null)
850
 
        WriteNull();
851
 
      else
852
 
        WriteValue(value.Value);
853
 
    }
854
 
 
855
 
    /// <summary>
856
 
    /// Writes a <see cref="Nullable{Single}"/> value.
857
 
    /// </summary>
858
 
    /// <param name="value">The <see cref="Nullable{Single}"/> value to write.</param>
859
 
    public virtual void WriteValue(float? value)
860
 
    {
861
 
      if (value == null)
862
 
        WriteNull();
863
 
      else
864
 
        WriteValue(value.Value);
865
 
    }
866
 
 
867
 
    /// <summary>
868
 
    /// Writes a <see cref="Nullable{Double}"/> value.
869
 
    /// </summary>
870
 
    /// <param name="value">The <see cref="Nullable{Double}"/> value to write.</param>
871
 
    public virtual void WriteValue(double? value)
872
 
    {
873
 
      if (value == null)
874
 
        WriteNull();
875
 
      else
876
 
        WriteValue(value.Value);
877
 
    }
878
 
 
879
 
    /// <summary>
880
 
    /// Writes a <see cref="Nullable{Boolean}"/> value.
881
 
    /// </summary>
882
 
    /// <param name="value">The <see cref="Nullable{Boolean}"/> value to write.</param>
883
 
    public virtual void WriteValue(bool? value)
884
 
    {
885
 
      if (value == null)
886
 
        WriteNull();
887
 
      else
888
 
        WriteValue(value.Value);
889
 
    }
890
 
 
891
 
    /// <summary>
892
 
    /// Writes a <see cref="Nullable{Int16}"/> value.
893
 
    /// </summary>
894
 
    /// <param name="value">The <see cref="Nullable{Int16}"/> value to write.</param>
895
 
    public virtual void WriteValue(short? value)
896
 
    {
897
 
      if (value == null)
898
 
        WriteNull();
899
 
      else
900
 
        WriteValue(value.Value);
901
 
    }
902
 
 
903
 
    /// <summary>
904
 
    /// Writes a <see cref="Nullable{UInt16}"/> value.
905
 
    /// </summary>
906
 
    /// <param name="value">The <see cref="Nullable{UInt16}"/> value to write.</param>
907
 
    [CLSCompliant(false)]
908
 
    public virtual void WriteValue(ushort? value)
909
 
    {
910
 
      if (value == null)
911
 
        WriteNull();
912
 
      else
913
 
        WriteValue(value.Value);
914
 
    }
915
 
 
916
 
    /// <summary>
917
 
    /// Writes a <see cref="Nullable{Char}"/> value.
918
 
    /// </summary>
919
 
    /// <param name="value">The <see cref="Nullable{Char}"/> value to write.</param>
920
 
    public virtual void WriteValue(char? value)
921
 
    {
922
 
      if (value == null)
923
 
        WriteNull();
924
 
      else
925
 
        WriteValue(value.Value);
926
 
    }
927
 
 
928
 
    /// <summary>
929
 
    /// Writes a <see cref="Nullable{Byte}"/> value.
930
 
    /// </summary>
931
 
    /// <param name="value">The <see cref="Nullable{Byte}"/> value to write.</param>
932
 
    public virtual void WriteValue(byte? value)
933
 
    {
934
 
      if (value == null)
935
 
        WriteNull();
936
 
      else
937
 
        WriteValue(value.Value);
938
 
    }
939
 
 
940
 
    /// <summary>
941
 
    /// Writes a <see cref="Nullable{SByte}"/> value.
942
 
    /// </summary>
943
 
    /// <param name="value">The <see cref="Nullable{SByte}"/> value to write.</param>
944
 
    [CLSCompliant(false)]
945
 
    public virtual void WriteValue(sbyte? value)
946
 
    {
947
 
      if (value == null)
948
 
        WriteNull();
949
 
      else
950
 
        WriteValue(value.Value);
951
 
    }
952
 
 
953
 
    /// <summary>
954
 
    /// Writes a <see cref="Nullable{Decimal}"/> value.
955
 
    /// </summary>
956
 
    /// <param name="value">The <see cref="Nullable{Decimal}"/> value to write.</param>
957
 
    public virtual void WriteValue(decimal? value)
958
 
    {
959
 
      if (value == null)
960
 
        WriteNull();
961
 
      else
962
 
        WriteValue(value.Value);
963
 
    }
964
 
 
965
 
    /// <summary>
966
 
    /// Writes a <see cref="Nullable{DateTime}"/> value.
967
 
    /// </summary>
968
 
    /// <param name="value">The <see cref="Nullable{DateTime}"/> value to write.</param>
969
 
    public virtual void WriteValue(DateTime? value)
970
 
    {
971
 
      if (value == null)
972
 
        WriteNull();
973
 
      else
974
 
        WriteValue(value.Value);
975
 
    }
976
 
 
977
 
#if !PocketPC && !NET20
978
 
    /// <summary>
979
 
    /// Writes a <see cref="Nullable{DateTimeOffset}"/> value.
980
 
    /// </summary>
981
 
    /// <param name="value">The <see cref="Nullable{DateTimeOffset}"/> value to write.</param>
982
 
    public virtual void WriteValue(DateTimeOffset? value)
983
 
    {
984
 
      if (value == null)
985
 
        WriteNull();
986
 
      else
987
 
        WriteValue(value.Value);
988
 
    }
989
 
#endif
990
 
 
991
 
    /// <summary>
992
 
    /// Writes a <see cref="T:Byte[]"/> value.
993
 
    /// </summary>
994
 
    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
995
 
    public virtual void WriteValue(byte[] value)
996
 
    {
997
 
      if (value == null)
998
 
        WriteNull();
999
 
      else
1000
 
        AutoComplete(JsonToken.Bytes);
1001
 
    }
1002
 
 
1003
 
    /// <summary>
1004
 
    /// Writes a <see cref="Object"/> value.
1005
 
    /// An error will raised if the value cannot be written as a single JSON token.
1006
 
    /// </summary>
1007
 
    /// <param name="value">The <see cref="Object"/> value to write.</param>
1008
 
    public virtual void WriteValue(object value)
1009
 
    {
1010
 
      if (value == null)
1011
 
      {
1012
 
        WriteNull();
1013
 
        return;
1014
 
      }
1015
 
      else if (value is IConvertible)
1016
 
      {
1017
 
        IConvertible convertible = value as IConvertible;
1018
 
 
1019
 
        switch (convertible.GetTypeCode())
1020
 
        {
1021
 
          case TypeCode.String:
1022
 
            WriteValue(convertible.ToString(CultureInfo.InvariantCulture));
1023
 
            return;
1024
 
          case TypeCode.Char:
1025
 
            WriteValue(convertible.ToChar(CultureInfo.InvariantCulture));
1026
 
            return;
1027
 
          case TypeCode.Boolean:
1028
 
            WriteValue(convertible.ToBoolean(CultureInfo.InvariantCulture));
1029
 
            return;
1030
 
          case TypeCode.SByte:
1031
 
            WriteValue(convertible.ToSByte(CultureInfo.InvariantCulture));
1032
 
            return;
1033
 
          case TypeCode.Int16:
1034
 
            WriteValue(convertible.ToInt16(CultureInfo.InvariantCulture));
1035
 
            return;
1036
 
          case TypeCode.UInt16:
1037
 
            WriteValue(convertible.ToUInt16(CultureInfo.InvariantCulture));
1038
 
            return;
1039
 
          case TypeCode.Int32:
1040
 
            WriteValue(convertible.ToInt32(CultureInfo.InvariantCulture));
1041
 
            return;
1042
 
          case TypeCode.Byte:
1043
 
            WriteValue(convertible.ToByte(CultureInfo.InvariantCulture));
1044
 
            return;
1045
 
          case TypeCode.UInt32:
1046
 
            WriteValue(convertible.ToUInt32(CultureInfo.InvariantCulture));
1047
 
            return;
1048
 
          case TypeCode.Int64:
1049
 
            WriteValue(convertible.ToInt64(CultureInfo.InvariantCulture));
1050
 
            return;
1051
 
          case TypeCode.UInt64:
1052
 
            WriteValue(convertible.ToUInt64(CultureInfo.InvariantCulture));
1053
 
            return;
1054
 
          case TypeCode.Single:
1055
 
            WriteValue(convertible.ToSingle(CultureInfo.InvariantCulture));
1056
 
            return;
1057
 
          case TypeCode.Double:
1058
 
            WriteValue(convertible.ToDouble(CultureInfo.InvariantCulture));
1059
 
            return;
1060
 
          case TypeCode.DateTime:
1061
 
            WriteValue(convertible.ToDateTime(CultureInfo.InvariantCulture));
1062
 
            return;
1063
 
          case TypeCode.Decimal:
1064
 
            WriteValue(convertible.ToDecimal(CultureInfo.InvariantCulture));
1065
 
            return;
1066
 
          case TypeCode.DBNull:
1067
 
            WriteNull();
1068
 
            return;
1069
 
        }
1070
 
      }
1071
 
#if !PocketPC && !NET20
1072
 
      else if (value is DateTimeOffset)
1073
 
      {
1074
 
        WriteValue((DateTimeOffset)value);
1075
 
        return;
1076
 
      }
1077
 
#endif
1078
 
      else if (value is byte[])
1079
 
      {
1080
 
        WriteValue((byte[])value);
1081
 
        return;
1082
 
      }
1083
 
 
1084
 
      throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
1085
 
    }
1086
 
    #endregion
1087
 
 
1088
 
    /// <summary>
1089
 
    /// Writes out a comment <code>/*...*/</code> containing the specified text. 
1090
 
    /// </summary>
1091
 
    /// <param name="text">Text to place inside the comment.</param>
1092
 
    public virtual void WriteComment(string text)
1093
 
    {
1094
 
      AutoComplete(JsonToken.Comment);
1095
 
    }
1096
 
 
1097
 
    /// <summary>
1098
 
    /// Writes out the given white space.
1099
 
    /// </summary>
1100
 
    /// <param name="ws">The string of white space characters.</param>
1101
 
    public virtual void WriteWhitespace(string ws)
1102
 
    {
1103
 
      if (ws != null)
1104
 
      {
1105
 
        if (!StringUtils.IsWhiteSpace(ws))
1106
 
          throw new JsonWriterException("Only white space characters should be used.");
1107
 
      }
1108
 
    }
1109
 
 
1110
 
 
1111
 
    void IDisposable.Dispose()
1112
 
    {
1113
 
      Dispose(true);
1114
 
    }
1115
 
 
1116
 
    private void Dispose(bool disposing)
1117
 
    {
1118
 
      if (WriteState != WriteState.Closed)
1119
 
        Close();
1120
 
    }
1121
 
  }
 
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.IO;
 
29
using Newtonsoft.Json.Utilities;
 
30
using System.Globalization;
 
31
#if NETFX_CORE
 
32
using IConvertible = Newtonsoft.Json.Utilities.Convertible;
 
33
#endif
 
34
#if NET20
 
35
using Newtonsoft.Json.Utilities.LinqBridge;
 
36
#else
 
37
using System.Linq;
 
38
#endif
 
39
 
 
40
namespace Newtonsoft.Json
 
41
{
 
42
  /// <summary>
 
43
  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
 
44
  /// </summary>
 
45
  public abstract class JsonWriter : IDisposable
 
46
  {
 
47
    internal enum State
 
48
    {
 
49
      Start,
 
50
      Property,
 
51
      ObjectStart,
 
52
      Object,
 
53
      ArrayStart,
 
54
      Array,
 
55
      ConstructorStart,
 
56
      Constructor,
 
57
      Bytes,
 
58
      Closed,
 
59
      Error
 
60
    }
 
61
 
 
62
    // array that gives a new state based on the current state an the token being written
 
63
    private static readonly State[][] StateArray;
 
64
 
 
65
    internal static readonly State[][] StateArrayTempate = new[] {
 
66
//                                      Start                   PropertyName            ObjectStart         Object            ArrayStart              Array                   ConstructorStart        Constructor             Closed          Error
 
67
//                        
 
68
/* None                        */new[]{ State.Error,            State.Error,            State.Error,        State.Error,      State.Error,            State.Error,            State.Error,            State.Error,            State.Error,    State.Error },
 
69
/* StartObject                 */new[]{ State.ObjectStart,      State.ObjectStart,      State.Error,        State.Error,      State.ObjectStart,      State.ObjectStart,      State.ObjectStart,      State.ObjectStart,      State.Error,    State.Error },
 
70
/* StartArray                  */new[]{ State.ArrayStart,       State.ArrayStart,       State.Error,        State.Error,      State.ArrayStart,       State.ArrayStart,       State.ArrayStart,       State.ArrayStart,       State.Error,    State.Error },
 
71
/* StartConstructor            */new[]{ State.ConstructorStart, State.ConstructorStart, State.Error,        State.Error,      State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.Error,    State.Error },
 
72
/* StartProperty               */new[]{ State.Property,         State.Error,            State.Property,     State.Property,   State.Error,            State.Error,            State.Error,            State.Error,            State.Error,    State.Error },
 
73
/* Comment                     */new[]{ State.Start,            State.Property,         State.ObjectStart,  State.Object,     State.ArrayStart,       State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error },
 
74
/* Raw                         */new[]{ State.Start,            State.Property,         State.ObjectStart,  State.Object,     State.ArrayStart,       State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error },
 
75
/* Value (this will be copied) */new[]{ State.Start,            State.Object,           State.Error,        State.Error,      State.Array,            State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error }
 
76
                };
 
77
 
 
78
    internal static State[][] BuildStateArray()
 
79
    {
 
80
      var allStates = StateArrayTempate.ToList();
 
81
      var errorStates = StateArrayTempate[0];
 
82
      var valueStates = StateArrayTempate[7];
 
83
 
 
84
      foreach (JsonToken valueToken in EnumUtils.GetValues(typeof(JsonToken)))
 
85
      {
 
86
        if (allStates.Count <= (int)valueToken)
 
87
        {
 
88
          switch (valueToken)
 
89
          {
 
90
            case JsonToken.Integer:
 
91
            case JsonToken.Float:
 
92
            case JsonToken.String:
 
93
            case JsonToken.Boolean:
 
94
            case JsonToken.Null:
 
95
            case JsonToken.Undefined:
 
96
            case JsonToken.Date:
 
97
            case JsonToken.Bytes:
 
98
              allStates.Add(valueStates);
 
99
              break;
 
100
            default:
 
101
              allStates.Add(errorStates);
 
102
              break;
 
103
          }
 
104
        }
 
105
      }
 
106
 
 
107
      return allStates.ToArray();
 
108
    }
 
109
 
 
110
    static JsonWriter()
 
111
    {
 
112
      StateArray = BuildStateArray();
 
113
    }
 
114
 
 
115
    private readonly List<JsonPosition> _stack;
 
116
    private JsonPosition _currentPosition;
 
117
    private State _currentState;
 
118
    private Formatting _formatting;
 
119
 
 
120
    /// <summary>
 
121
    /// Gets or sets a value indicating whether the underlying stream or
 
122
    /// <see cref="TextReader"/> should be closed when the writer is closed.
 
123
    /// </summary>
 
124
    /// <value>
 
125
    /// true to close the underlying stream or <see cref="TextReader"/> when
 
126
    /// the writer is closed; otherwise false. The default is true.
 
127
    /// </value>
 
128
    public bool CloseOutput { get; set; }
 
129
 
 
130
    /// <summary>
 
131
    /// Gets the top.
 
132
    /// </summary>
 
133
    /// <value>The top.</value>
 
134
    protected internal int Top
 
135
    {
 
136
      get
 
137
      {
 
138
        int depth = _stack.Count;
 
139
        if (Peek() != JsonContainerType.None)
 
140
          depth++;
 
141
 
 
142
        return depth;
 
143
      }
 
144
    }
 
145
 
 
146
    internal string ContainerPath
 
147
    {
 
148
      get
 
149
      {
 
150
        if (_currentPosition.Type == JsonContainerType.None)
 
151
          return string.Empty;
 
152
 
 
153
        IEnumerable<JsonPosition> positions = (_currentPosition.InsideContainer())
 
154
          ? _stack
 
155
          : _stack.Concat(new[] { _currentPosition });
 
156
 
 
157
        return JsonPosition.BuildPath(positions);
 
158
      }
 
159
    }
 
160
    
 
161
    /// <summary>
 
162
    /// Gets the state of the writer.
 
163
    /// </summary>
 
164
    public WriteState WriteState
 
165
    {
 
166
      get
 
167
      {
 
168
        switch (_currentState)
 
169
        {
 
170
          case State.Error:
 
171
            return WriteState.Error;
 
172
          case State.Closed:
 
173
            return WriteState.Closed;
 
174
          case State.Object:
 
175
          case State.ObjectStart:
 
176
            return WriteState.Object;
 
177
          case State.Array:
 
178
          case State.ArrayStart:
 
179
            return WriteState.Array;
 
180
          case State.Constructor:
 
181
          case State.ConstructorStart:
 
182
            return WriteState.Constructor;
 
183
          case State.Property:
 
184
            return WriteState.Property;
 
185
          case State.Start:
 
186
            return WriteState.Start;
 
187
          default:
 
188
            throw JsonWriterException.Create(this, "Invalid state: " + _currentState, null);
 
189
        }
 
190
      }
 
191
    }
 
192
 
 
193
    /// <summary>
 
194
    /// Gets the path of the writer. 
 
195
    /// </summary>
 
196
    public string Path
 
197
    {
 
198
      get
 
199
      {
 
200
        if (_currentPosition.Type == JsonContainerType.None)
 
201
          return string.Empty;
 
202
 
 
203
        return JsonPosition.BuildPath(_stack.Concat(new[] { _currentPosition }));
 
204
      }
 
205
    }
 
206
 
 
207
    private DateFormatHandling _dateFormatHandling;
 
208
    private DateTimeZoneHandling _dateTimeZoneHandling;
 
209
 
 
210
    /// <summary>
 
211
    /// Indicates how JSON text output is formatted.
 
212
    /// </summary>
 
213
    public Formatting Formatting
 
214
    {
 
215
      get { return _formatting; }
 
216
      set { _formatting = value; }
 
217
    }
 
218
 
 
219
    /// <summary>
 
220
    /// Get or set how dates are written to JSON text.
 
221
    /// </summary>
 
222
    public DateFormatHandling DateFormatHandling
 
223
    {
 
224
      get { return _dateFormatHandling; }
 
225
      set { _dateFormatHandling = value; }
 
226
    }
 
227
 
 
228
    /// <summary>
 
229
    /// Get or set how <see cref="DateTime"/> time zones are handling when writing JSON.
 
230
    /// </summary>
 
231
    public DateTimeZoneHandling DateTimeZoneHandling
 
232
    {
 
233
      get { return _dateTimeZoneHandling; }
 
234
      set { _dateTimeZoneHandling = value; }
 
235
    }
 
236
 
 
237
    /// <summary>
 
238
    /// Creates an instance of the <c>JsonWriter</c> class. 
 
239
    /// </summary>
 
240
    protected JsonWriter()
 
241
    {
 
242
      _stack = new List<JsonPosition>(4);
 
243
      _currentState = State.Start;
 
244
      _formatting = Formatting.None;
 
245
      _dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
 
246
 
 
247
      CloseOutput = true;
 
248
    }
 
249
 
 
250
    private void UpdateScopeWithFinishedValue()
 
251
    {
 
252
      if (_currentPosition.Type == JsonContainerType.Array
 
253
        || _currentPosition.Type == JsonContainerType.Constructor)
 
254
      {
 
255
        if (_currentPosition.Position == null)
 
256
          _currentPosition.Position = 0;
 
257
        else
 
258
          _currentPosition.Position++;
 
259
      }
 
260
    }
 
261
 
 
262
    private void Push(JsonContainerType value)
 
263
    {
 
264
      UpdateScopeWithFinishedValue();
 
265
 
 
266
      if (_currentPosition.Type == JsonContainerType.None)
 
267
      {
 
268
        _currentPosition.Type = value;
 
269
      }
 
270
      else
 
271
      {
 
272
        _stack.Add(_currentPosition);
 
273
        var state = new JsonPosition
 
274
        {
 
275
          Type = value
 
276
        };
 
277
        _currentPosition = state;
 
278
      }
 
279
    }
 
280
 
 
281
    private JsonContainerType Pop()
 
282
    {
 
283
      JsonPosition oldPosition;
 
284
      if (_stack.Count > 0)
 
285
      {
 
286
        oldPosition = _currentPosition;
 
287
        _currentPosition = _stack[_stack.Count - 1];
 
288
        _stack.RemoveAt(_stack.Count - 1);
 
289
      }
 
290
      else
 
291
      {
 
292
        oldPosition = _currentPosition;
 
293
        _currentPosition = new JsonPosition();
 
294
      }
 
295
 
 
296
      return oldPosition.Type;
 
297
    }
 
298
 
 
299
    private JsonContainerType Peek()
 
300
    {
 
301
      return _currentPosition.Type;
 
302
    }
 
303
 
 
304
    /// <summary>
 
305
    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
 
306
    /// </summary>
 
307
    public abstract void Flush();
 
308
 
 
309
    /// <summary>
 
310
    /// Closes this stream and the underlying stream.
 
311
    /// </summary>
 
312
    public virtual void Close()
 
313
    {
 
314
      AutoCompleteAll();
 
315
    }
 
316
 
 
317
    /// <summary>
 
318
    /// Writes the beginning of a Json object.
 
319
    /// </summary>
 
320
    public virtual void WriteStartObject()
 
321
    {
 
322
      AutoComplete(JsonToken.StartObject);
 
323
      Push(JsonContainerType.Object);
 
324
    }
 
325
 
 
326
    /// <summary>
 
327
    /// Writes the end of a Json object.
 
328
    /// </summary>
 
329
    public virtual void WriteEndObject()
 
330
    {
 
331
      AutoCompleteClose(JsonToken.EndObject);
 
332
    }
 
333
 
 
334
    /// <summary>
 
335
    /// Writes the beginning of a Json array.
 
336
    /// </summary>
 
337
    public virtual void WriteStartArray()
 
338
    {
 
339
      AutoComplete(JsonToken.StartArray);
 
340
      Push(JsonContainerType.Array);
 
341
    }
 
342
 
 
343
    /// <summary>
 
344
    /// Writes the end of an array.
 
345
    /// </summary>
 
346
    public virtual void WriteEndArray()
 
347
    {
 
348
      AutoCompleteClose(JsonToken.EndArray);
 
349
    }
 
350
 
 
351
    /// <summary>
 
352
    /// Writes the start of a constructor with the given name.
 
353
    /// </summary>
 
354
    /// <param name="name">The name of the constructor.</param>
 
355
    public virtual void WriteStartConstructor(string name)
 
356
    {
 
357
      AutoComplete(JsonToken.StartConstructor);
 
358
      Push(JsonContainerType.Constructor);
 
359
    }
 
360
 
 
361
    /// <summary>
 
362
    /// Writes the end constructor.
 
363
    /// </summary>
 
364
    public virtual void WriteEndConstructor()
 
365
    {
 
366
      AutoCompleteClose(JsonToken.EndConstructor);
 
367
    }
 
368
 
 
369
    /// <summary>
 
370
    /// Writes the property name of a name/value pair on a Json object.
 
371
    /// </summary>
 
372
    /// <param name="name">The name of the property.</param>
 
373
    public virtual void WritePropertyName(string name)
 
374
    {
 
375
      _currentPosition.PropertyName = name;
 
376
      AutoComplete(JsonToken.PropertyName);
 
377
    }
 
378
 
 
379
    /// <summary>
 
380
    /// Writes the end of the current Json object or array.
 
381
    /// </summary>
 
382
    public virtual void WriteEnd()
 
383
    {
 
384
      WriteEnd(Peek());
 
385
    }
 
386
 
 
387
    /// <summary>
 
388
    /// Writes the current <see cref="JsonReader"/> token.
 
389
    /// </summary>
 
390
    /// <param name="reader">The <see cref="JsonReader"/> to read the token from.</param>
 
391
    public void WriteToken(JsonReader reader)
 
392
    {
 
393
      ValidationUtils.ArgumentNotNull(reader, "reader");
 
394
 
 
395
      int initialDepth;
 
396
 
 
397
      if (reader.TokenType == JsonToken.None)
 
398
        initialDepth = -1;
 
399
      else if (!IsStartToken(reader.TokenType))
 
400
        initialDepth = reader.Depth + 1;
 
401
      else
 
402
        initialDepth = reader.Depth;
 
403
 
 
404
      WriteToken(reader, initialDepth);
 
405
    }
 
406
 
 
407
    internal void WriteToken(JsonReader reader, int initialDepth)
 
408
    {
 
409
      do
 
410
      {
 
411
        switch (reader.TokenType)
 
412
        {
 
413
          case JsonToken.None:
 
414
            // read to next
 
415
            break;
 
416
          case JsonToken.StartObject:
 
417
            WriteStartObject();
 
418
            break;
 
419
          case JsonToken.StartArray:
 
420
            WriteStartArray();
 
421
            break;
 
422
          case JsonToken.StartConstructor:
 
423
            string constructorName = reader.Value.ToString();
 
424
            // write a JValue date when the constructor is for a date
 
425
            if (string.Equals(constructorName, "Date", StringComparison.Ordinal))
 
426
              WriteConstructorDate(reader);
 
427
            else
 
428
              WriteStartConstructor(reader.Value.ToString());
 
429
            break;
 
430
          case JsonToken.PropertyName:
 
431
            WritePropertyName(reader.Value.ToString());
 
432
            break;
 
433
          case JsonToken.Comment:
 
434
            WriteComment(reader.Value.ToString());
 
435
            break;
 
436
          case JsonToken.Integer:
 
437
            WriteValue(Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture));
 
438
            break;
 
439
          case JsonToken.Float:
 
440
            WriteValue(Convert.ToDouble(reader.Value, CultureInfo.InvariantCulture));
 
441
            break;
 
442
          case JsonToken.String:
 
443
            WriteValue(reader.Value.ToString());
 
444
            break;
 
445
          case JsonToken.Boolean:
 
446
            WriteValue(Convert.ToBoolean(reader.Value, CultureInfo.InvariantCulture));
 
447
            break;
 
448
          case JsonToken.Null:
 
449
            WriteNull();
 
450
            break;
 
451
          case JsonToken.Undefined:
 
452
            WriteUndefined();
 
453
            break;
 
454
          case JsonToken.EndObject:
 
455
            WriteEndObject();
 
456
            break;
 
457
          case JsonToken.EndArray:
 
458
            WriteEndArray();
 
459
            break;
 
460
          case JsonToken.EndConstructor:
 
461
            WriteEndConstructor();
 
462
            break;
 
463
          case JsonToken.Date:
 
464
            WriteValue((DateTime)reader.Value);
 
465
            break;
 
466
          case JsonToken.Raw:
 
467
            WriteRawValue((string)reader.Value);
 
468
            break;
 
469
          case JsonToken.Bytes:
 
470
            WriteValue((byte[])reader.Value);
 
471
            break;
 
472
          default:
 
473
            throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", reader.TokenType, "Unexpected token type.");
 
474
        }
 
475
      }
 
476
      while (
 
477
        // stop if we have reached the end of the token being read
 
478
        initialDepth - 1 < reader.Depth - (IsEndToken(reader.TokenType) ? 1 : 0)
 
479
        && reader.Read());
 
480
    }
 
481
 
 
482
    private void WriteConstructorDate(JsonReader reader)
 
483
    {
 
484
      if (!reader.Read())
 
485
        throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null);
 
486
      if (reader.TokenType != JsonToken.Integer)
 
487
        throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected Integer, got " + reader.TokenType, null);
 
488
 
 
489
      long ticks = (long)reader.Value;
 
490
      DateTime date = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks);
 
491
 
 
492
      if (!reader.Read())
 
493
        throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null);
 
494
      if (reader.TokenType != JsonToken.EndConstructor)
 
495
        throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected EndConstructor, got " + reader.TokenType, null);
 
496
 
 
497
      WriteValue(date);
 
498
    }
 
499
 
 
500
    private bool IsEndToken(JsonToken token)
 
501
    {
 
502
      switch (token)
 
503
      {
 
504
        case JsonToken.EndObject:
 
505
        case JsonToken.EndArray:
 
506
        case JsonToken.EndConstructor:
 
507
          return true;
 
508
        default:
 
509
          return false;
 
510
      }
 
511
    }
 
512
 
 
513
    private bool IsStartToken(JsonToken token)
 
514
    {
 
515
      switch (token)
 
516
      {
 
517
        case JsonToken.StartObject:
 
518
        case JsonToken.StartArray:
 
519
        case JsonToken.StartConstructor:
 
520
          return true;
 
521
        default:
 
522
          return false;
 
523
      }
 
524
    }
 
525
 
 
526
    private void WriteEnd(JsonContainerType type)
 
527
    {
 
528
      switch (type)
 
529
      {
 
530
        case JsonContainerType.Object:
 
531
          WriteEndObject();
 
532
          break;
 
533
        case JsonContainerType.Array:
 
534
          WriteEndArray();
 
535
          break;
 
536
        case JsonContainerType.Constructor:
 
537
          WriteEndConstructor();
 
538
          break;
 
539
        default:
 
540
          throw JsonWriterException.Create(this, "Unexpected type when writing end: " + type, null);
 
541
      }
 
542
    }
 
543
 
 
544
    private void AutoCompleteAll()
 
545
    {
 
546
      while (Top > 0)
 
547
      {
 
548
        WriteEnd();
 
549
      }
 
550
    }
 
551
 
 
552
    private JsonContainerType GetTypeForCloseToken(JsonToken token)
 
553
    {
 
554
      switch (token)
 
555
      {
 
556
        case JsonToken.EndObject:
 
557
          return JsonContainerType.Object;
 
558
        case JsonToken.EndArray:
 
559
          return JsonContainerType.Array;
 
560
        case JsonToken.EndConstructor:
 
561
          return JsonContainerType.Constructor;
 
562
        default:
 
563
          throw JsonWriterException.Create(this, "No type for token: " + token, null);
 
564
      }
 
565
    }
 
566
 
 
567
    private JsonToken GetCloseTokenForType(JsonContainerType type)
 
568
    {
 
569
      switch (type)
 
570
      {
 
571
        case JsonContainerType.Object:
 
572
          return JsonToken.EndObject;
 
573
        case JsonContainerType.Array:
 
574
          return JsonToken.EndArray;
 
575
        case JsonContainerType.Constructor:
 
576
          return JsonToken.EndConstructor;
 
577
        default:
 
578
          throw JsonWriterException.Create(this, "No close token for type: " + type, null);
 
579
      }
 
580
    }
 
581
 
 
582
    private void AutoCompleteClose(JsonToken tokenBeingClosed)
 
583
    {
 
584
      // write closing symbol and calculate new state
 
585
      int levelsToComplete = 0;
 
586
      JsonContainerType type = GetTypeForCloseToken(tokenBeingClosed);
 
587
 
 
588
      if (_currentPosition.Type == type)
 
589
      {
 
590
        levelsToComplete = 1;
 
591
      }
 
592
      else
 
593
      {
 
594
        int top = Top - 2;
 
595
        for (int i = top; i >= 0; i--)
 
596
        {
 
597
          int currentLevel = top - i;
 
598
 
 
599
          if (_stack[currentLevel].Type == type)
 
600
          {
 
601
            levelsToComplete = i + 2;
 
602
            break;
 
603
          }
 
604
        }
 
605
      }
 
606
 
 
607
      if (levelsToComplete == 0)
 
608
        throw JsonWriterException.Create(this, "No token to close.", null);
 
609
 
 
610
      for (int i = 0; i < levelsToComplete; i++)
 
611
      {
 
612
        JsonToken token = GetCloseTokenForType(Pop());
 
613
 
 
614
        if (_currentState == State.Property)
 
615
          WriteNull();
 
616
 
 
617
        if (_formatting == Formatting.Indented)
 
618
        {
 
619
          if (_currentState != State.ObjectStart && _currentState != State.ArrayStart)
 
620
            WriteIndent();
 
621
        }
 
622
 
 
623
        WriteEnd(token);
 
624
 
 
625
        JsonContainerType currentLevelType = Peek();
 
626
 
 
627
        switch (currentLevelType)
 
628
        {
 
629
          case JsonContainerType.Object:
 
630
            _currentState = State.Object;
 
631
            break;
 
632
          case JsonContainerType.Array:
 
633
            _currentState = State.Array;
 
634
            break;
 
635
          case JsonContainerType.Constructor:
 
636
            _currentState = State.Array;
 
637
            break;
 
638
          case JsonContainerType.None:
 
639
            _currentState = State.Start;
 
640
            break;
 
641
          default:
 
642
            throw JsonWriterException.Create(this, "Unknown JsonType: " + currentLevelType, null);
 
643
        }
 
644
      }
 
645
    }
 
646
 
 
647
    /// <summary>
 
648
    /// Writes the specified end token.
 
649
    /// </summary>
 
650
    /// <param name="token">The end token to write.</param>
 
651
    protected virtual void WriteEnd(JsonToken token)
 
652
    {
 
653
    }
 
654
 
 
655
    /// <summary>
 
656
    /// Writes indent characters.
 
657
    /// </summary>
 
658
    protected virtual void WriteIndent()
 
659
    {
 
660
    }
 
661
 
 
662
    /// <summary>
 
663
    /// Writes the JSON value delimiter.
 
664
    /// </summary>
 
665
    protected virtual void WriteValueDelimiter()
 
666
    {
 
667
    }
 
668
 
 
669
    /// <summary>
 
670
    /// Writes an indent space.
 
671
    /// </summary>
 
672
    protected virtual void WriteIndentSpace()
 
673
    {
 
674
    }
 
675
 
 
676
    internal void AutoComplete(JsonToken tokenBeingWritten)
 
677
    {
 
678
      if (tokenBeingWritten != JsonToken.StartObject
 
679
        && tokenBeingWritten != JsonToken.StartArray
 
680
        && tokenBeingWritten != JsonToken.StartConstructor)
 
681
        UpdateScopeWithFinishedValue();
 
682
 
 
683
      // gets new state based on the current state and what is being written
 
684
      State newState = StateArray[(int)tokenBeingWritten][(int)_currentState];
 
685
 
 
686
      if (newState == State.Error)
 
687
        throw JsonWriterException.Create(this, "Token {0} in state {1} would result in an invalid JSON object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), _currentState.ToString()), null);
 
688
 
 
689
      if ((_currentState == State.Object || _currentState == State.Array || _currentState == State.Constructor) && tokenBeingWritten != JsonToken.Comment)
 
690
      {
 
691
        WriteValueDelimiter();
 
692
      }
 
693
      else if (_currentState == State.Property)
 
694
      {
 
695
        if (_formatting == Formatting.Indented)
 
696
          WriteIndentSpace();
 
697
      }
 
698
 
 
699
      if (_formatting == Formatting.Indented)
 
700
      {
 
701
        WriteState writeState = WriteState;
 
702
 
 
703
        // don't indent a property when it is the first token to be written (i.e. at the start)
 
704
        if ((tokenBeingWritten == JsonToken.PropertyName && writeState != WriteState.Start) ||
 
705
            writeState == WriteState.Array || writeState == WriteState.Constructor)
 
706
        {
 
707
          WriteIndent();
 
708
        }
 
709
      }
 
710
 
 
711
      _currentState = newState;
 
712
    }
 
713
 
 
714
    #region WriteValue methods
 
715
    /// <summary>
 
716
    /// Writes a null value.
 
717
    /// </summary>
 
718
    public virtual void WriteNull()
 
719
    {
 
720
      AutoComplete(JsonToken.Null);
 
721
    }
 
722
 
 
723
    /// <summary>
 
724
    /// Writes an undefined value.
 
725
    /// </summary>
 
726
    public virtual void WriteUndefined()
 
727
    {
 
728
      AutoComplete(JsonToken.Undefined);
 
729
    }
 
730
 
 
731
    /// <summary>
 
732
    /// Writes raw JSON without changing the writer's state.
 
733
    /// </summary>
 
734
    /// <param name="json">The raw JSON to write.</param>
 
735
    public virtual void WriteRaw(string json)
 
736
    {
 
737
    }
 
738
 
 
739
    /// <summary>
 
740
    /// Writes raw JSON where a value is expected and updates the writer's state.
 
741
    /// </summary>
 
742
    /// <param name="json">The raw JSON to write.</param>
 
743
    public virtual void WriteRawValue(string json)
 
744
    {
 
745
      // hack. want writer to change state as if a value had been written
 
746
      AutoComplete(JsonToken.Undefined);
 
747
      WriteRaw(json);
 
748
    }
 
749
 
 
750
    /// <summary>
 
751
    /// Writes a <see cref="String"/> value.
 
752
    /// </summary>
 
753
    /// <param name="value">The <see cref="String"/> value to write.</param>
 
754
    public virtual void WriteValue(string value)
 
755
    {
 
756
      AutoComplete(JsonToken.String);
 
757
    }
 
758
 
 
759
    /// <summary>
 
760
    /// Writes a <see cref="Int32"/> value.
 
761
    /// </summary>
 
762
    /// <param name="value">The <see cref="Int32"/> value to write.</param>
 
763
    public virtual void WriteValue(int value)
 
764
    {
 
765
      AutoComplete(JsonToken.Integer);
 
766
    }
 
767
 
 
768
    /// <summary>
 
769
    /// Writes a <see cref="UInt32"/> value.
 
770
    /// </summary>
 
771
    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
 
772
    [CLSCompliant(false)]
 
773
    public virtual void WriteValue(uint value)
 
774
    {
 
775
      AutoComplete(JsonToken.Integer);
 
776
    }
 
777
 
 
778
    /// <summary>
 
779
    /// Writes a <see cref="Int64"/> value.
 
780
    /// </summary>
 
781
    /// <param name="value">The <see cref="Int64"/> value to write.</param>
 
782
    public virtual void WriteValue(long value)
 
783
    {
 
784
      AutoComplete(JsonToken.Integer);
 
785
    }
 
786
 
 
787
    /// <summary>
 
788
    /// Writes a <see cref="UInt64"/> value.
 
789
    /// </summary>
 
790
    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
 
791
    [CLSCompliant(false)]
 
792
    public virtual void WriteValue(ulong value)
 
793
    {
 
794
      AutoComplete(JsonToken.Integer);
 
795
    }
 
796
 
 
797
    /// <summary>
 
798
    /// Writes a <see cref="Single"/> value.
 
799
    /// </summary>
 
800
    /// <param name="value">The <see cref="Single"/> value to write.</param>
 
801
    public virtual void WriteValue(float value)
 
802
    {
 
803
      AutoComplete(JsonToken.Float);
 
804
    }
 
805
 
 
806
    /// <summary>
 
807
    /// Writes a <see cref="Double"/> value.
 
808
    /// </summary>
 
809
    /// <param name="value">The <see cref="Double"/> value to write.</param>
 
810
    public virtual void WriteValue(double value)
 
811
    {
 
812
      AutoComplete(JsonToken.Float);
 
813
    }
 
814
 
 
815
    /// <summary>
 
816
    /// Writes a <see cref="Boolean"/> value.
 
817
    /// </summary>
 
818
    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
 
819
    public virtual void WriteValue(bool value)
 
820
    {
 
821
      AutoComplete(JsonToken.Boolean);
 
822
    }
 
823
 
 
824
    /// <summary>
 
825
    /// Writes a <see cref="Int16"/> value.
 
826
    /// </summary>
 
827
    /// <param name="value">The <see cref="Int16"/> value to write.</param>
 
828
    public virtual void WriteValue(short value)
 
829
    {
 
830
      AutoComplete(JsonToken.Integer);
 
831
    }
 
832
 
 
833
    /// <summary>
 
834
    /// Writes a <see cref="UInt16"/> value.
 
835
    /// </summary>
 
836
    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
 
837
    [CLSCompliant(false)]
 
838
    public virtual void WriteValue(ushort value)
 
839
    {
 
840
      AutoComplete(JsonToken.Integer);
 
841
    }
 
842
 
 
843
    /// <summary>
 
844
    /// Writes a <see cref="Char"/> value.
 
845
    /// </summary>
 
846
    /// <param name="value">The <see cref="Char"/> value to write.</param>
 
847
    public virtual void WriteValue(char value)
 
848
    {
 
849
      AutoComplete(JsonToken.String);
 
850
    }
 
851
 
 
852
    /// <summary>
 
853
    /// Writes a <see cref="Byte"/> value.
 
854
    /// </summary>
 
855
    /// <param name="value">The <see cref="Byte"/> value to write.</param>
 
856
    public virtual void WriteValue(byte value)
 
857
    {
 
858
      AutoComplete(JsonToken.Integer);
 
859
    }
 
860
 
 
861
    /// <summary>
 
862
    /// Writes a <see cref="SByte"/> value.
 
863
    /// </summary>
 
864
    /// <param name="value">The <see cref="SByte"/> value to write.</param>
 
865
    [CLSCompliant(false)]
 
866
    public virtual void WriteValue(sbyte value)
 
867
    {
 
868
      AutoComplete(JsonToken.Integer);
 
869
    }
 
870
 
 
871
    /// <summary>
 
872
    /// Writes a <see cref="Decimal"/> value.
 
873
    /// </summary>
 
874
    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
 
875
    public virtual void WriteValue(decimal value)
 
876
    {
 
877
      AutoComplete(JsonToken.Float);
 
878
    }
 
879
 
 
880
    /// <summary>
 
881
    /// Writes a <see cref="DateTime"/> value.
 
882
    /// </summary>
 
883
    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
 
884
    public virtual void WriteValue(DateTime value)
 
885
    {
 
886
      AutoComplete(JsonToken.Date);
 
887
    }
 
888
 
 
889
#if !PocketPC && !NET20
 
890
    /// <summary>
 
891
    /// Writes a <see cref="DateTimeOffset"/> value.
 
892
    /// </summary>
 
893
    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
 
894
    public virtual void WriteValue(DateTimeOffset value)
 
895
    {
 
896
      AutoComplete(JsonToken.Date);
 
897
    }
 
898
#endif
 
899
 
 
900
    /// <summary>
 
901
    /// Writes a <see cref="Guid"/> value.
 
902
    /// </summary>
 
903
    /// <param name="value">The <see cref="Guid"/> value to write.</param>
 
904
    public virtual void WriteValue(Guid value)
 
905
    {
 
906
      AutoComplete(JsonToken.String);
 
907
    }
 
908
 
 
909
    /// <summary>
 
910
    /// Writes a <see cref="TimeSpan"/> value.
 
911
    /// </summary>
 
912
    /// <param name="value">The <see cref="TimeSpan"/> value to write.</param>
 
913
    public virtual void WriteValue(TimeSpan value)
 
914
    {
 
915
      AutoComplete(JsonToken.String);
 
916
    }
 
917
 
 
918
    /// <summary>
 
919
    /// Writes a <see cref="Nullable{Int32}"/> value.
 
920
    /// </summary>
 
921
    /// <param name="value">The <see cref="Nullable{Int32}"/> value to write.</param>
 
922
    public virtual void WriteValue(int? value)
 
923
    {
 
924
      if (value == null)
 
925
        WriteNull();
 
926
      else
 
927
        WriteValue(value.Value);
 
928
    }
 
929
 
 
930
    /// <summary>
 
931
    /// Writes a <see cref="Nullable{UInt32}"/> value.
 
932
    /// </summary>
 
933
    /// <param name="value">The <see cref="Nullable{UInt32}"/> value to write.</param>
 
934
    [CLSCompliant(false)]
 
935
    public virtual void WriteValue(uint? value)
 
936
    {
 
937
      if (value == null)
 
938
        WriteNull();
 
939
      else
 
940
        WriteValue(value.Value);
 
941
    }
 
942
 
 
943
    /// <summary>
 
944
    /// Writes a <see cref="Nullable{Int64}"/> value.
 
945
    /// </summary>
 
946
    /// <param name="value">The <see cref="Nullable{Int64}"/> value to write.</param>
 
947
    public virtual void WriteValue(long? value)
 
948
    {
 
949
      if (value == null)
 
950
        WriteNull();
 
951
      else
 
952
        WriteValue(value.Value);
 
953
    }
 
954
 
 
955
    /// <summary>
 
956
    /// Writes a <see cref="Nullable{UInt64}"/> value.
 
957
    /// </summary>
 
958
    /// <param name="value">The <see cref="Nullable{UInt64}"/> value to write.</param>
 
959
    [CLSCompliant(false)]
 
960
    public virtual void WriteValue(ulong? value)
 
961
    {
 
962
      if (value == null)
 
963
        WriteNull();
 
964
      else
 
965
        WriteValue(value.Value);
 
966
    }
 
967
 
 
968
    /// <summary>
 
969
    /// Writes a <see cref="Nullable{Single}"/> value.
 
970
    /// </summary>
 
971
    /// <param name="value">The <see cref="Nullable{Single}"/> value to write.</param>
 
972
    public virtual void WriteValue(float? value)
 
973
    {
 
974
      if (value == null)
 
975
        WriteNull();
 
976
      else
 
977
        WriteValue(value.Value);
 
978
    }
 
979
 
 
980
    /// <summary>
 
981
    /// Writes a <see cref="Nullable{Double}"/> value.
 
982
    /// </summary>
 
983
    /// <param name="value">The <see cref="Nullable{Double}"/> value to write.</param>
 
984
    public virtual void WriteValue(double? value)
 
985
    {
 
986
      if (value == null)
 
987
        WriteNull();
 
988
      else
 
989
        WriteValue(value.Value);
 
990
    }
 
991
 
 
992
    /// <summary>
 
993
    /// Writes a <see cref="Nullable{Boolean}"/> value.
 
994
    /// </summary>
 
995
    /// <param name="value">The <see cref="Nullable{Boolean}"/> value to write.</param>
 
996
    public virtual void WriteValue(bool? value)
 
997
    {
 
998
      if (value == null)
 
999
        WriteNull();
 
1000
      else
 
1001
        WriteValue(value.Value);
 
1002
    }
 
1003
 
 
1004
    /// <summary>
 
1005
    /// Writes a <see cref="Nullable{Int16}"/> value.
 
1006
    /// </summary>
 
1007
    /// <param name="value">The <see cref="Nullable{Int16}"/> value to write.</param>
 
1008
    public virtual void WriteValue(short? value)
 
1009
    {
 
1010
      if (value == null)
 
1011
        WriteNull();
 
1012
      else
 
1013
        WriteValue(value.Value);
 
1014
    }
 
1015
 
 
1016
    /// <summary>
 
1017
    /// Writes a <see cref="Nullable{UInt16}"/> value.
 
1018
    /// </summary>
 
1019
    /// <param name="value">The <see cref="Nullable{UInt16}"/> value to write.</param>
 
1020
    [CLSCompliant(false)]
 
1021
    public virtual void WriteValue(ushort? value)
 
1022
    {
 
1023
      if (value == null)
 
1024
        WriteNull();
 
1025
      else
 
1026
        WriteValue(value.Value);
 
1027
    }
 
1028
 
 
1029
    /// <summary>
 
1030
    /// Writes a <see cref="Nullable{Char}"/> value.
 
1031
    /// </summary>
 
1032
    /// <param name="value">The <see cref="Nullable{Char}"/> value to write.</param>
 
1033
    public virtual void WriteValue(char? value)
 
1034
    {
 
1035
      if (value == null)
 
1036
        WriteNull();
 
1037
      else
 
1038
        WriteValue(value.Value);
 
1039
    }
 
1040
 
 
1041
    /// <summary>
 
1042
    /// Writes a <see cref="Nullable{Byte}"/> value.
 
1043
    /// </summary>
 
1044
    /// <param name="value">The <see cref="Nullable{Byte}"/> value to write.</param>
 
1045
    public virtual void WriteValue(byte? value)
 
1046
    {
 
1047
      if (value == null)
 
1048
        WriteNull();
 
1049
      else
 
1050
        WriteValue(value.Value);
 
1051
    }
 
1052
 
 
1053
    /// <summary>
 
1054
    /// Writes a <see cref="Nullable{SByte}"/> value.
 
1055
    /// </summary>
 
1056
    /// <param name="value">The <see cref="Nullable{SByte}"/> value to write.</param>
 
1057
    [CLSCompliant(false)]
 
1058
    public virtual void WriteValue(sbyte? value)
 
1059
    {
 
1060
      if (value == null)
 
1061
        WriteNull();
 
1062
      else
 
1063
        WriteValue(value.Value);
 
1064
    }
 
1065
 
 
1066
    /// <summary>
 
1067
    /// Writes a <see cref="Nullable{Decimal}"/> value.
 
1068
    /// </summary>
 
1069
    /// <param name="value">The <see cref="Nullable{Decimal}"/> value to write.</param>
 
1070
    public virtual void WriteValue(decimal? value)
 
1071
    {
 
1072
      if (value == null)
 
1073
        WriteNull();
 
1074
      else
 
1075
        WriteValue(value.Value);
 
1076
    }
 
1077
 
 
1078
    /// <summary>
 
1079
    /// Writes a <see cref="Nullable{DateTime}"/> value.
 
1080
    /// </summary>
 
1081
    /// <param name="value">The <see cref="Nullable{DateTime}"/> value to write.</param>
 
1082
    public virtual void WriteValue(DateTime? value)
 
1083
    {
 
1084
      if (value == null)
 
1085
        WriteNull();
 
1086
      else
 
1087
        WriteValue(value.Value);
 
1088
    }
 
1089
 
 
1090
#if !PocketPC && !NET20
 
1091
    /// <summary>
 
1092
    /// Writes a <see cref="Nullable{DateTimeOffset}"/> value.
 
1093
    /// </summary>
 
1094
    /// <param name="value">The <see cref="Nullable{DateTimeOffset}"/> value to write.</param>
 
1095
    public virtual void WriteValue(DateTimeOffset? value)
 
1096
    {
 
1097
      if (value == null)
 
1098
        WriteNull();
 
1099
      else
 
1100
        WriteValue(value.Value);
 
1101
    }
 
1102
#endif
 
1103
 
 
1104
    /// <summary>
 
1105
    /// Writes a <see cref="Nullable{Guid}"/> value.
 
1106
    /// </summary>
 
1107
    /// <param name="value">The <see cref="Nullable{Guid}"/> value to write.</param>
 
1108
    public virtual void WriteValue(Guid? value)
 
1109
    {
 
1110
      if (value == null)
 
1111
        WriteNull();
 
1112
      else
 
1113
        WriteValue(value.Value);
 
1114
    }
 
1115
 
 
1116
    /// <summary>
 
1117
    /// Writes a <see cref="Nullable{TimeSpan}"/> value.
 
1118
    /// </summary>
 
1119
    /// <param name="value">The <see cref="Nullable{TimeSpan}"/> value to write.</param>
 
1120
    public virtual void WriteValue(TimeSpan? value)
 
1121
    {
 
1122
      if (value == null)
 
1123
        WriteNull();
 
1124
      else
 
1125
        WriteValue(value.Value);
 
1126
    }
 
1127
 
 
1128
    /// <summary>
 
1129
    /// Writes a <see cref="T:Byte[]"/> value.
 
1130
    /// </summary>
 
1131
    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
 
1132
    public virtual void WriteValue(byte[] value)
 
1133
    {
 
1134
      if (value == null)
 
1135
        WriteNull();
 
1136
      else
 
1137
        AutoComplete(JsonToken.Bytes);
 
1138
    }
 
1139
 
 
1140
    /// <summary>
 
1141
    /// Writes a <see cref="Uri"/> value.
 
1142
    /// </summary>
 
1143
    /// <param name="value">The <see cref="Uri"/> value to write.</param>
 
1144
    public virtual void WriteValue(Uri value)
 
1145
    {
 
1146
      if (value == null)
 
1147
        WriteNull();
 
1148
      else
 
1149
        AutoComplete(JsonToken.String);
 
1150
    }
 
1151
 
 
1152
    /// <summary>
 
1153
    /// Writes a <see cref="Object"/> value.
 
1154
    /// An error will raised if the value cannot be written as a single JSON token.
 
1155
    /// </summary>
 
1156
    /// <param name="value">The <see cref="Object"/> value to write.</param>
 
1157
    public virtual void WriteValue(object value)
 
1158
    {
 
1159
      if (value == null)
 
1160
      {
 
1161
        WriteNull();
 
1162
        return;
 
1163
      }
 
1164
      else if (ConvertUtils.IsConvertible(value))
 
1165
      {
 
1166
        IConvertible convertible = ConvertUtils.ToConvertible(value);
 
1167
 
 
1168
        switch (convertible.GetTypeCode())
 
1169
        {
 
1170
          case TypeCode.String:
 
1171
            WriteValue(convertible.ToString(CultureInfo.InvariantCulture));
 
1172
            return;
 
1173
          case TypeCode.Char:
 
1174
            WriteValue(convertible.ToChar(CultureInfo.InvariantCulture));
 
1175
            return;
 
1176
          case TypeCode.Boolean:
 
1177
            WriteValue(convertible.ToBoolean(CultureInfo.InvariantCulture));
 
1178
            return;
 
1179
          case TypeCode.SByte:
 
1180
            WriteValue(convertible.ToSByte(CultureInfo.InvariantCulture));
 
1181
            return;
 
1182
          case TypeCode.Int16:
 
1183
            WriteValue(convertible.ToInt16(CultureInfo.InvariantCulture));
 
1184
            return;
 
1185
          case TypeCode.UInt16:
 
1186
            WriteValue(convertible.ToUInt16(CultureInfo.InvariantCulture));
 
1187
            return;
 
1188
          case TypeCode.Int32:
 
1189
            WriteValue(convertible.ToInt32(CultureInfo.InvariantCulture));
 
1190
            return;
 
1191
          case TypeCode.Byte:
 
1192
            WriteValue(convertible.ToByte(CultureInfo.InvariantCulture));
 
1193
            return;
 
1194
          case TypeCode.UInt32:
 
1195
            WriteValue(convertible.ToUInt32(CultureInfo.InvariantCulture));
 
1196
            return;
 
1197
          case TypeCode.Int64:
 
1198
            WriteValue(convertible.ToInt64(CultureInfo.InvariantCulture));
 
1199
            return;
 
1200
          case TypeCode.UInt64:
 
1201
            WriteValue(convertible.ToUInt64(CultureInfo.InvariantCulture));
 
1202
            return;
 
1203
          case TypeCode.Single:
 
1204
            WriteValue(convertible.ToSingle(CultureInfo.InvariantCulture));
 
1205
            return;
 
1206
          case TypeCode.Double:
 
1207
            WriteValue(convertible.ToDouble(CultureInfo.InvariantCulture));
 
1208
            return;
 
1209
          case TypeCode.DateTime:
 
1210
            WriteValue(convertible.ToDateTime(CultureInfo.InvariantCulture));
 
1211
            return;
 
1212
          case TypeCode.Decimal:
 
1213
            WriteValue(convertible.ToDecimal(CultureInfo.InvariantCulture));
 
1214
            return;
 
1215
#if !(NETFX_CORE || PORTABLE)
 
1216
          case TypeCode.DBNull:
 
1217
            WriteNull();
 
1218
            return;
 
1219
#endif
 
1220
        }
 
1221
      }
 
1222
#if !PocketPC && !NET20
 
1223
      else if (value is DateTimeOffset)
 
1224
      {
 
1225
        WriteValue((DateTimeOffset)value);
 
1226
        return;
 
1227
      }
 
1228
#endif
 
1229
      else if (value is byte[])
 
1230
      {
 
1231
        WriteValue((byte[])value);
 
1232
        return;
 
1233
      }
 
1234
      else if (value is Guid)
 
1235
      {
 
1236
        WriteValue((Guid)value);
 
1237
        return;
 
1238
      }
 
1239
      else if (value is Uri)
 
1240
      {
 
1241
        WriteValue((Uri)value);
 
1242
        return;
 
1243
      }
 
1244
      else if (value is TimeSpan)
 
1245
      {
 
1246
        WriteValue((TimeSpan)value);
 
1247
        return;
 
1248
      }
 
1249
 
 
1250
      throw JsonWriterException.Create(this, "Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
 
1251
    }
 
1252
    #endregion
 
1253
 
 
1254
    /// <summary>
 
1255
    /// Writes out a comment <code>/*...*/</code> containing the specified text. 
 
1256
    /// </summary>
 
1257
    /// <param name="text">Text to place inside the comment.</param>
 
1258
    public virtual void WriteComment(string text)
 
1259
    {
 
1260
      AutoComplete(JsonToken.Comment);
 
1261
    }
 
1262
 
 
1263
    /// <summary>
 
1264
    /// Writes out the given white space.
 
1265
    /// </summary>
 
1266
    /// <param name="ws">The string of white space characters.</param>
 
1267
    public virtual void WriteWhitespace(string ws)
 
1268
    {
 
1269
      if (ws != null)
 
1270
      {
 
1271
        if (!StringUtils.IsWhiteSpace(ws))
 
1272
          throw JsonWriterException.Create(this, "Only white space characters should be used.", null);
 
1273
      }
 
1274
    }
 
1275
 
 
1276
 
 
1277
    void IDisposable.Dispose()
 
1278
    {
 
1279
      Dispose(true);
 
1280
    }
 
1281
 
 
1282
    private void Dispose(bool disposing)
 
1283
    {
 
1284
      if (_currentState != State.Closed)
 
1285
        Close();
 
1286
    }
 
1287
  }
1122
1288
}
 
 
b'\\ No newline at end of file'