Json.NET
Code Coverage Statistics for Source File

Newtonsoft.Json\Utilities\CollectionWrapper.cs

Symbol Coverage: 29.52% (31 of 105)

Branch Coverage: 29.51% (18 of 61)

Cyclomatic Complexity Avg: 2.00 Max:5

Code Lines: 103


L V Source
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

  
26
using System;
27
using System.Collections;
28
using System.Collections.Generic;
29
using System.Threading;
30
using Newtonsoft.Json.Utilities;
31
using System.Linq;
32
using System.Globalization;
33

  
34
namespace Newtonsoft.Json.Utilities
35
{
36
  internal interface IWrappedCollection : IList
37
  {
38
    object UnderlyingCollection { get; }
39
  }
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

  
47
 20083
    public CollectionWrapper(IList list)
48
    {
49
 20083
      ValidationUtils.ArgumentNotNull(list, "list");
50

  
51
 20083
      if (list is ICollection<T>)
52
 27
        _genericCollection = (ICollection<T>)list;
53
      else
54
 20056
        _list = list;
55
 20083
    }
56

  
57
 7
    public CollectionWrapper(ICollection<T> list)
58
    {
59
 7
      ValidationUtils.ArgumentNotNull(list, "list");
60

  
61
 7
      _genericCollection = list;
62
 7
    }
63

  
64
    public void Add(T item)
65
    {
66
 50240
      if (_genericCollection != null)
67
 105
        _genericCollection.Add(item);
68
      else
69
 50135
        _list.Add(item);
70
 50239
    }
71

  
72
    public void Clear()
73
    {
74
 0
      if (_genericCollection != null)
75
 0
        _genericCollection.Clear();
76
      else
77
 0
        _list.Clear();
78
 0
    }
79

  
80
    public bool Contains(T item)
81
    {
82
 0
      if (_genericCollection != null)
83
 0
        return _genericCollection.Contains(item);
84
      else
85
 0
        return _list.Contains(item);
86
 0
    }
87

  
88
    public void CopyTo(T[] array, int arrayIndex)
89
    {
90
 0
      if (_genericCollection != null)
91
 0
        _genericCollection.CopyTo(array, arrayIndex);
92
      else
93
 0
        _list.CopyTo(array, arrayIndex);
94
 0
    }
95

  
96
    public int Count
97
    {
98
      get
99
      {
100
 50255
        if (_genericCollection != null)
101
 108
          return _genericCollection.Count;
102
        else
103
 50147
          return _list.Count;
104
 50255
      }
105
    }
106

  
107
    public bool IsReadOnly
108
    {
109
      get
110
      {
111
 0
        if (_genericCollection != null)
112
 0
          return _genericCollection.IsReadOnly;
113
        else
114
 0
          return _list.IsReadOnly;
115
 0
      }
116
    }
117

  
118
    public bool Remove(T item)
119
    {
120
 0
      if (_genericCollection != null)
121
      {
122
 0
        return _genericCollection.Remove(item);
123
      }
124
      else
125
      {
126
 0
        bool contains = _list.Contains(item);
127

  
128
 0
        if (contains)
129
 0
          _list.Remove(item);
130

  
131
 0
        return contains;
132
      }
133
 0
    }
134

  
135
    public IEnumerator<T> GetEnumerator()
136
    {
137
 0
      if (_genericCollection != null)
138
 0
        return _genericCollection.GetEnumerator();
139

  
140
 0
      return _list.Cast<T>().GetEnumerator();
141
 0
    }
142

  
143
    IEnumerator IEnumerable.GetEnumerator()
144
    {
145
 0
      if (_genericCollection != null)
146
 0
        return _genericCollection.GetEnumerator();
147
      else
148
 0
        return _list.GetEnumerator();
149
 0
    }
150

  
151
    int IList.Add(object value)
152
    {
153
 50240
      VerifyValueType(value);
154
 50240
      Add((T)value);
155

  
156
 50239
      return (Count - 1);
157
 50239
    }
158

  
159
    bool IList.Contains(object value)
160
    {
161
 0
      if (IsCompatibleObject(value))
162
 0
        return Contains((T)value);
163

  
164
 0
      return false;
165
 0
    }
166

  
167
    int IList.IndexOf(object value)
168
    {
169
 0
      if (_genericCollection != null)
170
 0
        throw new Exception("Wrapped ICollection<T> does not support IndexOf.");
171

  
172
 0
      if (IsCompatibleObject(value))
173
 0
        return _list.IndexOf((T)value);
174

  
175
 0
      return -1;
176
 0
    }
177

  
178
    void IList.RemoveAt(int index)
179
    {
180
 0
      if (_genericCollection != null)
181
 0
        throw new Exception("Wrapped ICollection<T> does not support RemoveAt.");
182

  
183
 0
      _list.RemoveAt(index);
184
 0
    }
185

  
186
    void IList.Insert(int index, object value)
187
    {
188
 0
      if (_genericCollection != null)
189
 0
        throw new Exception("Wrapped ICollection<T> does not support Insert.");
190

  
191
 0
      VerifyValueType(value);
192
 0
      _list.Insert(index, (T)value);
193
 0
    }
194

  
195
    bool IList.IsFixedSize
196
    {
197
 0
      get { return false; }
198
    }
199

  
200
    void IList.Remove(object value)
201
    {
202
 0
      if (IsCompatibleObject(value))
203
 0
        Remove((T)value);
204
 0
    }
205

  
206
    object IList.this[int index]
207
    {
208
      get
209
      {
210
 0
        if (_genericCollection != null)
211
 0
          throw new Exception("Wrapped ICollection<T> does not support indexer.");
212

  
213
 0
        return _list[index];
214
 0
      }
215
      set
216
      {
217
 0
        if (_genericCollection != null)
218
 0
          throw new Exception("Wrapped ICollection<T> does not support indexer.");
219

  
220
 0
        VerifyValueType(value);
221
 0
        _list[index] = (T)value;
222
 0
      }
223
    }
224

  
225
    void ICollection.CopyTo(Array array, int arrayIndex)
226
    {
227
 0
      CopyTo((T[])array, arrayIndex);
228
 0
    }
229

  
230
    bool ICollection.IsSynchronized
231
    {
232
 0
      get { return false; }
233
    }
234

  
235
    object ICollection.SyncRoot
236
    {
237
      get
238
      {
239
 0
        if (_syncRoot == null)
240
 0
          Interlocked.CompareExchange(ref _syncRoot, new object(), null);
241

  
242
 0
        return _syncRoot;
243
 0
      }
244
    }
245

  
246
    private static void VerifyValueType(object value)
247
    {
248
 50240
      if (!IsCompatibleObject(value))
249
 0
        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");
250
 50240
    }
251

  
252
    private static bool IsCompatibleObject(object value)
253
    {
254
 50240
      if (!(value is T) && (value != null || (typeof(T).IsValueType && !ReflectionUtils.IsNullableType(typeof(T)))))
255
 0
        return false;
256

  
257
 50240
      return true;
258
 50240
    }
259

  
260
    public object UnderlyingCollection
261
    {
262
      get
263
      {
264
 40176
        if (_genericCollection != null)
265
 67
          return _genericCollection;
266
        else
267
 40109
          return _list;
268
 40176
      }
269
    }
270
  }
271
}