Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/Newtonsoft.Json.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamesNK <james@newtonking.com>2012-01-18 10:27:43 +0400
committerJamesNK <james@newtonking.com>2012-01-18 10:27:43 +0400
commitb146481c8742e63bd7ad7170f59634aad5878509 (patch)
tree01f511f917487665b35688ec756f2dd65e438d49
parent61db48c01d680a7214b9b1dc7147cc823aef74be (diff)
-Code clean up
-Various performance improvements
-rw-r--r--Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs26
-rw-r--r--Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs26
-rw-r--r--Src/Newtonsoft.Json.Tests/PerformanceTests.cs77
-rw-r--r--Src/Newtonsoft.Json/Bson/BsonReader.cs16
-rw-r--r--Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs74
-rw-r--r--Src/Newtonsoft.Json/JsonTextReader.cs108
-rw-r--r--Src/Newtonsoft.Json/JsonWriter.cs86
-rw-r--r--Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs4
-rw-r--r--Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs22
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonContract.cs53
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs1
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs2
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs238
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs39
-rw-r--r--Src/Newtonsoft.Json/Utilities/ConvertUtils.cs14
-rw-r--r--Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs12
-rw-r--r--Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs10
-rw-r--r--Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs15
-rw-r--r--Src/Newtonsoft.Json/Utilities/StringBuffer.cs6
19 files changed, 512 insertions, 317 deletions
diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs
index 0076a54..9be99ab 100644
--- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs
+++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs
@@ -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);
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs
index 0793cb6..614bd08 100644
--- a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs
+++ b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs
@@ -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;
+ }
+ }
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
index 89fcdcd..97af7d1 100644
--- a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
+++ b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
@@ -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,
@@ -63,16 +78,35 @@ 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 \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Bson/BsonReader.cs b/Src/Newtonsoft.Json/Bson/BsonReader.cs
index 8391e06..569183f 100644
--- a/Src/Newtonsoft.Json/Bson/BsonReader.cs
+++ b/Src/Newtonsoft.Json/Bson/BsonReader.cs
@@ -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;
}
diff --git a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
index 65dcba7..cd6a9e2 100644
--- a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
@@ -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
diff --git a/Src/Newtonsoft.Json/JsonTextReader.cs b/Src/Newtonsoft.Json/JsonTextReader.cs
index 7564d9e..1963c8e 100644
--- a/Src/Newtonsoft.Json/JsonTextReader.cs
+++ b/Src/Newtonsoft.Json/JsonTextReader.cs
@@ -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;
}
}
diff --git a/Src/Newtonsoft.Json/JsonWriter.cs b/Src/Newtonsoft.Json/JsonWriter.cs
index 0eb6837..fb430bf 100644
--- a/Src/Newtonsoft.Json/JsonWriter.cs
+++ b/Src/Newtonsoft.Json/JsonWriter.cs
@@ -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)
{
diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs
index ba3c750..f126b9a 100644
--- a/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs
+++ b/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs
@@ -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);
diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
index b3a5fb2..6e2a474 100644
--- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
+++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
@@ -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)
diff --git a/Src/Newtonsoft.Json/Serialization/JsonContract.cs b/Src/Newtonsoft.Json/Serialization/JsonContract.cs
index 857e535..f8b1a4e 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonContract.cs
@@ -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;
+ }
}
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs b/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
index 45a83b3..16c67fe 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
@@ -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;
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs
index f455636..761fa76 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs
@@ -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)
{
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
index a393f79..bb77dda 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
@@ -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);
- }
- else
- {
- specialProperty = true;
- }
- }
- else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal))
- {
- CheckedRead(reader);
- string qualifiedTypeName = reader.Value.ToString();
-
- CheckedRead(reader);
+ string reference = (reader.Value != null) ? reader.Value.ToString() : null;
- if ((((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling) != TypeNameHandling.None)
- {
- string typeName;
- string assemblyName;
- ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName, out typeName, out assemblyName);
+ CheckedRead(reader);
- Type specifiedType;
- try
+ if (reference != null)
{
- specifiedType = Serializer.Binder.BindToType(assemblyName, typeName);
+ 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);
}
- catch (Exception ex)
+ else
{
- throw new JsonSerializationException("Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex);
+ specialProperty = true;
}
+ }
+ else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal))
+ {
+ CheckedRead(reader);
+ string qualifiedTypeName = reader.Value.ToString();
- 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));
+ CheckedRead(reader);
- objectType = specifiedType;
- contract = GetContractSafe(specifiedType);
+ 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;
}
- specialProperty = true;
- }
- else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
- {
- CheckedRead(reader);
+ else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
+ {
+ CheckedRead(reader);
- id = (reader.Value != null) ? reader.Value.ToString() : null;
+ 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);
+ 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);
+ }
}
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);
-
- return true;
- }
+ case JsonContract.ReadType.Read:
+ do
+ {
+ if (!reader.Read())
+ return false;
+ } while (reader.TokenType == JsonToken.Comment);
+
+ 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)
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
index e0d8798..5ac8dcd 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
@@ -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);
}
diff --git a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
index 45dc8c3..e3b3d9d 100644
--- a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
+++ b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
@@ -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);
diff --git a/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs b/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs
index 347474a..bd61026 100644
--- a/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs
+++ b/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs
@@ -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;
diff --git a/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs b/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs
index c36020c..7c9222b 100644
--- a/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs
+++ b/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs
@@ -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;
diff --git a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
index 0a904dd..be3f467 100644
--- a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
+++ b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
@@ -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;
diff --git a/Src/Newtonsoft.Json/Utilities/StringBuffer.cs b/Src/Newtonsoft.Json/Utilities/StringBuffer.cs
index 321caa4..840540b 100644
--- a/Src/Newtonsoft.Json/Utilities/StringBuffer.cs
+++ b/Src/Newtonsoft.Json/Utilities/StringBuffer.cs
@@ -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;
}