Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
ArrayOps.cs303 linesDownload Raw Back to Operations
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4// ReSharper disable UnusedMember.Global5 6using System.Collections.Generic;7using System.Globalization;8using System.Management.Automation.Internal;9using System.Management.Automation.Runspaces;10 11namespace System.Management.Automation12{13    internal static class ArrayOps14    {15        internal static object AddObjectArray(object[] lhs, object rhs)16        {17            int newIdx = lhs.Length;18            Array.Resize(ref lhs, newIdx + 1);19            lhs[newIdx] = rhs;20 21            return lhs;22        }23 24        internal static object[] SlicingIndex(object target, object[] indexes, Func<object, object, object> indexer)25        {26            var result = new object[indexes.Length];27            int j = 0;28            foreach (object t in indexes)29            {30                var value = indexer(target, t);31                if (value != AutomationNull.Value)32                {33                    result[j++] = value;34                }35            }36 37            if (j != indexes.Length)38            {39                var shortResult = new object[j];40                Array.Copy(result, shortResult, j);41                return shortResult;42            }43 44            return result;45        }46 47        /// <summary>48        /// Efficiently multiplies collection by integer.49        /// </summary>50        /// <param name="array">Collection to multiply.</param>51        /// <param name="times">Number of times the collection is to be multiplied/copied.</param>52        /// <returns>Collection multiplied by integer.</returns>53        internal static T[] Multiply<T>(T[] array, uint times)54        {55            Diagnostics.Assert(array != null, "Caller should verify the arguments for array multiplication");56 57            if (times == 1)58            {59                return array;60            }61 62            if (times == 0 || array.Length == 0)63            {64#pragma warning disable CA1825 // Avoid zero-length array allocations65                // Don't use Array.Empty<T>(); always return a new instance.66                return new T[0];67#pragma warning restore CA1825 // Avoid zero-length array allocations68            }69 70            var context = LocalPipeline.GetExecutionContextFromTLS();71            if (context != null &&72                context.LanguageMode == PSLanguageMode.RestrictedLanguage && (array.Length * times) > 1024)73            {74                throw InterpreterError.NewInterpreterException(times, typeof(RuntimeException),75                    null, "ArrayMultiplyToolongInDataSection", ParserStrings.ArrayMultiplyToolongInDataSection, 1024);76            }77 78            var uncheckedLength = array.Length * times;79            int elements = -1;80            try81            {82                elements = checked((int)uncheckedLength);83            }84            catch (OverflowException)85            {86                LanguagePrimitives.ThrowInvalidCastException(uncheckedLength, typeof(int));87            }88 89            // Make the minimum number of calls to Array.Copy by doubling the array up to90            // the most significant bit in times, then do one final Array.Copy to get the91            // remaining copies.92 93            T[] result = new T[elements];94            int resultLength = array.Length;95            Array.Copy(array, 0, result, 0, resultLength);96            times >>= 1;97            while (times != 0)98            {99                Array.Copy(result, 0, result, resultLength, resultLength);100                resultLength *= 2;101                times >>= 1;102            }103 104            if (result.Length != resultLength)105            {106                Array.Copy(result, 0, result, resultLength, (result.Length - resultLength));107            }108 109            return result;110        }111 112        internal static object GetMDArrayValue(Array array, int[] indexes, bool slicing)113        {114            if (array.Rank != indexes.Length)115            {116                ReportIndexingError(array, indexes, null);117            }118 119            for (int i = 0; i < indexes.Length; ++i)120            {121                int ub = array.GetUpperBound(i);122                int lb = array.GetLowerBound(i);123                if (indexes[i] < lb)124                {125                    indexes[i] = indexes[i] + ub + 1;126                }127 128                if (indexes[i] < lb || indexes[i] > ub)129                {130                    // In strict mode, don't return, fall through and let Array.GetValue raise an exception.131                    var context = LocalPipeline.GetExecutionContextFromTLS();132                    if (context != null && !context.IsStrictVersion(3))133                    {134                        // If we're slicing, return AutomationNull.Value to signal no result)135                        return slicing ? AutomationNull.Value : null;136                    }137                }138            }139 140            // All indexes have been validated, so this won't raise an exception.141            return array.GetValue(indexes);142        }143 144        internal static object GetMDArrayValueOrSlice(Array array, object indexes)145        {146            Exception whyFailed = null;147            int[] indexArray = null;148            try149            {150                indexArray = (int[])LanguagePrimitives.ConvertTo(indexes, typeof(int[]), NumberFormatInfo.InvariantInfo);151            }152            catch (InvalidCastException ice)153            {154                // Ignore an exception here as we may actually be looking at an array of arrays155                // which could still be ok. Save the exception as we may use it later...156                whyFailed = ice;157            }158 159            if (indexArray != null)160            {161                if (indexArray.Length != array.Rank)162                {163                    // rank failed to match so error...164                    ReportIndexingError(array, indexes, null);165                }166 167                return GetMDArrayValue(array, indexArray, false);168            }169 170            var indexList = new List<int[]>();171 172            var ie = LanguagePrimitives.GetEnumerator(indexes);173            while (EnumerableOps.MoveNext(null, ie))174            {175                var currentIndex = EnumerableOps.Current(ie);176                try177                {178                    indexArray = LanguagePrimitives.ConvertTo<int[]>(currentIndex);179                }180                catch (InvalidCastException)181                {182                    indexArray = null;183                }184 185                if (indexArray == null || indexArray.Length != array.Rank)186                {187                    if (whyFailed != null)188                    {189                        // If the first fails, report the original exception and all indices190                        ReportIndexingError(array, indexes, whyFailed);191                        Diagnostics.Assert(false, "ReportIndexingError must throw");192                    }193                    // If the second or subsequent index fails, report the failure for just that index194                    ReportIndexingError(array, currentIndex, null);195                    Diagnostics.Assert(false, "ReportIndexingError must throw");196                }197 198                // Only use whyFailed the first time through, otherwise199                whyFailed = null;200                indexList.Add(indexArray);201            }202 203            // Optimistically assume all indices are valid so the result array is the same size.204            // If that turns out to be wrong, we'll just copy the elements produced.205            var result = new object[indexList.Count];206            int j = 0;207            foreach (var i in indexList)208            {209                var value = GetMDArrayValue(array, i, true);210                if (value != AutomationNull.Value)211                {212                    result[j++] = value;213                }214            }215 216            if (j != indexList.Count)217            {218                var shortResult = new object[j];219                Array.Copy(result, shortResult, j);220                return shortResult;221            }222 223            return result;224        }225 226        private static void ReportIndexingError(Array array, object index, Exception reason)227        {228            // Convert this index into something printable (we hope)...229            string msgString = IndexStringMessage(index);230 231            if (reason == null)232            {233                throw InterpreterError.NewInterpreterException(index, typeof(RuntimeException), null,234                    "NeedMultidimensionalIndex", ParserStrings.NeedMultidimensionalIndex, array.Rank, msgString);235            }236 237            throw InterpreterError.NewInterpreterExceptionWithInnerException(index, typeof(RuntimeException), null,238                "NeedMultidimensionalIndex", ParserStrings.NeedMultidimensionalIndex, reason, array.Rank, msgString);239        }240 241        internal static string IndexStringMessage(object index)242        {243            // Convert this index into something printable (we hope)...244            string msgString = PSObject.ToString(null, index, ",", null, null, true, true);245            if (msgString.Length > 20)246                msgString = string.Concat(msgString.AsSpan(0, 20), " ...");247            return msgString;248        }249 250        internal static object SetMDArrayValue(Array array, int[] indexes, object value)251        {252            if (array.Rank != indexes.Length)253            {254                ReportIndexingError(array, indexes, null);255            }256 257            for (int i = 0; i < indexes.Length; ++i)258            {259                int ub = array.GetUpperBound(i);260                int lb = array.GetLowerBound(i);261                if (indexes[i] < lb)262                {263                    indexes[i] = indexes[i] + ub + 1;264                }265            }266 267            array.SetValue(value, indexes);268            return value;269        }270 271        internal static object GetNonIndexable(object target, object[] indices)272        {273            // We want to allow:274            //     $x[0]275            // and276            //     $x[-1]277            // to be the same as278            //     $x279            // But disallow anything else:280            //     if in the strict mode, throw exception281            //     otherwise, return AutomationNull.Value to signal no result282 283            if (indices.Length == 1)284            {285                var index = indices[0];286                if (index != null && (LanguagePrimitives.Equals(0, index) || LanguagePrimitives.Equals(-1, index)))287                {288                    return target;289                }290            }291 292            var context = LocalPipeline.GetExecutionContextFromTLS();293            if (context == null || !context.IsStrictVersion(2))294            {295                return AutomationNull.Value;296            }297 298            throw InterpreterError.NewInterpreterException(target, typeof(RuntimeException), null, "CannotIndex",299                                                           ParserStrings.CannotIndex, target.GetType());300        }301    }302}303