ValueSetExtensions.cs (6199B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="ValueSetExtensions.cs" company="Microsoft Corporation"> 3 // Copyright (c) Microsoft Corporation. Licensed under the MIT License. 4 // </copyright> 5 // ----------------------------------------------------------------------------- 6 7 namespace Microsoft.Management.Configuration.Processor.Extensions 8 { 9 using System; 10 using System.Collections; 11 using System.Collections.Generic; 12 using Windows.Foundation.Collections; 13 14 /// <summary> 15 /// Extensions for ValueSet. 16 /// </summary> 17 internal static class ValueSetExtensions 18 { 19 /// <summary> 20 /// The value in a ValueSet that indicates that it is an array of items. 21 /// </summary> 22 internal const string TreatAsArray = "treatAsArray"; 23 24 /// <summary> 25 /// Extension method to transform a ValueSet to a Hashtable. 26 /// </summary> 27 /// <param name="valueSet">Value set.</param> 28 /// <returns>A hashtable.</returns> 29 public static Hashtable ToHashtable(this ValueSet valueSet) 30 { 31 var hashtable = new Hashtable(); 32 33 foreach (var keyValuePair in valueSet) 34 { 35 if (keyValuePair.Value is ValueSet innerValueSet) 36 { 37 if (innerValueSet.ContainsKey(TreatAsArray)) 38 { 39 hashtable.Add(keyValuePair.Key, innerValueSet.ToArray()); 40 } 41 else 42 { 43 hashtable.Add(keyValuePair.Key, innerValueSet.ToHashtable()); 44 } 45 } 46 else 47 { 48 hashtable.Add(keyValuePair.Key, keyValuePair.Value); 49 } 50 } 51 52 return hashtable; 53 } 54 55 /// <summary> 56 /// Gets ordered list from a ValueSet that is threated as an array. 57 /// </summary> 58 /// <param name="valueSet">ValueSet.</param> 59 /// <returns>Ordered list.</returns> 60 public static IList<object> ToArray(this ValueSet valueSet) 61 { 62 if (!valueSet.ContainsKey(TreatAsArray)) 63 { 64 throw new InvalidOperationException(); 65 } 66 67 var sortedList = new SortedList<int, object>(); 68 69 foreach (var keyValuePair in valueSet) 70 { 71 if (keyValuePair.Key == TreatAsArray) 72 { 73 continue; 74 } 75 76 if (int.TryParse(keyValuePair.Key, out int key)) 77 { 78 if (keyValuePair.Value is ValueSet innerValueSet) 79 { 80 sortedList.Add(key, innerValueSet.ToHashtable()); 81 } 82 else 83 { 84 sortedList.Add(key, keyValuePair.Value); 85 } 86 } 87 else 88 { 89 throw new InvalidOperationException($"Invalid key for ValueSet to array {keyValuePair.Key}"); 90 } 91 } 92 93 return sortedList.Values; 94 } 95 96 /// <summary> 97 /// Performs a deep compare of the ValueSets. 98 /// </summary> 99 /// <param name="first">First ValueSet.</param> 100 /// <param name="second">Second ValueSet.</param> 101 /// <returns>Whether the two ValueSets equal.</returns> 102 public static bool ContentEquals(this ValueSet first, ValueSet second) 103 { 104 if (first.Count != second.Count) 105 { 106 return false; 107 } 108 109 foreach (var keyValuePair in first) 110 { 111 string key = keyValuePair.Key; 112 if (!second.ContainsKey(key)) 113 { 114 return false; 115 } 116 117 var firstValue = keyValuePair.Value; 118 var secondValue = second[key]; 119 120 // Empty value check. 121 if (firstValue == null && secondValue == null) 122 { 123 continue; 124 } 125 else if (firstValue == null || secondValue == null) 126 { 127 return false; 128 } 129 130 // Try as ValueSet. 131 var firstValueSet = firstValue as ValueSet; 132 var secondValueSet = secondValue as ValueSet; 133 134 if (firstValueSet != null && secondValueSet != null) 135 { 136 if (!firstValueSet.ContentEquals(secondValueSet)) 137 { 138 return false; 139 } 140 else 141 { 142 continue; 143 } 144 } 145 else if (firstValueSet != null || secondValueSet != null) 146 { 147 return false; 148 } 149 150 // Try as scalar. 151 if (firstValue is string firstString && secondValue is string secondString) 152 { 153 if (firstString != secondString) 154 { 155 return false; 156 } 157 } 158 else if (firstValue is long firstLong && secondValue is long secondLong) 159 { 160 if (firstLong != secondLong) 161 { 162 return false; 163 } 164 } 165 else if (firstValue is bool firstBool && secondValue is bool secondBool) 166 { 167 if (firstBool != secondBool) 168 { 169 return false; 170 } 171 } 172 else 173 { 174 // Note: DateTime and float are not supported in parser yet. 175 return false; 176 } 177 } 178 179 return true; 180 } 181 } 182 }