-Added JsonLoadSettings.LineInfoHandling
This commit is contained in:
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user