| File: FrameworkFork\System.Runtime.Serialization\System\Runtime\Serialization\ObjectReferenceStack.cs | Web Access |
| Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using Microsoft.Xml; using System.Collections.Generic; namespace System.Runtime.Serialization { internal struct ObjectReferenceStack { private const int MaximumArraySize = 16; private const int InitialArraySize = 4; private int _count; private object[] _objectArray; private bool[] _isReferenceArray; private Dictionary<object, object> _objectDictionary; internal void Push(object obj) { if (_objectArray == null) { _objectArray = new object[InitialArraySize]; _objectArray[_count++] = obj; } else if (_count < MaximumArraySize) { if (_count == _objectArray.Length) Array.Resize<object>(ref _objectArray, _objectArray.Length * 2); _objectArray[_count++] = obj; } else { if (_objectDictionary == null) _objectDictionary = new Dictionary<object, object>(); _objectDictionary.Add(obj, null); _count++; } } internal void EnsureSetAsIsReference(object obj) { if (_count == 0) return; if (_count > MaximumArraySize) { if (_objectDictionary == null) { DiagnosticUtility.DebugAssert("Object reference stack in invalid state"); } _objectDictionary.Remove(obj); } else { if ((_objectArray != null) && _objectArray[_count - 1] == obj) { if (_isReferenceArray == null) { _isReferenceArray = new bool[InitialArraySize]; } else if (_count == _isReferenceArray.Length) { Array.Resize<bool>(ref _isReferenceArray, _isReferenceArray.Length * 2); } _isReferenceArray[_count - 1] = true; } } } internal void Pop(object obj) { if (_count > MaximumArraySize) { if (_objectDictionary == null) { DiagnosticUtility.DebugAssert("Object reference stack in invalid state"); } _objectDictionary.Remove(obj); } _count--; } internal bool Contains(object obj) { int currentCount = _count; if (currentCount > MaximumArraySize) { if (_objectDictionary != null && _objectDictionary.ContainsKey(obj)) return true; currentCount = MaximumArraySize; } for (int i = (currentCount - 1); i >= 0; i--) { if (Object.ReferenceEquals(obj, _objectArray[i]) && _isReferenceArray != null && !_isReferenceArray[i]) return true; } return false; } } }