2021-03-29 14:54:12 +08:00
#region License
// Copyright (c) 2007 James Newton-King
/ /
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
/ /
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
/ /
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
# endregion
using System ;
using System.Collections ;
using System.Collections.Generic ;
using System.Threading ;
using System.Globalization ;
#if !HAVE_LINQ
using LC.Newtonsoft.Json.Utilities.LinqBridge ;
# else
using System.Linq ;
# endif
namespace LC.Newtonsoft.Json.Utilities
{
internal interface IWrappedCollection : IList
{
object UnderlyingCollection { get ; }
}
internal class CollectionWrapper < T > : ICollection < T > , IWrappedCollection
{
2021-03-30 10:54:25 +08:00
private readonly IList _list ;
private readonly ICollection < T > _genericCollection ;
private object _syncRoot ;
2021-03-29 14:54:12 +08:00
public CollectionWrapper ( IList list )
{
ValidationUtils . ArgumentNotNull ( list , nameof ( list ) ) ;
if ( list is ICollection < T > collection )
{
_genericCollection = collection ;
}
else
{
_list = list ;
}
}
public CollectionWrapper ( ICollection < T > list )
{
ValidationUtils . ArgumentNotNull ( list , nameof ( list ) ) ;
_genericCollection = list ;
}
public virtual void Add ( T item )
{
if ( _genericCollection ! = null )
{
_genericCollection . Add ( item ) ;
}
else
{
2021-03-30 10:54:25 +08:00
_list . Add ( item ) ;
2021-03-29 14:54:12 +08:00
}
}
public virtual void Clear ( )
{
if ( _genericCollection ! = null )
{
_genericCollection . Clear ( ) ;
}
else
{
2021-03-30 10:54:25 +08:00
_list . Clear ( ) ;
2021-03-29 14:54:12 +08:00
}
}
public virtual bool Contains ( T item )
{
if ( _genericCollection ! = null )
{
return _genericCollection . Contains ( item ) ;
}
else
{
2021-03-30 10:54:25 +08:00
return _list . Contains ( item ) ;
2021-03-29 14:54:12 +08:00
}
}
public virtual void CopyTo ( T [ ] array , int arrayIndex )
{
if ( _genericCollection ! = null )
{
_genericCollection . CopyTo ( array , arrayIndex ) ;
}
else
{
2021-03-30 10:54:25 +08:00
_list . CopyTo ( array , arrayIndex ) ;
2021-03-29 14:54:12 +08:00
}
}
public virtual int Count
{
get
{
if ( _genericCollection ! = null )
{
return _genericCollection . Count ;
}
else
{
2021-03-30 10:54:25 +08:00
return _list . Count ;
2021-03-29 14:54:12 +08:00
}
}
}
public virtual bool IsReadOnly
{
get
{
if ( _genericCollection ! = null )
{
return _genericCollection . IsReadOnly ;
}
else
{
2021-03-30 10:54:25 +08:00
return _list . IsReadOnly ;
2021-03-29 14:54:12 +08:00
}
}
}
public virtual bool Remove ( T item )
{
if ( _genericCollection ! = null )
{
return _genericCollection . Remove ( item ) ;
}
else
{
2021-03-30 10:54:25 +08:00
bool contains = _list . Contains ( item ) ;
2021-03-29 14:54:12 +08:00
if ( contains )
{
2021-03-30 10:54:25 +08:00
_list . Remove ( item ) ;
2021-03-29 14:54:12 +08:00
}
return contains ;
}
}
public virtual IEnumerator < T > GetEnumerator ( )
{
return ( _genericCollection ? ? _list . Cast < T > ( ) ) . GetEnumerator ( ) ;
}
IEnumerator IEnumerable . GetEnumerator ( )
{
2021-03-30 10:54:25 +08:00
return ( ( IEnumerable ) _genericCollection ? ? _list ) . GetEnumerator ( ) ;
2021-03-29 14:54:12 +08:00
}
int IList . Add ( object value )
{
VerifyValueType ( value ) ;
Add ( ( T ) value ) ;
return ( Count - 1 ) ;
}
bool IList . Contains ( object value )
{
if ( IsCompatibleObject ( value ) )
{
return Contains ( ( T ) value ) ;
}
return false ;
}
int IList . IndexOf ( object value )
{
if ( _genericCollection ! = null )
{
throw new InvalidOperationException ( "Wrapped ICollection<T> does not support IndexOf." ) ;
}
if ( IsCompatibleObject ( value ) )
{
2021-03-30 10:54:25 +08:00
return _list . IndexOf ( ( T ) value ) ;
2021-03-29 14:54:12 +08:00
}
return - 1 ;
}
void IList . RemoveAt ( int index )
{
if ( _genericCollection ! = null )
{
throw new InvalidOperationException ( "Wrapped ICollection<T> does not support RemoveAt." ) ;
}
2021-03-30 10:54:25 +08:00
_list . RemoveAt ( index ) ;
2021-03-29 14:54:12 +08:00
}
void IList . Insert ( int index , object value )
{
if ( _genericCollection ! = null )
{
throw new InvalidOperationException ( "Wrapped ICollection<T> does not support Insert." ) ;
}
VerifyValueType ( value ) ;
2021-03-30 10:54:25 +08:00
_list . Insert ( index , ( T ) value ) ;
2021-03-29 14:54:12 +08:00
}
bool IList . IsFixedSize
{
get
{
if ( _genericCollection ! = null )
{
// ICollection<T> only has IsReadOnly
return _genericCollection . IsReadOnly ;
}
else
{
2021-03-30 10:54:25 +08:00
return _list . IsFixedSize ;
2021-03-29 14:54:12 +08:00
}
}
}
void IList . Remove ( object value )
{
if ( IsCompatibleObject ( value ) )
{
Remove ( ( T ) value ) ;
}
}
object IList . this [ int index ]
{
get
{
if ( _genericCollection ! = null )
{
throw new InvalidOperationException ( "Wrapped ICollection<T> does not support indexer." ) ;
}
2021-03-30 10:54:25 +08:00
return _list [ index ] ;
2021-03-29 14:54:12 +08:00
}
set
{
if ( _genericCollection ! = null )
{
throw new InvalidOperationException ( "Wrapped ICollection<T> does not support indexer." ) ;
}
VerifyValueType ( value ) ;
2021-03-30 10:54:25 +08:00
_list [ index ] = ( T ) value ;
2021-03-29 14:54:12 +08:00
}
}
void ICollection . CopyTo ( Array array , int arrayIndex )
{
CopyTo ( ( T [ ] ) array , arrayIndex ) ;
}
bool ICollection . IsSynchronized = > false ;
object ICollection . SyncRoot
{
get
{
if ( _syncRoot = = null )
{
Interlocked . CompareExchange ( ref _syncRoot , new object ( ) , null ) ;
}
return _syncRoot ;
}
}
private static void VerifyValueType ( object value )
{
if ( ! IsCompatibleObject ( value ) )
{
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 ) ) , nameof ( value ) ) ;
}
}
private static bool IsCompatibleObject ( object value )
{
if ( ! ( value is T ) & & ( value ! = null | | ( typeof ( T ) . IsValueType ( ) & & ! ReflectionUtils . IsNullableType ( typeof ( T ) ) ) ) )
{
return false ;
}
return true ;
}
2021-03-30 10:54:25 +08:00
public object UnderlyingCollection = > ( object ) _genericCollection ? ? _list ;
2021-03-29 14:54:12 +08:00
}
}