Implement MachineKey.Protect and MachineKey.Unprotect
[mono.git] / mcs / class / System.Web.Mvc / 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.Runtime.Serialization;\r
19 \r
20     [Serializable]\r
21     public class TempDataDictionary : IDictionary<string, object>, ISerializable {\r
22         internal const string _tempDataSerializationKey = "__tempData";\r
23 \r
24         internal Dictionary<string, object> _data;\r
25         private HashSet<string> _initialKeys;\r
26         private HashSet<string> _modifiedKeys;        \r
27 \r
28         public TempDataDictionary() {\r
29             _initialKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\r
30             _modifiedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\r
31             _data = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);\r
32         }\r
33 \r
34         protected TempDataDictionary(SerializationInfo info, StreamingContext context) {\r
35             _initialKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\r
36             _modifiedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\r
37             _data = info.GetValue(_tempDataSerializationKey, typeof(Dictionary<string, object>)) as Dictionary<string, object>;\r
38         }\r
39 \r
40         public int Count {\r
41             [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
42             get {\r
43                 return _data.Count;\r
44             }\r
45         }\r
46 \r
47         public Dictionary<string, object>.KeyCollection Keys {\r
48             get {\r
49                 return _data.Keys;\r
50             }\r
51         }\r
52 \r
53         public void Load(ControllerContext controllerContext, ITempDataProvider tempDataProvider) {\r
54             IDictionary<string, object> providerDictionary = tempDataProvider.LoadTempData(controllerContext);\r
55             _data = (providerDictionary != null) ? new Dictionary<string, object>(providerDictionary, StringComparer.OrdinalIgnoreCase) : \r
56                 new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);\r
57             _initialKeys = new HashSet<string>(_data.Keys);\r
58             _modifiedKeys.Clear();\r
59         }\r
60 \r
61         public void Save(ControllerContext controllerContext, ITempDataProvider tempDataProvider) {\r
62             if (_modifiedKeys.Count > 0) {\r
63 \r
64                 // Apply change tracking.\r
65                 foreach (string x in _initialKeys) {\r
66                     if (!_modifiedKeys.Contains(x)) {\r
67                         _data.Remove(x);\r
68                     }\r
69                 }\r
70 \r
71                 // Store the dictionary\r
72                 tempDataProvider.SaveTempData(controllerContext, _data);\r
73             }\r
74         }\r
75 \r
76         public Dictionary<string, object>.ValueCollection Values {\r
77             get {\r
78                 return _data.Values;\r
79             }\r
80         }\r
81 \r
82         public object this[string key] {\r
83             [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
84             get {\r
85                 object value;\r
86                 if (TryGetValue(key, out value)) {\r
87                     return value;\r
88                 }\r
89                 return null;\r
90             }\r
91             [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
92             set {\r
93                 _data[key] = value;\r
94                 _modifiedKeys.Add(key);\r
95             }\r
96         }\r
97 \r
98         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
99         public void Add(string key, object value) {\r
100             _data.Add(key, value);\r
101             _modifiedKeys.Add(key);\r
102         }\r
103 \r
104         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
105         public void Clear() {\r
106             _data.Clear();\r
107             _modifiedKeys.Clear();\r
108             _initialKeys.Clear();\r
109         }\r
110 \r
111         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
112         public bool ContainsKey(string key) {\r
113             return _data.ContainsKey(key);\r
114         }\r
115 \r
116         public bool ContainsValue(object value) {\r
117             return _data.ContainsValue(value);\r
118         }\r
119 \r
120         public Dictionary<string, object>.Enumerator GetEnumerator() {\r
121             return _data.GetEnumerator();\r
122         }\r
123 \r
124         protected virtual void GetObjectData(SerializationInfo info, StreamingContext context) {\r
125             info.AddValue(_tempDataSerializationKey, _data);\r
126         }\r
127 \r
128         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
129         public bool Remove(string key) {\r
130             _initialKeys.Remove(key);\r
131             _modifiedKeys.Remove(key);\r
132             return _data.Remove(key);\r
133         }\r
134 \r
135         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
136         public bool TryGetValue(string key, out object value) {\r
137             return _data.TryGetValue(key, out value);\r
138         }\r
139 \r
140         #region IDictionary<string, object> Implementation\r
141         ICollection<string> IDictionary<string, object>.Keys {\r
142             [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
143             get {\r
144                 return ((IDictionary<string, object>)_data).Keys;\r
145             }\r
146         }\r
147 \r
148         ICollection<object> IDictionary<string, object>.Values {\r
149             [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
150             get {\r
151                 return ((IDictionary<string, object>)_data).Values;\r
152             }\r
153         }\r
154         #endregion\r
155 \r
156         #region IEnumerable<KeyValuePair<string, object>> Implementation\r
157         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
158         IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator() {\r
159             return ((IEnumerable<KeyValuePair<string, object>>)_data).GetEnumerator();\r
160         }\r
161         #endregion\r
162 \r
163         #region ICollection<KeyValuePair<string, object>> Implementation\r
164         bool ICollection<KeyValuePair<string, object>>.IsReadOnly {\r
165             [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
166             get {\r
167                 return ((ICollection<KeyValuePair<string, object>>)_data).IsReadOnly;\r
168             }\r
169         }\r
170 \r
171         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
172         void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int index) {\r
173             ((ICollection<KeyValuePair<string, object>>)_data).CopyTo(array, index);\r
174         }\r
175 \r
176         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
177         void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> keyValuePair) {\r
178             _modifiedKeys.Add(keyValuePair.Key);\r
179             ((ICollection<KeyValuePair<string, object>>)_data).Add(keyValuePair);\r
180         }\r
181 \r
182         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
183         bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> keyValuePair) {\r
184             return ((ICollection<KeyValuePair<string, object>>)_data).Contains(keyValuePair);\r
185         }\r
186 \r
187         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
188         bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> keyValuePair) {\r
189             _modifiedKeys.Remove(keyValuePair.Key);\r
190             return ((ICollection<KeyValuePair<string, object>>)_data).Remove(keyValuePair);\r
191         }\r
192         #endregion\r
193 \r
194         #region IEnumerable Implementation\r
195         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
196         IEnumerator IEnumerable.GetEnumerator() {\r
197             return ((IEnumerable)_data).GetEnumerator();\r
198         }\r
199         #endregion\r
200 \r
201         #region ISerializable Members\r
202         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]\r
203         void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {\r
204             GetObjectData(info, context);\r
205         }\r
206         #endregion\r
207     }\r
208 }\r