Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
Parameter.cs289 linesDownload Raw Back to hostifaces
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Management.Automation.Language;5 6using Microsoft.Management.Infrastructure;7 8namespace System.Management.Automation.Runspaces9{10    using System;11    using System.Collections.ObjectModel;12    using Debug = System.Management.Automation.Diagnostics;13 14    /// <summary>15    /// Define a parameter for <see cref="Command"/>16    /// </summary>17    public sealed class CommandParameter18    {19        #region Public constructors20 21        /// <summary>22        /// Create a named parameter with a null value.23        /// </summary>24        /// <param name="name">Parameter name.</param>25        /// <exception cref="ArgumentNullException">26        /// name is null.27        /// </exception>28        /// <exception cref="ArgumentException">29        /// Name length is zero after trimming whitespace.30        /// </exception>31        public CommandParameter(string name)32            : this(name, null)33        {34            if (name == null)35            {36                throw PSTraceSource.NewArgumentNullException(nameof(name));37            }38        }39 40        /// <summary>41        /// Create a named parameter.42        /// </summary>43        /// <param name="name">Parameter name.</param>44        /// <param name="value">Parameter value.</param>45        /// <exception cref="ArgumentException">46        /// Name is non null and name length is zero after trimming whitespace.47        /// </exception>48        public CommandParameter(string name, object value)49        {50            if (name != null)51            {52                if (string.IsNullOrWhiteSpace(name))53                {54                    throw PSTraceSource.NewArgumentException(nameof(name));55                }56 57                Name = name;58            }59            else60            {61                Name = null;62            }63 64            Value = value;65        }66 67        #endregion Public constructors68 69        #region Public properties70 71        /// <summary>72        /// Gets the parameter name.73        /// </summary>74        public string Name { get; }75 76        /// <summary>77        /// Gets the value of the parameter.78        /// </summary>79        public object Value { get; }80 81        #endregion Public properties82 83        /// <summary>84        /// Gets whether the parameter was from splatting a Hashtable.85        /// </summary>86        private bool FromHashtableSplatting { get; set; }87 88        #region Conversion from and to CommandParameterInternal89 90        internal static CommandParameter FromCommandParameterInternal(CommandParameterInternal internalParameter)91        {92            if (internalParameter == null)93            {94                throw PSTraceSource.NewArgumentNullException(nameof(internalParameter));95            }96 97            // we want the name to preserve 1) dashes, 2) colons, 3) followed-by-space information98            string name = null;99            if (internalParameter.ParameterNameSpecified)100            {101                name = internalParameter.ParameterText;102                if (internalParameter.SpaceAfterParameter)103                {104                    name += " ";105                }106 107                Diagnostics.Assert(name != null, "'name' variable should be initialized at this point");108                Diagnostics.Assert(name[0].IsDash(), "first character in parameter name must be a dash");109                Diagnostics.Assert(name.Trim().Length != 1, "Parameter name has to have some non-whitespace characters in it");110            }111 112            CommandParameter result = internalParameter.ParameterAndArgumentSpecified113                ? new CommandParameter(name, internalParameter.ArgumentValue)114                : name != null115                    ? new CommandParameter(name)116                    : new CommandParameter(name: null, internalParameter.ArgumentValue);117 118            result.FromHashtableSplatting = internalParameter.FromHashtableSplatting;119            return result;120        }121 122        internal static CommandParameterInternal ToCommandParameterInternal(CommandParameter publicParameter, bool forNativeCommand)123        {124            if (publicParameter == null)125            {126                throw PSTraceSource.NewArgumentNullException(nameof(publicParameter));127            }128 129            string name = publicParameter.Name;130            object value = publicParameter.Value;131 132            Debug.Assert((name == null) || (name.Trim().Length != 0), "Parameter name has to null or have some non-whitespace characters in it");133 134            if (name == null)135            {136                return CommandParameterInternal.CreateArgument(value);137            }138 139            string parameterText;140            if (!name[0].IsDash())141            {142                parameterText = forNativeCommand ? name : "-" + name;143                return CommandParameterInternal.CreateParameterWithArgument(144                    parameterAst: null,145                    parameterName: name,146                    parameterText: parameterText,147                    argumentAst: null,148                    value: value,149                    spaceAfterParameter: true);150            }151 152            // if first character of name is '-', then we try to fake the original token153            // reconstructing dashes, colons and followed-by-space information154 155            // find the last non-whitespace character156            bool spaceAfterParameter = false;157            int endPosition = name.Length;158            while ((endPosition > 0) && char.IsWhiteSpace(name[endPosition - 1]))159            {160                spaceAfterParameter = true;161                endPosition--;162            }163 164            Debug.Assert(endPosition > 0, "parameter name should have some non-whitespace characters in it");165 166            // now make sure that parameterText doesn't have whitespace at the end,167            parameterText = name.Substring(0, endPosition);168 169            // parameterName should contain only the actual name of the parameter (no whitespace, colons, dashes)170            bool hasColon = (name[endPosition - 1] == ':');171            var parameterName = parameterText.Substring(1, parameterText.Length - (hasColon ? 2 : 1));172 173            // At this point we have rebuilt the token.  There are 3 strings that might be different:174            //           name = nameToken.Script = "-foo: " <- needed to fake FollowedBySpace=true (i.e. for "testecho.exe -a:b -c: d")175            // tokenString = nameToken.TokenText = "-foo:" <- needed to preserve full token text (i.e. for write-output)176            //                    nameToken.Data =  "foo" <- needed to preserve name of parameter so parameter binding works177            // Now we just need to use the token to build appropriate CommandParameterInternal object178 179            // is this a name+value pair, or is it just a name (of a parameter)?180            if (!hasColon && value == null)181            {182                // just a name183                return CommandParameterInternal.CreateParameter(parameterName, parameterText);184            }185 186            // name+value pair187            return CommandParameterInternal.CreateParameterWithArgument(188                parameterAst: null,189                parameterName,190                parameterText,191                argumentAst: null,192                value,193                spaceAfterParameter,194                publicParameter.FromHashtableSplatting);195        }196 197        #endregion198 199        #region Serialization / deserialization for remoting200 201        /// <summary>202        /// Creates a CommandParameter object from a PSObject property bag.203        /// PSObject has to be in the format returned by ToPSObjectForRemoting method.204        /// </summary>205        /// <param name="parameterAsPSObject">PSObject to rehydrate.</param>206        /// <returns>207        /// CommandParameter rehydrated from a PSObject property bag208        /// </returns>209        /// <exception cref="ArgumentNullException">210        /// Thrown if the PSObject is null.211        /// </exception>212        /// <exception cref="System.Management.Automation.Remoting.PSRemotingDataStructureException">213        /// Thrown when the PSObject is not in the expected format214        /// </exception>215        internal static CommandParameter FromPSObjectForRemoting(PSObject parameterAsPSObject)216        {217            if (parameterAsPSObject == null)218            {219                throw PSTraceSource.NewArgumentNullException(nameof(parameterAsPSObject));220            }221 222            string name = RemotingDecoder.GetPropertyValue<string>(parameterAsPSObject, RemoteDataNameStrings.ParameterName);223            object value = RemotingDecoder.GetPropertyValue<object>(parameterAsPSObject, RemoteDataNameStrings.ParameterValue);224            return new CommandParameter(name, value);225        }226 227        /// <summary>228        /// Returns this object as a PSObject property bag229        /// that can be used in a remoting protocol data object.230        /// </summary>231        /// <returns>This object as a PSObject property bag.</returns>232        internal PSObject ToPSObjectForRemoting()233        {234            PSObject parameterAsPSObject = RemotingEncoder.CreateEmptyPSObject();235            parameterAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.ParameterName, this.Name));236            parameterAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.ParameterValue, this.Value));237            return parameterAsPSObject;238        }239 240        #endregion241    }242 243    /// <summary>244    /// Defines a collection of parameters.245    /// </summary>246    public sealed class CommandParameterCollection : Collection<CommandParameter>247    {248        // TODO: this class needs a mechanism to lock further changes249 250        /// <summary>251        /// Create a new empty instance of this collection type.252        /// </summary>253        public CommandParameterCollection()254        {255        }256 257        /// <summary>258        /// Add a parameter with given name and default null value.259        /// </summary>260        /// <param name="name">Name of the parameter.</param>261        /// <exception cref="ArgumentNullException">262        /// name is null.263        /// </exception>264        /// <exception cref="ArgumentException">265        /// Name length is zero after trimming whitespace.266        /// </exception>267        public void Add(string name)268        {269            Add(new CommandParameter(name));270        }271 272        /// <summary>273        /// Add a parameter with given name and value.274        /// </summary>275        /// <param name="name">Name of the parameter.</param>276        /// <param name="value">Value of the parameter.</param>277        /// <exception cref="ArgumentNullException">278        /// Both name and value are null. One of these must be non-null.279        /// </exception>280        /// <exception cref="ArgumentException">281        /// Name is non null and name length is zero after trimming whitespace.282        /// </exception>283        public void Add(string name, object value)284        {285            Add(new CommandParameter(name, value));286        }287    }288}289