diff options
author | Jo Shields <directhex@apebox.org> | 2014-02-19 22:12:43 +0000 |
---|---|---|
committer | Jo Shields <directhex@apebox.org> | 2014-02-19 22:12:43 +0000 |
commit | 9972bf87b4f27d9c8f358ef8414ac1ab957a2f0f (patch) | |
tree | 5bb230c1d698659115f918e243c1d4b0aa4c7f51 /mcs/class/System | |
parent | d0a215f5626219ff7927f576588a777e5331c7be (diff) | |
download | mono-upstream/3.2.8+dfsg.tar.gz |
Imported Upstream version 3.2.8+dfsgupstream/3.2.8+dfsg
Diffstat (limited to 'mcs/class/System')
37 files changed, 1537 insertions, 300 deletions
diff --git a/mcs/class/System/Documentation/en/System.Net/IPAddress.xml b/mcs/class/System/Documentation/en/System.Net/IPAddress.xml index f2caec0386..e428def11c 100755 --- a/mcs/class/System/Documentation/en/System.Net/IPAddress.xml +++ b/mcs/class/System/Documentation/en/System.Net/IPAddress.xml @@ -541,6 +541,21 @@ in network-byte-order.</para> <remarks>To be added.</remarks> </Docs> </Member> + <Member MemberName="IsIPv6Teredo"> + <MemberSignature Language="C#" Value="public bool IsIPv6Teredo { get; }" /> + <MemberType>Property</MemberType> + <AssemblyInfo> + <AssemblyVersion>4.0.0.0</AssemblyVersion> + </AssemblyInfo> + <ReturnValue> + <ReturnType>System.Boolean</ReturnType> + </ReturnValue> + <Docs> + <summary>To be added.</summary> + <value>To be added.</value> + <remarks>To be added.</remarks> + </Docs> + </Member> <Member MemberName="IsLoopback"> <MemberSignature Language="ILASM" Value=".method public hidebysig static bool IsLoopback(class System.Net.IPAddress address)" /> <MemberSignature Language="C#" Value="public static bool IsLoopback (System.Net.IPAddress addr);" /> diff --git a/mcs/class/System/Microsoft.CSharp/CSharpCodeCompiler.cs b/mcs/class/System/Microsoft.CSharp/CSharpCodeCompiler.cs index 26039bdd79..62b41de358 100644 --- a/mcs/class/System/Microsoft.CSharp/CSharpCodeCompiler.cs +++ b/mcs/class/System/Microsoft.CSharp/CSharpCodeCompiler.cs @@ -395,6 +395,20 @@ namespace Mono.CSharp args.AppendFormat("\"{0}\" ",source); return args.ToString(); } + + // Keep in sync with mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs + const string ErrorRegexPattern = @" + ^ + (\s*(?<file>[^\(]+) # filename (optional) + (\((?<line>\d*)(,(?<column>\d*[\+]*))?\))? # line+column (optional) + :\s+)? + (?<level>\w+) # error|warning + \s+ + (?<number>[^:]*\d) # CS1234 + : + \s* + (?<message>.*)$"; + private static CompilerError CreateErrorFromString(string error_string) { if (error_string.StartsWith ("BETA")) @@ -404,8 +418,7 @@ namespace Mono.CSharp return null; CompilerError error=new CompilerError(); - Regex reg = new Regex (@"^(\s*(?<file>.*)\((?<line>\d*)(,(?<column>\d*))?\)(:)?\s+)*(?<level>\w+)\s*(?<number>.*):\s(?<message>.*)", - RegexOptions.Compiled | RegexOptions.ExplicitCapture); + Regex reg = new Regex (ErrorRegexPattern, RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace); Match match=reg.Match(error_string); if (!match.Success) { // We had some sort of runtime crash diff --git a/mcs/class/System/System.CodeDom.Compiler/TempFileCollection.cs b/mcs/class/System/System.CodeDom.Compiler/TempFileCollection.cs index da056d1533..80c30eece7 100644 --- a/mcs/class/System/System.CodeDom.Compiler/TempFileCollection.cs +++ b/mcs/class/System/System.CodeDom.Compiler/TempFileCollection.cs @@ -73,33 +73,36 @@ namespace System.CodeDom.Compiler { // note: this property *cannot* change TempDir property string temp = tempdir; - if (temp.Length == 0) - temp = GetOwnTempDir (); + if (temp.Length == 0) { + if (ownTempDir != null) { + temp = ownTempDir; + Directory.CreateDirectory (temp); + } else { + temp = CreateOwnTempDir (); + } + } // Create a temporary file at the target directory. This ensures // that the generated file name is unique. - FileStream f = null; - do { + int test_counter = 1000; + while (true) { int num = rnd.Next (); num++; basepath = Path.Combine (temp, num.ToString("x")); string path = basepath + ".tmp"; try { - f = new FileStream (path, FileMode.CreateNew); - } - catch (System.IO.IOException) { - f = null; - continue; - } - catch { - // avoid endless loop + using (var f = new FileStream (path, FileMode.CreateNew)) { + break; + } + } catch (IOException) { + if (test_counter-- > 0) + continue; + throw; } - } while (f == null); - - f.Close (); - + } + // and you must have discovery access to the combined path // note: the cache behaviour is tested in the CAS tests if (SecurityManager.SecurityEnabled) { @@ -110,12 +113,9 @@ namespace System.CodeDom.Compiler { return(basepath); } } - - string GetOwnTempDir () - { - if (ownTempDir != null) - return ownTempDir; + string CreateOwnTempDir () + { // this call ensure the Environment permissions check string basedir = Path.GetTempPath (); @@ -245,9 +245,8 @@ namespace System.CodeDom.Compiler { File.Delete (tmpFile); basepath = null; } - if (allDeleted && ownTempDir != null) { + if (allDeleted && ownTempDir != null && filenames.Length > 0) { Directory.Delete (ownTempDir, true); - ownTempDir = null; } } diff --git a/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs b/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs index 26dc84a078..cc7e04ecdd 100644 --- a/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs +++ b/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs @@ -370,13 +370,19 @@ namespace System.Collections.Concurrent { item = default (T); CheckArray (collections); - int index = 0; - foreach (var coll in collections) { - try { - item = coll.Take (); - return index; - } catch {} - index++; + WaitHandle[] wait_table = null; + while (true) { + int index = 0; + for (int i = 0; i < collections.Length; ++i) { + if (collections [i].TryTake (out item)) + return i; + } + if (wait_table == null) { + wait_table = new WaitHandle [collections.Length]; + for (int i = 0; i < collections.Length; ++i) + wait_table [i] = collections [i].mreRemove.WaitHandle; + } + WaitHandle.WaitAny (wait_table); } return -1; } @@ -385,14 +391,24 @@ namespace System.Collections.Concurrent { item = default (T); CheckArray (collections); - int index = 0; - foreach (var coll in collections) { - try { - item = coll.Take (cancellationToken); - return index; - } catch {} - index++; + WaitHandle[] wait_table = null; + while (true) { + int index = 0; + for (int i = 0; i < collections.Length; ++i) { + if (collections [i].TryTake (out item)) + return i; + } + cancellationToken.ThrowIfCancellationRequested (); + if (wait_table == null) { + wait_table = new WaitHandle [collections.Length + 1]; + for (int i = 0; i < collections.Length; ++i) + wait_table [i] = collections [i].mreRemove.WaitHandle; + wait_table [collections.Length] = cancellationToken.WaitHandle; + } + WaitHandle.WaitAny (wait_table); + cancellationToken.ThrowIfCancellationRequested (); } + return -1; } diff --git a/mcs/class/System/System.Collections.Concurrent/ConcurrentBag.cs b/mcs/class/System/System.Collections.Concurrent/ConcurrentBag.cs index 5b4cbfcf1a..cd063347c6 100644 --- a/mcs/class/System/System.Collections.Concurrent/ConcurrentBag.cs +++ b/mcs/class/System/System.Collections.Concurrent/ConcurrentBag.cs @@ -65,6 +65,7 @@ namespace System.Collections.Concurrent int index; CyclicDeque<T> bag = GetBag (out index); bag.PushBottom (item); + staging.TryAdd (index, bag); AddHint (index); Interlocked.Increment (ref count); } @@ -88,6 +89,7 @@ namespace System.Collections.Concurrent if (bag == null || bag.PopBottom (out result) != PopResult.Succeed) { var self = bag; + ret = false; foreach (var other in staging) { // Try to retrieve something based on a hint ret = TryGetHint (out hintIndex) && (bag = container[hintIndex]).PopTop (out result) == PopResult.Succeed; @@ -129,6 +131,7 @@ namespace System.Collections.Concurrent if (bag == null || !bag.PeekBottom (out result)) { var self = bag; + ret = false; foreach (var other in staging) { // Try to retrieve something based on a hint ret = TryGetHint (out hintIndex) && container[hintIndex].PeekTop (out result); @@ -264,10 +267,7 @@ namespace System.Collections.Concurrent if (container.TryGetValue (index, out value)) return value; - var bag = createBag ? container.GetOrAdd (index, new CyclicDeque<T> ()) : null; - if (bag != null) - staging.TryAdd (index, bag); - return bag; + return createBag ? container.GetOrAdd (index, new CyclicDeque<T> ()) : null; } void TidyBag (int index, CyclicDeque<T> bag) @@ -279,4 +279,4 @@ namespace System.Collections.Concurrent } } } -#endif
\ No newline at end of file +#endif diff --git a/mcs/class/System/System.ComponentModel/BindingList.cs b/mcs/class/System/System.ComponentModel/BindingList.cs index b64d655efe..b4c0ce8b69 100644 --- a/mcs/class/System/System.ComponentModel/BindingList.cs +++ b/mcs/class/System/System.ComponentModel/BindingList.cs @@ -242,7 +242,7 @@ namespace System.ComponentModel { if (raise_list_changed_events) OnListChanged (new ListChangedEventArgs (ListChangedType.ItemAdded, index)); - if (type_raises_item_changed_events) + if (item != null && type_raises_item_changed_events) (item as INotifyPropertyChanged).PropertyChanged += Item_PropertyChanged; } diff --git a/mcs/class/System/System.ComponentModel/Component.cs b/mcs/class/System/System.ComponentModel/Component.cs index 5c61d72eef..1095161648 100644 --- a/mcs/class/System/System.ComponentModel/Component.cs +++ b/mcs/class/System/System.ComponentModel/Component.cs @@ -44,7 +44,7 @@ namespace System.ComponentModel { private EventHandlerList event_handlers; private ISite mySite; - private object disposedEvent = new object (); + static readonly object disposedEvent = new object (); public Component () { diff --git a/mcs/class/System/System.Configuration/SettingValueElement.cs b/mcs/class/System/System.Configuration/SettingValueElement.cs index bf618659ce..4c336dd005 100644 --- a/mcs/class/System/System.Configuration/SettingValueElement.cs +++ b/mcs/class/System/System.Configuration/SettingValueElement.cs @@ -27,6 +27,7 @@ // using System; +using System.Reflection; #if (XML_DEP) using System.Xml; #endif @@ -112,7 +113,79 @@ namespace System.Configuration #if (CONFIGURATION_DEP) protected override void Unmerge (ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode) { - throw new NotImplementedException (); + if (parentElement != null && sourceElement.GetType() != parentElement.GetType()) + throw new ConfigurationErrorsException ("Can't unmerge two elements of different type"); + + bool isMinimalOrModified = saveMode == ConfigurationSaveMode.Minimal || + saveMode == ConfigurationSaveMode.Modified; + + foreach (PropertyInformation prop in sourceElement.ElementInformation.Properties) + { + if (prop.ValueOrigin == PropertyValueOrigin.Default) + continue; + + PropertyInformation unmergedProp = ElementInformation.Properties [prop.Name]; + + object sourceValue = prop.Value; + if (parentElement == null || !HasValue (parentElement, prop.Name)) { + unmergedProp.Value = sourceValue; + continue; + } + + if (sourceValue == null) + continue; + + object parentValue = GetItem (parentElement, prop.Name); + if (!PropertyIsElement (prop)) { + if (!object.Equals (sourceValue, parentValue) || + (saveMode == ConfigurationSaveMode.Full) || + (saveMode == ConfigurationSaveMode.Modified && prop.ValueOrigin == PropertyValueOrigin.SetHere)) + unmergedProp.Value = sourceValue; + continue; + } + + var sourceElem = (ConfigurationElement) sourceValue; + if (isMinimalOrModified && !ElementIsModified (sourceElem)) + continue; + if (parentValue == null) { + unmergedProp.Value = sourceValue; + continue; + } + + var parentElem = (ConfigurationElement) parentValue; + ConfigurationElement copy = (ConfigurationElement) unmergedProp.Value; + ElementUnmerge (copy, sourceElem, parentElem, saveMode); + } + } + + bool HasValue (ConfigurationElement element, string propName) + { + PropertyInformation info = element.ElementInformation.Properties [propName]; + return info != null && info.ValueOrigin != PropertyValueOrigin.Default; + } + + object GetItem (ConfigurationElement element, string property) + { + PropertyInformation pi = ElementInformation.Properties [property]; + if (pi == null) + throw new InvalidOperationException ("Property '" + property + "' not found in configuration element"); + + return pi.Value; + } + + bool PropertyIsElement (PropertyInformation prop) + { + return (typeof(ConfigurationElement).IsAssignableFrom (prop.Type)); + } + + bool ElementIsModified (ConfigurationElement element) + { + return (bool) element.GetType ().GetMethod ("IsModified", BindingFlags.NonPublic | BindingFlags.Instance).Invoke (element, new object [0]); + } + + void ElementUnmerge (ConfigurationElement target, ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode) + { + target.GetType ().GetMethod ("Unmerge", BindingFlags.NonPublic | BindingFlags.Instance).Invoke (target, new object [] {sourceElement, parentElement, saveMode}); } #endif } diff --git a/mcs/class/System/System.Diagnostics/Process.cs b/mcs/class/System/System.Diagnostics/Process.cs index e08d79e0f1..7a63ce0377 100644 --- a/mcs/class/System/System.Diagnostics/Process.cs +++ b/mcs/class/System/System.Diagnostics/Process.cs @@ -918,8 +918,7 @@ namespace System.Diagnostics { IntPtr stderr, ref ProcInfo proc_info); - private static bool Start_shell (ProcessStartInfo startInfo, - Process process) + private static bool Start_shell (ProcessStartInfo startInfo, Process process) { ProcInfo proc_info=new ProcInfo(); bool ret; @@ -948,9 +947,7 @@ namespace System.Diagnostics { process.process_handle = proc_info.process_handle; process.pid = proc_info.pid; - process.StartExitCallbackIfNeeded (); - return(ret); } @@ -1182,9 +1179,9 @@ namespace System.Diagnostics { if (startInfo == null) throw new ArgumentNullException ("startInfo"); - Process process=new Process(); + Process process = new Process(); process.StartInfo = startInfo; - if (Start_common(startInfo, process)) + if (Start_common(startInfo, process) && process.process_handle != IntPtr.Zero) return process; return null; } @@ -1566,6 +1563,21 @@ namespace System.Diagnostics { async_output.Close (); if (async_error != null) async_error.Close (); + + if (input_stream != null) { + input_stream.Close(); + input_stream = null; + } + + if (output_stream != null) { + output_stream.Close(); + output_stream = null; + } + + if (error_stream != null) { + error_stream.Close(); + error_stream = null; + } } } @@ -1576,21 +1588,6 @@ namespace System.Diagnostics { Process_free_internal(process_handle); process_handle=IntPtr.Zero; } - - if (input_stream != null) { - input_stream.Close(); - input_stream = null; - } - - if (output_stream != null) { - output_stream.Close(); - output_stream = null; - } - - if (error_stream != null) { - error_stream.Close(); - error_stream = null; - } } } base.Dispose (disposing); diff --git a/mcs/class/System/System.IO.Compression/CompressionLevel.cs b/mcs/class/System/System.IO.Compression/CompressionLevel.cs index 7ea3a7a49f..2242c19cf5 100644 --- a/mcs/class/System/System.IO.Compression/CompressionLevel.cs +++ b/mcs/class/System/System.IO.Compression/CompressionLevel.cs @@ -27,7 +27,7 @@ #if NET_4_5 namespace System.IO.Compression { public enum CompressionLevel { - Optional, + Optimal, Fastest, NoCompression } diff --git a/mcs/class/System/System.Net.NetworkInformation/NetworkChange.cs b/mcs/class/System/System.Net.NetworkInformation/NetworkChange.cs index c60954c949..de9754e951 100644 --- a/mcs/class/System/System.Net.NetworkInformation/NetworkChange.cs +++ b/mcs/class/System/System.Net.NetworkInformation/NetworkChange.cs @@ -2,8 +2,8 @@ // System.Net.NetworkInformation.NetworkChange // // Authors: -// Gonzalo Paniagua Javier (gonzalo@novell.com) -// Aaron Bockover (abock@xamarin.com) +// Gonzalo Paniagua Javier (LinuxNetworkChange) (gonzalo@novell.com) +// Aaron Bockover (MacNetworkChange) (abock@xamarin.com) // // Copyright (c) 2006,2011 Novell, Inc. (http://www.novell.com) // Copyright (c) 2013 Xamarin, Inc. (http://www.xamarin.com) @@ -15,10 +15,10 @@ // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: -// +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -28,137 +28,298 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Threading; +#if NETWORK_CHANGE_STANDALONE +namespace NetworkInformation { + + public class NetworkAvailabilityEventArgs : EventArgs + { + public bool IsAvailable { get; set; } + + public NetworkAvailabilityEventArgs (bool available) + { + IsAvailable = available; + } + } + + public delegate void NetworkAddressChangedEventHandler (object sender, EventArgs args); + public delegate void NetworkAvailabilityChangedEventHandler (object sender, NetworkAvailabilityEventArgs args); +#else namespace System.Net.NetworkInformation { - internal interface INetworkChange { +#endif + + internal interface INetworkChange : IDisposable { event NetworkAddressChangedEventHandler NetworkAddressChanged; event NetworkAvailabilityChangedEventHandler NetworkAvailabilityChanged; + bool HasRegisteredEvents { get; } } public sealed class NetworkChange { static INetworkChange networkChange; - static NetworkChange () + public static event NetworkAddressChangedEventHandler NetworkAddressChanged { + add { + lock (typeof (INetworkChange)) { + MaybeCreate (); + if (networkChange != null) + networkChange.NetworkAddressChanged += value; + } + } + + remove { + lock (typeof (INetworkChange)) { + if (networkChange != null) { + networkChange.NetworkAddressChanged -= value; + MaybeDispose (); + } + } + } + } + + public static event NetworkAvailabilityChangedEventHandler NetworkAvailabilityChanged { + add { + lock (typeof (INetworkChange)) { + MaybeCreate (); + if (networkChange != null) + networkChange.NetworkAvailabilityChanged += value; + } + } + + remove { + lock (typeof (INetworkChange)) { + if (networkChange != null) { + networkChange.NetworkAvailabilityChanged -= value; + MaybeDispose (); + } + } + } + } + + static void MaybeCreate () { - if (MacNetworkChange.IsEnabled) { + if (networkChange != null) + return; + + try { networkChange = new MacNetworkChange (); - } else { + } catch { +#if !NETWORK_CHANGE_STANDALONE networkChange = new LinuxNetworkChange (); +#endif } } - public static event NetworkAddressChangedEventHandler NetworkAddressChanged { - add { networkChange.NetworkAddressChanged += value; } - remove { networkChange.NetworkAddressChanged -= value; } + static void MaybeDispose () + { + if (networkChange != null && networkChange.HasRegisteredEvents) { + networkChange.Dispose (); + networkChange = null; + } } + } - public static event NetworkAvailabilityChangedEventHandler NetworkAvailabilityChanged { - add { networkChange.NetworkAvailabilityChanged += value; } - remove { networkChange.NetworkAvailabilityChanged -= value; } + internal sealed class MacNetworkChange : INetworkChange + { + const string DL_LIB = "/usr/lib/libSystem.dylib"; + const string CORE_SERVICES_LIB = "/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration"; + const string CORE_FOUNDATION_LIB = "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"; + + [UnmanagedFunctionPointerAttribute (CallingConvention.Cdecl)] + delegate void SCNetworkReachabilityCallback (IntPtr target, NetworkReachabilityFlags flags, IntPtr info); + + [DllImport (DL_LIB)] + static extern IntPtr dlopen (string path, int mode); + + [DllImport (DL_LIB)] + static extern IntPtr dlsym (IntPtr handle, string symbol); + + [DllImport (DL_LIB)] + static extern int dlclose (IntPtr handle); + + [DllImport (CORE_FOUNDATION_LIB)] + static extern void CFRelease (IntPtr handle); + + [DllImport (CORE_FOUNDATION_LIB)] + static extern IntPtr CFRunLoopGetMain (); + + [DllImport (CORE_SERVICES_LIB)] + static extern IntPtr SCNetworkReachabilityCreateWithAddress (IntPtr allocator, ref sockaddr_in sockaddr); + + [DllImport (CORE_SERVICES_LIB)] + static extern bool SCNetworkReachabilityGetFlags (IntPtr reachability, out NetworkReachabilityFlags flags); + + [DllImport (CORE_SERVICES_LIB)] + static extern bool SCNetworkReachabilitySetCallback (IntPtr reachability, SCNetworkReachabilityCallback callback, ref SCNetworkReachabilityContext context); + + [DllImport (CORE_SERVICES_LIB)] + static extern bool SCNetworkReachabilityScheduleWithRunLoop (IntPtr reachability, IntPtr runLoop, IntPtr runLoopMode); + + [DllImport (CORE_SERVICES_LIB)] + static extern bool SCNetworkReachabilityUnscheduleFromRunLoop (IntPtr reachability, IntPtr runLoop, IntPtr runLoopMode); + + [StructLayout (LayoutKind.Explicit, Size = 28)] + struct sockaddr_in { + [FieldOffset (0)] public byte sin_len; + [FieldOffset (1)] public byte sin_family; + + public static sockaddr_in Create () + { + return new sockaddr_in { + sin_len = 28, + sin_family = 2 // AF_INET + }; + } } - } - internal sealed class MacNetworkChange : INetworkChange { - public static bool IsEnabled { - get { return mono_sc_reachability_enabled () != 0; } + [StructLayout (LayoutKind.Sequential)] + struct SCNetworkReachabilityContext { + public IntPtr version; + public IntPtr info; + public IntPtr retain; + public IntPtr release; + public IntPtr copyDescription; + } + + [Flags] + enum NetworkReachabilityFlags { + None = 0, + TransientConnection = 1 << 0, + Reachable = 1 << 1, + ConnectionRequired = 1 << 2, + ConnectionOnTraffic = 1 << 3, + InterventionRequired = 1 << 4, + ConnectionOnDemand = 1 << 5, + IsLocalAddress = 1 << 16, + IsDirect = 1 << 17, + IsWWAN = 1 << 18, + ConnectionAutomatic = ConnectionOnTraffic } + IntPtr handle; + IntPtr runLoopMode; + SCNetworkReachabilityCallback callback; + bool scheduledWithRunLoop; + NetworkReachabilityFlags flags; + event NetworkAddressChangedEventHandler networkAddressChanged; event NetworkAvailabilityChangedEventHandler networkAvailabilityChanged; public event NetworkAddressChangedEventHandler NetworkAddressChanged { add { - if (value != null) { - MaybeInitialize (); - networkAddressChanged += value; - value (null, EventArgs.Empty); - } + value (null, EventArgs.Empty); + networkAddressChanged += value; } - remove { - networkAddressChanged -= value; - MaybeDispose (); - } + remove { networkAddressChanged -= value; } } public event NetworkAvailabilityChangedEventHandler NetworkAvailabilityChanged { add { - if (value != null) { - MaybeInitialize (); - networkAvailabilityChanged += value; - var available = handle != IntPtr.Zero && mono_sc_reachability_is_available (handle) != 0; - value (null, new NetworkAvailabilityEventArgs (available)); - } + value (null, new NetworkAvailabilityEventArgs (IsAvailable)); + networkAvailabilityChanged += value; } - remove { - networkAvailabilityChanged -= value; - MaybeDispose (); + remove { networkAvailabilityChanged -= value; } + } + + bool IsAvailable { + get { + return (flags & NetworkReachabilityFlags.Reachable) != 0 && + (flags & NetworkReachabilityFlags.ConnectionRequired) == 0; } } - IntPtr handle; - MonoSCReachabilityCallback callback; + public bool HasRegisteredEvents { + get { return networkAddressChanged != null || networkAvailabilityChanged != null; } + } - void Callback (int available) + public MacNetworkChange () { - var addressChanged = networkAddressChanged; - if (addressChanged != null) { - addressChanged (null, EventArgs.Empty); - } + var sockaddr = sockaddr_in.Create (); + handle = SCNetworkReachabilityCreateWithAddress (IntPtr.Zero, ref sockaddr); + if (handle == IntPtr.Zero) + throw new Exception ("SCNetworkReachabilityCreateWithAddress returned NULL"); - var availabilityChanged = networkAvailabilityChanged; - if (availabilityChanged != null) { - availabilityChanged (null, new NetworkAvailabilityEventArgs (available != 0)); - } + callback = new SCNetworkReachabilityCallback (HandleCallback); + var info = new SCNetworkReachabilityContext { + info = GCHandle.ToIntPtr (GCHandle.Alloc (this)) + }; + + SCNetworkReachabilitySetCallback (handle, callback, ref info); + + scheduledWithRunLoop = + LoadRunLoopMode () && + SCNetworkReachabilityScheduleWithRunLoop (handle, CFRunLoopGetMain (), runLoopMode); + + SCNetworkReachabilityGetFlags (handle, out flags); } - void MaybeInitialize () + bool LoadRunLoopMode () { - lock (this) { - if (handle == IntPtr.Zero) { - callback = new MonoSCReachabilityCallback (Callback); - handle = mono_sc_reachability_new (callback); + var cfLibHandle = dlopen (CORE_FOUNDATION_LIB, 0); + if (cfLibHandle == IntPtr.Zero) + return false; + + try { + runLoopMode = dlsym (cfLibHandle, "kCFRunLoopDefaultMode"); + if (runLoopMode != IntPtr.Zero) { + runLoopMode = Marshal.ReadIntPtr (runLoopMode); + return runLoopMode != IntPtr.Zero; } + } finally { + dlclose (cfLibHandle); } + + return false; } - void MaybeDispose () + public void Dispose () { lock (this) { - var addressChanged = networkAddressChanged; - var availabilityChanged = networkAvailabilityChanged; - if (handle != IntPtr.Zero && addressChanged == null && availabilityChanged == null) { - mono_sc_reachability_free (handle); - handle = IntPtr.Zero; - } + if (handle == IntPtr.Zero) + return; + + if (scheduledWithRunLoop) + SCNetworkReachabilityUnscheduleFromRunLoop (handle, CFRunLoopGetMain (), runLoopMode); + + CFRelease (handle); + handle = IntPtr.Zero; + callback = null; + flags = NetworkReachabilityFlags.None; + scheduledWithRunLoop = false; } } -#if MONOTOUCH || MONODROID - const string LIBNAME = "__Internal"; -#else - const string LIBNAME = "MonoPosixHelper"; +#if MONOTOUCH + [MonoTouch.MonoPInvokeCallback (typeof (SCNetworkReachabilityCallback))] #endif + static void HandleCallback (IntPtr reachability, NetworkReachabilityFlags flags, IntPtr info) + { + if (info == IntPtr.Zero) + return; - delegate void MonoSCReachabilityCallback (int available); - - [DllImport (LIBNAME)] - static extern int mono_sc_reachability_enabled (); + var instance = GCHandle.FromIntPtr (info).Target as MacNetworkChange; + if (instance == null || instance.flags == flags) + return; - [DllImport (LIBNAME)] - static extern IntPtr mono_sc_reachability_new (MonoSCReachabilityCallback callback); + instance.flags = flags; - [DllImport (LIBNAME)] - static extern void mono_sc_reachability_free (IntPtr handle); + var addressChanged = instance.networkAddressChanged; + if (addressChanged != null) + addressChanged (null, EventArgs.Empty); - [DllImport (LIBNAME)] - static extern int mono_sc_reachability_is_available (IntPtr handle); + var availabilityChanged = instance.networkAvailabilityChanged; + if (availabilityChanged != null) + availabilityChanged (null, new NetworkAvailabilityEventArgs (instance.IsAvailable)); + } } +#if !NETWORK_CHANGE_STANDALONE + internal sealed class LinuxNetworkChange : INetworkChange { [Flags] enum EventType { @@ -185,6 +346,14 @@ namespace System.Net.NetworkInformation { remove { Unregister (value); } } + public bool HasRegisteredEvents { + get { return AddressChanged != null || AvailabilityChanged != null; } + } + + public void Dispose () + { + } + //internal Socket (AddressFamily family, SocketType type, ProtocolType proto, IntPtr sock) bool EnsureSocket () @@ -321,5 +490,7 @@ namespace System.Net.NetworkInformation { [DllImport (LIBNAME, CallingConvention=CallingConvention.Cdecl)] static extern IntPtr CloseNLSocket (IntPtr sock); } -} +#endif + +} diff --git a/mcs/class/System/System.Net.Sockets/NetworkStream.cs b/mcs/class/System/System.Net.Sockets/NetworkStream.cs index 65126ca24f..f358c4dbbc 100644 --- a/mcs/class/System/System.Net.Sockets/NetworkStream.cs +++ b/mcs/class/System/System.Net.Sockets/NetworkStream.cs @@ -51,8 +51,8 @@ namespace System.Net.Sockets { } - public NetworkStream (Socket socket, bool owns_socket) - : this (socket, FileAccess.ReadWrite, owns_socket) + public NetworkStream (Socket socket, bool ownsSocket) + : this (socket, FileAccess.ReadWrite, ownsSocket) { } @@ -61,7 +61,7 @@ namespace System.Net.Sockets { } - public NetworkStream (Socket socket, FileAccess access, bool owns_socket) + public NetworkStream (Socket socket, FileAccess access, bool ownsSocket) { if (socket == null) throw new ArgumentNullException ("socket is null"); @@ -73,7 +73,7 @@ namespace System.Net.Sockets throw new IOException ("Operation not allowed on a non-blocking socket."); this.socket = socket; - this.owns_socket = owns_socket; + this.owns_socket = ownsSocket; this.access = access; readable = CanRead; diff --git a/mcs/class/System/System.Net.WebSockets/ClientWebSocket.cs b/mcs/class/System/System.Net.WebSockets/ClientWebSocket.cs index f04cb3c054..3778c74053 100644 --- a/mcs/class/System/System.Net.WebSockets/ClientWebSocket.cs +++ b/mcs/class/System/System.Net.WebSockets/ClientWebSocket.cs @@ -1,10 +1,12 @@ // // ClientWebSocket.cs // -// Author: -// Martin Baulig <martin.baulig@xamarin.com> +// Authors: +// Jérémie Laval <jeremie dot laval at xamarin dot com> // -// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com) +// Copyright 2013 Xamarin Inc (http://www.xamarin.com). +// +// Lightly inspired from WebSocket4Net distributed under the Apache License 2.0 // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -27,71 +29,327 @@ #if NET_4_5 using System; +using System.Net; +using System.Net.Sockets; +using System.Security.Principal; +using System.Security.Cryptography.X509Certificates; +using System.Runtime.CompilerServices; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using System.Globalization; +using System.Text; +using System.Security.Cryptography; namespace System.Net.WebSockets { - [MonoTODO] - public class ClientWebSocket : WebSocket + public class ClientWebSocket : WebSocket, IDisposable { - public ClientWebSocketOptions Options { - get { throw new NotImplementedException (); } + const string Magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + const string VersionTag = "13"; + + ClientWebSocketOptions options; + WebSocketState state; + string subProtocol; + + HttpWebRequest req; + WebConnection connection; + Socket underlyingSocket; + + Random random = new Random (); + + const int HeaderMaxLength = 14; + byte[] headerBuffer; + byte[] sendBuffer; + + public ClientWebSocket () + { + options = new ClientWebSocketOptions (); + state = WebSocketState.None; + headerBuffer = new byte[HeaderMaxLength]; } - public Task ConnectAsync (Uri uri, CancellationToken cancellationToken) + public override void Dispose () { - throw new NotImplementedException (); + if (connection != null) + connection.Close (false); } - #region implemented abstract members of WebSocket + [MonoTODO] public override void Abort () { throw new NotImplementedException (); } - public override Task CloseAsync (WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) + + public ClientWebSocketOptions Options { + get { + return options; + } + } + + public override WebSocketState State { + get { + return state; + } + } + + public override WebSocketCloseStatus? CloseStatus { + get { + if (state != WebSocketState.Closed) + return (WebSocketCloseStatus?)null; + return WebSocketCloseStatus.Empty; + } + } + + public override string CloseStatusDescription { + get { + return null; + } + } + + public override string SubProtocol { + get { + return subProtocol; + } + } + + public async Task ConnectAsync (Uri uri, CancellationToken cancellationToken) { - throw new NotImplementedException (); + state = WebSocketState.Connecting; + var httpUri = new UriBuilder (uri); + if (uri.Scheme == "wss") + httpUri.Scheme = "https"; + else + httpUri.Scheme = "http"; + req = (HttpWebRequest)WebRequest.Create (httpUri.Uri); + req.ReuseConnection = true; + if (options.Cookies != null) + req.CookieContainer = options.Cookies; + + if (options.CustomRequestHeaders.Count > 0) { + foreach (var header in options.CustomRequestHeaders) + req.Headers[header.Key] = header.Value; + } + + var secKey = Convert.ToBase64String (Encoding.ASCII.GetBytes (Guid.NewGuid ().ToString ().Substring (0, 16))); + string expectedAccept = Convert.ToBase64String (SHA1.Create ().ComputeHash (Encoding.ASCII.GetBytes (secKey + Magic))); + + req.Headers["Upgrade"] = "WebSocket"; + req.Headers["Sec-WebSocket-Version"] = VersionTag; + req.Headers["Sec-WebSocket-Key"] = secKey; + req.Headers["Sec-WebSocket-Origin"] = uri.Host; + if (options.SubProtocols.Count > 0) + req.Headers["Sec-WebSocket-Protocol"] = string.Join (",", options.SubProtocols); + + if (options.Credentials != null) + req.Credentials = options.Credentials; + if (options.ClientCertificates != null) + req.ClientCertificates = options.ClientCertificates; + if (options.Proxy != null) + req.Proxy = options.Proxy; + req.UseDefaultCredentials = options.UseDefaultCredentials; + req.Connection = "Upgrade"; + + HttpWebResponse resp = null; + try { + resp = (HttpWebResponse)(await req.GetResponseAsync ().ConfigureAwait (false)); + } catch (Exception e) { + throw new WebSocketException (WebSocketError.Success, e); + } + + connection = req.StoredConnection; + underlyingSocket = connection.socket; + + if (resp.StatusCode != HttpStatusCode.SwitchingProtocols) + throw new WebSocketException ("The server returned status code '" + (int)resp.StatusCode + "' when status code '101' was expected"); + if (!string.Equals (resp.Headers["Upgrade"], "WebSocket", StringComparison.OrdinalIgnoreCase) + || !string.Equals (resp.Headers["Connection"], "Upgrade", StringComparison.OrdinalIgnoreCase) + || !string.Equals (resp.Headers["Sec-WebSocket-Accept"], expectedAccept)) + throw new WebSocketException ("HTTP header error during handshake"); + if (resp.Headers["Sec-WebSocket-Protocol"] != null) { + if (!options.SubProtocols.Contains (resp.Headers["Sec-WebSocket-Protocol"])) + throw new WebSocketException (WebSocketError.UnsupportedProtocol); + subProtocol = resp.Headers["Sec-WebSocket-Protocol"]; + } + + state = WebSocketState.Open; } - public override Task CloseOutputAsync (WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) + + public override Task SendAsync (ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) { - throw new NotImplementedException (); + EnsureWebSocketConnected (); + ValidateArraySegment (buffer); + if (connection == null) + throw new WebSocketException (WebSocketError.Faulted); + var count = Math.Max (options.SendBufferSize, buffer.Count) + HeaderMaxLength; + if (sendBuffer == null || sendBuffer.Length != count) + sendBuffer = new byte[count]; + return Task.Run (() => { + EnsureWebSocketState (WebSocketState.Open, WebSocketState.CloseReceived); + var maskOffset = WriteHeader (messageType, buffer, endOfMessage); + + if (buffer.Count > 0) + MaskData (buffer, maskOffset); + //underlyingSocket.Send (headerBuffer, 0, maskOffset + 4, SocketFlags.None); + var headerLength = maskOffset + 4; + Array.Copy (headerBuffer, sendBuffer, headerLength); + underlyingSocket.Send (sendBuffer, 0, buffer.Count + headerLength, SocketFlags.None); + }); } + public override Task<WebSocketReceiveResult> ReceiveAsync (ArraySegment<byte> buffer, CancellationToken cancellationToken) { - throw new NotImplementedException (); + EnsureWebSocketConnected (); + ValidateArraySegment (buffer); + return Task.Run (() => { + EnsureWebSocketState (WebSocketState.Open, WebSocketState.CloseSent); + // First read the two first bytes to know what we are doing next + connection.Read (req, headerBuffer, 0, 2); + var isLast = (headerBuffer[0] >> 7) > 0; + var isMasked = (headerBuffer[1] >> 7) > 0; + int mask = 0; + var type = (WebSocketMessageType)(headerBuffer[0] & 0xF); + long length = headerBuffer[1] & 0x7F; + int offset = 0; + if (length == 126) { + offset = 2; + connection.Read (req, headerBuffer, 2, offset); + length = (headerBuffer[2] << 8) | headerBuffer[3]; + } else if (length == 127) { + offset = 8; + connection.Read (req, headerBuffer, 2, offset); + length = 0; + for (int i = 2; i <= 9; i++) + length = (length << 8) | headerBuffer[i]; + } + + if (isMasked) { + connection.Read (req, headerBuffer, 2 + offset, 4); + for (int i = 0; i < 4; i++) { + var pos = i + offset + 2; + mask = (mask << 8) | headerBuffer[pos]; + } + } + + if (type == WebSocketMessageType.Close) { + state = WebSocketState.Closed; + var tmpBuffer = new byte[length]; + connection.Read (req, tmpBuffer, 0, tmpBuffer.Length); + var closeStatus = (WebSocketCloseStatus)(tmpBuffer[0] << 8 | tmpBuffer[1]); + var closeDesc = tmpBuffer.Length > 2 ? Encoding.UTF8.GetString (tmpBuffer, 2, tmpBuffer.Length - 2) : string.Empty; + return new WebSocketReceiveResult ((int)length, type, isLast, closeStatus, closeDesc); + } else { + var readLength = (int)(buffer.Count < length ? buffer.Count : length); + connection.Read (req, buffer.Array, buffer.Offset, readLength); + + return new WebSocketReceiveResult ((int)length, type, isLast); + } + }); } - public override Task SendAsync (ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) + + // The damn difference between those two methods is that CloseAsync will wait for server acknowledgement before completing + // while CloseOutputAsync will send the close packet and simply complete. + + public async override Task CloseAsync (WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) { - throw new NotImplementedException (); + EnsureWebSocketConnected (); + await SendCloseFrame (closeStatus, statusDescription, cancellationToken).ConfigureAwait (false); + state = WebSocketState.CloseSent; + // TODO: figure what's exceptions are thrown if the server returns something faulty here + await ReceiveAsync (new ArraySegment<byte> (new byte[0]), cancellationToken).ConfigureAwait (false); + state = WebSocketState.Closed; } - public override void Dispose () + + public async override Task CloseOutputAsync (WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) { - throw new NotImplementedException (); + EnsureWebSocketConnected (); + await SendCloseFrame (closeStatus, statusDescription, cancellationToken).ConfigureAwait (false); + state = WebSocketState.CloseSent; } - public override WebSocketCloseStatus? CloseStatus { - get { - throw new NotImplementedException (); - } + + async Task SendCloseFrame (WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) + { + var statusDescBuffer = string.IsNullOrEmpty (statusDescription) ? new byte[2] : new byte[2 + Encoding.UTF8.GetByteCount (statusDescription)]; + statusDescBuffer[0] = (byte)(((ushort)closeStatus) >> 8); + statusDescBuffer[1] = (byte)(((ushort)closeStatus) & 0xFF); + if (!string.IsNullOrEmpty (statusDescription)) + Encoding.UTF8.GetBytes (statusDescription, 0, statusDescription.Length, statusDescBuffer, 2); + await SendAsync (new ArraySegment<byte> (statusDescBuffer), WebSocketMessageType.Close, true, cancellationToken).ConfigureAwait (false); } - public override string CloseStatusDescription { - get { - throw new NotImplementedException (); + + int WriteHeader (WebSocketMessageType type, ArraySegment<byte> buffer, bool endOfMessage) + { + var opCode = (byte)type; + var length = buffer.Count; + + headerBuffer[0] = (byte)(opCode | (endOfMessage ? 0 : 0x80)); + if (length < 126) { + headerBuffer[1] = (byte)length; + } else if (length <= ushort.MaxValue) { + headerBuffer[1] = (byte)126; + headerBuffer[2] = (byte)(length / 256); + headerBuffer[3] = (byte)(length % 256); + } else { + headerBuffer[1] = (byte)127; + + int left = length; + int unit = 256; + + for (int i = 9; i > 1; i--) { + headerBuffer[i] = (byte)(left % unit); + left = left / unit; + } } + + var l = Math.Max (0, headerBuffer[1] - 125); + var maskOffset = 2 + l * l * 2; + GenerateMask (headerBuffer, maskOffset); + + // Since we are client only, we always mask the payload + headerBuffer[1] |= 0x80; + + return maskOffset; } - public override WebSocketState State { - get { - throw new NotImplementedException (); - } + + void GenerateMask (byte[] mask, int offset) + { + mask[offset + 0] = (byte)random.Next (0, 255); + mask[offset + 1] = (byte)random.Next (0, 255); + mask[offset + 2] = (byte)random.Next (0, 255); + mask[offset + 3] = (byte)random.Next (0, 255); } - public override string SubProtocol { - get { - throw new NotImplementedException (); - } + + void MaskData (ArraySegment<byte> buffer, int maskOffset) + { + var sendBufferOffset = maskOffset + 4; + for (var i = 0; i < buffer.Count; i++) + sendBuffer[i + sendBufferOffset] = (byte)(buffer.Array[buffer.Offset + i] ^ headerBuffer[maskOffset + (i % 4)]); + } + + void EnsureWebSocketConnected () + { + if (state < WebSocketState.Open) + throw new InvalidOperationException ("The WebSocket is not connected"); + } + + void EnsureWebSocketState (params WebSocketState[] validStates) + { + foreach (var validState in validStates) + if (state == validState) + return; + throw new WebSocketException ("The WebSocket is in an invalid state ('" + state + "') for this operation. Valid states are: " + string.Join (", ", validStates)); + } + + void ValidateArraySegment (ArraySegment<byte> segment) + { + if (segment.Array == null) + throw new ArgumentNullException ("buffer.Array"); + if (segment.Offset < 0) + throw new ArgumentOutOfRangeException ("buffer.Offset"); + if (segment.Offset + segment.Count > segment.Array.Length) + throw new ArgumentOutOfRangeException ("buffer.Count"); } - #endregion } } #endif - diff --git a/mcs/class/System/System.Net.WebSockets/ClientWebSocketOptions.cs b/mcs/class/System/System.Net.WebSockets/ClientWebSocketOptions.cs index a1d617cbad..586752d7f6 100644 --- a/mcs/class/System/System.Net.WebSockets/ClientWebSocketOptions.cs +++ b/mcs/class/System/System.Net.WebSockets/ClientWebSocketOptions.cs @@ -33,11 +33,15 @@ using System.Net; using System.Security.Principal; using System.Security.Cryptography.X509Certificates; using System.Runtime.CompilerServices; +using System.Collections.Generic; namespace System.Net.WebSockets { public sealed class ClientWebSocketOptions { + List<string> subprotocols = new List<string> (); + Dictionary<string, string> customRequestHeaders = new Dictionary<string, string> (); + public X509CertificateCollection ClientCertificates { get; set; } public CookieContainer Cookies { get; set; } @@ -50,28 +54,53 @@ namespace System.Net.WebSockets public bool UseDefaultCredentials { get; set; } - [MonoTODO] + internal IList<string> SubProtocols { + get { + return subprotocols.AsReadOnly (); + } + } + + internal Dictionary<string, string> CustomRequestHeaders { + get { + return customRequestHeaders; + } + } + + internal int ReceiveBufferSize { + get; + private set; + } + + internal ArraySegment<byte> CustomReceiveBuffer { + get; + private set; + } + + internal int SendBufferSize { + get; + private set; + } + public void AddSubProtocol (string subProtocol) { - throw new NotImplementedException (); + subprotocols.Add (subProtocol); } - [MonoTODO] public void SetBuffer (int receiveBufferSize, int sendBufferSize) { - throw new NotImplementedException (); + SetBuffer (receiveBufferSize, sendBufferSize, new ArraySegment<byte> ()); } - [MonoTODO] public void SetBuffer (int receiveBufferSize, int sendBufferSize, ArraySegment<byte> buffer) { - throw new NotImplementedException (); + ReceiveBufferSize = receiveBufferSize; + SendBufferSize = sendBufferSize; + CustomReceiveBuffer = buffer; } - [MonoTODO] public void SetRequestHeader (string headerName, string headerValue) { - throw new NotImplementedException (); + customRequestHeaders[headerName] = headerValue; } } } diff --git a/mcs/class/System/System.Net.WebSockets/WebSocketException.cs b/mcs/class/System/System.Net.WebSockets/WebSocketException.cs index b4980174f6..e617ab38b0 100644 --- a/mcs/class/System/System.Net.WebSockets/WebSocketException.cs +++ b/mcs/class/System/System.Net.WebSockets/WebSocketException.cs @@ -36,72 +36,68 @@ namespace System.Net.WebSockets { public sealed class WebSocketException : Win32Exception { - public WebSocketException () + const string DefaultMessage = "Generic WebSocket exception"; + + public WebSocketException () : this (WebSocketError.Success, -1, DefaultMessage, null) { } - public WebSocketException (int nativeError) : base (nativeError) + public WebSocketException (int nativeError) : this (WebSocketError.Success, nativeError, DefaultMessage, null) { } - public WebSocketException (string message) : base (message) + public WebSocketException (string message) : this (WebSocketError.Success, -1, message, null) { } - public WebSocketException (WebSocketError error) + public WebSocketException (WebSocketError error) : this (error, -1, DefaultMessage, null) { - WebSocketErrorCode = error; } - public WebSocketException (int nativeError, Exception innerException) + public WebSocketException (int nativeError, Exception innerException) : this (WebSocketError.Success, nativeError, DefaultMessage, innerException) { } - public WebSocketException (int nativeError, string message) : base (nativeError, message) + public WebSocketException (int nativeError, string message) : this (WebSocketError.Success, nativeError, message, null) { } - public WebSocketException (string message, Exception innerException) : base (message, innerException) + public WebSocketException (string message, Exception innerException) : this (WebSocketError.Success, -1, message, innerException) { } - public WebSocketException (WebSocketError error, Exception innerException) + public WebSocketException (WebSocketError error, Exception innerException) : this (error, -1, DefaultMessage, innerException) { - WebSocketErrorCode = error; + } - public WebSocketException (WebSocketError error, int nativeError) : base (nativeError) + public WebSocketException (WebSocketError error, int nativeError) : this (error, nativeError, DefaultMessage, null) { - WebSocketErrorCode = error; } - public WebSocketException (WebSocketError error, string message) : base (message) + public WebSocketException (WebSocketError error, string message) : this (error, -1, message, null) { - WebSocketErrorCode = error; } - public WebSocketException (WebSocketError error, int nativeError, Exception innerException) : base (nativeError) + public WebSocketException (WebSocketError error, int nativeError, Exception innerException) : this (error, nativeError, DefaultMessage, innerException) { - WebSocketErrorCode = error; } - public WebSocketException (WebSocketError error, int nativeError, string message) : base (nativeError, message) + public WebSocketException (WebSocketError error, int nativeError, string message) : this (error, nativeError, message, null) { - WebSocketErrorCode = error; } - public WebSocketException (WebSocketError error, string message, Exception innerException) + public WebSocketException (WebSocketError error, string message, Exception innerException) : this (error, -1, message, innerException) { - WebSocketErrorCode = error; } - public WebSocketException (WebSocketError error, int nativeError, string message, Exception innerException) : base (nativeError, message) + public WebSocketException (WebSocketError error, int nativeError, string message, Exception innerException) : base (message, innerException) { WebSocketErrorCode = error; } diff --git a/mcs/class/System/System.Net.WebSockets/WebSocketMessageType.cs b/mcs/class/System/System.Net.WebSockets/WebSocketMessageType.cs index 18e2d9ecbe..50cbc003c0 100644 --- a/mcs/class/System/System.Net.WebSockets/WebSocketMessageType.cs +++ b/mcs/class/System/System.Net.WebSockets/WebSocketMessageType.cs @@ -35,9 +35,9 @@ namespace System.Net.WebSockets { public enum WebSocketMessageType { - Text, - Binary, - Close + Text = 1, + Binary = 2, + Close = 8 } } diff --git a/mcs/class/System/System.Net.WebSockets/WebSocketReceiveResult.cs b/mcs/class/System/System.Net.WebSockets/WebSocketReceiveResult.cs index e237344e46..af97ebcdca 100644 --- a/mcs/class/System/System.Net.WebSockets/WebSocketReceiveResult.cs +++ b/mcs/class/System/System.Net.WebSockets/WebSocketReceiveResult.cs @@ -36,20 +36,22 @@ namespace System.Net.WebSockets { public class WebSocketReceiveResult { - [MonoTODO] public WebSocketReceiveResult (int count, WebSocketMessageType messageType, bool endOfMessage) + : this (count, messageType, endOfMessage, null, null) { - throw new NotImplementedException (); } - [MonoTODO] public WebSocketReceiveResult (int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus? closeStatus, string closeStatusDescription) { - throw new NotImplementedException (); + MessageType = messageType; + CloseStatus = closeStatus; + CloseStatusDescription = closeStatusDescription; + Count = count; + EndOfMessage = endOfMessage; } public WebSocketCloseStatus? CloseStatus { diff --git a/mcs/class/System/System.Net/HttpWebRequest.cs b/mcs/class/System/System.Net/HttpWebRequest.cs index 84d59f6802..1cdffff533 100644 --- a/mcs/class/System/System.Net/HttpWebRequest.cs +++ b/mcs/class/System/System.Net/HttpWebRequest.cs @@ -36,6 +36,7 @@ using System.Collections; using System.Configuration; using System.Globalization; using System.IO; +using System.Net; using System.Net.Cache; using System.Net.Sockets; using System.Runtime.Remoting.Messaging; @@ -950,6 +951,14 @@ namespace System.Net return result.Response; } + +#if NET_3_5 + public Stream EndGetRequestStream (IAsyncResult asyncResult, out TransportContext transportContext) + { + transportContext = null; + return EndGetRequestStream (asyncResult); + } +#endif public override WebResponse GetResponse() { @@ -1071,29 +1080,19 @@ namespace System.Net redirects++; Exception e = null; string uriString = null; - switch (code) { case HttpStatusCode.Ambiguous: // 300 e = new WebException ("Ambiguous redirect."); break; case HttpStatusCode.MovedPermanently: // 301 case HttpStatusCode.Redirect: // 302 - case HttpStatusCode.TemporaryRedirect: // 307 - /* MS follows the redirect for POST too - if (method != "GET" && method != "HEAD") // 10.3 - return false; - */ - - contentLength = -1; - bodyBufferLength = 0; - bodyBuffer = null; - if (code != HttpStatusCode.TemporaryRedirect) + if (method == "POST") method = "GET"; - uriString = webResponse.Headers ["Location"]; + break; + case HttpStatusCode.TemporaryRedirect: // 307 break; case HttpStatusCode.SeeOther: //303 method = "GET"; - uriString = webResponse.Headers ["Location"]; break; case HttpStatusCode.NotModified: // 304 return false; @@ -1109,6 +1108,11 @@ namespace System.Net if (e != null) throw e; + //contentLength = -1; + //bodyBufferLength = 0; + //bodyBuffer = null; + uriString = webResponse.Headers ["Location"]; + if (uriString == null) throw new WebException ("No Location header found for " + (int) code, WebExceptionStatus.ProtocolError); @@ -1163,7 +1167,9 @@ namespace System.Net bool spoint10 = (proto_version == null || proto_version == HttpVersion.Version10); if (keepAlive && (version == HttpVersion.Version10 || spoint10)) { - webHeaders.RemoveAndAdd (connectionHeader, "keep-alive"); + if (webHeaders[connectionHeader] == null + || webHeaders[connectionHeader].IndexOf ("keep-alive", StringComparison.OrdinalIgnoreCase) == -1) + webHeaders.RemoveAndAdd (connectionHeader, "keep-alive"); } else if (!keepAlive && version == HttpVersion.Version11) { webHeaders.RemoveAndAdd (connectionHeader, "close"); } @@ -1605,6 +1611,13 @@ namespace System.Net throw throwMe; } + + internal bool ReuseConnection { + get; + set; + } + + internal WebConnection StoredConnection; } } diff --git a/mcs/class/System/System.Net/HttpWebResponse.cs b/mcs/class/System/System.Net/HttpWebResponse.cs index 0cb3cd8c85..2b756a97bd 100644 --- a/mcs/class/System/System.Net/HttpWebResponse.cs +++ b/mcs/class/System/System.Net/HttpWebResponse.cs @@ -277,7 +277,7 @@ namespace System.Net CheckDisposed (); if (stream == null) return Stream.Null; - if (0 == String.Compare (method, "HEAD", true)) // see par 4.3 & 9.4 + if (string.Equals (method, "HEAD", StringComparison.OrdinalIgnoreCase)) // see par 4.3 & 9.4 return Stream.Null; return stream; @@ -319,7 +319,6 @@ namespace System.Net void IDisposable.Dispose () { Dispose (true); - GC.SuppressFinalize (this); } #if NET_4_0 diff --git a/mcs/class/System/System.Net/IPAddress.cs b/mcs/class/System/System.Net/IPAddress.cs index 2dd7d1ab31..92c0f8e6e0 100644 --- a/mcs/class/System/System.Net/IPAddress.cs +++ b/mcs/class/System/System.Net/IPAddress.cs @@ -333,6 +333,16 @@ namespace System.Net { } } +#if NET_4_0 + public bool IsIPv6Teredo { + get { + return m_Family != AddressFamily.InterNetwork && + NetworkToHostOrder ((short) m_Numbers [0]) == 0x2001 && + m_Numbers[1] == 0; + } + } +#endif + public long ScopeId { get { if (m_Family != AddressFamily.InterNetworkV6) diff --git a/mcs/class/System/System.Net/MacProxy.cs b/mcs/class/System/System.Net/MacProxy.cs index a21cf97c65..1a5e89ec0a 100644 --- a/mcs/class/System/System.Net/MacProxy.cs +++ b/mcs/class/System/System.Net/MacProxy.cs @@ -25,7 +25,9 @@ // using System; +using System.Collections.Generic; using System.Runtime.InteropServices; +using System.Threading; namespace System.Net { @@ -606,13 +608,87 @@ namespace System.Net public const string CFNetworkLibrary = "/System/Library/Frameworks/CFNetwork.framework/CFNetwork"; #endif - [DllImport (CFNetworkLibrary)] - // CFArrayRef CFNetworkCopyProxiesForAutoConfigurationScript (CFStringRef proxyAutoConfigurationScript, CFURLRef targetURL); - extern static IntPtr CFNetworkCopyProxiesForAutoConfigurationScript (IntPtr proxyAutoConfigurationScript, IntPtr targetURL); - + [DllImport (CFNetworkLibrary, EntryPoint = "CFNetworkCopyProxiesForAutoConfigurationScript")] + // CFArrayRef CFNetworkCopyProxiesForAutoConfigurationScript (CFStringRef proxyAutoConfigurationScript, CFURLRef targetURL, CFErrorRef* error); + extern static IntPtr CFNetworkCopyProxiesForAutoConfigurationScriptSequential (IntPtr proxyAutoConfigurationScript, IntPtr targetURL, out IntPtr error); + + class GetProxyData : IDisposable { + public IntPtr script; + public IntPtr targetUri; + public IntPtr error; + public IntPtr result; + public ManualResetEvent evt = new ManualResetEvent (false); + + public void Dispose () + { + evt.Close (); + } + } + + static object lock_obj = new object (); + static Queue<GetProxyData> get_proxy_queue; + static AutoResetEvent proxy_event; + + static void CFNetworkCopyProxiesForAutoConfigurationScriptThread () + { + GetProxyData data; + var data_left = true; + + while (true) { + proxy_event.WaitOne (); + + do { + lock (lock_obj) { + if (get_proxy_queue.Count == 0) + break; + data = get_proxy_queue.Dequeue (); + data_left = get_proxy_queue.Count > 0; + } + + data.result = CFNetworkCopyProxiesForAutoConfigurationScriptSequential (data.script, data.targetUri, out data.error); + data.evt.Set (); + } while (data_left); + } + } + + static IntPtr CFNetworkCopyProxiesForAutoConfigurationScript (IntPtr proxyAutoConfigurationScript, IntPtr targetURL, out IntPtr error) + { + // This method must only be called on only one thread during an application's life time. + // Note that it's not enough to use a lock to make calls sequential across different threads, + // it has to be one thread. Also note that that thread can't be the main thread, because the + // main thread might be blocking waiting for this network request to finish. + // Another possibility would be to use JavaScriptCore to execute this piece of + // javascript ourselves, but unfortunately it's not available before iOS7. + // See bug #7923 comment #21+. + + using (var data = new GetProxyData ()) { + data.script = proxyAutoConfigurationScript; + data.targetUri = targetURL; + + lock (lock_obj) { + if (get_proxy_queue == null) { + get_proxy_queue = new Queue<GetProxyData> (); + proxy_event = new AutoResetEvent (false); + new Thread (CFNetworkCopyProxiesForAutoConfigurationScriptThread) { + IsBackground = true, + }.Start (); + } + get_proxy_queue.Enqueue (data); + proxy_event.Set (); + } + + data.evt.WaitOne (); + + error = data.error; + + return data.result; + } + } + static CFArray CopyProxiesForAutoConfigurationScript (IntPtr proxyAutoConfigurationScript, CFUrl targetURL) { - IntPtr native = CFNetworkCopyProxiesForAutoConfigurationScript (proxyAutoConfigurationScript, targetURL.Handle); + IntPtr err = IntPtr.Zero; + IntPtr native = CFNetworkCopyProxiesForAutoConfigurationScript (proxyAutoConfigurationScript, targetURL.Handle, out err); if (native == IntPtr.Zero) return null; diff --git a/mcs/class/System/System.Net/ServicePointManager.cs b/mcs/class/System/System.Net/ServicePointManager.cs index a6d456293e..27e9893a80 100644 --- a/mcs/class/System/System.Net/ServicePointManager.cs +++ b/mcs/class/System/System.Net/ServicePointManager.cs @@ -326,7 +326,8 @@ namespace System.Net if (address == null) throw new ArgumentNullException ("address"); - RecycleServicePoints (); + if ((servicePoints.Count % 4) == 0) + RecycleServicePoints (); var origAddress = new Uri (address.Scheme + "://" + address.Authority); @@ -346,8 +347,8 @@ namespace System.Net address = new Uri (address.Scheme + "://" + address.Authority); ServicePoint sp = null; + SPKey key = new SPKey (origAddress, usesProxy ? address : null, useConnect); lock (servicePoints) { - SPKey key = new SPKey (origAddress, usesProxy ? address : null, useConnect); sp = servicePoints [key] as ServicePoint; if (sp != null) return sp; diff --git a/mcs/class/System/System.Net/TransportContext.cs b/mcs/class/System/System.Net/TransportContext.cs index 04d534fa13..e0366bb0db 100644 --- a/mcs/class/System/System.Net/TransportContext.cs +++ b/mcs/class/System/System.Net/TransportContext.cs @@ -26,7 +26,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if NET_4_0 +#if NET_3_5 using System.Security.Authentication.ExtendedProtection; diff --git a/mcs/class/System/System.Net/WebConnection.cs b/mcs/class/System/System.Net/WebConnection.cs index 7f09859cb5..7f65751c67 100644 --- a/mcs/class/System/System.Net/WebConnection.cs +++ b/mcs/class/System/System.Net/WebConnection.cs @@ -62,7 +62,7 @@ namespace System.Net { ServicePoint sPoint; Stream nstream; - Socket socket; + internal Socket socket; object socketLock = new object (); WebExceptionStatus status; WaitCallback initConn; @@ -613,16 +613,16 @@ namespace System.Net return (statusCode >= 200 && statusCode != 204 && statusCode != 304); } - internal void GetCertificates () + internal void GetCertificates (Stream stream) { // here the SSL negotiation have been done #if SECURITY_DEP && MONOTOUCH - HttpsClientStream s = (nstream as HttpsClientStream); + HttpsClientStream s = (stream as HttpsClientStream); X509Certificate client = s.SelectedClientCertificate; X509Certificate server = s.ServerCertificate; #else - X509Certificate client = (X509Certificate) piClient.GetValue (nstream, null); - X509Certificate server = (X509Certificate) piServer.GetValue (nstream, null); + X509Certificate client = (X509Certificate) piClient.GetValue (stream, null); + X509Certificate server = (X509Certificate) piServer.GetValue (stream, null); #endif sPoint.SetCertificates (client, server); certsAvailable = (server != null); @@ -750,6 +750,8 @@ namespace System.Net { HttpWebRequest request = (HttpWebRequest) state; request.WebConnection = this; + if (request.ReuseConnection) + request.StoredConnection = this; if (request.Aborted) return; @@ -1142,16 +1144,16 @@ namespace System.Net lock (this) { if (Data.request != request) throw new ObjectDisposedException (typeof (NetworkStream).FullName); - if (nstream == null) - return false; s = nstream; + if (s == null) + return false; } try { s.Write (buffer, offset, size); // here SSL handshake should have been done if (ssl && !certsAvailable) - GetCertificates (); + GetCertificates (s); } catch (Exception e) { err_msg = e.Message; WebExceptionStatus wes = WebExceptionStatus.SendFailure; @@ -1164,10 +1166,10 @@ namespace System.Net // if SSL is in use then check for TrustFailure if (ssl) { #if SECURITY_DEP && MONOTOUCH - HttpsClientStream https = (nstream as HttpsClientStream); + HttpsClientStream https = (s as HttpsClientStream); if (https.TrustFailure) { #else - if ((bool) piTrustFailure.GetValue (nstream, null)) { + if ((bool) piTrustFailure.GetValue (s , null)) { #endif wes = WebExceptionStatus.TrustFailure; msg = "Trust failure"; @@ -1183,6 +1185,11 @@ namespace System.Net internal void Close (bool sendNext) { lock (this) { + if (Data != null && Data.request != null && Data.request.ReuseConnection) { + Data.request.ReuseConnection = false; + return; + } + if (nstream != null) { try { nstream.Close (); diff --git a/mcs/class/System/System.Security.Cryptography.X509Certificates/X509Certificate2.cs b/mcs/class/System/System.Security.Cryptography.X509Certificates/X509Certificate2.cs index 300e1140e1..4559687a7f 100644 --- a/mcs/class/System/System.Security.Cryptography.X509Certificates/X509Certificate2.cs +++ b/mcs/class/System/System.Security.Cryptography.X509Certificates/X509Certificate2.cs @@ -426,17 +426,34 @@ namespace System.Security.Cryptography.X509Certificates { } } - private void ImportPkcs12 (byte[] rawData, string password) + private MX.X509Certificate ImportPkcs12 (byte[] rawData, string password) { MX.PKCS12 pfx = (password == null) ? new MX.PKCS12 (rawData) : new MX.PKCS12 (rawData, password); - if (pfx.Certificates.Count > 0) { - _cert = pfx.Certificates [0]; + if (pfx.Certificates.Count == 0) { + // no certificate was found + return null; + } else if (pfx.Keys.Count == 0) { + // no key were found - pick the first certificate + return pfx.Certificates [0]; } else { - _cert = null; - } - if (pfx.Keys.Count > 0) { - _cert.RSA = (pfx.Keys [0] as RSA); - _cert.DSA = (pfx.Keys [0] as DSA); + // find the certificate that match the first key + MX.X509Certificate cert = null; + var keypair = (pfx.Keys [0] as AsymmetricAlgorithm); + string pubkey = keypair.ToXmlString (false); + foreach (var c in pfx.Certificates) { + if (((c.RSA != null) && (pubkey == c.RSA.ToXmlString (false))) || + ((c.DSA != null) && (pubkey == c.DSA.ToXmlString (false)))) { + cert = c; + break; + } + } + if (cert == null) { + cert = pfx.Certificates [0]; // no match, pick first certificate without keys + } else { + cert.RSA = (keypair as RSA); + cert.DSA = (keypair as DSA); + } + return cert; } } @@ -448,14 +465,14 @@ namespace System.Security.Cryptography.X509Certificates { [MonoTODO ("missing KeyStorageFlags support")] public override void Import (byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags) { - base.Import (rawData, password, keyStorageFlags); + MX.X509Certificate cert = null; if (password == null) { try { - _cert = new MX.X509Certificate (rawData); + cert = new MX.X509Certificate (rawData); } catch (Exception e) { try { - ImportPkcs12 (rawData, null); + cert = ImportPkcs12 (rawData, null); } catch { string msg = Locale.GetText ("Unable to decode certificate."); @@ -466,14 +483,19 @@ namespace System.Security.Cryptography.X509Certificates { } else { // try PKCS#12 try { - ImportPkcs12 (rawData, password); + cert = ImportPkcs12 (rawData, password); } catch { // it's possible to supply a (unrequired/unusued) password // fix bug #79028 - _cert = new MX.X509Certificate (rawData); + cert = new MX.X509Certificate (rawData); } } + // we do not have to fully re-decode the certificate since X509Certificate does not deal with keys + if (cert != null) { + base.Import (cert.RawData, (string) null, keyStorageFlags); + _cert = cert; // becuase base call will call Reset! + } } [MonoTODO ("SecureString is incomplete")] @@ -484,35 +506,24 @@ namespace System.Security.Cryptography.X509Certificates { public override void Import (string fileName) { - byte[] rawData = Load (fileName); + byte[] rawData = File.ReadAllBytes (fileName); Import (rawData, (string)null, X509KeyStorageFlags.DefaultKeySet); } [MonoTODO ("missing KeyStorageFlags support")] public override void Import (string fileName, string password, X509KeyStorageFlags keyStorageFlags) { - byte[] rawData = Load (fileName); + byte[] rawData = File.ReadAllBytes (fileName); Import (rawData, password, keyStorageFlags); } [MonoTODO ("SecureString is incomplete")] public override void Import (string fileName, SecureString password, X509KeyStorageFlags keyStorageFlags) { - byte[] rawData = Load (fileName); + byte[] rawData = File.ReadAllBytes (fileName); Import (rawData, (string)null, keyStorageFlags); } - private static byte[] Load (string fileName) - { - byte[] data = null; - using (FileStream fs = File.OpenRead (fileName)) { - data = new byte [fs.Length]; - fs.Read (data, 0, data.Length); - fs.Close (); - } - return data; - } - public override void Reset () { _cert = null; @@ -654,7 +665,7 @@ namespace System.Security.Cryptography.X509Certificates { if (fileName.Length == 0) throw new ArgumentException ("fileName"); - byte[] data = Load (fileName); + byte[] data = File.ReadAllBytes (fileName); return GetCertContentType (data); } diff --git a/mcs/class/System/System.Timers/Timer.cs b/mcs/class/System/System.Timers/Timer.cs index d35ee4e0eb..28a7011bb5 100644 --- a/mcs/class/System/System.Timers/Timer.cs +++ b/mcs/class/System/System.Timers/Timer.cs @@ -159,7 +159,13 @@ namespace System.Timers protected override void Dispose (bool disposing) { - Close (); + // If we're disposing explicitly, clear all + // fields. If not, all fields will have been + // nulled by the GC during finalization, so + // trying to lock on _lock will blow up. + if (disposing) + Close (); + base.Dispose (disposing); } diff --git a/mcs/class/System/System.Windows.Input/ICommand.cs b/mcs/class/System/System.Windows.Input/ICommand.cs index c15af7e2d9..7cb430fef6 100644 --- a/mcs/class/System/System.Windows.Input/ICommand.cs +++ b/mcs/class/System/System.Windows.Input/ICommand.cs @@ -27,11 +27,15 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if NET_4_0 +#if NET_4_5 + +using System.Runtime.CompilerServices; namespace System.Windows.Input { - public interface ICommand { + [TypeForwardedFrom (Consts.AssemblyPresentationCore_4_0)] + public interface ICommand + { bool CanExecute (object parameter); void Execute (object parameter); event EventHandler CanExecuteChanged; diff --git a/mcs/class/System/System_test.dll.sources b/mcs/class/System/System_test.dll.sources index a306d52be4..33f8326b2d 100644 --- a/mcs/class/System/System_test.dll.sources +++ b/mcs/class/System/System_test.dll.sources @@ -499,3 +499,4 @@ System.Collections.Concurrent/BlockingCollectionTests.cs System.Collections.Concurrent/ConcurrentBagTests.cs System.Collections.Concurrent/CollectionStressTestHelper.cs System.Collections.Concurrent/ParallelTestHelper.cs +System.Net.WebSockets/ClientWebSocketTest.cs diff --git a/mcs/class/System/Test/Microsoft.CSharp/CSharpCodeProviderTest.cs b/mcs/class/System/Test/Microsoft.CSharp/CSharpCodeProviderTest.cs index f34bcca6d6..fe60d4e5a8 100644 --- a/mcs/class/System/Test/Microsoft.CSharp/CSharpCodeProviderTest.cs +++ b/mcs/class/System/Test/Microsoft.CSharp/CSharpCodeProviderTest.cs @@ -360,6 +360,49 @@ namespace MonoTests.Microsoft.CSharp } [Test] + public void CompileFromSource_InMemory_Twice () + { + CompilerParameters options = new CompilerParameters (); + options.GenerateExecutable = false; + options.GenerateInMemory = true; + + ICodeCompiler compiler = _codeProvider.CreateCompiler (); + + var src_1 = "class X { "; + + CompilerResults results_1 = compiler.CompileAssemblyFromSource (options, src_1); + var output_1 = options.OutputAssembly; + + var src_2 = "class X { }"; + + CompilerResults results_2 = compiler.CompileAssemblyFromSource (options, src_2); + var output_2 = options.OutputAssembly; + + // verify compilation was successful + AssertCompileResults (results_2, true); + + Assert.AreEqual (output_1, output_2, "#1"); + } + + + [Test] + public void CompileFromSource_InMemory_With_Extra_Delete () + { + CompilerParameters options = new CompilerParameters (); + options.GenerateExecutable = false; + options.GenerateInMemory = true; + + ICodeCompiler compiler = _codeProvider.CreateCompiler (); + + var src_1 = "class X { "; + + compiler.CompileAssemblyFromSource (options, src_1); + + options.TempFiles.Delete (); + options.TempFiles.Delete (); + } + + [Test] public void CompileFromSourceBatch_InMemory () { // create a file in temp directory to ensure that compiler is not removing diff --git a/mcs/class/System/Test/System.Collections.Concurrent/BlockingCollectionTests.cs b/mcs/class/System/Test/System.Collections.Concurrent/BlockingCollectionTests.cs index 0098e2de92..9f0e9b0190 100644 --- a/mcs/class/System/Test/System.Collections.Concurrent/BlockingCollectionTests.cs +++ b/mcs/class/System/Test/System.Collections.Concurrent/BlockingCollectionTests.cs @@ -27,6 +27,7 @@ using System; using System.Threading; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Threading.Tasks; using NUnit.Framework; @@ -192,6 +193,60 @@ namespace MonoTests.System.Collections.Concurrent Assert.IsNull (o); Assert.IsFalse (success); } + + [Test] + public void TakeAnyFromSecondCollection () + { + var a = new BlockingCollection<string> (); + var b = new BlockingCollection<string> (); + var arr = new [] { a, b }; + string res = null; + + Task<int> t = Task.Factory.StartNew (() => BlockingCollection<string>.TakeFromAny (arr, out res)); + a.Add ("foo"); + Assert.AreEqual (0, t.Result, "#1"); + Assert.AreEqual ("foo", res, "#2"); + + t = Task.Factory.StartNew (() => BlockingCollection<string>.TakeFromAny (arr, out res)); + b.Add ("bar"); + Assert.AreEqual (1, t.Result, "#3"); + Assert.AreEqual ("bar", res, "#4"); + } + + [Test] + public void TakeAnyCancellable () + { + var a = new BlockingCollection<string> (); + var b = new BlockingCollection<string> (); + var arr = new [] { a, b }; + var cts = new CancellationTokenSource (); + string res = null; + + Task<int> t = Task.Factory.StartNew (() => BlockingCollection<string>.TakeFromAny (arr, out res, cts.Token)); + Thread.Sleep (100); + a.Add ("foo"); + Assert.AreEqual (0, t.Result, "#1"); + Assert.AreEqual ("foo", res, "#2"); + + t = Task.Factory.StartNew (() => BlockingCollection<string>.TakeFromAny (arr, out res, cts.Token)); + Thread.Sleep (100); + b.Add ("bar"); + Assert.AreEqual (1, t.Result, "#3"); + Assert.AreEqual ("bar", res, "#4"); + + t = Task.Factory.StartNew (() => { + try { + return BlockingCollection<string>.TakeFromAny (arr, out res, cts.Token); + } catch (OperationCanceledException WE_GOT_CANCELED) { + res = "canceled"; + return -10; + } + }); + + cts.Cancel (); + Assert.AreEqual (-10, t.Result, "#5"); + Assert.AreEqual ("canceled", res, "#6"); + } } } #endif diff --git a/mcs/class/System/Test/System.Collections.Concurrent/ConcurrentBagTests.cs b/mcs/class/System/Test/System.Collections.Concurrent/ConcurrentBagTests.cs index 1262cc3947..b7bc6b5b7e 100644 --- a/mcs/class/System/Test/System.Collections.Concurrent/ConcurrentBagTests.cs +++ b/mcs/class/System/Test/System.Collections.Concurrent/ConcurrentBagTests.cs @@ -191,6 +191,50 @@ namespace MonoTests.System.Collections.Concurrent Assert.IsTrue (valid, "Aggregate test"); } + + [Test] + public void BasicRemoveEmptyTest () + { + int result; + Assert.IsTrue(bag.IsEmpty); + Assert.IsFalse(bag.TryTake(out result)); + } + + [Test] + public void BasicRemoveTwiceTest() + { + bag.Add (1); + Assert.IsFalse (bag.IsEmpty); + Assert.AreEqual (1, bag.Count); + + int result; + Assert.IsTrue (bag.TryTake (out result)); + Assert.AreEqual (1, result); + Assert.IsTrue (bag.IsEmpty); + Assert.IsFalse (bag.TryTake (out result)); + Assert.IsFalse (bag.TryTake (out result)); + } + + [Test] + public void AddRemoveAddTest() + { + bag.Add (1); + Assert.IsFalse (bag.IsEmpty); + Assert.AreEqual (1, bag.Count); + + int result; + Assert.IsTrue (bag.TryTake (out result)); + Assert.AreEqual (1, result); + Assert.IsTrue (bag.IsEmpty); + + bag.Add (1); + Assert.IsFalse (bag.IsEmpty); + Assert.AreEqual (1, bag.Count); + + Assert.IsTrue (bag.TryTake (out result)); + Assert.AreEqual (1, result); + Assert.IsTrue (bag.IsEmpty); + } [Test] public void AddStressTest () diff --git a/mcs/class/System/Test/System.ComponentModel/BindingListTest.cs b/mcs/class/System/Test/System.ComponentModel/BindingListTest.cs index 88be568f42..92a6253db9 100644 --- a/mcs/class/System/Test/System.ComponentModel/BindingListTest.cs +++ b/mcs/class/System/Test/System.ComponentModel/BindingListTest.cs @@ -629,6 +629,16 @@ namespace MonoTests.System.ComponentModel Assert.IsTrue (added, "ItemAdded"); Assert.IsTrue (changed, "ItemChanged"); } + + [Test] // https://bugzilla.xamarin.com/show_bug.cgi?id=16902 + public void Bug16902 () + { + var list = new BindingList<Item> (); + list.Insert (0, null); + var count = list.Count; + + Assert.AreEqual (1, count, "1"); + } } } diff --git a/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs b/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs index 6f0e4cf3ee..4bd26f9fae 100644..100755 --- a/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs +++ b/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs @@ -4144,6 +4144,54 @@ namespace MonoTests.System.Net.Sockets } [Test] + public void SetSocketOption_MulticastInterfaceIndex_Any () + { + IPAddress ip = IPAddress.Parse ("239.255.255.250"); + int index = 0; + using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) + { + s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, IPAddress.HostToNetworkOrder(index)); + s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ip, index)); + } + } + + [Test] + public void SetSocketOption_MulticastInterfaceIndex_Loopback () + { + IPAddress ip = IPAddress.Parse ("239.255.255.250"); + int index = 1; + using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) + { + s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, IPAddress.HostToNetworkOrder(index)); + s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ip, index)); + } + } + + [Test] + public void SetSocketOption_MulticastInterfaceIndex_Invalid () + { + IPAddress ip = IPAddress.Parse ("239.255.255.250"); + int index = 31415; + using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) + { + try + { + s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, IPAddress.HostToNetworkOrder(index)); + Assert.Fail ("#1"); + } + catch + {} + try + { + s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ip, index)); + Assert.Fail ("#2"); + } + catch + {} + } + } + + [Test] public void Shutdown_NoConnect () { Socket s = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); diff --git a/mcs/class/System/Test/System.Net.Sockets/UdpClientTest.cs b/mcs/class/System/Test/System.Net.Sockets/UdpClientTest.cs index 6fa403c607..710b4982c1 100644 --- a/mcs/class/System/Test/System.Net.Sockets/UdpClientTest.cs +++ b/mcs/class/System/Test/System.Net.Sockets/UdpClientTest.cs @@ -1051,16 +1051,21 @@ namespace MonoTests.System.Net.Sockets { [Test] public void Available () { - UdpClient client = new UdpClient (1238); - IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 1238); - byte[] bytes = new byte[] {10, 11, 12, 13}; - - client.Send (bytes, bytes.Length, ep); - int avail = client.Available; - - Assert.AreEqual (bytes.Length, avail, "Available #1"); + using (UdpClient client = new UdpClient (1238)) { + IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 1238); + byte[] bytes = new byte[] {10, 11, 12, 13}; + + int res = client.Send (bytes, bytes.Length, ep); + Assert.AreEqual (bytes.Length, res, "Send"); + + // that might happen too quickly, data sent and not yet received/available + Thread.Sleep (100); + int avail = client.Available; + + Assert.AreEqual (bytes.Length, avail, "Available #1"); - client.Close (); + client.Close (); + } } [Test] diff --git a/mcs/class/System/Test/System.Net.WebSockets/ClientWebSocketTest.cs b/mcs/class/System/Test/System.Net.WebSockets/ClientWebSocketTest.cs new file mode 100644 index 0000000000..3666003a3f --- /dev/null +++ b/mcs/class/System/Test/System.Net.WebSockets/ClientWebSocketTest.cs @@ -0,0 +1,242 @@ +#if NET_4_5 && !MOBILE +using System; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Net.WebSockets; +using System.Reflection; +using System.Text; + +using NUnit.Framework; + + +namespace MonoTests.System.Net.WebSockets +{ + [TestFixture] + public class ClientWebSocketTest + { + const string EchoServerUrl = "ws://echo.websocket.org"; + const int Port = 42123; + HttpListener listener; + ClientWebSocket socket; + MethodInfo headerSetMethod; + + [SetUp] + public void Setup () + { + listener = new HttpListener (); + listener.Prefixes.Add ("http://localhost:" + Port + "/"); + listener.Start (); + socket = new ClientWebSocket (); + } + + [TearDown] + public void Teardown () + { + if (listener != null) { + listener.Stop (); + listener = null; + } + if (socket != null) { + if (socket.State == WebSocketState.Open) + socket.CloseAsync (WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait (); + socket.Dispose (); + socket = null; + } + } + + [Test] + public void ServerHandshakeReturnCrapStatusCodeTest () + { + HandleHttpRequestAsync ((req, resp) => resp.StatusCode = 418); + try { + socket.ConnectAsync (new Uri ("ws://localhost:" + Port), CancellationToken.None).Wait (); + } catch (AggregateException e) { + AssertWebSocketException (e, WebSocketError.Success, typeof (WebException)); + return; + } + Assert.Fail ("Should have thrown"); + } + + [Test] + public void ServerHandshakeReturnWrongUpgradeHeader () + { + HandleHttpRequestAsync ((req, resp) => { + resp.StatusCode = 101; + resp.Headers["Upgrade"] = "gtfo"; + }); + try { + socket.ConnectAsync (new Uri ("ws://localhost:" + Port), CancellationToken.None).Wait (); + } catch (AggregateException e) { + AssertWebSocketException (e, WebSocketError.Success); + return; + } + Assert.Fail ("Should have thrown"); + } + + [Test] + public void ServerHandshakeReturnWrongConnectionHeader () + { + HandleHttpRequestAsync ((req, resp) => { + resp.StatusCode = 101; + resp.Headers["Upgrade"] = "websocket"; + // Mono http request doesn't like the forcing, test still valid since the default connection header value is empty + //ForceSetHeader (resp.Headers, "Connection", "Foo"); + }); + try { + socket.ConnectAsync (new Uri ("ws://localhost:" + Port), CancellationToken.None).Wait (); + } catch (AggregateException e) { + AssertWebSocketException (e, WebSocketError.Success); + return; + } + Assert.Fail ("Should have thrown"); + } + + [Test] + public void EchoTest () + { + const string Payload = "This is a websocket test"; + + Assert.AreEqual (WebSocketState.None, socket.State); + socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (); + Assert.AreEqual (WebSocketState.Open, socket.State); + + var sendBuffer = Encoding.ASCII.GetBytes (Payload); + socket.SendAsync (new ArraySegment<byte> (sendBuffer), WebSocketMessageType.Text, true, CancellationToken.None).Wait (); + + var receiveBuffer = new byte[Payload.Length]; + var resp = socket.ReceiveAsync (new ArraySegment<byte> (receiveBuffer), CancellationToken.None).Result; + + Assert.AreEqual (Payload.Length, resp.Count); + Assert.IsTrue (resp.EndOfMessage); + Assert.AreEqual (WebSocketMessageType.Text, resp.MessageType); + Assert.AreEqual (Payload, Encoding.ASCII.GetString (receiveBuffer, 0, resp.Count)); + + socket.CloseAsync (WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait (); + Assert.AreEqual (WebSocketState.Closed, socket.State); + } + + [Test] + public void CloseOutputAsyncTest () + { + socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (); + Assert.AreEqual (WebSocketState.Open, socket.State); + + socket.CloseOutputAsync (WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait (); + Assert.AreEqual (WebSocketState.CloseSent, socket.State); + + var resp = socket.ReceiveAsync (new ArraySegment<byte> (new byte[0]), CancellationToken.None).Result; + Assert.AreEqual (WebSocketState.Closed, socket.State); + Assert.AreEqual (WebSocketMessageType.Close, resp.MessageType); + Assert.AreEqual (WebSocketCloseStatus.NormalClosure, resp.CloseStatus); + Assert.AreEqual (string.Empty, resp.CloseStatusDescription); + } + + [Test] + public void CloseAsyncTest () + { + socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (); + Assert.AreEqual (WebSocketState.Open, socket.State); + + socket.CloseAsync (WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait (); + Assert.AreEqual (WebSocketState.Closed, socket.State); + } + + [Test, ExpectedException (typeof (InvalidOperationException))] + public void SendAsyncArgTest_NotConnected () + { + socket.SendAsync (new ArraySegment<byte> (new byte[0]), WebSocketMessageType.Text, true, CancellationToken.None); + } + + [Test, ExpectedException (typeof (ArgumentNullException))] + public void SendAsyncArgTest_NoArray () + { + socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (); + socket.SendAsync (new ArraySegment<byte> (), WebSocketMessageType.Text, true, CancellationToken.None); + } + + [Test, ExpectedException (typeof (InvalidOperationException))] + public void ReceiveAsyncArgTest_NotConnected () + { + socket.ReceiveAsync (new ArraySegment<byte> (new byte[0]), CancellationToken.None); + } + + [Test, ExpectedException (typeof (ArgumentNullException))] + public void ReceiveAsyncArgTest_NoArray () + { + socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (); + socket.ReceiveAsync (new ArraySegment<byte> (), CancellationToken.None); + } + + [Test] + public void ReceiveAsyncWrongState_Closed () + { + try { + socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (); + socket.CloseAsync (WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait (); + socket.ReceiveAsync (new ArraySegment<byte> (new byte[0]), CancellationToken.None).Wait (); + } catch (AggregateException e) { + AssertWebSocketException (e, WebSocketError.Success); + return; + } + Assert.Fail ("Should have thrown"); + } + + [Test] + public void SendAsyncWrongState_Closed () + { + try { + socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (); + socket.CloseAsync (WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait (); + socket.SendAsync (new ArraySegment<byte> (new byte[0]), WebSocketMessageType.Text, true, CancellationToken.None).Wait (); + } catch (AggregateException e) { + AssertWebSocketException (e, WebSocketError.Success); + return; + } + Assert.Fail ("Should have thrown"); + } + + [Test] + public void SendAsyncWrongState_CloseSent () + { + try { + socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (); + socket.CloseOutputAsync (WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait (); + socket.SendAsync (new ArraySegment<byte> (new byte[0]), WebSocketMessageType.Text, true, CancellationToken.None).Wait (); + } catch (AggregateException e) { + AssertWebSocketException (e, WebSocketError.Success); + return; + } + Assert.Fail ("Should have thrown"); + } + + async Task HandleHttpRequestAsync (Action<HttpListenerRequest, HttpListenerResponse> handler) + { + var ctx = await listener.GetContextAsync (); + handler (ctx.Request, ctx.Response); + ctx.Response.Close (); + } + + void AssertWebSocketException (AggregateException e, WebSocketError error, Type inner = null) + { + var wsEx = e.InnerException as WebSocketException; + Console.WriteLine (e.InnerException.ToString ()); + Assert.IsNotNull (wsEx, "Not a websocketexception"); + Assert.AreEqual (error, wsEx.WebSocketErrorCode); + if (inner != null) { + Assert.IsNotNull (wsEx.InnerException); + Assert.IsInstanceOfType (inner, wsEx.InnerException); + } + } + + void ForceSetHeader (WebHeaderCollection headers, string name, string value) + { + if (headerSetMethod == null) + headerSetMethod = typeof (WebHeaderCollection).GetMethod ("AddValue", BindingFlags.NonPublic); + headerSetMethod.Invoke (headers, new[] { name, value }); + } + } +} + +#endif diff --git a/mcs/class/System/Test/System.Net/IPAddressTest.cs b/mcs/class/System/Test/System.Net/IPAddressTest.cs index 965b1cd44a..a07c1a19d9 100644 --- a/mcs/class/System/Test/System.Net/IPAddressTest.cs +++ b/mcs/class/System/Test/System.Net/IPAddressTest.cs @@ -545,6 +545,15 @@ public class IPAddressTest Assert.IsTrue (IPAddress.Parse ("FF01::1").IsIPv6Multicast, "#2"); Assert.IsFalse (IPAddress.Parse ("FE00::1").IsIPv6Multicast, "#3"); } + +#if NET_4_0 + [Test] + public void IsIPv6Teredo () + { + Assert.IsTrue (IPAddress.Parse ("2001::1").IsIPv6Teredo, "#1"); + Assert.IsFalse (IPAddress.Parse ("2002::1").IsIPv6Teredo, "#2"); + } +#endif } } diff --git a/mcs/class/System/mobile_System.dll.sources b/mcs/class/System/mobile_System.dll.sources index 8b5c746266..f5ffb4ac71 100644 --- a/mcs/class/System/mobile_System.dll.sources +++ b/mcs/class/System/mobile_System.dll.sources @@ -20,6 +20,8 @@ System.Collections.Specialized/HybridDictionary.cs System.Collections.Specialized/ListDictionary.cs System.Collections.Specialized/NameObjectCollectionBase.cs System.Collections.Specialized/NameValueCollection.cs +System.Collections.Specialized/IOrderedDictionary.cs +System.Collections.Specialized/OrderedDictionary.cs System.Collections.Specialized/ProcessStringDictionary.cs System.Collections.Specialized/StringCollection.cs System.Collections.Specialized/StringDictionary.cs @@ -28,7 +30,28 @@ System.Collections.Specialized/INotifyCollectionChanged.cs System.Collections.Specialized/NotifyCollectionChangedEventArgs.cs System.Collections.Specialized/NotifyCollectionChangedAction.cs System.Collections.Specialized/NotifyCollectionChangedEventHandler.cs +System.ComponentModel.Design.Serialization/ComponentSerializationService.cs +System.ComponentModel.Design.Serialization/ContextStack.cs +System.ComponentModel.Design.Serialization/DefaultSerializationProviderAttribute.cs +System.ComponentModel.Design.Serialization/DesignerLoader.cs +System.ComponentModel.Design.Serialization/DesignerSerializerAttribute.cs +System.ComponentModel.Design.Serialization/IDesignerLoaderHost.cs +System.ComponentModel.Design.Serialization/IDesignerLoaderHost2.cs +System.ComponentModel.Design.Serialization/IDesignerLoaderService.cs +System.ComponentModel.Design.Serialization/IDesignerSerializationManager.cs +System.ComponentModel.Design.Serialization/IDesignerSerializationProvider.cs +System.ComponentModel.Design.Serialization/IDesignerSerializationService.cs +System.ComponentModel.Design.Serialization/INameCreationService.cs System.ComponentModel.Design.Serialization/InstanceDescriptor.cs +System.ComponentModel.Design.Serialization/MemberRelationship.cs +System.ComponentModel.Design.Serialization/MemberRelationshipService.cs +System.ComponentModel.Design.Serialization/ResolveNameEventArgs.cs +System.ComponentModel.Design.Serialization/ResolveNameEventHandler.cs +System.ComponentModel.Design.Serialization/RootDesignerSerializerAttribute.cs +System.ComponentModel.Design.Serialization/SerializationStore.cs +System.ComponentModel.Design/ActiveDesignerEventArgs.cs +System.ComponentModel.Design/ActiveDesignerEventHandler.cs +System.ComponentModel.Design/CheckoutException.cs System.ComponentModel.Design/CommandID.cs System.ComponentModel.Design/ComponentChangedEventArgs.cs System.ComponentModel.Design/ComponentChangedEventHandler.cs @@ -38,31 +61,61 @@ System.ComponentModel.Design/ComponentEventArgs.cs System.ComponentModel.Design/ComponentEventHandler.cs System.ComponentModel.Design/ComponentRenameEventArgs.cs System.ComponentModel.Design/ComponentRenameEventHandler.cs +System.ComponentModel.Design/DesignerCollection.cs +System.ComponentModel.Design/DesignerEventArgs.cs +System.ComponentModel.Design/DesignerEventHandler.cs +System.ComponentModel.Design/DesignerOptionService.cs System.ComponentModel.Design/DesignerTransaction.cs System.ComponentModel.Design/DesignerTransactionCloseEventArgs.cs System.ComponentModel.Design/DesignerTransactionCloseEventHandler.cs System.ComponentModel.Design/DesignerVerb.cs System.ComponentModel.Design/DesignerVerbCollection.cs +System.ComponentModel.Design/HelpContextType.cs +System.ComponentModel.Design/HelpKeywordAttribute.cs +System.ComponentModel.Design/HelpKeywordType.cs System.ComponentModel.Design/IComponentChangeService.cs +System.ComponentModel.Design/IComponentDiscoveryService.cs +System.ComponentModel.Design/IComponentInitializer.cs System.ComponentModel.Design/IDesigner.cs +System.ComponentModel.Design/IDesignerEventService.cs +System.ComponentModel.Design/IDesignerFilter.cs System.ComponentModel.Design/IDesignerHost.cs +System.ComponentModel.Design/IDesignerHostTransactionState.cs +System.ComponentModel.Design/IDesignerOptionService.cs +System.ComponentModel.Design/IDictionaryService.cs +System.ComponentModel.Design/IEventBindingService.cs +System.ComponentModel.Design/IExtenderListService.cs +System.ComponentModel.Design/IExtenderProviderService.cs +System.ComponentModel.Design/IHelpService.cs +System.ComponentModel.Design/IInheritanceService.cs +System.ComponentModel.Design/IMenuCommandService.cs System.ComponentModel.Design/IReferenceService.cs +System.ComponentModel.Design/IResourceService.cs System.ComponentModel.Design/IRootDesigner.cs +System.ComponentModel.Design/ISelectionService.cs System.ComponentModel.Design/IServiceContainer.cs +System.ComponentModel.Design/ITreeDesigner.cs System.ComponentModel.Design/ITypeDescriptorFilterService.cs +System.ComponentModel.Design/ITypeDiscoveryService.cs System.ComponentModel.Design/ITypeResolutionService.cs System.ComponentModel.Design/MenuCommand.cs +System.ComponentModel.Design/SelectionTypes.cs +System.ComponentModel.Design/ServiceContainer.cs System.ComponentModel.Design/ServiceCreatorCallback.cs System.ComponentModel.Design/StandardCommands.cs +System.ComponentModel.Design/StandardToolWindows.cs +System.ComponentModel.Design/TypeDescriptionProviderService.cs System.ComponentModel.Design/ViewTechnology.cs System.ComponentModel/AddingNewEventArgs.cs System.ComponentModel/AddingNewEventHandler.cs +System.ComponentModel/AmbientValueAttribute.cs System.ComponentModel/ArrayConverter.cs System.ComponentModel/AsyncCompletedEventArgs.cs System.ComponentModel/AsyncCompletedEventHandler.cs System.ComponentModel/AsyncOperation.cs System.ComponentModel/AsyncOperationManager.cs System.ComponentModel/AttributeCollection.cs +System.ComponentModel/AttributeProviderAttribute.cs System.ComponentModel/BackgroundWorker.cs System.ComponentModel/BaseNumberConverter.cs System.ComponentModel/BindableAttribute.cs @@ -73,20 +126,32 @@ System.ComponentModel/BooleanConverter.cs System.ComponentModel/BrowsableAttribute.cs System.ComponentModel/ByteConverter.cs System.ComponentModel/CancelEventArgs.cs +System.ComponentModel/CancelEventHandler.cs System.ComponentModel/CategoryAttribute.cs System.ComponentModel/CharConverter.cs System.ComponentModel/CollectionChangeAction.cs System.ComponentModel/CollectionChangeEventArgs.cs System.ComponentModel/CollectionChangeEventHandler.cs System.ComponentModel/CollectionConverter.cs +System.ComponentModel/ComplexBindingPropertiesAttribute.cs System.ComponentModel/Component.cs System.ComponentModel/ComponentCollection.cs System.ComponentModel/ComponentConverter.cs +System.ComponentModel/ComponentEditor.cs +System.ComponentModel/ComponentResourceManager.cs +System.ComponentModel/Container.cs +System.ComponentModel/ContainerFilterService.cs System.ComponentModel/CultureInfoConverter.cs System.ComponentModel/CustomTypeDescriptor.cs System.ComponentModel/DataErrorsChangedEventArgs.cs +System.ComponentModel/DataObjectAttribute.cs +System.ComponentModel/DataObjectFieldAttribute.cs +System.ComponentModel/DataObjectMethodAttribute.cs +System.ComponentModel/DataObjectMethodType.cs System.ComponentModel/DateTimeConverter.cs +System.ComponentModel/DateTimeOffsetConverter.cs System.ComponentModel/DecimalConverter.cs +System.ComponentModel/DefaultBindingPropertyAttribute.cs System.ComponentModel/DefaultEventAttribute.cs System.ComponentModel/DefaultPropertyAttribute.cs System.ComponentModel/DefaultValueAttribute.cs @@ -109,24 +174,35 @@ System.ComponentModel/EventDescriptor.cs System.ComponentModel/EventDescriptorCollection.cs System.ComponentModel/EventHandlerList.cs System.ComponentModel/ExpandableObjectConverter.cs +System.ComponentModel/ExtenderProvidedPropertyAttribute.cs System.ComponentModel/GuidConverter.cs +System.ComponentModel/HandledEventArgs.cs +System.ComponentModel/HandledEventHandler.cs System.ComponentModel/IBindingList.cs System.ComponentModel/IBindingListView.cs System.ComponentModel/ICancelAddNew.cs System.ComponentModel/IChangeTracking.cs System.ComponentModel/IComNativeDescriptorHandler.cs System.ComponentModel/IComponent.cs -System.ComponentModel/IComponent.cs System.ComponentModel/IContainer.cs System.ComponentModel/ICustomTypeDescriptor.cs System.ComponentModel/IDataErrorInfo.cs -System.ComponentModel/IDataErrorInfo.cs System.ComponentModel/IEditableObject.cs System.ComponentModel/IExtenderProvider.cs +System.ComponentModel/IIntellisenseBuilder.cs System.ComponentModel/IListSource.cs +System.ComponentModel/ImmutableObjectAttribute.cs +System.ComponentModel/INestedContainer.cs +System.ComponentModel/INestedSite.cs +System.ComponentModel/InheritanceAttribute.cs +System.ComponentModel/InheritanceLevel.cs +System.ComponentModel/InitializationEventAttribute.cs System.ComponentModel/INotifyDataErrorInfo.cs System.ComponentModel/INotifyPropertyChanged.cs System.ComponentModel/INotifyPropertyChanging.cs +System.ComponentModel/InstallerTypeAttribute.cs +System.ComponentModel/InstanceCreationEditor.cs +System.ComponentModel/InvalidAsynchronousStateException.cs System.ComponentModel/IRaiseItemChangedEvents.cs System.ComponentModel/IRevertibleChangeTracking.cs System.ComponentModel/ISite.cs @@ -139,7 +215,6 @@ System.ComponentModel/Int16Converter.cs System.ComponentModel/Int32Converter.cs System.ComponentModel/Int64Converter.cs System.ComponentModel/InvalidEnumArgumentException.cs -System.ComponentModel/InvalidEnumArgumentException.cs System.ComponentModel/ListBindableAttribute.cs System.ComponentModel/ListChangedEventArgs.cs System.ComponentModel/ListChangedEventHandler.cs @@ -147,14 +222,18 @@ System.ComponentModel/ListChangedType.cs System.ComponentModel/ListSortDescription.cs System.ComponentModel/ListSortDescriptionCollection.cs System.ComponentModel/ListSortDirection.cs -System.ComponentModel/ListSortDirection.cs System.ComponentModel/LocalizableAttribute.cs +System.ComponentModel/LookupBindingPropertiesAttribute.cs System.ComponentModel/MarshalByValueComponent.cs +System.ComponentModel/MaskedTextProvider.cs +System.ComponentModel/MaskedTextResultHint.cs System.ComponentModel/MemberDescriptor.cs System.ComponentModel/MergablePropertyAttribute.cs System.ComponentModel/MultilineStringConverter.cs +System.ComponentModel/NestedContainer.cs System.ComponentModel/NotifyParentPropertyAttribute.cs System.ComponentModel/NullableConverter.cs +System.ComponentModel/ParenthesizePropertyNameAttribute.cs System.ComponentModel/PasswordPropertyTextAttribute.cs System.ComponentModel/ProgressChangedEventArgs.cs System.ComponentModel/ProgressChangedEventHandler.cs @@ -163,24 +242,27 @@ System.ComponentModel/PropertyChangedEventHandler.cs System.ComponentModel/PropertyChangingEventArgs.cs System.ComponentModel/PropertyChangingEventHandler.cs System.ComponentModel/PropertyDescriptor.cs -System.ComponentModel/PropertyDescriptor.cs System.ComponentModel/PropertyDescriptorCollection.cs -System.ComponentModel/ReadOnlyAttribute.cs +System.ComponentModel/PropertyTabAttribute.cs +System.ComponentModel/PropertyTabScope.cs +System.ComponentModel/ProvidePropertyAttribute.cs System.ComponentModel/ReadOnlyAttribute.cs System.ComponentModel/RecommendedAsConfigurableAttribute.cs System.ComponentModel/ReferenceConverter.cs -System.ComponentModel/ReferenceConverter.cs System.ComponentModel/ReflectionEventDescriptor.cs System.ComponentModel/ReflectionPropertyDescriptor.cs System.ComponentModel/RefreshEventArgs.cs System.ComponentModel/RefreshEventHandler.cs System.ComponentModel/RefreshProperties.cs System.ComponentModel/RefreshPropertiesAttribute.cs +System.ComponentModel/RunInstallerAttribute.cs System.ComponentModel/RunWorkerCompletedEventArgs.cs System.ComponentModel/RunWorkerCompletedEventHandler.cs System.ComponentModel/SByteConverter.cs +System.ComponentModel/SettingsBindableAttribute.cs System.ComponentModel/SingleConverter.cs System.ComponentModel/StringConverter.cs +System.ComponentModel/SyntaxCheck.cs System.ComponentModel/TimeSpanConverter.cs System.ComponentModel/ToolboxItemAttribute.cs System.ComponentModel/ToolboxItemFilterAttribute.cs @@ -188,11 +270,13 @@ System.ComponentModel/ToolboxItemFilterType.cs System.ComponentModel/TypeConverter.cs System.ComponentModel/TypeConverterAttribute.cs System.ComponentModel/TypeDescriptionProvider.cs +System.ComponentModel/TypeDescriptionProviderAttribute.cs System.ComponentModel/TypeDescriptor.cs System.ComponentModel/TypeListConverter.cs System.ComponentModel/UInt16Converter.cs System.ComponentModel/UInt32Converter.cs System.ComponentModel/UInt64Converter.cs +System.ComponentModel/WarningException.cs System.ComponentModel/WeakObjectWrapper.cs System.ComponentModel/WeakObjectWrapperComparer.cs System.ComponentModel/Win32Exception.cs |