/// <summary> /// Walks BSON tokens and validates and fires events on the supplied events instance. /// </summary> /// <param name="tokens"></param> /// <param name="events"></param> public void Walk(BSONTokenStream tokens, BSONWalkingEvents events) { _Start(tokens, events); tokens.MoveNext(); if (BSONTokenType.EOF != tokens.Current.Type) { throw new BSONValidationException("Expected EOF but got: " + tokens.Current.Type); } }
/// <summary> /// Walk a Document. Fires DocumentStart and DocumentEnd /// </summary> /// <param name="tokens"></param> /// <param name="events"></param> /// <param name="docType"></param> private void _Document(BSONTokenStream tokens, BSONWalkingEvents events, BSONTypes docType) { if (null != events) { events.RaiseDocumentStart(docType); } BSONToken next = tokens.Current; while (true) { tokens.MoveNext(); next = tokens.Current; if (BSONTokenType.END != next.Type && BSONTokenType.EOF != next.Type) { _DocumentElement(next, tokens, events); } else { break; } } if (BSONTokenType.END == next.Type) { if (null != events) { events.RaiseDocumentEnd(docType); } return; } else { throw new BSONValidationException("Expected value or end of document but got: " + next.Type); } }
/// <summary> /// Start walking the BSON structure. /// </summary> /// <param name="tokens"></param> /// <param name="events"></param> private void _Start(BSONTokenStream tokens, BSONWalkingEvents events) { tokens.MoveNext(); BSONToken next = tokens.Current; if (BSONTokenType.DOCUMENT_START == next.Type) { _Document(tokens, events, BSONTypes.DOCUMENT); } else if (BSONTokenType.ARRAY_START == next.Type) { _Document(tokens, events, BSONTypes.ARRAY); } else { throw new BSONValidationException("Expected DOCUMENT or ARRAY but got: " + next.Type); } }
private void _DocumentElement(BSONToken token, BSONTokenStream tokens, BSONWalkingEvents events) { if (BSONTokenType.END == token.Type || BSONTokenType.EOF == token.Type) { throw new BSONValidationException("Unexpected BSON token type encountered: " + token.Type); } if (BSONTokenType.DOCUMENT_START == token.Type) { events.RaiseElement(token.Name, token.Type); _Document(tokens, events, BSONTypes.DOCUMENT); } else if (BSONTokenType.ARRAY_START == token.Type) { events.RaiseElement(token.Name, token.Type); _Document(tokens, events, BSONTypes.ARRAY); } else if (BSONTokenType.CODE_WITH_SCOPE == token.Type) { events.RaiseElement(token.Name, token.Type); events.RaiseValue(token); tokens.MoveNext(); token = tokens.Current; if (BSONTokenType.END == token.Type || BSONTokenType.EOF == token.Type) { throw new BSONValidationException("Expected DOCUMENT but got: " + token.Type); } if (BSONTokenType.DOCUMENT_START == token.Type) { _Document(tokens, events, BSONTypes.DOCUMENT); } else if (BSONTokenType.ARRAY_START == token.Type) { _Document(tokens, events, BSONTypes.ARRAY); } } else { events.RaiseElement(token.Name, token.Type); events.RaiseValue(token); } }
public BSONSelector(BSONWalkingEvents events, string[] paths, BSONSelectorOptions options) { if (null == events) { throw new ArgumentNullException("events"); } _events = events; paths = paths ?? new string[0]; if (options.IgnoreArrays()) { // Filter out paths containing array specifiers _paths = paths.Where(p => -1 == p.IndexOf(ArraySpecifier)) .ToDictionary<string, string>(p => p); } else { _paths = paths.ToDictionary<string, string>(p => p); } _selectedValues = new List<SelectedValue>(); _options = options; _documentPathStack = new Stack<string>(); _docTypeStack = new Stack<BSONTypes>(); _docPath = string.Empty; _memberPath = string.Empty; _arrayIndex = -1; _arrayIndexStack = new Stack<int>(); _events.DocumentStart += new BSONEventHandler(_events_DocumentStart); _events.DocumentEnd += new BSONEventHandler(_events_DocumentEnd); _events.Element += new BSONElementEventHandler(_events_Element); _events.ArrayStart += new BSONEventHandler(_events_ArrayStart); _events.ArrayEnd += new BSONEventHandler(_events_ArrayEnd); _events.String += new BSONValueEventHandler<string>(_events_String); _events.Int32 += new BSONValueEventHandler<Int32>(_events_Int32); _events.Int64 += new BSONValueEventHandler<Int64>(_events_Int64); _events.Double += new BSONValueEventHandler<double>(_events_Double); _events.DateTime += new BSONValueEventHandler<DateTime>(_events_DateTime); _events.Value += new BSONValueEventHandler(_events_Value); _events.Null += new BSONEventHandler(_events_Null); _events.Boolean += new BSONValueEventHandler<bool>(_events_Boolean); }
public BSONSelector(BSONWalkingEvents events, string[] paths) : this(events, paths, DefaultOptions) { }
public static SelectedValue[] SelectValues(BinaryReader bson, string[] selectors, BSONSelectorOptions options) { if (null == bson) { return new SelectedValue[0]; } // Create tokenizer for the BSON document - this is fed to a Tree Walking Validator BSONTokenizer tokenizer = new BSONTokenizer(bson); // Create an events object for the Tree Walker - events are fired as the walker // traverses nodes in the tree. BSONWalkingEvents events = new BSONWalkingEvents(); // The selector subscribes to the Walker Events and selects the appropriate values from the // BSON tree. BSONSelector selector = new BSONSelector(events, selectors); // A BSON Tree Walker that validates the structure of the BSON and also fires events // while traversing the document. BSONWalkingValidator walker = new BSONWalkingValidator(); walker.Walk(tokenizer.GetEnumerator(), events); // Retrieve the values selected from the BSON. return selector.SelectedValues; }