-Added JsonLoadSettings.LineInfoHandling

This commit is contained in:
James Newton-King
2015-11-21 19:31:17 +13:00
parent 000407f610
commit 7903b4b2e2
16 changed files with 166 additions and 50 deletions
@@ -560,5 +560,21 @@ Parameter name: index");
Assert.AreEqual(2, (int)a[1]);
Assert.AreEqual(3, (int)a[2]);
}
[Test]
public void Parse_LineInfo()
{
string json = "[1,2,3]";
JArray a = JArray.Parse(json, new JsonLoadSettings
{
LineInfoHandling = LineInfoHandling.Load
});
Assert.AreEqual(false, ((IJsonLineInfo)a).HasLineInfo());
Assert.AreEqual(false, ((IJsonLineInfo)a[0]).HasLineInfo());
Assert.AreEqual(false, ((IJsonLineInfo)a[1]).HasLineInfo());
Assert.AreEqual(false, ((IJsonLineInfo)a[2]).HasLineInfo());
}
}
}
@@ -1,7 +1,7 @@
{
"dependencies": {
"NUnit": "2.6.2",
"FSharp.Core": "4.0.0"
"FSharp.Core": "4.0.0.1"
},
"frameworks": {
"net40": {}
@@ -1,6 +1,6 @@
{
"dependencies": {
"FSharp.Core": "4.0.0",
"FSharp.Core": "4.0.0.1",
"NUnit": "2.6.2",
"System.Collections.Immutable": "1.1.36"
},
@@ -1,6 +1,6 @@
{
"dependencies": {
"FSharp.Core": "4.0.0",
"FSharp.Core": "4.0.0.1",
"NUnit": "2.6.2"
},
"frameworks": {
@@ -1,7 +1,7 @@
{
"dependencies": {
"Autofac": "4.0.0-beta7-130",
"FSharp.Core": "4.0.0",
"FSharp.Core": "4.0.0.1",
"NUnit": "2.6.2",
"System.Collections.Immutable": "1.1.36"
},
+40 -5
View File
@@ -56,6 +56,20 @@ namespace Newtonsoft.Json
PropertyName = null;
}
internal int CalculateLength()
{
switch (Type)
{
case JsonContainerType.Object:
return PropertyName.Length + 5;
case JsonContainerType.Array:
case JsonContainerType.Constructor:
return MathUtils.IntLength((ulong)Position) + 2;
default:
throw new ArgumentOutOfRangeException("Type");
}
}
internal void WriteTo(StringBuilder sb)
{
switch (Type)
@@ -71,7 +85,9 @@ namespace Newtonsoft.Json
else
{
if (sb.Length > 0)
{
sb.Append('.');
}
sb.Append(propertyName);
}
@@ -90,13 +106,32 @@ namespace Newtonsoft.Json
return (type == JsonContainerType.Array || type == JsonContainerType.Constructor);
}
internal static string BuildPath(IEnumerable<JsonPosition> positions)
internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition)
{
StringBuilder sb = new StringBuilder();
foreach (JsonPosition state in positions)
int capacity = 0;
if (positions != null)
{
state.WriteTo(sb);
for (int i = 0; i < positions.Count; i++)
{
capacity += positions[i].CalculateLength();
}
}
if (currentPosition != null)
{
capacity += currentPosition.Value.CalculateLength();
}
StringBuilder sb = new StringBuilder(capacity);
if (positions != null)
{
foreach (JsonPosition state in positions)
{
state.WriteTo(sb);
}
}
if (currentPosition != null)
{
currentPosition.Value.WriteTo(sb);
}
return sb.ToString();
+19 -9
View File
@@ -128,7 +128,7 @@ namespace Newtonsoft.Json
internal DateParseHandling _dateParseHandling;
internal FloatParseHandling _floatParseHandling;
private string _dateFormatString;
private readonly List<JsonPosition> _stack;
private List<JsonPosition> _stack;
/// <summary>
/// Gets the current reader state.
@@ -280,11 +280,15 @@ namespace Newtonsoft.Json
{
get
{
int depth = _stack.Count;
int depth = (_stack != null) ? _stack.Count : 0;
if (JsonTokenUtils.IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None)
{
return depth;
}
else
{
return depth + 1;
}
}
}
@@ -302,11 +306,9 @@ namespace Newtonsoft.Json
&& _currentState != State.ConstructorStart
&& _currentState != State.ObjectStart);
IEnumerable<JsonPosition> positions = (!insideContainer)
? _stack
: _stack.Concat(new[] { _currentPosition });
JsonPosition? current = insideContainer ? (JsonPosition?)_currentPosition : null;
return JsonPosition.BuildPath(positions);
return JsonPosition.BuildPath(_stack, current);
}
}
@@ -321,8 +323,10 @@ namespace Newtonsoft.Json
internal JsonPosition GetPosition(int depth)
{
if (depth < _stack.Count)
if (_stack != null && depth < _stack.Count)
{
return _stack[depth];
}
return _currentPosition;
}
@@ -333,7 +337,6 @@ namespace Newtonsoft.Json
protected JsonReader()
{
_currentState = State.Start;
_stack = new List<JsonPosition>(4);
_dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
_dateParseHandling = DateParseHandling.DateTime;
_floatParseHandling = FloatParseHandling.Double;
@@ -351,6 +354,11 @@ namespace Newtonsoft.Json
}
else
{
if (_stack == null)
{
_stack = new List<JsonPosition>();
}
_stack.Add(_currentPosition);
_currentPosition = new JsonPosition(value);
@@ -366,7 +374,7 @@ namespace Newtonsoft.Json
private JsonContainerType Pop()
{
JsonPosition oldPosition;
if (_stack.Count > 0)
if (_stack != null && _stack.Count > 0)
{
oldPosition = _currentPosition;
_currentPosition = _stack[_stack.Count - 1];
@@ -379,7 +387,9 @@ namespace Newtonsoft.Json
}
if (_maxDepth != null && Depth <= _maxDepth)
{
_hasExceededMaxDepth = false;
}
return oldPosition.Type;
}
+20 -10
View File
@@ -113,7 +113,7 @@ namespace Newtonsoft.Json
StateArray = BuildStateArray();
}
private readonly List<JsonPosition> _stack;
private List<JsonPosition> _stack;
private JsonPosition _currentPosition;
private State _currentState;
private Formatting _formatting;
@@ -136,9 +136,11 @@ namespace Newtonsoft.Json
{
get
{
int depth = _stack.Count;
int depth = (_stack != null) ? _stack.Count : 0;
if (Peek() != JsonContainerType.None)
{
depth++;
}
return depth;
}
@@ -180,10 +182,12 @@ namespace Newtonsoft.Json
{
get
{
if (_currentPosition.Type == JsonContainerType.None)
if (_currentPosition.Type == JsonContainerType.None || _stack == null)
{
return string.Empty;
}
return JsonPosition.BuildPath(_stack);
return JsonPosition.BuildPath(_stack, null);
}
}
@@ -195,17 +199,17 @@ namespace Newtonsoft.Json
get
{
if (_currentPosition.Type == JsonContainerType.None)
{
return string.Empty;
}
bool insideContainer = (_currentState != State.ArrayStart
&& _currentState != State.ConstructorStart
&& _currentState != State.ObjectStart);
IEnumerable<JsonPosition> positions = (!insideContainer)
? _stack
: _stack.Concat(new[] { _currentPosition });
JsonPosition? current = insideContainer ? (JsonPosition?) _currentPosition : null;
return JsonPosition.BuildPath(positions);
return JsonPosition.BuildPath(_stack, current);
}
}
@@ -332,7 +336,6 @@ namespace Newtonsoft.Json
/// </summary>
protected JsonWriter()
{
_stack = new List<JsonPosition>(4);
_currentState = State.Start;
_formatting = Formatting.None;
_dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
@@ -349,7 +352,14 @@ namespace Newtonsoft.Json
private void Push(JsonContainerType value)
{
if (_currentPosition.Type != JsonContainerType.None)
{
if (_stack == null)
{
_stack = new List<JsonPosition>();
}
_stack.Add(_currentPosition);
}
_currentPosition = new JsonPosition(value);
}
@@ -358,7 +368,7 @@ namespace Newtonsoft.Json
{
JsonPosition oldPosition = _currentPosition;
if (_stack.Count > 0)
if (_stack != null && _stack.Count > 0)
{
_currentPosition = _stack[_stack.Count - 1];
_stack.RemoveAt(_stack.Count - 1);
@@ -14,4 +14,19 @@
/// </summary>
Load = 1
}
/// <summary>
/// Specifies how line information is handled when loading JSON.
/// </summary>
public enum LineInfoHandling
{
/// <summary>
/// Ignore line information.
/// </summary>
Ignore = 0,
/// <summary>
/// Load line information.
/// </summary>
Load = 1
}
}
+1 -1
View File
@@ -139,7 +139,7 @@ namespace Newtonsoft.Json.Linq
throw JsonReaderException.Create(reader, "Error reading JArray from JsonReader. Current JsonReader item is not an array: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
JArray a = new JArray();
a.SetLineInfo(reader as IJsonLineInfo);
a.SetLineInfo(reader as IJsonLineInfo, settings);
a.ReadTokenFrom(reader, settings);
+1 -1
View File
@@ -220,7 +220,7 @@ namespace Newtonsoft.Json.Linq
throw JsonReaderException.Create(reader, "Error reading JConstructor from JsonReader. Current JsonReader item is not a constructor: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
JConstructor c = new JConstructor((string)reader.Value);
c.SetLineInfo(reader as IJsonLineInfo);
c.SetLineInfo(reader as IJsonLineInfo, settings);
c.ReadTokenFrom(reader, settings);
+10 -10
View File
@@ -693,7 +693,7 @@ namespace Newtonsoft.Json.Linq
throw JsonReaderException.Create(reader, "Unexpected end of content while loading {0}.".FormatWith(CultureInfo.InvariantCulture, GetType().Name));
}
internal void ReadContentFrom(JsonReader r, JsonLoadSettings options)
internal void ReadContentFrom(JsonReader r, JsonLoadSettings settings)
{
ValidationUtils.ArgumentNotNull(r, "r");
IJsonLineInfo lineInfo = r as IJsonLineInfo;
@@ -717,7 +717,7 @@ namespace Newtonsoft.Json.Linq
break;
case JsonToken.StartArray:
JArray a = new JArray();
a.SetLineInfo(lineInfo);
a.SetLineInfo(lineInfo, settings);
parent.Add(a);
parent = a;
break;
@@ -730,7 +730,7 @@ namespace Newtonsoft.Json.Linq
break;
case JsonToken.StartObject:
JObject o = new JObject();
o.SetLineInfo(lineInfo);
o.SetLineInfo(lineInfo, settings);
parent.Add(o);
parent = o;
break;
@@ -742,7 +742,7 @@ namespace Newtonsoft.Json.Linq
break;
case JsonToken.StartConstructor:
JConstructor constructor = new JConstructor(r.Value.ToString());
constructor.SetLineInfo(lineInfo);
constructor.SetLineInfo(lineInfo, settings);
parent.Add(constructor);
parent = constructor;
break;
@@ -759,31 +759,31 @@ namespace Newtonsoft.Json.Linq
case JsonToken.Boolean:
case JsonToken.Bytes:
JValue v = new JValue(r.Value);
v.SetLineInfo(lineInfo);
v.SetLineInfo(lineInfo, settings);
parent.Add(v);
break;
case JsonToken.Comment:
if (options != null && options.CommentHandling == CommentHandling.Load)
if (settings != null && settings.CommentHandling == CommentHandling.Load)
{
v = JValue.CreateComment(r.Value.ToString());
v.SetLineInfo(lineInfo);
v.SetLineInfo(lineInfo, settings);
parent.Add(v);
}
break;
case JsonToken.Null:
v = JValue.CreateNull();
v.SetLineInfo(lineInfo);
v.SetLineInfo(lineInfo, settings);
parent.Add(v);
break;
case JsonToken.Undefined:
v = JValue.CreateUndefined();
v.SetLineInfo(lineInfo);
v.SetLineInfo(lineInfo, settings);
parent.Add(v);
break;
case JsonToken.PropertyName:
string propertyName = r.Value.ToString();
JProperty property = new JProperty(propertyName);
property.SetLineInfo(lineInfo);
property.SetLineInfo(lineInfo, settings);
JObject parentObject = (JObject)parent;
// handle multiple properties with the same name in JSON
JProperty existingPropertyWithName = parentObject.Property(propertyName);
+1 -1
View File
@@ -354,7 +354,7 @@ namespace Newtonsoft.Json.Linq
}
JObject o = new JObject();
o.SetLineInfo(reader as IJsonLineInfo);
o.SetLineInfo(reader as IJsonLineInfo, settings);
o.ReadTokenFrom(reader, settings);
+1 -1
View File
@@ -357,7 +357,7 @@ namespace Newtonsoft.Json.Linq
throw JsonReaderException.Create(reader, "Error reading JProperty from JsonReader. Current JsonReader item is not a property: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
JProperty p = new JProperty((string)reader.Value);
p.SetLineInfo(reader as IJsonLineInfo);
p.SetLineInfo(reader as IJsonLineInfo, settings);
p.ReadTokenFrom(reader, settings);
+19 -8
View File
@@ -186,15 +186,19 @@ namespace Newtonsoft.Json.Linq
IList<JToken> ancestors = AncestorsAndSelf().Reverse().ToList();
IList<JsonPosition> positions = new List<JsonPosition>();
List<JsonPosition> positions = new List<JsonPosition>();
for (int i = 0; i < ancestors.Count; i++)
{
JToken current = ancestors[i];
JToken next = null;
if (i + 1 < ancestors.Count)
{
next = ancestors[i + 1];
}
else if (ancestors[i].Type == JTokenType.Property)
{
next = ancestors[i];
}
if (next != null)
{
@@ -214,7 +218,7 @@ namespace Newtonsoft.Json.Linq
}
}
return JsonPosition.BuildPath(positions);
return JsonPosition.BuildPath(positions, null);
}
}
@@ -1894,7 +1898,7 @@ namespace Newtonsoft.Json.Linq
case JsonToken.Boolean:
case JsonToken.Bytes:
JValue v = new JValue(reader.Value);
v.SetLineInfo(lineInfo);
v.SetLineInfo(lineInfo, settings);
return v;
case JsonToken.Comment:
if (settings != null && settings.CommentHandling == CommentHandling.Ignore)
@@ -1906,15 +1910,15 @@ namespace Newtonsoft.Json.Linq
}
v = JValue.CreateComment(reader.Value.ToString());
v.SetLineInfo(lineInfo);
v.SetLineInfo(lineInfo, settings);
return v;
case JsonToken.Null:
v = JValue.CreateNull();
v.SetLineInfo(lineInfo);
v.SetLineInfo(lineInfo, settings);
return v;
case JsonToken.Undefined:
v = JValue.CreateUndefined();
v.SetLineInfo(lineInfo);
v.SetLineInfo(lineInfo, settings);
return v;
default:
throw JsonReaderException.Create(reader, "Error reading JToken from JsonReader. Unexpected token: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
@@ -1982,10 +1986,17 @@ namespace Newtonsoft.Json.Linq
return Load(reader, null);
}
internal void SetLineInfo(IJsonLineInfo lineInfo)
internal void SetLineInfo(IJsonLineInfo lineInfo, JsonLoadSettings settings)
{
if (lineInfo == null || !lineInfo.HasLineInfo())
if (settings != null && settings.LineInfoHandling == LineInfoHandling.Load)
{
return;
}
if (lineInfo == null || !lineInfo.HasLineInfo())
{
return;
}
SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
}
@@ -8,6 +8,7 @@ namespace Newtonsoft.Json.Linq
public class JsonLoadSettings
{
private CommentHandling _commentHandling;
private LineInfoHandling _lineInfoHandling;
/// <summary>
/// Gets or sets how JSON comments are handled when loading JSON.
@@ -26,5 +27,23 @@ namespace Newtonsoft.Json.Linq
_commentHandling = value;
}
}
/// <summary>
/// Gets or sets how JSON line info is handled when loading JSON.
/// </summary>
/// <value>The JSON line info handling.</value>
public LineInfoHandling LineInfoHandling
{
get { return _lineInfoHandling; }
set
{
if (value < LineInfoHandling.Ignore || value > LineInfoHandling.Load)
{
throw new ArgumentOutOfRangeException("value");
}
_lineInfoHandling = value;
}
}
}
}