2 // System.Runtime.Remoting.Messaging.MethodDictionary.cs
4 // Author: Lluis Sanchez Gual (lluis@ideary.com)
6 // 2003 (C) Lluis Sanchez Gual
10 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System
.Collections
;
35 namespace System
.Runtime
.Remoting
.Messaging
38 internal class MethodDictionary
: IDictionary
40 IDictionary _internalProperties
= null;
41 protected IMethodMessage _message
;
43 bool _ownProperties
= false;
45 public MethodDictionary (IMethodMessage message
)
50 internal bool HasInternalProperties
54 if (null != _internalProperties
)
56 // MethodCallMessageWrapper uses a nested MethodDictionary
57 if (_internalProperties
is MethodDictionary
)
58 return ((MethodDictionary
)_internalProperties
).HasInternalProperties
;
60 return _internalProperties
.Count
> 0;
66 internal IDictionary InternalProperties
70 if (null != _internalProperties
)
72 if (_internalProperties
is MethodDictionary
)
73 return ((MethodDictionary
)_internalProperties
).InternalProperties
;
75 return _internalProperties
;
79 public string[] MethodKeys
81 get { return _methodKeys; }
82 set { _methodKeys = value; }
85 protected virtual IDictionary
AllocInternalProperties()
87 _ownProperties
= true;
88 return new Hashtable();
91 public IDictionary
GetInternalProperties()
93 if (_internalProperties
== null) _internalProperties
= AllocInternalProperties();
94 return _internalProperties
;
97 private bool IsOverridenKey (string key
)
99 // Small optimization. If the internal properties have been
100 // created by this dictionary, then it can be assured that it does
101 // not contain values for overriden keys.
102 if (_ownProperties
) return false;
104 foreach (string mkey
in _methodKeys
)
105 if (key
== mkey
) return true;
109 public MethodDictionary(string[] keys
)
114 public bool IsFixedSize
116 get { return false; }
119 public bool IsReadOnly
121 get { return false; }
124 public object this[object key
]
128 string keyStr
= (string)key
;
129 for (int n
=0; n
<_methodKeys
.Length
; n
++)
130 if (_methodKeys
[n
] == keyStr
) return GetMethodProperty (keyStr
);
132 if (_internalProperties
!= null)
133 return _internalProperties
[key
];
144 protected virtual object GetMethodProperty (string key
)
148 case "__Uri" : return _message
.Uri
;
149 case "__MethodName" : return _message
.MethodName
;
150 case "__TypeName" : return _message
.TypeName
;
151 case "__MethodSignature" : return _message
.MethodSignature
;
152 case "__CallContext" : return _message
.LogicalCallContext
;
153 case "__Args" : return _message
.Args
;
154 case "__OutArgs": return ((IMethodReturnMessage
)_message
).OutArgs
;
155 case "__Return": return ((IMethodReturnMessage
)_message
).ReturnValue
;
156 default : return null;
160 protected virtual void SetMethodProperty (string key
, object value)
164 case "__CallContext": // Ignore?
166 case "__Return": return;
168 case "__MethodName" :
170 case "__MethodSignature" :
171 case "__Args" : throw new ArgumentException ("key was invalid");
172 case "__Uri": ((IInternalMessage
)_message
).Uri
= (string) value; return;
176 public ICollection Keys
180 ArrayList keys
= new ArrayList();
181 for (int n
=0; n
<_methodKeys
.Length
; n
++)
182 keys
.Add (_methodKeys
[n
]);
184 if (_internalProperties
!= null)
186 foreach (string key
in _internalProperties
.Keys
)
187 if (!IsOverridenKey (key
)) keys
.Add (key
);
194 public ICollection Values
198 ArrayList values
= new ArrayList();
199 for (int n
=0; n
<_methodKeys
.Length
; n
++)
200 values
.Add (GetMethodProperty(_methodKeys
[n
]));
202 if (_internalProperties
!= null)
204 foreach (DictionaryEntry entry
in _internalProperties
)
205 if (!IsOverridenKey((string)entry
.Key
)) values
.Add (entry
.Value
);
212 public void Add (object key
, object value)
214 string keyStr
= (string)key
;
215 for (int n
=0; n
<_methodKeys
.Length
; n
++)
216 if (_methodKeys
[n
] == keyStr
) {
217 SetMethodProperty (keyStr
, value);
221 if (_internalProperties
== null) _internalProperties
= AllocInternalProperties();
222 _internalProperties
[key
] = value;
227 if (_internalProperties
!= null) _internalProperties
.Clear();
230 public bool Contains (object key
)
232 string keyStr
= (string)key
;
233 for (int n
=0; n
<_methodKeys
.Length
; n
++)
234 if (_methodKeys
[n
] == keyStr
) return true;
236 if (_internalProperties
!= null) return _internalProperties
.Contains (key
);
240 public void Remove (object key
)
242 string keyStr
= (string)key
;
243 for (int n
=0; n
<_methodKeys
.Length
; n
++)
244 if (_methodKeys
[n
] == keyStr
) throw new ArgumentException ("key was invalid");
246 if (_internalProperties
!= null) _internalProperties
.Remove (key
);
253 if (_internalProperties
!= null) return _internalProperties
.Count
+ _methodKeys
.Length
;
254 else return _methodKeys
.Length
;
258 public bool IsSynchronized
260 get { return false; }
263 public object SyncRoot
268 public void CopyTo (Array array
, int index
)
270 Values
.CopyTo (array
, index
);
273 IEnumerator IEnumerable
.GetEnumerator()
275 return new DictionaryEnumerator (this);
278 public IDictionaryEnumerator
GetEnumerator ()
280 return new DictionaryEnumerator (this);
283 // Dictionary enumerator
285 class DictionaryEnumerator
: IDictionaryEnumerator
287 MethodDictionary _methodDictionary
;
288 IDictionaryEnumerator _hashtableEnum
;
291 public DictionaryEnumerator (MethodDictionary methodDictionary
)
293 _methodDictionary
= methodDictionary
;
294 _hashtableEnum
= (_methodDictionary
._internalProperties
!= null) ? _methodDictionary
._internalProperties
.GetEnumerator() : null;
298 public object Current
300 get {return Entry.Value; }
303 public bool MoveNext()
305 if (_posMethod
!= -2)
308 if (_posMethod
< _methodDictionary
._methodKeys
.Length
) return true;
312 if (_hashtableEnum
== null) return false;
314 while (_hashtableEnum
.MoveNext())
316 if (!_methodDictionary
.IsOverridenKey((string)_hashtableEnum
.Key
))
325 _hashtableEnum
.Reset();
328 public DictionaryEntry Entry
333 return new DictionaryEntry (_methodDictionary
._methodKeys
[_posMethod
], _methodDictionary
.GetMethodProperty(_methodDictionary
._methodKeys
[_posMethod
]));
334 else if (_posMethod
== -1 || _hashtableEnum
== null)
335 throw new InvalidOperationException ("The enumerator is positioned before the first element of the collection or after the last element");
337 return _hashtableEnum
.Entry
;
343 get { return Entry.Key; }
348 get { return Entry.Value; }