Beispiel #1
0
 internal ValueCollection(ExpandoObject expando)
 {
     lock (expando.LockObject)
     {
         _expando        = expando;
         _expandoVersion = expando._data.Version;
         _expandoCount   = expando._count;
         _expandoData    = expando._data;
     }
 }
Beispiel #2
0
        /// <summary>
        /// Promotes the class from the old type to the new type and returns the new
        /// ExpandoData object.
        /// </summary>
        private ExpandoData PromoteClassCore(ExpandoClass oldClass, ExpandoClass newClass)
        {
            Debug.Assert(oldClass != newClass);
            ContractUtils.AssertLockHeld(LockObject);

            if (_data.Class == oldClass)
            {
                _data = _data.UpdateClass(newClass);
            }

            return(_data);
        }
        /// <summary>
        /// Promotes the class from the old type to the new type and returns the new
        /// ExpandoData object.
        /// </summary>
        private ExpandoData PromoteClassCore(ExpandoClass oldClass, ExpandoClass newClass)
        {
            Debug.Assert(oldClass != newClass);

            lock (LockObject) {
                if (_data.Class == oldClass)
                {
                    _data = _data.UpdateClass(newClass);
                }
                return(_data);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Promotes the class from the old type to the new type and returns the new
        /// ExpandoData object.
        /// </summary>
        private ExpandoData PromoteClassWorker(ExpandoClass oldClass, ExpandoClass newClass)
        {
            Debug.Assert(oldClass != newClass);

            lock (this) {
                if (_data.Class == oldClass)
                {
                    _data = new ExpandoData(newClass, newClass.GetNewKeys(_data.Data));
                }
                return(_data);
            }
        }
 public void CopyTo(object[] array, int arrayIndex)
 {
     ContractUtils.RequiresNotNull(array, "array");
     ContractUtils.RequiresArrayRange(array, arrayIndex, _expandoCount, "arrayIndex", "Count");
     lock (_expando.LockObject) {
         CheckVersion();
         ExpandoData data = _expando._data;
         for (int i = 0; i < data.Class.Keys.Length; i++)
         {
             if (data[i] != Uninitialized)
             {
                 array[arrayIndex++] = data[i];
             }
         }
     }
 }
Beispiel #6
0
            public IEnumerator <object> GetEnumerator()
            {
                ExpandoData data = _expando._data;

                for (int i = 0; i < data.Class.Keys.Length; i++)
                {
                    CheckVersion();
                    // Capture the value into a temp so we don't inadvertently
                    // return Uninitialized.
                    object temp = data[i];
                    if (temp != Uninitialized)
                    {
                        yield return(temp);
                    }
                }
            }
Beispiel #7
0
 public void CopyTo(object?[] array, int arrayIndex)
 {
     ArgumentNullException.ThrowIfNull(array);
     ContractUtils.RequiresArrayRange(array, arrayIndex, _expandoCount, nameof(arrayIndex), nameof(Count));
     lock (_expando.LockObject)
     {
         CheckVersion();
         ExpandoData data = _expando._data;
         for (int i = 0; i < data.Class.Keys.Length; i++)
         {
             if (data[i] != Uninitialized)
             {
                 array[arrayIndex++] = data[i];
             }
         }
     }
 }
Beispiel #8
0
        /// <summary>
        /// Try to get the data stored for the specified class at the specified index.  If the
        /// class has changed a full lookup for the slot will be performed and the correct
        /// value will be retrieved.
        /// </summary>
        internal bool TryGetValue(object indexClass, int index, string name, bool ignoreCase, out object value)
        {
            // read the data now.  The data is immutable so we get a consistent view.
            // If there's a concurrent writer they will replace data and it just appears
            // that we won the race
            ExpandoData data = _data;

            if (data.Class != indexClass || ignoreCase)
            {
                /* Re-search for the index matching the name here if
                 *  1) the class has changed, we need to get the correct index and return
                 *  the value there.
                 *  2) the search is case insensitive:
                 *      a. the member specified by index may be deleted, but there might be other
                 *      members matching the name if the binder is case insensitive.
                 *      b. the member that exactly matches the name didn't exist before and exists now,
                 *      need to find the exact match.
                 */
                index = data.Class.GetValueIndex(name, ignoreCase, this);
                if (index == ExpandoObject.AmbiguousMatchFound)
                {
                    throw System.Linq.Expressions.Error.AmbiguousMatchInExpandoObject(name);
                }
            }

            if (index == ExpandoObject.NoMatch)
            {
                value = null;
                return(false);
            }

            // Capture the value into a temp, so it doesn't get mutated after we check
            // for Uninitialized.
            object temp = data[index];

            if (temp == Uninitialized)
            {
                value = null;
                return(false);
            }

            // index is now known to be correct
            value = temp;
            return(true);
        }
            public bool Contains(object item)
            {
                lock (_expando.LockObject) {
                    CheckVersion();

                    ExpandoData data = _expando._data;
                    for (int i = 0; i < data.Class.Keys.Length; i++)
                    {
                        // See comment in TryDeleteValue; it's okay to call
                        // object.Equals with the lock held.
                        if (object.Equals(data[i], item))
                        {
                            return(true);
                        }
                    }
                    return(false);
                }
            }
Beispiel #10
0
 /// <summary>
 /// Update the associated class and increases the storage for the data array if needed.
 /// </summary>
 internal ExpandoData UpdateClass(ExpandoClass newClass)
 {
     if (_dataArray.Length >= newClass.Keys.Length)
     {
         // we have extra space in our buffer, just initialize it to Uninitialized.
         this[newClass.Keys.Length - 1] = ExpandoObject.Uninitialized;
         return(new ExpandoData(newClass, _dataArray, _version));
     }
     else
     {
         // we've grown too much - we need a new object array
         int      oldLength = _dataArray.Length;
         object[] arr       = new object[GetAlignedSize(newClass.Keys.Length)];
         Array.Copy(_dataArray, 0, arr, 0, _dataArray.Length);
         ExpandoData newData = new ExpandoData(newClass, arr, _version);
         newData[oldLength] = ExpandoObject.Uninitialized;
         return(newData);
     }
 }
Beispiel #11
0
 // Note: takes the data and version as parameters so they will be
 // captured before the first call to MoveNext().
 private IEnumerator <KeyValuePair <string, object> > GetExpandoEnumerator(ExpandoData data, int version)
 {
     for (int i = 0; i < data.Class.Keys.Length; i++)
     {
         if (_data.Version != version || data != _data)
         {
             // The underlying expando object has changed:
             // 1) the version of the expando data changed
             // 2) the data object is changed
             throw System.Linq.Expressions.Error.CollectionModifiedWhileEnumerating();
         }
         // Capture the value into a temp so we don't inadvertently
         // return Uninitialized.
         object temp = data[i];
         if (temp != Uninitialized)
         {
             yield return(new KeyValuePair <string, object>(data.Class.Keys[i], temp));
         }
     }
 }
Beispiel #12
0
        void ICollection <KeyValuePair <string, object> > .Clear()
        {
            // We remove both class and data!
            ExpandoData data;

            lock (LockObject)
            {
                data   = _data;
                _data  = ExpandoData.Empty;
                _count = 0;
            }

            // Notify property changed for all properties.
            for (int i = 0, n = data.Class.Keys.Length; i < n; i++)
            {
                if (data[i] != Uninitialized)
                {
                    _propertyChanged.Invoke(this, new PropertyChangedEventArgs(data.Class.Keys[i]));
                }
            }
        }
Beispiel #13
0
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            ExpandoData data = _data;

            return(GetExpandoEnumerator(data, data.Version));
        }
Beispiel #14
0
        IEnumerator <KeyValuePair <string, object> > IEnumerable <KeyValuePair <string, object> > .GetEnumerator()
        {
            ExpandoData data = _data;

            return(GetExpandoEnumerator(data, data.Version));
        }
Beispiel #15
0
 /// <summary>
 /// Creates a new ExpandoObject with no members.
 /// </summary>
 public ExpandoObject()
 {
     _data      = ExpandoData.Empty;
     LockObject = new object();
 }
Beispiel #16
0
        // the count of available members

        // A marker object used to identify that a value is uninitialized.

        // The value is used to indicate there is no matching member
        /// <summary>
        ///     Creates a new ExpandoObject with no members.
        /// </summary>
        public ExpandoObject()
        {
            _data            = ExpandoData.Empty;
            _propertyChanged = new StrongEvent <PropertyChangedEventArgs>(true);
            LockObject       = new object();
        }
Beispiel #17
0
        internal static object Uninitialized = new object();        // A marker object used to identify that a value is uninitialized.

        /// <summary>
        /// Creates a new Expando object with no members.
        /// </summary>
        public ExpandoObject() {
            _data = ExpandoData.Empty;
        }
Beispiel #18
0
        /// <summary>
        /// Promotes the class from the old type to the new type and returns the new
        /// ExpandoData object.
        /// </summary>
        private ExpandoData PromoteClassWorker(ExpandoClass oldClass, ExpandoClass newClass) {
            Debug.Assert(oldClass != newClass);

            lock (this) {
                if (_data.Class == oldClass) {
                    _data = new ExpandoData(newClass, newClass.GetNewKeys(_data.Data));
                }
                return _data;
            }
        }
Beispiel #19
0
        internal static object Uninitialized = new object();        // A marker object used to identify that a value is uninitialized.

        /// <summary>
        /// Creates a new Expando object with no members.
        /// </summary>
        public ExpandoObject()
        {
            _data = ExpandoData.Empty;
        }
Beispiel #20
0
        IEnumerator IEnumerable.GetEnumerator()
        {
            ExpandoData data = _data;

            return(GetExpandoEnumerator(data, data.Version));
        }
Beispiel #21
0
        internal const int NoMatch = -1;                    // The value is used to indicate there is no matching member

        /// <summary>
        /// Creates a new ExpandoObject with no members.
        /// </summary>
        public ExpandoObject() {
            _data = ExpandoData.Empty;
            LockObject = new object();
        }