1 // Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. 2 3 using System.Collections; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Text; 7 8 namespace System.Json 9 { 10 internal static class Util 11 { 12 public static bool CompareObjects<T>(T o1, T o2) where T : class 13 { 14 if ((o1 == null) != (o2 == null)) 15 { 16 return false; 17 } 18 19 return (o1 == null) || o1.Equals(o2); 20 } 21 22 public static bool CompareNullable<T>(Nullable<T> n1, Nullable<T> n2) where T : struct 23 { 24 if (n1.HasValue != n2.HasValue) 25 { 26 return false; 27 } 28 29 return (!n1.HasValue) || n1.Value.Equals(n2.Value); 30 } 31 CompareLists(List<T> list1, List<T> list2)32 public static bool CompareLists<T>(List<T> list1, List<T> list2) 33 { 34 if (list1 == null) 35 { 36 return list2 == null; 37 } 38 39 if (list2 == null) 40 { 41 return false; 42 } 43 44 return CompareArrays(list1.ToArray(), list2.ToArray()); 45 } 46 47 public static bool CompareDictionaries<K, V>(Dictionary<K, V> dict1, Dictionary<K, V> dict2) 48 where K : IComparable 49 where V : class 50 { 51 if (dict1 == null) 52 { 53 return dict2 == null; 54 } 55 56 if (dict2 == null) 57 { 58 return false; 59 } 60 61 List<K> keys1 = new List<K>(dict1.Keys); 62 List<K> keys2 = new List<K>(dict2.Keys); keys1.Sort()63 keys1.Sort(); keys2.Sort()64 keys2.Sort(); 65 if (!CompareLists<K>(keys1, keys2)) 66 { 67 return false; 68 } 69 70 foreach (K key in keys1) 71 { 72 V value1 = dict1[key]; 73 V value2 = dict2[key]; 74 if (!CompareObjects<V>(value1, value2)) 75 { 76 return false; 77 } 78 } 79 80 return true; 81 } 82 CompareArrays(Array array1, Array array2)83 public static bool CompareArrays(Array array1, Array array2) 84 { 85 if (array1 == null) 86 { 87 return array2 == null; 88 } 89 90 if (array2 == null || array1.Length != array2.Length) 91 { 92 return false; 93 } 94 95 for (int i = 0; i < array1.Length; i++) 96 { 97 object o1 = array1.GetValue(i); 98 object o2 = array2.GetValue(i); 99 if ((o1 == null) != (o2 == null)) 100 { 101 return false; 102 } 103 104 if (o1 != null) 105 { 106 if ((o1 is Array) && (o2 is Array)) 107 { 108 if (!CompareArrays((Array)o1, (Array)o2)) 109 { 110 return false; 111 } 112 } 113 else if (o1 is IEnumerable && o2 is IEnumerable) 114 { 115 if (!CompareArrays(ToObjectArray((IEnumerable)o1), ToObjectArray((IEnumerable)o2))) 116 { 117 return false; 118 } 119 } 120 else 121 { 122 if (!o1.Equals(o2)) 123 { 124 return false; 125 } 126 } 127 } 128 } 129 130 return true; 131 } 132 ComputeArrayHashCode(Array array)133 public static int ComputeArrayHashCode(Array array) 134 { 135 if (array == null) 136 { 137 return 0; 138 } 139 140 int result = 0; 141 result += array.Length; 142 for (int i = 0; i < array.Length; i++) 143 { 144 object o = array.GetValue(i); 145 if (o != null) 146 { 147 if (o is Array) 148 { 149 result ^= ComputeArrayHashCode((Array)o); 150 } 151 else if (o is Enumerable) 152 { 153 result ^= ComputeArrayHashCode(ToObjectArray((IEnumerable)o)); 154 } 155 else 156 { 157 result ^= o.GetHashCode(); 158 } 159 } 160 } 161 162 return result; 163 } 164 EscapeString(object obj)165 public static string EscapeString(object obj) 166 { 167 StringBuilder sb = new StringBuilder(); 168 if (obj == null) 169 { 170 return "<<null>>"; 171 } 172 else 173 { 174 string str = obj.ToString(); 175 for (int i = 0; i < str.Length; i++) 176 { 177 char c = str[i]; 178 if (c < ' ' || c > '~') 179 { 180 sb.AppendFormat("\\u{0:X4}", (int)c); 181 } 182 else 183 { 184 sb.Append(c); 185 } 186 } 187 } 188 189 return sb.ToString(); 190 } 191 ToObjectArray(IEnumerable enumerable)192 static object[] ToObjectArray(IEnumerable enumerable) 193 { 194 List<object> result = new List<object>(); 195 foreach (var item in enumerable) 196 { 197 result.Add(item); 198 } 199 200 return result.ToArray(); 201 } 202 } 203 }