internal override void EndProcessing() { // need to pop all the contexts, in case the transmission sequence // was interrupted while (true) { FormattingContextState ctx = contextManager.Peek(); if (ctx == FormattingContextState.none) { break; // we emerged and we are done } else if (ctx == FormattingContextState.group) { PopGroup(); } else if (ctx == FormattingContextState.document) { // inject the end format information FormatEndData endFormat = new FormatEndData(); this.WriteObject(endFormat); contextManager.Pop(); } } // while }
/// <summary> /// compute the group transition, given an input object /// </summary> /// <param name="so">object received from the input pipeline</param> /// <returns>GroupTransition enumeration</returns> private GroupTransition ComputeGroupTransition(PSObject so) { // check if we have to start a group FormattingContextState ctx = contextManager.Peek(); if (ctx == FormattingContextState.document) { // prime the grouping algorithm _viewManager.ViewGenerator.UpdateGroupingKeyValue(so); // need to start a group, but we are not in one return(GroupTransition.enter); } // check if we need to start another group and keep track // of the current value for the grouping property return(_viewManager.ViewGenerator.UpdateGroupingKeyValue(so) ? GroupTransition.startNew : GroupTransition.none); }
/// <summary> /// execute formatting on a single object /// </summary> /// <param name="so">object to process</param> private void ProcessObject(PSObject so) { // we do protect against reentrancy, assuming // no fancy multiplexing if (_formatObjectDeserializer.IsFormatInfoData(so)) { // we are already formatted... this.WriteObject(so); return; } // if objects have to be treated as out of band, just // bail now // this is the case of objects coming before the // context manager is properly set if (ProcessOutOfBandObjectOutsideDocumentSequence(so)) { return; } // if we haven't started yet, need to do so FormattingContextState ctx = contextManager.Peek(); if (ctx == FormattingContextState.none) { // initialize the view manager _viewManager.Initialize(this.TerminatingErrorContext, _expressionFactory, _typeInfoDataBase, so, _shape, _parameters); // add the start message to output queue WriteFormatStartData(so); // enter the document context contextManager.Push(FormattingContextState.document); } // if we are here, we are either in the document document, or in a group // since we have a view now, we check if objects should be treated as out of band if (ProcessOutOfBandObjectInsideDocumentSequence(so)) { return; } // check if we have to enter or exit a group GroupTransition transition = ComputeGroupTransition(so); if (transition == GroupTransition.enter) { // insert the group start marker PushGroup(so); this.WritePayloadObject(so); } else if (transition == GroupTransition.exit) { this.WritePayloadObject(so); // insert the group end marker PopGroup(); } else if (transition == GroupTransition.startNew) { // double transition PopGroup(); // exit the current one PushGroup(so); // start a sibling group this.WritePayloadObject(so); } else // none, we did not have any transitions, just push out the data { this.WritePayloadObject(so); } }