MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.Generic;5 6namespace Microsoft.PowerShell.Commands.Internal.Format7{8 /// <summary>9 /// INTERNAL IMPLEMENTATION CLASS10 ///11 /// It manages the finite state machine for the sequence of formatting messages.12 /// It achieves this by maintaining a stack of OutputContext-derived objects.13 /// A predefined set of events allows the host of this class to process the information14 /// as it comes trough the finite state machine (push model)15 ///16 /// IMPORTANT: The code using this class will have to provide ALL the callbacks.17 /// </summary>18 internal class FormatMessagesContextManager19 {20 // callbacks declarations21 internal delegate OutputContext FormatContextCreationCallback(OutputContext parentContext, FormatInfoData formatData);22 23 internal delegate void FormatStartCallback(OutputContext c);24 25 internal delegate void FormatEndCallback(FormatEndData fe, OutputContext c);26 27 internal delegate void GroupStartCallback(OutputContext c);28 29 internal delegate void GroupEndCallback(GroupEndData fe, OutputContext c);30 31 internal delegate void PayloadCallback(FormatEntryData formatEntryData, OutputContext c);32 33 // callback instances34 internal FormatContextCreationCallback contextCreation = null;35 internal FormatStartCallback fs = null;36 internal FormatEndCallback fe = null;37 internal GroupStartCallback gs = null;38 internal GroupEndCallback ge = null;39 internal PayloadCallback payload = null;40 41 /// <summary>42 /// The current output context, as determined by the43 /// sequence of formatting messages in the object stream.44 /// </summary>45 internal abstract class OutputContext46 {47 /// <summary>48 /// </summary>49 /// <param name="parentContextInStack">Parent context in the stack, it can be null.</param>50 internal OutputContext(OutputContext parentContextInStack)51 {52 ParentContext = parentContextInStack;53 }54 55 /// <summary>56 /// The outer context: the context object pushed onto the57 /// stack before the current one. For the first object pushed onto58 /// the stack it will be null.59 /// </summary>60 internal OutputContext ParentContext { get; }61 }62 63 /// <summary>64 /// Process an object from an input stream. It manages the context stack and65 /// calls back on the specified event delegates.66 /// </summary>67 /// <param name="o">Object to process.</param>68 internal void Process(object o)69 {70 PacketInfoData formatData = o as PacketInfoData;71 if (formatData is FormatEntryData fed)72 {73 OutputContext ctx = null;74 75 if (!fed.outOfBand)76 {77 ctx = _stack.Peek();78 }79 // notify for Payload80 this.payload(fed, ctx);81 }82 else83 {84 bool formatDataIsFormatStartData = formatData is FormatStartData;85 bool formatDataIsGroupStartData = formatData is GroupStartData;86 // it's one of our formatting messages87 // we assume for the moment that they are in the correct sequence88 if (formatDataIsFormatStartData || formatDataIsGroupStartData)89 {90 OutputContext oc = this.contextCreation(this.ActiveOutputContext, formatData);91 _stack.Push(oc);92 93 // now we have the context properly set: need to notify the94 // underlying algorithm to do the start document or group stuff95 if (formatDataIsFormatStartData)96 {97 // notify for Fs98 this.fs(oc);99 }100 else if (formatDataIsGroupStartData)101 {102 // GroupStartData gsd = (GroupStartData) formatData;103 // notify for Gs104 this.gs(oc);105 }106 }107 else108 {109 GroupEndData ged = formatData as GroupEndData;110 FormatEndData fEndd = formatData as FormatEndData;111 if (ged != null || fEndd != null)112 {113 OutputContext oc = _stack.Peek();114 if (fEndd != null)115 {116 // notify for Fe, passing the Fe info, before a Pop()117 this.fe(fEndd, oc);118 }119 else if (ged != null)120 {121 // notify for Fe, passing the Fe info, before a Pop()122 this.ge(ged, oc);123 }124 125 _stack.Pop();126 }127 }128 }129 }130 131 /// <summary>132 /// Access the active context (top of the stack). It can be null.133 /// </summary>134 internal OutputContext ActiveOutputContext135 {136 get { return (_stack.Count > 0) ? _stack.Peek() : null; }137 }138 139 /// <summary>140 /// Internal stack to manage context.141 /// </summary>142 private readonly Stack<OutputContext> _stack = new Stack<OutputContext>();143 }144}145 