PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/DICK.B1/IronPython/Runtime/Types/DictProxy.cs

https://bitbucket.org/williamybs/uidipythontool
C# | 348 lines | 255 code | 79 blank | 14 comment | 23 complexity | af2b49ca8e4647b2e95a9790e7af20f2 MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Microsoft Public License, please send an email to
  8. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. using System;
  16. using System.Collections;
  17. using System.Collections.Generic;
  18. using System.Diagnostics;
  19. using System.Runtime.CompilerServices;
  20. using Microsoft.Scripting;
  21. using Microsoft.Scripting.Runtime;
  22. using IronPython.Runtime.Binding;
  23. using IronPython.Runtime.Operations;
  24. using System.Runtime.InteropServices;
  25. namespace IronPython.Runtime.Types {
  26. [PythonType("dictproxy")]
  27. public class DictProxy : IDictionary, IEnumerable, IDictionary<object, object> {
  28. private readonly PythonType/*!*/ _dt;
  29. public DictProxy(PythonType/*!*/ dt) {
  30. Debug.Assert(dt != null);
  31. _dt = dt;
  32. }
  33. #region Python Public API Surface
  34. public int __len__(CodeContext context) {
  35. return _dt.GetMemberDictionary(context, false).Count;
  36. }
  37. public bool __contains__(CodeContext/*!*/ context, object value) {
  38. return has_key(context, value);
  39. }
  40. public string/*!*/ __str__(CodeContext/*!*/ context) {
  41. return DictionaryOps.__repr__(context, this);
  42. }
  43. public bool has_key(CodeContext/*!*/ context, object key) {
  44. object dummy;
  45. return TryGetValue(context, key, out dummy);
  46. }
  47. public object get(CodeContext/*!*/ context, [NotNull]object k, [DefaultParameterValue(null)]object d) {
  48. object res;
  49. if (!TryGetValue(context, k, out res)) {
  50. res = d;
  51. }
  52. return res;
  53. }
  54. public object keys(CodeContext context) {
  55. return new List(_dt.GetMemberDictionary(context, false).Keys);
  56. }
  57. public object values(CodeContext context) {
  58. List res = new List();
  59. foreach (KeyValuePair<object, object> kvp in _dt.GetMemberDictionary(context, false)) {
  60. PythonTypeUserDescriptorSlot dts = kvp.Value as PythonTypeUserDescriptorSlot;
  61. if (dts != null) {
  62. res.AddNoLock(dts.Value);
  63. } else {
  64. res.AddNoLock(kvp.Value);
  65. }
  66. }
  67. return res;
  68. }
  69. public List items(CodeContext context) {
  70. List res = new List();
  71. foreach (KeyValuePair<object, object> kvp in _dt.GetMemberDictionary(context, false)) {
  72. PythonTypeUserDescriptorSlot dts = kvp.Value as PythonTypeUserDescriptorSlot;
  73. object val;
  74. if (dts != null) {
  75. val = dts.Value;
  76. } else {
  77. val = kvp.Value;
  78. }
  79. res.append(PythonTuple.MakeTuple(kvp.Key, val));
  80. }
  81. return res;
  82. }
  83. public PythonDictionary copy(CodeContext/*!*/ context) {
  84. return new PythonDictionary(context, this);
  85. }
  86. public IEnumerator iteritems(CodeContext/*!*/ context) {
  87. return new DictionaryItemEnumerator(_dt.GetMemberDictionary(context, false)._storage);
  88. }
  89. public IEnumerator iterkeys(CodeContext/*!*/ context) {
  90. return new DictionaryKeyEnumerator(_dt.GetMemberDictionary(context, false)._storage);
  91. }
  92. public IEnumerator itervalues(CodeContext/*!*/ context) {
  93. return new DictionaryValueEnumerator(_dt.GetMemberDictionary(context, false)._storage);
  94. }
  95. #endregion
  96. #region Object overrides
  97. public override bool Equals(object obj) {
  98. DictProxy proxy = obj as DictProxy;
  99. if (proxy == null) return false;
  100. return proxy._dt == _dt;
  101. }
  102. public override int GetHashCode() {
  103. return ~_dt.GetHashCode();
  104. }
  105. #endregion
  106. #region IDictionary Members
  107. public object this[object key] {
  108. get {
  109. return GetIndex(DefaultContext.Default, key);
  110. }
  111. [PythonHidden]
  112. set {
  113. throw PythonOps.TypeError("cannot assign to dictproxy");
  114. }
  115. }
  116. bool IDictionary.Contains(object key) {
  117. return has_key(DefaultContext.Default, key);
  118. }
  119. #endregion
  120. #region IEnumerable Members
  121. System.Collections.IEnumerator IEnumerable.GetEnumerator() {
  122. return DictionaryOps.iterkeys(_dt.GetMemberDictionary(DefaultContext.Default, false));
  123. }
  124. #endregion
  125. #region IDictionary Members
  126. [PythonHidden]
  127. public void Add(object key, object value) {
  128. this[key] = value;
  129. }
  130. [PythonHidden]
  131. public void Clear() {
  132. throw new InvalidOperationException("dictproxy is read-only");
  133. }
  134. IDictionaryEnumerator IDictionary.GetEnumerator() {
  135. return new PythonDictionary.DictEnumerator(_dt.GetMemberDictionary(DefaultContext.Default, false).GetEnumerator());
  136. }
  137. bool IDictionary.IsFixedSize {
  138. get { return true; }
  139. }
  140. bool IDictionary.IsReadOnly {
  141. get { return true; }
  142. }
  143. ICollection IDictionary.Keys {
  144. get {
  145. ICollection<object> res = _dt.GetMemberDictionary(DefaultContext.Default, false).Keys;
  146. ICollection coll = res as ICollection;
  147. if (coll != null) {
  148. return coll;
  149. }
  150. return new List<object>(res);
  151. }
  152. }
  153. void IDictionary.Remove(object key) {
  154. throw new InvalidOperationException("dictproxy is read-only");
  155. }
  156. ICollection IDictionary.Values {
  157. get {
  158. List<object> res = new List<object>();
  159. foreach (KeyValuePair<object, object> kvp in _dt.GetMemberDictionary(DefaultContext.Default, false)) {
  160. res.Add(kvp.Value);
  161. }
  162. return res;
  163. }
  164. }
  165. #endregion
  166. #region ICollection Members
  167. void ICollection.CopyTo(Array array, int index) {
  168. foreach (DictionaryEntry de in (IDictionary)this) {
  169. array.SetValue(de, index++);
  170. }
  171. }
  172. int ICollection.Count {
  173. get { return __len__(DefaultContext.Default); }
  174. }
  175. bool ICollection.IsSynchronized {
  176. get { return false; }
  177. }
  178. object ICollection.SyncRoot {
  179. get { return this; }
  180. }
  181. #endregion
  182. #region IDictionary<object,object> Members
  183. bool IDictionary<object, object>.ContainsKey(object key) {
  184. return has_key(DefaultContext.Default, key);
  185. }
  186. ICollection<object> IDictionary<object, object>.Keys {
  187. get {
  188. return _dt.GetMemberDictionary(DefaultContext.Default, false).Keys;
  189. }
  190. }
  191. bool IDictionary<object, object>.Remove(object key) {
  192. throw new InvalidOperationException("dictproxy is read-only");
  193. }
  194. bool IDictionary<object, object>.TryGetValue(object key, out object value) {
  195. return TryGetValue(DefaultContext.Default, key, out value);
  196. }
  197. ICollection<object> IDictionary<object, object>.Values {
  198. get {
  199. return _dt.GetMemberDictionary(DefaultContext.Default, false).Values;
  200. }
  201. }
  202. #endregion
  203. #region ICollection<KeyValuePair<object,object>> Members
  204. void ICollection<KeyValuePair<object, object>>.Add(KeyValuePair<object, object> item) {
  205. this[item.Key] = item.Value;
  206. }
  207. bool ICollection<KeyValuePair<object, object>>.Contains(KeyValuePair<object, object> item) {
  208. return has_key(DefaultContext.Default, item.Key);
  209. }
  210. void ICollection<KeyValuePair<object, object>>.CopyTo(KeyValuePair<object, object>[] array, int arrayIndex) {
  211. foreach (KeyValuePair<object, object> de in (IEnumerable<KeyValuePair<object, object>>)this) {
  212. array.SetValue(de, arrayIndex++);
  213. }
  214. }
  215. int ICollection<KeyValuePair<object, object>>.Count {
  216. get { return __len__(DefaultContext.Default); }
  217. }
  218. bool ICollection<KeyValuePair<object, object>>.IsReadOnly {
  219. get { return true; }
  220. }
  221. bool ICollection<KeyValuePair<object, object>>.Remove(KeyValuePair<object, object> item) {
  222. return ((IDictionary<object, object>)this).Remove(item.Key);
  223. }
  224. #endregion
  225. #region IEnumerable<KeyValuePair<object,object>> Members
  226. IEnumerator<KeyValuePair<object, object>> IEnumerable<KeyValuePair<object, object>>.GetEnumerator() {
  227. return _dt.GetMemberDictionary(DefaultContext.Default, false).GetEnumerator();
  228. }
  229. #endregion
  230. #region Internal implementation details
  231. private object GetIndex(CodeContext context, object index) {
  232. string strIndex = index as string;
  233. if (strIndex != null) {
  234. PythonTypeSlot dts;
  235. if (_dt.TryLookupSlot(context, strIndex, out dts)) {
  236. PythonTypeUserDescriptorSlot uds = dts as PythonTypeUserDescriptorSlot;
  237. if (uds != null) {
  238. return uds.Value;
  239. }
  240. return dts;
  241. }
  242. }
  243. throw PythonOps.KeyError(index.ToString());
  244. }
  245. private bool TryGetValue(CodeContext/*!*/ context, object key, out object value) {
  246. string strIndex = key as string;
  247. if (strIndex != null) {
  248. PythonTypeSlot dts;
  249. if (_dt.TryLookupSlot(context, strIndex, out dts)) {
  250. PythonTypeUserDescriptorSlot uds = dts as PythonTypeUserDescriptorSlot;
  251. if (uds != null) {
  252. value = uds.Value;
  253. return true;
  254. }
  255. value = dts;
  256. return true;
  257. }
  258. }
  259. value = null;
  260. return false;
  261. }
  262. internal PythonType Type {
  263. get {
  264. return _dt;
  265. }
  266. }
  267. #endregion
  268. }
  269. }