PageRenderTime 49ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Json45r7/Source/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs

https://bitbucket.org/wantstudios/bitbucketclient
C# | 281 lines | 215 code | 43 blank | 23 comment | 45 complexity | 7abbfc6b54596e729f2674fbdbbe07c6 MD5 | raw file
  1. #region License
  2. // Copyright (c) 2007 James Newton-King
  3. //
  4. // Permission is hereby granted, free of charge, to any person
  5. // obtaining a copy of this software and associated documentation
  6. // files (the "Software"), to deal in the Software without
  7. // restriction, including without limitation the rights to use,
  8. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following
  11. // conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. // OTHER DEALINGS IN THE SOFTWARE.
  24. #endregion
  25. using System;
  26. using System.Collections;
  27. using System.Collections.Generic;
  28. using System.Threading;
  29. using System.Globalization;
  30. #if NET20
  31. using Newtonsoft.Json.Utilities.LinqBridge;
  32. #else
  33. using System.Linq;
  34. #endif
  35. namespace Newtonsoft.Json.Utilities
  36. {
  37. internal interface IWrappedCollection : IList
  38. {
  39. object UnderlyingCollection { get; }
  40. }
  41. internal class CollectionWrapper<T> : ICollection<T>, IWrappedCollection
  42. {
  43. private readonly IList _list;
  44. private readonly ICollection<T> _genericCollection;
  45. private object _syncRoot;
  46. public CollectionWrapper(IList list)
  47. {
  48. ValidationUtils.ArgumentNotNull(list, "list");
  49. if (list is ICollection<T>)
  50. _genericCollection = (ICollection<T>)list;
  51. else
  52. _list = list;
  53. }
  54. public CollectionWrapper(ICollection<T> list)
  55. {
  56. ValidationUtils.ArgumentNotNull(list, "list");
  57. _genericCollection = list;
  58. }
  59. public virtual void Add(T item)
  60. {
  61. if (_genericCollection != null)
  62. _genericCollection.Add(item);
  63. else
  64. _list.Add(item);
  65. }
  66. public virtual void Clear()
  67. {
  68. if (_genericCollection != null)
  69. _genericCollection.Clear();
  70. else
  71. _list.Clear();
  72. }
  73. public virtual bool Contains(T item)
  74. {
  75. if (_genericCollection != null)
  76. return _genericCollection.Contains(item);
  77. else
  78. return _list.Contains(item);
  79. }
  80. public virtual void CopyTo(T[] array, int arrayIndex)
  81. {
  82. if (_genericCollection != null)
  83. _genericCollection.CopyTo(array, arrayIndex);
  84. else
  85. _list.CopyTo(array, arrayIndex);
  86. }
  87. public virtual int Count
  88. {
  89. get
  90. {
  91. if (_genericCollection != null)
  92. return _genericCollection.Count;
  93. else
  94. return _list.Count;
  95. }
  96. }
  97. public virtual bool IsReadOnly
  98. {
  99. get
  100. {
  101. if (_genericCollection != null)
  102. return _genericCollection.IsReadOnly;
  103. else
  104. return _list.IsReadOnly;
  105. }
  106. }
  107. public virtual bool Remove(T item)
  108. {
  109. if (_genericCollection != null)
  110. {
  111. return _genericCollection.Remove(item);
  112. }
  113. else
  114. {
  115. bool contains = _list.Contains(item);
  116. if (contains)
  117. _list.Remove(item);
  118. return contains;
  119. }
  120. }
  121. public virtual IEnumerator<T> GetEnumerator()
  122. {
  123. if (_genericCollection != null)
  124. return _genericCollection.GetEnumerator();
  125. return _list.Cast<T>().GetEnumerator();
  126. }
  127. IEnumerator IEnumerable.GetEnumerator()
  128. {
  129. if (_genericCollection != null)
  130. return _genericCollection.GetEnumerator();
  131. else
  132. return _list.GetEnumerator();
  133. }
  134. int IList.Add(object value)
  135. {
  136. VerifyValueType(value);
  137. Add((T)value);
  138. return (Count - 1);
  139. }
  140. bool IList.Contains(object value)
  141. {
  142. if (IsCompatibleObject(value))
  143. return Contains((T)value);
  144. return false;
  145. }
  146. int IList.IndexOf(object value)
  147. {
  148. if (_genericCollection != null)
  149. throw new InvalidOperationException("Wrapped ICollection<T> does not support IndexOf.");
  150. if (IsCompatibleObject(value))
  151. return _list.IndexOf((T)value);
  152. return -1;
  153. }
  154. void IList.RemoveAt(int index)
  155. {
  156. if (_genericCollection != null)
  157. throw new InvalidOperationException("Wrapped ICollection<T> does not support RemoveAt.");
  158. _list.RemoveAt(index);
  159. }
  160. void IList.Insert(int index, object value)
  161. {
  162. if (_genericCollection != null)
  163. throw new InvalidOperationException("Wrapped ICollection<T> does not support Insert.");
  164. VerifyValueType(value);
  165. _list.Insert(index, (T)value);
  166. }
  167. bool IList.IsFixedSize
  168. {
  169. get
  170. {
  171. if (_genericCollection != null)
  172. // ICollection<T> only has IsReadOnly
  173. return _genericCollection.IsReadOnly;
  174. else
  175. return _list.IsFixedSize;
  176. }
  177. }
  178. void IList.Remove(object value)
  179. {
  180. if (IsCompatibleObject(value))
  181. Remove((T)value);
  182. }
  183. object IList.this[int index]
  184. {
  185. get
  186. {
  187. if (_genericCollection != null)
  188. throw new InvalidOperationException("Wrapped ICollection<T> does not support indexer.");
  189. return _list[index];
  190. }
  191. set
  192. {
  193. if (_genericCollection != null)
  194. throw new InvalidOperationException("Wrapped ICollection<T> does not support indexer.");
  195. VerifyValueType(value);
  196. _list[index] = (T)value;
  197. }
  198. }
  199. void ICollection.CopyTo(Array array, int arrayIndex)
  200. {
  201. CopyTo((T[])array, arrayIndex);
  202. }
  203. bool ICollection.IsSynchronized
  204. {
  205. get { return false; }
  206. }
  207. object ICollection.SyncRoot
  208. {
  209. get
  210. {
  211. if (_syncRoot == null)
  212. Interlocked.CompareExchange(ref _syncRoot, new object(), null);
  213. return _syncRoot;
  214. }
  215. }
  216. private static void VerifyValueType(object value)
  217. {
  218. if (!IsCompatibleObject(value))
  219. throw new ArgumentException("The value '{0}' is not of type '{1}' and cannot be used in this generic collection.".FormatWith(CultureInfo.InvariantCulture, value, typeof(T)), "value");
  220. }
  221. private static bool IsCompatibleObject(object value)
  222. {
  223. if (!(value is T) && (value != null || (typeof(T).IsValueType() && !ReflectionUtils.IsNullableType(typeof(T)))))
  224. return false;
  225. return true;
  226. }
  227. public object UnderlyingCollection
  228. {
  229. get
  230. {
  231. if (_genericCollection != null)
  232. return _genericCollection;
  233. else
  234. return _list;
  235. }
  236. }
  237. }
  238. }