-Code clean up

-Various performance improvements
This commit is contained in:
JamesNK
2012-01-18 06:27:43 +00:00
parent 61db48c01d
commit b146481c87
19 changed files with 518 additions and 323 deletions
@@ -1811,5 +1811,31 @@ bye", reader.Value);
Assert.AreEqual(JsonToken.Float, reader.TokenType);
Assert.AreEqual(32m, reader.Value);
}
[Test]
public void ParseNumbers()
{
string json = @"[0,1,2 , 3]";
JsonTextReader reader = new JsonTextReader(new StringReader(json));
reader.Read();
Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
reader.Read();
Assert.AreEqual(JsonToken.Integer, reader.TokenType);
reader.Read();
Assert.AreEqual(JsonToken.Integer, reader.TokenType);
reader.Read();
Assert.AreEqual(JsonToken.Integer, reader.TokenType);
reader.Read();
Assert.AreEqual(JsonToken.Integer, reader.TokenType);
reader.Read();
Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
}
}
}
@@ -29,6 +29,7 @@ using System.Text;
using NUnit.Framework;
using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Tests
{
@@ -618,5 +619,30 @@ _____'propertyName': NaN
Assert.AreEqual(expected, result);
}
[Test]
public void BuildStateArray()
{
JsonWriter.State[][] stateArray = JsonWriter.BuildStateArray();
var valueStates = JsonWriter.StateArrayTempate[7];
foreach (JsonToken valueToken in EnumUtils.GetValues(typeof(JsonToken)))
{
switch (valueToken)
{
case JsonToken.Integer:
case JsonToken.Float:
case JsonToken.String:
case JsonToken.Boolean:
case JsonToken.Null:
case JsonToken.Undefined:
case JsonToken.Date:
case JsonToken.Bytes:
Assert.AreEqual(valueStates, stateArray[(int)valueToken], "Error for " + valueToken + " states.");
break;
}
}
}
}
}
+66 -11
View File
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Web.Script.Serialization;
using System.Xml.Linq;
@@ -35,8 +36,19 @@ namespace Newtonsoft.Json.Tests
public class PerformanceTests : TestFixtureBase
{
private const int Iterations = 100;
//private const int Iterations = 5000;
//private const int Iterations = 100;
private const int Iterations = 5000;
private static SimpleObject CreateSimpleObject()
{
return new SimpleObject
{
Name = "Simple-1",
Id = 2311,
Address = "Planet Earth",
Scores = new int[] { 82,96,49,40,38,38,78,96,2,39 }
};
}
#region Data
private const string BsonHex =
@@ -51,6 +63,9 @@ namespace Newtonsoft.Json.Tests
private const string JsonText =
@"{""strings"":[null,""Markus egger ]><[, (2nd)"",null],""dictionary"":{""Val & asd1"":1,""Val2 & asd1"":3,""Val3 & asd1"":4},""Name"":""Rick"",""Now"":""\/Date(1262301136080+1300)\/"",""BigNumber"":34123123123.121,""Address1"":{""Street"":""fff Street"",""Phone"":""(503) 814-6335"",""Entered"":""\/Date(1264025536080+1300)\/""},""Addresses"":[{""Street"":""\u001farray<address"",""Phone"":""(503) 814-6335"",""Entered"":""\/Date(1262211136080+1300)\/""},{""Street"":""array 2 address"",""Phone"":""(503) 814-6335"",""Entered"":""\/Date(1262124736080+1300)\/""}]}";
private const string SimpleJsonText =
@"{""Id"":2311,""Name"":""Simple-1"",""Address"":""Planet Earth"",""Scores"":[82,96,49,40,38,38,78,96,2,39]}";
public enum SerializeMethod
{
JsonNet,
@@ -62,17 +77,36 @@ namespace Newtonsoft.Json.Tests
}
#endregion
[Test]
public void SerializeSimpleObject()
{
var value = CreateSimpleObject();
SerializeTests(value);
}
[Test]
public void DeserializeSimpleObject()
{
DeserializeTests<SimpleObject>(SimpleJsonText);
}
[Test]
public void Serialize()
{
TestClass test = CreateSerializationObject();
BenchmarkSerializeMethod(SerializeMethod.DataContractSerializer, test);
BenchmarkSerializeMethod(SerializeMethod.BinaryFormatter, test);
BenchmarkSerializeMethod(SerializeMethod.JavaScriptSerializer, test);
BenchmarkSerializeMethod(SerializeMethod.DataContractJsonSerializer, test);
BenchmarkSerializeMethod(SerializeMethod.JsonNet, test);
BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, test);
SerializeTests(test);
}
private void SerializeTests(object value)
{
//BenchmarkSerializeMethod(SerializeMethod.DataContractSerializer, value);
////BenchmarkSerializeMethod(SerializeMethod.BinaryFormatter, value);
//BenchmarkSerializeMethod(SerializeMethod.JavaScriptSerializer, value);
//BenchmarkSerializeMethod(SerializeMethod.DataContractJsonSerializer, value);
BenchmarkSerializeMethod(SerializeMethod.JsonNet, value);
//BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, value);
}
[Test]
@@ -80,12 +114,17 @@ namespace Newtonsoft.Json.Tests
{
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.DataContractSerializer, XmlText);
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.BinaryFormatter, MiscellaneousUtils.HexToBytes(BinaryFormatterHex));
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.JavaScriptSerializer, JsonText);
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.DataContractJsonSerializer, JsonText);
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.JsonNet, JsonText);
DeserializeTests<TestClass>(JsonText);
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.JsonNetBinary, MiscellaneousUtils.HexToBytes(BsonHex));
}
public void DeserializeTests<T>(string json)
{
BenchmarkDeserializeMethod<T>(SerializeMethod.JavaScriptSerializer, json);
BenchmarkDeserializeMethod<T>(SerializeMethod.DataContractJsonSerializer, json);
BenchmarkDeserializeMethod<T>(SerializeMethod.JsonNet, json);
}
[Test]
public void SerializeSizeNormal()
{
@@ -722,6 +761,22 @@ namespace Newtonsoft.Json.Tests
}
private DateTime _Entered = DateTime.Parse("01/01/2007", CultureInfo.CurrentCulture.DateTimeFormat);
}
[DataContract]
public class SimpleObject
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Address { get; set; }
[DataMember]
public int[] Scores { get; set; }
}
#endregion
}
#endif
+8 -8
View File
@@ -39,10 +39,10 @@ namespace Newtonsoft.Json.Bson
public class BsonReader : JsonReader
{
private const int MaxCharBytesSize = 128;
private static readonly byte[] _seqRange1 = new byte[] { 0, 127 }; // range of 1-byte sequence
private static readonly byte[] _seqRange2 = new byte[] { 194, 223 }; // range of 2-byte sequence
private static readonly byte[] _seqRange3 = new byte[] { 224, 239 }; // range of 3-byte sequence
private static readonly byte[] _seqRange4 = new byte[] { 240, 244 }; // range of 4-byte sequence
private static readonly byte[] SeqRange1 = new byte[] { 0, 127 }; // range of 1-byte sequence
private static readonly byte[] SeqRange2 = new byte[] { 194, 223 }; // range of 2-byte sequence
private static readonly byte[] SeqRange3 = new byte[] { 224, 239 }; // range of 3-byte sequence
private static readonly byte[] SeqRange4 = new byte[] { 240, 244 }; // range of 4-byte sequence
private readonly BinaryReader _reader;
private readonly List<ContainerContext> _stack;
@@ -778,10 +778,10 @@ namespace Newtonsoft.Json.Bson
private int BytesInSequence(byte b)
{
if (b <= _seqRange1[1]) return 1;
if (b >= _seqRange2[0] && b <= _seqRange2[1]) return 2;
if (b >= _seqRange3[0] && b <= _seqRange3[1]) return 3;
if (b >= _seqRange4[0] && b <= _seqRange4[1]) return 4;
if (b <= SeqRange1[1]) return 1;
if (b >= SeqRange2[0] && b <= SeqRange2[1]) return 2;
if (b >= SeqRange3[0] && b <= SeqRange3[1]) return 3;
if (b >= SeqRange4[0] && b <= SeqRange4[1]) return 4;
return 0;
}
@@ -88,9 +88,9 @@ namespace Newtonsoft.Json.Converters
return new XmlElementWrapper(_document.CreateElement(elementName));
}
public IXmlElement CreateElement(string qualifiedName, string namespaceURI)
public IXmlElement CreateElement(string qualifiedName, string namespaceUri)
{
return new XmlElementWrapper(_document.CreateElement(qualifiedName, namespaceURI));
return new XmlElementWrapper(_document.CreateElement(qualifiedName, namespaceUri));
}
public IXmlNode CreateAttribute(string name, string value)
@@ -101,9 +101,9 @@ namespace Newtonsoft.Json.Converters
return attribute;
}
public IXmlNode CreateAttribute(string qualifiedName, string namespaceURI, string value)
public IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value)
{
XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(qualifiedName, namespaceURI));
XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(qualifiedName, namespaceUri));
attribute.Value = value;
return attribute;
@@ -138,9 +138,9 @@ namespace Newtonsoft.Json.Converters
_element.SetAttributeNode((XmlAttribute) xmlAttributeWrapper.WrappedNode);
}
public string GetPrefixOfNamespace(string namespaceURI)
public string GetPrefixOfNamespace(string namespaceUri)
{
return _element.GetPrefixOfNamespace(namespaceURI);
return _element.GetPrefixOfNamespace(namespaceUri);
}
}
@@ -264,7 +264,7 @@ namespace Newtonsoft.Json.Converters
get { return _node.Prefix; }
}
public string NamespaceURI
public string NamespaceUri
{
get { return _node.NamespaceURI; }
}
@@ -283,9 +283,9 @@ namespace Newtonsoft.Json.Converters
IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone);
IXmlNode CreateProcessingInstruction(string target, string data);
IXmlElement CreateElement(string elementName);
IXmlElement CreateElement(string qualifiedName, string namespaceURI);
IXmlElement CreateElement(string qualifiedName, string namespaceUri);
IXmlNode CreateAttribute(string name, string value);
IXmlNode CreateAttribute(string qualifiedName, string namespaceURI, string value);
IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value);
IXmlElement DocumentElement { get; }
}
@@ -300,7 +300,7 @@ namespace Newtonsoft.Json.Converters
internal interface IXmlElement : IXmlNode
{
void SetAttributeNode(IXmlNode attribute);
string GetPrefixOfNamespace(string namespaceURI);
string GetPrefixOfNamespace(string namespaceUri);
}
internal interface IXmlNode
@@ -312,7 +312,7 @@ namespace Newtonsoft.Json.Converters
IXmlNode ParentNode { get; }
string Value { get; set; }
IXmlNode AppendChild(IXmlNode newChild);
string NamespaceURI { get; }
string NamespaceUri { get; }
object WrappedNode { get; }
}
#endregion
@@ -321,12 +321,12 @@ namespace Newtonsoft.Json.Converters
#if !NET20
internal class XDeclarationWrapper : XObjectWrapper, IXmlDeclaration
{
internal readonly XDeclaration _declaration;
internal XDeclaration Declaration { get; private set; }
public XDeclarationWrapper(XDeclaration declaration)
: base(null)
{
_declaration = declaration;
Declaration = declaration;
}
public override XmlNodeType NodeType
@@ -336,19 +336,19 @@ namespace Newtonsoft.Json.Converters
public string Version
{
get { return _declaration.Version; }
get { return Declaration.Version; }
}
public string Encoding
{
get { return _declaration.Encoding; }
set { _declaration.Encoding = value; }
get { return Declaration.Encoding; }
set { Declaration.Encoding = value; }
}
public string Standalone
{
get { return _declaration.Standalone; }
set { _declaration.Standalone = value; }
get { return Declaration.Standalone; }
set { Declaration.Standalone = value; }
}
}
@@ -417,10 +417,10 @@ namespace Newtonsoft.Json.Converters
return new XElementWrapper(new XElement(elementName));
}
public IXmlElement CreateElement(string qualifiedName, string namespaceURI)
public IXmlElement CreateElement(string qualifiedName, string namespaceUri)
{
string localName = MiscellaneousUtils.GetLocalName(qualifiedName);
return new XElementWrapper(new XElement(XName.Get(localName, namespaceURI)));
return new XElementWrapper(new XElement(XName.Get(localName, namespaceUri)));
}
public IXmlNode CreateAttribute(string name, string value)
@@ -428,10 +428,10 @@ namespace Newtonsoft.Json.Converters
return new XAttributeWrapper(new XAttribute(name, value));
}
public IXmlNode CreateAttribute(string qualifiedName, string namespaceURI, string value)
public IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value)
{
string localName = MiscellaneousUtils.GetLocalName(qualifiedName);
return new XAttributeWrapper(new XAttribute(XName.Get(localName, namespaceURI), value));
return new XAttributeWrapper(new XAttribute(XName.Get(localName, namespaceUri), value));
}
public IXmlElement DocumentElement
@@ -450,7 +450,7 @@ namespace Newtonsoft.Json.Converters
XDeclarationWrapper declarationWrapper = newChild as XDeclarationWrapper;
if (declarationWrapper != null)
{
Document.Declaration = declarationWrapper._declaration;
Document.Declaration = declarationWrapper.Declaration;
return declarationWrapper;
}
else
@@ -649,7 +649,7 @@ namespace Newtonsoft.Json.Converters
throw new InvalidOperationException();
}
public virtual string NamespaceURI
public virtual string NamespaceUri
{
get { return null; }
}
@@ -678,7 +678,7 @@ namespace Newtonsoft.Json.Converters
get { return Attribute.Name.LocalName; }
}
public override string NamespaceURI
public override string NamespaceUri
{
get { return Attribute.Name.NamespaceName; }
}
@@ -729,14 +729,14 @@ namespace Newtonsoft.Json.Converters
get { return Element.Name.LocalName; }
}
public override string NamespaceURI
public override string NamespaceUri
{
get { return Element.Name.NamespaceName; }
}
public string GetPrefixOfNamespace(string namespaceURI)
public string GetPrefixOfNamespace(string namespaceUri)
{
return Element.GetPrefixOfNamespace(namespaceURI);
return Element.GetPrefixOfNamespace(namespaceUri);
}
}
#endif
@@ -836,7 +836,7 @@ namespace Newtonsoft.Json.Converters
manager.PushScope();
foreach (IXmlNode attribute in parentElement.Attributes)
{
if (attribute.NamespaceURI == "http://www.w3.org/2000/xmlns/" && attribute.LocalName != "xmlns")
if (attribute.NamespaceUri == "http://www.w3.org/2000/xmlns/" && attribute.LocalName != "xmlns")
manager.AddNamespace(attribute.LocalName, attribute.Value);
}
}
@@ -845,9 +845,9 @@ namespace Newtonsoft.Json.Converters
private string ResolveFullName(IXmlNode node, XmlNamespaceManager manager)
{
string prefix = (node.NamespaceURI == null || (node.LocalName == "xmlns" && node.NamespaceURI == "http://www.w3.org/2000/xmlns/"))
string prefix = (node.NamespaceUri == null || (node.LocalName == "xmlns" && node.NamespaceUri == "http://www.w3.org/2000/xmlns/"))
? null
: manager.LookupPrefix(node.NamespaceURI);
: manager.LookupPrefix(node.NamespaceUri);
if (!string.IsNullOrEmpty(prefix))
return prefix + ":" + node.LocalName;
@@ -860,7 +860,7 @@ namespace Newtonsoft.Json.Converters
switch (node.NodeType)
{
case XmlNodeType.Attribute:
if (node.NamespaceURI == JsonNamespaceUri)
if (node.NamespaceUri == JsonNamespaceUri)
return "$" + node.LocalName;
else
return "@" + ResolveFullName(node, manager);
@@ -888,7 +888,7 @@ namespace Newtonsoft.Json.Converters
private bool IsArray(IXmlNode node)
{
IXmlNode jsonArrayAttribute = (node.Attributes != null)
? node.Attributes.SingleOrDefault(a => a.LocalName == "Array" && a.NamespaceURI == JsonNamespaceUri)
? node.Attributes.SingleOrDefault(a => a.LocalName == "Array" && a.NamespaceUri == JsonNamespaceUri)
: null;
return (jsonArrayAttribute != null && XmlConvert.ToBoolean(jsonArrayAttribute.Value));
@@ -970,7 +970,7 @@ namespace Newtonsoft.Json.Converters
{
foreach (IXmlNode attribute in node.Attributes)
{
if (attribute.NamespaceURI == "http://www.w3.org/2000/xmlns/")
if (attribute.NamespaceUri == "http://www.w3.org/2000/xmlns/")
{
string prefix = (attribute.LocalName != "xmlns")
? attribute.LocalName
@@ -1020,10 +1020,10 @@ namespace Newtonsoft.Json.Converters
case XmlNodeType.ProcessingInstruction:
case XmlNodeType.Whitespace:
case XmlNodeType.SignificantWhitespace:
if (node.NamespaceURI == "http://www.w3.org/2000/xmlns/" && node.Value == JsonNamespaceUri)
if (node.NamespaceUri == "http://www.w3.org/2000/xmlns/" && node.Value == JsonNamespaceUri)
return;
if (node.NamespaceURI == JsonNamespaceUri)
if (node.NamespaceUri == JsonNamespaceUri)
{
if (node.LocalName == "Array")
return;
@@ -1512,7 +1512,7 @@ namespace Newtonsoft.Json.Converters
private IEnumerable<IXmlNode> ValueAttributes(IEnumerable<IXmlNode> c)
{
return c.Where(a => a.NamespaceURI != JsonNamespaceUri);
return c.Where(a => a.NamespaceUri != JsonNamespaceUri);
}
#endregion
+66 -42
View File
@@ -161,7 +161,7 @@ namespace Newtonsoft.Json
// once in the last 10% of the buffer shift the remainling content to the start to avoid
// unnessesarly increasing the buffer size when reading numbers/strings
int length = _chars.Length;
if (length - _charPos <= length*0.1)
if (length - _charPos <= length * 0.1)
{
int count = _charsUsed - _charPos;
if (count > 0)
@@ -403,7 +403,7 @@ namespace Newtonsoft.Json
if (TokenType == JsonToken.Null)
return null;
if (TokenType == JsonToken.Bytes)
return (byte[]) Value;
return (byte[])Value;
if (TokenType == JsonToken.StartArray)
{
List<byte> data = new List<byte>();
@@ -453,10 +453,10 @@ namespace Newtonsoft.Json
if (TokenType == JsonToken.Null)
return null;
if (TokenType == JsonToken.Float)
return (decimal?) Value;
return (decimal?)Value;
decimal d;
if (TokenType == JsonToken.String && decimal.TryParse((string) Value, NumberStyles.Number, Culture, out d))
if (TokenType == JsonToken.String && decimal.TryParse((string)Value, NumberStyles.Number, Culture, out d))
{
SetToken(JsonToken.Float, d);
return d;
@@ -486,10 +486,10 @@ namespace Newtonsoft.Json
if (TokenType == JsonToken.Null)
return null;
if (TokenType == JsonToken.Date)
return (DateTimeOffset) Value;
return (DateTimeOffset)Value;
DateTimeOffset dt;
if (TokenType == JsonToken.String && DateTimeOffset.TryParse((string) Value, Culture, DateTimeStyles.None, out dt))
if (TokenType == JsonToken.String && DateTimeOffset.TryParse((string)Value, Culture, DateTimeStyles.None, out dt))
{
SetToken(JsonToken.Date, dt);
return dt;
@@ -506,12 +506,6 @@ namespace Newtonsoft.Json
{
while (true)
{
if (_charPos >= _charsUsed)
{
if (!ReadChars(0, false))
return false;
}
switch (_currentState)
{
case State.Start:
@@ -706,6 +700,58 @@ namespace Newtonsoft.Json
}
}
private void ReadNumberIntoBuffer()
{
int charPos = _charPos;
while (true)
{
switch (_chars[charPos++])
{
case '\0':
if (_charsUsed == charPos - 1)
{
charPos--;
_charPos = charPos;
if (ReadData(true) == 0)
return;
}
break;
case '-':
case '+':
case 'a':
case 'A':
case 'b':
case 'B':
case 'c':
case 'C':
case 'd':
case 'D':
case 'e':
case 'E':
case 'f':
case 'F':
case 'x':
case 'X':
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
break;
default:
_charPos = charPos - 1;
return;
}
}
}
private void ClearRecentString()
{
if (_buffer != null)
@@ -726,7 +772,10 @@ namespace Newtonsoft.Json
if (_charsUsed == _charPos)
{
if (ReadData(false) == 0)
{
_currentState = State.Finished;
return false;
}
}
else
{
@@ -890,7 +939,7 @@ namespace Newtonsoft.Json
{
if (ReadData(true) == 0)
throw CreateJsonReaderException("Unexpected end when parsing unquoted property name. Line {0}, position {1}.", LineNumber, LinePosition);
break;
}
@@ -909,7 +958,7 @@ namespace Newtonsoft.Json
_stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
return;
}
throw CreateJsonReaderException("Invalid JavaScript property identifier character: {0}. Line {1}, position {2}.", currentChar, LineNumber, LinePosition);
}
}
@@ -1173,32 +1222,7 @@ namespace Newtonsoft.Json
char firstChar = _chars[_charPos];
int initialPosition = _charPos;
// parse until seperator character or end
while (true)
{
char currentChar = _chars[_charPos];
if (currentChar == '\0')
{
if (_charsUsed == _charPos)
{
if (ReadData(true) == 0)
break;
}
else
{
_charPos++;
}
}
else if (IsSeperator(currentChar))
{
break;
}
else
{
_charPos++;
}
}
ReadNumberIntoBuffer();
_stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
@@ -1240,7 +1264,7 @@ namespace Newtonsoft.Json
if (singleDigit)
{
// digit char values start at 48
numberValue = (long) firstChar - 48;
numberValue = (long)firstChar - 48;
numberType = JsonToken.Integer;
}
else if (nonBase10)
@@ -1531,7 +1555,7 @@ namespace Newtonsoft.Json
{
if (CurrentState == State.Start && LinePosition == 0)
return 0;
return _lineNumber;
}
}
+53 -33
View File
@@ -25,6 +25,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
@@ -91,7 +92,7 @@ namespace Newtonsoft.Json
/// </summary>
public abstract class JsonWriter : IDisposable
{
private enum State
internal enum State
{
Start,
Property,
@@ -107,19 +108,58 @@ namespace Newtonsoft.Json
}
// array that gives a new state based on the current state an the token being written
private static readonly State[][] stateArray = new[] {
// Start PropertyName ObjectStart Object ArrayStart Array ConstructorStart Constructor Closed Error
private static readonly State[][] StateArray;
internal static readonly State[][] StateArrayTempate = new[] {
// Start PropertyName ObjectStart Object ArrayStart Array ConstructorStart Constructor Closed Error
//
/* None */new[]{ State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error },
/* StartObject */new[]{ State.ObjectStart, State.ObjectStart, State.Error, State.Error, State.ObjectStart, State.ObjectStart, State.ObjectStart, State.ObjectStart, State.Error, State.Error },
/* StartArray */new[]{ State.ArrayStart, State.ArrayStart, State.Error, State.Error, State.ArrayStart, State.ArrayStart, State.ArrayStart, State.ArrayStart, State.Error, State.Error },
/* StartConstructor */new[]{ State.ConstructorStart, State.ConstructorStart, State.Error, State.Error, State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.Error, State.Error },
/* StartProperty */new[]{ State.Property, State.Error, State.Property, State.Property, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error },
/* Comment */new[]{ State.Start, State.Property, State.ObjectStart, State.Object, State.ArrayStart, State.Array, State.Constructor, State.Constructor, State.Error, State.Error },
/* Raw */new[]{ State.Start, State.Property, State.ObjectStart, State.Object, State.ArrayStart, State.Array, State.Constructor, State.Constructor, State.Error, State.Error },
/* Value */new[]{ State.Start, State.Object, State.Error, State.Error, State.Array, State.Array, State.Constructor, State.Constructor, State.Error, State.Error },
/* None */new[]{ State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error },
/* StartObject */new[]{ State.ObjectStart, State.ObjectStart, State.Error, State.Error, State.ObjectStart, State.ObjectStart, State.ObjectStart, State.ObjectStart, State.Error, State.Error },
/* StartArray */new[]{ State.ArrayStart, State.ArrayStart, State.Error, State.Error, State.ArrayStart, State.ArrayStart, State.ArrayStart, State.ArrayStart, State.Error, State.Error },
/* StartConstructor */new[]{ State.ConstructorStart, State.ConstructorStart, State.Error, State.Error, State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.Error, State.Error },
/* StartProperty */new[]{ State.Property, State.Error, State.Property, State.Property, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error },
/* Comment */new[]{ State.Start, State.Property, State.ObjectStart, State.Object, State.ArrayStart, State.Array, State.Constructor, State.Constructor, State.Error, State.Error },
/* Raw */new[]{ State.Start, State.Property, State.ObjectStart, State.Object, State.ArrayStart, State.Array, State.Constructor, State.Constructor, State.Error, State.Error },
/* Value (this will be copied) */new[]{ State.Start, State.Object, State.Error, State.Error, State.Array, State.Array, State.Constructor, State.Constructor, State.Error, State.Error }
};
internal static State[][] BuildStateArray()
{
var allStates = StateArrayTempate.ToList();
var errorStates = StateArrayTempate[0];
var valueStates = StateArrayTempate[7];
foreach (JsonToken valueToken in EnumUtils.GetValues(typeof(JsonToken)))
{
if (allStates.Count <= (int)valueToken)
{
switch (valueToken)
{
case JsonToken.Integer:
case JsonToken.Float:
case JsonToken.String:
case JsonToken.Boolean:
case JsonToken.Null:
case JsonToken.Undefined:
case JsonToken.Date:
case JsonToken.Bytes:
allStates.Add(valueStates);
break;
default:
allStates.Add(errorStates);
break;
}
}
}
return allStates.ToArray();
}
static JsonWriter()
{
StateArray = BuildStateArray();
}
private int _top;
private readonly List<JTokenType> _stack;
@@ -583,31 +623,11 @@ namespace Newtonsoft.Json
internal void AutoComplete(JsonToken tokenBeingWritten)
{
int token;
switch (tokenBeingWritten)
{
default:
token = (int)tokenBeingWritten;
break;
case JsonToken.Integer:
case JsonToken.Float:
case JsonToken.String:
case JsonToken.Boolean:
case JsonToken.Null:
case JsonToken.Undefined:
case JsonToken.Date:
case JsonToken.Bytes:
// a value is being written
token = 7;
break;
}
// gets new state based on the current state and what is being written
State newState = stateArray[token][(int)_currentState];
State newState = StateArray[(int)tokenBeingWritten][(int)_currentState];
if (newState == State.Error)
throw new JsonWriterException("Token {0} in state {1} would result in an invalid JavaScript object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), _currentState.ToString()));
throw new JsonWriterException("Token {0} in state {1} would result in an invalid JSON object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), _currentState.ToString()));
if ((_currentState == State.Object || _currentState == State.Array || _currentState == State.Constructor) && tokenBeingWritten != JsonToken.Comment)
{
@@ -157,12 +157,12 @@ namespace Newtonsoft.Json.Schema
model.PatternProperties[property.Key] = BuildNodeModel(property.Value);
}
for (int i = 0; i < node.Items.Count; i++)
foreach (JsonSchemaNode t in node.Items)
{
if (model.Items == null)
model.Items = new List<JsonSchemaModel>();
model.Items.Add(BuildNodeModel(node.Items[i]));
model.Items.Add(BuildNodeModel(t));
}
if (node.AdditionalProperties != null)
model.AdditionalProperties = BuildNodeModel(node.AdditionalProperties);
@@ -594,7 +594,7 @@ namespace Newtonsoft.Json.Serialization
JsonISerializableContract contract = new JsonISerializableContract(objectType);
InitializeContract(contract);
ConstructorInfo constructorInfo = objectType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(SerializationInfo), typeof(StreamingContext) }, null);
ConstructorInfo constructorInfo = contract.NonNullableUnderlyingType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(SerializationInfo), typeof(StreamingContext) }, null);
if (constructorInfo != null)
{
MethodCall<object, object> methodCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(constructorInfo);
@@ -647,37 +647,37 @@ namespace Newtonsoft.Json.Serialization
Type t = ReflectionUtils.EnsureNotNullableType(objectType);
if (JsonConvert.IsJsonPrimitiveType(t))
return CreatePrimitiveContract(t);
return CreatePrimitiveContract(objectType);
if (JsonTypeReflector.GetJsonObjectAttribute(t) != null)
return CreateObjectContract(t);
return CreateObjectContract(objectType);
if (JsonTypeReflector.GetJsonArrayAttribute(t) != null)
return CreateArrayContract(t);
return CreateArrayContract(objectType);
if (t == typeof(JToken) || t.IsSubclassOf(typeof(JToken)))
return CreateLinqContract(t);
return CreateLinqContract(objectType);
if (CollectionUtils.IsDictionaryType(t))
return CreateDictionaryContract(t);
return CreateDictionaryContract(objectType);
if (typeof(IEnumerable).IsAssignableFrom(t))
return CreateArrayContract(t);
return CreateArrayContract(objectType);
if (CanConvertToString(t))
return CreateStringContract(t);
return CreateStringContract(objectType);
#if !SILVERLIGHT && !PocketPC
if (typeof(ISerializable).IsAssignableFrom(t))
return CreateISerializableContract(t);
return CreateISerializableContract(objectType);
#endif
#if !(NET35 || NET20 || WINDOWS_PHONE)
if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(t))
return CreateDynamicContract(t);
return CreateDynamicContract(objectType);
#endif
return CreateObjectContract(t);
return CreateObjectContract(objectType);
}
internal static bool CanConvertToString(Type type)
@@ -35,6 +35,16 @@ namespace Newtonsoft.Json.Serialization
/// </summary>
public abstract class JsonContract
{
internal enum ReadType
{
Read,
ReadAsDecimal,
ReadAsBytes,
#if !NET20
ReadAsDateTimeOffset
#endif
}
/// <summary>
/// Gets the underlying type for the contract.
/// </summary>
@@ -63,22 +73,30 @@ namespace Newtonsoft.Json.Serialization
// checked for after passed in converters and attribute specified converters
internal JsonConverter InternalConverter { get; set; }
internal ReadType InternalReadType;
internal bool IsNullable;
internal bool IsConvertable;
internal Type NonNullableUnderlyingType;
#if !PocketPC
/// <summary>
/// Gets or sets the method called immediately after deserialization of the object.
/// </summary>
/// <value>The method called immediately after deserialization of the object.</value>
public MethodInfo OnDeserialized { get; set; }
/// <summary>
/// Gets or sets the method called during deserialization of the object.
/// </summary>
/// <value>The method called during deserialization of the object.</value>
public MethodInfo OnDeserializing { get; set; }
/// <summary>
/// Gets or sets the method called after serialization of the object graph.
/// </summary>
/// <value>The method called after serialization of the object graph.</value>
public MethodInfo OnSerialized { get; set; }
/// <summary>
/// Gets or sets the method called before serialization of the object.
/// </summary>
@@ -108,7 +126,7 @@ namespace Newtonsoft.Json.Serialization
{
#if !PocketPC
if (OnSerializing != null)
OnSerializing.Invoke(o, new object[] { context });
OnSerializing.Invoke(o, new object[] {context});
#endif
}
@@ -116,7 +134,7 @@ namespace Newtonsoft.Json.Serialization
{
#if !PocketPC
if (OnSerialized != null)
OnSerialized.Invoke(o, new object[] { context });
OnSerialized.Invoke(o, new object[] {context});
#endif
}
@@ -124,7 +142,7 @@ namespace Newtonsoft.Json.Serialization
{
#if !PocketPC
if (OnDeserializing != null)
OnDeserializing.Invoke(o, new object[] { context });
OnDeserializing.Invoke(o, new object[] {context});
#endif
}
@@ -132,14 +150,14 @@ namespace Newtonsoft.Json.Serialization
{
#if !PocketPC
if (OnDeserialized != null)
OnDeserialized.Invoke(o, new object[] { context });
OnDeserialized.Invoke(o, new object[] {context});
#endif
}
internal void InvokeOnError(object o, StreamingContext context, ErrorContext errorContext)
{
if (OnError != null)
OnError.Invoke(o, new object[] { context, errorContext });
OnError.Invoke(o, new object[] {context, errorContext});
}
internal JsonContract(Type underlyingType)
@@ -148,6 +166,31 @@ namespace Newtonsoft.Json.Serialization
UnderlyingType = underlyingType;
CreatedType = underlyingType;
IsNullable = ReflectionUtils.IsNullable(underlyingType);
NonNullableUnderlyingType = (IsNullable && ReflectionUtils.IsNullableType(underlyingType)) ? Nullable.GetUnderlyingType(underlyingType) : underlyingType;
IsConvertable = typeof(IConvertible).IsAssignableFrom(NonNullableUnderlyingType);
if (NonNullableUnderlyingType == typeof(byte[]))
{
InternalReadType = ReadType.ReadAsBytes;
}
else if (NonNullableUnderlyingType == typeof(decimal))
{
InternalReadType = ReadType.ReadAsDecimal;
}
#if !NET20
else if (NonNullableUnderlyingType == typeof(DateTimeOffset))
{
InternalReadType = ReadType.ReadAsDateTimeOffset;
}
#endif
else
{
InternalReadType = ReadType.Read;
}
}
}
}
@@ -45,6 +45,7 @@ namespace Newtonsoft.Json.Serialization
internal Type DictionaryKeyType { get; private set; }
internal Type DictionaryValueType { get; private set; }
internal JsonContract DictionaryKeyContract { get; set; }
internal JsonContract DictionaryValueContract { get; set; }
private readonly bool _isDictionaryValueTypeNullableType;
@@ -55,7 +55,7 @@ namespace Newtonsoft.Json.Serialization
private ErrorContext _currentErrorContext;
private BidirectionalDictionary<string, object> _mappings;
internal JsonSerializer Serializer { get; private set; }
internal readonly JsonSerializer Serializer;
protected JsonSerializerInternalBase(JsonSerializer serializer)
{
@@ -241,19 +241,17 @@ namespace Newtonsoft.Json.Serialization
case JsonToken.Boolean:
case JsonToken.Date:
case JsonToken.Bytes:
return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType);
return EnsureType(reader.Value, CultureInfo.InvariantCulture, contract, objectType);
case JsonToken.String:
// convert empty string to null automatically for nullable types
if (string.IsNullOrEmpty((string) reader.Value) &&
objectType != null &&
ReflectionUtils.IsNullableType(objectType))
if (string.IsNullOrEmpty((string) reader.Value) && objectType != typeof(string) && contract.IsNullable)
return null;
// string that needs to be returned as a byte array should be base 64 decoded
if (objectType == typeof (byte[]))
return Convert.FromBase64String((string) reader.Value);
return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType);
return EnsureType(reader.Value, CultureInfo.InvariantCulture, contract, objectType);
case JsonToken.StartConstructor:
case JsonToken.EndConstructor:
string constructorName = reader.Value.ToString();
@@ -264,7 +262,7 @@ namespace Newtonsoft.Json.Serialization
if (objectType == typeof (DBNull))
return DBNull.Value;
return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType);
return EnsureType(reader.Value, CultureInfo.InvariantCulture, contract, objectType);
case JsonToken.Raw:
return new JRaw((string) reader.Value);
case JsonToken.Comment:
@@ -310,90 +308,97 @@ namespace Newtonsoft.Json.Serialization
if (reader.TokenType == JsonToken.PropertyName)
{
bool specialProperty;
string propertyName = reader.Value.ToString();
do
if (propertyName.Length > 0 && propertyName[0] == '$')
{
string propertyName = reader.Value.ToString();
// read 'special' properties
// $type, $id, $ref, etc
bool specialProperty;
if (string.Equals(propertyName, JsonTypeReflector.RefPropertyName, StringComparison.Ordinal))
do
{
CheckedRead(reader);
if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Null)
throw new JsonSerializationException("JSON reference {0} property must have a string or null value.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName));
propertyName = reader.Value.ToString();
string reference = (reader.Value != null) ? reader.Value.ToString() : null;
CheckedRead(reader);
if (reference != null)
if (string.Equals(propertyName, JsonTypeReflector.RefPropertyName, StringComparison.Ordinal))
{
if (reader.TokenType == JsonToken.PropertyName)
throw new JsonSerializationException("Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName));
CheckedRead(reader);
if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Null)
throw new JsonSerializationException("JSON reference {0} property must have a string or null value.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName));
return Serializer.ReferenceResolver.ResolveReference(this, reference);
string reference = (reader.Value != null) ? reader.Value.ToString() : null;
CheckedRead(reader);
if (reference != null)
{
if (reader.TokenType == JsonToken.PropertyName)
throw new JsonSerializationException("Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName));
return Serializer.ReferenceResolver.ResolveReference(this, reference);
}
else
{
specialProperty = true;
}
}
else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal))
{
CheckedRead(reader);
string qualifiedTypeName = reader.Value.ToString();
CheckedRead(reader);
if ((((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling) != TypeNameHandling.None)
{
string typeName;
string assemblyName;
ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName, out typeName, out assemblyName);
Type specifiedType;
try
{
specifiedType = Serializer.Binder.BindToType(assemblyName, typeName);
}
catch (Exception ex)
{
throw new JsonSerializationException("Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex);
}
if (specifiedType == null)
throw new JsonSerializationException("Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName));
if (objectType != null && !objectType.IsAssignableFrom(specifiedType))
throw new JsonSerializationException("Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName));
objectType = specifiedType;
contract = GetContractSafe(specifiedType);
}
specialProperty = true;
}
else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
{
CheckedRead(reader);
id = (reader.Value != null) ? reader.Value.ToString() : null;
CheckedRead(reader);
specialProperty = true;
}
else if (string.Equals(propertyName, JsonTypeReflector.ArrayValuesPropertyName, StringComparison.Ordinal))
{
CheckedRead(reader);
object list = CreateList(reader, objectType, contract, member, existingValue, id);
CheckedRead(reader);
return list;
}
else
{
specialProperty = true;
specialProperty = false;
}
}
else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal))
{
CheckedRead(reader);
string qualifiedTypeName = reader.Value.ToString();
CheckedRead(reader);
if ((((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling) != TypeNameHandling.None)
{
string typeName;
string assemblyName;
ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName, out typeName, out assemblyName);
Type specifiedType;
try
{
specifiedType = Serializer.Binder.BindToType(assemblyName, typeName);
}
catch (Exception ex)
{
throw new JsonSerializationException("Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex);
}
if (specifiedType == null)
throw new JsonSerializationException("Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName));
if (objectType != null && !objectType.IsAssignableFrom(specifiedType))
throw new JsonSerializationException("Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName));
objectType = specifiedType;
contract = GetContractSafe(specifiedType);
}
specialProperty = true;
}
else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
{
CheckedRead(reader);
id = (reader.Value != null) ? reader.Value.ToString() : null;
CheckedRead(reader);
specialProperty = true;
}
else if (string.Equals(propertyName, JsonTypeReflector.ArrayValuesPropertyName, StringComparison.Ordinal))
{
CheckedRead(reader);
object list = CreateList(reader, objectType, contract, member, existingValue, id);
CheckedRead(reader);
return list;
}
else
{
specialProperty = false;
}
} while (specialProperty
&& reader.TokenType == JsonToken.PropertyName);
} while (specialProperty
&& reader.TokenType == JsonToken.PropertyName);
}
}
if (!HasDefinedType(objectType))
@@ -499,7 +504,7 @@ namespace Newtonsoft.Json.Serialization
);
}
private object EnsureType(object value, CultureInfo culture, Type targetType)
private object EnsureType(object value, CultureInfo culture, JsonContract contract, Type targetType)
{
if (targetType == null)
return value;
@@ -512,6 +517,22 @@ namespace Newtonsoft.Json.Serialization
{
try
{
if (value == null && contract.IsNullable)
return null;
if (contract.IsConvertable)
{
if (targetType.IsEnum)
{
if (value is string)
return Enum.Parse(targetType, value.ToString(), true);
else if (ConvertUtils.IsInteger(value))
return Enum.ToObject(targetType, value);
}
return Convert.ChangeType(value, contract.NonNullableUnderlyingType, culture);
}
return ConvertUtils.ConvertOrCast(value, culture, targetType);
}
catch (Exception ex)
@@ -654,9 +675,12 @@ namespace Newtonsoft.Json.Serialization
object keyValue = reader.Value;
try
{
if (contract.DictionaryKeyContract == null)
contract.DictionaryKeyContract = GetContractSafe(contract.DictionaryKeyType);
try
{
keyValue = EnsureType(keyValue, CultureInfo.InvariantCulture, contract.DictionaryKeyType);
keyValue = EnsureType(keyValue, CultureInfo.InvariantCulture, contract.DictionaryKeyContract, contract.DictionaryKeyType);
}
catch (Exception ex)
{
@@ -1069,47 +1093,46 @@ namespace Newtonsoft.Json.Serialization
private bool ReadForType(JsonReader reader, JsonContract contract, bool hasConverter, bool inArray)
{
Type t = (contract != null) ? contract.UnderlyingType : null;
// don't read properties with converters as a specific value
// the value might be a string which will then get converted which will error if read as date for example
if (hasConverter)
return reader.Read();
if (t == typeof (byte[]))
{
SetSerializeInArray(reader, inArray, true);
reader.ReadAsBytes();
SetSerializeInArray(reader, inArray, false);
JsonContract.ReadType t = (contract != null) ? contract.InternalReadType : JsonContract.ReadType.Read;
return true;
}
else if ((t == typeof (decimal) || t == typeof (decimal?)))
switch (t)
{
SetSerializeInArray(reader, inArray, true);
reader.ReadAsDecimal();
SetSerializeInArray(reader, inArray, false);
case JsonContract.ReadType.Read:
do
{
if (!reader.Read())
return false;
} while (reader.TokenType == JsonToken.Comment);
return true;
}
return true;
case JsonContract.ReadType.ReadAsDecimal:
SetSerializeInArray(reader, inArray, true);
reader.ReadAsDecimal();
SetSerializeInArray(reader, inArray, false);
return true;
case JsonContract.ReadType.ReadAsBytes:
SetSerializeInArray(reader, inArray, true);
reader.ReadAsBytes();
SetSerializeInArray(reader, inArray, false);
return true;
#if !NET20
else if ((t == typeof (DateTimeOffset) || t == typeof (DateTimeOffset?)))
{
SetSerializeInArray(reader, inArray, true);
reader.ReadAsDateTimeOffset();
SetSerializeInArray(reader, inArray, false);
case JsonContract.ReadType.ReadAsDateTimeOffset:
SetSerializeInArray(reader, inArray, true);
reader.ReadAsDateTimeOffset();
SetSerializeInArray(reader, inArray, false);
return true;
}
return true;
#endif
do
{
if (!reader.Read())
return false;
} while (reader.TokenType == JsonToken.Comment);
return true;
default:
throw new ArgumentOutOfRangeException();
}
}
private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id)
@@ -1178,9 +1201,12 @@ namespace Newtonsoft.Json.Serialization
if (property.Required == Required.AllowNull || property.Required == Required.Always)
throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));
if (property.PropertyContract == null)
property.PropertyContract = GetContractSafe(property.PropertyType);
if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Populate)
&& property.Writable)
property.ValueProvider.SetValue(newObject, EnsureType(property.DefaultValue, CultureInfo.InvariantCulture, property.PropertyType));
property.ValueProvider.SetValue(newObject, EnsureType(property.DefaultValue, CultureInfo.InvariantCulture, property.PropertyContract, property.PropertyType));
break;
case PropertyPresence.Null:
if (property.Required == Required.Always)
@@ -43,19 +43,8 @@ namespace Newtonsoft.Json.Serialization
{
internal class JsonSerializerInternalWriter : JsonSerializerInternalBase
{
private readonly List<object> _serializeStack = new List<object>();
private JsonSerializerProxy _internalSerializer;
private List<object> _serializeStack;
private List<object> SerializeStack
{
get
{
if (_serializeStack == null)
_serializeStack = new List<object>();
return _serializeStack;
}
}
public JsonSerializerInternalWriter(JsonSerializer serializer)
: base(serializer)
@@ -228,7 +217,7 @@ namespace Newtonsoft.Json.Serialization
if (value == null || contract is JsonPrimitiveContract)
return true;
if (SerializeStack.IndexOf(value) != -1)
if (_serializeStack.IndexOf(value) != -1)
{
switch (referenceLoopHandling.GetValueOrDefault(Serializer.ReferenceLoopHandling))
{
@@ -311,7 +300,7 @@ namespace Newtonsoft.Json.Serialization
{
contract.InvokeOnSerializing(value, Serializer.Context);
SerializeStack.Add(value);
_serializeStack.Add(value);
writer.WriteStartObject();
bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
@@ -352,7 +341,7 @@ namespace Newtonsoft.Json.Serialization
}
writer.WriteEndObject();
SerializeStack.RemoveAt(SerializeStack.Count - 1);
_serializeStack.RemoveAt(_serializeStack.Count - 1);
contract.InvokeOnSerialized(value, Serializer.Context);
}
@@ -389,11 +378,11 @@ namespace Newtonsoft.Json.Serialization
if (!CheckForCircularReference(value, null, contract))
return;
SerializeStack.Add(value);
_serializeStack.Add(value);
converter.WriteJson(writer, value, GetInternalSerializer());
SerializeStack.RemoveAt(SerializeStack.Count - 1);
_serializeStack.RemoveAt(_serializeStack.Count - 1);
}
}
@@ -401,7 +390,7 @@ namespace Newtonsoft.Json.Serialization
{
contract.InvokeOnSerializing(values.UnderlyingCollection, Serializer.Context);
SerializeStack.Add(values.UnderlyingCollection);
_serializeStack.Add(values.UnderlyingCollection);
bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, collectionValueContract);
@@ -471,7 +460,7 @@ namespace Newtonsoft.Json.Serialization
writer.WriteEndObject();
}
SerializeStack.RemoveAt(SerializeStack.Count - 1);
_serializeStack.RemoveAt(_serializeStack.Count - 1);
contract.InvokeOnSerialized(values.UnderlyingCollection, Serializer.Context);
}
@@ -484,7 +473,7 @@ namespace Newtonsoft.Json.Serialization
private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContract collectionValueContract)
{
contract.InvokeOnSerializing(value, Serializer.Context);
SerializeStack.Add(value);
_serializeStack.Add(value);
writer.WriteStartObject();
@@ -504,7 +493,7 @@ namespace Newtonsoft.Json.Serialization
writer.WriteEndObject();
SerializeStack.RemoveAt(SerializeStack.Count - 1);
_serializeStack.RemoveAt(_serializeStack.Count - 1);
contract.InvokeOnSerialized(value, Serializer.Context);
}
#endif
@@ -519,7 +508,7 @@ namespace Newtonsoft.Json.Serialization
private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract)
{
contract.InvokeOnSerializing(value, Serializer.Context);
SerializeStack.Add(value);
_serializeStack.Add(value);
writer.WriteStartObject();
@@ -539,7 +528,7 @@ namespace Newtonsoft.Json.Serialization
writer.WriteEndObject();
SerializeStack.RemoveAt(SerializeStack.Count - 1);
_serializeStack.RemoveAt(_serializeStack.Count - 1);
contract.InvokeOnSerialized(value, Serializer.Context);
}
#endif
@@ -574,7 +563,7 @@ namespace Newtonsoft.Json.Serialization
{
contract.InvokeOnSerializing(values.UnderlyingDictionary, Serializer.Context);
SerializeStack.Add(values.UnderlyingDictionary);
_serializeStack.Add(values.UnderlyingDictionary);
writer.WriteStartObject();
bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
@@ -636,7 +625,7 @@ namespace Newtonsoft.Json.Serialization
}
writer.WriteEndObject();
SerializeStack.RemoveAt(SerializeStack.Count - 1);
_serializeStack.RemoveAt(_serializeStack.Count - 1);
contract.InvokeOnSerialized(values.UnderlyingDictionary, Serializer.Context);
}
@@ -118,12 +118,6 @@ namespace Newtonsoft.Json.Utilities
if (targetType == initialType)
return initialValue;
if (initialValue is string && typeof(Type).IsAssignableFrom(targetType))
return Type.GetType((string) initialValue, true);
if (targetType.IsInterface || targetType.IsGenericTypeDefinition || targetType.IsAbstract)
throw new ArgumentException("Target type {0} is not a value type or a non-abstract class.".FormatWith(CultureInfo.InvariantCulture, targetType), "targetType");
// use Convert.ChangeType if both types are IConvertible
if (initialValue is IConvertible && typeof(IConvertible).IsAssignableFrom(targetType))
{
@@ -134,10 +128,16 @@ namespace Newtonsoft.Json.Utilities
else if (IsInteger(initialValue))
return Enum.ToObject(targetType, initialValue);
}
return System.Convert.ChangeType(initialValue, targetType, culture);
}
if (initialValue is string && typeof(Type).IsAssignableFrom(targetType))
return Type.GetType((string) initialValue, true);
if (targetType.IsInterface || targetType.IsGenericTypeDefinition || targetType.IsAbstract)
throw new ArgumentException("Target type {0} is not a value type or a non-abstract class.".FormatWith(CultureInfo.InvariantCulture, targetType), "targetType");
#if !PocketPC && !NET20
if (initialValue is DateTime && targetType == typeof(DateTimeOffset))
return new DateTimeOffset((DateTime)initialValue);
@@ -224,19 +224,19 @@ namespace Newtonsoft.Json.Utilities
callArgs.AddRange(args);
callArgs.Add(result);
DynamicMetaObject resultMO = new DynamicMetaObject(result, BindingRestrictions.Empty);
DynamicMetaObject resultMetaObject = new DynamicMetaObject(result, BindingRestrictions.Empty);
// Need to add a conversion if calling TryConvert
if (binder.ReturnType != typeof (object))
{
UnaryExpression convert = Expression.Convert(resultMO.Expression, binder.ReturnType);
UnaryExpression convert = Expression.Convert(resultMetaObject.Expression, binder.ReturnType);
// will always be a cast or unbox
resultMO = new DynamicMetaObject(convert, resultMO.Restrictions);
resultMetaObject = new DynamicMetaObject(convert, resultMetaObject.Restrictions);
}
if (fallbackInvoke != null)
resultMO = fallbackInvoke(resultMO);
resultMetaObject = fallbackInvoke(resultMetaObject);
DynamicMetaObject callDynamic = new DynamicMetaObject(
Expression.Block(
@@ -247,12 +247,12 @@ namespace Newtonsoft.Json.Utilities
typeof(DynamicProxy<T>).GetMethod(methodName),
callArgs
),
resultMO.Expression,
resultMetaObject.Expression,
fallbackResult.Expression,
binder.ReturnType
)
),
GetRestrictions().Merge(resultMO.Restrictions).Merge(fallbackResult.Restrictions)
GetRestrictions().Merge(resultMetaObject.Restrictions).Merge(fallbackResult.Restrictions)
);
return callDynamic;
@@ -51,7 +51,7 @@ namespace Newtonsoft.Json.Utilities
var c = s[i];
// don't escape standard text/numbers except '\' and the text delimiter
if (c >= ' ' && c < 128 && c != '\\' && c != '\'' && c != '"')
if (c >= ' ' && c < 128 && c != '\\' && c != delimiter)
continue;
string escapedValue;
@@ -86,12 +86,12 @@ namespace Newtonsoft.Json.Utilities
escapedValue = @"\u2029";
break;
case '\'':
// only escape if this charater is being used as the delimiter
escapedValue = (delimiter == '\'') ? @"\'" : null;
// this charater is being used as the delimiter
escapedValue = @"\'";
break;
case '"':
// only escape if this charater is being used as the delimiter
escapedValue = (delimiter == '"') ? "\\\"" : null;
// this charater is being used as the delimiter
escapedValue = "\\\"";
break;
default:
escapedValue = (c <= '\u001f') ? StringUtils.ToCharAsUnicode(c) : null;
@@ -202,21 +202,6 @@ namespace Newtonsoft.Json.Utilities
: t;
}
public static object CreateUnitializedValue(Type type)
{
ValidationUtils.ArgumentNotNull(type, "type");
if (type.IsGenericTypeDefinition)
throw new ArgumentException("Type {0} is a generic type definition and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, type), "type");
if (type.IsClass || type.IsInterface || type == typeof(void))
return null;
else if (type.IsValueType)
return Activator.CreateInstance(type);
else
throw new ArgumentException("Type {0} cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, type), "type");
}
public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition)
{
Type implementingType;
@@ -35,7 +35,7 @@ namespace Newtonsoft.Json.Utilities
private char[] _buffer;
private int _position;
private static readonly char[] _emptyBuffer = new char[0];
private static readonly char[] EmptyBuffer = new char[0];
public int Position
{
@@ -45,7 +45,7 @@ namespace Newtonsoft.Json.Utilities
public StringBuffer()
{
_buffer = _emptyBuffer;
_buffer = EmptyBuffer;
}
public StringBuffer(int initalSize)
@@ -75,7 +75,7 @@ namespace Newtonsoft.Json.Utilities
public void Clear()
{
_buffer = _emptyBuffer;
_buffer = EmptyBuffer;
_position = 0;
}