-Added JContainer.DescendantsAndSelf
-Added CurrentToken to JTokenReader
This commit is contained in:
@@ -0,0 +1,250 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Newtonsoft.Json.Tests.Linq
|
||||
{
|
||||
[TestFixture]
|
||||
public class AnnotationsTests : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void AddAnnotation()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
o.AddAnnotation("A string!");
|
||||
|
||||
string s = o.Annotation<string>();
|
||||
Assert.AreEqual("A string!", s);
|
||||
|
||||
s = (string)o.Annotation(typeof(string));
|
||||
Assert.AreEqual("A string!", s);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAnnotation_MultipleOfTheSameType()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
o.AddAnnotation("A string!");
|
||||
o.AddAnnotation("Another string!");
|
||||
|
||||
string s = o.Annotation<string>();
|
||||
Assert.AreEqual("A string!", s);
|
||||
|
||||
s = (string)o.Annotation(typeof(string));
|
||||
Assert.AreEqual("A string!", s);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAnnotation_MultipleOfDifferentTypes()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
o.AddAnnotation("A string!");
|
||||
o.AddAnnotation(new Uri("http://www.google.com/"));
|
||||
|
||||
string s = o.Annotation<string>();
|
||||
Assert.AreEqual("A string!", s);
|
||||
|
||||
s = (string)o.Annotation(typeof(string));
|
||||
Assert.AreEqual("A string!", s);
|
||||
|
||||
Uri i = o.Annotation<Uri>();
|
||||
Assert.AreEqual(new Uri("http://www.google.com/"), i);
|
||||
|
||||
i = (Uri)o.Annotation(typeof(Uri));
|
||||
Assert.AreEqual(new Uri("http://www.google.com/"), i);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetAnnotation_NeverSet()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
|
||||
string s = o.Annotation<string>();
|
||||
Assert.AreEqual(null, s);
|
||||
|
||||
s = (string)o.Annotation(typeof(string));
|
||||
Assert.AreEqual(null, s);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetAnnotations()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
o.AddAnnotation("A string!");
|
||||
o.AddAnnotation("A string 2!");
|
||||
o.AddAnnotation("A string 3!");
|
||||
|
||||
IList<string> l = o.Annotations<string>().ToList();
|
||||
|
||||
Assert.AreEqual(3, l.Count);
|
||||
Assert.AreEqual("A string!", l[0]);
|
||||
Assert.AreEqual("A string 2!", l[1]);
|
||||
Assert.AreEqual("A string 3!", l[2]);
|
||||
|
||||
l = o.Annotations(typeof(string)).Cast<string>().ToList();
|
||||
|
||||
Assert.AreEqual(3, l.Count);
|
||||
Assert.AreEqual("A string!", l[0]);
|
||||
Assert.AreEqual("A string 2!", l[1]);
|
||||
Assert.AreEqual("A string 3!", l[2]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetAnnotations_MultipleTypes()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
o.AddAnnotation("A string!");
|
||||
o.AddAnnotation("A string 2!");
|
||||
o.AddAnnotation("A string 3!");
|
||||
o.AddAnnotation(new Uri("http://www.google.com/"));
|
||||
|
||||
IList<object> l = o.Annotations<object>().ToList();
|
||||
|
||||
Assert.AreEqual(4, l.Count);
|
||||
Assert.AreEqual("A string!", l[0]);
|
||||
Assert.AreEqual("A string 2!", l[1]);
|
||||
Assert.AreEqual("A string 3!", l[2]);
|
||||
Assert.AreEqual(new Uri("http://www.google.com/"), l[3]);
|
||||
|
||||
l = o.Annotations(typeof(object)).ToList();
|
||||
|
||||
Assert.AreEqual(4, l.Count);
|
||||
Assert.AreEqual("A string!", l[0]);
|
||||
Assert.AreEqual("A string 2!", l[1]);
|
||||
Assert.AreEqual("A string 3!", l[2]);
|
||||
Assert.AreEqual(new Uri("http://www.google.com/"), l[3]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RemoveAnnotation()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
o.AddAnnotation("A string!");
|
||||
|
||||
o.RemoveAnnotations<string>();
|
||||
|
||||
string s = o.Annotation<string>();
|
||||
Assert.AreEqual(null, s);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RemoveAnnotation_NonGeneric()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
o.AddAnnotation("A string!");
|
||||
|
||||
o.RemoveAnnotations(typeof(string));
|
||||
|
||||
string s = o.Annotation<string>();
|
||||
Assert.AreEqual(null, s);
|
||||
|
||||
s = (string)o.Annotation(typeof(string));
|
||||
Assert.AreEqual(null, s);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RemoveAnnotation_Multiple()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
o.AddAnnotation("A string!");
|
||||
o.AddAnnotation("A string 2!");
|
||||
o.AddAnnotation("A string 3!");
|
||||
|
||||
o.RemoveAnnotations<string>();
|
||||
|
||||
string s = o.Annotation<string>();
|
||||
Assert.AreEqual(null, s);
|
||||
|
||||
o.AddAnnotation("A string 4!");
|
||||
|
||||
s = o.Annotation<string>();
|
||||
Assert.AreEqual("A string 4!", s);
|
||||
|
||||
Uri i = (Uri)o.Annotation(typeof(Uri));
|
||||
Assert.AreEqual(null, i);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RemoveAnnotation_MultipleCalls()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
o.AddAnnotation("A string!");
|
||||
o.AddAnnotation(new Uri("http://www.google.com/"));
|
||||
|
||||
o.RemoveAnnotations<string>();
|
||||
o.RemoveAnnotations<Uri>();
|
||||
|
||||
string s = o.Annotation<string>();
|
||||
Assert.AreEqual(null, s);
|
||||
|
||||
Uri i = o.Annotation<Uri>();
|
||||
Assert.AreEqual(null, i);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RemoveAnnotation_Multiple_NonGeneric()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
o.AddAnnotation("A string!");
|
||||
o.AddAnnotation("A string 2!");
|
||||
|
||||
o.RemoveAnnotations(typeof(string));
|
||||
|
||||
string s = o.Annotation<string>();
|
||||
Assert.AreEqual(null, s);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RemoveAnnotation_MultipleCalls_NonGeneric()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
o.AddAnnotation("A string!");
|
||||
o.AddAnnotation(new Uri("http://www.google.com/"));
|
||||
|
||||
o.RemoveAnnotations(typeof(string));
|
||||
o.RemoveAnnotations(typeof(Uri));
|
||||
|
||||
string s = o.Annotation<string>();
|
||||
Assert.AreEqual(null, s);
|
||||
|
||||
Uri i = o.Annotation<Uri>();
|
||||
Assert.AreEqual(null, i);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RemoveAnnotation_MultipleWithDifferentTypes()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
o.AddAnnotation("A string!");
|
||||
o.AddAnnotation(new Uri("http://www.google.com/"));
|
||||
|
||||
o.RemoveAnnotations<string>();
|
||||
|
||||
string s = o.Annotation<string>();
|
||||
Assert.AreEqual(null, s);
|
||||
|
||||
Uri i = o.Annotation<Uri>();
|
||||
Assert.AreEqual(new Uri("http://www.google.com/"), i);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RemoveAnnotation_MultipleWithDifferentTypes_NonGeneric()
|
||||
{
|
||||
JObject o = new JObject();
|
||||
o.AddAnnotation("A string!");
|
||||
o.AddAnnotation(new Uri("http://www.google.com/"));
|
||||
|
||||
o.RemoveAnnotations(typeof(string));
|
||||
|
||||
string s = o.Annotation<string>();
|
||||
Assert.AreEqual(null, s);
|
||||
|
||||
Uri i = o.Annotation<Uri>();
|
||||
Assert.AreEqual(new Uri("http://www.google.com/"), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,8 +208,6 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
]
|
||||
}";
|
||||
|
||||
StringReader sr = new StringReader(input);
|
||||
|
||||
JObject o = JObject.Parse(input);
|
||||
|
||||
using (JTokenReader jsonReader = new JTokenReader(o))
|
||||
@@ -220,12 +218,14 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
Assert.AreEqual(0, lineInfo.LineNumber);
|
||||
Assert.AreEqual(0, lineInfo.LinePosition);
|
||||
Assert.AreEqual(false, lineInfo.HasLineInfo());
|
||||
Assert.AreEqual(null, jsonReader.CurrentToken);
|
||||
|
||||
jsonReader.Read();
|
||||
Assert.AreEqual(jsonReader.TokenType, JsonToken.StartObject);
|
||||
Assert.AreEqual(1, lineInfo.LineNumber);
|
||||
Assert.AreEqual(1, lineInfo.LinePosition);
|
||||
Assert.AreEqual(true, lineInfo.HasLineInfo());
|
||||
Assert.AreEqual(o, jsonReader.CurrentToken);
|
||||
|
||||
jsonReader.Read();
|
||||
Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName);
|
||||
@@ -233,6 +233,7 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
Assert.AreEqual(2, lineInfo.LineNumber);
|
||||
Assert.AreEqual(7, lineInfo.LinePosition);
|
||||
Assert.AreEqual(true, lineInfo.HasLineInfo());
|
||||
Assert.AreEqual(o.Property("CPU"), jsonReader.CurrentToken);
|
||||
|
||||
jsonReader.Read();
|
||||
Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
|
||||
@@ -240,6 +241,7 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
Assert.AreEqual(2, lineInfo.LineNumber);
|
||||
Assert.AreEqual(15, lineInfo.LinePosition);
|
||||
Assert.AreEqual(true, lineInfo.HasLineInfo());
|
||||
Assert.AreEqual(o.Property("CPU").Value, jsonReader.CurrentToken);
|
||||
|
||||
jsonReader.Read();
|
||||
Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName);
|
||||
@@ -247,12 +249,14 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
Assert.AreEqual(3, lineInfo.LineNumber);
|
||||
Assert.AreEqual(10, lineInfo.LinePosition);
|
||||
Assert.AreEqual(true, lineInfo.HasLineInfo());
|
||||
Assert.AreEqual(o.Property("Drives"), jsonReader.CurrentToken);
|
||||
|
||||
jsonReader.Read();
|
||||
Assert.AreEqual(jsonReader.TokenType, JsonToken.StartArray);
|
||||
Assert.AreEqual(3, lineInfo.LineNumber);
|
||||
Assert.AreEqual(12, lineInfo.LinePosition);
|
||||
Assert.AreEqual(true, lineInfo.HasLineInfo());
|
||||
Assert.AreEqual(o.Property("Drives").Value, jsonReader.CurrentToken);
|
||||
|
||||
jsonReader.Read();
|
||||
Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
|
||||
@@ -260,6 +264,7 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
Assert.AreEqual(4, lineInfo.LineNumber);
|
||||
Assert.AreEqual(22, lineInfo.LinePosition);
|
||||
Assert.AreEqual(true, lineInfo.HasLineInfo());
|
||||
Assert.AreEqual(o["Drives"][0], jsonReader.CurrentToken);
|
||||
|
||||
jsonReader.Read();
|
||||
Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
|
||||
@@ -267,21 +272,29 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
Assert.AreEqual(5, lineInfo.LineNumber);
|
||||
Assert.AreEqual(30, lineInfo.LinePosition);
|
||||
Assert.AreEqual(true, lineInfo.HasLineInfo());
|
||||
Assert.AreEqual(o["Drives"][1], jsonReader.CurrentToken);
|
||||
|
||||
jsonReader.Read();
|
||||
Assert.AreEqual(jsonReader.TokenType, JsonToken.EndArray);
|
||||
Assert.AreEqual(3, lineInfo.LineNumber);
|
||||
Assert.AreEqual(12, lineInfo.LinePosition);
|
||||
Assert.AreEqual(true, lineInfo.HasLineInfo());
|
||||
Assert.AreEqual(o["Drives"], jsonReader.CurrentToken);
|
||||
|
||||
jsonReader.Read();
|
||||
Assert.AreEqual(jsonReader.TokenType, JsonToken.EndObject);
|
||||
Assert.AreEqual(1, lineInfo.LineNumber);
|
||||
Assert.AreEqual(1, lineInfo.LinePosition);
|
||||
Assert.AreEqual(true, lineInfo.HasLineInfo());
|
||||
Assert.AreEqual(o, jsonReader.CurrentToken);
|
||||
|
||||
jsonReader.Read();
|
||||
Assert.AreEqual(jsonReader.TokenType, JsonToken.None);
|
||||
Assert.AreEqual(null, jsonReader.CurrentToken);
|
||||
|
||||
jsonReader.Read();
|
||||
Assert.AreEqual(jsonReader.TokenType, JsonToken.None);
|
||||
Assert.AreEqual(null, jsonReader.CurrentToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,15 +484,18 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
|
||||
JObject o = JObject.Parse(json);
|
||||
|
||||
JsonReader reader = o.CreateReader();
|
||||
JTokenReader reader = (JTokenReader)o.CreateReader();
|
||||
|
||||
Assert.IsTrue(reader.Read());
|
||||
Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
|
||||
Assert.AreEqual(o, reader.CurrentToken);
|
||||
|
||||
Assert.IsTrue(reader.Read());
|
||||
Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
|
||||
Assert.AreEqual(o.Property("Name"), reader.CurrentToken);
|
||||
|
||||
reader.ReadAsInt32();
|
||||
Assert.AreEqual(o["Name"], reader.CurrentToken);
|
||||
Assert.AreEqual(JsonToken.Integer, reader.TokenType);
|
||||
Assert.AreEqual(typeof(int), reader.ValueType);
|
||||
Assert.AreEqual(1, reader.Value);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
#if !(NET20 || NET35 || PORTABLE || ASPNETCORE50)
|
||||
using System.Numerics;
|
||||
#endif
|
||||
@@ -717,6 +718,35 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
Assert.AreEqual(3, (int)descendants[descendants.Count - 1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DescendantsAndSelf()
|
||||
{
|
||||
XElement e = new XElement("name");
|
||||
e.Add(new XElement("child"));
|
||||
|
||||
var x = e.DescendantsAndSelf().ToList();
|
||||
Assert.AreEqual(2, x.Count);
|
||||
Assert.AreEqual(e, x[0]);
|
||||
Assert.AreEqual(e.Element("child"), x[1]);
|
||||
|
||||
JArray a =
|
||||
new JArray(
|
||||
5,
|
||||
new JArray(1),
|
||||
new JArray(1, 2),
|
||||
new JArray(1, 2, 3)
|
||||
);
|
||||
|
||||
List<JToken> descendantsAndSelf = a.DescendantsAndSelf().ToList();
|
||||
Assert.AreEqual(11, descendantsAndSelf.Count());
|
||||
Assert.AreEqual(a, descendantsAndSelf[0]);
|
||||
Assert.AreEqual(5, (int)descendantsAndSelf[1]);
|
||||
Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), descendantsAndSelf[descendantsAndSelf.Count - 4]));
|
||||
Assert.AreEqual(1, (int)descendantsAndSelf[descendantsAndSelf.Count - 3]);
|
||||
Assert.AreEqual(2, (int)descendantsAndSelf[descendantsAndSelf.Count - 2]);
|
||||
Assert.AreEqual(3, (int)descendantsAndSelf[descendantsAndSelf.Count - 1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateWriter()
|
||||
{
|
||||
|
||||
@@ -213,6 +213,7 @@
|
||||
<Compile Include="LinqToSql\LinqToSqlClassesSerializationTests.cs" />
|
||||
<Compile Include="LinqToSql\Person.cs" />
|
||||
<Compile Include="LinqToSql\Role.cs" />
|
||||
<Compile Include="Linq\AnnotationsTests.cs" />
|
||||
<Compile Include="Linq\ComponentModel\BindingTests.cs" />
|
||||
<Compile Include="Linq\ComponentModel\JPropertyDescriptorTests.cs" />
|
||||
<Compile Include="Linq\DynamicTests.cs" />
|
||||
|
||||
@@ -35,7 +35,7 @@ using Newtonsoft.Json.Linq;
|
||||
namespace Newtonsoft.Json.Bson
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
|
||||
/// Represents a reader that provides fast, non-cached, forward-only access to serialized JSON data.
|
||||
/// </summary>
|
||||
public class BsonReader : JsonReader
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@ using System.Linq;
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
|
||||
/// Represents a reader that provides fast, non-cached, forward-only access to serialized JSON data.
|
||||
/// </summary>
|
||||
public abstract class JsonReader : IDisposable
|
||||
{
|
||||
|
||||
@@ -272,6 +272,23 @@ namespace Newtonsoft.Json.Linq
|
||||
/// <returns>An <see cref="IEnumerable{JToken}"/> containing the descendant tokens of the <see cref="JToken"/>.</returns>
|
||||
public IEnumerable<JToken> Descendants()
|
||||
{
|
||||
return GetDescendants(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a collection of the tokens that contain this token, and all descendant tokens of this token, in document order.
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="IEnumerable{JToken}"/> containing this token, and all the descendant tokens of the <see cref="JToken"/>.</returns>
|
||||
public IEnumerable<JToken> DescendantsAndSelf()
|
||||
{
|
||||
return GetDescendants(true);
|
||||
}
|
||||
|
||||
internal IEnumerable<JToken> GetDescendants(bool self)
|
||||
{
|
||||
if (self)
|
||||
yield return this;
|
||||
|
||||
foreach (JToken o in ChildrenTokens)
|
||||
{
|
||||
yield return o;
|
||||
|
||||
@@ -59,13 +59,15 @@ namespace Newtonsoft.Json.Linq
|
||||
, IDynamicMetaObjectProvider
|
||||
#endif
|
||||
{
|
||||
private static JTokenEqualityComparer _equalityComparer;
|
||||
|
||||
private JContainer _parent;
|
||||
private JToken _previous;
|
||||
private JToken _next;
|
||||
private static JTokenEqualityComparer _equalityComparer;
|
||||
private object _annotations;
|
||||
|
||||
private int? _lineNumber;
|
||||
private int? _linePosition;
|
||||
//private int? _lineNumber;
|
||||
//private int? _linePosition;
|
||||
|
||||
private static readonly JTokenType[] BooleanTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean };
|
||||
private static readonly JTokenType[] NumberTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean };
|
||||
@@ -1923,25 +1925,50 @@ namespace Newtonsoft.Json.Linq
|
||||
SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
|
||||
}
|
||||
|
||||
private class LineInfoAnnotation
|
||||
{
|
||||
internal readonly int LineNumber;
|
||||
internal readonly int LinePosition;
|
||||
|
||||
public LineInfoAnnotation(int lineNumber, int linePosition)
|
||||
{
|
||||
LineNumber = lineNumber;
|
||||
LinePosition = linePosition;
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetLineInfo(int lineNumber, int linePosition)
|
||||
{
|
||||
_lineNumber = lineNumber;
|
||||
_linePosition = linePosition;
|
||||
AddAnnotation(new LineInfoAnnotation(lineNumber, linePosition));
|
||||
}
|
||||
|
||||
bool IJsonLineInfo.HasLineInfo()
|
||||
{
|
||||
return (_lineNumber != null && _linePosition != null);
|
||||
return (Annotation<LineInfoAnnotation>() != null);
|
||||
}
|
||||
|
||||
int IJsonLineInfo.LineNumber
|
||||
{
|
||||
get { return _lineNumber ?? 0; }
|
||||
get
|
||||
{
|
||||
LineInfoAnnotation annotation = Annotation<LineInfoAnnotation>();
|
||||
if (annotation != null)
|
||||
return annotation.LineNumber;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int IJsonLineInfo.LinePosition
|
||||
{
|
||||
get { return _linePosition ?? 0; }
|
||||
get
|
||||
{
|
||||
LineInfoAnnotation annotation = Annotation<LineInfoAnnotation>();
|
||||
if (annotation != null)
|
||||
return annotation.LinePosition;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2047,5 +2074,266 @@ namespace Newtonsoft.Json.Linq
|
||||
{
|
||||
return CloneToken();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an object to the annotation list of this <see cref="JToken"/>.
|
||||
/// </summary>
|
||||
/// <param name="annotation">The annotation to add.</param>
|
||||
public void AddAnnotation(object annotation)
|
||||
{
|
||||
if (annotation == null)
|
||||
throw new ArgumentNullException("annotation");
|
||||
|
||||
if (_annotations == null)
|
||||
{
|
||||
_annotations = (annotation is object[]) ? new [] { annotation } : annotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
object[] annotations = _annotations as object[];
|
||||
if (annotations == null)
|
||||
{
|
||||
_annotations = new [] { _annotations, annotation };
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = 0;
|
||||
while (index < annotations.Length && annotations[index] != null)
|
||||
{
|
||||
index++;
|
||||
}
|
||||
if (index == annotations.Length)
|
||||
{
|
||||
Array.Resize(ref annotations, index * 2);
|
||||
_annotations = annotations;
|
||||
}
|
||||
annotations[index] = annotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the first annotation object of the specified type from this <see cref="JToken"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the annotation to retrieve.</typeparam>
|
||||
/// <returns>The first annotation object that matches the specified type, or <c>null</c> if no annotation is of the specified type.</returns>
|
||||
public T Annotation<T>() where T : class
|
||||
{
|
||||
if (_annotations != null)
|
||||
{
|
||||
object[] annotations = _annotations as object[];
|
||||
if (annotations == null)
|
||||
{
|
||||
return (_annotations as T);
|
||||
}
|
||||
for (int i = 0; i < annotations.Length; i++)
|
||||
{
|
||||
object annotation = annotations[i];
|
||||
if (annotation == null)
|
||||
break;
|
||||
|
||||
T local = annotation as T;
|
||||
if (local != null)
|
||||
return local;
|
||||
}
|
||||
}
|
||||
|
||||
return default(T);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first annotation object of the specified type from this <see cref="JToken"/>.
|
||||
/// </summary>
|
||||
/// <param name="type">The <see cref="Type"/> of the annotation to retrieve.</param>
|
||||
/// <returns>The first annotation object that matches the specified type, or <c>null</c> if no annotation is of the specified type.</returns>
|
||||
public object Annotation(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
throw new ArgumentNullException("type");
|
||||
|
||||
if (_annotations != null)
|
||||
{
|
||||
object[] annotations = _annotations as object[];
|
||||
if (annotations == null)
|
||||
{
|
||||
if (type.IsInstanceOfType(_annotations))
|
||||
return _annotations;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < annotations.Length; i++)
|
||||
{
|
||||
object o = annotations[i];
|
||||
if (o == null)
|
||||
break;
|
||||
|
||||
if (type.IsInstanceOfType(o))
|
||||
return o;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of annotations of the specified type for this <see cref="JToken"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the annotations to retrieve.</typeparam>
|
||||
/// <returns>An <see cref="IEnumerable{T}"/> that contains the annotations for this <see cref="JToken"/>.</returns>
|
||||
public IEnumerable<T> Annotations<T>() where T : class
|
||||
{
|
||||
if (_annotations == null)
|
||||
yield break;
|
||||
|
||||
object[] annotations = _annotations as object[];
|
||||
if (annotations != null)
|
||||
{
|
||||
for (int i = 0; i < annotations.Length; i++)
|
||||
{
|
||||
object o = annotations[i];
|
||||
if (o == null)
|
||||
break;
|
||||
|
||||
T casted = o as T;
|
||||
if (casted != null)
|
||||
yield return casted;
|
||||
}
|
||||
yield break;
|
||||
}
|
||||
|
||||
T annotation = _annotations as T;
|
||||
if (annotation == null)
|
||||
yield break;
|
||||
|
||||
yield return annotation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of annotations of the specified type for this <see cref="JToken"/>.
|
||||
/// </summary>
|
||||
/// <param name="type">The <see cref="Type"/> of the annotations to retrieve.</param>
|
||||
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="Object"/> that contains the annotations that match the specified type for this <see cref="JToken"/>.</returns>
|
||||
public IEnumerable<object> Annotations(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
throw new ArgumentNullException("type");
|
||||
|
||||
if (_annotations == null)
|
||||
yield break;
|
||||
|
||||
object[] annotations = _annotations as object[];
|
||||
if (annotations != null)
|
||||
{
|
||||
for (int i = 0; i < annotations.Length; i++)
|
||||
{
|
||||
object o = annotations[i];
|
||||
if (o == null)
|
||||
break;
|
||||
|
||||
if (type.IsInstanceOfType(o))
|
||||
yield return o;
|
||||
}
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (!type.IsInstanceOfType(_annotations))
|
||||
yield break;
|
||||
|
||||
yield return _annotations;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the annotations of the specified type from this <see cref="JToken"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of annotations to remove.</typeparam>
|
||||
public void RemoveAnnotations<T>() where T : class
|
||||
{
|
||||
if (_annotations != null)
|
||||
{
|
||||
object[] annotations = _annotations as object[];
|
||||
if (annotations == null)
|
||||
{
|
||||
if (_annotations is T)
|
||||
_annotations = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = 0;
|
||||
int keepCount = 0;
|
||||
while (index < annotations.Length)
|
||||
{
|
||||
object obj2 = annotations[index];
|
||||
if (obj2 == null)
|
||||
break;
|
||||
|
||||
if (!(obj2 is T))
|
||||
annotations[keepCount++] = obj2;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
if (keepCount != 0)
|
||||
{
|
||||
while (keepCount < index)
|
||||
{
|
||||
annotations[keepCount++] = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_annotations = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the annotations of the specified type from this <see cref="JToken"/>.
|
||||
/// </summary>
|
||||
/// <param name="type">The <see cref="Type"/> of annotations to remove.</param>
|
||||
public void RemoveAnnotations(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
throw new ArgumentNullException("type");
|
||||
|
||||
if (_annotations != null)
|
||||
{
|
||||
object[] annotations = _annotations as object[];
|
||||
if (annotations == null)
|
||||
{
|
||||
if (type.IsInstanceOfType(_annotations))
|
||||
_annotations = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = 0;
|
||||
int keepCount = 0;
|
||||
while (index < annotations.Length)
|
||||
{
|
||||
object o = annotations[index];
|
||||
if (o == null)
|
||||
break;
|
||||
|
||||
if (!type.IsInstanceOfType(o))
|
||||
annotations[keepCount++] = o;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
if (keepCount != 0)
|
||||
{
|
||||
while (keepCount < index)
|
||||
{
|
||||
annotations[keepCount++] = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_annotations = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,14 +29,22 @@ using Newtonsoft.Json.Utilities;
|
||||
namespace Newtonsoft.Json.Linq
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
|
||||
/// Represents a reader that provides fast, non-cached, forward-only access to serialized JSON data.
|
||||
/// </summary>
|
||||
public class JTokenReader : JsonReader, IJsonLineInfo
|
||||
{
|
||||
private readonly string _initialPath;
|
||||
private readonly JToken _root;
|
||||
private JToken _parent;
|
||||
internal JToken _current;
|
||||
private JToken _current;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="JToken"/> at the reader's current position.
|
||||
/// </summary>
|
||||
public JToken CurrentToken
|
||||
{
|
||||
get { return _current; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JTokenReader"/> class.
|
||||
@@ -47,7 +55,6 @@ namespace Newtonsoft.Json.Linq
|
||||
ValidationUtils.ArgumentNotNull(token, "token");
|
||||
|
||||
_root = token;
|
||||
_current = token;
|
||||
}
|
||||
|
||||
internal JTokenReader(JToken token, string initialPath)
|
||||
@@ -118,6 +125,9 @@ namespace Newtonsoft.Json.Linq
|
||||
{
|
||||
if (CurrentState != State.Start)
|
||||
{
|
||||
if (_current == null)
|
||||
return false;
|
||||
|
||||
JContainer container = _current as JContainer;
|
||||
if (container != null && _parent != container)
|
||||
return ReadInto(container);
|
||||
@@ -125,6 +135,7 @@ namespace Newtonsoft.Json.Linq
|
||||
return ReadOver(_current);
|
||||
}
|
||||
|
||||
_current = _root;
|
||||
SetToken(_current);
|
||||
return true;
|
||||
}
|
||||
@@ -165,6 +176,7 @@ namespace Newtonsoft.Json.Linq
|
||||
|
||||
private bool ReadToEnd()
|
||||
{
|
||||
_current = null;
|
||||
SetToken(JsonToken.None);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -526,7 +526,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
if (reader.TokenType == JsonToken.StartObject)
|
||||
{
|
||||
JObject current = (JObject)reader._current;
|
||||
JObject current = (JObject)reader.CurrentToken;
|
||||
|
||||
JToken refToken = current[JsonTypeReflector.RefPropertyName];
|
||||
if (refToken != null)
|
||||
|
||||
@@ -74,20 +74,16 @@ namespace Newtonsoft.Json.Utilities
|
||||
DoubleNullable = 25,
|
||||
DateTime = 26,
|
||||
DateTimeNullable = 27,
|
||||
#if !NET20
|
||||
DateTimeOffset = 28,
|
||||
DateTimeOffsetNullable = 29,
|
||||
#endif
|
||||
Decimal = 30,
|
||||
DecimalNullable = 31,
|
||||
Guid = 32,
|
||||
GuidNullable = 33,
|
||||
TimeSpan = 34,
|
||||
TimeSpanNullable = 35,
|
||||
#if !(PORTABLE || NET35 || NET20)
|
||||
BigInteger = 36,
|
||||
BigIntegerNullable = 37,
|
||||
#endif
|
||||
Uri = 38,
|
||||
String = 39,
|
||||
Bytes = 40,
|
||||
|
||||
@@ -76,6 +76,14 @@ namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
return type.GetTypeInfo().IsAssignableFrom(c.GetTypeInfo());
|
||||
}
|
||||
|
||||
public static bool IsInstanceOfType(this Type type, object o)
|
||||
{
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
return IsAssignableFrom(type, o.GetType());
|
||||
}
|
||||
#endif
|
||||
|
||||
public static MethodInfo Method(this Delegate d)
|
||||
|
||||
Reference in New Issue
Block a user