/// <summary> /// Descendants iterator /// </summary> /// <param name="source"></param> /// <returns></returns> private static IEnumerable <TokenSequence> DescendantsIterator(TokenSequence source) { if (ModelSubsequencer.IsPrimitive(source)) { yield break; } if (ModelSubsequencer.IsObject(source)) { foreach (KeyValuePair <DataName, TokenSequence> property in ModelSubsequencer.Properties(source, null)) { yield return(property.Value); foreach (TokenSequence descendant in ModelSubsequencer.Descendants(property.Value)) { yield return(descendant); } } yield break; } if (ModelSubsequencer.IsArray(source)) { foreach (TokenSequence item in ModelSubsequencer.ArrayItems(source, null)) { yield return(item); foreach (TokenSequence descendant in ModelSubsequencer.Descendants(item)) { yield return(descendant); } } yield break; } }
/// <summary> /// Gets all properties of the root object /// </summary> /// <param name="source"></param> /// <param name="predicate"></param> /// <returns>all properties for the object</returns> public static TokenSequence Property(this TokenSequence source, DataName propertyName) { using (var enumerator = ModelSubsequencer.Properties(source, name => (name == propertyName)).GetEnumerator()) { // effectively FirstOrDefault() return(enumerator.MoveNext() ? enumerator.Current.Value : null); } }
private static IEnumerable <TokenSequence> SplitValuesIterator(TokenSequence source) { using (var stream = Stream <ModelToken> .Create(source)) { while (!stream.IsCompleted) { yield return(ModelSubsequencer.SpliceNextValue(stream)); } } }
/// <summary> /// DescendantsAndSelf iterator /// </summary> /// <param name="source"></param> /// <returns></returns> private static IEnumerable <TokenSequence> DescendantsAndSelfIterator(TokenSequence source) { // and self yield return(source); foreach (TokenSequence descendant in ModelSubsequencer.DescendantsIterator(source)) { yield return(descendant); } }
/// <summary> /// Covers the sitation where a stream of sequences may be back to back /// </summary> /// <param name="source"></param> /// <returns></returns> internal static IEnumerable <TokenSequence> SplitValues(this TokenSequence source) { if (source == null) { return(new TokenSequence[0]); } if (!(source is IList <ModelToken>)) { // ensure buffered source = new SequenceBuffer <ModelToken>(source); } return(ModelSubsequencer.SplitValuesIterator(source)); }
/// <summary> /// Gets all descendant values below the current root, as well as the current root /// </summary> /// <param name="source"></param> /// <returns></returns> public static IEnumerable <TokenSequence> DescendantsAndSelf(this TokenSequence source) { if (source == null) { throw new ArgumentNullException("source"); } if (!(source is IList <ModelToken>)) { // ensure buffered source = new SequenceBuffer <ModelToken>(source); } return(ModelSubsequencer.DescendantsAndSelfIterator(source)); }
/// <summary> /// Gets the items of the root array with indexes satisfying the <paramref name="predicate"/> /// </summary> /// <param name="source"></param> /// <param name="predicate"></param> /// <returns>items of the root array which statisfy the predicate</returns> public static IEnumerable <TokenSequence> ArrayItems(this TokenSequence source, Func <int, bool> predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (!(source is IList <ModelToken>)) { // ensure buffered source = new SequenceBuffer <ModelToken>(source); } return(ModelSubsequencer.ArrayItemsIterator(source, predicate)); }
/// <summary> /// Gets the properties of the root object which satisfies the <paramref name="predicate"/> /// </summary> /// <param name="source"></param> /// <param name="predicate"></param> /// <returns>matching properties for the root object</returns> public static IEnumerable <KeyValuePair <DataName, TokenSequence> > Properties(this TokenSequence source, Func <DataName, bool> predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (!(source is IList <ModelToken>)) { // ensure buffered source = new SequenceBuffer <ModelToken>(source); } return(ModelSubsequencer.PropertiesIterator(source, predicate)); }
/// <summary> /// ArrayItems iterator /// </summary> /// <param name="source"></param> /// <param name="predicate"></param> /// <returns></returns> private static IEnumerable <TokenSequence> ArrayItemsIterator(TokenSequence source, Func <int, bool> predicate) { IStream <ModelToken> stream = Stream <ModelToken> .Create(source); if (stream.IsCompleted) { yield break; } if (stream.Pop().TokenType != ModelTokenType.ArrayBegin) { yield return(source); yield break; } int index = 0; while (!stream.IsCompleted) { ModelToken token = stream.Peek(); if (token.TokenType == ModelTokenType.ArrayEnd) { break; } if (predicate == null || predicate(index)) { yield return(ModelSubsequencer.SpliceNextValue(stream)); } else { ModelSubsequencer.SkipNextValue(stream); } index++; } }
/// <summary> /// Gets all the items of the array /// </summary> /// <param name="source"></param> /// <returns>all items of the array</returns> public static IEnumerable <TokenSequence> ArrayItems(this TokenSequence source) { return(ModelSubsequencer.ArrayItems(source, null)); }
/// <summary> /// Gets the properties of the root object which satisfies the <paramref name="predicate"/> /// </summary> /// <param name="source"></param> /// <param name="predicate"></param> /// <returns>matching properties for the root object</returns> private static IEnumerable <KeyValuePair <DataName, TokenSequence> > PropertiesIterator(TokenSequence source, Func <DataName, bool> predicate) { IStream <ModelToken> stream = Stream <ModelToken> .Create(source); if (stream.IsCompleted || stream.Pop().TokenType != ModelTokenType.ObjectBegin) { yield break; } int depth = 0; while (!stream.IsCompleted) { ModelToken token = stream.Peek(); switch (token.TokenType) { case ModelTokenType.ArrayBegin: case ModelTokenType.ObjectBegin: { depth++; stream.Pop(); continue; } case ModelTokenType.ArrayEnd: { depth--; stream.Pop(); continue; } case ModelTokenType.ObjectEnd: { if (depth != 0) { depth--; stream.Pop(); continue; } // don't look beyond end of object yield break; } case ModelTokenType.Property: { stream.Pop(); if (depth != 0 || (predicate != null && !predicate(token.Name))) { continue; } // return property value sequence yield return(new KeyValuePair <DataName, TokenSequence>(token.Name, ModelSubsequencer.SpliceNextValue(stream))); continue; } default: { stream.Pop(); continue; } } } }
/// <summary> /// Gets all properties of the root object /// </summary> /// <param name="source"></param> /// <param name="predicate"></param> /// <returns>all properties for the object</returns> public static IEnumerable <KeyValuePair <DataName, TokenSequence> > Properties(this TokenSequence source) { return(ModelSubsequencer.Properties(source, null)); }