private static IEnumerable <TokenSequence> SplitValuesIterator(TokenSequence source) { using (var stream = Stream <ModelToken> .Create(source)) { while (!stream.IsCompleted) { yield return(ModelSubsequencer.SpliceNextValue(stream)); } } }
/// <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 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; } } } }