New features
-New, more concise, LINQ to JSON querying syntax. -Added FromObject to JObject, JArray. -JToken WriteTo method now supports JsonConverters. -JsonSerializer supports serializing to and from LINQ to JSON objects. -JsonSerializer properly serializes IEnumerable objects. -Added Depth property to JsonReader. Changes -Made JsonReader and JsonWriter abstract. Added JsonTextReader/JsonNodeReader and JsonTextWriter/JsonNodeWriter. -Removed JavaScriptObject, JavaScriptArray. Replaced by LINQ to JSON objects.
This commit is contained in:
@@ -1,64 +0,0 @@
|
||||
#region License
|
||||
// Copyright (c) 2007 James Newton-King
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a JavaScript array.
|
||||
/// </summary>
|
||||
public class JavaScriptArray : List<object>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JavaScriptObject"/> class.
|
||||
/// </summary>
|
||||
public JavaScriptArray()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JavaScriptArray"/> class that
|
||||
/// contains elements copied from the specified collection.
|
||||
/// </summary>
|
||||
/// <param name="collection">The collection whose elements are copied to the new array.</param>
|
||||
public JavaScriptArray(IEnumerable<object> collection)
|
||||
: base(collection)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JavaScriptArray"/> class that
|
||||
/// is empty and has the specified initial capacity.
|
||||
/// </summary>
|
||||
/// <param name="capacity">The number of elements that the new array can initially store.</param>
|
||||
public JavaScriptArray(int capacity)
|
||||
: base(capacity)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
#region License
|
||||
// Copyright (c) 2007 James Newton-King
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a JavaScript constructor.
|
||||
/// </summary>
|
||||
public class JavaScriptConstructor
|
||||
{
|
||||
private string _name;
|
||||
private JavaScriptParameters _parameters;
|
||||
|
||||
public JavaScriptParameters Parameters
|
||||
{
|
||||
get { return _parameters; }
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
}
|
||||
|
||||
public JavaScriptConstructor(string name, JavaScriptParameters parameters)
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException("name");
|
||||
|
||||
if (name.Length == 0)
|
||||
throw new ArgumentException("Constructor name cannot be empty.", "name");
|
||||
|
||||
_name = name;
|
||||
_parameters = parameters ?? JavaScriptParameters.Empty;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append("new ");
|
||||
sb.Append(_name);
|
||||
sb.Append("(");
|
||||
if (_parameters != null)
|
||||
{
|
||||
for (int i = 0; i < _parameters.Count; i++)
|
||||
{
|
||||
sb.Append(_parameters[i]);
|
||||
}
|
||||
}
|
||||
sb.Append(")");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -388,7 +388,7 @@ namespace Newtonsoft.Json
|
||||
}
|
||||
}
|
||||
|
||||
using (JsonWriter jsonWriter = new JsonWriter(sw))
|
||||
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
|
||||
{
|
||||
//jsonWriter.Formatting = Formatting.Indented;
|
||||
jsonSerializer.Serialize(jsonWriter, value);
|
||||
@@ -472,7 +472,7 @@ namespace Newtonsoft.Json
|
||||
|
||||
object deserializedValue;
|
||||
|
||||
using (JsonReader jsonReader = new JsonReader(sr))
|
||||
using (JsonReader jsonReader = new JsonTextReader(sr))
|
||||
{
|
||||
deserializedValue = jsonSerializer.Deserialize(jsonReader, type);
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
#region License
|
||||
// Copyright (c) 2007 James Newton-King
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a JavaScript object.
|
||||
/// </summary>
|
||||
public class JavaScriptObject : Dictionary<string, object>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JavaScriptObject"/> class.
|
||||
/// </summary>
|
||||
public JavaScriptObject()
|
||||
: base(EqualityComparer<string>.Default)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JavaScriptObject"/> class that
|
||||
/// contains values copied from the specified <see cref="JavaScriptObject"/>.
|
||||
/// </summary>
|
||||
/// <param name="javaScriptObject">The <see cref="JavaScriptObject"/> whose elements are copied to the new object.</param>
|
||||
public JavaScriptObject(JavaScriptObject javaScriptObject)
|
||||
: base(javaScriptObject, EqualityComparer<string>.Default)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
#region License
|
||||
// Copyright (c) 2007 James Newton-King
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
public class JavaScriptParameters : ReadOnlyCollection<object>
|
||||
{
|
||||
public static readonly JavaScriptParameters Empty = new JavaScriptParameters(new List<object>());
|
||||
|
||||
public JavaScriptParameters(IList<object> list)
|
||||
: base(list)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,15 +29,16 @@ using System.Text;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
|
||||
/// </summary>
|
||||
public class JsonReader : IDisposable
|
||||
public abstract class JsonReader : IDisposable
|
||||
{
|
||||
private enum State
|
||||
protected enum State
|
||||
{
|
||||
Start,
|
||||
Complete,
|
||||
@@ -54,20 +55,22 @@ namespace Newtonsoft.Json
|
||||
Finished
|
||||
}
|
||||
|
||||
private TextReader _reader;
|
||||
private char _currentChar;
|
||||
|
||||
// current Token data
|
||||
private JsonToken _token;
|
||||
private object _value;
|
||||
private Type _valueType;
|
||||
private char _quoteChar;
|
||||
private StringBuffer _buffer;
|
||||
//private StringBuilder _testBuffer;
|
||||
private State _currentState;
|
||||
|
||||
protected State CurrentState
|
||||
{
|
||||
get { return _currentState; }
|
||||
private set { _currentState = value; }
|
||||
}
|
||||
|
||||
private int _top;
|
||||
private List<JsonType> _stack;
|
||||
|
||||
private List<JsonTokenType> _stack;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the quotation mark character used to enclose the value of a string.
|
||||
@@ -75,6 +78,7 @@ namespace Newtonsoft.Json
|
||||
public char QuoteChar
|
||||
{
|
||||
get { return _quoteChar; }
|
||||
protected set { _quoteChar = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -101,409 +105,55 @@ namespace Newtonsoft.Json
|
||||
get { return _valueType; }
|
||||
}
|
||||
|
||||
public int Depth
|
||||
{
|
||||
get { return _top - 1; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonReader"/> class with the specified <see cref="TextReader"/>.
|
||||
/// </summary>
|
||||
/// <param name="reader">The <c>TextReader</c> containing the XML data to read.</param>
|
||||
public JsonReader(TextReader reader)
|
||||
public JsonReader()
|
||||
{
|
||||
if (reader == null)
|
||||
throw new ArgumentNullException("reader");
|
||||
|
||||
_reader = reader;
|
||||
_buffer = new StringBuffer(4096);
|
||||
//_testBuffer = new StringBuilder();
|
||||
_currentState = State.Start;
|
||||
_stack = new List<JsonType>();
|
||||
_stack = new List<JsonTokenType>();
|
||||
_top = 0;
|
||||
Push(JsonType.None);
|
||||
Push(JsonTokenType.None);
|
||||
}
|
||||
|
||||
private void Push(JsonType value)
|
||||
private void Push(JsonTokenType value)
|
||||
{
|
||||
_stack.Add(value);
|
||||
_top++;
|
||||
}
|
||||
|
||||
private JsonType Pop()
|
||||
private JsonTokenType Pop()
|
||||
{
|
||||
JsonType value = Peek();
|
||||
JsonTokenType value = Peek();
|
||||
_stack.RemoveAt(_stack.Count - 1);
|
||||
_top--;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private JsonType Peek()
|
||||
private JsonTokenType Peek()
|
||||
{
|
||||
return _stack[_top - 1];
|
||||
}
|
||||
|
||||
private void ParseString(char quote)
|
||||
{
|
||||
bool stringTerminated = false;
|
||||
bool hexNumber = false;
|
||||
int hexCount = 0;
|
||||
|
||||
while (!stringTerminated && MoveNext())
|
||||
{
|
||||
if (hexNumber)
|
||||
hexCount++;
|
||||
|
||||
switch (_currentChar)
|
||||
{
|
||||
case '\\':
|
||||
if (MoveNext())
|
||||
{
|
||||
switch (_currentChar)
|
||||
{
|
||||
case 'b':
|
||||
_buffer.Append('\b');
|
||||
break;
|
||||
case 't':
|
||||
_buffer.Append('\t');
|
||||
break;
|
||||
case 'n':
|
||||
_buffer.Append('\n');
|
||||
break;
|
||||
case 'f':
|
||||
_buffer.Append('\f');
|
||||
break;
|
||||
case 'r':
|
||||
_buffer.Append('\r');
|
||||
break;
|
||||
case 'u':
|
||||
// note the start of a hex character
|
||||
hexNumber = true;
|
||||
break;
|
||||
default:
|
||||
_buffer.Append(_currentChar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Unterminated string. Expected delimiter: " + quote);
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
case '\'':
|
||||
if (_currentChar == quote)
|
||||
stringTerminated = true;
|
||||
else
|
||||
goto default;
|
||||
break;
|
||||
default:
|
||||
_buffer.Append(_currentChar);
|
||||
break;
|
||||
}
|
||||
|
||||
if (hexCount == 4)
|
||||
{
|
||||
// remove hex characters from buffer, convert to char and then add
|
||||
string hexString = _buffer.ToString(_buffer.Position - 4, 4);
|
||||
char hexChar = Convert.ToChar(int.Parse(hexString, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo));
|
||||
|
||||
_buffer.Position = _buffer.Position - 4;
|
||||
_buffer.Append(hexChar);
|
||||
|
||||
hexNumber = false;
|
||||
hexCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stringTerminated)
|
||||
throw new JsonReaderException("Unterminated string. Expected delimiter: " + quote);
|
||||
|
||||
ClearCurrentChar();
|
||||
_currentState = State.PostValue;
|
||||
string text = _buffer.ToString();
|
||||
_buffer.Position = 0;
|
||||
|
||||
if (text.StartsWith("/Date(", StringComparison.Ordinal) && text.EndsWith(")/", StringComparison.Ordinal))
|
||||
{
|
||||
ParseDate(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetToken(JsonToken.String, text);
|
||||
_quoteChar = quote;
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseDate(string text)
|
||||
{
|
||||
string value = text.Substring(6, text.Length - 8);
|
||||
DateTimeKind kind = DateTimeKind.Utc;
|
||||
|
||||
int index = value.IndexOf('+', 1);
|
||||
|
||||
if (index == -1)
|
||||
index = value.IndexOf('-', 1);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
kind = DateTimeKind.Local;
|
||||
value = value.Substring(0, index);
|
||||
}
|
||||
|
||||
long javaScriptTicks = long.Parse(value);
|
||||
DateTime utcDateTime = JavaScriptConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
|
||||
DateTime dateTime;
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
case DateTimeKind.Unspecified:
|
||||
dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified);
|
||||
break;
|
||||
case DateTimeKind.Local:
|
||||
dateTime = utcDateTime.ToLocalTime();
|
||||
break;
|
||||
default:
|
||||
dateTime = utcDateTime;
|
||||
break;
|
||||
}
|
||||
|
||||
SetToken(JsonToken.Date, dateTime);
|
||||
}
|
||||
|
||||
private bool MoveNext()
|
||||
{
|
||||
int value = _reader.Read();
|
||||
|
||||
if (value != -1)
|
||||
{
|
||||
_currentChar = (char)value;
|
||||
//_testBuffer.Append(_currentChar);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasNext()
|
||||
{
|
||||
return (_reader.Peek() != -1);
|
||||
}
|
||||
|
||||
private char PeekNext()
|
||||
{
|
||||
return (char)_reader.Peek();
|
||||
}
|
||||
|
||||
private void ClearCurrentChar()
|
||||
{
|
||||
_currentChar = '\0';
|
||||
}
|
||||
|
||||
private bool MoveTo(char value)
|
||||
{
|
||||
while (MoveNext())
|
||||
{
|
||||
if (_currentChar == value)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the next Json token from the stream.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool Read()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (_currentChar == '\0')
|
||||
{
|
||||
if (!MoveNext())
|
||||
return false;
|
||||
}
|
||||
public abstract bool Read();
|
||||
|
||||
switch (_currentState)
|
||||
{
|
||||
case State.Start:
|
||||
case State.Property:
|
||||
case State.Array:
|
||||
case State.ArrayStart:
|
||||
case State.Constructor:
|
||||
case State.ConstructorStart:
|
||||
return ParseValue();
|
||||
case State.Complete:
|
||||
break;
|
||||
case State.Object:
|
||||
case State.ObjectStart:
|
||||
return ParseObject();
|
||||
case State.PostValue:
|
||||
// returns true if it hits
|
||||
// end of object or array
|
||||
if (ParsePostValue())
|
||||
return true;
|
||||
break;
|
||||
case State.Closed:
|
||||
break;
|
||||
case State.Error:
|
||||
break;
|
||||
default:
|
||||
throw new JsonReaderException("Unexpected state: " + _currentState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ParsePostValue()
|
||||
{
|
||||
do
|
||||
{
|
||||
switch (_currentChar)
|
||||
{
|
||||
case '}':
|
||||
SetToken(JsonToken.EndObject);
|
||||
ClearCurrentChar();
|
||||
return true;
|
||||
case ']':
|
||||
SetToken(JsonToken.EndArray);
|
||||
ClearCurrentChar();
|
||||
return true;
|
||||
case ')':
|
||||
SetToken(JsonToken.EndConstructor);
|
||||
ClearCurrentChar();
|
||||
return true;
|
||||
case '/':
|
||||
ParseComment();
|
||||
return true;
|
||||
case ',':
|
||||
// finished paring
|
||||
SetStateBasedOnCurrent();
|
||||
ClearCurrentChar();
|
||||
return false;
|
||||
default:
|
||||
if (char.IsWhiteSpace(_currentChar))
|
||||
{
|
||||
// eat whitespace
|
||||
ClearCurrentChar();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("After parsing a value an unexpected character was encoutered: " + _currentChar);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (MoveNext());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ParseObject()
|
||||
{
|
||||
do
|
||||
{
|
||||
switch (_currentChar)
|
||||
{
|
||||
case '}':
|
||||
SetToken(JsonToken.EndObject);
|
||||
return true;
|
||||
case '/':
|
||||
ParseComment();
|
||||
return true;
|
||||
case ',':
|
||||
SetToken(JsonToken.Undefined);
|
||||
return true;
|
||||
default:
|
||||
if (char.IsWhiteSpace(_currentChar))
|
||||
{
|
||||
// eat
|
||||
}
|
||||
else
|
||||
{
|
||||
return ParseProperty();
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (MoveNext());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ParseProperty()
|
||||
{
|
||||
if (ValidIdentifierChar(_currentChar))
|
||||
{
|
||||
ParseUnquotedProperty();
|
||||
}
|
||||
else if (_currentChar == '"' || _currentChar == '\'')
|
||||
{
|
||||
ParseQuotedProperty(_currentChar);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Invalid property identifier character: " + _currentChar);
|
||||
}
|
||||
|
||||
// finished property. move to colon
|
||||
if (_currentChar != ':')
|
||||
{
|
||||
MoveTo(':');
|
||||
}
|
||||
|
||||
SetToken(JsonToken.PropertyName, _buffer.ToString());
|
||||
_buffer.Position = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ParseQuotedProperty(char quoteChar)
|
||||
{
|
||||
// parse property name until quoted char is hit
|
||||
while (MoveNext())
|
||||
{
|
||||
if (_currentChar == quoteChar)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffer.Append(_currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
throw new JsonReaderException("Unclosed quoted property. Expected: " + quoteChar);
|
||||
}
|
||||
|
||||
private bool ValidIdentifierChar(char value)
|
||||
{
|
||||
return (char.IsLetterOrDigit(_currentChar) || _currentChar == '_' || _currentChar == '$');
|
||||
}
|
||||
|
||||
private void ParseUnquotedProperty()
|
||||
{
|
||||
// parse unquoted property name until whitespace or colon
|
||||
_buffer.Append(_currentChar);
|
||||
|
||||
while (MoveNext())
|
||||
{
|
||||
if (char.IsWhiteSpace(_currentChar) || _currentChar == ':')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (ValidIdentifierChar(_currentChar))
|
||||
{
|
||||
_buffer.Append(_currentChar);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Invalid JavaScript property identifier character: " + _currentChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetToken(JsonToken newToken)
|
||||
protected void SetToken(JsonToken newToken)
|
||||
{
|
||||
SetToken(newToken, null);
|
||||
}
|
||||
|
||||
private void SetToken(JsonToken newToken, object value)
|
||||
protected virtual void SetToken(JsonToken newToken, object value)
|
||||
{
|
||||
_token = newToken;
|
||||
|
||||
@@ -511,37 +161,30 @@ namespace Newtonsoft.Json
|
||||
{
|
||||
case JsonToken.StartObject:
|
||||
_currentState = State.ObjectStart;
|
||||
Push(JsonType.Object);
|
||||
ClearCurrentChar();
|
||||
Push(JsonTokenType.Object);
|
||||
break;
|
||||
case JsonToken.StartArray:
|
||||
_currentState = State.ArrayStart;
|
||||
Push(JsonType.Array);
|
||||
ClearCurrentChar();
|
||||
Push(JsonTokenType.Array);
|
||||
break;
|
||||
case JsonToken.StartConstructor:
|
||||
_currentState = State.ConstructorStart;
|
||||
Push(JsonType.Constructor);
|
||||
ClearCurrentChar();
|
||||
Push(JsonTokenType.Constructor);
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
ValidateEnd(JsonToken.EndObject);
|
||||
ClearCurrentChar();
|
||||
_currentState = State.PostValue;
|
||||
break;
|
||||
case JsonToken.EndArray:
|
||||
ValidateEnd(JsonToken.EndArray);
|
||||
ClearCurrentChar();
|
||||
_currentState = State.PostValue;
|
||||
break;
|
||||
case JsonToken.EndConstructor:
|
||||
ValidateEnd(JsonToken.EndConstructor);
|
||||
ClearCurrentChar();
|
||||
_currentState = State.PostValue;
|
||||
break;
|
||||
case JsonToken.PropertyName:
|
||||
_currentState = State.Property;
|
||||
ClearCurrentChar();
|
||||
break;
|
||||
case JsonToken.Undefined:
|
||||
case JsonToken.Integer:
|
||||
@@ -549,6 +192,7 @@ namespace Newtonsoft.Json
|
||||
case JsonToken.Boolean:
|
||||
case JsonToken.Null:
|
||||
case JsonToken.Date:
|
||||
case JsonToken.String:
|
||||
_currentState = State.PostValue;
|
||||
break;
|
||||
}
|
||||
@@ -565,242 +209,30 @@ namespace Newtonsoft.Json
|
||||
}
|
||||
}
|
||||
|
||||
private bool ParseValue()
|
||||
{
|
||||
do
|
||||
{
|
||||
switch (_currentChar)
|
||||
{
|
||||
case '"':
|
||||
case '\'':
|
||||
ParseString(_currentChar);
|
||||
return true;
|
||||
case 't':
|
||||
ParseTrue();
|
||||
return true;
|
||||
case 'f':
|
||||
ParseFalse();
|
||||
return true;
|
||||
case 'n':
|
||||
if (HasNext())
|
||||
{
|
||||
char next = PeekNext();
|
||||
|
||||
if (next == 'u')
|
||||
ParseNull();
|
||||
else if (next == 'e')
|
||||
ParseConstructor();
|
||||
else
|
||||
throw new JsonReaderException("Unexpected character encountered while parsing value: " + _currentChar);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Unexpected end");
|
||||
}
|
||||
return true;
|
||||
case '/':
|
||||
ParseComment();
|
||||
return true;
|
||||
case 'u':
|
||||
ParseUndefined();
|
||||
return true;
|
||||
case '{':
|
||||
SetToken(JsonToken.StartObject);
|
||||
return true;
|
||||
case '[':
|
||||
SetToken(JsonToken.StartArray);
|
||||
return true;
|
||||
case '}':
|
||||
SetToken(JsonToken.EndObject);
|
||||
return true;
|
||||
case ']':
|
||||
SetToken(JsonToken.EndArray);
|
||||
return true;
|
||||
case ',':
|
||||
SetToken(JsonToken.Undefined);
|
||||
//ClearCurrentChar();
|
||||
return true;
|
||||
case ')':
|
||||
SetToken(JsonToken.EndConstructor);
|
||||
return true;
|
||||
//if (_currentState == State.Constructor)
|
||||
//{
|
||||
// _currentState = State.ConstructorEnd;
|
||||
// return false;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// throw new JsonReaderException("Unexpected character encountered while parsing value: " + _currentChar);
|
||||
//}
|
||||
default:
|
||||
if (char.IsWhiteSpace(_currentChar))
|
||||
{
|
||||
// eat
|
||||
}
|
||||
else if (char.IsNumber(_currentChar) || _currentChar == '-' || _currentChar == '.')
|
||||
{
|
||||
ParseNumber();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Unexpected character encountered while parsing value: " + _currentChar);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (MoveNext());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool EatWhitespace(bool oneOrMore)
|
||||
{
|
||||
bool whitespace = false;
|
||||
while (char.IsWhiteSpace(_currentChar))
|
||||
{
|
||||
whitespace = true;
|
||||
MoveNext();
|
||||
}
|
||||
|
||||
return (!oneOrMore || whitespace);
|
||||
}
|
||||
|
||||
private void ParseConstructor()
|
||||
{
|
||||
if (MatchValue("new", true))
|
||||
{
|
||||
if (EatWhitespace(true))
|
||||
{
|
||||
while (char.IsLetter(_currentChar))
|
||||
{
|
||||
_buffer.Append(_currentChar);
|
||||
MoveNext();
|
||||
}
|
||||
|
||||
|
||||
EatWhitespace(false);
|
||||
|
||||
if (_currentChar != '(')
|
||||
throw new JsonReaderException("Unexpected character while parsing constructor: " + _currentChar);
|
||||
|
||||
string constructorName = _buffer.ToString();
|
||||
_buffer.Position = 0;
|
||||
|
||||
SetToken(JsonToken.StartConstructor);
|
||||
|
||||
_value = constructorName;
|
||||
_valueType = typeof(string);
|
||||
|
||||
//if (string.CompareOrdinal(constructorName, "Date") == 0)
|
||||
//{
|
||||
// IList<object> parameters = new List<object>();
|
||||
|
||||
// MoveNext();
|
||||
// while (ParseValue() && _token != JsonToken.EndConstructor)
|
||||
// {
|
||||
// parameters.Add(_value);
|
||||
// }
|
||||
|
||||
// long javaScriptTicks = Convert.ToInt64(parameters[0]);
|
||||
|
||||
// DateTime date = JavaScriptConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
|
||||
|
||||
// SetToken(JsonToken.Date, date);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
//{
|
||||
// _currentState = State.Constructor;
|
||||
|
||||
// while (ParseValue())
|
||||
// {
|
||||
// parameters.Add(_value);
|
||||
// _currentState = State.Constructor;
|
||||
// }
|
||||
|
||||
// if (string.CompareOrdinal(constructorName, "Date") == 0)
|
||||
// {
|
||||
// long javaScriptTicks = Convert.ToInt64(parameters[0]);
|
||||
|
||||
// DateTime date = JavaScriptConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
|
||||
|
||||
// SetToken(JsonToken.Date, date);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// JavaScriptConstructor constructor = new JavaScriptConstructor(constructorName, new JavaScriptParameters(parameters));
|
||||
|
||||
// if (_currentState == State.ConstructorEnd)
|
||||
// {
|
||||
// SetToken(JsonToken.Constructor, constructor);
|
||||
// }
|
||||
// }
|
||||
|
||||
// // move past ')'
|
||||
// MoveNext();
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseNumber()
|
||||
{
|
||||
// parse until seperator character or end
|
||||
bool end = false;
|
||||
do
|
||||
{
|
||||
if (CurrentIsSeperator())
|
||||
end = true;
|
||||
else
|
||||
_buffer.Append(_currentChar);
|
||||
|
||||
} while (!end && MoveNext());
|
||||
|
||||
string number = _buffer.ToString();
|
||||
object numberValue;
|
||||
JsonToken numberType;
|
||||
|
||||
if (number.IndexOf('.') == -1)
|
||||
{
|
||||
numberValue = Convert.ToInt64(_buffer.ToString(), CultureInfo.InvariantCulture);
|
||||
numberType = JsonToken.Integer;
|
||||
}
|
||||
else
|
||||
{
|
||||
numberValue = Convert.ToDouble(_buffer.ToString(), CultureInfo.InvariantCulture);
|
||||
numberType = JsonToken.Float;
|
||||
}
|
||||
|
||||
_buffer.Position = 0;
|
||||
|
||||
SetToken(numberType, numberValue);
|
||||
}
|
||||
|
||||
private void ValidateEnd(JsonToken endToken)
|
||||
{
|
||||
JsonType currentObject = Pop();
|
||||
JsonTokenType currentObject = Pop();
|
||||
|
||||
if (GetTypeForCloseToken(endToken) != currentObject)
|
||||
throw new JsonReaderException(string.Format("JsonToken {0} is not valid for closing JsonType {1}.", endToken, currentObject));
|
||||
}
|
||||
|
||||
private void SetStateBasedOnCurrent()
|
||||
|
||||
protected void SetStateBasedOnCurrent()
|
||||
{
|
||||
JsonType currentObject = Peek();
|
||||
JsonTokenType currentObject = Peek();
|
||||
|
||||
switch (currentObject)
|
||||
{
|
||||
case JsonType.Object:
|
||||
case JsonTokenType.Object:
|
||||
_currentState = State.Object;
|
||||
break;
|
||||
case JsonType.Array:
|
||||
case JsonTokenType.Array:
|
||||
_currentState = State.Array;
|
||||
break;
|
||||
case JsonType.Constructor:
|
||||
case JsonTokenType.Constructor:
|
||||
_currentState = State.Constructor;
|
||||
break;
|
||||
case JsonType.None:
|
||||
case JsonTokenType.None:
|
||||
_currentState = State.Finished;
|
||||
break;
|
||||
default:
|
||||
@@ -808,172 +240,27 @@ namespace Newtonsoft.Json
|
||||
}
|
||||
}
|
||||
|
||||
private JsonType GetTypeForCloseToken(JsonToken token)
|
||||
private JsonTokenType GetTypeForCloseToken(JsonToken token)
|
||||
{
|
||||
switch (token)
|
||||
{
|
||||
case JsonToken.EndObject:
|
||||
return JsonType.Object;
|
||||
return JsonTokenType.Object;
|
||||
case JsonToken.EndArray:
|
||||
return JsonType.Array;
|
||||
return JsonTokenType.Array;
|
||||
case JsonToken.EndConstructor:
|
||||
return JsonType.Constructor;
|
||||
return JsonTokenType.Constructor;
|
||||
default:
|
||||
throw new JsonReaderException("Not a valid close JsonToken: " + token);
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseComment()
|
||||
{
|
||||
// should have already parsed / character before reaching this method
|
||||
|
||||
MoveNext();
|
||||
|
||||
if (_currentChar == '*')
|
||||
{
|
||||
while (MoveNext())
|
||||
{
|
||||
if (_currentChar == '*')
|
||||
{
|
||||
if (MoveNext())
|
||||
{
|
||||
if (_currentChar == '/')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffer.Append('*');
|
||||
_buffer.Append(_currentChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffer.Append(_currentChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Error parsing comment. Expected: *");
|
||||
}
|
||||
|
||||
SetToken(JsonToken.Comment, _buffer.ToString());
|
||||
|
||||
_buffer.Position = 0;
|
||||
|
||||
ClearCurrentChar();
|
||||
}
|
||||
|
||||
private bool MatchValue(string value)
|
||||
{
|
||||
int i = 0;
|
||||
do
|
||||
{
|
||||
if (_currentChar != value[i])
|
||||
{
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
while (i < value.Length && MoveNext());
|
||||
|
||||
return (i == value.Length);
|
||||
}
|
||||
|
||||
private bool MatchValue(string value, bool noTrailingNonSeperatorCharacters)
|
||||
{
|
||||
// will match value and then move to the next character, checking that it is a seperator character
|
||||
bool match = MatchValue(value);
|
||||
|
||||
if (!noTrailingNonSeperatorCharacters)
|
||||
return match;
|
||||
else
|
||||
return (match && (!MoveNext() || CurrentIsSeperator()));
|
||||
}
|
||||
|
||||
private bool CurrentIsSeperator()
|
||||
{
|
||||
switch (_currentChar)
|
||||
{
|
||||
case '}':
|
||||
case ']':
|
||||
case ',':
|
||||
return true;
|
||||
case '/':
|
||||
// check next character to see if start of a comment
|
||||
return (HasNext() && PeekNext() == '*');
|
||||
case ')':
|
||||
if (_currentState == State.Constructor || _currentState == State.ConstructorStart)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
if (char.IsWhiteSpace(_currentChar))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ParseTrue()
|
||||
{
|
||||
// check characters equal 'true'
|
||||
// and that it is followed by either a seperator character
|
||||
// or the text ends
|
||||
if (MatchValue(JavaScriptConvert.True, true))
|
||||
{
|
||||
SetToken(JsonToken.Boolean, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Error parsing boolean value.");
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseNull()
|
||||
{
|
||||
if (MatchValue(JavaScriptConvert.Null, true))
|
||||
{
|
||||
SetToken(JsonToken.Null);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Error parsing null value.");
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseUndefined()
|
||||
{
|
||||
if (MatchValue(JavaScriptConvert.Undefined, true))
|
||||
{
|
||||
SetToken(JsonToken.Undefined);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Error parsing undefined value.");
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseFalse()
|
||||
{
|
||||
if (MatchValue(JavaScriptConvert.False, true))
|
||||
{
|
||||
SetToken(JsonToken.Boolean, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Error parsing boolean value.");
|
||||
}
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (_currentState != State.Closed && disposing)
|
||||
Close();
|
||||
@@ -982,18 +269,12 @@ namespace Newtonsoft.Json
|
||||
/// <summary>
|
||||
/// Changes the <see cref="State"/> to Closed.
|
||||
/// </summary>
|
||||
public void Close()
|
||||
public virtual void Close()
|
||||
{
|
||||
_currentState = State.Closed;
|
||||
_token = JsonToken.None;
|
||||
_value = null;
|
||||
_valueType = null;
|
||||
|
||||
if (_reader != null)
|
||||
_reader.Close();
|
||||
|
||||
if (_buffer != null)
|
||||
_buffer.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ using System.ComponentModel;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
@@ -140,64 +141,22 @@ namespace Newtonsoft.Json
|
||||
if (!reader.Read())
|
||||
return null;
|
||||
|
||||
return GetObject(reader, objectType);
|
||||
if (objectType != null)
|
||||
return GetObject(reader, objectType);
|
||||
else
|
||||
return CreateJToken(reader);
|
||||
}
|
||||
|
||||
private JavaScriptArray PopulateJavaScriptArray(JsonReader reader)
|
||||
private JToken CreateJToken(JsonReader reader)
|
||||
{
|
||||
JavaScriptArray jsArray = new JavaScriptArray();
|
||||
|
||||
while (reader.Read())
|
||||
JToken token;
|
||||
using (JsonTokenWriter writer = new JsonTokenWriter())
|
||||
{
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonToken.EndArray:
|
||||
return jsArray;
|
||||
case JsonToken.Comment:
|
||||
break;
|
||||
default:
|
||||
object value = GetObject(reader, null);
|
||||
|
||||
jsArray.Add(value);
|
||||
break;
|
||||
}
|
||||
writer.WriteToken(reader);
|
||||
token = writer.Token;
|
||||
}
|
||||
|
||||
throw new JsonSerializationException("Unexpected end while deserializing array.");
|
||||
}
|
||||
|
||||
private JavaScriptObject PopulateJavaScriptObject(JsonReader reader)
|
||||
{
|
||||
JavaScriptObject jsObject = new JavaScriptObject();
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonToken.PropertyName:
|
||||
string memberName = reader.Value.ToString();
|
||||
|
||||
// move to the value token. skip comments
|
||||
do
|
||||
{
|
||||
if (!reader.Read())
|
||||
throw new JsonSerializationException("Unexpected end while deserializing object.");
|
||||
} while (reader.TokenType == JsonToken.Comment);
|
||||
|
||||
object value = GetObject(reader, null);
|
||||
|
||||
jsObject[memberName] = value;
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
return jsObject;
|
||||
case JsonToken.Comment:
|
||||
break;
|
||||
default:
|
||||
throw new JsonSerializationException("Unexpected token while deserializing object: " + reader.TokenType);
|
||||
}
|
||||
}
|
||||
|
||||
throw new JsonSerializationException("Unexpected end while deserializing object.");
|
||||
return token;
|
||||
}
|
||||
|
||||
private object GetObject(JsonReader reader, Type objectType)
|
||||
@@ -218,10 +177,10 @@ namespace Newtonsoft.Json
|
||||
// populate a typed object or generic dictionary/array
|
||||
// depending upon whether an objectType was supplied
|
||||
case JsonToken.StartObject:
|
||||
value = (objectType != null) ? PopulateObject(reader, objectType) : PopulateJavaScriptObject(reader);
|
||||
value = (objectType != null) ? PopulateObject(reader, objectType) : CreateJToken(reader);
|
||||
break;
|
||||
case JsonToken.StartArray:
|
||||
value = (objectType != null) ? PopulateList(reader, objectType) : PopulateJavaScriptArray(reader);
|
||||
value = (objectType != null) ? PopulateList(reader, objectType) : CreateJToken(reader);
|
||||
break;
|
||||
case JsonToken.Integer:
|
||||
case JsonToken.Float:
|
||||
@@ -517,7 +476,7 @@ namespace Newtonsoft.Json
|
||||
/// <param name="value">The <see cref="Object"/> to serialize.</param>
|
||||
public void Serialize(TextWriter textWriter, object value)
|
||||
{
|
||||
Serialize(new JsonWriter(textWriter), value);
|
||||
Serialize(new JsonTextWriter(textWriter), value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -531,7 +490,10 @@ namespace Newtonsoft.Json
|
||||
if (jsonWriter == null)
|
||||
throw new ArgumentNullException("jsonWriter");
|
||||
|
||||
SerializeValue(jsonWriter, value);
|
||||
if (value is JToken)
|
||||
((JToken)value).WriteTo(jsonWriter, (_converters != null) ? _converters.ToArray() : null);
|
||||
else
|
||||
SerializeValue(jsonWriter, value);
|
||||
}
|
||||
|
||||
|
||||
@@ -619,6 +581,10 @@ namespace Newtonsoft.Json
|
||||
{
|
||||
SerializeCollection(writer, (ICollection)value);
|
||||
}
|
||||
else if (value is IEnumerable)
|
||||
{
|
||||
SerializeEnumerable(writer, (IEnumerable)value);
|
||||
}
|
||||
else if (value is Identifier)
|
||||
{
|
||||
writer.WriteRaw(value.ToString());
|
||||
@@ -631,11 +597,16 @@ namespace Newtonsoft.Json
|
||||
|
||||
private bool HasMatchingConverter(Type type, out JsonConverter matchingConverter)
|
||||
{
|
||||
if (_converters != null)
|
||||
return HasMatchingConverter(_converters, type, out matchingConverter);
|
||||
}
|
||||
|
||||
internal static bool HasMatchingConverter(IList<JsonConverter> converters, Type type, out JsonConverter matchingConverter)
|
||||
{
|
||||
if (converters != null)
|
||||
{
|
||||
for (int i = 0; i < _converters.Count; i++)
|
||||
for (int i = 0; i < converters.Count; i++)
|
||||
{
|
||||
JsonConverter converter = _converters[i];
|
||||
JsonConverter converter = converters[i];
|
||||
|
||||
if (converter.CanConvert(type))
|
||||
{
|
||||
@@ -713,6 +684,11 @@ namespace Newtonsoft.Json
|
||||
writer.SerializeStack.Remove(value);
|
||||
}
|
||||
|
||||
private void SerializeEnumerable(JsonWriter writer, IEnumerable values)
|
||||
{
|
||||
SerializeList(writer, values.Cast<object>().ToList());
|
||||
}
|
||||
|
||||
private void SerializeCollection(JsonWriter writer, ICollection values)
|
||||
{
|
||||
object[] collectionValues = new object[values.Count];
|
||||
|
||||
@@ -0,0 +1,755 @@
|
||||
#region License
|
||||
// Copyright (c) 2007 James Newton-King
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
|
||||
/// </summary>
|
||||
public class JsonTextReader : JsonReader
|
||||
{
|
||||
private TextReader _reader;
|
||||
private char _currentChar;
|
||||
|
||||
// current Token data
|
||||
private StringBuffer _buffer;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonReader"/> class with the specified <see cref="TextReader"/>.
|
||||
/// </summary>
|
||||
/// <param name="reader">The <c>TextReader</c> containing the XML data to read.</param>
|
||||
public JsonTextReader(TextReader reader)
|
||||
{
|
||||
if (reader == null)
|
||||
throw new ArgumentNullException("reader");
|
||||
|
||||
_reader = reader;
|
||||
_buffer = new StringBuffer(4096);
|
||||
}
|
||||
|
||||
private void ParseString(char quote)
|
||||
{
|
||||
bool stringTerminated = false;
|
||||
bool hexNumber = false;
|
||||
int hexCount = 0;
|
||||
|
||||
while (!stringTerminated && MoveNext())
|
||||
{
|
||||
if (hexNumber)
|
||||
hexCount++;
|
||||
|
||||
switch (_currentChar)
|
||||
{
|
||||
case '\\':
|
||||
if (MoveNext())
|
||||
{
|
||||
switch (_currentChar)
|
||||
{
|
||||
case 'b':
|
||||
_buffer.Append('\b');
|
||||
break;
|
||||
case 't':
|
||||
_buffer.Append('\t');
|
||||
break;
|
||||
case 'n':
|
||||
_buffer.Append('\n');
|
||||
break;
|
||||
case 'f':
|
||||
_buffer.Append('\f');
|
||||
break;
|
||||
case 'r':
|
||||
_buffer.Append('\r');
|
||||
break;
|
||||
case 'u':
|
||||
// note the start of a hex character
|
||||
hexNumber = true;
|
||||
break;
|
||||
default:
|
||||
_buffer.Append(_currentChar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Unterminated string. Expected delimiter: " + quote);
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
case '\'':
|
||||
if (_currentChar == quote)
|
||||
stringTerminated = true;
|
||||
else
|
||||
goto default;
|
||||
break;
|
||||
default:
|
||||
_buffer.Append(_currentChar);
|
||||
break;
|
||||
}
|
||||
|
||||
if (hexCount == 4)
|
||||
{
|
||||
// remove hex characters from buffer, convert to char and then add
|
||||
string hexString = _buffer.ToString(_buffer.Position - 4, 4);
|
||||
char hexChar = Convert.ToChar(int.Parse(hexString, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo));
|
||||
|
||||
_buffer.Position = _buffer.Position - 4;
|
||||
_buffer.Append(hexChar);
|
||||
|
||||
hexNumber = false;
|
||||
hexCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stringTerminated)
|
||||
throw new JsonReaderException("Unterminated string. Expected delimiter: " + quote);
|
||||
|
||||
ClearCurrentChar();
|
||||
string text = _buffer.ToString();
|
||||
_buffer.Position = 0;
|
||||
|
||||
if (text.StartsWith("/Date(", StringComparison.Ordinal) && text.EndsWith(")/", StringComparison.Ordinal))
|
||||
{
|
||||
ParseDate(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetToken(JsonToken.String, text);
|
||||
QuoteChar = quote;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SetToken(JsonToken newToken, object value)
|
||||
{
|
||||
base.SetToken(newToken, value);
|
||||
|
||||
switch (newToken)
|
||||
{
|
||||
case JsonToken.StartObject:
|
||||
ClearCurrentChar();
|
||||
break;
|
||||
case JsonToken.StartArray:
|
||||
ClearCurrentChar();
|
||||
break;
|
||||
case JsonToken.StartConstructor:
|
||||
ClearCurrentChar();
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
ClearCurrentChar();
|
||||
break;
|
||||
case JsonToken.EndArray:
|
||||
ClearCurrentChar();
|
||||
break;
|
||||
case JsonToken.EndConstructor:
|
||||
ClearCurrentChar();
|
||||
break;
|
||||
case JsonToken.PropertyName:
|
||||
ClearCurrentChar();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseDate(string text)
|
||||
{
|
||||
string value = text.Substring(6, text.Length - 8);
|
||||
DateTimeKind kind = DateTimeKind.Utc;
|
||||
|
||||
int index = value.IndexOf('+', 1);
|
||||
|
||||
if (index == -1)
|
||||
index = value.IndexOf('-', 1);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
kind = DateTimeKind.Local;
|
||||
value = value.Substring(0, index);
|
||||
}
|
||||
|
||||
long javaScriptTicks = long.Parse(value);
|
||||
DateTime utcDateTime = JavaScriptConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
|
||||
DateTime dateTime;
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
case DateTimeKind.Unspecified:
|
||||
dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified);
|
||||
break;
|
||||
case DateTimeKind.Local:
|
||||
dateTime = utcDateTime.ToLocalTime();
|
||||
break;
|
||||
default:
|
||||
dateTime = utcDateTime;
|
||||
break;
|
||||
}
|
||||
|
||||
SetToken(JsonToken.Date, dateTime);
|
||||
}
|
||||
|
||||
private bool MoveNext()
|
||||
{
|
||||
int value = _reader.Read();
|
||||
|
||||
if (value != -1)
|
||||
{
|
||||
_currentChar = (char)value;
|
||||
//_testBuffer.Append(_currentChar);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasNext()
|
||||
{
|
||||
return (_reader.Peek() != -1);
|
||||
}
|
||||
|
||||
private char PeekNext()
|
||||
{
|
||||
return (char)_reader.Peek();
|
||||
}
|
||||
|
||||
private void ClearCurrentChar()
|
||||
{
|
||||
_currentChar = '\0';
|
||||
}
|
||||
|
||||
private bool MoveTo(char value)
|
||||
{
|
||||
while (MoveNext())
|
||||
{
|
||||
if (_currentChar == value)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the next Json token from the stream.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool Read()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (_currentChar == '\0')
|
||||
{
|
||||
if (!MoveNext())
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (CurrentState)
|
||||
{
|
||||
case State.Start:
|
||||
case State.Property:
|
||||
case State.Array:
|
||||
case State.ArrayStart:
|
||||
case State.Constructor:
|
||||
case State.ConstructorStart:
|
||||
return ParseValue();
|
||||
case State.Complete:
|
||||
break;
|
||||
case State.Object:
|
||||
case State.ObjectStart:
|
||||
return ParseObject();
|
||||
case State.PostValue:
|
||||
// returns true if it hits
|
||||
// end of object or array
|
||||
if (ParsePostValue())
|
||||
return true;
|
||||
break;
|
||||
case State.Closed:
|
||||
break;
|
||||
case State.Error:
|
||||
break;
|
||||
default:
|
||||
throw new JsonReaderException("Unexpected state: " + CurrentState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ParsePostValue()
|
||||
{
|
||||
do
|
||||
{
|
||||
switch (_currentChar)
|
||||
{
|
||||
case '}':
|
||||
SetToken(JsonToken.EndObject);
|
||||
ClearCurrentChar();
|
||||
return true;
|
||||
case ']':
|
||||
SetToken(JsonToken.EndArray);
|
||||
ClearCurrentChar();
|
||||
return true;
|
||||
case ')':
|
||||
SetToken(JsonToken.EndConstructor);
|
||||
ClearCurrentChar();
|
||||
return true;
|
||||
case '/':
|
||||
ParseComment();
|
||||
return true;
|
||||
case ',':
|
||||
// finished paring
|
||||
SetStateBasedOnCurrent();
|
||||
ClearCurrentChar();
|
||||
return false;
|
||||
default:
|
||||
if (char.IsWhiteSpace(_currentChar))
|
||||
{
|
||||
// eat whitespace
|
||||
ClearCurrentChar();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("After parsing a value an unexpected character was encoutered: " + _currentChar);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (MoveNext());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ParseObject()
|
||||
{
|
||||
do
|
||||
{
|
||||
switch (_currentChar)
|
||||
{
|
||||
case '}':
|
||||
SetToken(JsonToken.EndObject);
|
||||
return true;
|
||||
case '/':
|
||||
ParseComment();
|
||||
return true;
|
||||
case ',':
|
||||
SetToken(JsonToken.Undefined);
|
||||
return true;
|
||||
default:
|
||||
if (char.IsWhiteSpace(_currentChar))
|
||||
{
|
||||
// eat
|
||||
}
|
||||
else
|
||||
{
|
||||
return ParseProperty();
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (MoveNext());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ParseProperty()
|
||||
{
|
||||
if (ValidIdentifierChar(_currentChar))
|
||||
{
|
||||
ParseUnquotedProperty();
|
||||
}
|
||||
else if (_currentChar == '"' || _currentChar == '\'')
|
||||
{
|
||||
ParseQuotedProperty(_currentChar);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Invalid property identifier character: " + _currentChar);
|
||||
}
|
||||
|
||||
// finished property. move to colon
|
||||
if (_currentChar != ':')
|
||||
{
|
||||
MoveTo(':');
|
||||
}
|
||||
|
||||
SetToken(JsonToken.PropertyName, _buffer.ToString());
|
||||
_buffer.Position = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ParseQuotedProperty(char quoteChar)
|
||||
{
|
||||
// parse property name until quoted char is hit
|
||||
while (MoveNext())
|
||||
{
|
||||
if (_currentChar == quoteChar)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffer.Append(_currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
throw new JsonReaderException("Unclosed quoted property. Expected: " + quoteChar);
|
||||
}
|
||||
|
||||
private bool ValidIdentifierChar(char value)
|
||||
{
|
||||
return (char.IsLetterOrDigit(_currentChar) || _currentChar == '_' || _currentChar == '$');
|
||||
}
|
||||
|
||||
private void ParseUnquotedProperty()
|
||||
{
|
||||
// parse unquoted property name until whitespace or colon
|
||||
_buffer.Append(_currentChar);
|
||||
|
||||
while (MoveNext())
|
||||
{
|
||||
if (char.IsWhiteSpace(_currentChar) || _currentChar == ':')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (ValidIdentifierChar(_currentChar))
|
||||
{
|
||||
_buffer.Append(_currentChar);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Invalid JavaScript property identifier character: " + _currentChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ParseValue()
|
||||
{
|
||||
do
|
||||
{
|
||||
switch (_currentChar)
|
||||
{
|
||||
case '"':
|
||||
case '\'':
|
||||
ParseString(_currentChar);
|
||||
return true;
|
||||
case 't':
|
||||
ParseTrue();
|
||||
return true;
|
||||
case 'f':
|
||||
ParseFalse();
|
||||
return true;
|
||||
case 'n':
|
||||
if (HasNext())
|
||||
{
|
||||
char next = PeekNext();
|
||||
|
||||
if (next == 'u')
|
||||
ParseNull();
|
||||
else if (next == 'e')
|
||||
ParseConstructor();
|
||||
else
|
||||
throw new JsonReaderException("Unexpected character encountered while parsing value: " + _currentChar);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Unexpected end");
|
||||
}
|
||||
return true;
|
||||
case '/':
|
||||
ParseComment();
|
||||
return true;
|
||||
case 'u':
|
||||
ParseUndefined();
|
||||
return true;
|
||||
case '{':
|
||||
SetToken(JsonToken.StartObject);
|
||||
return true;
|
||||
case '[':
|
||||
SetToken(JsonToken.StartArray);
|
||||
return true;
|
||||
case '}':
|
||||
SetToken(JsonToken.EndObject);
|
||||
return true;
|
||||
case ']':
|
||||
SetToken(JsonToken.EndArray);
|
||||
return true;
|
||||
case ',':
|
||||
SetToken(JsonToken.Undefined);
|
||||
//ClearCurrentChar();
|
||||
return true;
|
||||
case ')':
|
||||
SetToken(JsonToken.EndConstructor);
|
||||
return true;
|
||||
default:
|
||||
if (char.IsWhiteSpace(_currentChar))
|
||||
{
|
||||
// eat
|
||||
}
|
||||
else if (char.IsNumber(_currentChar) || _currentChar == '-' || _currentChar == '.')
|
||||
{
|
||||
ParseNumber();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Unexpected character encountered while parsing value: " + _currentChar);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (MoveNext());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool EatWhitespace(bool oneOrMore)
|
||||
{
|
||||
bool whitespace = false;
|
||||
while (char.IsWhiteSpace(_currentChar))
|
||||
{
|
||||
whitespace = true;
|
||||
MoveNext();
|
||||
}
|
||||
|
||||
return (!oneOrMore || whitespace);
|
||||
}
|
||||
|
||||
private void ParseConstructor()
|
||||
{
|
||||
if (MatchValue("new", true))
|
||||
{
|
||||
if (EatWhitespace(true))
|
||||
{
|
||||
while (char.IsLetter(_currentChar))
|
||||
{
|
||||
_buffer.Append(_currentChar);
|
||||
MoveNext();
|
||||
}
|
||||
|
||||
EatWhitespace(false);
|
||||
|
||||
if (_currentChar != '(')
|
||||
throw new JsonReaderException("Unexpected character while parsing constructor: " + _currentChar);
|
||||
|
||||
string constructorName = _buffer.ToString();
|
||||
_buffer.Position = 0;
|
||||
|
||||
SetToken(JsonToken.StartConstructor, constructorName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseNumber()
|
||||
{
|
||||
// parse until seperator character or end
|
||||
bool end = false;
|
||||
do
|
||||
{
|
||||
if (CurrentIsSeperator())
|
||||
end = true;
|
||||
else
|
||||
_buffer.Append(_currentChar);
|
||||
|
||||
} while (!end && MoveNext());
|
||||
|
||||
string number = _buffer.ToString();
|
||||
object numberValue;
|
||||
JsonToken numberType;
|
||||
|
||||
if (number.IndexOf('.') == -1)
|
||||
{
|
||||
numberValue = Convert.ToInt64(_buffer.ToString(), CultureInfo.InvariantCulture);
|
||||
numberType = JsonToken.Integer;
|
||||
}
|
||||
else
|
||||
{
|
||||
numberValue = Convert.ToDouble(_buffer.ToString(), CultureInfo.InvariantCulture);
|
||||
numberType = JsonToken.Float;
|
||||
}
|
||||
|
||||
_buffer.Position = 0;
|
||||
|
||||
SetToken(numberType, numberValue);
|
||||
}
|
||||
|
||||
private void ParseComment()
|
||||
{
|
||||
// should have already parsed / character before reaching this method
|
||||
|
||||
MoveNext();
|
||||
|
||||
if (_currentChar == '*')
|
||||
{
|
||||
while (MoveNext())
|
||||
{
|
||||
if (_currentChar == '*')
|
||||
{
|
||||
if (MoveNext())
|
||||
{
|
||||
if (_currentChar == '/')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffer.Append('*');
|
||||
_buffer.Append(_currentChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffer.Append(_currentChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Error parsing comment. Expected: *");
|
||||
}
|
||||
|
||||
SetToken(JsonToken.Comment, _buffer.ToString());
|
||||
|
||||
_buffer.Position = 0;
|
||||
|
||||
ClearCurrentChar();
|
||||
}
|
||||
|
||||
private bool MatchValue(string value)
|
||||
{
|
||||
int i = 0;
|
||||
do
|
||||
{
|
||||
if (_currentChar != value[i])
|
||||
{
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
while (i < value.Length && MoveNext());
|
||||
|
||||
return (i == value.Length);
|
||||
}
|
||||
|
||||
private bool MatchValue(string value, bool noTrailingNonSeperatorCharacters)
|
||||
{
|
||||
// will match value and then move to the next character, checking that it is a seperator character
|
||||
bool match = MatchValue(value);
|
||||
|
||||
if (!noTrailingNonSeperatorCharacters)
|
||||
return match;
|
||||
else
|
||||
return (match && (!MoveNext() || CurrentIsSeperator()));
|
||||
}
|
||||
|
||||
private bool CurrentIsSeperator()
|
||||
{
|
||||
switch (_currentChar)
|
||||
{
|
||||
case '}':
|
||||
case ']':
|
||||
case ',':
|
||||
return true;
|
||||
case '/':
|
||||
// check next character to see if start of a comment
|
||||
return (HasNext() && PeekNext() == '*');
|
||||
case ')':
|
||||
if (CurrentState == State.Constructor || CurrentState == State.ConstructorStart)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
if (char.IsWhiteSpace(_currentChar))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ParseTrue()
|
||||
{
|
||||
// check characters equal 'true'
|
||||
// and that it is followed by either a seperator character
|
||||
// or the text ends
|
||||
if (MatchValue(JavaScriptConvert.True, true))
|
||||
{
|
||||
SetToken(JsonToken.Boolean, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Error parsing boolean value.");
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseNull()
|
||||
{
|
||||
if (MatchValue(JavaScriptConvert.Null, true))
|
||||
{
|
||||
SetToken(JsonToken.Null);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Error parsing null value.");
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseUndefined()
|
||||
{
|
||||
if (MatchValue(JavaScriptConvert.Undefined, true))
|
||||
{
|
||||
SetToken(JsonToken.Undefined);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Error parsing undefined value.");
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseFalse()
|
||||
{
|
||||
if (MatchValue(JavaScriptConvert.False, true))
|
||||
{
|
||||
SetToken(JsonToken.Boolean, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonReaderException("Error parsing boolean value.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the <see cref="State"/> to Closed.
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
base.Close();
|
||||
|
||||
if (_reader != null)
|
||||
_reader.Close();
|
||||
|
||||
if (_buffer != null)
|
||||
_buffer.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,441 @@
|
||||
#region License
|
||||
// Copyright (c) 2007 James Newton-King
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
|
||||
/// </summary>
|
||||
public class JsonTextWriter : JsonWriter
|
||||
{
|
||||
private TextWriter _writer;
|
||||
private char _indentChar;
|
||||
private int _indentation;
|
||||
private char _quoteChar;
|
||||
private bool _quoteName;
|
||||
|
||||
/// <summary>
|
||||
/// 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>.
|
||||
/// </summary>
|
||||
public int Indentation
|
||||
{
|
||||
get { return _indentation; }
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
throw new ArgumentException("Indentation value must be greater than 0.");
|
||||
|
||||
_indentation = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets which character to use to quote attribute values.
|
||||
/// </summary>
|
||||
public char QuoteChar
|
||||
{
|
||||
get { return _quoteChar; }
|
||||
set
|
||||
{
|
||||
if (value != '"' && value != '\'')
|
||||
throw new ArgumentException(@"Invalid JavaScript string quote character. Valid quote characters are ' and "".");
|
||||
|
||||
_quoteChar = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets which character to use for indenting when <paramref name="Formatting"/> is set to <c>Formatting.Indented</c>.
|
||||
/// </summary>
|
||||
public char IndentChar
|
||||
{
|
||||
get { return _indentChar; }
|
||||
set { _indentChar = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether object names will be surrounded with quotes.
|
||||
/// </summary>
|
||||
public bool QuoteName
|
||||
{
|
||||
get { return _quoteName; }
|
||||
set { _quoteName = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of the <c>JsonWriter</c> class using the specified <see cref="TextWriter"/>.
|
||||
/// </summary>
|
||||
/// <param name="textWriter">The <c>TextWriter</c> to write to.</param>
|
||||
public JsonTextWriter(TextWriter textWriter)
|
||||
{
|
||||
if (textWriter == null)
|
||||
throw new ArgumentNullException("textWriter");
|
||||
|
||||
_writer = textWriter;
|
||||
_quoteChar = '"';
|
||||
_quoteName = true;
|
||||
_indentChar = ' ';
|
||||
_indentation = 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
|
||||
/// </summary>
|
||||
public override void Flush()
|
||||
{
|
||||
_writer.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes this stream and the underlying stream.
|
||||
/// </summary>
|
||||
public override void Close()
|
||||
{
|
||||
base.Close();
|
||||
|
||||
_writer.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the beginning of a Json object.
|
||||
/// </summary>
|
||||
public override void WriteStartObject()
|
||||
{
|
||||
base.WriteStartObject();
|
||||
|
||||
_writer.Write("{");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the beginning of a Json array.
|
||||
/// </summary>
|
||||
public override void WriteStartArray()
|
||||
{
|
||||
base.WriteStartArray();
|
||||
|
||||
_writer.Write("[");
|
||||
}
|
||||
|
||||
public override void WriteStartConstructor(string name)
|
||||
{
|
||||
base.WriteStartConstructor(name);
|
||||
|
||||
_writer.Write("new ");
|
||||
_writer.Write(name);
|
||||
_writer.Write("(");
|
||||
}
|
||||
|
||||
protected override void WriteEnd(JsonToken token)
|
||||
{
|
||||
switch (token)
|
||||
{
|
||||
case JsonToken.EndObject:
|
||||
_writer.Write("}");
|
||||
break;
|
||||
case JsonToken.EndArray:
|
||||
_writer.Write("]");
|
||||
break;
|
||||
case JsonToken.EndConstructor:
|
||||
_writer.Write(")");
|
||||
break;
|
||||
default:
|
||||
throw new JsonWriterException("Invalid JsonToken: " + token);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the property name of a name/value pair on a Json object.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public override void WritePropertyName(string name)
|
||||
{
|
||||
base.WritePropertyName(name);
|
||||
|
||||
if (_quoteName)
|
||||
_writer.Write(_quoteChar);
|
||||
|
||||
_writer.Write(name);
|
||||
|
||||
if (_quoteName)
|
||||
_writer.Write(_quoteChar);
|
||||
|
||||
_writer.Write(':');
|
||||
}
|
||||
|
||||
protected override void WriteIndent()
|
||||
{
|
||||
if (Formatting == Formatting.Indented)
|
||||
{
|
||||
_writer.Write(Environment.NewLine);
|
||||
// for each level of object...
|
||||
for (int i = 0; i < Top; i++)
|
||||
{
|
||||
// ...write the indent char the specified number of times
|
||||
for (int j = 0; j < _indentation; j++)
|
||||
{
|
||||
_writer.Write(_indentChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void WriteValueDelimiter()
|
||||
{
|
||||
_writer.Write(',');
|
||||
}
|
||||
|
||||
protected override void WriteIndentSpace()
|
||||
{
|
||||
_writer.Write(' ');
|
||||
}
|
||||
|
||||
private void WriteValueInternal(string value, JsonToken token)
|
||||
{
|
||||
_writer.Write(value);
|
||||
}
|
||||
|
||||
#region WriteValue methods
|
||||
/// <summary>
|
||||
/// Writes a null value.
|
||||
/// </summary>
|
||||
public override void WriteNull()
|
||||
{
|
||||
base.WriteNull();
|
||||
WriteValueInternal(JavaScriptConvert.Null, JsonToken.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an undefined value.
|
||||
/// </summary>
|
||||
public override void WriteUndefined()
|
||||
{
|
||||
base.WriteUndefined();
|
||||
WriteValueInternal(JavaScriptConvert.Undefined, JsonToken.Undefined);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes raw JavaScript manually.
|
||||
/// </summary>
|
||||
/// <param name="javaScript">The raw JavaScript to write.</param>
|
||||
public override void WriteRaw(string javaScript)
|
||||
{
|
||||
base.WriteRaw(javaScript);
|
||||
// hack. some 'raw' or 'other' token perhaps?
|
||||
WriteValueInternal(javaScript, JsonToken.Undefined);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="String"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="String"/> value to write.</param>
|
||||
public override void WriteValue(string value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value, _quoteChar), JsonToken.String);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Int32"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Int32"/> value to write.</param>
|
||||
public override void WriteValue(int value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="UInt32"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="UInt32"/> value to write.</param>
|
||||
public override void WriteValue(uint value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Int64"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Int64"/> value to write.</param>
|
||||
public override void WriteValue(long value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="UInt64"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="UInt64"/> value to write.</param>
|
||||
public override void WriteValue(ulong value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Single"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Single"/> value to write.</param>
|
||||
public override void WriteValue(float value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Float);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Double"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Double"/> value to write.</param>
|
||||
public override void WriteValue(double value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Float);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Boolean"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Boolean"/> value to write.</param>
|
||||
public override void WriteValue(bool value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Boolean);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Int16"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Int16"/> value to write.</param>
|
||||
public override void WriteValue(short value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="UInt16"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="UInt16"/> value to write.</param>
|
||||
public override void WriteValue(ushort value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Char"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Char"/> value to write.</param>
|
||||
public override void WriteValue(char value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Byte"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Byte"/> value to write.</param>
|
||||
public override void WriteValue(byte value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="SByte"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="SByte"/> value to write.</param>
|
||||
public override void WriteValue(sbyte value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Decimal"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Decimal"/> value to write.</param>
|
||||
public override void WriteValue(decimal value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Float);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="DateTime"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="DateTime"/> value to write.</param>
|
||||
public override void WriteValue(DateTime value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Date);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="DateTimeOffset"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
|
||||
public override void WriteValue(DateTimeOffset value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Date);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Writes out a comment <code>/*...*/</code> containing the specified text.
|
||||
/// </summary>
|
||||
/// <param name="text">Text to place inside the comment.</param>
|
||||
public override void WriteComment(string text)
|
||||
{
|
||||
base.WriteComment(text);
|
||||
|
||||
_writer.Write("/*");
|
||||
_writer.Write(text);
|
||||
_writer.Write("*/");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes out the given white space.
|
||||
/// </summary>
|
||||
/// <param name="ws">The string of white space characters.</param>
|
||||
public override void WriteWhitespace(string ws)
|
||||
{
|
||||
base.WriteWhitespace(ws);
|
||||
|
||||
_writer.Write(ws);
|
||||
}
|
||||
}
|
||||
}
|
||||
+178
-211
@@ -29,17 +29,10 @@ using System.Text;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
internal enum JsonType
|
||||
{
|
||||
Object,
|
||||
Array,
|
||||
Constructor,
|
||||
None
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the state of the <see cref="JsonWriter"/>.
|
||||
/// </summary>
|
||||
@@ -95,7 +88,7 @@ namespace Newtonsoft.Json
|
||||
/// <summary>
|
||||
/// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
|
||||
/// </summary>
|
||||
public class JsonWriter : IDisposable
|
||||
public abstract class JsonWriter : IDisposable
|
||||
{
|
||||
private enum State
|
||||
{
|
||||
@@ -125,15 +118,11 @@ namespace Newtonsoft.Json
|
||||
};
|
||||
|
||||
private int _top;
|
||||
private List<JsonType> _stack;
|
||||
|
||||
private List<JsonTokenType> _stack;
|
||||
private List<object> _serializeStack;
|
||||
private TextWriter _writer;
|
||||
private Formatting _formatting;
|
||||
private char _indentChar;
|
||||
private int _indentation;
|
||||
private char _quoteChar;
|
||||
private bool _quoteName;
|
||||
private State _currentState;
|
||||
private Formatting _formatting;
|
||||
|
||||
internal List<object> SerializeStack
|
||||
{
|
||||
@@ -146,6 +135,11 @@ namespace Newtonsoft.Json
|
||||
}
|
||||
}
|
||||
|
||||
protected int Top
|
||||
{
|
||||
get { return _top; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the state of the writer.
|
||||
/// </summary>
|
||||
@@ -187,75 +181,19 @@ namespace Newtonsoft.Json
|
||||
set { _formatting = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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>.
|
||||
/// </summary>
|
||||
public int Indentation
|
||||
{
|
||||
get { return _indentation; }
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
throw new ArgumentException("Indentation value must be greater than 0.");
|
||||
|
||||
_indentation = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets which character to use to quote attribute values.
|
||||
/// </summary>
|
||||
public char QuoteChar
|
||||
{
|
||||
get { return _quoteChar; }
|
||||
set
|
||||
{
|
||||
if (value != '"' && value != '\'')
|
||||
throw new ArgumentException(@"Invalid JavaScript string quote character. Valid quote characters are ' and "".");
|
||||
|
||||
_quoteChar = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets which character to use for indenting when <paramref name="Formatting"/> is set to <c>Formatting.Indented</c>.
|
||||
/// </summary>
|
||||
public char IndentChar
|
||||
{
|
||||
get { return _indentChar; }
|
||||
set { _indentChar = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether object names will be surrounded with quotes.
|
||||
/// </summary>
|
||||
public bool QuoteName
|
||||
{
|
||||
get { return _quoteName; }
|
||||
set { _quoteName = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of the <c>JsonWriter</c> class using the specified <see cref="TextWriter"/>.
|
||||
/// </summary>
|
||||
/// <param name="textWriter">The <c>TextWriter</c> to write to.</param>
|
||||
public JsonWriter(TextWriter textWriter)
|
||||
public JsonWriter()
|
||||
{
|
||||
if (textWriter == null)
|
||||
throw new ArgumentNullException("textWriter");
|
||||
|
||||
_writer = textWriter;
|
||||
_quoteChar = '"';
|
||||
_quoteName = true;
|
||||
_indentChar = ' ';
|
||||
_indentation = 2;
|
||||
_formatting = Formatting.None;
|
||||
_stack = new List<JsonType>(1);
|
||||
_stack.Add(JsonType.None);
|
||||
_stack = new List<JsonTokenType>(1);
|
||||
_stack.Add(JsonTokenType.None);
|
||||
_currentState = State.Start;
|
||||
_formatting = Formatting.None;
|
||||
}
|
||||
|
||||
private void Push(JsonType value)
|
||||
private void Push(JsonTokenType value)
|
||||
{
|
||||
_top++;
|
||||
if (_stack.Count <= _top)
|
||||
@@ -264,15 +202,15 @@ namespace Newtonsoft.Json
|
||||
_stack[_top] = value;
|
||||
}
|
||||
|
||||
private JsonType Pop()
|
||||
private JsonTokenType Pop()
|
||||
{
|
||||
JsonType value = Peek();
|
||||
JsonTokenType value = Peek();
|
||||
_top--;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private JsonType Peek()
|
||||
private JsonTokenType Peek()
|
||||
{
|
||||
return _stack[_top];
|
||||
}
|
||||
@@ -280,31 +218,23 @@ namespace Newtonsoft.Json
|
||||
/// <summary>
|
||||
/// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
|
||||
/// </summary>
|
||||
public void Flush()
|
||||
{
|
||||
_writer.Flush();
|
||||
}
|
||||
public abstract void Flush();
|
||||
|
||||
/// <summary>
|
||||
/// Closes this stream and the underlying stream.
|
||||
/// </summary>
|
||||
public void Close()
|
||||
public virtual void Close()
|
||||
{
|
||||
AutoCompleteAll();
|
||||
|
||||
_writer.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the beginning of a Json object.
|
||||
/// </summary>
|
||||
public void WriteStartObject()
|
||||
public virtual void WriteStartObject()
|
||||
{
|
||||
AutoComplete(JsonToken.StartObject);
|
||||
|
||||
Push(JsonType.Object);
|
||||
|
||||
_writer.Write("{");
|
||||
Push(JsonTokenType.Object);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -318,11 +248,10 @@ namespace Newtonsoft.Json
|
||||
/// <summary>
|
||||
/// Writes the beginning of a Json array.
|
||||
/// </summary>
|
||||
public void WriteStartArray()
|
||||
public virtual void WriteStartArray()
|
||||
{
|
||||
AutoComplete(JsonToken.StartArray);
|
||||
Push(JsonType.Array);
|
||||
_writer.Write("[");
|
||||
Push(JsonTokenType.Array);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -333,13 +262,10 @@ namespace Newtonsoft.Json
|
||||
AutoCompleteClose(JsonToken.EndArray);
|
||||
}
|
||||
|
||||
public void WriteStartConstructor(string name)
|
||||
public virtual void WriteStartConstructor(string name)
|
||||
{
|
||||
AutoComplete(JsonToken.StartConstructor);
|
||||
Push(JsonType.Constructor);
|
||||
_writer.Write("new ");
|
||||
_writer.Write(name);
|
||||
_writer.Write("(");
|
||||
Push(JsonTokenType.Constructor);
|
||||
}
|
||||
|
||||
public void WriteEndConstructor()
|
||||
@@ -351,20 +277,9 @@ namespace Newtonsoft.Json
|
||||
/// Writes the property name of a name/value pair on a Json object.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public void WritePropertyName(string name)
|
||||
public virtual void WritePropertyName(string name)
|
||||
{
|
||||
//_objectStack.Push(new JsonObjectInfo(JsonType.Property));
|
||||
AutoComplete(JsonToken.PropertyName);
|
||||
|
||||
if (_quoteName)
|
||||
_writer.Write(_quoteChar);
|
||||
|
||||
_writer.Write(name);
|
||||
|
||||
if (_quoteName)
|
||||
_writer.Write(_quoteChar);
|
||||
|
||||
_writer.Write(':');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -375,17 +290,95 @@ namespace Newtonsoft.Json
|
||||
WriteEnd(Peek());
|
||||
}
|
||||
|
||||
private void WriteEnd(JsonType type)
|
||||
public void WriteToken(JsonReader reader)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(reader, "reader");
|
||||
|
||||
int currentDepth = (reader.TokenType == JsonToken.None) ? -1 : reader.Depth;
|
||||
bool continue1;
|
||||
do
|
||||
{
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonToken.None:
|
||||
// read to next
|
||||
break;
|
||||
case JsonToken.StartObject:
|
||||
WriteStartObject();
|
||||
break;
|
||||
case JsonToken.StartArray:
|
||||
WriteStartArray();
|
||||
break;
|
||||
case JsonToken.StartConstructor:
|
||||
WriteStartConstructor(reader.Value.ToString());
|
||||
break;
|
||||
case JsonToken.PropertyName:
|
||||
WritePropertyName(reader.Value.ToString());
|
||||
break;
|
||||
case JsonToken.Comment:
|
||||
WriteComment(reader.Value.ToString());
|
||||
break;
|
||||
case JsonToken.Integer:
|
||||
WriteValue((long)reader.Value);
|
||||
break;
|
||||
case JsonToken.Float:
|
||||
WriteValue((double)reader.Value);
|
||||
break;
|
||||
case JsonToken.String:
|
||||
WriteValue(reader.Value.ToString());
|
||||
break;
|
||||
case JsonToken.Boolean:
|
||||
WriteValue((bool)reader.Value);
|
||||
break;
|
||||
case JsonToken.Null:
|
||||
WriteNull();
|
||||
break;
|
||||
case JsonToken.Undefined:
|
||||
WriteUndefined();
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
WriteEndObject();
|
||||
break;
|
||||
case JsonToken.EndArray:
|
||||
WriteEndArray();
|
||||
break;
|
||||
case JsonToken.EndConstructor:
|
||||
WriteEndConstructor();
|
||||
break;
|
||||
case JsonToken.Date:
|
||||
WriteValue((DateTime)reader.Value);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("TokenType", reader.TokenType, "Unexpected token type.");
|
||||
}
|
||||
}
|
||||
while (reader.Read() && (currentDepth - 1 < reader.Depth || (currentDepth == reader.Depth && !IsEndToken(reader.TokenType))));
|
||||
}
|
||||
|
||||
private bool IsEndToken(JsonToken token)
|
||||
{
|
||||
switch (token)
|
||||
{
|
||||
case JsonToken.EndObject:
|
||||
case JsonToken.EndArray:
|
||||
case JsonToken.EndConstructor:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteEnd(JsonTokenType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case JsonType.Object:
|
||||
case JsonTokenType.Object:
|
||||
WriteEndObject();
|
||||
break;
|
||||
case JsonType.Array:
|
||||
case JsonTokenType.Array:
|
||||
WriteEndArray();
|
||||
break;
|
||||
case JsonType.Constructor:
|
||||
case JsonTokenType.Constructor:
|
||||
WriteEndConstructor();
|
||||
break;
|
||||
default:
|
||||
@@ -401,30 +394,30 @@ namespace Newtonsoft.Json
|
||||
}
|
||||
}
|
||||
|
||||
private JsonType GetTypeForCloseToken(JsonToken token)
|
||||
private JsonTokenType GetTypeForCloseToken(JsonToken token)
|
||||
{
|
||||
switch (token)
|
||||
{
|
||||
case JsonToken.EndObject:
|
||||
return JsonType.Object;
|
||||
return JsonTokenType.Object;
|
||||
case JsonToken.EndArray:
|
||||
return JsonType.Array;
|
||||
return JsonTokenType.Array;
|
||||
case JsonToken.EndConstructor:
|
||||
return JsonType.Constructor;
|
||||
return JsonTokenType.Constructor;
|
||||
default:
|
||||
throw new JsonWriterException("No type for token: " + token);
|
||||
}
|
||||
}
|
||||
|
||||
private JsonToken GetCloseTokenForType(JsonType type)
|
||||
private JsonToken GetCloseTokenForType(JsonTokenType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case JsonType.Object:
|
||||
case JsonTokenType.Object:
|
||||
return JsonToken.EndObject;
|
||||
case JsonType.Array:
|
||||
case JsonTokenType.Array:
|
||||
return JsonToken.EndArray;
|
||||
case JsonType.Constructor:
|
||||
case JsonTokenType.Constructor:
|
||||
return JsonToken.EndConstructor;
|
||||
default:
|
||||
throw new JsonWriterException("No close token for type: " + type);
|
||||
@@ -458,33 +451,20 @@ namespace Newtonsoft.Json
|
||||
if (_currentState != State.ObjectStart && _currentState != State.ArrayStart)
|
||||
WriteIndent();
|
||||
|
||||
switch (token)
|
||||
{
|
||||
case JsonToken.EndObject:
|
||||
_writer.Write("}");
|
||||
break;
|
||||
case JsonToken.EndArray:
|
||||
_writer.Write("]");
|
||||
break;
|
||||
case JsonToken.EndConstructor:
|
||||
_writer.Write(")");
|
||||
break;
|
||||
default:
|
||||
throw new JsonWriterException("Invalid JsonToken: " + token);
|
||||
}
|
||||
WriteEnd(token);
|
||||
}
|
||||
|
||||
JsonType currentLevelType = Peek();
|
||||
JsonTokenType currentLevelType = Peek();
|
||||
|
||||
switch (currentLevelType)
|
||||
{
|
||||
case JsonType.Object:
|
||||
case JsonTokenType.Object:
|
||||
_currentState = State.Object;
|
||||
break;
|
||||
case JsonType.Array:
|
||||
case JsonTokenType.Array:
|
||||
_currentState = State.Array;
|
||||
break;
|
||||
case JsonType.None:
|
||||
case JsonTokenType.None:
|
||||
_currentState = State.Start;
|
||||
break;
|
||||
default:
|
||||
@@ -492,21 +472,20 @@ namespace Newtonsoft.Json
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteIndent()
|
||||
protected virtual void WriteEnd(JsonToken token)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void WriteIndent()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void WriteValueDelimiter()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void WriteIndentSpace()
|
||||
{
|
||||
if (_formatting == Formatting.Indented)
|
||||
{
|
||||
_writer.Write(Environment.NewLine);
|
||||
// for each level of object...
|
||||
for (int i = 0; i < _top; i++)
|
||||
{
|
||||
// ...write the indent char the specified number of times
|
||||
for (int j = 0; j < _indentation; j++)
|
||||
{
|
||||
_writer.Write(_indentChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AutoComplete(JsonToken tokenBeingWritten)
|
||||
@@ -538,12 +517,12 @@ namespace Newtonsoft.Json
|
||||
|
||||
if ((_currentState == State.Object || _currentState == State.Array || _currentState == State.Constructor) && tokenBeingWritten != JsonToken.Comment)
|
||||
{
|
||||
_writer.Write(',');
|
||||
WriteValueDelimiter();
|
||||
}
|
||||
else if (_currentState == State.Property)
|
||||
{
|
||||
if (_formatting == Formatting.Indented)
|
||||
_writer.Write(' ');
|
||||
WriteIndentSpace();
|
||||
}
|
||||
|
||||
// don't indent a property when it is the first token to be written (i.e. at the start)
|
||||
@@ -556,182 +535,175 @@ namespace Newtonsoft.Json
|
||||
_currentState = newState;
|
||||
}
|
||||
|
||||
private void WriteValueInternal(string value, JsonToken token)
|
||||
{
|
||||
AutoComplete(token);
|
||||
|
||||
_writer.Write(value);
|
||||
}
|
||||
|
||||
#region WriteValue methods
|
||||
/// <summary>
|
||||
/// Writes a null value.
|
||||
/// </summary>
|
||||
public void WriteNull()
|
||||
public virtual void WriteNull()
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.Null, JsonToken.Null);
|
||||
AutoComplete(JsonToken.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an undefined value.
|
||||
/// </summary>
|
||||
public void WriteUndefined()
|
||||
public virtual void WriteUndefined()
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.Undefined, JsonToken.Undefined);
|
||||
AutoComplete(JsonToken.Undefined);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes raw JavaScript manually.
|
||||
/// </summary>
|
||||
/// <param name="javaScript">The raw JavaScript to write.</param>
|
||||
public void WriteRaw(string javaScript)
|
||||
public virtual void WriteRaw(string javaScript)
|
||||
{
|
||||
// hack. some 'raw' or 'other' token perhaps?
|
||||
WriteValueInternal(javaScript, JsonToken.Undefined);
|
||||
AutoComplete(JsonToken.Undefined);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="String"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="String"/> value to write.</param>
|
||||
public void WriteValue(string value)
|
||||
public virtual void WriteValue(string value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value, _quoteChar), JsonToken.String);
|
||||
AutoComplete(JsonToken.String);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Int32"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Int32"/> value to write.</param>
|
||||
public void WriteValue(int value)
|
||||
public virtual void WriteValue(int value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
AutoComplete(JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="UInt32"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="UInt32"/> value to write.</param>
|
||||
public void WriteValue(uint value)
|
||||
public virtual void WriteValue(uint value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
AutoComplete(JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Int64"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Int64"/> value to write.</param>
|
||||
public void WriteValue(long value)
|
||||
public virtual void WriteValue(long value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
AutoComplete(JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="UInt64"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="UInt64"/> value to write.</param>
|
||||
public void WriteValue(ulong value)
|
||||
public virtual void WriteValue(ulong value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
AutoComplete(JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Single"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Single"/> value to write.</param>
|
||||
public void WriteValue(float value)
|
||||
public virtual void WriteValue(float value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Float);
|
||||
AutoComplete(JsonToken.Float);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Double"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Double"/> value to write.</param>
|
||||
public void WriteValue(double value)
|
||||
public virtual void WriteValue(double value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Float);
|
||||
AutoComplete(JsonToken.Float);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Boolean"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Boolean"/> value to write.</param>
|
||||
public void WriteValue(bool value)
|
||||
public virtual void WriteValue(bool value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Boolean);
|
||||
AutoComplete(JsonToken.Boolean);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Int16"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Int16"/> value to write.</param>
|
||||
public void WriteValue(short value)
|
||||
public virtual void WriteValue(short value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
AutoComplete(JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="UInt16"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="UInt16"/> value to write.</param>
|
||||
public void WriteValue(ushort value)
|
||||
public virtual void WriteValue(ushort value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
AutoComplete(JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Char"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Char"/> value to write.</param>
|
||||
public void WriteValue(char value)
|
||||
public virtual void WriteValue(char value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
AutoComplete(JsonToken.String);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Byte"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Byte"/> value to write.</param>
|
||||
public void WriteValue(byte value)
|
||||
public virtual void WriteValue(byte value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
AutoComplete(JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="SByte"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="SByte"/> value to write.</param>
|
||||
public void WriteValue(sbyte value)
|
||||
public virtual void WriteValue(sbyte value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
|
||||
AutoComplete(JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Decimal"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Decimal"/> value to write.</param>
|
||||
public void WriteValue(decimal value)
|
||||
public virtual void WriteValue(decimal value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Float);
|
||||
AutoComplete(JsonToken.Float);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="DateTime"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="DateTime"/> value to write.</param>
|
||||
public void WriteValue(DateTime value)
|
||||
public virtual void WriteValue(DateTime value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Date);
|
||||
AutoComplete(JsonToken.Date);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="DateTimeOffset"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
|
||||
public void WriteValue(DateTimeOffset value)
|
||||
public virtual void WriteValue(DateTimeOffset value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Date);
|
||||
AutoComplete(JsonToken.Date);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -739,30 +711,25 @@ namespace Newtonsoft.Json
|
||||
/// Writes out a comment <code>/*...*/</code> containing the specified text.
|
||||
/// </summary>
|
||||
/// <param name="text">Text to place inside the comment.</param>
|
||||
public void WriteComment(string text)
|
||||
public virtual void WriteComment(string text)
|
||||
{
|
||||
AutoComplete(JsonToken.Comment);
|
||||
|
||||
_writer.Write("/*");
|
||||
_writer.Write(text);
|
||||
_writer.Write("*/");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes out the given white space.
|
||||
/// </summary>
|
||||
/// <param name="ws">The string of white space characters.</param>
|
||||
public void WriteWhitespace(string ws)
|
||||
public virtual void WriteWhitespace(string ws)
|
||||
{
|
||||
if (ws != null)
|
||||
{
|
||||
if (!StringUtils.IsWhiteSpace(ws))
|
||||
throw new JsonWriterException("Only white space characters should be used.");
|
||||
|
||||
_writer.Write(ws);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
@@ -71,25 +71,75 @@ namespace Newtonsoft.Json.Linq
|
||||
return source.SelectMany(d => d.Properties());
|
||||
}
|
||||
|
||||
public static IEnumerable<T> PropertyValues<T>(this IEnumerable<JObject> source, string name)
|
||||
public static IEnumerable<JToken> Values(this IEnumerable<JToken> source, object key)
|
||||
{
|
||||
return Values<JToken, JToken>(source, key);
|
||||
}
|
||||
|
||||
public static IEnumerable<JToken> Values(this IEnumerable<JToken> source)
|
||||
{
|
||||
return Values<JToken, JToken>(source, null);
|
||||
}
|
||||
|
||||
public static IEnumerable<U> Values<U>(this IEnumerable<JToken> source, object key)
|
||||
{
|
||||
return Values<JToken, U>(source, key);
|
||||
}
|
||||
|
||||
public static IEnumerable<U> Values<U>(this IEnumerable<JToken> source)
|
||||
{
|
||||
return Values<JToken, U>(source, null);
|
||||
}
|
||||
|
||||
//public static IEnumerable<U> Values<U>(this IEnumerable<JToken> source, object key)
|
||||
//{
|
||||
// return Values<JToken, U>(source, null);
|
||||
//}
|
||||
|
||||
internal static IEnumerable<U> Values<T, U>(this IEnumerable<T> source, object key) where T : JToken
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(source, "source");
|
||||
|
||||
return source.SelectMany(d => d.Properties())
|
||||
.Where(p => string.Compare(p.Name, name, StringComparison.Ordinal) == 0)
|
||||
.Select(p => p.Value)
|
||||
.Convert<JToken, T>();
|
||||
foreach (JToken token in source)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
foreach (JToken t in token.Children())
|
||||
{
|
||||
yield return t.Convert<JToken, U>(); ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JToken value = token[key];
|
||||
if (value != null)
|
||||
yield return value.Convert<JToken, U>();
|
||||
}
|
||||
}
|
||||
|
||||
yield break;
|
||||
|
||||
//IEnumerable<JToken> allChildren = source.SelectMany(d => d.Children());
|
||||
//IEnumerable<JToken> childrenValues = (key != null) ? allChildren.Select(p => p[key]) : allChildren.SelectMany(p => p.Children());
|
||||
|
||||
//List<U> s = childrenValues.Convert<JToken, U>().ToList();
|
||||
//return childrenValues.Convert<JToken, U>();
|
||||
|
||||
// return source.SelectMany(d => d.Properties())
|
||||
//.Where(p => string.Compare(p.Name, name, StringComparison.Ordinal) == 0)
|
||||
//.Select(p => p.Value)
|
||||
//.Convert<JToken, T>();
|
||||
}
|
||||
|
||||
//TODO
|
||||
//public static IEnumerable<T> InDocumentOrder<T>(this IEnumerable<T> source) where T : JObject;
|
||||
|
||||
public static IEnumerable<JToken> Children<T>(this IEnumerable<T> source) where T : JContainer
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(source, "source");
|
||||
//public static IEnumerable<JToken> Children<T>(this IEnumerable<T> source) where T : JToken
|
||||
//{
|
||||
// ValidationUtils.ArgumentNotNull(source, "source");
|
||||
|
||||
return source.SelectMany(c => c.Children());
|
||||
}
|
||||
// return source.SelectMany(c => c.Children());
|
||||
//}
|
||||
|
||||
public static IEnumerable<U> Children<U>(this IEnumerable<JArray> source)
|
||||
{
|
||||
@@ -126,6 +176,9 @@ namespace Newtonsoft.Json.Linq
|
||||
}
|
||||
else
|
||||
{
|
||||
if (token == null)
|
||||
return default(U);
|
||||
|
||||
JValue value = token as JValue;
|
||||
if (value == null)
|
||||
throw new InvalidCastException(string.Format("Cannot cast {0} to {1}.", token.GetType(), typeof(T)));
|
||||
|
||||
@@ -39,7 +39,12 @@ namespace Newtonsoft.Json.Linq
|
||||
get { return JsonTokenType.Array; }
|
||||
}
|
||||
|
||||
public JArray(params object[] content) : this((object)content)
|
||||
public JArray()
|
||||
{
|
||||
}
|
||||
|
||||
public JArray(params object[] content)
|
||||
: this((object)content)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -78,7 +83,7 @@ namespace Newtonsoft.Json.Linq
|
||||
|
||||
public static JArray Parse(string json)
|
||||
{
|
||||
JsonReader jsonReader = new JsonReader(new StringReader(json));
|
||||
JsonReader jsonReader = new JsonTextReader(new StringReader(json));
|
||||
|
||||
return Load(jsonReader);
|
||||
}
|
||||
@@ -91,16 +96,39 @@ namespace Newtonsoft.Json.Linq
|
||||
throw new ArgumentException(string.Format("An item of type {0} cannot be added to content.", o.Type));
|
||||
}
|
||||
|
||||
public override void WriteTo(JsonWriter writer)
|
||||
public static JArray FromObject(object o)
|
||||
{
|
||||
JToken token = FromObjectInternal(o);
|
||||
|
||||
if (token.Type != JsonTokenType.Array)
|
||||
throw new ArgumentException(string.Format("Object serialized to {0}. JArray instance expected.", token.Type));
|
||||
|
||||
return (JArray)token;
|
||||
}
|
||||
|
||||
public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
|
||||
{
|
||||
writer.WriteStartArray();
|
||||
|
||||
foreach (JToken token in Children())
|
||||
{
|
||||
token.WriteTo(writer);
|
||||
token.WriteTo(writer, converters);
|
||||
}
|
||||
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
|
||||
public override JToken this[object key]
|
||||
{
|
||||
get
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(key, "o");
|
||||
|
||||
if (!(key is int))
|
||||
throw new ArgumentException(string.Format("Accessed JArray values with invalid key value: {0}. Array position index expected.", MiscellaneousUtils.ToString(key)));
|
||||
|
||||
return GetIndex(this, (int)key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,16 +77,29 @@ namespace Newtonsoft.Json.Linq
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteTo(JsonWriter writer)
|
||||
public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
|
||||
{
|
||||
writer.WriteStartConstructor(_name);
|
||||
|
||||
foreach (JToken token in Children())
|
||||
{
|
||||
token.WriteTo(writer);
|
||||
token.WriteTo(writer, converters);
|
||||
}
|
||||
|
||||
writer.WriteEndConstructor();
|
||||
}
|
||||
|
||||
public override JToken this[object key]
|
||||
{
|
||||
get
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(key, "o");
|
||||
|
||||
if (!(key is int))
|
||||
throw new ArgumentException(string.Format("Accessed JConstructor values with invalid key value: {0}. Argument position index expected.", MiscellaneousUtils.ToString(key)));
|
||||
|
||||
return GetIndex(this, (int)key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ namespace Newtonsoft.Json.Linq
|
||||
set { _content = value; }
|
||||
}
|
||||
|
||||
public JToken First
|
||||
public override JToken First
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -53,12 +53,17 @@ namespace Newtonsoft.Json.Linq
|
||||
}
|
||||
}
|
||||
|
||||
public JToken Last
|
||||
public override JToken Last
|
||||
{
|
||||
get { return _content; }
|
||||
}
|
||||
|
||||
public IEnumerable<JToken> Children()
|
||||
public override JEnumerable<JToken> Children()
|
||||
{
|
||||
return new JEnumerable<JToken>(ChildrenInternal());
|
||||
}
|
||||
|
||||
private IEnumerable<JToken> ChildrenInternal()
|
||||
{
|
||||
JToken first = First;
|
||||
JToken current = first;
|
||||
@@ -71,11 +76,18 @@ namespace Newtonsoft.Json.Linq
|
||||
} while ((current = current.Next) != first);
|
||||
}
|
||||
|
||||
public IEnumerable<T> Children<T>()
|
||||
public override IEnumerable<T> Children<T>()
|
||||
{
|
||||
return Children().Convert<JToken, T>();
|
||||
}
|
||||
|
||||
public override T Value<T>(object key)
|
||||
{
|
||||
JToken token = this[key];
|
||||
|
||||
return Extensions.Convert<JToken, T>(token);
|
||||
}
|
||||
|
||||
public IEnumerable<JToken> Descendants()
|
||||
{
|
||||
foreach (JToken o in Children())
|
||||
@@ -92,9 +104,35 @@ namespace Newtonsoft.Json.Linq
|
||||
}
|
||||
}
|
||||
|
||||
internal static JToken FromObjectInternal(object o)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(o, "o");
|
||||
|
||||
JsonSerializer jsonSerializer = new JsonSerializer();
|
||||
|
||||
JToken token;
|
||||
using (JsonTokenWriter jsonWriter = new JsonTokenWriter())
|
||||
{
|
||||
jsonSerializer.Serialize(jsonWriter, o);
|
||||
token = jsonWriter.Token;
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
internal static JToken GetIndex(JContainer c, object o)
|
||||
{
|
||||
return c.Children().ElementAt((int)o);
|
||||
}
|
||||
|
||||
internal bool IsMultiContent(object content)
|
||||
{
|
||||
return (content is IEnumerable && !(content is string));
|
||||
}
|
||||
|
||||
public virtual void Add(object content)
|
||||
{
|
||||
if (content is IEnumerable && !(content is string))
|
||||
if (IsMultiContent(content))
|
||||
{
|
||||
IEnumerable enumerable = content as IEnumerable;
|
||||
foreach (object c in enumerable)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using System.Collections;
|
||||
|
||||
namespace Newtonsoft.Json.Linq
|
||||
{
|
||||
public struct JEnumerable<T> : IEnumerable<T> where T : JToken
|
||||
{
|
||||
public static readonly JEnumerable<T> Empty = new JEnumerable<T>(Enumerable.Empty<T>());
|
||||
|
||||
private IEnumerable<T> _enumerable;
|
||||
|
||||
public JEnumerable(IEnumerable<T> enumerable)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(enumerable, "enumerable");
|
||||
|
||||
_enumerable = enumerable;
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return _enumerable.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public IEnumerable<JToken> this[object key]
|
||||
{
|
||||
get { return Extensions.Values<T, JToken>(_enumerable, key); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,24 +64,41 @@ namespace Newtonsoft.Json.Linq
|
||||
.SingleOrDefault();
|
||||
}
|
||||
|
||||
public IEnumerable<JToken> PropertyValues()
|
||||
public JEnumerable<JToken> PropertyValues()
|
||||
{
|
||||
return Properties().Select(p => p.Value);
|
||||
return new JEnumerable<JToken>(Properties().Select(p => p.Value));
|
||||
}
|
||||
|
||||
public T PropertyValue<T>(string name)
|
||||
public override void Add(object content)
|
||||
{
|
||||
JProperty property = Property(name);
|
||||
ValidationUtils.ArgumentNotNull(content, "content");
|
||||
|
||||
if (property == null)
|
||||
throw new Exception(string.Format("Property '{0}' does not exist in JSON object.", name));
|
||||
if (!(content is JProperty) && !IsMultiContent(content))
|
||||
throw new ArgumentException(string.Format("Error adding {0} to JObject. JObject only supports JProperty content.", content.GetType().Name));
|
||||
|
||||
// HACK
|
||||
return Extensions.Convert<JToken, T>(property.Value);
|
||||
base.Add(content);
|
||||
}
|
||||
|
||||
public override JToken this[object key]
|
||||
{
|
||||
get
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(key, "o");
|
||||
|
||||
string propertyName = key as string;
|
||||
if (propertyName == null)
|
||||
throw new ArgumentException(string.Format("Accessed JObject values with invalid key value: {0}. Object property name expected.", MiscellaneousUtils.ToString(key)));
|
||||
|
||||
JProperty property = Property(propertyName);
|
||||
|
||||
return (property != null) ? property.Value : null;
|
||||
}
|
||||
}
|
||||
|
||||
public static JObject Load(JsonReader reader)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(reader, "reader");
|
||||
|
||||
if (reader.TokenType == JsonToken.None)
|
||||
{
|
||||
if (!reader.Read())
|
||||
@@ -105,11 +122,21 @@ namespace Newtonsoft.Json.Linq
|
||||
|
||||
public static JObject Parse(string json)
|
||||
{
|
||||
JsonReader jsonReader = new JsonReader(new StringReader(json));
|
||||
JsonReader jsonReader = new JsonTextReader(new StringReader(json));
|
||||
|
||||
return Load(jsonReader);
|
||||
}
|
||||
|
||||
public static JObject FromObject(object o)
|
||||
{
|
||||
JToken token = FromObjectInternal(o);
|
||||
|
||||
if (token.Type != JsonTokenType.Object)
|
||||
throw new ArgumentException(string.Format("Object serialized to {0}. JObject instance expected.", token.Type));
|
||||
|
||||
return (JObject)token;
|
||||
}
|
||||
|
||||
internal override void ValidateObject(JToken o, JToken previous)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(o, "o");
|
||||
@@ -118,13 +145,13 @@ namespace Newtonsoft.Json.Linq
|
||||
throw new ArgumentException(string.Format("An item of type {0} cannot be added to content.", o.Type));
|
||||
}
|
||||
|
||||
public override void WriteTo(JsonWriter writer)
|
||||
public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
|
||||
{
|
||||
writer.WriteStartObject();
|
||||
|
||||
foreach (JProperty property in Properties())
|
||||
{
|
||||
property.WriteTo(writer);
|
||||
property.WriteTo(writer, converters);
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Newtonsoft.Json.Linq
|
||||
|
||||
public JProperty(string name)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNullOrEmpty(name, "name");
|
||||
ValidationUtils.ArgumentNotNull(name, "name");
|
||||
|
||||
_name = name;
|
||||
}
|
||||
@@ -77,10 +77,10 @@ namespace Newtonsoft.Json.Linq
|
||||
throw new ArgumentException(string.Format("An item of type {0} cannot be added to content.", o.Type));
|
||||
}
|
||||
|
||||
public override void WriteTo(JsonWriter writer)
|
||||
public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
|
||||
{
|
||||
writer.WritePropertyName(_name);
|
||||
Value.WriteTo(writer);
|
||||
Value.WriteTo(writer, converters);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,15 +107,35 @@ namespace Newtonsoft.Json.Linq
|
||||
yield return o;
|
||||
}
|
||||
|
||||
//public IEnumerable<JObject> ObjectsAfterSelf()
|
||||
//{
|
||||
// return null;
|
||||
//}
|
||||
public virtual JToken this[object key]
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
//public IEnumerable<JObject> ObjectsBeforeSelf()
|
||||
//{
|
||||
// return null;
|
||||
//}
|
||||
public virtual T Value<T>(object key)
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public virtual JToken First
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public virtual JToken Last
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public virtual JEnumerable<JToken> Children()
|
||||
{
|
||||
return JEnumerable<JToken>.Empty;
|
||||
}
|
||||
|
||||
public virtual IEnumerable<T> Children<T>()
|
||||
{
|
||||
return Enumerable.Empty<T>();
|
||||
}
|
||||
|
||||
public void Remove()
|
||||
{
|
||||
@@ -129,13 +149,18 @@ namespace Newtonsoft.Json.Linq
|
||||
{
|
||||
}
|
||||
|
||||
public abstract void WriteTo(JsonWriter writer);
|
||||
public abstract void WriteTo(JsonWriter writer, params JsonConverter[] converters);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(null);
|
||||
}
|
||||
|
||||
private string ToString(params JsonConverter[] converters)
|
||||
{
|
||||
using (StringWriter sw = new StringWriter())
|
||||
{
|
||||
JsonWriter jw = new JsonWriter(sw);
|
||||
JsonTextWriter jw = new JsonTextWriter(sw);
|
||||
jw.Formatting = Formatting.Indented;
|
||||
|
||||
WriteTo(jw);
|
||||
@@ -410,6 +435,5 @@ namespace Newtonsoft.Json.Linq
|
||||
return (ulong)v.Value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -84,12 +84,12 @@ namespace Newtonsoft.Json.Linq
|
||||
return JsonTokenType.Null;
|
||||
else if (value is string)
|
||||
return JsonTokenType.String;
|
||||
else if (value is long || value is int || value is short
|
||||
|| value is ulong || value is uint || value is ushort)
|
||||
else if (value is long || value is int || value is short || value is sbyte
|
||||
|| value is ulong || value is uint || value is ushort || value is byte)
|
||||
return JsonTokenType.Integer;
|
||||
else if (value is double || value is float)
|
||||
else if (value is double || value is float || value is decimal)
|
||||
return JsonTokenType.Float;
|
||||
else if (value is DateTime)
|
||||
else if (value is DateTime || value is DateTimeOffset)
|
||||
return JsonTokenType.Date;
|
||||
else if (value is bool)
|
||||
return JsonTokenType.Boolean;
|
||||
@@ -113,7 +113,18 @@ namespace Newtonsoft.Json.Linq
|
||||
return new JValue(value, JsonTokenType.String);
|
||||
}
|
||||
|
||||
public override void WriteTo(JsonWriter writer)
|
||||
private static void WriteConvertableValue(JsonWriter writer, IList<JsonConverter> converters, Action<object> _defaultWrite, object value)
|
||||
{
|
||||
JsonConverter matchingConverter;
|
||||
|
||||
JsonSerializer.HasMatchingConverter(converters, value.GetType(), out matchingConverter);
|
||||
if (matchingConverter != null)
|
||||
matchingConverter.WriteJson(writer, value);
|
||||
else
|
||||
_defaultWrite(value);
|
||||
}
|
||||
|
||||
public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
|
||||
{
|
||||
switch (_valueType)
|
||||
{
|
||||
@@ -121,16 +132,25 @@ namespace Newtonsoft.Json.Linq
|
||||
writer.WriteComment(_value.ToString());
|
||||
break;
|
||||
case JsonTokenType.Integer:
|
||||
writer.WriteValue(Convert.ToInt64(_value));
|
||||
WriteConvertableValue(writer, converters, v => writer.WriteValue(Convert.ToInt64(v)), _value);
|
||||
break;
|
||||
case JsonTokenType.Float:
|
||||
writer.WriteValue(Convert.ToDouble(_value));
|
||||
WriteConvertableValue(writer, converters, v => writer.WriteValue(Convert.ToDouble(v)), _value);
|
||||
break;
|
||||
case JsonTokenType.String:
|
||||
writer.WriteValue(_value.ToString());
|
||||
WriteConvertableValue(writer, converters, v => writer.WriteValue(v.ToString()), _value);
|
||||
break;
|
||||
case JsonTokenType.Boolean:
|
||||
writer.WriteValue(Convert.ToBoolean(_value));
|
||||
WriteConvertableValue(writer, converters, v => writer.WriteValue(Convert.ToBoolean(v)), _value);
|
||||
break;
|
||||
case JsonTokenType.Date:
|
||||
WriteConvertableValue(writer, converters, v =>
|
||||
{
|
||||
if (v is DateTimeOffset)
|
||||
writer.WriteValue((DateTimeOffset)v);
|
||||
else
|
||||
writer.WriteValue(Convert.ToDateTime(v));
|
||||
}, _value);
|
||||
break;
|
||||
case JsonTokenType.Null:
|
||||
writer.WriteNull();
|
||||
@@ -138,9 +158,6 @@ namespace Newtonsoft.Json.Linq
|
||||
case JsonTokenType.Undefined:
|
||||
writer.WriteUndefined();
|
||||
break;
|
||||
case JsonTokenType.Date:
|
||||
writer.WriteValue(Convert.ToDateTime(_value));
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("TokenType", _valueType, "Unexpected token type.");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json.Linq
|
||||
{
|
||||
public class JsonTokenReader : JsonReader
|
||||
{
|
||||
private JToken _root;
|
||||
private JToken _parent;
|
||||
private JToken _current;
|
||||
|
||||
public JsonTokenReader(JToken token)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(token, "token");
|
||||
|
||||
_root = token;
|
||||
_current = token;
|
||||
}
|
||||
|
||||
public override bool Read()
|
||||
{
|
||||
if (CurrentState != State.Start)
|
||||
{
|
||||
JContainer container = _current as JContainer;
|
||||
if (container != null && _parent != container)
|
||||
return ReadInto(container);
|
||||
else
|
||||
return ReadOver(_current);
|
||||
}
|
||||
|
||||
SetToken(_current);
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ReadOver(JToken t)
|
||||
{
|
||||
if (t == _root)
|
||||
return ReadToEnd();
|
||||
|
||||
JToken next = t.Next;
|
||||
if ((next == null || next == t) || t == t.Parent.Last)
|
||||
{
|
||||
if (t.Parent == null)
|
||||
return ReadToEnd();
|
||||
|
||||
return SetEnd(t.Parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
_current = next;
|
||||
SetToken(_current);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool ReadToEnd()
|
||||
{
|
||||
//CurrentState = State.Finished;
|
||||
return false;
|
||||
}
|
||||
|
||||
private JsonToken? GetEndToken(JContainer c)
|
||||
{
|
||||
switch (c.Type)
|
||||
{
|
||||
case JsonTokenType.Object:
|
||||
return JsonToken.EndObject;
|
||||
case JsonTokenType.Array:
|
||||
return JsonToken.EndArray;
|
||||
case JsonTokenType.Constructor:
|
||||
return JsonToken.EndConstructor;
|
||||
case JsonTokenType.Property:
|
||||
return null;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("Type", c.Type, "Unexpected JContainer type.");
|
||||
}
|
||||
}
|
||||
|
||||
private bool ReadInto(JContainer c)
|
||||
{
|
||||
JToken firstChild = c.First;
|
||||
if (firstChild == null)
|
||||
{
|
||||
return SetEnd(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetToken(firstChild);
|
||||
_current = firstChild;
|
||||
_parent = c;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool SetEnd(JContainer c)
|
||||
{
|
||||
JsonToken? endToken = GetEndToken(c);
|
||||
if (endToken != null)
|
||||
{
|
||||
SetToken(endToken.Value);
|
||||
_current = c;
|
||||
_parent = c;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ReadOver(c);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetToken(JToken token)
|
||||
{
|
||||
switch (token.Type)
|
||||
{
|
||||
case JsonTokenType.Object:
|
||||
SetToken(JsonToken.StartObject);
|
||||
break;
|
||||
case JsonTokenType.Array:
|
||||
SetToken(JsonToken.StartArray);
|
||||
break;
|
||||
case JsonTokenType.Constructor:
|
||||
SetToken(JsonToken.StartConstructor);
|
||||
break;
|
||||
case JsonTokenType.Property:
|
||||
SetToken(JsonToken.PropertyName, ((JProperty)token).Name);
|
||||
break;
|
||||
case JsonTokenType.Comment:
|
||||
SetToken(JsonToken.Comment, ((JValue)token).Value);
|
||||
break;
|
||||
case JsonTokenType.Integer:
|
||||
SetToken(JsonToken.Integer, ((JValue)token).Value);
|
||||
break;
|
||||
case JsonTokenType.Float:
|
||||
SetToken(JsonToken.Float, ((JValue)token).Value);
|
||||
break;
|
||||
case JsonTokenType.String:
|
||||
SetToken(JsonToken.String, ((JValue)token).Value);
|
||||
break;
|
||||
case JsonTokenType.Boolean:
|
||||
SetToken(JsonToken.Boolean, ((JValue)token).Value);
|
||||
break;
|
||||
case JsonTokenType.Null:
|
||||
SetToken(JsonToken.Null, ((JValue)token).Value);
|
||||
break;
|
||||
case JsonTokenType.Undefined:
|
||||
SetToken(JsonToken.Undefined, ((JValue)token).Value);
|
||||
break;
|
||||
case JsonTokenType.Date:
|
||||
SetToken(JsonToken.Date, ((JValue)token).Value);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("Type", token.Type, "Unexpected JsonTokenType.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ namespace Newtonsoft.Json.Linq
|
||||
{
|
||||
public enum JsonTokenType
|
||||
{
|
||||
None,
|
||||
Object,
|
||||
Array,
|
||||
Constructor,
|
||||
|
||||
@@ -0,0 +1,306 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json.Linq
|
||||
{
|
||||
public class JsonTokenWriter : JsonWriter
|
||||
{
|
||||
private JContainer _token;
|
||||
private JContainer _parent;
|
||||
|
||||
public JContainer Token
|
||||
{
|
||||
get { return _token; }
|
||||
}
|
||||
|
||||
public JsonTokenWriter(JContainer container)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(container, "container");
|
||||
|
||||
_token = container;
|
||||
_parent = container;
|
||||
}
|
||||
|
||||
public JsonTokenWriter()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
|
||||
/// </summary>
|
||||
public override void Flush()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes this stream and the underlying stream.
|
||||
/// </summary>
|
||||
public override void Close()
|
||||
{
|
||||
base.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the beginning of a Json object.
|
||||
/// </summary>
|
||||
public override void WriteStartObject()
|
||||
{
|
||||
base.WriteStartObject();
|
||||
|
||||
AddParent(new JObject());
|
||||
}
|
||||
|
||||
private void AddParent(JContainer container)
|
||||
{
|
||||
if (_parent == null)
|
||||
_token = container;
|
||||
else
|
||||
_parent.Add(container);
|
||||
|
||||
_parent = container;
|
||||
}
|
||||
|
||||
private void RemoveParent()
|
||||
{
|
||||
_parent = _parent.Parent;
|
||||
|
||||
if (_parent != null && _parent.Type == JsonTokenType.Property)
|
||||
_parent = _parent.Parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the beginning of a Json array.
|
||||
/// </summary>
|
||||
public override void WriteStartArray()
|
||||
{
|
||||
base.WriteStartArray();
|
||||
|
||||
AddParent(new JArray());
|
||||
}
|
||||
|
||||
public override void WriteStartConstructor(string name)
|
||||
{
|
||||
base.WriteStartConstructor(name);
|
||||
|
||||
AddParent(new JConstructor());
|
||||
}
|
||||
|
||||
protected override void WriteEnd(JsonToken token)
|
||||
{
|
||||
RemoveParent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the property name of a name/value pair on a Json object.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public override void WritePropertyName(string name)
|
||||
{
|
||||
base.WritePropertyName(name);
|
||||
|
||||
AddParent(new JProperty(name));
|
||||
}
|
||||
|
||||
private void AddValue(object value, JsonToken token)
|
||||
{
|
||||
_parent.Add(new JValue(value));
|
||||
|
||||
if (_parent.Type == JsonTokenType.Property)
|
||||
_parent = _parent.Parent;
|
||||
}
|
||||
|
||||
#region WriteValue methods
|
||||
/// <summary>
|
||||
/// Writes a null value.
|
||||
/// </summary>
|
||||
public override void WriteNull()
|
||||
{
|
||||
base.WriteNull();
|
||||
AddValue(null, JsonToken.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an undefined value.
|
||||
/// </summary>
|
||||
public override void WriteUndefined()
|
||||
{
|
||||
base.WriteUndefined();
|
||||
AddValue(null, JsonToken.Undefined);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes raw JavaScript manually.
|
||||
/// </summary>
|
||||
/// <param name="javaScript">The raw JavaScript to write.</param>
|
||||
public override void WriteRaw(string javaScript)
|
||||
{
|
||||
base.WriteRaw(javaScript);
|
||||
// hack. some 'raw' or 'other' token perhaps?
|
||||
AddValue(javaScript, JsonToken.Undefined);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="String"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="String"/> value to write.</param>
|
||||
public override void WriteValue(string value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value ?? string.Empty, JsonToken.String);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Int32"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Int32"/> value to write.</param>
|
||||
public override void WriteValue(int value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="UInt32"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="UInt32"/> value to write.</param>
|
||||
public override void WriteValue(uint value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Int64"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Int64"/> value to write.</param>
|
||||
public override void WriteValue(long value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="UInt64"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="UInt64"/> value to write.</param>
|
||||
public override void WriteValue(ulong value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Single"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Single"/> value to write.</param>
|
||||
public override void WriteValue(float value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Float);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Double"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Double"/> value to write.</param>
|
||||
public override void WriteValue(double value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Float);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Boolean"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Boolean"/> value to write.</param>
|
||||
public override void WriteValue(bool value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Boolean);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Int16"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Int16"/> value to write.</param>
|
||||
public override void WriteValue(short value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="UInt16"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="UInt16"/> value to write.</param>
|
||||
public override void WriteValue(ushort value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Char"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Char"/> value to write.</param>
|
||||
public override void WriteValue(char value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value.ToString(), JsonToken.String);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Byte"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Byte"/> value to write.</param>
|
||||
public override void WriteValue(byte value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="SByte"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="SByte"/> value to write.</param>
|
||||
public override void WriteValue(sbyte value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Integer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="Decimal"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Decimal"/> value to write.</param>
|
||||
public override void WriteValue(decimal value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Float);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="DateTime"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="DateTime"/> value to write.</param>
|
||||
public override void WriteValue(DateTime value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Date);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="DateTimeOffset"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
|
||||
public override void WriteValue(DateTimeOffset value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, JsonToken.Date);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -78,15 +78,13 @@
|
||||
<Compile Include="Converters\JsonDateTimeSerializationMode.cs" />
|
||||
<Compile Include="Converters\XmlNodeConverter.cs" />
|
||||
<Compile Include="Converters\HtmlColorConverter.cs" />
|
||||
<Compile Include="JavaScriptParameters.cs" />
|
||||
<Compile Include="JavaScriptConstructor.cs" />
|
||||
<Compile Include="JsonTextReader.cs" />
|
||||
<Compile Include="JsonPropertyAttribute.cs" />
|
||||
<Compile Include="JsonIgnoreAttribute.cs" />
|
||||
<Compile Include="JsonTextWriter.cs" />
|
||||
<Compile Include="JsonWriterException.cs" />
|
||||
<Compile Include="JsonReaderException.cs" />
|
||||
<Compile Include="Identifier.cs" />
|
||||
<Compile Include="JavaScriptArray.cs" />
|
||||
<Compile Include="JavaScriptObject.cs" />
|
||||
<Compile Include="JsonConverter.cs" />
|
||||
<Compile Include="JsonConverterCollection.cs" />
|
||||
<Compile Include="JsonReader.cs" />
|
||||
@@ -96,8 +94,11 @@
|
||||
<Compile Include="Linq\Extensions.cs" />
|
||||
<Compile Include="Linq\JConstructor.cs" />
|
||||
<Compile Include="Linq\JContainer.cs" />
|
||||
<Compile Include="Linq\JEnumerable.cs" />
|
||||
<Compile Include="Linq\JObject.cs" />
|
||||
<Compile Include="Linq\JArray.cs" />
|
||||
<Compile Include="Linq\JsonTokenReader.cs" />
|
||||
<Compile Include="Linq\JsonTokenWriter.cs" />
|
||||
<Compile Include="Linq\JToken.cs" />
|
||||
<Compile Include="Linq\JProperty.cs" />
|
||||
<Compile Include="Linq\JsonTokenType.cs" />
|
||||
|
||||
@@ -78,7 +78,10 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
public static string ToString(object value)
|
||||
{
|
||||
return (value != null) ? value.ToString() : "{null}";
|
||||
if (value == null)
|
||||
return "{null}";
|
||||
|
||||
return (value is string) ? @"""" + value.ToString() + @"""" : value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user