From 79103573867bcde141199efeb65aceca9523ce77 Mon Sep 17 00:00:00 2001 From: fejj Date: Wed, 2 Dec 2009 23:07:52 +0000 Subject: [PATCH] 2009-12-02 Jeffrey Stedfast * CollectionIteratorError.cs: Added to the build. * ResourceDictionary.cs (IsFixedSize): Implemented. (IDictionary.Add): Implemented. (IDictionary.CopyTo): Stubbed out. (IDictionary.GetEnumerator): Implemented. (IDictionary.Remove): Implemented. (ICollection.IsSynchronized): Implemented. (ICollection.SyncRoot): Implemented. (IEnumerable.GetEnumerator): Implemented. * PresentationFrameworkCollection.cs: Updated for NativeMethods.collection_iterator API changes. git-svn-id: svn+ssh://mono-cvs.ximian.com/source/trunk/moon@147505 e3ebcda4-bce8-0310-ba0a-eca2169e7518 --- class/System.Windows/Makefile.am | 1 + class/System.Windows/Mono/GeneratedPInvokes.cs | 22 +- class/System.Windows/Mono/ManagedXamlLoader.cs | 4 - class/System.Windows/System.Windows.mdp | 3 +- class/System.Windows/System.Windows/ChangeLog | 16 + .../PresentationFrameworkCollection.cs | 79 ++-- .../System.Windows/ResourceDictionary.cs | 408 +++++++++++++++------ 7 files changed, 383 insertions(+), 150 deletions(-) diff --git a/class/System.Windows/Makefile.am b/class/System.Windows/Makefile.am index b0475efc8..ed370e183 100644 --- a/class/System.Windows/Makefile.am +++ b/class/System.Windows/Makefile.am @@ -315,6 +315,7 @@ system_windows_sources = \ $(srcdir)/System.Windows/ApplicationUnhandledExceptionEventArgs.cs \ $(srcdir)/System.Windows/AssemblyPart.cs \ $(srcdir)/System.Windows/AssemblyPartCollection.cs \ + $(srcdir)/System.Windows/CollectionIteratorError.cs \ $(srcdir)/System.Windows/CornerRadius.cs \ $(srcdir)/System.Windows/CustomDependencyProperty.cs \ $(srcdir)/System.Windows/CrossDomainAccess.cs \ diff --git a/class/System.Windows/Mono/GeneratedPInvokes.cs b/class/System.Windows/Mono/GeneratedPInvokes.cs index 1f8abb0c2..0ca7eebca 100644 --- a/class/System.Windows/Mono/GeneratedPInvokes.cs +++ b/class/System.Windows/Mono/GeneratedPInvokes.cs @@ -447,12 +447,13 @@ namespace Mono { public extern static void collection_iterator_destroy (IntPtr iterator); [DllImport ("moon")] - // Value *collection_iterator_get_current (CollectionIterator *instance, int *error); - public extern static IntPtr collection_iterator_get_current (IntPtr instance, out int error); + // Value *collection_iterator_get_current (CollectionIterator *instance, CollectionIteratorError *err); + public extern static IntPtr collection_iterator_get_current (IntPtr instance, out CollectionIteratorError err); [DllImport ("moon")] - // int collection_iterator_next (CollectionIterator *instance); - public extern static int collection_iterator_next (IntPtr instance); + [return: MarshalAs (UnmanagedType.U1)] + // bool collection_iterator_next (CollectionIterator *instance, CollectionIteratorError *err); + public extern static bool collection_iterator_next (IntPtr instance, out CollectionIteratorError err); [DllImport ("moon")] [return: MarshalAs (UnmanagedType.U1)] @@ -1673,6 +1674,19 @@ namespace Mono { // ResourceDictionaryCollection *resource_dictionary_collection_new (); public extern static IntPtr resource_dictionary_collection_new (); + [DllImport ("moon", EntryPoint="resource_dictionary_iterator_get_current_key")] + // const char *resource_dictionary_iterator_get_current_key (ResourceDictionaryIterator *instance, CollectionIteratorError *err); + private extern static IntPtr resource_dictionary_iterator_get_current_key_ (IntPtr instance, out CollectionIteratorError err); + public static string resource_dictionary_iterator_get_current_key (IntPtr instance, out CollectionIteratorError err) + { + IntPtr result; + result = resource_dictionary_iterator_get_current_key_ (instance, out err); + if (result == IntPtr.Zero) + return null; + string s = Marshal.PtrToStringAnsi (result); // *copy* unmanaged string + return s; + } + [DllImport ("moon")] // RotateTransform *rotate_transform_new (); public extern static IntPtr rotate_transform_new (); diff --git a/class/System.Windows/Mono/ManagedXamlLoader.cs b/class/System.Windows/Mono/ManagedXamlLoader.cs index 14969946e..02b8f4549 100644 --- a/class/System.Windows/Mono/ManagedXamlLoader.cs +++ b/class/System.Windows/Mono/ManagedXamlLoader.cs @@ -1172,9 +1172,7 @@ namespace Mono.Xaml { error = null; object obj_value = Value.ToObject (null, value_ptr); - - if (pi.GetCustomAttributes (typeof (SetPropertyDelayedAttribute), true).Length > 0) { if ((data->flags & XamlCallbackFlags.SettingDelayedProperty) == 0) { Value v = *value_ptr; @@ -1183,7 +1181,6 @@ namespace Mono.Xaml } } - if (obj_value is Binding && target is FrameworkElement) { FrameworkElement fe = (FrameworkElement) target; fe.SetBinding (DependencyProperty.Lookup (fe.GetKind (), pi.Name), (Binding) obj_value); @@ -1208,7 +1205,6 @@ namespace Mono.Xaml string str_value = obj_value as string; if (str_value != null) { IntPtr unmanaged_value; - // // HACK: This really shouldn't be here, but I don't want to bother putting it in Helper, because that diff --git a/class/System.Windows/System.Windows.mdp b/class/System.Windows/System.Windows.mdp index 28a0a6182..d59352073 100644 --- a/class/System.Windows/System.Windows.mdp +++ b/class/System.Windows/System.Windows.mdp @@ -24,6 +24,7 @@ + @@ -540,4 +541,4 @@ - \ No newline at end of file + diff --git a/class/System.Windows/System.Windows/ChangeLog b/class/System.Windows/System.Windows/ChangeLog index 51f08d7c4..e0ba640e3 100644 --- a/class/System.Windows/System.Windows/ChangeLog +++ b/class/System.Windows/System.Windows/ChangeLog @@ -1,3 +1,19 @@ +2009-12-02 Jeffrey Stedfast + + * CollectionIteratorError.cs: Added to the build. + + * ResourceDictionary.cs (IsFixedSize): Implemented. + (IDictionary.Add): Implemented. + (IDictionary.CopyTo): Stubbed out. + (IDictionary.GetEnumerator): Implemented. + (IDictionary.Remove): Implemented. + (ICollection.IsSynchronized): Implemented. + (ICollection.SyncRoot): Implemented. + (IEnumerable.GetEnumerator): Implemented. + + * PresentationFrameworkCollection.cs: Updated for + NativeMethods.collection_iterator API changes. + 2009-12-01 Rolf Bjarne Kvinge * DependencyObject.cs: Add comment about corcompare issue. diff --git a/class/System.Windows/System.Windows/PresentationFrameworkCollection.cs b/class/System.Windows/System.Windows/PresentationFrameworkCollection.cs index 5a21c4b88..ae966d7ae 100644 --- a/class/System.Windows/System.Windows/PresentationFrameworkCollection.cs +++ b/class/System.Windows/System.Windows/PresentationFrameworkCollection.cs @@ -210,9 +210,14 @@ namespace System.Windows { } } - static internal Exception GetInvalid () + static internal void ThrowInvalidOperation (CollectionIteratorError error) { - return new InvalidOperationException ("The underlying collection has mutated"); + switch (error) { + case CollectionIteratorError.Mutated: + throw new InvalidOperationException ("The underlying collection has mutated"); + case CollectionIteratorError.Bounds: + throw new InvalidOperationException ("Index out of range"); + } } internal sealed class CollectionIterator : IEnumerator, IDisposable { @@ -227,29 +232,34 @@ namespace System.Windows { public bool MoveNext () { - int r = NativeMethods.collection_iterator_next (native_iter); - - if (r == -1) - throw GetInvalid (); + CollectionIteratorError err; + bool result; + + result = NativeMethods.collection_iterator_next (native_iter, out err); + + if (err != CollectionIteratorError.None) + ThrowInvalidOperation (err); - return r == 1; + return result; } public void Reset () { if (NativeMethods.collection_iterator_reset (native_iter)) return; - - throw GetInvalid (); + + ThrowInvalidOperation (CollectionIteratorError.Mutated); } public object Current { get { - int error; - IntPtr val = NativeMethods.collection_iterator_get_current (native_iter, out error); - - if (error == 1) - throw GetInvalid (); + CollectionIteratorError err; + IntPtr val; + + val = NativeMethods.collection_iterator_get_current (native_iter, out err); + + if (err != CollectionIteratorError.None) + ThrowInvalidOperation (err); if (val == IntPtr.Zero) return null; @@ -257,14 +267,15 @@ namespace System.Windows { return Value.ToObject (type, val); } } - + public void Dispose () { - if (native_iter != IntPtr.Zero){ + if (native_iter != IntPtr.Zero) { // This is safe, as it only does a "delete" in the C++ side NativeMethods.collection_iterator_destroy (native_iter); native_iter = IntPtr.Zero; } + GC.SuppressFinalize (this); } @@ -284,29 +295,34 @@ namespace System.Windows { public bool MoveNext () { - int r = NativeMethods.collection_iterator_next (native_iter); - - if (r == -1) - throw GetInvalid (); + CollectionIteratorError err; + bool result; - return r == 1; + result = NativeMethods.collection_iterator_next (native_iter, out err); + + if (err != CollectionIteratorError.None) + ThrowInvalidOperation (err); + + return result; } public void Reset () { if (NativeMethods.collection_iterator_reset (native_iter)) return; - - throw GetInvalid (); + + ThrowInvalidOperation (CollectionIteratorError.Mutated); } T GetCurrent () { - int error; - IntPtr val = NativeMethods.collection_iterator_get_current (native_iter, out error); - - if (error == 1) - throw GetInvalid (); + CollectionIteratorError err; + IntPtr val; + + val = NativeMethods.collection_iterator_get_current (native_iter, out err); + + if (err != CollectionIteratorError.None) + ThrowInvalidOperation (err); if (val == IntPtr.Zero) { // not sure if this is valid, @@ -323,20 +339,21 @@ namespace System.Windows { return GetCurrent (); } } - + object System.Collections.IEnumerator.Current { get { return GetCurrent (); } } - + public void Dispose () { - if (native_iter != IntPtr.Zero){ + if (native_iter != IntPtr.Zero) { // This is safe, as it only does a "delete" in the C++ side NativeMethods.collection_iterator_destroy (native_iter); native_iter = IntPtr.Zero; } + GC.SuppressFinalize (this); } diff --git a/class/System.Windows/System.Windows/ResourceDictionary.cs b/class/System.Windows/System.Windows/ResourceDictionary.cs index c8942883c..d48169bf4 100644 --- a/class/System.Windows/System.Windows/ResourceDictionary.cs +++ b/class/System.Windows/System.Windows/ResourceDictionary.cs @@ -42,15 +42,119 @@ using Mono.Xaml; namespace System.Windows { - public partial class ResourceDictionary : DependencyObject, IDictionary { - + public partial class ResourceDictionary : DependencyObject, IDictionary, IDictionary { + object sync_root = new object (); + Uri source; + + // + // Properties + // + + public int Count { + get { return NativeMethods.collection_get_count (native); } + } + + public bool IsReadOnly { + get { return false; } + } + + public bool IsFixedSize { + get { return false; } + } + + public ICollection Keys { + get { throw new NotImplementedException (); } + } + + public ICollection Values { + get { throw new NotImplementedException (); } + } + + public object this[object key] { + get { + bool exists; + IntPtr val = NativeMethods.resource_dictionary_get (native, ToStringKey (key), out exists); + if (val == IntPtr.Zero) + return null; + return Value.ToObject (null, val); + } + set { + var str_key = ToStringKey (key); + + Value v = Value.FromObject (value, true); + try { + NativeMethods.resource_dictionary_set (native, str_key, ref v); + } finally { + NativeMethods.value_free_value (ref v); + } + } + } + + public Uri Source { + get { return source; } + set { + if (source == value) + return; + + Clear (); + + source = value; + + var stream = Application.GetResourceStream (value); + + using (StreamReader sr = new StreamReader (stream.Stream)) { + string xaml = sr.ReadToEnd (); + + Value v = Value.FromObject (this); + ManagedXamlLoader loader = new ManagedXamlLoader (Deployment.Current.EntryAssembly, value.ToString (), Deployment.Current.Surface.Native, PluginHost.Handle); + loader.Hydrate (v, xaml, true, false, true); + } + } + } + + + // + // Helper Methods + // + + static string ToStringKey (object key) + { + if (key == null) + throw new ArgumentNullException ("key"); + + var str_key = key as string; + if (str_key == null) + throw new ArgumentException ("Key must be a string"); + + return str_key; + } + + bool RemoveInternal (string key) + { + if (key == null) + throw new ArgumentNullException ("key"); + + if (IsReadOnly || IsFixedSize) + throw new NotSupportedException (); + + return NativeMethods.resource_dictionary_remove (native, key); + } + + + // + // Methods + // + public void Add (string key, object value) { if (key == null) throw new ArgumentNullException ("key"); if (value == null) throw new NotSupportedException ("value"); - + + if (IsReadOnly || IsFixedSize) + throw new NotSupportedException (); + Value v = Value.FromObject (value, true); try { NativeMethods.resource_dictionary_add (native, key, ref v); @@ -58,96 +162,116 @@ namespace System.Windows { NativeMethods.value_free_value (ref v); } } - + + public void Add (object key, object value) + { + Add (ToStringKey (key), value); + } + public void Clear () { + if (IsReadOnly || IsFixedSize) + throw new NotSupportedException (); + NativeMethods.resource_dictionary_clear (native); } - + public bool Contains (object key) { return NativeMethods.resource_dictionary_contains_key (native, ToStringKey (key)); } - - static string ToStringKey (object key) + + public void CopyTo (Array array, int index) { - if (key == null) - throw new ArgumentNullException ("key"); - - var str_key = key as string; - if (str_key == null) - throw new ArgumentException ("Key must be a string"); - - return str_key; + if (array == null) + throw new ArgumentNullException ("array"); + + if (index < 0) + throw new ArgumentOutOfRangeException ("index"); + + if (array.Rank > 0 || Count > array.Length - index) + throw new ArgumentException ("array"); + + throw new NotImplementedException(); } - + + public IDictionaryEnumerator GetEnumerator () + { + return new ResourceDictionaryIterator (NativeMethods.collection_get_iterator (native)); + } + public void Remove (string key) { RemoveInternal (key); } - - private Uri source; - public Uri Source { - get { return source; } - set { - if (source == value) - return; - Clear (); - - source = value; - - var stream = Application.GetResourceStream (value); - - using (StreamReader sr = new StreamReader (stream.Stream)) { - string xaml = sr.ReadToEnd (); - - Value v = Value.FromObject (this); - ManagedXamlLoader loader = new ManagedXamlLoader (Deployment.Current.EntryAssembly, value.ToString (), Deployment.Current.Surface.Native, PluginHost.Handle); - loader.Hydrate (v, xaml, true, false, true); - } - } + + public void Remove (object key) + { + RemoveInternal (ToStringKey (key)); } - - private bool RemoveInternal (string key) + + + // + // ICollection implementation + // + + bool ICollection.IsSynchronized { + get { return false; } + } + + object ICollection.SyncRoot { + get { return sync_root; } + } + + IEnumerator IEnumerable.GetEnumerator () { - return NativeMethods.resource_dictionary_remove (native, key); + return GetEnumerator (); } - - public int Count { - get { return NativeMethods.collection_get_count (native); } + + + // + // ICollection> implementation + // + + void ICollection>.Add (KeyValuePair item) + { + Add (ToStringKey (item.Key), item.Value); } - - public bool IsReadOnly { - get { return false; } + + void ICollection>.Clear () + { + Clear (); } - - public object this[object key] { - get { - bool exists; - IntPtr val = NativeMethods.resource_dictionary_get (native, ToStringKey (key), out exists); - if (val == IntPtr.Zero) - return null; - return Value.ToObject (null, val); - } - set { - var str_key = ToStringKey (key); - - Value v = Value.FromObject (value, true); - try { - NativeMethods.resource_dictionary_set (native, str_key, ref v); - } finally { - NativeMethods.value_free_value (ref v); - } - } + + bool ICollection>.Contains (KeyValuePair item) + { + return Contains (item.Key); } - - IEnumerator IEnumerable.GetEnumerator() + + void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) { throw new NotImplementedException(); } - - // IDictionary implementation + + int ICollection>.Count { + get { return Count; } + } + + bool ICollection>.IsReadOnly { + get { return IsReadOnly; } + } + + bool ICollection>.Remove (KeyValuePair item) + { + RemoveInternal (ToStringKey (item.Key)); + return false; + } + + + // + // IDictionary implementation // + void IDictionary.Add(object key, object value) { Add (ToStringKey (key), value); @@ -181,45 +305,7 @@ namespace System.Windows { return exists; } - - // ICollection> implementation - // - void ICollection>.Add (KeyValuePair item) - { - Add (ToStringKey (item.Key), item.Value); - } - - void ICollection>.Clear () - { - Clear (); - } - - bool ICollection>.Contains (KeyValuePair item) - { - return Contains (item.Key); - } - - void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) - { - throw new NotImplementedException(); - } - - int ICollection>.Count { - get { throw new NotImplementedException (); } - } - - bool ICollection>.IsReadOnly { - get { return IsReadOnly; } - } - - bool ICollection>.Remove (KeyValuePair item) - { - RemoveInternal (ToStringKey (item.Key)); - return false; - } - - // IDictionary implementation - // + ICollection IDictionary.Keys { get {throw new NotImplementedException();} } @@ -227,12 +313,114 @@ namespace System.Windows { ICollection IDictionary.Values { get {throw new NotImplementedException();} } - - // IEnumerator> implementation + + // + // IEnumerator> implementation // + IEnumerator> IEnumerable>.GetEnumerator() { throw new NotImplementedException(); } + + + // + // Enumerator implementations + // + + static internal void ThrowInvalidOperation (CollectionIteratorError error) + { + switch (error) { + case CollectionIteratorError.Mutated: + throw new InvalidOperationException ("The underlying collection has mutated"); + case CollectionIteratorError.Bounds: + throw new InvalidOperationException ("Index out of range"); + } + } + + internal sealed class ResourceDictionaryIterator : IDictionaryEnumerator, IDisposable { + IntPtr native_iter; + + public ResourceDictionaryIterator (IntPtr native_iter) + { + this.native_iter = native_iter; + } + + ~ResourceDictionaryIterator () + { + Dispose (); + } + + public bool MoveNext () + { + CollectionIteratorError err; + bool result; + + result = NativeMethods.collection_iterator_next (native_iter, out err); + + if (err != CollectionIteratorError.None) + ThrowInvalidOperation (err); + + return result; + } + + public void Reset () + { + if (NativeMethods.collection_iterator_reset (native_iter)) + return; + + ThrowInvalidOperation (CollectionIteratorError.Mutated); + } + + public object Current { + get { return (object) Entry; } + } + + public DictionaryEntry Entry { + get { return new DictionaryEntry (Key, Value); } + } + + public object Key { + get { + CollectionIteratorError err; + string val; + + val = NativeMethods.resource_dictionary_iterator_get_current_key (native_iter, out err); + + if (err != CollectionIteratorError.None) + ThrowInvalidOperation (err); + + return val; + } + } + + public object Value { + get { + CollectionIteratorError err; + IntPtr val; + + val = NativeMethods.collection_iterator_get_current (native_iter, out err); + + if (err != CollectionIteratorError.None) + ThrowInvalidOperation (err); + + if (val == IntPtr.Zero) + return null; + + return Mono.Value.ToObject (null, val); + } + } + + public void Dispose () + { + if (native_iter != IntPtr.Zero) { + // This is safe, as it only does a "delete" in the C++ side + NativeMethods.collection_iterator_destroy (native_iter); + native_iter = IntPtr.Zero; + } + + GC.SuppressFinalize (this); + } + } } } -- 2.11.4.GIT