chore: 初始化北汽福田MES采集程序
This commit is contained in:
44
Common/00-1Json8.3/Json8.3/Linq/JsonPath/ArrayIndexFilter.cs
Normal file
44
Common/00-1Json8.3/Json8.3/Linq/JsonPath/ArrayIndexFilter.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json.Linq.JsonPath
|
||||
{
|
||||
internal class ArrayIndexFilter : PathFilter
|
||||
{
|
||||
public int? Index { get; set; }
|
||||
|
||||
public override IEnumerable<JToken> ExecuteFilter(IEnumerable<JToken> current, bool errorWhenNoMatch)
|
||||
{
|
||||
foreach (JToken t in current)
|
||||
{
|
||||
if (Index != null)
|
||||
{
|
||||
JToken v = GetTokenIndex(t, errorWhenNoMatch, Index.GetValueOrDefault());
|
||||
|
||||
if (v != null)
|
||||
{
|
||||
yield return v;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t is JArray || t is JConstructor)
|
||||
{
|
||||
foreach (JToken v in t)
|
||||
{
|
||||
yield return v;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (errorWhenNoMatch)
|
||||
{
|
||||
throw new JsonException("Index * not valid on {0}.".FormatWith(CultureInfo.InvariantCulture, t.GetType().Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Newtonsoft.Json.Linq.JsonPath
|
||||
{
|
||||
internal class ArrayMultipleIndexFilter : PathFilter
|
||||
{
|
||||
public List<int> Indexes { get; set; }
|
||||
|
||||
public override IEnumerable<JToken> ExecuteFilter(IEnumerable<JToken> current, bool errorWhenNoMatch)
|
||||
{
|
||||
foreach (JToken t in current)
|
||||
{
|
||||
foreach (int i in Indexes)
|
||||
{
|
||||
JToken v = GetTokenIndex(t, errorWhenNoMatch, i);
|
||||
|
||||
if (v != null)
|
||||
{
|
||||
yield return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Common/00-1Json8.3/Json8.3/Linq/JsonPath/ArraySliceFilter.cs
Normal file
88
Common/00-1Json8.3/Json8.3/Linq/JsonPath/ArraySliceFilter.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json.Linq.JsonPath
|
||||
{
|
||||
internal class ArraySliceFilter : PathFilter
|
||||
{
|
||||
public int? Start { get; set; }
|
||||
public int? End { get; set; }
|
||||
public int? Step { get; set; }
|
||||
|
||||
public override IEnumerable<JToken> ExecuteFilter(IEnumerable<JToken> current, bool errorWhenNoMatch)
|
||||
{
|
||||
if (Step == 0)
|
||||
{
|
||||
throw new JsonException("Step cannot be zero.");
|
||||
}
|
||||
|
||||
foreach (JToken t in current)
|
||||
{
|
||||
JArray a = t as JArray;
|
||||
if (a != null)
|
||||
{
|
||||
// set defaults for null arguments
|
||||
int stepCount = Step ?? 1;
|
||||
int startIndex = Start ?? ((stepCount > 0) ? 0 : a.Count - 1);
|
||||
int stopIndex = End ?? ((stepCount > 0) ? a.Count : -1);
|
||||
|
||||
// start from the end of the list if start is negitive
|
||||
if (Start < 0)
|
||||
{
|
||||
startIndex = a.Count + startIndex;
|
||||
}
|
||||
|
||||
// end from the start of the list if stop is negitive
|
||||
if (End < 0)
|
||||
{
|
||||
stopIndex = a.Count + stopIndex;
|
||||
}
|
||||
|
||||
// ensure indexes keep within collection bounds
|
||||
startIndex = Math.Max(startIndex, (stepCount > 0) ? 0 : int.MinValue);
|
||||
startIndex = Math.Min(startIndex, (stepCount > 0) ? a.Count : a.Count - 1);
|
||||
stopIndex = Math.Max(stopIndex, -1);
|
||||
stopIndex = Math.Min(stopIndex, a.Count);
|
||||
|
||||
bool positiveStep = (stepCount > 0);
|
||||
|
||||
if (IsValid(startIndex, stopIndex, positiveStep))
|
||||
{
|
||||
for (int i = startIndex; IsValid(i, stopIndex, positiveStep); i += stepCount)
|
||||
{
|
||||
yield return a[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (errorWhenNoMatch)
|
||||
{
|
||||
throw new JsonException("Array slice of {0} to {1} returned no results.".FormatWith(CultureInfo.InvariantCulture,
|
||||
Start != null ? Start.GetValueOrDefault().ToString(CultureInfo.InvariantCulture) : "*",
|
||||
End != null ? End.GetValueOrDefault().ToString(CultureInfo.InvariantCulture) : "*"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (errorWhenNoMatch)
|
||||
{
|
||||
throw new JsonException("Array slice is not valid on {0}.".FormatWith(CultureInfo.InvariantCulture, t.GetType().Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsValid(int index, int stopIndex, bool positiveStep)
|
||||
{
|
||||
if (positiveStep)
|
||||
{
|
||||
return (index < stopIndex);
|
||||
}
|
||||
|
||||
return (index > stopIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
Common/00-1Json8.3/Json8.3/Linq/JsonPath/FieldFilter.cs
Normal file
49
Common/00-1Json8.3/Json8.3/Linq/JsonPath/FieldFilter.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json.Linq.JsonPath
|
||||
{
|
||||
internal class FieldFilter : PathFilter
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public override IEnumerable<JToken> ExecuteFilter(IEnumerable<JToken> current, bool errorWhenNoMatch)
|
||||
{
|
||||
foreach (JToken t in current)
|
||||
{
|
||||
JObject o = t as JObject;
|
||||
if (o != null)
|
||||
{
|
||||
if (Name != null)
|
||||
{
|
||||
JToken v = o[Name];
|
||||
|
||||
if (v != null)
|
||||
{
|
||||
yield return v;
|
||||
}
|
||||
else if (errorWhenNoMatch)
|
||||
{
|
||||
throw new JsonException("Property '{0}' does not exist on JObject.".FormatWith(CultureInfo.InvariantCulture, Name));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (KeyValuePair<string, JToken> p in o)
|
||||
{
|
||||
yield return p.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (errorWhenNoMatch)
|
||||
{
|
||||
throw new JsonException("Property '{0}' not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, Name ?? "*", t.GetType().Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
#if NET20
|
||||
using Newtonsoft.Json.Utilities.LinqBridge;
|
||||
#else
|
||||
using System.Linq;
|
||||
#endif
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json.Linq.JsonPath
|
||||
{
|
||||
internal class FieldMultipleFilter : PathFilter
|
||||
{
|
||||
public List<string> Names { get; set; }
|
||||
|
||||
public override IEnumerable<JToken> ExecuteFilter(IEnumerable<JToken> current, bool errorWhenNoMatch)
|
||||
{
|
||||
foreach (JToken t in current)
|
||||
{
|
||||
JObject o = t as JObject;
|
||||
if (o != null)
|
||||
{
|
||||
foreach (string name in Names)
|
||||
{
|
||||
JToken v = o[name];
|
||||
|
||||
if (v != null)
|
||||
{
|
||||
yield return v;
|
||||
}
|
||||
|
||||
if (errorWhenNoMatch)
|
||||
{
|
||||
throw new JsonException("Property '{0}' does not exist on JObject.".FormatWith(CultureInfo.InvariantCulture, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (errorWhenNoMatch)
|
||||
{
|
||||
throw new JsonException("Properties {0} not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, string.Join(", ", Names.Select(n => "'" + n + "'").ToArray()), t.GetType().Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
777
Common/00-1Json8.3/Json8.3/Linq/JsonPath/JPath.cs
Normal file
777
Common/00-1Json8.3/Json8.3/Linq/JsonPath/JPath.cs
Normal file
@@ -0,0 +1,777 @@
|
||||
#region License
|
||||
// Copyright (c) 2007 James Newton-King
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json.Linq.JsonPath
|
||||
{
|
||||
internal class JPath
|
||||
{
|
||||
private readonly string _expression;
|
||||
public List<PathFilter> Filters { get; private set; }
|
||||
|
||||
private int _currentIndex;
|
||||
|
||||
public JPath(string expression)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(expression, nameof(expression));
|
||||
_expression = expression;
|
||||
Filters = new List<PathFilter>();
|
||||
|
||||
ParseMain();
|
||||
}
|
||||
|
||||
private void ParseMain()
|
||||
{
|
||||
int currentPartStartIndex = _currentIndex;
|
||||
|
||||
EatWhitespace();
|
||||
|
||||
if (_expression.Length == _currentIndex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_expression[_currentIndex] == '$')
|
||||
{
|
||||
if (_expression.Length == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// only increment position for "$." or "$["
|
||||
// otherwise assume property that starts with $
|
||||
char c = _expression[_currentIndex + 1];
|
||||
if (c == '.' || c == '[')
|
||||
{
|
||||
_currentIndex++;
|
||||
currentPartStartIndex = _currentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ParsePath(Filters, currentPartStartIndex, false))
|
||||
{
|
||||
int lastCharacterIndex = _currentIndex;
|
||||
|
||||
EatWhitespace();
|
||||
|
||||
if (_currentIndex < _expression.Length)
|
||||
{
|
||||
throw new JsonException("Unexpected character while parsing path: " + _expression[lastCharacterIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ParsePath(List<PathFilter> filters, int currentPartStartIndex, bool query)
|
||||
{
|
||||
bool scan = false;
|
||||
bool followingIndexer = false;
|
||||
bool followingDot = false;
|
||||
|
||||
bool ended = false;
|
||||
while (_currentIndex < _expression.Length && !ended)
|
||||
{
|
||||
char currentChar = _expression[_currentIndex];
|
||||
|
||||
switch (currentChar)
|
||||
{
|
||||
case '[':
|
||||
case '(':
|
||||
if (_currentIndex > currentPartStartIndex)
|
||||
{
|
||||
string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
|
||||
if (member == "*")
|
||||
{
|
||||
member = null;
|
||||
}
|
||||
|
||||
PathFilter filter = (scan) ? (PathFilter)new ScanFilter { Name = member } : new FieldFilter { Name = member };
|
||||
filters.Add(filter);
|
||||
scan = false;
|
||||
}
|
||||
|
||||
filters.Add(ParseIndexer(currentChar));
|
||||
_currentIndex++;
|
||||
currentPartStartIndex = _currentIndex;
|
||||
followingIndexer = true;
|
||||
followingDot = false;
|
||||
break;
|
||||
case ']':
|
||||
case ')':
|
||||
ended = true;
|
||||
break;
|
||||
case ' ':
|
||||
if (_currentIndex < _expression.Length)
|
||||
{
|
||||
ended = true;
|
||||
}
|
||||
break;
|
||||
case '.':
|
||||
if (_currentIndex > currentPartStartIndex)
|
||||
{
|
||||
string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
|
||||
if (member == "*")
|
||||
{
|
||||
member = null;
|
||||
}
|
||||
|
||||
PathFilter filter = (scan) ? (PathFilter)new ScanFilter { Name = member } : new FieldFilter { Name = member };
|
||||
filters.Add(filter);
|
||||
scan = false;
|
||||
}
|
||||
if (_currentIndex + 1 < _expression.Length && _expression[_currentIndex + 1] == '.')
|
||||
{
|
||||
scan = true;
|
||||
_currentIndex++;
|
||||
}
|
||||
_currentIndex++;
|
||||
currentPartStartIndex = _currentIndex;
|
||||
followingIndexer = false;
|
||||
followingDot = true;
|
||||
break;
|
||||
default:
|
||||
if (query && (currentChar == '=' || currentChar == '<' || currentChar == '!' || currentChar == '>' || currentChar == '|' || currentChar == '&'))
|
||||
{
|
||||
ended = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (followingIndexer)
|
||||
{
|
||||
throw new JsonException("Unexpected character following indexer: " + currentChar);
|
||||
}
|
||||
|
||||
_currentIndex++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool atPathEnd = (_currentIndex == _expression.Length);
|
||||
|
||||
if (_currentIndex > currentPartStartIndex)
|
||||
{
|
||||
string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex).TrimEnd();
|
||||
if (member == "*")
|
||||
{
|
||||
member = null;
|
||||
}
|
||||
PathFilter filter = (scan) ? (PathFilter)new ScanFilter { Name = member } : new FieldFilter { Name = member };
|
||||
filters.Add(filter);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no field name following dot in path and at end of base path/query
|
||||
if (followingDot && (atPathEnd || query))
|
||||
{
|
||||
throw new JsonException("Unexpected end while parsing path.");
|
||||
}
|
||||
}
|
||||
|
||||
return atPathEnd;
|
||||
}
|
||||
|
||||
private PathFilter ParseIndexer(char indexerOpenChar)
|
||||
{
|
||||
_currentIndex++;
|
||||
|
||||
char indexerCloseChar = (indexerOpenChar == '[') ? ']' : ')';
|
||||
|
||||
EnsureLength("Path ended with open indexer.");
|
||||
|
||||
EatWhitespace();
|
||||
|
||||
if (_expression[_currentIndex] == '\'')
|
||||
{
|
||||
return ParseQuotedField(indexerCloseChar);
|
||||
}
|
||||
else if (_expression[_currentIndex] == '?')
|
||||
{
|
||||
return ParseQuery(indexerCloseChar);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ParseArrayIndexer(indexerCloseChar);
|
||||
}
|
||||
}
|
||||
|
||||
private PathFilter ParseArrayIndexer(char indexerCloseChar)
|
||||
{
|
||||
int start = _currentIndex;
|
||||
int? end = null;
|
||||
List<int> indexes = null;
|
||||
int colonCount = 0;
|
||||
int? startIndex = null;
|
||||
int? endIndex = null;
|
||||
int? step = null;
|
||||
|
||||
while (_currentIndex < _expression.Length)
|
||||
{
|
||||
char currentCharacter = _expression[_currentIndex];
|
||||
|
||||
if (currentCharacter == ' ')
|
||||
{
|
||||
end = _currentIndex;
|
||||
EatWhitespace();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentCharacter == indexerCloseChar)
|
||||
{
|
||||
int length = (end ?? _currentIndex) - start;
|
||||
|
||||
if (indexes != null)
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
throw new JsonException("Array index expected.");
|
||||
}
|
||||
|
||||
string indexer = _expression.Substring(start, length);
|
||||
int index = Convert.ToInt32(indexer, CultureInfo.InvariantCulture);
|
||||
|
||||
indexes.Add(index);
|
||||
return new ArrayMultipleIndexFilter { Indexes = indexes };
|
||||
}
|
||||
else if (colonCount > 0)
|
||||
{
|
||||
if (length > 0)
|
||||
{
|
||||
string indexer = _expression.Substring(start, length);
|
||||
int index = Convert.ToInt32(indexer, CultureInfo.InvariantCulture);
|
||||
|
||||
if (colonCount == 1)
|
||||
{
|
||||
endIndex = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
step = index;
|
||||
}
|
||||
}
|
||||
|
||||
return new ArraySliceFilter { Start = startIndex, End = endIndex, Step = step };
|
||||
}
|
||||
else
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
throw new JsonException("Array index expected.");
|
||||
}
|
||||
|
||||
string indexer = _expression.Substring(start, length);
|
||||
int index = Convert.ToInt32(indexer, CultureInfo.InvariantCulture);
|
||||
|
||||
return new ArrayIndexFilter { Index = index };
|
||||
}
|
||||
}
|
||||
else if (currentCharacter == ',')
|
||||
{
|
||||
int length = (end ?? _currentIndex) - start;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
throw new JsonException("Array index expected.");
|
||||
}
|
||||
|
||||
if (indexes == null)
|
||||
{
|
||||
indexes = new List<int>();
|
||||
}
|
||||
|
||||
string indexer = _expression.Substring(start, length);
|
||||
indexes.Add(Convert.ToInt32(indexer, CultureInfo.InvariantCulture));
|
||||
|
||||
_currentIndex++;
|
||||
|
||||
EatWhitespace();
|
||||
|
||||
start = _currentIndex;
|
||||
end = null;
|
||||
}
|
||||
else if (currentCharacter == '*')
|
||||
{
|
||||
_currentIndex++;
|
||||
EnsureLength("Path ended with open indexer.");
|
||||
EatWhitespace();
|
||||
|
||||
if (_expression[_currentIndex] != indexerCloseChar)
|
||||
{
|
||||
throw new JsonException("Unexpected character while parsing path indexer: " + currentCharacter);
|
||||
}
|
||||
|
||||
return new ArrayIndexFilter();
|
||||
}
|
||||
else if (currentCharacter == ':')
|
||||
{
|
||||
int length = (end ?? _currentIndex) - start;
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
string indexer = _expression.Substring(start, length);
|
||||
int index = Convert.ToInt32(indexer, CultureInfo.InvariantCulture);
|
||||
|
||||
if (colonCount == 0)
|
||||
{
|
||||
startIndex = index;
|
||||
}
|
||||
else if (colonCount == 1)
|
||||
{
|
||||
endIndex = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
step = index;
|
||||
}
|
||||
}
|
||||
|
||||
colonCount++;
|
||||
|
||||
_currentIndex++;
|
||||
|
||||
EatWhitespace();
|
||||
|
||||
start = _currentIndex;
|
||||
end = null;
|
||||
}
|
||||
else if (!char.IsDigit(currentCharacter) && currentCharacter != '-')
|
||||
{
|
||||
throw new JsonException("Unexpected character while parsing path indexer: " + currentCharacter);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (end != null)
|
||||
{
|
||||
throw new JsonException("Unexpected character while parsing path indexer: " + currentCharacter);
|
||||
}
|
||||
|
||||
_currentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
throw new JsonException("Path ended with open indexer.");
|
||||
}
|
||||
|
||||
private void EatWhitespace()
|
||||
{
|
||||
while (_currentIndex < _expression.Length)
|
||||
{
|
||||
if (_expression[_currentIndex] != ' ')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
_currentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
private PathFilter ParseQuery(char indexerCloseChar)
|
||||
{
|
||||
_currentIndex++;
|
||||
EnsureLength("Path ended with open indexer.");
|
||||
|
||||
if (_expression[_currentIndex] != '(')
|
||||
{
|
||||
throw new JsonException("Unexpected character while parsing path indexer: " + _expression[_currentIndex]);
|
||||
}
|
||||
|
||||
_currentIndex++;
|
||||
|
||||
QueryExpression expression = ParseExpression();
|
||||
|
||||
_currentIndex++;
|
||||
EnsureLength("Path ended with open indexer.");
|
||||
EatWhitespace();
|
||||
|
||||
if (_expression[_currentIndex] != indexerCloseChar)
|
||||
{
|
||||
throw new JsonException("Unexpected character while parsing path indexer: " + _expression[_currentIndex]);
|
||||
}
|
||||
|
||||
return new QueryFilter
|
||||
{
|
||||
Expression = expression
|
||||
};
|
||||
}
|
||||
|
||||
private QueryExpression ParseExpression()
|
||||
{
|
||||
QueryExpression rootExpression = null;
|
||||
CompositeExpression parentExpression = null;
|
||||
|
||||
while (_currentIndex < _expression.Length)
|
||||
{
|
||||
EatWhitespace();
|
||||
|
||||
if (_expression[_currentIndex] != '@')
|
||||
{
|
||||
throw new JsonException("Unexpected character while parsing path query: " + _expression[_currentIndex]);
|
||||
}
|
||||
|
||||
_currentIndex++;
|
||||
|
||||
List<PathFilter> expressionPath = new List<PathFilter>();
|
||||
|
||||
if (ParsePath(expressionPath, _currentIndex, true))
|
||||
{
|
||||
throw new JsonException("Path ended with open query.");
|
||||
}
|
||||
|
||||
EatWhitespace();
|
||||
EnsureLength("Path ended with open query.");
|
||||
|
||||
QueryOperator op;
|
||||
object value = null;
|
||||
if (_expression[_currentIndex] == ')'
|
||||
|| _expression[_currentIndex] == '|'
|
||||
|| _expression[_currentIndex] == '&')
|
||||
{
|
||||
op = QueryOperator.Exists;
|
||||
}
|
||||
else
|
||||
{
|
||||
op = ParseOperator();
|
||||
|
||||
EatWhitespace();
|
||||
EnsureLength("Path ended with open query.");
|
||||
|
||||
value = ParseValue();
|
||||
|
||||
EatWhitespace();
|
||||
EnsureLength("Path ended with open query.");
|
||||
}
|
||||
|
||||
BooleanQueryExpression booleanExpression = new BooleanQueryExpression
|
||||
{
|
||||
Path = expressionPath,
|
||||
Operator = op,
|
||||
Value = (op != QueryOperator.Exists) ? new JValue(value) : null
|
||||
};
|
||||
|
||||
if (_expression[_currentIndex] == ')')
|
||||
{
|
||||
if (parentExpression != null)
|
||||
{
|
||||
parentExpression.Expressions.Add(booleanExpression);
|
||||
return rootExpression;
|
||||
}
|
||||
|
||||
return booleanExpression;
|
||||
}
|
||||
if (_expression[_currentIndex] == '&' && Match("&&"))
|
||||
{
|
||||
if (parentExpression == null || parentExpression.Operator != QueryOperator.And)
|
||||
{
|
||||
CompositeExpression andExpression = new CompositeExpression { Operator = QueryOperator.And };
|
||||
|
||||
if (parentExpression != null)
|
||||
{
|
||||
parentExpression.Expressions.Add(andExpression);
|
||||
}
|
||||
|
||||
parentExpression = andExpression;
|
||||
|
||||
if (rootExpression == null)
|
||||
{
|
||||
rootExpression = parentExpression;
|
||||
}
|
||||
}
|
||||
|
||||
parentExpression.Expressions.Add(booleanExpression);
|
||||
}
|
||||
if (_expression[_currentIndex] == '|' && Match("||"))
|
||||
{
|
||||
if (parentExpression == null || parentExpression.Operator != QueryOperator.Or)
|
||||
{
|
||||
CompositeExpression orExpression = new CompositeExpression { Operator = QueryOperator.Or };
|
||||
|
||||
if (parentExpression != null)
|
||||
{
|
||||
parentExpression.Expressions.Add(orExpression);
|
||||
}
|
||||
|
||||
parentExpression = orExpression;
|
||||
|
||||
if (rootExpression == null)
|
||||
{
|
||||
rootExpression = parentExpression;
|
||||
}
|
||||
}
|
||||
|
||||
parentExpression.Expressions.Add(booleanExpression);
|
||||
}
|
||||
}
|
||||
|
||||
throw new JsonException("Path ended with open query.");
|
||||
}
|
||||
|
||||
private object ParseValue()
|
||||
{
|
||||
char currentChar = _expression[_currentIndex];
|
||||
if (currentChar == '\'')
|
||||
{
|
||||
return ReadQuotedString();
|
||||
}
|
||||
else if (char.IsDigit(currentChar) || currentChar == '-')
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(currentChar);
|
||||
|
||||
_currentIndex++;
|
||||
while (_currentIndex < _expression.Length)
|
||||
{
|
||||
currentChar = _expression[_currentIndex];
|
||||
if (currentChar == ' ' || currentChar == ')')
|
||||
{
|
||||
string numberText = sb.ToString();
|
||||
|
||||
if (numberText.IndexOfAny(new char[] { '.', 'E', 'e' }) != -1)
|
||||
{
|
||||
double d;
|
||||
if (double.TryParse(numberText, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out d))
|
||||
{
|
||||
return d;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonException("Could not read query value.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
long l;
|
||||
if (long.TryParse(numberText, NumberStyles.Integer, CultureInfo.InvariantCulture, out l))
|
||||
{
|
||||
return l;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonException("Could not read query value.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(currentChar);
|
||||
_currentIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (currentChar == 't')
|
||||
{
|
||||
if (Match("true"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (currentChar == 'f')
|
||||
{
|
||||
if (Match("false"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (currentChar == 'n')
|
||||
{
|
||||
if (Match("null"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
throw new JsonException("Could not read query value.");
|
||||
}
|
||||
|
||||
private string ReadQuotedString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
_currentIndex++;
|
||||
while (_currentIndex < _expression.Length)
|
||||
{
|
||||
char currentChar = _expression[_currentIndex];
|
||||
if (currentChar == '\\' && _currentIndex + 1 < _expression.Length)
|
||||
{
|
||||
_currentIndex++;
|
||||
|
||||
if (_expression[_currentIndex] == '\'')
|
||||
{
|
||||
sb.Append('\'');
|
||||
}
|
||||
else if (_expression[_currentIndex] == '\\')
|
||||
{
|
||||
sb.Append('\\');
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonException(@"Unknown escape chracter: \" + _expression[_currentIndex]);
|
||||
}
|
||||
|
||||
_currentIndex++;
|
||||
}
|
||||
else if (currentChar == '\'')
|
||||
{
|
||||
_currentIndex++;
|
||||
{
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentIndex++;
|
||||
sb.Append(currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
throw new JsonException("Path ended with an open string.");
|
||||
}
|
||||
|
||||
private bool Match(string s)
|
||||
{
|
||||
int currentPosition = _currentIndex;
|
||||
foreach (char c in s)
|
||||
{
|
||||
if (currentPosition < _expression.Length && _expression[currentPosition] == c)
|
||||
{
|
||||
currentPosition++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_currentIndex = currentPosition;
|
||||
return true;
|
||||
}
|
||||
|
||||
private QueryOperator ParseOperator()
|
||||
{
|
||||
if (_currentIndex + 1 >= _expression.Length)
|
||||
{
|
||||
throw new JsonException("Path ended with open query.");
|
||||
}
|
||||
|
||||
if (Match("=="))
|
||||
{
|
||||
return QueryOperator.Equals;
|
||||
}
|
||||
if (Match("!=") || Match("<>"))
|
||||
{
|
||||
return QueryOperator.NotEquals;
|
||||
}
|
||||
if (Match("<="))
|
||||
{
|
||||
return QueryOperator.LessThanOrEquals;
|
||||
}
|
||||
if (Match("<"))
|
||||
{
|
||||
return QueryOperator.LessThan;
|
||||
}
|
||||
if (Match(">="))
|
||||
{
|
||||
return QueryOperator.GreaterThanOrEquals;
|
||||
}
|
||||
if (Match(">"))
|
||||
{
|
||||
return QueryOperator.GreaterThan;
|
||||
}
|
||||
|
||||
throw new JsonException("Could not read query operator.");
|
||||
}
|
||||
|
||||
private PathFilter ParseQuotedField(char indexerCloseChar)
|
||||
{
|
||||
List<string> fields = null;
|
||||
|
||||
while (_currentIndex < _expression.Length)
|
||||
{
|
||||
string field = ReadQuotedString();
|
||||
|
||||
EatWhitespace();
|
||||
EnsureLength("Path ended with open indexer.");
|
||||
|
||||
if (_expression[_currentIndex] == indexerCloseChar)
|
||||
{
|
||||
if (fields != null)
|
||||
{
|
||||
fields.Add(field);
|
||||
return new FieldMultipleFilter { Names = fields };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new FieldFilter { Name = field };
|
||||
}
|
||||
}
|
||||
else if (_expression[_currentIndex] == ',')
|
||||
{
|
||||
_currentIndex++;
|
||||
EatWhitespace();
|
||||
|
||||
if (fields == null)
|
||||
{
|
||||
fields = new List<string>();
|
||||
}
|
||||
|
||||
fields.Add(field);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonException("Unexpected character while parsing path indexer: " + _expression[_currentIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
throw new JsonException("Path ended with open indexer.");
|
||||
}
|
||||
|
||||
private void EnsureLength(string message)
|
||||
{
|
||||
if (_currentIndex >= _expression.Length)
|
||||
{
|
||||
throw new JsonException(message);
|
||||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<JToken> Evaluate(JToken t, bool errorWhenNoMatch)
|
||||
{
|
||||
return Evaluate(Filters, t, errorWhenNoMatch);
|
||||
}
|
||||
|
||||
internal static IEnumerable<JToken> Evaluate(List<PathFilter> filters, JToken t, bool errorWhenNoMatch)
|
||||
{
|
||||
IEnumerable<JToken> current = new[] { t };
|
||||
foreach (PathFilter filter in filters)
|
||||
{
|
||||
current = filter.ExecuteFilter(current, errorWhenNoMatch);
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
}
|
||||
}
|
||||
55
Common/00-1Json8.3/Json8.3/Linq/JsonPath/PathFilter.cs
Normal file
55
Common/00-1Json8.3/Json8.3/Linq/JsonPath/PathFilter.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json.Linq.JsonPath
|
||||
{
|
||||
internal abstract class PathFilter
|
||||
{
|
||||
public abstract IEnumerable<JToken> ExecuteFilter(IEnumerable<JToken> current, bool errorWhenNoMatch);
|
||||
|
||||
protected static JToken GetTokenIndex(JToken t, bool errorWhenNoMatch, int index)
|
||||
{
|
||||
JArray a = t as JArray;
|
||||
JConstructor c = t as JConstructor;
|
||||
|
||||
if (a != null)
|
||||
{
|
||||
if (a.Count <= index)
|
||||
{
|
||||
if (errorWhenNoMatch)
|
||||
{
|
||||
throw new JsonException("Index {0} outside the bounds of JArray.".FormatWith(CultureInfo.InvariantCulture, index));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return a[index];
|
||||
}
|
||||
else if (c != null)
|
||||
{
|
||||
if (c.Count <= index)
|
||||
{
|
||||
if (errorWhenNoMatch)
|
||||
{
|
||||
throw new JsonException("Index {0} outside the bounds of JConstructor.".FormatWith(CultureInfo.InvariantCulture, index));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return c[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (errorWhenNoMatch)
|
||||
{
|
||||
throw new JsonException("Index {0} not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, index, t.GetType().Name));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
180
Common/00-1Json8.3/Json8.3/Linq/JsonPath/QueryExpression.cs
Normal file
180
Common/00-1Json8.3/Json8.3/Linq/JsonPath/QueryExpression.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json.Linq.JsonPath
|
||||
{
|
||||
internal enum QueryOperator
|
||||
{
|
||||
None = 0,
|
||||
Equals = 1,
|
||||
NotEquals = 2,
|
||||
Exists = 3,
|
||||
LessThan = 4,
|
||||
LessThanOrEquals = 5,
|
||||
GreaterThan = 6,
|
||||
GreaterThanOrEquals = 7,
|
||||
And = 8,
|
||||
Or = 9
|
||||
}
|
||||
|
||||
internal abstract class QueryExpression
|
||||
{
|
||||
public QueryOperator Operator { get; set; }
|
||||
|
||||
public abstract bool IsMatch(JToken t);
|
||||
}
|
||||
|
||||
internal class CompositeExpression : QueryExpression
|
||||
{
|
||||
public List<QueryExpression> Expressions { get; set; }
|
||||
|
||||
public CompositeExpression()
|
||||
{
|
||||
Expressions = new List<QueryExpression>();
|
||||
}
|
||||
|
||||
public override bool IsMatch(JToken t)
|
||||
{
|
||||
switch (Operator)
|
||||
{
|
||||
case QueryOperator.And:
|
||||
foreach (QueryExpression e in Expressions)
|
||||
{
|
||||
if (!e.IsMatch(t))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
case QueryOperator.Or:
|
||||
foreach (QueryExpression e in Expressions)
|
||||
{
|
||||
if (e.IsMatch(t))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class BooleanQueryExpression : QueryExpression
|
||||
{
|
||||
public List<PathFilter> Path { get; set; }
|
||||
public JValue Value { get; set; }
|
||||
|
||||
public override bool IsMatch(JToken t)
|
||||
{
|
||||
IEnumerable<JToken> pathResult = JPath.Evaluate(Path, t, false);
|
||||
|
||||
foreach (JToken r in pathResult)
|
||||
{
|
||||
JValue v = r as JValue;
|
||||
switch (Operator)
|
||||
{
|
||||
case QueryOperator.Equals:
|
||||
if (v != null && EqualsWithStringCoercion(v, Value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case QueryOperator.NotEquals:
|
||||
if (v != null && !EqualsWithStringCoercion(v, Value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case QueryOperator.GreaterThan:
|
||||
if (v != null && v.CompareTo(Value) > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case QueryOperator.GreaterThanOrEquals:
|
||||
if (v != null && v.CompareTo(Value) >= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case QueryOperator.LessThan:
|
||||
if (v != null && v.CompareTo(Value) < 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case QueryOperator.LessThanOrEquals:
|
||||
if (v != null && v.CompareTo(Value) <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case QueryOperator.Exists:
|
||||
return true;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool EqualsWithStringCoercion(JValue value, JValue queryValue)
|
||||
{
|
||||
if (value.Equals(queryValue))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (queryValue.Type != JTokenType.String)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string queryValueString = (string)queryValue.Value;
|
||||
|
||||
string currentValueString;
|
||||
|
||||
// potential performance issue with converting every value to string?
|
||||
switch (value.Type)
|
||||
{
|
||||
case JTokenType.Date:
|
||||
using (StringWriter writer = StringUtils.CreateStringWriter(64))
|
||||
{
|
||||
#if !NET20
|
||||
if (value.Value is DateTimeOffset)
|
||||
{
|
||||
DateTimeUtils.WriteDateTimeOffsetString(writer, (DateTimeOffset)value.Value, DateFormatHandling.IsoDateFormat, null, CultureInfo.InvariantCulture);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
DateTimeUtils.WriteDateTimeString(writer, (DateTime)value.Value, DateFormatHandling.IsoDateFormat, null, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
currentValueString = writer.ToString();
|
||||
}
|
||||
break;
|
||||
case JTokenType.Bytes:
|
||||
currentValueString = Convert.ToBase64String((byte[])value.Value);
|
||||
break;
|
||||
case JTokenType.Guid:
|
||||
case JTokenType.TimeSpan:
|
||||
currentValueString = value.Value.ToString();
|
||||
break;
|
||||
case JTokenType.Uri:
|
||||
currentValueString = ((Uri)value.Value).OriginalString;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return string.Equals(currentValueString, queryValueString, StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Common/00-1Json8.3/Json8.3/Linq/JsonPath/QueryFilter.cs
Normal file
24
Common/00-1Json8.3/Json8.3/Linq/JsonPath/QueryFilter.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Newtonsoft.Json.Linq.JsonPath
|
||||
{
|
||||
internal class QueryFilter : PathFilter
|
||||
{
|
||||
public QueryExpression Expression { get; set; }
|
||||
|
||||
public override IEnumerable<JToken> ExecuteFilter(IEnumerable<JToken> current, bool errorWhenNoMatch)
|
||||
{
|
||||
foreach (JToken t in current)
|
||||
{
|
||||
foreach (JToken v in t)
|
||||
{
|
||||
if (Expression.IsMatch(v))
|
||||
{
|
||||
yield return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
Common/00-1Json8.3/Json8.3/Linq/JsonPath/ScanFilter.cs
Normal file
63
Common/00-1Json8.3/Json8.3/Linq/JsonPath/ScanFilter.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Newtonsoft.Json.Linq.JsonPath
|
||||
{
|
||||
internal class ScanFilter : PathFilter
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public override IEnumerable<JToken> ExecuteFilter(IEnumerable<JToken> current, bool errorWhenNoMatch)
|
||||
{
|
||||
foreach (JToken root in current)
|
||||
{
|
||||
if (Name == null)
|
||||
{
|
||||
yield return root;
|
||||
}
|
||||
|
||||
JToken value = root;
|
||||
JToken container = root;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (container != null && container.HasValues)
|
||||
{
|
||||
value = container.First;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (value != null && value != root && value == value.Parent.Last)
|
||||
{
|
||||
value = value.Parent;
|
||||
}
|
||||
|
||||
if (value == null || value == root)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
value = value.Next;
|
||||
}
|
||||
|
||||
JProperty e = value as JProperty;
|
||||
if (e != null)
|
||||
{
|
||||
if (e.Name == Name)
|
||||
{
|
||||
yield return e.Value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Name == null)
|
||||
{
|
||||
yield return value;
|
||||
}
|
||||
}
|
||||
|
||||
container = value as JContainer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user