Fix bugs in sizing TableLayoutPanel (Xamarin bug 18638)
[mono.git] / mcs / class / System.Web.Mvc2 / System.Web.Mvc / TempDataDictionary.cs
1 /* ****************************************************************************\r
2  *\r
3  * Copyright (c) Microsoft Corporation. All rights reserved.\r
4  *\r
5  * This software is subject to the Microsoft Public License (Ms-PL). \r
6  * A copy of the license can be found in the license.htm file included \r
7  * in this distribution.\r
8  *\r
9  * You must not remove this notice, or any other, from this software.\r
10  *\r
11  * ***************************************************************************/\r
12 \r
13 namespace System.Web.Mvc {\r
14     using System;\r
15     using System.Collections;\r
16     using System.Collections.Generic;\r
17     using System.Diagnostics.CodeAnalysis;\r
18     using System.Linq;\r
19     using System.Runtime.Serialization;\r
20 \r
21     [Serializable]\r
22     public class TempDataDictionary : IDictionary<string, object>, ISerializable {\r
23         internal const string _tempDataSerializationKey = "__tempData";\r
24 \r
25         private Dictionary<string, object> _data;\r
26         private HashSet<string> _initialKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\r
27         private HashSet<string> _retainedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\r
28 \r
29         public TempDataDictionary() {\r
30             _data = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);\r
31         }\r
32 \r
33         protected TempDataDictionary(SerializationInfo info, StreamingContext context) {\r
34             _data = info.GetValue(_tempDataSerializationKey, typeof(Dictionary<string, object>)) as Dictionary<string, object>;\r
35         }\r
36 \r
37         public int Count {\r
38             get {\r
39                 return _data.Count;\r
40             }\r
41         }\r
42 \r
43         public ICollection<string> Keys {\r
44             get {\r
45                 return _data.Keys;\r
46             }\r
47         }\r
48 \r
49         public void Keep() {\r
50             _retainedKeys.Clear();\r
51             _retainedKeys.UnionWith(_data.Keys);\r
52         }\r
53 \r
54         public void Keep(string key) {\r
55             _retainedKeys.Add(key);\r
56         }\r
57 \r
58         public void Load(ControllerContext controllerContext, ITempDataProvider tempDataProvider) {\r
59             IDictionary<string, object> providerDictionary = tempDataProvider.LoadTempData(controllerContext);\r
60             _data = (providerDictionary != null) ? new Dictionary<string, object>(providerDictionary, StringComparer.OrdinalIgnoreCase) :\r
61                 new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);\r
62             _initialKeys = new HashSet<string>(_data.Keys, StringComparer.OrdinalIgnoreCase);\r
63             _retainedKeys.Clear();\r
64         }\r
65 \r
66         public object Peek(string key) {\r
67             object value;\r
68             _data.TryGetValue(key, out value);\r
69             return value;\r
70         }\r
71 \r
72         public void Save(ControllerContext controllerContext, ITempDataProvider tempDataProvider) {\r
73             string[] keysToKeep = _initialKeys.Union(_retainedKeys, StringComparer.OrdinalIgnoreCase).ToArray();\r
74             string[] keysToRemove = _data.Keys.Except(keysToKeep, StringComparer.OrdinalIgnoreCase).ToArray();\r
75             foreach (string key in keysToRemove) {\r
76                 _data.Remove(key);\r
77             }\r
78             tempDataProvider.SaveTempData(controllerContext, _data);\r
79         }\r
80 \r
81         public ICollection<object> Values {\r
82             get {\r
83                 return _data.Values;\r
84             }\r
85         }\r
86 \r
87         public object this[string key] {\r
88             get {\r
89                 object value;\r
90                 if (TryGetValue(key, out value)) {\r
91                     _initialKeys.Remove(key);\r
92                     return value;\r
93                 }\r
94                 return null;\r
95             }\r
96             set {\r
97                 _data[key] = value;\r
98                 _initialKeys.Add(key);\r
99             }\r
100         }\r
101 \r
102         public void Add(string key, object value) {\r
103             _data.Add(key, value);\r
104             _initialKeys.Add(key);\r
105         }\r
106 \r
107         public void Clear() {\r
108             _data.Clear();\r
109             _retainedKeys.Clear();\r
110             _initialKeys.Clear();\r
111         }\r
112 \r
113         public bool ContainsKey(string key) {\r
114             return _data.ContainsKey(key);\r
115         }\r
116 \r
117         public bool ContainsValue(object value) {\r
118             return _data.ContainsValue(value);\r
119         }\r
120 \r
121         public IEnumerator<KeyValuePair<string, object>> GetEnumerator() {\r
122             return new TempDataDictionaryEnumerator(this);\r
123         }\r
124 \r
125         protected virtual void GetObjectData(SerializationInfo info, StreamingContext context) {\r
126             info.AddValue(_tempDataSerializationKey, _data);\r
127         }\r
128 \r
129         public bool Remove(string key) {\r
130             _retainedKeys.Remove(key);\r
131             _initialKeys.Remove(key);\r
132             return _data.Remove(key);\r
133         }\r
134 \r
135         public bool TryGetValue(string key, out object value) {\r
136             _initialKeys.Remove(key);\r
137             return _data.TryGetValue(key, out value);\r
138         }\r
139 \r
140         #region ICollection<KeyValuePair<string, object>> Implementation\r
141         bool ICollection<KeyValuePair<string, object>>.IsReadOnly {\r
142             get {\r
143                 return ((ICollection<KeyValuePair<string, object>>)_data).IsReadOnly;\r
144             }\r
145         }\r
146 \r
147         void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int index) {\r
148             ((ICollection<KeyValuePair<string, object>>)_data).CopyTo(array, index);\r
149         }\r
150 \r
151         void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> keyValuePair) {\r
152             _initialKeys.Add(keyValuePair.Key);\r
153             ((ICollection<KeyValuePair<string, object>>)_data).Add(keyValuePair);\r
154         }\r
155 \r
156         bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> keyValuePair) {\r
157             return ((ICollection<KeyValuePair<string, object>>)_data).Contains(keyValuePair);\r
158         }\r
159 \r
160         bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> keyValuePair) {\r
161             _initialKeys.Remove(keyValuePair.Key);\r
162             return ((ICollection<KeyValuePair<string, object>>)_data).Remove(keyValuePair);\r
163         }\r
164         #endregion\r
165 \r
166         #region IEnumerable Implementation\r
167         IEnumerator IEnumerable.GetEnumerator() {\r
168             return (IEnumerator)(new TempDataDictionaryEnumerator(this));\r
169         }\r
170         #endregion\r
171 \r
172         #region ISerializable Members\r
173         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
174         void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {\r
175             GetObjectData(info, context);\r
176         }\r
177         #endregion\r
178 \r
179         private sealed class TempDataDictionaryEnumerator : IEnumerator<KeyValuePair<string, object>> {\r
180             private IEnumerator<KeyValuePair<string, object>> _enumerator;\r
181             private TempDataDictionary _tempData;\r
182 \r
183             public TempDataDictionaryEnumerator(TempDataDictionary tempData) {\r
184                 _tempData = tempData;\r
185                 _enumerator = _tempData._data.GetEnumerator();\r
186             }\r
187 \r
188             public KeyValuePair<string, object> Current {\r
189                 get {\r
190                     KeyValuePair<string, object> kvp = _enumerator.Current;\r
191                     _tempData._initialKeys.Remove(kvp.Key);\r
192                     return kvp;\r
193                 }\r
194             }\r
195 \r
196             public bool MoveNext() {\r
197                 return _enumerator.MoveNext();\r
198             }\r
199 \r
200             public void Reset() {\r
201                 _enumerator.Reset();\r
202             }\r
203 \r
204             #region IEnumerator Implementation\r
205             object IEnumerator.Current {\r
206                 get {\r
207                     return Current;\r
208                 }\r
209             }\r
210             #endregion\r
211 \r
212             #region IDisposable Implementation\r
213             void IDisposable.Dispose() {\r
214                 _enumerator.Dispose();\r
215             }\r
216             #endregion\r
217         }\r
218     }\r
219 }\r