using System.Collections.Generic; using System.Globalization; using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Linq.JsonPath { internal abstract class PathFilter { public abstract IEnumerable ExecuteFilter(JToken root, IEnumerable current, JsonSelectSettings? settings); protected static JToken? GetTokenIndex(JToken t, JsonSelectSettings? settings, int index) { if (t is JArray a) { if (a.Count <= index) { if (settings?.ErrorWhenNoMatch ?? false) { throw new JsonException("Index {0} outside the bounds of JArray.".FormatWith(CultureInfo.InvariantCulture, index)); } return null; } return a[index]; } else if (t is JConstructor c) { if (c.Count <= index) { if (settings?.ErrorWhenNoMatch ?? false) { throw new JsonException("Index {0} outside the bounds of JConstructor.".FormatWith(CultureInfo.InvariantCulture, index)); } return null; } return c[index]; } else { if (settings?.ErrorWhenNoMatch ?? false) { throw new JsonException("Index {0} not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, index, t.GetType().Name)); } return null; } } protected static JToken? GetNextScanValue(JToken originalParent, JToken? container, JToken? value) { // step into container's values if (container != null && container.HasValues) { value = container.First; } else { // finished container, move to parent while (value != null && value != originalParent && value == value.Parent!.Last) { value = value.Parent; } // finished if (value == null || value == originalParent) { return null; } // move to next value in container value = value.Next; } return value; } } }